You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Whenever you load a DLL or start an EXE which has a manifest you should create an AcrivationContext before loading any dependent libraries (before calling BuildImportTable())
This is required when any of the imported libraries exists in multiple versions in the SXS Side-by-Side store of Windows.
The ActivationContext is required to tell Windows for example which version of COMCTL32.dll or MSVCR80.dll has to be loaded.
I made lots of changes in the original code. Therefore I don't make a pull request now.
Apart from that Joachim Bauch does not merge pull requests anymore. He does not even answer emails.
So here is my code:
// Required for all DLL's and EXE's which load dependent SXS DLL's like COMCTL32.dll or MSVCR80.dll
// Returns API error
DWORD cMemMod::CreateActivationContext(PMEMORYMODULE module, HANDLE* ph_ActCtx, ULONG_PTR* pu32_ActCtxCookie)
{
DWORD u32_Error = 0;
LPCWSTR u16_Manifest = module->isDLL ? ISOLATIONAWARE_MANIFEST_RESOURCE_ID : CREATEPROCESS_MANIFEST_RESOURCE_ID;
HRSRC h_Resource = FindResource((HMODULE)module->codeBase, u16_Manifest, RT_MANIFEST);
if (!h_Resource)
return 0; // The EXE / DLL has no manifest
BYTE* u8_MemPtr = (BYTE*)LoadResource ((HMODULE)module->codeBase, h_Resource);
DWORD u32_Size = SizeofResource((HMODULE)module->codeBase, h_Resource);
WCHAR u16_TempPath[MAX_PATH];
GetTempPath(MAX_PATH, u16_TempPath); // terminated with backslash
// Create a random temporary file name
WCHAR u16_TmpFile[MAX_PATH];
swprintf(u16_TmpFile, L"%sDLL%X.manifest", u16_TempPath, (DWORD)__rdtsc());
HANDLE h_File = CreateFileW(u16_TmpFile, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0);
if (h_File == INVALID_HANDLE_VALUE)
return GetLastError();
DWORD u32_Written;
if (!WriteFile(h_File, u8_MemPtr, u32_Size, &u32_Written, 0))
u32_Error = GetLastError();
CloseHandle(h_File);
if (u32_Error)
return u32_Error;
// Getting a manifest from memory does not work.
// Even with Flags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID --> Windows searches for the *.DLL file
// and for the *.MANIFEST file specified in lpSource on disk.
// If lpSource == NULL --> ERROR_MOD_NOT_FOUND. On Windows XP bug --> ERROR_NOT_ENOUGH_MEMORY
ACTCTXW k_Ctx = {0};
k_Ctx.cbSize = sizeof(k_Ctx);
k_Ctx.lpSource = u16_TmpFile;
*ph_ActCtx = CreateActCtxW(&k_Ctx);
u32_Error = GetLastError();
DeleteFile(u16_TmpFile);
if (*ph_ActCtx == INVALID_HANDLE_VALUE)
return u32_Error;
if (!ActivateActCtx(*ph_ActCtx, pu32_ActCtxCookie))
return GetLastError();
TRACE(L">> Activate ActCtx: %p", *ph_ActCtx);
return 0;
}
You must call this function before calling BuildImportTable().
Whenever you load a DLL or start an EXE which has a manifest you should create an AcrivationContext before loading any dependent libraries (before calling BuildImportTable())
This is required when any of the imported libraries exists in multiple versions in the SXS Side-by-Side store of Windows.
The ActivationContext is required to tell Windows for example which version of COMCTL32.dll or MSVCR80.dll has to be loaded.
I made lots of changes in the original code. Therefore I don't make a pull request now.
Apart from that Joachim Bauch does not merge pull requests anymore. He does not even answer emails.
So here is my code:
You must call this function before calling BuildImportTable().
After calling the entry point of the DLL you don't need the activation context anymore.
The text was updated successfully, but these errors were encountered: