/* GLOBALS *******************************************************************/
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache, LdrpGetModuleHandleCache;
+
BOOLEAN g_ShimsEnabled;
+PVOID g_pShimEngineModule;
+PVOID g_pfnSE_DllLoaded;
+PVOID g_pfnSE_DllUnloaded;
+PVOID g_pfnSE_InstallBeforeInit;
+PVOID g_pfnSE_InstallAfterInit;
+PVOID g_pfnSE_ProcessDying;
/* FUNCTIONS *****************************************************************/
-/* NOTE: Remove those two once our actctx support becomes better */
-NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module )
-{
- NTSTATUS status;
- LDR_RESOURCE_INFO info;
- IMAGE_RESOURCE_DATA_ENTRY *entry;
-
- info.Type = (ULONG)RT_MANIFEST;
- info.Name = (ULONG)ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
- info.Language = 0;
- if (!(status = LdrFindResource_U( module->DllBase, &info, 3, &entry )))
- {
- ACTCTXW ctx;
- ctx.cbSize = sizeof(ctx);
- ctx.lpSource = NULL;
- ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
- ctx.hModule = module->DllBase;
- ctx.lpResourceName = (LPCWSTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
- status = RtlCreateActivationContext(0, (PVOID)&ctx, 0, NULL, NULL, &module->EntryPointActivationContext);
- }
- return status;
-}
-
-NTSTATUS find_actctx_dll( LPCWSTR libname, WCHAR *fullname )
-{
- static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'};
- static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
-
- ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info;
- ACTCTX_SECTION_KEYED_DATA data;
- UNICODE_STRING nameW;
- NTSTATUS status;
- SIZE_T needed, size = 1024;
- WCHAR *p;
-
- RtlInitUnicodeString( &nameW, libname );
- data.cbSize = sizeof(data);
- status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
- ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
- &nameW, &data );
- if (status != STATUS_SUCCESS) return status;
-
- for (;;)
- {
- if (!(info = RtlAllocateHeap( RtlGetProcessHeap(), 0, size )))
- {
- status = STATUS_NO_MEMORY;
- goto done;
- }
- status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex,
- AssemblyDetailedInformationInActivationContext,
- info, size, &needed );
- if (status == STATUS_SUCCESS) break;
- if (status != STATUS_BUFFER_TOO_SMALL) goto done;
- RtlFreeHeap( RtlGetProcessHeap(), 0, info );
- size = needed;
- }
-
- DPRINT("manifestpath === %S\n", info->lpAssemblyManifestPath);
- DPRINT("DirectoryName === %S\n", info->lpAssemblyDirectoryName);
- if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName)
- {
- status = STATUS_SXS_KEY_NOT_FOUND;
- goto done;
- }
-
- if ((p = wcsrchr( info->lpAssemblyManifestPath, '\\' )))
- {
- DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
-
- p++;
- if (_wcsnicmp( p, info->lpAssemblyDirectoryName, dirlen ) || wcsicmp( p + dirlen, dotManifestW ))
- {
- /* manifest name does not match directory name, so it's not a global
- * windows/winsxs manifest; use the manifest directory name instead */
- dirlen = p - info->lpAssemblyManifestPath;
- needed = (dirlen + 1) * sizeof(WCHAR) + nameW.Length;
-
- p = fullname;
- /*if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed )))
- {
- status = STATUS_NO_MEMORY;
- goto done;
- }*/
- memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) );
- p += dirlen;
- wcscpy( p, libname );
- goto done;
- }
- }
-
- needed = (wcslen(SharedUserData->NtSystemRoot) * sizeof(WCHAR) +
- sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + nameW.Length + 2*sizeof(WCHAR));
-
- p = fullname;
- //if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed )))
- //{
- //status = STATUS_NO_MEMORY;
- //goto done;
- //}
- wcscpy( p, SharedUserData->NtSystemRoot );
- p += wcslen(p);
- memcpy( p, winsxsW, sizeof(winsxsW) );
- p += sizeof(winsxsW) / sizeof(WCHAR);
- memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength );
- p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
- *p++ = '\\';
- wcscpy( p, libname );
-
-done:
- RtlFreeHeap( RtlGetProcessHeap(), 0, info );
- RtlReleaseActivationContext( data.hActCtx );
- DPRINT("%S\n", fullname);
- return status;
-}
-
-
NTSTATUS
NTAPI
LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut,
}
/* Allocate the string*/
- StringOut->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ StringOut->Buffer = RtlAllocateHeap(LdrpHeap,
0,
- StringOut->Length + sizeof(WCHAR));
+ Length + sizeof(WCHAR));
if (!StringOut->Buffer)
{
/* Fail */
}
/* Null-terminate it */
- StringOut->Buffer[StringOut->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ StringOut->Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
/* Check if this is a maximum-sized string */
- if (StringOut->Length != UNICODE_STRING_MAX_BYTES)
+ if (Length != UNICODE_STRING_MAX_BYTES)
{
/* It's not, so set the maximum length to be one char more */
- StringOut->MaximumLength = StringOut->Length + sizeof(UNICODE_NULL);
+ StringOut->MaximumLength = (USHORT)Length + sizeof(UNICODE_NULL);
}
else
{
/* If Buffer is not NULL - free it */
if (StringIn->Buffer)
{
- RtlFreeHeap(RtlGetProcessHeap(), 0, StringIn->Buffer);
+ RtlFreeHeap(LdrpHeap, 0, StringIn->Buffer);
}
/* Zero it out */
RtlInitEmptyUnicodeString(StringIn, NULL, 0);
}
+
BOOLEAN
NTAPI
LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint,
OUT PUNICODE_STRING UpdateString)
{
PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
+ PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry;
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
PIMAGE_THUNK_DATA FirstThunk;
PLDR_DATA_TABLE_ENTRY Entry;
- PUNICODE_STRING ImportNameUnic;
+ PUNICODE_STRING ImportNameUnic, RedirectedImportName;
ANSI_STRING ImportNameAnsi;
LPSTR ImportName;
ULONG ImportSize;
NTSTATUS Status;
ULONG i;
+ BOOLEAN RedirectedDll;
+ RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
+
+ /* Set up the Act Ctx */
+ ActCtx.Size = sizeof(ActCtx);
+ ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER;
+ RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
+
+ /* Activate the ActCtx */
+ RtlActivateActivationContextUnsafeFast(&ActCtx,
+ LdrEntry->EntryPointActivationContext);
/* Check the action we need to perform */
if ((Flags == LDRP_UPDATE_REFCOUNT) || (Flags == LDRP_UPDATE_PIN))
{
/* Make sure entry is not being loaded already */
if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS)
- return;
+ goto done;
LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
}
{
/* Make sure the entry is not being unloaded already */
if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
- return;
+ goto done;
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
}
ImportNameUnic = &NtCurrentTeb()->StaticUnicodeString;
/* Try to get the new import entry */
- BoundEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(LdrEntry->DllBase,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
- &ImportSize);
+ FirstEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+ &ImportSize);
- if (BoundEntry)
+ if (FirstEntry)
{
/* Set entry flags if refing/derefing */
if (Flags == LDRP_UPDATE_REFCOUNT)
else if (Flags == LDRP_UPDATE_DEREFCOUNT)
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
+ BoundEntry = FirstEntry;
while (BoundEntry->OffsetModuleName)
{
/* Get pointer to the current import name */
- ImportName = (PCHAR)BoundEntry + BoundEntry->OffsetModuleName;
+ ImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
RtlInitAnsiString(&ImportNameAnsi, ImportName);
Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
if (NT_SUCCESS(Status))
{
- if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
- TRUE,
- FALSE,
- &Entry))
+ RedirectedDll = FALSE;
+ RedirectedImportName = ImportNameUnic;
+
+ /* Check if the SxS Assemblies specify another file */
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ ImportNameUnic,
+ &LdrApiDefaultExtension,
+ UpdateString,
+ NULL,
+ &RedirectedImportName,
+ NULL,
+ NULL,
+ NULL);
+
+ /* Check success */
+ if (NT_SUCCESS(Status))
{
- if (Entry->LoadCount != 0xFFFF)
+ /* Let Ldrp know */
+ if (ShowSnaps)
{
- /* Perform the required action */
- switch (Flags)
- {
- case LDRP_UPDATE_REFCOUNT:
- Entry->LoadCount++;
- break;
- case LDRP_UPDATE_DEREFCOUNT:
- Entry->LoadCount--;
- break;
- case LDRP_UPDATE_PIN:
- Entry->LoadCount = 0xFFFF;
- break;
- }
-
- /* Show snaps */
- if (ShowSnaps)
- {
- DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount);
- }
+ DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
}
- /* Recurse into this entry */
- LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
+ RedirectedDll = TRUE;
}
- }
- /* Go through forwarders */
- NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
- for (i=0; i<BoundEntry->NumberOfModuleForwarderRefs; i++)
- {
- ImportName = (PCHAR)BoundEntry + NewImportForwarder->OffsetModuleName;
-
- RtlInitAnsiString(&ImportNameAnsi, ImportName);
- Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
- if (NT_SUCCESS(Status))
+ if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
{
if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
+ RedirectedImportName,
TRUE,
- FALSE,
+ RedirectedDll,
&Entry))
{
if (Entry->LoadCount != 0xFFFF)
/* Show snaps */
if (ShowSnaps)
{
- DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount);
+ DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
}
}
/* Recurse into this entry */
LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
}
+ else if (RedirectedDll)
+ {
+ DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
+ }
+ }
+ else
+ {
+ /* Unrecoverable SxS failure */
+ DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
+ }
+
+ }
+
+ /* Go through forwarders */
+ NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
+ for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
+ {
+ ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName;
+
+ RtlInitAnsiString(&ImportNameAnsi, ImportName);
+ Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ RedirectedDll = FALSE;
+ RedirectedImportName = ImportNameUnic;
+
+ /* Check if the SxS Assemblies specify another file */
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ ImportNameUnic,
+ &LdrApiDefaultExtension,
+ UpdateString,
+ NULL,
+ &RedirectedImportName,
+ NULL,
+ NULL,
+ NULL);
+ /* Check success */
+ if (NT_SUCCESS(Status))
+ {
+ if (ShowSnaps)
+ {
+ DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
+ }
+ /* Let Ldrp know */
+ RedirectedDll = TRUE;
+ }
+
+ if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
+ {
+ if (LdrpCheckForLoadedDll(NULL,
+ RedirectedImportName,
+ TRUE,
+ RedirectedDll,
+ &Entry))
+ {
+ if (Entry->LoadCount != 0xFFFF)
+ {
+ /* Perform the required action */
+ switch (Flags)
+ {
+ case LDRP_UPDATE_REFCOUNT:
+ Entry->LoadCount++;
+ break;
+ case LDRP_UPDATE_DEREFCOUNT:
+ Entry->LoadCount--;
+ break;
+ case LDRP_UPDATE_PIN:
+ Entry->LoadCount = 0xFFFF;
+ break;
+ }
+
+ /* Show snaps */
+ if (ShowSnaps)
+ {
+ DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
+ }
+ }
+
+ /* Recurse into this entry */
+ LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
+ }
+ else if (RedirectedDll)
+ {
+ DPRINT1("LDR: LdrpCheckForLoadedDll failed with status %x for redirected dll %wZ\n", Status, RedirectedImportName);
+ }
+ }
+ else
+ {
+ /* Unrecoverable SxS failure */
+ DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic);
+ }
+
}
NewImportForwarder++;
}
/* We're done */
- return;
+ goto done;
}
/* Check oldstyle import descriptor */
Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
if (NT_SUCCESS(Status))
{
- if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
- TRUE,
- FALSE,
- &Entry))
+ RedirectedDll = FALSE;
+ RedirectedImportName = ImportNameUnic;
+
+ /* Check if the SxS Assemblies specify another file */
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ ImportNameUnic,
+ &LdrApiDefaultExtension,
+ UpdateString,
+ NULL,
+ &RedirectedImportName,
+ NULL,
+ NULL,
+ NULL);
+ /* Check success */
+ if (NT_SUCCESS(Status))
{
- if (Entry->LoadCount != 0xFFFF)
+ if (ShowSnaps)
{
- /* Perform the required action */
- switch (Flags)
- {
- case LDRP_UPDATE_REFCOUNT:
- Entry->LoadCount++;
- break;
- case LDRP_UPDATE_DEREFCOUNT:
- Entry->LoadCount--;
- break;
- case LDRP_UPDATE_PIN:
- Entry->LoadCount = 0xFFFF;
- break;
- }
+ DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
+ }
- /* Show snaps */
- if (ShowSnaps)
+ /* Let Ldrp know */
+ RedirectedDll = TRUE;
+ }
+
+ if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
+ {
+ if (LdrpCheckForLoadedDll(NULL,
+ RedirectedImportName,
+ TRUE,
+ RedirectedDll,
+ &Entry))
+ {
+ if (Entry->LoadCount != 0xFFFF)
{
- DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount);
+ /* Perform the required action */
+ switch (Flags)
+ {
+ case LDRP_UPDATE_REFCOUNT:
+ Entry->LoadCount++;
+ break;
+ case LDRP_UPDATE_DEREFCOUNT:
+ Entry->LoadCount--;
+ break;
+ case LDRP_UPDATE_PIN:
+ Entry->LoadCount = 0xFFFF;
+ break;
+ }
+
+ /* Show snaps */
+ if (ShowSnaps)
+ {
+ DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
+ }
}
+
+ /* Recurse */
+ LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
+ }
+ else if (RedirectedDll)
+ {
+ DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
}
- /* Recurse */
- LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
}
+ else
+ {
+ /* Unrecoverable SxS failure */
+ DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed for dll %wZ\n", ImportNameUnic);
+ }
+
}
/* Go to the next entry */
ImportEntry++;
}
}
+
+done:
+ /* Release the context */
+ RtlDeactivateActivationContextUnsafeFast(&ActCtx);
}
VOID
VOID
NTAPI
-LdrpCallTlsInitializers(IN PVOID BaseAddress,
+LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
IN ULONG Reason)
{
PIMAGE_TLS_DIRECTORY TlsDirectory;
ULONG Size;
/* Get the TLS Directory */
- TlsDirectory = RtlImageDirectoryEntryToData(BaseAddress,
+ TlsDirectory = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_TLS,
&Size);
if (ShowSnaps)
{
DPRINT1("LDR: Tls Callbacks Found. Imagebase %p Tls %p CallBacks %p\n",
- BaseAddress, TlsDirectory, Array);
+ LdrEntry->DllBase, TlsDirectory, Array);
}
/* Loop the array */
if (ShowSnaps)
{
DPRINT1("LDR: Calling Tls Callback Imagebase %p Function %p\n",
- BaseAddress, Callback);
+ LdrEntry->DllBase, Callback);
}
/* Call it */
LdrpCallInitRoutine((PDLL_INIT_ROUTINE)Callback,
- BaseAddress,
+ LdrEntry->DllBase,
Reason,
NULL);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- /* Do nothing */
+ DPRINT1("LDR: Exception 0x%x during Tls Callback(%u) for %wZ\n",
+ _SEH2_GetExceptionCode(), Reason, &LdrEntry->BaseDllName);
}
_SEH2_END;
}
PWCHAR NameBuffer, p1, p2 = 0;
ULONG Length;
ULONG BufSize = 500;
- NTSTATUS Status;
/* Allocate space for full DLL name */
- FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL));
+ FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BufSize + sizeof(UNICODE_NULL));
if (!FullDllName->Buffer) return FALSE;
Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
if (!Length || Length > BufSize)
{
- /* HACK: Try to find active context dll */
- Status = find_actctx_dll(DllName, FullDllName->Buffer);
- if(Status == STATUS_SUCCESS)
+ if (ShowSnaps)
{
- Length = wcslen(FullDllName->Buffer) * sizeof(WCHAR);
- DPRINT1("found %S for %S\n", FullDllName->Buffer, DllName);
+ DPRINT1("LDR: LdrResolveDllName - Unable to find ");
+ DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
}
- else
- {
- /* NOTE: This code should remain after removing the hack */
- if (ShowSnaps)
- {
- DPRINT1("LDR: LdrResolveDllName - Unable to find ");
- DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
- }
- RtlFreeUnicodeString(FullDllName);
- return FALSE;
- }
+ LdrpFreeUnicodeString(FullDllName);
+ return FALSE;
}
/* Construct full DLL name */
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
/* Allocate a new buffer */
- NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
+ NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
if (!NameBuffer)
{
- RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+ RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
return FALSE;
}
/* Copy over the contents from the previous one and free it */
RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
- RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+ RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
FullDllName->Buffer = NameBuffer;
/* Find last backslash */
/* Construct base DLL name */
BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
- BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BaseDllName->MaximumLength);
+ BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
if (!BaseDllName->Buffer)
{
- RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
+ RtlFreeHeap(LdrpHeap, 0, NameBuffer);
return FALSE;
}
/* Set up BaseDllName */
BaseDllName->Length = DllNameUnic.Length;
BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
- BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
0,
DllNameUnic.MaximumLength);
if (!BaseDllName->Buffer)
/* Set up FullDllName */
FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
- FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
+ FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
if (!FullDllName->Buffer)
{
Status = STATUS_NO_MEMORY;
if (Section) NtClose(Section);
/* Free string resources */
- if (BaseDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
- if (FullDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
+ if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
+ if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
/* Return status */
return Status;
}
/* Check if we have a known dll directory */
- if (LdrpKnownDllObjectDirectory)
+ if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
{
/* Check if the path is full */
while (*p1)
if (!NT_SUCCESS(Status))
{
/* Free the name strings and return */
- RtlFreeUnicodeString(&FullDllName);
- RtlFreeUnicodeString(&BaseDllName);
+ LdrpFreeUnicodeString(&FullDllName);
+ LdrpFreeUnicodeString(&BaseDllName);
return Status;
}
}
{
/* Remove the DLL from the lists */
RemoveEntryList(&LdrEntry->InLoadOrderLinks);
- RemoveEntryList(&LdrEntry->InMemoryOrderModuleList);
+ RemoveEntryList(&LdrEntry->InMemoryOrderLinks);
RemoveEntryList(&LdrEntry->HashLinks);
/* Remove the LDR Entry */
- RtlFreeHeap(RtlGetProcessHeap(), 0, LdrEntry );
+ RtlFreeHeap(LdrpHeap, 0, LdrEntry );
/* Unmap and close section */
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
ImageEnd = ImageBase + ViewSize;
- DPRINT1("LDR: LdrpMapDll Relocating Image Name %ws (%p -> %p)\n", DllName, (PVOID)ImageBase, ViewBase);
+ DPRINT("LDR: LdrpMapDll Relocating Image Name %ws (%p-%p -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, ViewBase);
/* Scan all the modules */
ListHead = &Peb->Ldr->InLoadOrderModuleList;
CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
/* Make sure this entry isn't unloading */
- if (!CandidateEntry->InMemoryOrderModuleList.Flink) continue;
+ if (!CandidateEntry->InMemoryOrderLinks.Flink) continue;
/* Check if our regions are colliding */
if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
RtlInitUnicodeString(&OverlapDll, L"Dynamically Allocated Memory");
}
- DPRINT1("Overlapping DLL: %wZ\n", &OverlapDll);
+ DPRINT("Overlapping DLL: %wZ\n", &OverlapDll);
/* Are we dealing with a DLL? */
if (LdrEntry->Flags & LDRP_IMAGE_DLL)
/* Don't do relocation */
Status = STATUS_CONFLICTING_ADDRESSES;
- goto NoRelocNeeded;
+ goto FailRelocate;
}
/* Change the protection to prepare for relocation */
Status = LdrpSetProtection(ViewBase, TRUE);
}
}
-//FailRelocate:
+FailRelocate:
/* Handle any kind of failure */
if (!NT_SUCCESS(Status))
{
/* Remove it from the lists */
RemoveEntryList(&LdrEntry->InLoadOrderLinks);
- RemoveEntryList(&LdrEntry->InMemoryOrderModuleList);
+ RemoveEntryList(&LdrEntry->InMemoryOrderLinks);
RemoveEntryList(&LdrEntry->HashLinks);
/* Unmap it, clear the entry */
if (NtHeader)
{
/* Allocate an entry */
- LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ LdrEntry = RtlAllocateHeap(LdrpHeap,
HEAP_ZERO_MEMORY,
sizeof(LDR_DATA_TABLE_ENTRY));
/* Insert into other lists */
InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
- InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderModuleList);
+ InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderLinks);
}
VOID
if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
/* Finally free the entry's memory */
- RtlFreeHeap(RtlGetProcessHeap(), 0, Entry);
+ RtlFreeHeap(LdrpHeap, 0, Entry);
}
BOOLEAN
InLoadOrderLinks);
/* Make sure it's not unloading and check for a match */
- if ((Current->InMemoryOrderModuleList.Flink) && (Base == Current->DllBase))
+ if ((Current->InMemoryOrderLinks.Flink) && (Base == Current->DllBase))
{
/* Save in cache */
LdrpLoadedDllHandleCache = Current;
/* FIXME: Setup TestName here */
Status = STATUS_NOT_FOUND;
+ BufEnd = Buffer;
/* Start loop */
do
/* Look in the hash table if flag was set */
lookinhash:
- if (Flag)
+ if (Flag /* the second check is a hack */ && !RedirectedDll)
{
+ /* FIXME: if we get redirected dll it means that we also get a full path so we need to find its filename for the hash lookup */
+
/* Get hash index */
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
return FALSE;
}
- /* Check if there is a full path in this DLL */
- wc = DllName->Buffer;
- while (*wc)
+ /* Check if this is a redirected DLL */
+ if (RedirectedDll)
+ {
+ /* Redirected dlls already have a full path */
+ FullPath = TRUE;
+ FullDllName = *DllName;
+ }
+ else
{
- /* Check for a slash in the current position*/
- if ((*wc == L'\\') || (*wc == L'/'))
+ /* Check if there is a full path in this DLL */
+ wc = DllName->Buffer;
+ while (*wc)
{
- /* Found the slash, so dll name contains path */
- FullPath = TRUE;
-
- /* Setup full dll name string */
- FullDllName.Buffer = NameBuf;
-
- /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */
- Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
- DllName->Buffer,
- NULL,
- sizeof(NameBuf) - sizeof(UNICODE_NULL),
- FullDllName.Buffer,
- NULL);
-
- /* Check if that was successful */
- if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL))))
+ /* Check for a slash in the current position*/
+ if ((*wc == L'\\') || (*wc == L'/'))
{
- /* HACK: Try to find active context dll */
- Status = find_actctx_dll(DllName->Buffer, FullDllName.Buffer);
- if(Status == STATUS_SUCCESS)
- {
- Length = wcslen(FullDllName.Buffer) * sizeof(WCHAR);
- DPRINT1("found %S for %S\n", FullDllName.Buffer, DllName->Buffer);
- }
- else
- {
-
- if (ShowSnaps)
+ /* Found the slash, so dll name contains path */
+ FullPath = TRUE;
+
+ /* Setup full dll name string */
+ FullDllName.Buffer = NameBuf;
+
+ /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */
+ Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
+ DllName->Buffer,
+ NULL,
+ sizeof(NameBuf) - sizeof(UNICODE_NULL),
+ FullDllName.Buffer,
+ NULL);
+
+ /* Check if that was successful */
+ if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL))))
{
- DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
- &DllName, Length);
+ if (ShowSnaps)
+ {
+ DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
+ &DllName, Length);
+ }
}
- /* Return failure */
- return FALSE;
- }
+ /* Full dll name is found */
+ FullDllName.Length = Length;
+ FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
+ break;
}
- /* Full dll name is found */
- FullDllName.Length = Length;
- FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
- break;
+ wc++;
}
-
- wc++;
}
/* Go check the hash table */
}
/* FIXME: Warning, activation context missing */
+ DPRINT("Warning, activation context missing\n");
+
/* NOTE: From here on down, everything looks good */
/* Loop the module list */
ListEntry = ListEntry->Flink;
/* Check if it's being unloaded */
- if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
+ if (!CurEntry->InMemoryOrderLinks.Flink) continue;
/* Check if name matches */
if (RtlEqualUnicodeString(&FullDllName,
ListEntry = ListEntry->Flink;
/* Check if it's in the process of being unloaded */
- if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
+ if (!CurEntry->InMemoryOrderLinks.Flink) continue;
/* The header is untrusted, use SEH */
_SEH2_TRY
return STATUS_INVALID_PARAMETER;
}
- /* Set the orginal flag in the thunk */
+ /* Set the original flag in the thunk */
Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;
}
Entry = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
LdrEntry = CONTAINING_RECORD(Entry,
LDR_DATA_TABLE_ENTRY,
- InInitializationOrderModuleList);
+ InInitializationOrderLinks);
/* Make sure we didn't process it yet*/
if (!(LdrEntry->Flags & LDRP_ENTRY_PROCESSED))
/* Check for init flag and acquire lock */
if (!InInit) RtlEnterCriticalSection(&LdrpLoaderLock);
- /* Show debug message */
- if (ShowSnaps)
+ _SEH2_TRY
{
- DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
- &RawDllName,
- DllPath ? DllPath : L"");
- }
-
- /* Check if the DLL is already loaded */
- if (!LdrpCheckForLoadedDll(DllPath,
- &RawDllName,
- FALSE,
- Redirected,
- &LdrEntry))
- {
- /* Map it */
- Status = LdrpMapDll(DllPath,
- DllPath,
- NameBuffer,
- DllCharacteristics,
- FALSE,
- Redirected,
- &LdrEntry);
- if (!NT_SUCCESS(Status)) goto Quickie;
-
- /* FIXME: Need to mark the DLL range for the stack DB */
- //RtlpStkMarkDllRange(LdrEntry);
-
- /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
- if ((DllCharacteristics) &&
- (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
+ /* Show debug message */
+ if (ShowSnaps)
{
- /* This is not a DLL, so remove such data */
- LdrEntry->EntryPoint = NULL;
- LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
+ DPRINT1("LDR: LdrLoadDll, loading %wZ from %ws\n",
+ &RawDllName,
+ DllPath ? DllPath : L"");
}
- /* Make sure it's a DLL */
- if (LdrEntry->Flags & LDRP_IMAGE_DLL)
+ /* Check if the DLL is already loaded */
+ if (!LdrpCheckForLoadedDll(DllPath,
+ &RawDllName,
+ FALSE,
+ Redirected,
+ &LdrEntry))
{
- /* Check if this is a .NET Image */
- if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
- {
- /* Walk the Import Descriptor */
- Status = LdrpWalkImportDescriptor(DllPath, LdrEntry);
- }
+ /* Map it */
+ Status = LdrpMapDll(DllPath,
+ DllPath,
+ NameBuffer,
+ DllCharacteristics,
+ FALSE,
+ Redirected,
+ &LdrEntry);
+ if (!NT_SUCCESS(Status))
+ _SEH2_LEAVE;
- /* Update load count, unless it's locked */
- if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
- LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
+ /* FIXME: Need to mark the DLL range for the stack DB */
+ //RtlpStkMarkDllRange(LdrEntry);
- /* Check if we failed */
- if (!NT_SUCCESS(Status))
+ /* Check if IMAGE_FILE_EXECUTABLE_IMAGE was provided */
+ if ((DllCharacteristics) &&
+ (*DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
{
- /* Clear entrypoint, and insert into list */
+ /* This is not a DLL, so remove such data */
LdrEntry->EntryPoint = NULL;
- InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &LdrEntry->InInitializationOrderModuleList);
-
- /* Cancel the load */
- LdrpClearLoadInProgress();
+ LdrEntry->Flags &= ~LDRP_IMAGE_DLL;
+ }
- /* Unload the DLL */
- if (ShowSnaps)
+ /* Make sure it's a DLL */
+ if (LdrEntry->Flags & LDRP_IMAGE_DLL)
+ {
+ /* Check if this is a .NET Image */
+ if (!(LdrEntry->Flags & LDRP_COR_IMAGE))
{
- DbgPrint("LDR: Unloading %wZ due to error %x walking "
- "import descriptors",
- DllName,
- Status);
+ /* Walk the Import Descriptor */
+ Status = LdrpWalkImportDescriptor(DllPath, LdrEntry);
}
- LdrUnloadDll(LdrEntry->DllBase);
- /* Return the error */
- goto Quickie;
- }
- }
- else if (LdrEntry->LoadCount != 0xFFFF)
- {
- /* Increase load count */
- LdrEntry->LoadCount++;
- }
+ /* Update load count, unless it's locked */
+ if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
+ LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
- /* Insert it into the list */
- InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &LdrEntry->InInitializationOrderModuleList);
+ /* Check if we failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Clear entrypoint, and insert into list */
+ LdrEntry->EntryPoint = NULL;
+ InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
+ &LdrEntry->InInitializationOrderLinks);
- /* If we have to run the entrypoint, make sure the DB is ready */
- if (CallInit && LdrpLdrDatabaseIsSetup)
- {
- /* FIXME: Notify Shim Engine */
- if (g_ShimsEnabled)
+ /* Cancel the load */
+ LdrpClearLoadInProgress();
+
+ /* Unload the DLL */
+ if (ShowSnaps)
+ {
+ DbgPrint("LDR: Unloading %wZ due to error %x walking "
+ "import descriptors\n",
+ DllName,
+ Status);
+ }
+ LdrUnloadDll(LdrEntry->DllBase);
+
+ /* Return the error */
+ _SEH2_LEAVE;
+ }
+ }
+ else if (LdrEntry->LoadCount != 0xFFFF)
{
- /* Call it */
- //ShimLoadCallback = RtlDecodeSystemPointer(g_pfnSE_DllLoaded);
- //ShimLoadCallback(LdrEntry);
+ /* Increase load count */
+ LdrEntry->LoadCount++;
}
- /* Run the init routine */
- Status = LdrpRunInitializeRoutines(NULL);
- if (!NT_SUCCESS(Status))
+ /* Insert it into the list */
+ InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
+ &LdrEntry->InInitializationOrderLinks);
+
+ /* If we have to run the entrypoint, make sure the DB is ready */
+ if (CallInit && LdrpLdrDatabaseIsSetup)
{
- /* Failed, unload the DLL */
- if (ShowSnaps)
+ /* Notify Shim Engine */
+ if (g_ShimsEnabled)
{
- DbgPrint("LDR: Unloading %wZ because either its init "
- "routine or one of its static imports failed; "
- "status = 0x%08lx\n",
- DllName,
- Status);
+ VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded);
+ SE_DllLoaded(LdrEntry);
+ }
+
+ /* Run the init routine */
+ Status = LdrpRunInitializeRoutines(NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed, unload the DLL */
+ if (ShowSnaps)
+ {
+ DbgPrint("LDR: Unloading %wZ because either its init "
+ "routine or one of its static imports failed; "
+ "status = 0x%08lx\n",
+ DllName,
+ Status);
+ }
+ LdrUnloadDll(LdrEntry->DllBase);
}
- LdrUnloadDll(LdrEntry->DllBase);
+ }
+ else
+ {
+ /* The DB isn't ready, which means we were loaded because of a forwarder */
+ Status = STATUS_SUCCESS;
}
}
else
{
- /* The DB isn't ready, which means we were loaded because of a forwarder */
- Status = STATUS_SUCCESS;
+ /* We were already loaded. Are we a DLL? */
+ if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
+ {
+ /* Increase load count */
+ LdrEntry->LoadCount++;
+ LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
+
+ /* Clear the load in progress */
+ LdrpClearLoadInProgress();
+ }
+ else
+ {
+ /* Not a DLL, just increase the load count */
+ if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
+ }
}
+
}
- else
+ _SEH2_FINALLY
{
- /* We were already loaded. Are we a DLL? */
- if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
- {
- /* Increase load count */
- LdrEntry->LoadCount++;
- LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
-
- /* Clear the load in progress */
- LdrpClearLoadInProgress();
- }
- else
- {
- /* Not a DLL, just increase the load count */
- if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
- }
+ /* Release the lock */
+ if (!InInit) RtlLeaveCriticalSection(&LdrpLoaderLock);
}
-
-Quickie:
- /* Release the lock */
- if (!InInit) RtlLeaveCriticalSection(Peb->LoaderLock);
+ _SEH2_END;
/* Check for success */
if (NT_SUCCESS(Status))
/* Get the loader entry */
LdrEntry = CONTAINING_RECORD(Entry,
LDR_DATA_TABLE_ENTRY,
- InInitializationOrderModuleList);
+ InInitializationOrderLinks);
/* Clear load in progress flag */
LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
return ModulesCount;
}
+PVOID LdrpGetShimEngineFunction(PCSZ FunctionName)
+{
+ ANSI_STRING Function;
+ NTSTATUS Status;
+ PVOID Address;
+ RtlInitAnsiString(&Function, FunctionName);
+ /* Skip Dll init */
+ Status = LdrpGetProcedureAddress(g_pShimEngineModule, &Function, 0, &Address, FALSE);
+ return NT_SUCCESS(Status) ? Address : NULL;
+}
+
+VOID
+NTAPI
+LdrpGetShimEngineInterface()
+{
+ PVOID SE_DllLoaded = LdrpGetShimEngineFunction("SE_DllLoaded");
+ PVOID SE_DllUnloaded = LdrpGetShimEngineFunction("SE_DllUnloaded");
+ PVOID SE_InstallBeforeInit = LdrpGetShimEngineFunction("SE_InstallBeforeInit");
+ PVOID SE_InstallAfterInit = LdrpGetShimEngineFunction("SE_InstallAfterInit");
+ PVOID SE_ProcessDying = LdrpGetShimEngineFunction("SE_ProcessDying");
+
+ if (SE_DllLoaded && SE_DllUnloaded && SE_InstallBeforeInit && SE_InstallAfterInit && SE_ProcessDying)
+ {
+ g_pfnSE_DllLoaded = RtlEncodeSystemPointer(SE_DllLoaded);
+ g_pfnSE_DllUnloaded = RtlEncodeSystemPointer(SE_DllUnloaded);
+ g_pfnSE_InstallBeforeInit = RtlEncodeSystemPointer(SE_InstallBeforeInit);
+ g_pfnSE_InstallAfterInit = RtlEncodeSystemPointer(SE_InstallAfterInit);
+ g_pfnSE_ProcessDying = RtlEncodeSystemPointer(SE_ProcessDying);
+ g_ShimsEnabled = TRUE;
+ }
+ else
+ {
+ LdrpUnloadShimEngine();
+ }
+}
+
+VOID
+NTAPI
+LdrpRunShimEngineInitRoutine(IN ULONG Reason)
+{
+ PLIST_ENTRY ListHead, Next;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+
+ ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
+ Next = ListHead->Flink;
+ while (Next != ListHead)
+ {
+ LdrEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+
+ if (g_pShimEngineModule == LdrEntry->DllBase)
+ {
+ if (LdrEntry->EntryPoint)
+ {
+ _SEH2_TRY
+ {
+ LdrpCallInitRoutine(LdrEntry->EntryPoint, LdrEntry->DllBase, Reason, NULL);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("WARNING: Exception 0x%x during LdrpRunShimEngineInitRoutine(%u)\n",
+ _SEH2_GetExceptionCode(), Reason);
+ }
+ _SEH2_END;
+ }
+ return;
+ }
+
+ Next = Next->Flink;
+ }
+}
+
+VOID
+NTAPI
+LdrpLoadShimEngine(IN PWSTR ImageName, IN PUNICODE_STRING ProcessImage, IN PVOID pShimData)
+{
+ UNICODE_STRING ShimLibraryName;
+ PVOID ShimLibrary;
+ NTSTATUS Status;
+ RtlInitUnicodeString(&ShimLibraryName, ImageName);
+ /* We should NOT pass CallInit = TRUE!
+ If we do this, other init routines will be called before we get a chance to shim stuff.. */
+ Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ g_pShimEngineModule = ShimLibrary;
+ LdrpRunShimEngineInitRoutine(DLL_PROCESS_ATTACH);
+ LdrpGetShimEngineInterface();
+ if (g_ShimsEnabled)
+ {
+ VOID(NTAPI *SE_InstallBeforeInit)(PUNICODE_STRING, PVOID);
+ SE_InstallBeforeInit = RtlDecodeSystemPointer(g_pfnSE_InstallBeforeInit);
+ SE_InstallBeforeInit(ProcessImage, pShimData);
+ }
+ }
+}
+
+VOID
+NTAPI
+LdrpUnloadShimEngine()
+{
+ /* Make sure we do not call into the shim engine anymore */
+ g_ShimsEnabled = FALSE;
+ LdrpRunShimEngineInitRoutine(DLL_PROCESS_DETACH);
+ LdrUnloadDll(g_pShimEngineModule);
+ g_pShimEngineModule = NULL;
+}
+
/* EOF */