Saturday, November 17, 2007

Thinstall and Wine

For people who see Thinstall for the first time, it seems like magic and they wonder how it works. But Thinstall isn't new - most of the concepts for Thinstall are a decade old and have been implemented by various open source projects such as Wine and UML. Thinstall was first released in 2001 but wine was available many years before this and can rightfully claim many "first" boasting rights.

Wine (Wine is not an emulator, well actually it is....)

Although Thinstall and Wine do not share any code internally and they are targeting different operating systems the underlying designs have many similarities. Both systems use a combinations of API translation and API emulation to achieve their goals.

Thinstall’s primary goal is to allow Windows applications to run on the Windows operating system without installation and with limited changes to the host PC. The primary goal of Wine is to allow Windows applications to run on unix operating systems.

Wine works by emulating vast portions of the Win32 layer and translating Win32 API calls such as CreateFile (Windows) into open (Linux). When a call to CreateFile is made by the applicaion, part of the translation process is to convert paths from Windows format into unix format. For example, Windows has the concept of drive letters which unix does not have so the path “c:\windows\win.ini” is converted into something like “/home/username/.wine/drive_c/Windows/win.ini”. Applications running on top of the Wine emulation layer are accessing a virtualized file system that mirrors what they would expect on a real windows system. If the application tries to create new files or modifies data in the virtualized file system, the host PC is unaffected outside of changes to the directory “/home/username/.wine”. In this fashion, wine serves as a “protection layer” that prevents the application from modifying the real host file system. A wine virtual environment can be completely removed from the host PC by recursively deleting /home/username/.wine.

Wine runs in user mode so it relies on the security policies of the host machine to prevent the emulated application from doing dangerous operations. For example, even if there are bugs in wine the applications would not be able to access other user's files, format the hard drive, or execute privileged instructions.

Windows has a number of concepts that are not present on Unix systems, for example a registry. In order to allow windows applications to run on unix systems, Wine emulates a fake (“virtualized” in today’s marketing lingo) registry. Wine’s registry emulation loads registry values into memory from a disk file on startup and periodically saves any changes made back to the disk file. WineHQ keeps source code revisions back to 1999 so you can go back and browse Wine's early virtual registry code.

When an application is installed into a wine's virtual environment, all of it’s modifications are stored under a single data directory (default is /home/username/.wine).

Wine can be configured to use multiple different “virtual” environments on startup using an environment variable called WINEPREFIX. This enables applications to be fully separated from each other and registry or file system modifications from one application cannot effect other applications.

Wine’s data directory also serves as a “snapshot” of the installed state of an individual application. For example, after installing Microsoft Office inside of a virtual environment, the persistent state of the application can be copied to other machines or users and run directly without installation.

Wine was originally designed for Linux but was quickly ported to FreeBSD and today supports many other operating systems. While it never came to fruition, cygwin and Wine developers have contemplated porting wine to the Windows operating system using cygwin.

How Thinstall works

Design-wise, Thinstall has many similarities wtih Wine. Thinstall emulates and translates the Win32 API on a more selective basis to achieve its stated goals. With Thinstall the vast majority of the Win32 API passes directly to Windows with no emulation or translation. For example, when an application calls BitBlt, a function used to draw a bitmap to the screen, the call passes directly to Windows. Because Thinstall only replaces about 600 of the 10,000+ or so Win32 APIs it can achieve much higher levels of compatibility than are possible with Wine and generally it automatically supports newer operating systems and kernel updates. Because Thinstall is already running on top of Windows, we can use the existing operating system where possible rather than needing to reimplement everything.

For API functions that have the ability to make persistent machine changes or affect other running applications, the APIs are either emulated or translated. For an example of how translation is used, when an application tries to write to the file “c:\windows\win.ini” using the CreateFile API Thinstall will translate this call into CreateFile “c:\documents and settings\username\application data\thinstall\appname\%SystemRoot%\win.ini”. In this case, most of the functionality for a file system is being provided by Windows. Thinstall also provides a fully functional read-only compressed filesystem and registry that is embedded with an application and can search multiple locations for a file. The read-only file system is probed first, then the "sandbox", and then the real file system. Various isolation rules can be used to control what parts of each of these 3 systems are visible and writable.

Thinstall also uses emulation to achieve it’s goals, for example it completely emulates the Windows Loader, Windows registry, Services, COM/DCOM, and about 30 other subsystems, rather than passing API calls on to Windows. When an application tries to write to the registry using RegSetValue Thinstall emulates the behavior of the Windows registry and writes the updated registry data to a disk file under %AppData%\Thinstall\registry.rw.tvr.

Like wine, Thinstall can support multiple data directories so that applications can be separated from each other and the changes made by one application do not affect another application. In Thinstall, the default model is to give each application it's own private data directory. In Wine, the default model is to use one virtual environment for all Windows application. Also like wine, this data directory can be copied to other machines or users and used as “snapshot” and thus eliminating some or all installation steps normally needed to use the application. Thinstall takes this a bit further by implementing a compressed read-only file system that can be directly embedded in the original EXE file so distributions can occur via a single file.

Thinstall uses another concept called Copy on Write (COW) which is not present in Wine. COW has been a key concept in operating system design and CPU design over the years.

Thinstall uses COW to allow read-only access to parts of the file system and registry such that any operations that would cause modifications will copy the data to a private sandbox area where modifications occur without affecting the rest of the PC. The first implementations for COW occurred in microprocessor and OS design in the 1980’s and soon after it was adopted by virtualization/emulation solutions such as Bochs, QEMU, and UML for virtual disk storage. As well, numerous older file systems implemented the concept of snapshots and COW at the file granularity level. For example, WAFL, fossil for Plan 9 from Bell Labs, and ODS-5 would track older versions of files and make snapshots available through a special name space.

Thinstall's Sandbox merge utility allows you to take runtime changes that occured via COW and merge them back into a single EXE for easier redistribute to end-users.

Summary

Thinstall and wine share a lot of common design ancestry that goes back more than a decade. This design commonality evolved naturally and independently because both projects were targeting the same standard which was defined by Microsoft - otherwise known as the Win32 API. Thinstall and wine are not unique in targeting this platform, IBM's OS/2, ReactOS, Windows 9X, and Windows NT also implement the Win32 API as a standard.