/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/ldr/utils.c
/* INCLUDES *****************************************************************/
-#include <reactos/config.h>
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <string.h>
-#include <wchar.h>
-#include <ntdll/ldr.h>
-#include <ntos/minmax.h>
+#include <ntdll.h>
+#define NDEBUG
+#include <debug.h>
#define LDRP_PROCESS_CREATION_TIME 0x8000000
-#ifdef DBG_NTDLL_LDR_UTILS
-#define NDEBUG
-#endif
-#include <ntdll/ntdll.h>
-
/* GLOBALS *******************************************************************/
+#ifdef NDEBUG
+#if defined(__GNUC__)
+#define TRACE_LDR(args...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); }
+#else
+#endif /* __GNUC__ */
+#else
+#define TRACE_LDR(args...) do { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0)
+#endif
+
typedef struct _TLS_DATA
{
PVOID StartAddressOfRawData;
DWORD TlsDataSize;
DWORD TlsZeroSize;
PIMAGE_TLS_CALLBACK TlsAddressOfCallBacks;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
} TLS_DATA, *PTLS_DATA;
static PTLS_DATA LdrpTlsArray = NULL;
static ULONG LdrpTlsSize = 0;
static HANDLE LdrpKnownDllsDirHandle = NULL;
static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL};
-static PLDR_MODULE LdrpLastModule = NULL;
-extern PLDR_MODULE ExeModule;
+static PLDR_DATA_TABLE_ENTRY LdrpLastModule = NULL;
+extern PLDR_DATA_TABLE_ENTRY ExeModule;
/* PROTOTYPES ****************************************************************/
-static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module, BOOL Ref);
+static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_DATA_TABLE_ENTRY *Module, BOOLEAN 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);
+ OUT PLDR_DATA_TABLE_ENTRY *Module,
+ OUT PVOID *BaseAddress OPTIONAL);
static NTSTATUS LdrpAttachProcess(VOID);
-static VOID LdrpDetachProcess(BOOL UnloadAll);
+static VOID LdrpDetachProcess(BOOLEAN UnloadAll);
/* FUNCTIONS *****************************************************************/
#if defined(DBG) || defined(KDBG)
VOID
-LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
+LdrpLoadUserModuleSymbols(PLDR_DATA_TABLE_ENTRY LdrModule)
{
NtSystemDebugControl(
DebugDbgLoadSymbols,
#endif /* DBG || KDBG */
-static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
+BOOLEAN
+LdrMappedAsDataFile(PVOID *BaseAddress)
+{
+ if (0 != ((DWORD_PTR) *BaseAddress & (PAGE_SIZE - 1)))
+ {
+ *BaseAddress = (PVOID) ((DWORD_PTR) *BaseAddress & ~ ((DWORD_PTR) PAGE_SIZE - 1));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static __inline LONG LdrpDecrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Locked)
{
LONG LoadCount;
if (!Locked)
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
}
LoadCount = Module->LoadCount;
- if (Module->LoadCount > 0)
+ if (Module->LoadCount > 0 && Module->LoadCount != 0xFFFF)
{
Module->LoadCount--;
}
return LoadCount;
}
-static inline LONG LdrpIncrementLoadCount(PLDR_MODULE Module, BOOL Locked)
+static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Locked)
{
LONG LoadCount;
if (!Locked)
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
}
LoadCount = Module->LoadCount;
- if (Module->LoadCount >= 0)
+ if (Module->LoadCount != 0xFFFF)
{
Module->LoadCount++;
}
return LoadCount;
}
-static inline VOID LdrpAcquireTlsSlot(PLDR_MODULE Module, ULONG Size, BOOL Locked)
+static __inline VOID LdrpAcquireTlsSlot(PLDR_DATA_TABLE_ENTRY Module, ULONG Size, BOOLEAN Locked)
{
if (!Locked)
{
}
}
-static inline VOID LdrpTlsCallback(PLDR_MODULE Module, ULONG dwReason)
+static __inline VOID LdrpTlsCallback(PLDR_DATA_TABLE_ENTRY Module, ULONG dwReason)
{
PIMAGE_TLS_CALLBACK TlsCallback;
- if (Module->TlsIndex >= 0 && Module->LoadCount == -1)
+ if (Module->TlsIndex != 0xFFFF && Module->LoadCount == 0xFFFF)
{
TlsCallback = LdrpTlsArray[Module->TlsIndex].TlsAddressOfCallBacks;
if (TlsCallback)
{
TRACE_LDR("%wZ - Calling tls callback at %x\n",
&Module->BaseDllName, TlsCallback);
- TlsCallback(Module->BaseAddress, dwReason, NULL);
- TlsCallback++;
+ TlsCallback(Module->DllBase, dwReason, NULL);
+ TlsCallback = (PIMAGE_TLS_CALLBACK)((ULONG_PTR)TlsCallback + sizeof(PVOID));
}
}
}
}
-static BOOL LdrpCallDllEntry(PLDR_MODULE Module, DWORD dwReason, PVOID lpReserved)
+static BOOLEAN LdrpCallDllEntry(PLDR_DATA_TABLE_ENTRY Module, DWORD dwReason, PVOID lpReserved)
{
- if (!(Module->Flags & IMAGE_DLL) ||
+ if (!(Module->Flags & LDRP_IMAGE_DLL) ||
Module->EntryPoint == 0)
{
return TRUE;
}
LdrpTlsCallback(Module, dwReason);
- return ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->BaseAddress, dwReason, lpReserved);
+ return ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, lpReserved);
}
static NTSTATUS
PTLS_DATA TlsInfo;
PVOID TlsData;
ULONG i;
+ PTEB Teb = NtCurrentTeb();
DPRINT("LdrpInitializeTlsForThread() called for %wZ\n", &ExeModule->BaseDllName);
+ Teb->StaticUnicodeString.Length = 0;
+ Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
+ Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
+
if (LdrpTlsCount > 0)
{
TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(),
return STATUS_NO_MEMORY;
}
- TlsData = (PVOID)TlsPointers + LdrpTlsCount * sizeof(PVOID);
- NtCurrentTeb()->ThreadLocalStoragePointer = TlsPointers;
+ TlsData = (PVOID)((ULONG_PTR)TlsPointers + LdrpTlsCount * sizeof(PVOID));
+ Teb->ThreadLocalStoragePointer = TlsPointers;
TlsInfo = LdrpTlsArray;
for (i = 0; i < LdrpTlsCount; i++, TlsInfo++)
if (TlsInfo->TlsDataSize)
{
memcpy(TlsData, TlsInfo->StartAddressOfRawData, TlsInfo->TlsDataSize);
- TlsData += TlsInfo->TlsDataSize;
+ TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsDataSize);
}
if (TlsInfo->TlsZeroSize)
{
memset(TlsData, 0, TlsInfo->TlsZeroSize);
- TlsData += TlsInfo->TlsZeroSize;
+ TlsData = (PVOID)((ULONG_PTR)TlsData + TlsInfo->TlsZeroSize);
}
}
}
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
PIMAGE_TLS_DIRECTORY TlsDirectory;
PTLS_DATA TlsData;
+ ULONG Size;
DPRINT("LdrpInitializeTlsForProccess() called for %wZ\n", &ExeModule->BaseDllName);
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
- if (Module->LoadCount == -1 &&
- Module->TlsIndex >= 0)
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
+ if (Module->LoadCount == 0xFFFF &&
+ Module->TlsIndex != 0xFFFF)
{
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_TLS,
- NULL);
- assert(Module->TlsIndex < LdrpTlsCount);
+ &Size);
+ ASSERT(Module->TlsIndex < LdrpTlsCount);
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;
+ TlsData->TlsAddressOfCallBacks = *(PIMAGE_TLS_CALLBACK*)TlsDirectory->AddressOfCallBacks;
else
TlsData->TlsAddressOfCallBacks = NULL;
TlsData->Module = Module;
* Is this region allways writable ?
*/
*(PULONG)TlsDirectory->AddressOfIndex = Module->TlsIndex;
- CHECKPOINT1;
}
Entry = Entry->Flink;
}
RtlCreateUnicodeString(FullDllName, Buffer);
}
-PLDR_MODULE
+PLDR_DATA_TABLE_ENTRY
LdrAddModuleEntry(PVOID ImageBase,
PIMAGE_NT_HEADERS NTHeaders,
PWSTR FullDosName)
{
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
- Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE));
- assert(Module);
- memset(Module, 0, sizeof(LDR_MODULE));
- Module->BaseAddress = (PVOID)ImageBase;
- Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint;
+ Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_DATA_TABLE_ENTRY));
+ ASSERT(Module);
+ memset(Module, 0, sizeof(LDR_DATA_TABLE_ENTRY));
+ Module->DllBase = (PVOID)ImageBase;
+ Module->EntryPoint = (PVOID)NTHeaders->OptionalHeader.AddressOfEntryPoint;
if (Module->EntryPoint != 0)
- Module->EntryPoint += (ULONG)Module->BaseAddress;
- Module->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
+ Module->EntryPoint = (PVOID)((ULONG_PTR)Module->EntryPoint + (ULONG_PTR)Module->DllBase);
+ Module->SizeOfImage = LdrpGetResidentSize(NTHeaders);
if (NtCurrentPeb()->Ldr->Initialized == TRUE)
{
/* loading while app is running */
* loading while app is initializing
* dll must not be unloaded
*/
- Module->LoadCount = -1;
+ Module->LoadCount = 0xFFFF;
}
Module->Flags = 0;
LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
IN PUNICODE_STRING DllName,
OUT PUNICODE_STRING FullDosName,
+ IN BOOLEAN MapAsDataFile,
OUT PHANDLE SectionHandle)
{
WCHAR SearchPathBuffer[MAX_PATH];
char BlockBuffer [1024];
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
- PVOID ImageBase;
- ULONG ImageSize;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ULONG len;
/*
* Check it is a PE image file.
*/
- if ((DosHeader->e_magic != IMAGE_DOS_MAGIC)
+ if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|| (DosHeader->e_lfanew == 0L)
- || (*(PULONG)(NTHeaders) != IMAGE_PE_MAGIC))
+ || (*(PULONG)(NTHeaders) != IMAGE_NT_SIGNATURE))
{
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.
*/
SECTION_ALL_ACCESS,
NULL,
NULL,
- PAGE_READWRITE,
- SEC_COMMIT | SEC_IMAGE,
+ PAGE_READONLY,
+ SEC_COMMIT | (MapAsDataFile ? 0 : SEC_IMAGE),
FileHandle);
NtClose(FileHandle);
*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
IN ULONG LoadFlags,
IN PUNICODE_STRING Name,
OUT PVOID *BaseAddress OPTIONAL)
{
NTSTATUS Status;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
Name,
*BaseAddress = NULL;
- Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module);
- if (NT_SUCCESS(Status))
+ Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module, BaseAddress);
+ if (NT_SUCCESS(Status) && 0 == (LoadFlags & LOAD_LIBRARY_AS_DATAFILE))
{
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
Status = LdrpAttachProcess();
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
if (NT_SUCCESS(Status))
{
- *BaseAddress = Module->BaseAddress;
+ *BaseAddress = Module->DllBase;
}
}
return Status;
*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrFindEntryForAddress(PVOID Address,
- PLDR_MODULE *Module)
+ PLDR_DATA_TABLE_ENTRY *Module)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE ModulePtr;
+ PLDR_DATA_TABLE_ENTRY ModulePtr;
DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
while (Entry != ModuleListHead)
{
- ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
- DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->BaseAddress);
+ DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->DllBase);
- if ((Address >= ModulePtr->BaseAddress) &&
- (Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage)))
+ if ((Address >= ModulePtr->DllBase) &&
+ ((ULONG_PTR)Address <= ((ULONG_PTR)ModulePtr->DllBase + ModulePtr->SizeOfImage)))
{
*Module = ModulePtr;
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
*/
static NTSTATUS
LdrFindEntryForName(PUNICODE_STRING Name,
- PLDR_MODULE *Module,
- BOOL Ref)
+ PLDR_DATA_TABLE_ENTRY *Module,
+ BOOLEAN Ref)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE ModulePtr;
+ PLDR_DATA_TABLE_ENTRY ModulePtr;
BOOLEAN ContainsPath;
UNICODE_STRING AdjustedName;
unsigned i;
0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule;
- if (Ref && (*Module)->LoadCount != -1)
+ if (Ref && (*Module)->LoadCount != 0xFFFF)
{
(*Module)->LoadCount++;
}
}
while (Entry != ModuleListHead)
{
- ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, &AdjustedName);
0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule = ModulePtr;
- if (Ref && ModulePtr->LoadCount != -1)
+ if (Ref && ModulePtr->LoadCount != 0xFFFF)
{
ModulePtr->LoadCount++;
}
UNICODE_STRING DllName;
NTSTATUS Status;
PCHAR p;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
PVOID BaseAddress;
strcpy(NameBuffer, ForwardName);
return NULL;
}
- DPRINT("BaseAddress: %p\n", Module->BaseAddress);
+ DPRINT("BaseAddress: %p\n", Module->DllBase);
- return LdrGetExportByName(Module->BaseAddress, (PUCHAR)(p+1), -1);
+ return LdrGetExportByName(Module->DllBase, (PUCHAR)(p+1), -1);
}
return NULL;
ExportDir->AddressOfFunctions
);
DPRINT(
- "LdrGetExportByOrdinal(Ordinal %d) = %x\n",
+ "LdrGetExportByOrdinal(Ordinal %d) = %p\n",
Ordinal,
RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
);
PDWORD * ExFunctions;
PDWORD * ExNames;
USHORT * ExOrdinals;
- ULONG i;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
}
/*
- * Try a binary search first
+ * Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
}
}
- /*
- * Fall back on a linear search
- */
- DPRINT("LdrGetExportByName(): Falling back on a linear search of export table\n");
- for (i = 0; i < ExportDir->NumberOfNames; i++)
- {
- ExName = RVA(BaseAddress, ExNames[i]);
- if (strcmp(ExName, (PCHAR)SymbolName) == 0)
- {
- Ordinal = ExOrdinals[i];
- Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
- if (((ULONG)Function >= (ULONG)ExportDir) &&
- ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
- {
- DPRINT("Forward: %s\n", (PCHAR)Function);
- Function = LdrFixupForward((PCHAR)Function);
- }
- if (Function == NULL)
- {
- break;
- }
- return Function;
- }
- }
DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
{
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
sizeof(USHORT);
- Page = ImageBase + RelocationDir->VirtualAddress;
+ Page = (PVOID)((ULONG_PTR)ImageBase + (ULONG_PTR)RelocationDir->VirtualAddress);
TypeOffset = (PUSHORT)(RelocationDir + 1);
/* Unprotect the page(s) we're about to relocate. */
if (RelocationDir->VirtualAddress + PAGE_SIZE <
NTHeaders->OptionalHeader.SizeOfImage)
{
- ProtectPage2 = ProtectPage + PAGE_SIZE;
+ ProtectPage2 = (PVOID)((ULONG_PTR)ProtectPage + PAGE_SIZE);
Status = NtProtectVirtualMemory(NtCurrentProcess(),
&ProtectPage2,
&ProtectSize,
static NTSTATUS
LdrpGetOrLoadModule(PWCHAR SerachPath,
PCHAR Name,
- PLDR_MODULE* Module,
- BOOL Load)
+ PLDR_DATA_TABLE_ENTRY* Module,
+ BOOLEAN Load)
{
UNICODE_STRING DllName;
NTSTATUS Status;
Status = LdrpLoadModule(SerachPath,
NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME,
&DllName,
- Module);
+ Module,
+ NULL);
if (NT_SUCCESS(Status))
{
Status = LdrFindEntryForName (&DllName, Module, FALSE);
}
static NTSTATUS
-LdrpProcessImportDirectoryEntry(PLDR_MODULE Module,
- PLDR_MODULE ImportedModule,
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory)
+LdrpProcessImportDirectoryEntry(PLDR_DATA_TABLE_ENTRY Module,
+ PLDR_DATA_TABLE_ENTRY ImportedModule,
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
{
NTSTATUS Status;
PVOID* ImportAddressList;
ULONG Ordinal;
ULONG IATSize;
- if (ImportModuleDirectory == NULL || ImportModuleDirectory->dwRVAModuleName == 0)
+ if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the import address list. */
- ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ ImportAddressList = (PVOID *)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
- if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
+ if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
- FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+ FunctionNameList = (PULONG) ((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
}
else
{
- FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ FunctionNameList = (PULONG)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
}
/* Get the size of IAT. */
if ((*FunctionNameList) & 0x80000000)
{
Ordinal = (*FunctionNameList) & 0x7fffffff;
- *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->BaseAddress, Ordinal);
+ *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
else
{
IMAGE_IMPORT_BY_NAME *pe_name;
- pe_name = RVA(Module->BaseAddress, *FunctionNameList);
- *ImportAddressList = LdrGetExportByName(ImportedModule->BaseAddress, pe_name->Name, pe_name->Hint);
+ pe_name = RVA(Module->DllBase, *FunctionNameList);
+ *ImportAddressList = LdrGetExportByName(ImportedModule->DllBase, pe_name->Name, pe_name->Hint);
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
static NTSTATUS
LdrpProcessImportDirectory(
- PLDR_MODULE Module,
- PLDR_MODULE ImportedModule,
+ PLDR_DATA_TABLE_ENTRY Module,
+ PLDR_DATA_TABLE_ENTRY ImportedModule,
PCHAR ImportedName)
{
NTSTATUS Status;
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PCHAR Name;
+ ULONG Size;
DPRINT("LdrpProcessImportDirectory(%x '%wZ', '%s')\n",
Module, &Module->BaseDllName, ImportedName);
- ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ &Size);
if (ImportModuleDirectory == NULL)
{
return STATUS_UNSUCCESSFUL;
}
- while (ImportModuleDirectory->dwRVAModuleName)
+ while (ImportModuleDirectory->Name)
{
- Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
+ Name = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
if (0 == _stricmp(Name, ImportedName))
{
Status = LdrpProcessImportDirectoryEntry(Module,
static NTSTATUS
-LdrpAdjustImportDirectory(PLDR_MODULE Module,
- PLDR_MODULE ImportedModule,
+LdrpAdjustImportDirectory(PLDR_DATA_TABLE_ENTRY Module,
+ PLDR_DATA_TABLE_ENTRY ImportedModule,
PCHAR ImportedName)
{
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
NTSTATUS Status;
PVOID* ImportAddressList;
PVOID Start;
ULONG IATSize;
PIMAGE_NT_HEADERS NTHeaders;
PCHAR Name;
+ ULONG Size;
DPRINT("LdrpAdjustImportDirectory(Module %x '%wZ', %x '%wZ', %x '%s')\n",
Module, &Module->BaseDllName, ImportedModule, &ImportedModule->BaseDllName, ImportedName);
- ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ &Size);
if (ImportModuleDirectory == NULL)
{
return STATUS_UNSUCCESSFUL;
}
- while (ImportModuleDirectory->dwRVAModuleName)
+ while (ImportModuleDirectory->Name)
{
- Name = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
+ Name = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
if (0 == _stricmp(Name, (PCHAR)ImportedName))
{
/* Get the import address list. */
- ImportAddressList = (PVOID *)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ ImportAddressList = (PVOID *)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
- if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
+ if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
- FunctionNameList = (PULONG) (Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionNameList);
+ FunctionNameList = (PULONG) ((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
}
else
{
- FunctionNameList = (PULONG)(Module->BaseAddress + ImportModuleDirectory->dwRVAFunctionAddressList);
+ FunctionNameList = (PULONG)((ULONG_PTR)Module->DllBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
}
/* Get the size of IAT. */
return(Status);
}
- NTHeaders = RtlImageNtHeader (ImportedModule->BaseAddress);
+ NTHeaders = RtlImageNtHeader (ImportedModule->DllBase);
Start = (PVOID)NTHeaders->OptionalHeader.ImageBase;
- End = Start + ImportedModule->SizeOfImage;
- Offset = ImportedModule->BaseAddress - Start;
+ End = (PVOID)((ULONG_PTR)Start + ImportedModule->SizeOfImage);
+ Offset = (ULONG)((ULONG_PTR)ImportedModule->DllBase - (ULONG_PTR)Start);
/* Walk through function list and fixup addresses. */
while (*FunctionNameList != 0L)
{
if (*ImportAddressList >= Start && *ImportAddressList < End)
{
- (*ImportAddressList) += Offset;
+ (*ImportAddressList) = (PVOID)((ULONG_PTR)(*ImportAddressList) + Offset);
}
ImportAddressList++;
FunctionNameList++;
*/
static NTSTATUS
LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
- IN PLDR_MODULE Module)
+ IN PLDR_DATA_TABLE_ENTRY Module)
{
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectoryCurrent;
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectoryCurrent;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
PIMAGE_TLS_DIRECTORY TlsDirectory;
ULONG TlsSize = 0;
NTSTATUS Status;
- PLDR_MODULE ImportedModule;
+ PLDR_DATA_TABLE_ENTRY ImportedModule;
PCHAR ImportedName;
+ ULONG Size;
DPRINT("LdrFixupImports(SearchPath %x, Module %x)\n", SearchPath, Module);
/* Check for tls data */
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_TLS,
- NULL);
+ &Size);
if (TlsDirectory)
{
TlsSize = TlsDirectory->EndAddressOfRawData
/*
* Process each import module.
*/
- ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ &Size);
BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
- NULL);
+ &Size);
if (BoundImportDescriptor != NULL && ImportModuleDirectory == NULL)
{
}
else
{
- BOOL WrongForwarder;
+ BOOLEAN WrongForwarder;
WrongForwarder = FALSE;
- if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
{
TRACE_LDR("%wZ has stale binding to %s\n",
&Module->BaseDllName, ImportedName);
{
PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
ULONG i;
- PLDR_MODULE ForwarderModule;
+ PLDR_DATA_TABLE_ENTRY ForwarderModule;
PCHAR ForwarderName;
BoundForwarderRef = (PIMAGE_BOUND_FORWARDER_REF)(BoundImportDescriptorCurrent + 1);
LdrpDecrementLoadCount(Module, FALSE);
}
if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
- ForwarderModule->Flags & IMAGE_NOT_AT_BASE)
+ ForwarderModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
{
TRACE_LDR("%wZ has stale binding to %s\n",
&Module->BaseDllName, ForwarderName);
}
}
if (WrongForwarder ||
- ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
{
Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
if (!NT_SUCCESS(Status))
return Status;
}
}
- else if (ImportedModule->Flags & IMAGE_NOT_AT_BASE)
+ else if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
{
TRACE_LDR("Adjust imports for %s from %wZ\n",
ImportedName, &Module->BaseDllName);
DPRINT("ImportModuleDirectory %x\n", ImportModuleDirectory);
ImportModuleDirectoryCurrent = ImportModuleDirectory;
- while (ImportModuleDirectoryCurrent->dwRVAModuleName)
+ while (ImportModuleDirectoryCurrent->Name)
{
- ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectoryCurrent->dwRVAModuleName;
+ ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectoryCurrent->Name;
TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
*/
PEPFUNC LdrPEStartup (PVOID ImageBase,
HANDLE SectionHandle,
- PLDR_MODULE* Module,
+ PLDR_DATA_TABLE_ENTRY* Module,
PWSTR FullDosName)
{
NTSTATUS Status;
PEPFUNC EntryPoint = NULL;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
- PLDR_MODULE tmpModule;
+ PLDR_DATA_TABLE_ENTRY tmpModule;
DPRINT("LdrPEStartup(ImageBase %x SectionHandle %x)\n",
ImageBase, (ULONG)SectionHandle);
* to the DLL's image.
*/
DosHeader = (PIMAGE_DOS_HEADER) ImageBase;
- NTHeaders = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew);
+ NTHeaders = (PIMAGE_NT_HEADERS) ((ULONG_PTR)ImageBase + DosHeader->e_lfanew);
/*
* If the base address is different from the
if (Module != NULL)
{
*Module = LdrAddModuleEntry(ImageBase, NTHeaders, FullDosName);
- (*Module)->SectionHandle = SectionHandle;
+ (*Module)->SectionPointer = SectionHandle;
}
else
{
if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
{
- (*Module)->Flags |= IMAGE_NOT_AT_BASE;
+ (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
}
/*
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
if (!NT_SUCCESS(Status))
{
- CHECKPOINT1;
return NULL;
}
DPRINT("AddressOfEntryPoint = %x\n",(ULONG)NTHeaders->OptionalHeader.AddressOfEntryPoint);
if (NTHeaders->OptionalHeader.AddressOfEntryPoint != 0)
{
- EntryPoint = (PEPFUNC) (ImageBase
+ EntryPoint = (PEPFUNC) ((ULONG_PTR)ImageBase
+ NTHeaders->OptionalHeader.AddressOfEntryPoint);
}
DPRINT("LdrPEStartup() = %x\n",EntryPoint);
LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
IN ULONG LoadFlags,
IN PUNICODE_STRING Name,
- PLDR_MODULE *Module)
+ PLDR_DATA_TABLE_ENTRY *Module,
+ PVOID *BaseAddress OPTIONAL)
{
UNICODE_STRING AdjustedName;
UNICODE_STRING FullDosName;
NTSTATUS Status;
- PLDR_MODULE tmpModule;
+ PLDR_DATA_TABLE_ENTRY tmpModule;
HANDLE SectionHandle;
ULONG ViewSize;
PVOID ImageBase;
PIMAGE_NT_HEADERS NtHeaders;
+ BOOLEAN MappedAsDataFile;
if (Module == NULL)
{
DPRINT("%wZ\n", &AdjustedName);
+ MappedAsDataFile = FALSE;
/* Test if dll is already loaded */
Status = LdrFindEntryForName(&AdjustedName, Module, TRUE);
if (NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&AdjustedName);
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = (*Module)->DllBase;
+ }
}
else
{
Status = LdrpMapKnownDll(&AdjustedName, &FullDosName, &SectionHandle);
if (!NT_SUCCESS(Status))
{
- Status = LdrpMapDllImageFile(SearchPath, &AdjustedName, &FullDosName, &SectionHandle);
+ MappedAsDataFile = (0 != (LoadFlags & LOAD_LIBRARY_AS_DATAFILE));
+ Status = LdrpMapDllImageFile(SearchPath, &AdjustedName, &FullDosName,
+ MappedAsDataFile, &SectionHandle);
}
if (!NT_SUCCESS(Status))
{
&ViewSize,
0,
MEM_COMMIT,
- PAGE_READWRITE);
+ PAGE_READONLY);
if (!NT_SUCCESS(Status))
{
DPRINT1("map view of section failed (Status %x)\n", Status);
NtClose(SectionHandle);
return(Status);
}
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = ImageBase;
+ }
/* Get and check the NT headers */
NtHeaders = RtlImageNtHeader(ImageBase);
if (NtHeaders == NULL)
RtlFreeUnicodeString(&FullDosName);
return STATUS_UNSUCCESSFUL;
}
+ DPRINT("Mapped %wZ at %x\n", &FullDosName, ImageBase);
+ if (MappedAsDataFile)
+ {
+ ASSERT(NULL != BaseAddress);
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = (PVOID) ((char *) *BaseAddress + 1);
+ }
+ *Module = NULL;
+ RtlFreeUnicodeString(&FullDosName);
+ NtClose(SectionHandle);
+ return STATUS_SUCCESS;
+ }
/* If the base address is different from the
* one the DLL is actually loaded, perform any
* relocation. */
}
}
*Module = LdrAddModuleEntry(ImageBase, NtHeaders, FullDosName.Buffer);
- (*Module)->SectionHandle = SectionHandle;
+ (*Module)->SectionPointer = SectionHandle;
if (ImageBase != (PVOID) NtHeaders->OptionalHeader.ImageBase)
{
- (*Module)->Flags |= IMAGE_NOT_AT_BASE;
+ (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
}
if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
{
- (*Module)->Flags |= IMAGE_DLL;
+ (*Module)->Flags |= LDRP_IMAGE_DLL;
}
/* fixup the imported calls entry points */
Status = LdrFixupImports(SearchPath, *Module);
}
static NTSTATUS
-LdrpUnloadModule(PLDR_MODULE Module,
- BOOL Unload)
+LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
+ BOOLEAN Unload)
{
- PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
+ PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
PCHAR ImportedName;
- PLDR_MODULE ImportedModule;
+ PLDR_DATA_TABLE_ENTRY ImportedModule;
NTSTATUS Status;
LONG LoadCount;
-
+ ULONG Size;
if (Unload)
{
if (LoadCount == 0)
{
/* ?????????????????? */
- CHECKPOINT1;
}
else if (LoadCount == 1)
{
BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
- NULL);
+ &Size);
if (BoundImportDescriptor)
{
/* dereferencing all imported modules, use the bound import descriptor */
}
else
{
- ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
- RtlImageDirectoryEntryToData(Module->BaseAddress,
+ ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ &Size);
if (ImportModuleDirectory)
{
/* dereferencing all imported modules, use the import descriptor */
- while (ImportModuleDirectory->dwRVAModuleName)
+ while (ImportModuleDirectory->Name)
{
- ImportedName = (PCHAR)Module->BaseAddress + ImportModuleDirectory->dwRVAModuleName;
+ ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectory->Name;
TRACE_LDR("%wZ trys to unload %s\n", &Module->BaseDllName, ImportedName);
Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
if (!NT_SUCCESS(Status))
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrUnloadDll (IN PVOID BaseAddress)
{
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
NTSTATUS Status;
if (BaseAddress == NULL)
return STATUS_SUCCESS;
- Status = LdrFindEntryForAddress(BaseAddress, &Module);
- if (NT_SUCCESS(Status))
+ if (LdrMappedAsDataFile(&BaseAddress))
{
- TRACE_LDR("LdrUnloadDll, , unloading %wZ\n", &Module->BaseDllName);
- Status = LdrpUnloadModule(Module, TRUE);
+ Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
+ else
+ {
+ Status = LdrFindEntryForAddress(BaseAddress, &Module);
+ if (NT_SUCCESS(Status))
+ {
+ TRACE_LDR("LdrUnloadDll, , unloading %wZ\n", &Module->BaseDllName);
+ Status = LdrpUnloadModule(Module, TRUE);
+ }
+ }
+
return Status;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
NTSTATUS Status;
DPRINT("LdrDisableThreadCalloutsForDll (BaseAddress %x)\n", BaseAddress);
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
- DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->BaseAddress);
+ DPRINT("BaseDllName %wZ BaseAddress %x\n", &Module->BaseDllName, Module->DllBase);
- if (Module->BaseAddress == BaseAddress)
+ if (Module->DllBase == BaseAddress)
{
- if (Module->TlsIndex == -1)
+ if (Module->TlsIndex == 0xFFFF)
{
- Module->Flags |= DONT_CALL_FOR_THREAD;
+ Module->Flags |= LDRP_DONT_CALL_FOR_THREADS;
Status = STATUS_SUCCESS;
}
break;
/*
* @implemented
*/
-NTSTATUS STDCALL
-LdrGetDllHandle(IN PWCHAR Path OPTIONAL,
- IN ULONG Unknown2,
+NTSTATUS NTAPI
+LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
+ IN PULONG DllCharacteristics,
IN PUNICODE_STRING DllName,
- OUT PVOID* BaseAddress)
+ OUT PVOID *DllHandle)
{
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
NTSTATUS Status;
- TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n", DllName, Path ? Path : L"");
+ TRACE_LDR("LdrGetDllHandle, searching for %wZ from %S\n",
+ DllName, DllPath ? DllPath : L"");
/* NULL is the current executable */
if (DllName == NULL)
{
- *BaseAddress = ExeModule->BaseAddress;
- DPRINT("BaseAddress %x\n", *BaseAddress);
+ *DllHandle = ExeModule->DllBase;
+ DPRINT("BaseAddress %x\n", *DllHandle);
return STATUS_SUCCESS;
}
Status = LdrFindEntryForName(DllName, &Module, FALSE);
if (NT_SUCCESS(Status))
{
- *BaseAddress = Module->BaseAddress;
+ *DllHandle = Module->DllBase;
return STATUS_SUCCESS;
}
DPRINT("Failed to find dll %wZ\n", DllName);
- *BaseAddress = NULL;
+ *DllHandle = NULL;
return STATUS_DLL_NOT_FOUND;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrGetProcedureAddress (IN PVOID BaseAddress,
IN PANSI_STRING Name,
IN ULONG Ordinal,
* The loader lock must be held on enty.
*/
static VOID
-LdrpDetachProcess(BOOL UnloadAll)
+LdrpDetachProcess(BOOLEAN UnloadAll)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
static ULONG CallingCount = 0;
DPRINT("LdrpDetachProcess() called for %wZ\n",
Entry = ModuleListHead->Blink;
while (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 = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ if (((UnloadAll && Module->LoadCount == 0xFFFF) || Module->LoadCount == 0) &&
+ Module->Flags & LDRP_ENTRY_PROCESSED &&
+ !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
{
- Module->Flags |= UNLOAD_IN_PROGRESS;
+ Module->Flags |= LDRP_UNLOAD_IN_PROGRESS;
if (Module == LdrpLastModule)
{
LdrpLastModule = NULL;
}
- if (Module->Flags & PROCESS_ATTACH_CALLED)
+ if (Module->Flags & LDRP_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));
+ LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == 0xFFFF ? 1 : 0));
}
else
{
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
Entry = Entry->Blink;
- if (Module->Flags & UNLOAD_IN_PROGRESS &&
- ((UnloadAll && Module->LoadCount >= 0) || Module->LoadCount == 0))
+ if (Module->Flags & LDRP_UNLOAD_IN_PROGRESS &&
+ ((UnloadAll && Module->LoadCount != 0xFFFF) || Module->LoadCount == 0))
{
/* remove the module entry from the list */
RemoveEntryList (&Module->InLoadOrderModuleList);
RemoveEntryList (&Module->InInitializationOrderModuleList);
- NtUnmapViewOfSection (NtCurrentProcess (), Module->BaseAddress);
- NtClose (Module->SectionHandle);
+ NtUnmapViewOfSection (NtCurrentProcess (), Module->DllBase);
+ NtClose (Module->SectionPointer);
TRACE_LDR("%wZ unloaded\n", &Module->BaseDllName);
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
- BOOL Result;
+ PLDR_DATA_TABLE_ENTRY Module;
+ BOOLEAN Result;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("LdrpAttachProcess() called for %wZ\n",
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
- if (!(Module->Flags & (LOAD_IN_PROGRESS|UNLOAD_IN_PROGRESS|ENTRY_PROCESSED)))
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ if (!(Module->Flags & (LDRP_LOAD_IN_PROGRESS|LDRP_UNLOAD_IN_PROGRESS|LDRP_ENTRY_PROCESSED)))
{
- Module->Flags |= LOAD_IN_PROGRESS;
+ Module->Flags |= LDRP_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));
+ Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(Module->LoadCount == 0xFFFF ? 1 : 0));
if (!Result)
{
Status = STATUS_DLL_INIT_FAILED;
break;
}
- if (Module->Flags & IMAGE_DLL && Module->EntryPoint != 0)
+ if (Module->Flags & LDRP_IMAGE_DLL && Module->EntryPoint != 0)
{
- Module->Flags |= PROCESS_ATTACH_CALLED|ENTRY_PROCESSED;
+ Module->Flags |= LDRP_PROCESS_ATTACH_CALLED|LDRP_ENTRY_PROCESSED;
}
else
{
- Module->Flags |= ENTRY_PROCESSED;
+ Module->Flags |= LDRP_ENTRY_PROCESSED;
}
- Module->Flags &= ~LOAD_IN_PROGRESS;
+ Module->Flags &= ~LDRP_LOAD_IN_PROGRESS;
}
Entry = Entry->Flink;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrShutdownProcess (VOID)
{
LdrpDetachProcess(TRUE);
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
NTSTATUS Status;
DPRINT("LdrpAttachThread() called for %wZ\n",
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))
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
+ !(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
+ !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
{
TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
&Module->BaseDllName, Module->EntryPoint);
}
Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrShutdownThread (VOID)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
+ PLDR_DATA_TABLE_ENTRY Module;
DPRINT("LdrShutdownThread() called for %wZ\n",
&ExeModule->BaseDllName);
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
- if (Module->Flags & PROCESS_ATTACH_CALLED &&
- !(Module->Flags & DONT_CALL_FOR_THREAD) &&
- !(Module->Flags & UNLOAD_IN_PROGRESS))
+ if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
+ !(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
+ !(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
{
TRACE_LDR("%wZ - Calling entry point at %x for thread detaching\n",
&Module->BaseDllName, Module->EntryPoint);
*
* @implemented
*/
-NTSTATUS STDCALL
-LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL,
+NTSTATUS NTAPI
+LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL,
IN ULONG Size OPTIONAL,
OUT PULONG ReturnedSize)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
- PLDR_MODULE Module;
- PDEBUG_MODULE_INFORMATION ModulePtr = NULL;
+ PLDR_DATA_TABLE_ENTRY Module;
+ PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG UsedSize = sizeof(ULONG);
ANSI_STRING AnsiString;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
DPRINT(" Module %wZ\n",
&Module->FullDllName);
else if (ModuleInformation != NULL)
{
ModulePtr->Reserved[0] = ModulePtr->Reserved[1] = 0; // FIXME: ??
- ModulePtr->Base = Module->BaseAddress;
+ ModulePtr->Base = Module->DllBase;
ModulePtr->Size = Module->SizeOfImage;
ModulePtr->Flags = Module->Flags;
ModulePtr->Index = 0; // FIXME: index ??
ModulePtr++;
ModuleInformation->ModuleCount++;
}
- UsedSize += sizeof(DEBUG_MODULE_INFORMATION);
+ UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
Entry = Entry->Flink;
}
return (BOOLEAN)(CalcSum == HeaderSum);
}
+/*
+ * Compute size of an image as it is actually present in virt memory
+ * (i.e. excluding NEVER_LOAD sections)
+ */
+ULONG
+LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
+{
+ PIMAGE_SECTION_HEADER SectionHeader;
+ unsigned SectionIndex;
+ ULONG ResidentSize;
+
+ SectionHeader = (PIMAGE_SECTION_HEADER)((char *) &NTHeaders->OptionalHeader
+ + NTHeaders->FileHeader.SizeOfOptionalHeader);
+ ResidentSize = 0;
+ for (SectionIndex = 0; SectionIndex < NTHeaders->FileHeader.NumberOfSections; SectionIndex++)
+ {
+ if (0 == (SectionHeader->Characteristics & IMAGE_SCN_LNK_REMOVE)
+ && ResidentSize < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)
+ {
+ ResidentSize = SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize;
+ }
+ SectionHeader++;
+ }
+
+ return ResidentSize;
+}
+
/***************************************************************************
* NAME EXPORTED
*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
ULONG Unknown1,
ULONG Unknown2,
DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
Status = NtCreateSection (&SectionHandle,
- SECTION_MAP_EXECUTE,
+ SECTION_MAP_READ,
NULL,
NULL,
- PAGE_EXECUTE,
+ PAGE_READONLY,
SEC_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
&ViewSize,
ViewShare,
0,
- PAGE_EXECUTE);
+ PAGE_READONLY);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
IN PCWSTR ValueName,
IN ULONG Type,
}
-PIMAGE_BASE_RELOCATION STDCALL
+PIMAGE_BASE_RELOCATION NTAPI
LdrProcessRelocationBlock(IN PVOID Address,
IN USHORT Count,
IN PUSHORT TypeOffset,
break;
case IMAGE_REL_BASED_HIGH:
- ShortPtr = (PUSHORT)(Address + Offset);
+ ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
*ShortPtr += HIWORD(Delta);
break;
case IMAGE_REL_BASED_LOW:
- ShortPtr = (PUSHORT)(Address + Offset);
+ ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
*ShortPtr += LOWORD(Delta);
break;
case IMAGE_REL_BASED_HIGHLOW:
- LongPtr = (PULONG)(Address + Offset);
+ LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
*LongPtr += Delta;
break;