}
/* 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 = 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 */
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;
}
ULONG BufSize = 500;
/* 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,
DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
}
- RtlFreeUnicodeString(FullDllName);
+ LdrpFreeUnicodeString(FullDllName);
return FALSE;
}
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;
if (!NT_SUCCESS(Status))
{
/* Free the name strings and return */
- RtlFreeUnicodeString(&FullDllName);
- RtlFreeUnicodeString(&BaseDllName);
+ LdrpFreeUnicodeString(&FullDllName);
+ LdrpFreeUnicodeString(&BaseDllName);
return Status;
}
}
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 -> %p)\n", DllName, (PVOID)ImageBase, (PVOID)ImageEnd, 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;
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)
if (NtHeader)
{
/* Allocate an entry */
- LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ LdrEntry = RtlAllocateHeap(LdrpHeap,
HEAP_ZERO_MEMORY,
sizeof(LDR_DATA_TABLE_ENTRY));
if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
/* Finally free the entry's memory */
- RtlFreeHeap(RtlGetProcessHeap(), 0, Entry);
+ RtlFreeHeap(LdrpHeap, 0, Entry);
}
BOOLEAN
/* FIXME: Setup TestName here */
Status = STATUS_NOT_FOUND;
+ BufEnd = Buffer;
/* Start loop */
do
/* 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->InInitializationOrderLinks);
-
- /* 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\n",
- 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);
+
+ /* Check if we failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Clear entrypoint, and insert into list */
+ LdrEntry->EntryPoint = NULL;
+ InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
+ &LdrEntry->InInitializationOrderLinks);
- /* Insert it into the list */
- InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &LdrEntry->InInitializationOrderLinks);
+ /* Cancel the load */
+ LdrpClearLoadInProgress();
- /* If we have to run the entrypoint, make sure the DB is ready */
- if (CallInit && LdrpLdrDatabaseIsSetup)
- {
- /* Notify Shim Engine */
- if (g_ShimsEnabled)
+ /* 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)
{
- VOID (NTAPI* SE_DllLoaded)(PLDR_DATA_TABLE_ENTRY) = RtlDecodeSystemPointer(g_pfnSE_DllLoaded);
- SE_DllLoaded(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);
}
- LdrUnloadDll(LdrEntry->DllBase);
+
+ /* 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);
+ }
+ }
+ 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(&LdrpLoaderLock);
+ _SEH2_END;
/* Check for success */
if (NT_SUCCESS(Status))
NTSTATUS Status;
PVOID Address;
RtlInitAnsiString(&Function, FunctionName);
- Status = LdrGetProcedureAddress(g_pShimEngineModule, &Function, 0, &Address);
+ /* Skip Dll init */
+ Status = LdrpGetProcedureAddress(g_pShimEngineModule, &Function, 0, &Address, FALSE);
return NT_SUCCESS(Status) ? Address : NULL;
}
}
}
+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
PVOID ShimLibrary;
NTSTATUS Status;
RtlInitUnicodeString(&ShimLibraryName, ImageName);
- Status = LdrpLoadDll(FALSE, NULL, NULL, &ShimLibraryName, &ShimLibrary, TRUE);
+ /* 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)
{
{
/* Make sure we do not call into the shim engine anymore */
g_ShimsEnabled = FALSE;
+ LdrpRunShimEngineInitRoutine(DLL_PROCESS_DETACH);
LdrUnloadDll(g_pShimEngineModule);
g_pShimEngineModule = NULL;
}