This page describes the versioning support for ReactOS
ReactOS is currently based on the Windows 2003 design, both in kernel mode as well as in user mode. It has been the notion among developers that creating a version chimera can lead to a lot of unexpected problems, arising for example from exporting some functions from Windows Vista, but not others, leading applications to believe they run on Vista, but then fail to load due to missing features, while they work on a normal Windows 2003 system. A full switch from the current state to NT 6+ in one step is unrealistic though. The conclusion is therefore, that we need a versioning system to provide a consistent interface for applications in usermode, which can be adjusted for each application in the appropriate way.
- Allow setting version compatibility per application for all major versions, both lower as well as higher than Windows 2003
- Try to provide the best compatibility
- As simple as possible, as effective as possible
- Allow DLLs to still be built in a Windows 2003 compatible way.
- Actual implementation of NT 6+ APIs
- Systemcall ID compatibility (not possible and not required)
One existing part for app-compatibility is the shim-engine, which is also part of Windows. But the main purpose of the shim-engine is to allow for backwards compatibility, not forward compatibility.
To provide applications with the appropriate exports for each NT target version, a set of forwarder DLLs are a possibility. This can create some problems though:
- Complex mechanism required to load the appropriate DLL (SxS based?)
- Additional DLLs need to be loaded (slow)
- Multiple DLLs with the same name loaded into the process.
- It is unclear where to put the actual implementation (all in a core DLL, or in the DLL where they are required?) How can internal functions be shared?
- Function implementation is not in the same DLL as the function is exported from.
"Roscompat-engine" design proposal
In order to provide a relatively simple mechanism, the following design was developed:
- All functions from all versions are exported from the appropriate DLL.
- Each DLL is provided with a special section that contains a version-compatibility descriptor.
- When loading the DLL, the loader in NTDLL checks for this descriptor and uses it to apply the relevant "modifications".
- As the source for the correct modifications, the appcompat version is used.
- The export table is patched by using a mask-array that specifies for each named export, in what versions it is present.
- The export table is split into a visible table for public exports and a hidden table for private exports.
- For nameless ordinal exports, a similar mechanism is used.
- ReactOS-DLLs are allowed to statically import hidden exports.