-/* $Id: utils.c,v 1.80 2004/01/25 08:32:49 navaraf Exp $
+/* $Id: utils.c,v 1.102 2004/12/15 03:00:33 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module, BOOL Ref);
static PVOID LdrFixupForward(PCHAR ForwardName);
static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint);
-static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
- IN ULONG LoadFlags,
- IN PUNICODE_STRING Name,
- OUT PLDR_MODULE *Module);
+static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
+ IN ULONG LoadFlags,
+ IN PUNICODE_STRING Name,
+ OUT PLDR_MODULE *Module);
static NTSTATUS LdrpAttachProcess(VOID);
static VOID LdrpDetachProcess(BOOL UnloadAll);
/* FUNCTIONS *****************************************************************/
-#ifdef KDBG
+#if defined(DBG) || defined(KDBG)
VOID
LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
NULL);
}
-#endif /* DBG */
+#endif /* DBG || KDBG */
static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
{
{
while (*TlsCallback)
{
- TRACE_LDR("%wZ - Calling tls callback at %x\n",
- &Module->BaseDllName, TlsCallback);
- TlsCallback(Module->BaseAddress, dwReason, NULL);
- TlsCallback++;
- }
- }
+ TRACE_LDR("%wZ - Calling tls callback at %x\n",
+ &Module->BaseDllName, TlsCallback);
+ TlsCallback(Module->BaseAddress, dwReason, NULL);
+ TlsCallback++;
+ }
+ }
}
}
{
TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(),
0,
- LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize);
+ LdrpTlsCount * sizeof(PVOID) + LdrpTlsSize);
if (TlsPointers == NULL)
{
- DPRINT1("failed to allocate thread tls data\n");
- return STATUS_NO_MEMORY;
- }
-
+ DPRINT1("failed to allocate thread tls data\n");
+ return STATUS_NO_MEMORY;
+ }
+
TlsData = (PVOID)TlsPointers + LdrpTlsCount * sizeof(PVOID);
NtCurrentTeb()->ThreadLocalStoragePointer = TlsPointers;
TlsInfo = LdrpTlsArray;
for (i = 0; i < LdrpTlsCount; i++, TlsInfo++)
{
- TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName);
- TlsPointers[i] = TlsData;
- if (TlsInfo->TlsDataSize)
- {
- memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
- TlsData += TlsInfo->TlsDataSize;
- }
- if (TlsInfo->TlsZeroSize)
- {
- memset(TlsData, 0, TlsInfo->TlsZeroSize);
- TlsData += TlsInfo->TlsZeroSize;
- }
- }
+ TRACE_LDR("Initialize tls data for %wZ\n", &TlsInfo->Module->BaseDllName);
+ TlsPointers[i] = TlsData;
+ if (TlsInfo->TlsDataSize)
+ {
+ memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
+ TlsData += TlsInfo->TlsDataSize;
+ }
+ if (TlsInfo->TlsZeroSize)
+ {
+ memset(TlsData, 0, TlsInfo->TlsZeroSize);
+ TlsData += TlsInfo->TlsZeroSize;
+ }
+ }
}
DPRINT("LdrpInitializeTlsForThread() done\n");
return STATUS_SUCCESS;
PTLS_DATA TlsData;
DPRINT("LdrpInitializeTlsForProccess() called for %wZ\n", &ExeModule->BaseDllName);
-
+
if (LdrpTlsCount > 0)
{
LdrpTlsArray = RtlAllocateHeap(RtlGetProcessHeap(),
0,
- LdrpTlsCount * sizeof(TLS_DATA));
+ LdrpTlsCount * sizeof(TLS_DATA));
if (LdrpTlsArray == NULL)
{
- DPRINT1("Failed to allocate global tls data\n");
+ DPRINT1("Failed to allocate global tls data\n");
return STATUS_NO_MEMORY;
}
-
+
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
- if (Module->LoadCount == -1 &&
- Module->TlsIndex >= 0)
+ if (Module->LoadCount == -1 &&
+ Module->TlsIndex >= 0)
{
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_TLS,
NULL);
assert(Module->TlsIndex < LdrpTlsCount);
- TlsData = &LdrpTlsArray[Module->TlsIndex];
- TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
- TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
- TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
- TlsData->TlsAddressOfCallBacks = *TlsDirectory->AddressOfCallBacks;
- TlsData->Module = Module;
+ TlsData = &LdrpTlsArray[Module->TlsIndex];
+ TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
+ TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
+ TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
+ if (TlsDirectory->AddressOfCallBacks)
+ TlsData->TlsAddressOfCallBacks = *TlsDirectory->AddressOfCallBacks;
+ else
+ TlsData->TlsAddressOfCallBacks = NULL;
+ TlsData->Module = Module;
#if 0
DbgPrint("TLS directory for %wZ\n", &Module->BaseDllName);
- DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData);
- DbgPrint("EndAddressOfRawData: %x\n", TlsDirectory->EndAddressOfRawData);
- DbgPrint("SizeOfRawData: %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData);
- DbgPrint("AddressOfIndex: %x\n", TlsDirectory->AddressOfIndex);
- DbgPrint("AddressOfCallBacks: %x (%x)\n", TlsDirectory->AddressOfCallBacks, *TlsDirectory->AddressOfCallBacks);
- DbgPrint("SizeOfZeroFill: %d\n", TlsDirectory->SizeOfZeroFill);
- DbgPrint("Characteristics: %x\n", TlsDirectory->Characteristics);
+ DbgPrint("StartAddressOfRawData: %x\n", TlsDirectory->StartAddressOfRawData);
+ DbgPrint("EndAddressOfRawData: %x\n", TlsDirectory->EndAddressOfRawData);
+ DbgPrint("SizeOfRawData: %d\n", TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData);
+ DbgPrint("AddressOfIndex: %x\n", TlsDirectory->AddressOfIndex);
+ DbgPrint("AddressOfCallBacks: %x (%x)\n", TlsDirectory->AddressOfCallBacks, *TlsDirectory->AddressOfCallBacks);
+ DbgPrint("SizeOfZeroFill: %d\n", TlsDirectory->SizeOfZeroFill);
+ DbgPrint("Characteristics: %x\n", TlsDirectory->Characteristics);
#endif
- /*
- * FIXME:
- * Is this region allways writable ?
- */
+ /*
+ * FIXME:
+ * Is this region allways writable ?
+ */
*(PULONG)TlsDirectory->AddressOfIndex = Module->TlsIndex;
- CHECKPOINT1;
- }
- Entry = Entry->Flink;
- }
+ CHECKPOINT1;
+ }
+ Entry = Entry->Flink;
+ }
}
DPRINT("LdrpInitializeTlsForProccess() done\n");
return STATUS_SUCCESS;
/* Get handle to the 'KnownDlls' directory */
RtlInitUnicodeString(&Name,
- L"\\KnownDlls");
+ L"\\KnownDlls");
InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
Status = NtOpenDirectoryObject(&LdrpKnownDllsDirHandle,
- DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
- &ObjectAttributes);
+ DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
+ &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
LinkTarget.Length = 0;
LinkTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
LinkTarget.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- MAX_PATH * sizeof(WCHAR));
+ 0,
+ MAX_PATH * sizeof(WCHAR));
if (LinkTarget.Buffer == NULL)
{
NtClose(LdrpKnownDllsDirHandle);
}
RtlInitUnicodeString(&Name,
- L"KnownDllPath");
+ L"KnownDllPath");
InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
- LdrpKnownDllsDirHandle,
- NULL);
+ &Name,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
+ LdrpKnownDllsDirHandle,
+ NULL);
Status = NtOpenSymbolicLinkObject(&LinkHandle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&LinkTarget);
}
Status = NtQuerySymbolicLinkObject(LinkHandle,
- &LinkTarget,
- &Length);
+ &LinkTarget,
+ &Length);
NtClose(LinkHandle);
if (!NT_SUCCESS(Status))
{
}
RtlCreateUnicodeString(&LdrpKnownDllPath,
- LinkTarget.Buffer);
+ LinkTarget.Buffer);
RtlFreeUnicodeString(&LinkTarget);
PLDR_MODULE
LdrAddModuleEntry(PVOID ImageBase,
- PIMAGE_NT_HEADERS NTHeaders,
- PWSTR FullDosName)
+ PIMAGE_NT_HEADERS NTHeaders,
+ PWSTR FullDosName)
{
PLDR_MODULE Module;
RtlCreateUnicodeString (&Module->BaseDllName,
wcsrchr(FullDosName, L'\\') + 1);
DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
-
+
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
&Module->InLoadOrderModuleList);
static NTSTATUS
LdrpMapKnownDll(IN PUNICODE_STRING DllName,
- OUT PUNICODE_STRING FullDosName,
- OUT PHANDLE SectionHandle)
+ OUT PUNICODE_STRING FullDosName,
+ OUT PHANDLE SectionHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
DPRINT("LdrpKnownDllPath '%wZ'\n", &LdrpKnownDllPath);
InitializeObjectAttributes(&ObjectAttributes,
- DllName,
- OBJ_CASE_INSENSITIVE,
- LdrpKnownDllsDirHandle,
- NULL);
+ DllName,
+ OBJ_CASE_INSENSITIVE,
+ LdrpKnownDllsDirHandle,
+ NULL);
Status = NtOpenSection(SectionHandle,
- SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
- &ObjectAttributes);
+ SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
+ &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenSection() failed for '%wZ' (Status %lx)\n", DllName, Status);
FullDosName->Length = LdrpKnownDllPath.Length + DllName->Length + sizeof(WCHAR);
FullDosName->MaximumLength = FullDosName->Length + sizeof(WCHAR);
FullDosName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- FullDosName->MaximumLength);
+ 0,
+ FullDosName->MaximumLength);
if (FullDosName->Buffer == NULL)
{
FullDosName->Length = 0;
static NTSTATUS
LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
- IN PUNICODE_STRING DllName,
- OUT PUNICODE_STRING FullDosName,
- OUT PHANDLE SectionHandle)
+ IN PUNICODE_STRING DllName,
+ OUT PUNICODE_STRING FullDosName,
+ OUT PHANDLE SectionHandle)
{
WCHAR SearchPathBuffer[MAX_PATH];
WCHAR DosName[MAX_PATH];
PVOID ImageBase;
ULONG ImageSize;
IO_STATUS_BLOCK IoStatusBlock;
- NTSTATUS Status;
+ NTSTATUS Status;
+ ULONG len;
DPRINT("LdrpMapDllImageFile() called\n");
if (SearchPath == NULL)
{
- SearchPath = SearchPathBuffer;
- wcscpy (SearchPathBuffer, SharedUserData->NtSystemRoot);
+ /* get application running path */
+
+ wcscpy (SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
+
+ len = wcslen (SearchPathBuffer);
+
+ while (len && SearchPathBuffer[len - 1] != L'\\')
+ len--;
+
+ if (len) SearchPathBuffer[len-1] = L'\0';
+
+ wcscat (SearchPathBuffer, L";");
+
+ wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
wcscat (SearchPathBuffer, L"\\system32;");
wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
wcscat (SearchPathBuffer, L";.");
- }
- DPRINT("SearchPath %S\n", SearchPath);
+ SearchPath = SearchPathBuffer;
+ }
if (RtlDosSearchPath_U (SearchPath,
DllName->Buffer,
NULL) == 0)
return STATUS_DLL_NOT_FOUND;
- DPRINT("DosName %S\n", DosName);
if (!RtlDosPathNameToNtPathName_U (DosName,
&FullNtFileName,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
- DbgPrint("Dll open of %wZ failed: Status = 0x%08x\n",
+ DPRINT1("Dll open of %wZ failed: Status = 0x%08x\n",
&FullNtFileName, Status);
RtlFreeUnicodeString (&FullNtFileName);
return Status;
return Status;
}
/*
- * Overlay DOS and NT headers structures to the
+ * Overlay DOS and NT headers structures to the
* buffer with DLL's header raw data.
*/
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
{
DPRINT("NTDLL format invalid\n");
NtClose(FileHandle);
-
+
return STATUS_UNSUCCESSFUL;
}
-
+
ImageBase = (PVOID) NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
-
+
DPRINT("ImageBase 0x%08x\n", ImageBase);
-
+
/*
* Create a section for dll.
*/
}
RtlCreateUnicodeString(FullDosName,
- DosName);
+ DosName);
return Status;
}
NTSTATUS Status;
PLDR_MODULE Module;
- TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n", Name, SearchPath ? " from " : "", SearchPath ? SearchPath : L"");
+ TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
+ Name,
+ SearchPath ? " from " : "",
+ SearchPath ? SearchPath : L"");
if (Name == NULL)
{
(Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage)))
{
*Module = ModulePtr;
- RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
+ RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
return(STATUS_SUCCESS);
}
static NTSTATUS
LdrFindEntryForName(PUNICODE_STRING Name,
PLDR_MODULE *Module,
- BOOL Ref)
+ BOOL Ref)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
ContainsPath = L'\\' == AdjustedName.Buffer[i] ||
L'/' == AdjustedName.Buffer[i];
}
-
+
if (LdrpLastModule)
{
if ((! ContainsPath &&
0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule;
- if (Ref && (*Module)->LoadCount != -1)
- {
+ if (Ref && (*Module)->LoadCount != -1)
+ {
(*Module)->LoadCount++;
- }
+ }
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
- RtlFreeUnicodeString(&AdjustedName);
+ RtlFreeUnicodeString(&AdjustedName);
return(STATUS_SUCCESS);
}
}
0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule = ModulePtr;
- if (Ref && ModulePtr->LoadCount != -1)
- {
+ if (Ref && ModulePtr->LoadCount != -1)
+ {
ModulePtr->LoadCount++;
}
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
- RtlFreeUnicodeString(&AdjustedName);
+ RtlFreeUnicodeString(&AdjustedName);
return(STATUS_SUCCESS);
}
NameBuffer);
Status = LdrFindEntryForName (&DllName, &Module, FALSE);
- /* FIXME:
- * The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
+ /* FIXME:
+ * The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
*/
if (!NT_SUCCESS(Status))
{
LDRP_PROCESS_CREATION_TIME,
&DllName,
&BaseAddress);
- if (NT_SUCCESS(Status))
- {
- Status = LdrFindEntryForName (&DllName, &Module, FALSE);
- }
- }
+ if (NT_SUCCESS(Status))
+ {
+ Status = LdrFindEntryForName (&DllName, &Module, FALSE);
+ }
+ }
RtlFreeUnicodeString (&DllName);
if (!NT_SUCCESS(Status))
{
}
DPRINT("BaseAddress: %p\n", Module->BaseAddress);
-
+
return LdrGetExportByName(Module->BaseAddress, p+1, -1);
}
/**********************************************************************
* NAME LOCAL
* LdrGetExportByOrdinal
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
*/
static PVOID
LdrGetExportByOrdinal (
- PVOID BaseAddress,
+ PVOID BaseAddress,
ULONG Ordinal
)
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
ULONG ExportDirSize;
PDWORD * ExFunctions;
- USHORT * ExOrdinals;
PVOID Function;
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
&ExportDirSize);
- ExOrdinals = (USHORT *)
- RVA(
- BaseAddress,
- ExportDir->AddressOfNameOrdinals
- );
ExFunctions = (PDWORD *)
RVA(
BaseAddress,
ExportDir->AddressOfFunctions
);
- DbgPrint(
+ DPRINT(
"LdrGetExportByOrdinal(Ordinal %d) = %x\n",
Ordinal,
RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
);
- Function = RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] );
+ Function = (0 != ExFunctions[Ordinal - ExportDir->Base]
+ ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
+ : NULL);
if (((ULONG)Function >= (ULONG)ExportDir) &&
((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
/**********************************************************************
* NAME LOCAL
* LdrGetExportByName
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
* REVISIONS
*
* NOTE
- * AddressOfNames and AddressOfNameOrdinals are paralell tables,
+ * AddressOfNames and AddressOfNameOrdinals are paralell tables,
* both with NumberOfNames entries.
*
*/
PVOID Function;
LONG minn, maxn;
ULONG ExportDirSize;
-
+
DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
&ExportDirSize);
if (ExportDir == NULL)
{
- DbgPrint("LdrGetExportByName(): no export directory!\n");
+ DPRINT1("LdrGetExportByName(): no export directory!\n");
return NULL;
}
//The symbol names may be missing entirely
if (ExportDir->AddressOfNames == 0)
{
- DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
+ DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
return NULL;
}
ExportDir->AddressOfNameOrdinals);
ExFunctions = (PDWORD *)RVA(BaseAddress,
ExportDir->AddressOfFunctions);
-
+
/*
* Check the hint first
*/
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
- if (Function == NULL)
- {
+ if (Function == NULL)
+ {
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
- }
- return Function;
+ }
+ return Function;
}
if (Function != NULL)
return Function;
}
}
-
+
/*
* Try a binary search first
*/
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
- if (Function == NULL)
- {
+ if (Function == NULL)
+ {
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
- }
- return Function;
+ }
+ return Function;
}
if (Function != NULL)
return Function;
minn = mid + 1;
}
}
-
+
/*
* Fall back on a linear search
*/
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
- }
- if (Function == NULL)
- {
- break;
- }
- return Function;
+ }
+ if (Function == NULL)
+ {
+ break;
+ }
+ return Function;
}
}
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
/**********************************************************************
* NAME LOCAL
* LdrPerformRelocations
- *
+ *
* DESCRIPTION
* Relocate a DLL's memory image.
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* NOTE
*
*/
-static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
- PVOID ImageBase)
+static NTSTATUS
+LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
+ PVOID ImageBase)
{
- USHORT NumberOfEntries;
- PUSHORT pValue16;
- ULONG RelocationRVA;
- ULONG Delta32;
- ULONG Offset;
- PULONG pValue32;
- PRELOCATION_DIRECTORY RelocationDir;
- PRELOCATION_ENTRY RelocationBlock;
- int i;
PIMAGE_DATA_DIRECTORY RelocationDDir;
- ULONG OldProtect;
- ULONG OldProtect2;
+ PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+ ULONG Count, ProtectSize, OldProtect, OldProtect2;
+ PVOID Page, ProtectPage, ProtectPage2;
+ PUSHORT TypeOffset;
+ ULONG_PTR Delta;
NTSTATUS Status;
- PIMAGE_SECTION_HEADER Sections;
- ULONG MaxExtend;
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
{
return STATUS_UNSUCCESSFUL;
}
- Sections =
- (PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS));
- MaxExtend = 0;
- for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
- {
- if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD))
- {
- ULONG Extend;
- Extend =
- (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize);
- MaxExtend = max(MaxExtend, Extend);
- }
- }
-
- RelocationDDir =
+ RelocationDDir =
&NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- RelocationRVA = RelocationDDir->VirtualAddress;
- if (RelocationRVA)
+ if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
{
- RelocationDir =
- (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA);
+ return STATUS_SUCCESS;
+ }
- while (RelocationDir->SizeOfBlock)
- {
- if (RelocationDir->VirtualAddress > MaxExtend)
- {
- RelocationRVA += RelocationDir->SizeOfBlock;
- RelocationDir =
- (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
- continue;
- }
+ ProtectSize = PAGE_SIZE;
+ Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase;
+ RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+ RelocationDDir->VirtualAddress);
+ RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+ RelocationDDir->VirtualAddress + RelocationDDir->Size);
- Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase);
- RelocationBlock =
- (PRELOCATION_ENTRY) (RelocationRVA + ImageBase +
- sizeof (RELOCATION_DIRECTORY));
- NumberOfEntries =
- RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY);
- NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY);
+ while (RelocationDir < RelocationEnd &&
+ RelocationDir->SizeOfBlock > 0)
+ {
+ Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
+ sizeof(USHORT);
+ Page = ImageBase + RelocationDir->VirtualAddress;
+ TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+ /* Unprotect the page(s) we're about to relocate. */
+ ProtectPage = Page;
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ PAGE_READWRITE,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unprotect relocation target.\n");
+ return Status;
+ }
+ if (RelocationDir->VirtualAddress + PAGE_SIZE <
+ NTHeaders->OptionalHeader.SizeOfImage)
+ {
+ ProtectPage2 = ProtectPage + PAGE_SIZE;
Status = NtProtectVirtualMemory(NtCurrentProcess(),
- ImageBase +
- RelocationDir->VirtualAddress,
- PAGE_SIZE,
+ &ProtectPage2,
+ &ProtectSize,
PAGE_READWRITE,
- &OldProtect);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect relocation target.\n");
- return(Status);
- }
-
- if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
- {
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- ImageBase +
- RelocationDir->VirtualAddress + PAGE_SIZE,
- PAGE_SIZE,
- PAGE_READWRITE,
- &OldProtect2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect relocation target (2).\n");
- NtProtectVirtualMemory(NtCurrentProcess(),
- ImageBase +
- RelocationDir->VirtualAddress,
- PAGE_SIZE,
- OldProtect,
- &OldProtect);
- return(Status);
- }
- }
-
- for (i = 0; i < NumberOfEntries; i++)
- {
- Offset = (RelocationBlock[i].TypeOffset & 0xfff);
- Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase);
-
- /*
- * What kind of relocations should we perform
- * for the current entry?
- */
- switch (RelocationBlock[i].TypeOffset >> 12)
- {
- case TYPE_RELOC_ABSOLUTE:
- break;
-
- case TYPE_RELOC_HIGH:
- pValue16 = (PUSHORT)Offset;
- *pValue16 += Delta32 >> 16;
- break;
-
- case TYPE_RELOC_LOW:
- pValue16 = (PUSHORT)Offset;
- *pValue16 += Delta32 & 0xffff;
- break;
-
- case TYPE_RELOC_HIGHLOW:
- pValue32 = (PULONG)Offset;
- *pValue32 += Delta32;
- break;
-
- case TYPE_RELOC_HIGHADJ:
- /* FIXME: do the highadjust fixup */
- DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
- return(STATUS_UNSUCCESSFUL);
-
- default:
- DPRINT("unexpected fixup type\n");
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- ImageBase +
- RelocationDir->VirtualAddress,
- PAGE_SIZE,
- OldProtect,
- &OldProtect);
+ &OldProtect2);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to protect relocation target.\n");
- return(Status);
- }
-
- if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
- {
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- ImageBase +
- RelocationDir->VirtualAddress + PAGE_SIZE,
- PAGE_SIZE,
- OldProtect2,
- &OldProtect2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to protect relocation target2.\n");
- return(Status);
- }
+ DPRINT1("Failed to unprotect relocation target (2).\n");
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ OldProtect,
+ &OldProtect);
+ return Status;
}
+ }
+ else
+ {
+ ProtectPage2 = NULL;
+ }
- RelocationRVA += RelocationDir->SizeOfBlock;
- RelocationDir =
- (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
+ RelocationDir = LdrProcessRelocationBlock(Page,
+ Count,
+ TypeOffset,
+ Delta);
+ if (RelocationDir == NULL)
+ return STATUS_UNSUCCESSFUL;
+
+ /* Restore old page protection. */
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ OldProtect,
+ &OldProtect);
+
+ if (ProtectPage2 != NULL)
+ {
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage2,
+ &ProtectSize,
+ OldProtect2,
+ &OldProtect2);
}
}
+
return STATUS_SUCCESS;
}
-
-static NTSTATUS
+
+static NTSTATUS
LdrpGetOrLoadModule(PWCHAR SerachPath,
- PCHAR Name,
- PLDR_MODULE* Module,
- BOOL Load)
+ PCHAR Name,
+ PLDR_MODULE* Module,
+ BOOL Load)
{
UNICODE_STRING DllName;
NTSTATUS Status;
DPRINT("LdrpGetOrLoadModule() called for %s\n", Name);
RtlCreateUnicodeStringFromAsciiz (&DllName, Name);
-
+
Status = LdrFindEntryForName (&DllName, Module, Load);
if (Load && !NT_SUCCESS(Status))
{
- Status = LdrpLoadModule(SerachPath,
- NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME,
- &DllName,
- Module);
+ Status = LdrpLoadModule(SerachPath,
+ NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME,
+ &DllName,
+ Module);
if (NT_SUCCESS(Status))
{
- Status = LdrFindEntryForName (&DllName, Module, FALSE);
- }
+ Status = LdrFindEntryForName (&DllName, Module, FALSE);
+ }
if (!NT_SUCCESS(Status))
{
DPRINT1("failed to load %wZ\n", &DllName);
}
static NTSTATUS
-LdrpProcessImportDirectory(PLDR_MODULE Module,
- PLDR_MODULE ImportedModule,
- PCHAR ImportedName)
+LdrpProcessImportDirectoryEntry(PLDR_MODULE Module,
+ PLDR_MODULE ImportedModule,
+ PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory)
{
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
NTSTATUS Status;
PVOID* ImportAddressList;
PULONG FunctionNameList;
- DWORD pName;
- WORD pHint;
PVOID IATBase;
ULONG OldProtect;
ULONG Ordinal;
ULONG IATSize;
- PCHAR Name;
-
- DPRINT("LdrpProcessImportDirectory(%x '%wZ', %x '%wZ', %x '%s')\n",
- Module, &Module->BaseDllName, ImportedModule,
- &ImportedModule->BaseDllName, ImportedName, ImportedName);
- ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
- if (ImportModuleDirectory == NULL)
+ if (ImportModuleDirectory == NULL || ImportModuleDirectory->dwRVAModuleName == 0)
{
return STATUS_UNSUCCESSFUL;
}
- while (ImportModuleDirectory->dwRVAModuleName)
+ /* Get the import address list. */
+ ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+
+ /* Get the list of functions to import. */
+ if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
{
- Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
- if (0 == _stricmp(Name, ImportedName))
- {
+ FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+ }
+ else
+ {
+ FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ }
- /* Get the import address list. */
- ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ /* Get the size of IAT. */
+ IATSize = 0;
+ while (FunctionNameList[IATSize] != 0L)
+ {
+ IATSize++;
+ }
- /* Get the list of functions to import. */
- if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
+ /* Unprotect the region we are about to write into. */
+ IATBase = (PVOID)ImportAddressList;
+ IATSize *= sizeof(PVOID*);
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &IATBase,
+ &IATSize,
+ PAGE_READWRITE,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unprotect IAT.\n");
+ return(Status);
+ }
+
+ /* Walk through function list and fixup addresses. */
+ while (*FunctionNameList != 0L)
+ {
+ if ((*FunctionNameList) & 0x80000000)
+ {
+ Ordinal = (*FunctionNameList) & 0x7fffffff;
+ *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->BaseAddress, Ordinal);
+ if ((*ImportAddressList) == NULL)
{
- FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+ DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
+ return STATUS_UNSUCCESSFUL;
}
- else
+ }
+ else
+ {
+ IMAGE_IMPORT_BY_NAME *pe_name;
+ pe_name = RVA(Module->BaseAddress, *FunctionNameList);
+ *ImportAddressList = LdrGetExportByName(ImportedModule->BaseAddress, pe_name->Name, pe_name->Hint);
+ if ((*ImportAddressList) == NULL)
{
- FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
+ return STATUS_UNSUCCESSFUL;
}
+ }
+ ImportAddressList++;
+ FunctionNameList++;
+ }
- /* Get the size of IAT. */
- IATSize = 0;
- while (FunctionNameList[IATSize] != 0L)
- {
- IATSize++;
- }
+ /* Protect the region we are about to write into. */
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &IATBase,
+ &IATSize,
+ OldProtect,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to protect IAT.\n");
+ return(Status);
+ }
- /* Unprotect the region we are about to write into. */
- IATBase = (PVOID)ImportAddressList;
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- IATBase,
- IATSize * sizeof(PVOID*),
- PAGE_READWRITE,
- &OldProtect);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect IAT.\n");
- return(Status);
- }
-
- /* Walk through function list and fixup addresses. */
-
- while (*FunctionNameList != 0L)
- {
- if ((*FunctionNameList) & 0x80000000)
- {
- Ordinal = (*FunctionNameList) & 0x7fffffff;
- *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->BaseAddress, Ordinal);
- }
- else
- {
- pName = (DWORD) (Module->BaseAddress + *FunctionNameList + 2);
- pHint = *(PWORD)(Module->BaseAddress + *FunctionNameList);
+ return STATUS_SUCCESS;
+}
- *ImportAddressList = LdrGetExportByName(ImportedModule->BaseAddress, (PUCHAR)pName, pHint);
- if ((*ImportAddressList) == NULL)
- {
- DPRINT1("Failed to import %s\n", pName);
- return STATUS_UNSUCCESSFUL;
- }
- }
- ImportAddressList++;
- FunctionNameList++;
- }
+static NTSTATUS
+LdrpProcessImportDirectory(
+ PLDR_MODULE Module,
+ PLDR_MODULE ImportedModule,
+ PCHAR ImportedName)
+{
+ NTSTATUS Status;
+ PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+ PCHAR Name;
- /* Protect the region we are about to write into. */
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- IATBase,
- IATSize * sizeof(PVOID*),
- OldProtect,
- &OldProtect);
+ DPRINT("LdrpProcessImportDirectory(%x '%wZ', '%s')\n",
+ Module, &Module->BaseDllName, ImportedName);
+
+
+ ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ NULL);
+ if (ImportModuleDirectory == NULL)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ while (ImportModuleDirectory->dwRVAModuleName)
+ {
+ Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
+ if (0 == _stricmp(Name, ImportedName))
+ {
+ Status = LdrpProcessImportDirectoryEntry(Module,
+ ImportedModule,
+ ImportModuleDirectory);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to protect IAT.\n");
- return(Status);
+ return Status;
}
- }
+ }
ImportModuleDirectory++;
}
+
return STATUS_SUCCESS;
}
-NTSTATUS LdrpAdjustImportDirectory(PLDR_MODULE Module,
- PLDR_MODULE ImportedModule,
- PUCHAR ImportedName)
+
+static NTSTATUS
+LdrpAdjustImportDirectory(PLDR_MODULE Module,
+ PLDR_MODULE ImportedModule,
+ PUCHAR ImportedName)
{
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
NTSTATUS Status;
Module, &Module->BaseDllName, ImportedModule, &ImportedModule->BaseDllName, ImportedName);
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ NULL);
if (ImportModuleDirectory == NULL)
{
return STATUS_UNSUCCESSFUL;
IATSize++;
}
- /* Unprotect the region we are about to write into. */
- IATBase = (PVOID)ImportAddressList;
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- IATBase,
- IATSize * sizeof(PVOID*),
- PAGE_READWRITE,
- &OldProtect);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect IAT.\n");
- return(Status);
- }
-
- NTHeaders = RtlImageNtHeader (ImportedModule->BaseAddress);
- Start = (PVOID)NTHeaders->OptionalHeader.ImageBase;
- End = Start + ImportedModule->SizeOfImage;
- Offset = ImportedModule->BaseAddress - Start;
-
- /* Walk through function list and fixup addresses. */
- while (*FunctionNameList != 0L)
- {
- if (*ImportAddressList >= Start && *ImportAddressList < End)
+ /* Unprotect the region we are about to write into. */
+ IATBase = (PVOID)ImportAddressList;
+ IATSize *= sizeof(PVOID*);
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &IATBase,
+ &IATSize,
+ PAGE_READWRITE,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unprotect IAT.\n");
+ return(Status);
+ }
+
+ NTHeaders = RtlImageNtHeader (ImportedModule->BaseAddress);
+ Start = (PVOID)NTHeaders->OptionalHeader.ImageBase;
+ End = Start + ImportedModule->SizeOfImage;
+ Offset = ImportedModule->BaseAddress - Start;
+
+ /* Walk through function list and fixup addresses. */
+ while (*FunctionNameList != 0L)
+ {
+ if (*ImportAddressList >= Start && *ImportAddressList < End)
{
- (*ImportAddressList) += Offset;
- }
- ImportAddressList++;
- FunctionNameList++;
- }
+ (*ImportAddressList) += Offset;
+ }
+ ImportAddressList++;
+ FunctionNameList++;
+ }
- /* Protect the region we are about to write into. */
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- IATBase,
- IATSize * sizeof(PVOID*),
- OldProtect,
- &OldProtect);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to protect IAT.\n");
- return(Status);
- }
- }
+ /* Protect the region we are about to write into. */
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &IATBase,
+ &IATSize,
+ OldProtect,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to protect IAT.\n");
+ return(Status);
+ }
+ }
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
/**********************************************************************
* NAME LOCAL
* LdrFixupImports
- *
+ *
* DESCRIPTION
* Compute the entry point for every symbol the DLL imports
* from other modules.
* NOTE
*
*/
-static NTSTATUS
+static NTSTATUS
LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
- IN PLDR_MODULE Module)
+ IN PLDR_MODULE Module)
{
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectoryCurrent;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
PIMAGE_TLS_DIRECTORY TlsDirectory;
- ULONG TlsSize;
+ ULONG TlsSize = 0;
NTSTATUS Status;
PLDR_MODULE ImportedModule;
PCHAR ImportedName;
-
+
DPRINT("LdrFixupImports(SearchPath %x, Module %x)\n", SearchPath, Module);
-
+
/* Check for tls data */
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_TLS,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_TLS,
+ NULL);
if (TlsDirectory)
{
- TlsSize = TlsDirectory->EndAddressOfRawData
- - TlsDirectory->StartAddressOfRawData
- + TlsDirectory->SizeOfZeroFill;
+ TlsSize = TlsDirectory->EndAddressOfRawData
+ - TlsDirectory->StartAddressOfRawData
+ + TlsDirectory->SizeOfZeroFill;
if (TlsSize > 0 &&
- NtCurrentPeb()->Ldr->Initialized)
+ NtCurrentPeb()->Ldr->Initialized)
{
TRACE_LDR("Trying to load dynamicly %wZ which contains a tls directory\n",
- &Module->BaseDllName);
- return STATUS_UNSUCCESSFUL;
- }
+ &Module->BaseDllName);
+ return STATUS_UNSUCCESSFUL;
+ }
}
/*
* Process each import module.
*/
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ NULL);
BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+ NULL);
if (BoundImportDescriptor != NULL && ImportModuleDirectory == NULL)
{
BoundImportDescriptorCurrent = BoundImportDescriptor;
while (BoundImportDescriptorCurrent->OffsetModuleName)
{
- ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
- TRACE_LDR("%wZ bound to %s\n", &Module->BaseDllName, ImportedName);
- Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to load %s\n", ImportedName);
- return Status;
- }
- if (Module == ImportedModule)
- {
- LdrpDecrementLoadCount(Module, FALSE);
- }
- if (ImportedModule->TimeDateStamp != BoundImportDescriptorCurrent->TimeDateStamp)
- {
- TRACE_LDR("%wZ has stale binding to %wZ\n",
- &Module->BaseDllName, &ImportedModule->BaseDllName);
- Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to import %s\n", ImportedName);
- return Status;
- }
- }
- else
- {
- BOOL WrongForwarder;
- WrongForwarder = FALSE;
- if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
- {
- TRACE_LDR("%wZ has stale binding to %s\n",
- &Module->BaseDllName, ImportedName);
- }
- else
- {
- TRACE_LDR("%wZ has correct binding to %wZ\n",
- &Module->BaseDllName, &ImportedModule->BaseDllName);
- }
- if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
- {
- PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
- ULONG i;
- PLDR_MODULE ForwarderModule;
- PUCHAR ForwarderName;
+ ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
+ TRACE_LDR("%wZ bound to %s\n", &Module->BaseDllName, ImportedName);
+ Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to load %s\n", ImportedName);
+ return Status;
+ }
+ if (Module == ImportedModule)
+ {
+ LdrpDecrementLoadCount(Module, FALSE);
+ }
+ if (ImportedModule->TimeDateStamp != BoundImportDescriptorCurrent->TimeDateStamp)
+ {
+ TRACE_LDR("%wZ has stale binding to %wZ\n",
+ &Module->BaseDllName, &ImportedModule->BaseDllName);
+ Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to import %s\n", ImportedName);
+ return Status;
+ }
+ }
+ else
+ {
+ BOOL WrongForwarder;
+ WrongForwarder = FALSE;
+ if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ {
+ TRACE_LDR("%wZ has stale binding to %s\n",
+ &Module->BaseDllName, ImportedName);
+ }
+ else
+ {
+ TRACE_LDR("%wZ has correct binding to %wZ\n",
+ &Module->BaseDllName, &ImportedModule->BaseDllName);
+ }
+ if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
+ {
+ PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
+ ULONG i;
+ PLDR_MODULE ForwarderModule;
+ PUCHAR ForwarderName;
BoundForwarderRef = (PIMAGE_BOUND_FORWARDER_REF)(BoundImportDescriptorCurrent + 1);
- for (i = 0; i < BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs; i++, BoundForwarderRef++)
- {
- ForwarderName = (PCHAR)BoundImportDescriptor + BoundForwarderRef->OffsetModuleName;
- TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
- &Module->BaseDllName, ForwarderName, ImportedName);
- Status = LdrpGetOrLoadModule(SearchPath, ForwarderName, &ForwarderModule, TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to load %s\n", ForwarderName);
- return Status;
- }
- if (Module == ImportedModule)
- {
- LdrpDecrementLoadCount(Module, FALSE);
- }
- if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
- ForwarderModule->Flags & IMAGE_NOT_AT_BASE)
- {
- TRACE_LDR("%wZ has stale binding to %s\n",
- &Module->BaseDllName, ForwarderName);
- WrongForwarder = TRUE;
- }
- else
- {
- TRACE_LDR("%wZ has correct binding to %s\n",
- &Module->BaseDllName, ForwarderName);
- }
- }
- }
- if (WrongForwarder ||
- ImportedModule->Flags & IMAGE_NOT_AT_BASE)
- {
+ for (i = 0; i < BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs; i++, BoundForwarderRef++)
+ {
+ ForwarderName = (PCHAR)BoundImportDescriptor + BoundForwarderRef->OffsetModuleName;
+ TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
+ &Module->BaseDllName, ForwarderName, ImportedName);
+ Status = LdrpGetOrLoadModule(SearchPath, ForwarderName, &ForwarderModule, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to load %s\n", ForwarderName);
+ return Status;
+ }
+ if (Module == ImportedModule)
+ {
+ LdrpDecrementLoadCount(Module, FALSE);
+ }
+ if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
+ ForwarderModule->Flags & IMAGE_NOT_AT_BASE)
+ {
+ TRACE_LDR("%wZ has stale binding to %s\n",
+ &Module->BaseDllName, ForwarderName);
+ WrongForwarder = TRUE;
+ }
+ else
+ {
+ TRACE_LDR("%wZ has correct binding to %s\n",
+ &Module->BaseDllName, ForwarderName);
+ }
+ }
+ }
+ if (WrongForwarder ||
+ ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ {
Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to import %s\n", ImportedName);
- return Status;
- }
- }
- else if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
- {
- TRACE_LDR("Adjust imports for %s from %wZ\n",
- ImportedName, &Module->BaseDllName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to import %s\n", ImportedName);
+ return Status;
+ }
+ }
+ else if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ {
+ TRACE_LDR("Adjust imports for %s from %wZ\n",
+ ImportedName, &Module->BaseDllName);
Status = LdrpAdjustImportDirectory(Module, ImportedModule, ImportedName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to adjust import entries for %s\n", ImportedName);
- return Status;
- }
- }
- else if (WrongForwarder)
- {
- /*
- * FIXME:
- * Update only forwarders
- */
- TRACE_LDR("Stale BIND %s from %wZ\n",
- ImportedName, &Module->BaseDllName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to adjust import entries for %s\n", ImportedName);
+ return Status;
+ }
+ }
+ else if (WrongForwarder)
+ {
+ /*
+ * FIXME:
+ * Update only forwarders
+ */
+ TRACE_LDR("Stale BIND %s from %wZ\n",
+ ImportedName, &Module->BaseDllName);
Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("faild to import %s\n", ImportedName);
- return Status;
- }
- }
- else
- {
- /* nothing to do */
- }
- }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("faild to import %s\n", ImportedName);
+ return Status;
+ }
+ }
+ else
+ {
+ /* nothing to do */
+ }
+ }
BoundImportDescriptorCurrent += BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs + 1;
- }
+ }
}
else if (ImportModuleDirectory)
{
ImportModuleDirectoryCurrent = ImportModuleDirectory;
while (ImportModuleDirectoryCurrent->dwRVAModuleName)
{
- ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectoryCurrent->dwRVAModuleName;
- TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
+ ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectoryCurrent->dwRVAModuleName;
+ TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
if (!NT_SUCCESS(Status))
DPRINT1("failed to load %s\n", ImportedName);
return Status;
}
- if (Module == ImportedModule)
- {
- LdrpDecrementLoadCount(Module, FALSE);
- }
- TRACE_LDR("Initializing imports for %wZ from %s\n",
- &Module->BaseDllName, ImportedName);
- Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("failed to import %s\n", ImportedName);
- return Status;
- }
- ImportModuleDirectoryCurrent++;
- }
+ if (Module == ImportedModule)
+ {
+ LdrpDecrementLoadCount(Module, FALSE);
+ }
+
+ TRACE_LDR("Initializing imports for %wZ from %s\n",
+ &Module->BaseDllName, ImportedName);
+ Status = LdrpProcessImportDirectoryEntry(Module, ImportedModule, ImportModuleDirectoryCurrent);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("failed to import %s\n", ImportedName);
+ return Status;
+ }
+ ImportModuleDirectoryCurrent++;
+ }
}
+
if (TlsDirectory && TlsSize > 0)
{
LdrpAcquireTlsSlot(Module, TlsSize, FALSE);
* ImageBase
* Address at which the EXE's image
* is loaded.
- *
+ *
* SectionHandle
* Handle of the section that contains
* the EXE's image.
*/
if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
{
- DbgPrint("LDR: Performing relocations\n");
+ DPRINT("LDR: Performing relocations\n");
Status = LdrPerformRelocations(NTHeaders, ImageBase);
if (!NT_SUCCESS(Status))
{
- DbgPrint("LdrPerformRelocations() failed\n");
+ DPRINT1("LdrPerformRelocations() failed\n");
return NULL;
}
}
Status = LdrFindEntryForAddress(ImageBase, Module);
if (!NT_SUCCESS(Status))
{
- return NULL;
- }
+ return NULL;
+ }
}
-
+
if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
{
(*Module)->Flags |= IMAGE_NOT_AT_BASE;
return EntryPoint;
}
-static NTSTATUS
+static NTSTATUS
LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
- IN ULONG LoadFlags,
- IN PUNICODE_STRING Name,
- PLDR_MODULE *Module)
+ IN ULONG LoadFlags,
+ IN PUNICODE_STRING Name,
+ PLDR_MODULE *Module)
{
UNICODE_STRING AdjustedName;
UNICODE_STRING FullDosName;
{
/* Open or create dll image section */
Status = LdrpMapKnownDll(&AdjustedName, &FullDosName, &SectionHandle);
- if (!NT_SUCCESS(Status))
- {
+ if (!NT_SUCCESS(Status))
+ {
Status = LdrpMapDllImageFile(SearchPath, &AdjustedName, &FullDosName, &SectionHandle);
- }
- if (!NT_SUCCESS(Status))
- {
+ }
+ if (!NT_SUCCESS(Status))
+ {
DPRINT1("Failed to create or open dll section of '%wZ' (Status %lx)\n", &AdjustedName, Status);
RtlFreeUnicodeString(&AdjustedName);
RtlFreeUnicodeString(&FullDosName);
return Status;
- }
+ }
RtlFreeUnicodeString(&AdjustedName);
- /* Map the dll into the process */
- ViewSize = 0;
- ImageBase = 0;
+ /* Map the dll into the process */
+ ViewSize = 0;
+ ImageBase = 0;
Status = NtMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&ImageBase,
* relocation. */
if (ImageBase != (PVOID) NtHeaders->OptionalHeader.ImageBase)
{
- DPRINT1("Performing relocations (%x -> %x)\n",
- NtHeaders->OptionalHeader.ImageBase, ImageBase);
+ DPRINT1("Relocating (%x -> %x) %wZ\n",
+ NtHeaders->OptionalHeader.ImageBase, ImageBase, &FullDosName);
Status = LdrPerformRelocations(NtHeaders, ImageBase);
if (!NT_SUCCESS(Status))
{
DPRINT1("LdrPerformRelocations() failed\n");
- NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
+ NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
NtClose (SectionHandle);
RtlFreeUnicodeString(&FullDosName);
return STATUS_UNSUCCESSFUL;
- }
+ }
}
*Module = LdrAddModuleEntry(ImageBase, NtHeaders, FullDosName.Buffer);
(*Module)->SectionHandle = SectionHandle;
if (ImageBase != (PVOID) NtHeaders->OptionalHeader.ImageBase)
{
- (*Module)->Flags |= IMAGE_NOT_AT_BASE;
- }
+ (*Module)->Flags |= IMAGE_NOT_AT_BASE;
+ }
if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
{
- (*Module)->Flags |= IMAGE_DLL;
- }
+ (*Module)->Flags |= IMAGE_DLL;
+ }
/* fixup the imported calls entry points */
Status = LdrFixupImports(SearchPath, *Module);
if (!NT_SUCCESS(Status))
{
- DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
- return Status;
- }
-#ifdef KDBG
+ DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
+ return Status;
+ }
+#if defined(DBG) || defined(KDBG)
LdrpLoadUserModuleSymbols(*Module);
-#endif
+#endif /* DBG || KDBG */
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
- InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
- &(*Module)->InInitializationOrderModuleList);
+ InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
+ &(*Module)->InInitializationOrderModuleList);
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
}
return STATUS_SUCCESS;
}
-static NTSTATUS
-LdrpUnloadModule(PLDR_MODULE Module,
- BOOL Unload)
+static NTSTATUS
+LdrpUnloadModule(PLDR_MODULE Module,
+ BOOL Unload)
{
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
LoadCount = LdrpDecrementLoadCount(Module, Unload);
TRACE_LDR("Unload %wZ, LoadCount %d\n", &Module->BaseDllName, LoadCount);
-
+
if (LoadCount == 0)
{
/* ?????????????????? */
else if (LoadCount == 1)
{
BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+ NULL);
if (BoundImportDescriptor)
{
- /* dereferencing all imported modules, use the bound import descriptor */
+ /* dereferencing all imported modules, use the bound import descriptor */
BoundImportDescriptorCurrent = BoundImportDescriptor;
while (BoundImportDescriptorCurrent->OffsetModuleName)
{
- ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
- TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
+ ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
+ TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("unable to found imported modul %s\n", ImportedName);
- }
- else
- {
- if (Module != ImportedModule)
- {
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("unable to found imported modul %s\n", ImportedName);
+ }
+ else
+ {
+ if (Module != ImportedModule)
+ {
Status = LdrpUnloadModule(ImportedModule, FALSE);
if (!NT_SUCCESS(Status))
- {
- DPRINT1("unable to unload %s\n", ImportedName);
- }
- }
- }
- BoundImportDescriptorCurrent++;
- }
+ {
+ DPRINT1("unable to unload %s\n", ImportedName);
+ }
+ }
+ }
+ BoundImportDescriptorCurrent++;
+ }
}
- else
+ else
{
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ RtlImageDirectoryEntryToData(Module->BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ NULL);
if (ImportModuleDirectory)
- {
- /* dereferencing all imported modules, use the import descriptor */
- while (ImportModuleDirectory->dwRVAModuleName)
- {
- ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
- TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
+ {
+ /* dereferencing all imported modules, use the import descriptor */
+ while (ImportModuleDirectory->dwRVAModuleName)
+ {
+ ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
+ TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("unable to found imported modul %s\n", ImportedName);
- }
- else
- {
- if (Module != ImportedModule)
- {
- Status = LdrpUnloadModule(ImportedModule, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("unable to unload %s\n", ImportedName);
- }
- }
- }
- ImportModuleDirectory++;
- }
- }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("unable to found imported modul %s\n", ImportedName);
+ }
+ else
+ {
+ if (Module != ImportedModule)
+ {
+ Status = LdrpUnloadModule(ImportedModule, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("unable to unload %s\n", ImportedName);
+ }
+ }
+ }
+ ImportModuleDirectory++;
+ }
+ }
}
}
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
- while (Entry != ModuleListHead)
+ while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->BaseAddress);
- if (Module->BaseAddress == BaseAddress)
- {
- if (Module->TlsIndex == -1)
- {
+ if (Module->BaseAddress == BaseAddress)
+ {
+ if (Module->TlsIndex == -1)
+ {
Module->Flags |= DONT_CALL_FOR_THREAD;
Status = STATUS_SUCCESS;
}
TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n", DllName, Path ? Path : L"");
/* NULL is the current executable */
- if (DllName == NULL)
+ if (DllName == NULL)
{
*BaseAddress = ExeModule->BaseAddress;
DPRINT("BaseAddress %x\n", *BaseAddress);
/* by name */
*ProcedureAddress = LdrGetExportByName(BaseAddress, Name->Buffer, 0xffff);
if (*ProcedureAddress != NULL)
- {
+ {
return STATUS_SUCCESS;
}
DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
/**********************************************************************
* NAME LOCAL
* LdrpDetachProcess
- *
+ *
* DESCRIPTION
* Unload dll's which are no longer referenced from others dll's
*
* REVISIONS
*
* NOTE
- * The loader lock must be held on enty.
+ * The loader lock must be held on enty.
*/
-static VOID
+static VOID
LdrpDetachProcess(BOOL UnloadAll)
{
PLIST_ENTRY ModuleListHead;
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
if (((UnloadAll && Module->LoadCount <= 0) || Module->LoadCount == 0) &&
- Module->Flags & ENTRY_PROCESSED &&
- !(Module->Flags & UNLOAD_IN_PROGRESS))
+ Module->Flags & ENTRY_PROCESSED &&
+ !(Module->Flags & UNLOAD_IN_PROGRESS))
{
Module->Flags |= UNLOAD_IN_PROGRESS;
- if (Module == LdrpLastModule)
- {
- LdrpLastModule = NULL;
- }
+ if (Module == LdrpLastModule)
+ {
+ LdrpLastModule = NULL;
+ }
if (Module->Flags & PROCESS_ATTACH_CALLED)
- {
- TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
- &Module->BaseDllName, Module->EntryPoint);
- LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
- }
- else
- {
+ {
+ TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
+ &Module->BaseDllName, Module->EntryPoint);
+ LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
+ }
+ else
+ {
TRACE_LDR("Unload %wZ\n", &Module->BaseDllName);
- }
- Entry = ModuleListHead->Blink;
- }
+ }
+ Entry = ModuleListHead->Blink;
+ }
else
{
- Entry = Entry->Blink;
- }
+ Entry = Entry->Blink;
+ }
}
-
+
if (CallingCount == 1)
{
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
- Entry = Entry->Blink;
- if (Module->Flags & UNLOAD_IN_PROGRESS &&
- ((UnloadAll && Module->LoadCount >= 0) || Module->LoadCount == 0))
- {
+ Entry = Entry->Blink;
+ if (Module->Flags & UNLOAD_IN_PROGRESS &&
+ ((UnloadAll && Module->LoadCount >= 0) || Module->LoadCount == 0))
+ {
/* remove the module entry from the list */
- RemoveEntryList (&Module->InLoadOrderModuleList)
+ RemoveEntryList (&Module->InLoadOrderModuleList);
RemoveEntryList (&Module->InInitializationOrderModuleList);
- NtUnmapViewOfSection (NtCurrentProcess (), Module->BaseAddress);
+ NtUnmapViewOfSection (NtCurrentProcess (), Module->BaseAddress);
NtClose (Module->SectionHandle);
- TRACE_LDR("%wZ unloaded\n", &Module->BaseDllName);
+ TRACE_LDR("%wZ unloaded\n", &Module->BaseDllName);
RtlFreeUnicodeString (&Module->FullDllName);
RtlFreeUnicodeString (&Module->BaseDllName);
RtlFreeHeap (RtlGetProcessHeap (), 0, Module);
- }
+ }
}
}
CallingCount--;
/**********************************************************************
* NAME LOCAL
* LdrpAttachProcess
- *
+ *
* DESCRIPTION
* Initialize all dll's which are prepered for loading
*
PLIST_ENTRY Entry;
PLDR_MODULE Module;
BOOL Result;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("LdrpAttachProcess() called for %wZ\n",
&ExeModule->BaseDllName);
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
if (!(Module->Flags & (LOAD_IN_PROGRESS|UNLOAD_IN_PROGRESS|ENTRY_PROCESSED)))
- {
- Module->Flags |= LOAD_IN_PROGRESS;
+ {
+ Module->Flags |= LOAD_IN_PROGRESS;
TRACE_LDR("%wZ loaded - Calling init routine at %x for process attaching\n",
- &Module->BaseDllName, Module->EntryPoint);
- Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
+ &Module->BaseDllName, Module->EntryPoint);
+ Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == -1 ? 1 : 0));
if (!Result)
{
- Status = STATUS_DLL_INIT_FAILED;
- break;
- }
- if (Module->Flags & IMAGE_DLL && Module->EntryPoint != 0)
- {
- Module->Flags |= PROCESS_ATTACH_CALLED|ENTRY_PROCESSED;
- }
- else
- {
- Module->Flags |= ENTRY_PROCESSED;
- }
+ Status = STATUS_DLL_INIT_FAILED;
+ break;
+ }
+ if (Module->Flags & IMAGE_DLL && Module->EntryPoint != 0)
+ {
+ Module->Flags |= PROCESS_ATTACH_CALLED|ENTRY_PROCESSED;
+ }
+ else
+ {
+ Module->Flags |= ENTRY_PROCESSED;
+ }
Module->Flags &= ~LOAD_IN_PROGRESS;
- }
+ }
Entry = Entry->Flink;
}
NTSTATUS STDCALL
LdrShutdownProcess (VOID)
{
- LdrpDetachProcess(TRUE);
- return STATUS_SUCCESS;
+ LdrpDetachProcess(TRUE);
+ return STATUS_SUCCESS;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
LdrpAttachThread (VOID)
{
- PLIST_ENTRY ModuleListHead;
- PLIST_ENTRY Entry;
- PLDR_MODULE Module;
- NTSTATUS Status;
-
- DPRINT("LdrpAttachThread() called for %wZ\n",
- &ExeModule->BaseDllName);
+ PLIST_ENTRY ModuleListHead;
+ PLIST_ENTRY Entry;
+ PLDR_MODULE Module;
+ NTSTATUS Status;
- RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
+ DPRINT("LdrpAttachThread() called for %wZ\n",
+ &ExeModule->BaseDllName);
- Status = LdrpInitializeTlsForThread();
+ RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
- if (NT_SUCCESS(Status))
- {
+ Status = LdrpInitializeTlsForThread();
- ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
- Entry = ModuleListHead->Flink;
+ if (NT_SUCCESS(Status))
+ {
+ ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
+ Entry = ModuleListHead->Flink;
- while (Entry != ModuleListHead)
- {
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
- if (Module->Flags & PROCESS_ATTACH_CALLED &&
- !(Module->Flags & DONT_CALL_FOR_THREAD) &&
- !(Module->Flags & UNLOAD_IN_PROGRESS))
- {
- TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
- &Module->BaseDllName, Module->EntryPoint);
- LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, NULL);
- }
- Entry = Entry->Flink;
- }
+ while (Entry != ModuleListHead)
+ {
+ Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
+ if (Module->Flags & PROCESS_ATTACH_CALLED &&
+ !(Module->Flags & DONT_CALL_FOR_THREAD) &&
+ !(Module->Flags & UNLOAD_IN_PROGRESS))
+ {
+ TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
+ &Module->BaseDllName, Module->EntryPoint);
+ LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
+ }
+ Entry = Entry->Flink;
+ }
- Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
- LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
- }
+ Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
+ Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
+ }
- RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
+ RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
- DPRINT("LdrpAttachThread() done\n");
+ DPRINT("LdrpAttachThread() done\n");
- return Status;
+ return Status;
}
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
if (Module->Flags & PROCESS_ATTACH_CALLED &&
- !(Module->Flags & DONT_CALL_FOR_THREAD) &&
+ !(Module->Flags & DONT_CALL_FOR_THREAD) &&
!(Module->Flags & UNLOAD_IN_PROGRESS))
{
- TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
- &Module->BaseDllName, Module->EntryPoint);
+ TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
+ &Module->BaseDllName, Module->EntryPoint);
LdrpCallDllEntry(Module, DLL_THREAD_DETACH, NULL);
}
Entry = Entry->Blink;
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_MODULE Module;
- PMODULE_ENTRY ModulePtr = NULL;
+ PDEBUG_MODULE_INFORMATION ModulePtr = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG UsedSize = sizeof(ULONG);
ANSI_STRING AnsiString;
}
else if (ModuleInformation != NULL)
{
- ModulePtr->Unknown0 = 0; // FIXME: ??
- ModulePtr->Unknown1 = 0; // FIXME: ??
- ModulePtr->BaseAddress = Module->BaseAddress;
- ModulePtr->SizeOfImage = Module->SizeOfImage;
+ ModulePtr->Reserved[0] = ModulePtr->Reserved[1] = 0; // FIXME: ??
+ ModulePtr->Base = Module->BaseAddress;
+ ModulePtr->Size = Module->SizeOfImage;
ModulePtr->Flags = Module->Flags;
- ModulePtr->Unknown2 = 0; // FIXME: load order index ??
- ModulePtr->Unknown3 = 0; // FIXME: ??
+ ModulePtr->Index = 0; // FIXME: index ??
+ ModulePtr->Unknown = 0; // FIXME: ??
ModulePtr->LoadCount = Module->LoadCount;
AnsiString.Length = 0;
AnsiString.MaximumLength = 256;
- AnsiString.Buffer = ModulePtr->ModuleName;
+ AnsiString.Buffer = ModulePtr->ImageName;
RtlUnicodeStringToAnsiString(&AnsiString,
&Module->FullDllName,
FALSE);
- p = strrchr(ModulePtr->ModuleName, '\\');
+ p = strrchr(ModulePtr->ImageName, '\\');
if (p != NULL)
- ModulePtr->PathLength = p - ModulePtr->ModuleName + 1;
+ ModulePtr->ModuleNameOffset = p - ModulePtr->ImageName + 1;
else
- ModulePtr->PathLength = 0;
+ ModulePtr->ModuleNameOffset = 0;
ModulePtr++;
ModuleInformation->ModuleCount++;
}
- UsedSize += sizeof(MODULE_ENTRY);
+ UsedSize += sizeof(DEBUG_MODULE_INFORMATION);
Entry = Entry->Flink;
}
static BOOLEAN
LdrpCheckImageChecksum (IN PVOID BaseAddress,
- IN ULONG ImageSize)
+ IN ULONG ImageSize)
{
PIMAGE_NT_HEADERS Header;
PUSHORT Ptr;
{
Sum += (ULONG)*Ptr;
if (HIWORD(Sum) != 0)
- {
- Sum = LOWORD(Sum) + HIWORD(Sum);
- }
+ {
+ Sum = LOWORD(Sum) + HIWORD(Sum);
+ }
Ptr++;
}
{
Sum += (ULONG)*((PUCHAR)Ptr);
if (HIWORD(Sum) != 0)
- {
- Sum = LOWORD(Sum) + HIWORD(Sum);
- }
+ {
+ Sum = LOWORD(Sum) + HIWORD(Sum);
+ }
}
CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum));
*/
NTSTATUS STDCALL
LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
- ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3)
+ ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3)
{
FILE_STANDARD_INFORMATION FileInfo;
IO_STATUS_BLOCK IoStatusBlock;
DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
Status = NtCreateSection (&SectionHandle,
- SECTION_MAP_EXECUTE,
- NULL,
- NULL,
- PAGE_EXECUTE,
- SEC_COMMIT,
- FileHandle);
+ SECTION_MAP_EXECUTE,
+ NULL,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_COMMIT,
+ FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status);
ViewSize = 0;
BaseAddress = NULL;
Status = NtMapViewOfSection (SectionHandle,
- NtCurrentProcess (),
- &BaseAddress,
- 0,
- 0,
- NULL,
- &ViewSize,
- ViewShare,
- 0,
- PAGE_EXECUTE);
+ NtCurrentProcess (),
+ &BaseAddress,
+ 0,
+ 0,
+ NULL,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_EXECUTE);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
}
Status = NtQueryInformationFile (FileHandle,
- &IoStatusBlock,
- &FileInfo,
- sizeof (FILE_STANDARD_INFORMATION),
- FileStandardInformation);
+ &IoStatusBlock,
+ &FileInfo,
+ sizeof (FILE_STANDARD_INFORMATION),
+ FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
NtUnmapViewOfSection (NtCurrentProcess (),
- BaseAddress);
+ BaseAddress);
NtClose (SectionHandle);
return Status;
}
Result = LdrpCheckImageChecksum (BaseAddress,
- FileInfo.EndOfFile.u.LowPart);
+ FileInfo.EndOfFile.u.LowPart);
if (Result == FALSE)
{
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
}
NtUnmapViewOfSection (NtCurrentProcess (),
- BaseAddress);
+ BaseAddress);
NtClose (SectionHandle);
*/
NTSTATUS STDCALL
LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
- IN PCWSTR ValueName,
- IN ULONG Type,
- OUT PVOID Buffer,
- IN ULONG BufferSize,
- OUT PULONG ReturnedLength OPTIONAL)
+ IN PCWSTR ValueName,
+ IN ULONG Type,
+ OUT PVOID Buffer,
+ IN ULONG BufferSize,
+ OUT PULONG ReturnedLength OPTIONAL)
{
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
wcscpy (NameBuffer,
- L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\");
+ L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\");
Ptr = wcsrchr (SubKey->Buffer, L'\\');
if (Ptr == NULL)
{
}
wcscat (NameBuffer, Ptr);
RtlInitUnicodeString (&KeyName,
- NameBuffer);
+ NameBuffer);
InitializeObjectAttributes (&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
Status = NtOpenKey (&KeyHandle,
- KEY_READ,
- &ObjectAttributes);
+ KEY_READ,
+ &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT ("NtOpenKey() failed (Status %lx)\n", Status);
KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32;
KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- KeyInfoSize);
+ HEAP_ZERO_MEMORY,
+ KeyInfoSize);
RtlInitUnicodeString (&ValueNameString,
- (PWSTR)ValueName);
+ (PWSTR)ValueName);
Status = NtQueryValueKey (KeyHandle,
- &ValueNameString,
- KeyValuePartialInformation,
- KeyInfo,
- KeyInfoSize,
- &ResultSize);
+ &ValueNameString,
+ KeyValuePartialInformation,
+ KeyInfo,
+ KeyInfoSize,
+ &ResultSize);
if (Status == STATUS_BUFFER_OVERFLOW)
{
KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + KeyInfo->DataLength;
RtlFreeHeap (RtlGetProcessHeap(),
- 0,
- KeyInfo);
+ 0,
+ KeyInfo);
KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- KeyInfoSize);
+ HEAP_ZERO_MEMORY,
+ KeyInfoSize);
if (KeyInfo == NULL)
- {
- NtClose (KeyHandle);
- return Status;
- }
+ {
+ NtClose (KeyHandle);
+ return Status;
+ }
Status = NtQueryValueKey (KeyHandle,
- &ValueNameString,
- KeyValuePartialInformation,
- KeyInfo,
- KeyInfoSize,
- &ResultSize);
+ &ValueNameString,
+ KeyValuePartialInformation,
+ KeyInfo,
+ KeyInfoSize,
+ &ResultSize);
}
NtClose (KeyHandle);
if (!NT_SUCCESS(Status))
{
if (KeyInfo != NULL)
- {
- RtlFreeHeap (RtlGetProcessHeap(),
- 0,
- KeyInfo);
- }
+ {
+ RtlFreeHeap (RtlGetProcessHeap(),
+ 0,
+ KeyInfo);
+ }
return Status;
}
if (KeyInfo->Type != Type)
{
RtlFreeHeap (RtlGetProcessHeap(),
- 0,
- KeyInfo);
+ 0,
+ KeyInfo);
return STATUS_OBJECT_TYPE_MISMATCH;
}
ResultSize = KeyInfo->DataLength;
}
RtlCopyMemory (Buffer,
- &KeyInfo->Data,
- ResultSize);
+ &KeyInfo->Data,
+ ResultSize);
RtlFreeHeap (RtlGetProcessHeap(),
- 0,
- KeyInfo);
+ 0,
+ KeyInfo);
if (ReturnedLength != NULL)
{
return Status;
}
+
+PIMAGE_BASE_RELOCATION STDCALL
+LdrProcessRelocationBlock(IN PVOID Address,
+ IN USHORT Count,
+ IN PUSHORT TypeOffset,
+ IN ULONG_PTR Delta)
+{
+ SHORT Offset;
+ USHORT Type;
+ USHORT i;
+ PUSHORT ShortPtr;
+ PULONG LongPtr;
+
+ for (i = 0; i < Count; i++)
+ {
+ Offset = *TypeOffset & 0xFFF;
+ Type = *TypeOffset >> 12;
+
+ switch (Type)
+ {
+ case IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case IMAGE_REL_BASED_HIGH:
+ ShortPtr = (PUSHORT)(Address + Offset);
+ *ShortPtr += HIWORD(Delta);
+ break;
+
+ case IMAGE_REL_BASED_LOW:
+ ShortPtr = (PUSHORT)(Address + Offset);
+ *ShortPtr += LOWORD(Delta);
+ break;
+
+ case IMAGE_REL_BASED_HIGHLOW:
+ LongPtr = (PULONG)(Address + Offset);
+ *LongPtr += Delta;
+ break;
+
+ case IMAGE_REL_BASED_HIGHADJ:
+ case IMAGE_REL_BASED_MIPS_JMPADDR:
+ default:
+ DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
+ return NULL;
+ }
+
+ TypeOffset++;
+ }
+
+ return (PIMAGE_BASE_RELOCATION)TypeOffset;
+}
+
/* EOF */