RT_MANIFEST resource, and ISOLATION_AWARE_ENABLED
RT_MANIFEST
Since Windows XP, Windows reserves a new type of resource RT_MANIFEST for SxS manifests.
Within the RT_MANIFEST resource, Windows reserves ID 1-16. A binary cannot have two IDs of resource type RT_MANIFEST within 1-16. Windows will refuse to load such binary in Windows XP/Windows Server 2003.
Only three IDs are used today in Windows.
excerpt from Winuser.h
#define RT_MANIFEST MAKEINTRESOURCE(24)
#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1)
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2)
#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3)
#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1 /*inclusive*/)
#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16 /*inclusive*/)
CREATEPROCESS_MANIFEST_RESOURCE_ID
CREATEPROCESS_MANIFEST_RESOURCE_ID is used primarily for EXEs. If an executable has a resource of type RT_MANIFEST, ID CREATEPROCESS_MANIFEST_RESOURCE_ID, Windows will create a process default activation context for the process. The process default activation context will be used by all components running in the process.
CREATEPROCESS_MANIFEST_RESOURCE_ID can also used by DLLs. When Windows probe for dependencies, if the dll has a resource of type RT_MANIFEST, ID CREATEPROCESS_MANIFEST_RESOURCE_ID, Windows will use that manifest as the dependency.
ISOLATIONAWARE_MANIFEST_RESOURCE_ID
ISOLATIONAWARE_MANIFEST_RESOURCE_ID is used primarily for DLLs. It should be used if the dll wants private dependencies other than the process default. For example, if an dll depends on comctl32.dll version 6.0.0.0. It should have a resource of type RT_MANIFEST, ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID to depend on comctl32.dll version 6.0.0.0, so that even if the process executable wants comctl32.dll version 5.1, the dll itself will still use the right version of comctl32.dll.
When LoadLibrary is called, before loading the dependencies of the dll, the NT library loader checks to see if the dll has a resource of type RT_MANIFEST, ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID. If it does, the loader calls CreateActCtx with the resource, and use the generated activation context to probe the dll's static dependencies. This is reason why the dll can have private dependencies with the ISOLATIONAWARE_MANIFEST_RESOURCE_ID resource.
The activation context created during LoadLibrary is stored in the loader data structure tracking the dll.
Normally this activation context is used only during LoadLibrary, for the dll's static dependencies.
Sometimes, you want to use the activation context outside of probing the dll's static dependencies. You can define macro ISOLATION_AWARE_ENABLED when you compile the module.
ISOLATION_AWARE_ENABLED
When ISOLATION_AWARE_ENABLED is defined, Windows re-defines certain APIs. For example LoadLibraryExW is redefined to IsolationAwareLoadLibraryExW.
When IsolationAwareLoadLibraryExW is first called, it tries to retrieve the activation context stored in the loader data structure when the calling library is loaded. If the library does not have such activation context (for example, the library does not have a manifest of id ISOLATIONAWARE_MANIFEST_RESOURCE_ID), IsolationAwareLoadLibraryExW tries to create a new activation context with the calling library with id ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE. If the creation fails, IsolationAwareLoadLibraryExW will use the process default activation context.
Once the activation context is determined, IsolationAwareLoadLibraryExW will call ActivateActCtx on the activation context, call the real API (LoadLibraryExW), and on return, it calls DeactivationActCtx. This way, the correct activation context is automatically used.
Not all APIs affected by activation context are wrapped. For example, GetModuleHandleEx is not wrapped, and neither is any of the COM APIs. For a complete list of APIs wrapped by ISOLATION_AWARE_ENABLED, check your copy of Windows SDK.
C:\Program Files\Microsoft SDKs\Windows\v6.0\Include>dir *.inl
Volume in drive C has no label.
Volume Serial Number is ECD1-6DB0
Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0\Include
10/30/2006 01:44 AM 159,222 commctrl.inl
10/30/2006 01:44 AM 32,836 commdlg.inl
10/30/2006 01:44 AM 12,065 prsht.inl
10/30/2006 01:44 AM 23,430 WinBase.Inl
10/30/2006 01:44 AM 36,308 WinUser.Inl
If the APIs you use are not wrapped by ISOLATION_AWARE_ENABLED, you have to do the activation/deactivation yourself properly. You can use the C++ helper class described in MSDN https://msdn2.microsoft.com/en-us/library/aa375197.aspx.
For more information, please see MSDN section about Sxs Isolated Applications and Side-by-side Assemblies.
Comments
Anonymous
June 26, 2007
>> Now all APIs affected by activation context are wrapped I think you meant 'NOT all APIs...'Anonymous
June 26, 2007
Yes Oleg, thanks for pointing out.Anonymous
August 09, 2007
Great post, Thanks! I did have one question. I saw an article elsewhere that made the comment that VB COM Addins couldn't be made to support themes like this. Is that because you can't compile the VB addin with the ISOLATION_AWARE_ENABLED switch? Thanks Darin