User:Learn more/Appcompat

From ReactOS Wiki
Jump to: navigation, search

What is it?

The Application Compatibility Framework is a mechanism designed to work around bugs in applications. It can happen after upgrading your operating system that applications suddenly stop working. A common reason for this is because the application (unknowningly to the author) relies on a bug in the operating system. Once this bug is fixed, the application suddenly stops working, and without an update from the author would not be usable anymore. Because an author might not be available to create an update (or might not even be aware of the problem), the Application Compatiblity Framework has mitigations to work around common errors.

The part most visible to the user is the 'Compatibility' tab presented in the properties dialog.

caption Example from Windows 10

How does it work?

Overview

There are various techniques used to 'fix' applications:

  • Call a specific function
    • For example: If an application needs to run in 640x480, a fix will call a function at process start to change the resolution.
  • Alter the behavior of a function.
    • For example: If an application cannot properly handle disks above 2GB, a fix can make it appear as if there was only 2GB available.
  • Alter the (percieved) environment of the application.
    • For example: If an application checks that it is running on a certain version of windows, a fix can make it appear to the application as if it is running on this version.

Technical details

Initialization

Outlined below is a rough outline of the initialization of the shim engine. (...) is used as a placeholder to indicate some omitted (non-relevant) function calls

Parent process

This is where the shim engine checks if there should be a shim applied. The checks if shims need to be applied are called from the function that creates the process. When shims need to be applied, memory is allocated in the target process, and a pointer in the PEB (pShimData) is initialized, pointing to this data.

  • kernel32!CreateProcess
    • kernel32!CreateProcessInternal
      • (...)
      • kernel32!BasepCheckBadapp
        • kernel32!BaseCheckAppcompatCache
          • TODO
        • kernel32!BaseCheckRunApp
          • apphelp!ApphelpCheckRunApp[Ex]
    • (...)
    • kernel32!BasePushProcessParameters
      • (...)
      • ntdll!NtAllocateVirtualMemory (Peb->pShimData)
      • ntdll!NtWriteVirtualMemory (Peb->pShimData)

Child process, initialization

At process start, LdrpInitializeProcess checks pShimData. If this is set, the process will need a shim, and the Shim Engine is initialized with LdrpLoadShimEngine. The dll to load for this is specified in the pShimData, and in w2k3 this is still shimeng.dll. In later versions this is changed to apphelp.dll.

That process roughly looks like this:

  • ntoskrnl!PspUserThreadStartup
    • (...)
    • ntdll!LdrInitializeThunk
      • (...)
      • ntdll!LdrpInit
        • (...)
        • ntdll!LdrpInitializeProcess (Peb->pShimData)
          • (...)
          • ntdll!!LdrpLoadShimEngine (Peb->pShimData)
            • (...)
            • shimeng!SE_InstallbeforeInit

Child process, execution

SeiInit does most of the work:

  • Creating a list of shims to load (SeiBuildShimRefArray)
  • Building lists of modules to include / exclude (global and per shim, SeiBuildGlobalInclExclList, SeiBuildInclExclList)
  • Loading the shim modules (LdrLoadDll)
  • Calling into the loaded shim modules to retrieve a list of functions to redirect (GetHookAPIs)
  • Redirecting the api's specified by the shims (SeiHookImports)

Initialization roughly looks like this:

  • apphelp!SE_InstallBeforeInit
    • apphelp!SeiGetShimData
      • (...)
      • apphelp!SdbInitDatabase
        • (...)
      • apphelp!SdbUnpackAppCompatData
    • apphelp!SeiInit
      • (...)
      • apphelp!SeiCheckComPlusImage
      • (...)
      • apphelp!SeiBuildGlobalInclExclList
      • (...)
      • ntdll!LdrGetDllHandle
      • ntdll!LdrLoadDll
      • <loaded shim module>!GetHookAPIs
      • (...)
      • apphelp!SeiBuildInclExclList
      • (...)
      • apphelp!SeiAddInternalHooks
      • apphelp!SeiResolveAPIs
      • apphelp!PatchNewModules
        • apphelp!SeiHookImports
    • apphelp!SdbReleaseDatabase

Current state

Implemented shims

Shim Description
DisableThemes Disable themes while the application is running.
Force640x480 Change the resolution to 640 x 480 while the application is running.
Force8BitColor Change the bitdepth to 8 bits while the application is running.
IgnoreDebugOutput Silently ignore debug output from an application.
IgnoreFreeLibrary Ignore calls to the 'FreeLibrary' function. The commandline specifies for which DLL.
VMHorizonSetup Fix some known problems in the setup of VMWare Horizon.
WinNT4SP5VersionLie Lie to the application about the OS version it's running on.
Win95VersionLie Lie to the application about the OS version it's running on.
Win98VersionLie Lie to the application about the OS version it's running on.
Win2000VersionLie Lie to the application about the OS version it's running on.
Win2000SP1VersionLie Lie to the application about the OS version it's running on.
Win2000SP2VersionLie Lie to the application about the OS version it's running on.
Win2000SP3VersionLie Lie to the application about the OS version it's running on.
WinXPVersionLie Lie to the application about the OS version it's running on.
WinXPSP1VersionLie Lie to the application about the OS version it's running on.
WinXPSP2VersionLie Lie to the application about the OS version it's running on.
WinXPSP3VersionLie Lie to the application about the OS version it's running on.
Win2k3RTMVersionLie Lie to the application about the OS version it's running on.
Win2k3SP1VersionLie Lie to the application about the OS version it's running on.
VistaRTMVersionLie Lie to the application about the OS version it's running on.
VistaSP1VersionLie Lie to the application about the OS version it's running on.
VistaSP2VersionLie Lie to the application about the OS version it's running on.
Win7RTMVersionLie Lie to the application about the OS version it's running on.
Win8RTMVersionLie Lie to the application about the OS version it's running on.
Win81RTMVersionLie Lie to the application about the OS version it's running on.

Source: https://git.reactos.org/?p=reactos.git&a=search&h=HEAD&st=grep&s=%23define+SHIM_NS&sr=1

Framework status