-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/ldr/utils.c
#define NDEBUG
#include <debug.h>
-#define LDRP_PROCESS_CREATION_TIME 0x8000000
+#define LDRP_PROCESS_CREATION_TIME 0xffff
+#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
/* 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)
+#define TRACE_LDR(...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(__VA_ARGS__); }
#endif
typedef struct _TLS_DATA
PVOID StartAddressOfRawData;
DWORD TlsDataSize;
DWORD TlsZeroSize;
- PIMAGE_TLS_CALLBACK TlsAddressOfCallBacks;
+ PIMAGE_TLS_CALLBACK *TlsAddressOfCallBacks;
PLDR_DATA_TABLE_ENTRY Module;
} TLS_DATA, *PTLS_DATA;
+static BOOLEAN LdrpDllShutdownInProgress = FALSE;
static PTLS_DATA LdrpTlsArray = NULL;
static ULONG LdrpTlsCount = 0;
static ULONG LdrpTlsSize = 0;
/* FUNCTIONS *****************************************************************/
-#if defined(DBG) || defined(KDBG)
+#if DBG || defined(KDBG)
VOID
LdrpLoadUserModuleSymbols(PLDR_DATA_TABLE_ENTRY LdrModule)
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
}
LoadCount = Module->LoadCount;
- if (Module->LoadCount > 0 && Module->LoadCount != 0xFFFF)
+ if (Module->LoadCount > 0 && Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
{
Module->LoadCount--;
}
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
}
LoadCount = Module->LoadCount;
- if (Module->LoadCount != 0xFFFF)
+ if (Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
{
Module->LoadCount++;
}
static __inline VOID LdrpTlsCallback(PLDR_DATA_TABLE_ENTRY Module, ULONG dwReason)
{
- PIMAGE_TLS_CALLBACK TlsCallback;
- if (Module->TlsIndex != 0xFFFF && Module->LoadCount == 0xFFFF)
+ PIMAGE_TLS_CALLBACK *TlsCallback;
+ if (Module->TlsIndex != 0xFFFF && Module->LoadCount == LDRP_PROCESS_CREATION_TIME)
{
TlsCallback = LdrpTlsArray[Module->TlsIndex].TlsAddressOfCallBacks;
if (TlsCallback)
while (*TlsCallback)
{
TRACE_LDR("%wZ - Calling tls callback at %x\n",
- &Module->BaseDllName, TlsCallback);
- TlsCallback(Module->DllBase, dwReason, NULL);
- TlsCallback = (PIMAGE_TLS_CALLBACK)((ULONG_PTR)TlsCallback + sizeof(PVOID));
+ &Module->BaseDllName, *TlsCallback);
+ (*TlsCallback)(Module->DllBase, dwReason, NULL);
+ TlsCallback++;
}
}
}
return ((PDLLMAIN_FUNC)Module->EntryPoint)(Module->DllBase, dwReason, lpReserved);
}
+static PWSTR
+LdrpQueryAppPaths(IN PCWSTR ImageName)
+{
+ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ WCHAR SearchPathBuffer[5*MAX_PATH];
+ UNICODE_STRING ValueNameString;
+ UNICODE_STRING KeyName;
+ WCHAR NameBuffer[MAX_PATH];
+ ULONG KeyInfoSize;
+ ULONG ResultSize;
+ PWCHAR Backslash;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PWSTR Path = NULL;
+
+ _snwprintf(NameBuffer,
+ sizeof(NameBuffer) / sizeof(WCHAR),
+ L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s",
+ ImageName);
+
+ RtlInitUnicodeString(&KeyName, NameBuffer);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenKey(&KeyHandle,
+ KEY_READ,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT ("NtOpenKey() failed (Status %lx)\n", Status);
+ return NULL;
+ }
+
+ KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR);
+
+ KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize);
+ if (KeyInfo == NULL)
+ {
+ DPRINT("RtlAllocateHeap() failed\n");
+ NtClose(KeyHandle);
+ return NULL;
+ }
+
+ RtlInitUnicodeString(&ValueNameString,
+ L"Path");
+
+ Status = NtQueryValueKey(KeyHandle,
+ &ValueNameString,
+ KeyValuePartialInformation,
+ KeyInfo,
+ KeyInfoSize,
+ &ResultSize);
+
+ if (!NT_SUCCESS(Status))
+ {
+ NtClose(KeyHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+ return NULL;
+ }
+
+ RtlCopyMemory(SearchPathBuffer,
+ &KeyInfo->Data,
+ KeyInfo->DataLength);
+
+ /* Free KeyInfo memory, we won't need it anymore */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+
+ /* Close the key handle */
+ NtClose(KeyHandle);
+
+ /* get application running path */
+ wcscat(SearchPathBuffer, L";");
+ wcscat(SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer); // FIXME: Don't rely on it being NULL-terminated!!!
+
+ /* Remove trailing backslash */
+ Backslash = wcsrchr(SearchPathBuffer, L'\\');
+ if (Backslash) Backslash = L'\0';
+
+ wcscat(SearchPathBuffer, L";");
+
+ wcscat(SearchPathBuffer, SharedUserData->NtSystemRoot);
+ wcscat(SearchPathBuffer, L"\\system32;");
+ wcscat(SearchPathBuffer, SharedUserData->NtSystemRoot);
+ wcscat(SearchPathBuffer, L";.");
+
+ /* Copy it to the heap allocd memory */
+ Path = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ wcslen(SearchPathBuffer) * sizeof(WCHAR));
+
+ if (!Path)
+ {
+ DPRINT1("RtlAllocateHeap() failed\n");
+ return NULL;
+ }
+
+ wcscpy(Path, SearchPathBuffer);
+
+ return Path;
+}
+
static NTSTATUS
LdrpInitializeTlsForThread(VOID)
{
}
}
}
+
DPRINT("LdrpInitializeTlsForThread() done\n");
return STATUS_SUCCESS;
}
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
- if (Module->LoadCount == 0xFFFF &&
+ if (Module->LoadCount == LDRP_PROCESS_CREATION_TIME &&
Module->TlsIndex != 0xFFFF)
{
TlsDirectory = (PIMAGE_TLS_DIRECTORY)
TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
if (TlsDirectory->AddressOfCallBacks)
- TlsData->TlsAddressOfCallBacks = *(PIMAGE_TLS_CALLBACK*)TlsDirectory->AddressOfCallBacks;
+ TlsData->TlsAddressOfCallBacks = (PIMAGE_TLS_CALLBACK *)TlsDirectory->AddressOfCallBacks;
else
TlsData->TlsAddressOfCallBacks = NULL;
TlsData->Module = Module;
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("AddressOfCallBacks: %x\n", TlsDirectory->AddressOfCallBacks);
DbgPrint("SizeOfZeroFill: %d\n", TlsDirectory->SizeOfZeroFill);
DbgPrint("Characteristics: %x\n", TlsDirectory->Characteristics);
#endif
Entry = Entry->Flink;
}
}
+
DPRINT("LdrpInitializeTlsForProccess() done\n");
return STATUS_SUCCESS;
}
L"KnownDllPath");
InitializeObjectAttributes(&ObjectAttributes,
&Name,
- OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
+ OBJ_CASE_INSENSITIVE,
LdrpKnownDllsDirHandle,
NULL);
Status = NtOpenSymbolicLinkObject(&LinkHandle,
ASSERT(Module);
memset(Module, 0, sizeof(LDR_DATA_TABLE_ENTRY));
Module->DllBase = (PVOID)ImageBase;
- Module->EntryPoint = (PVOID)NTHeaders->OptionalHeader.AddressOfEntryPoint;
+ Module->EntryPoint = (PVOID)(ULONG_PTR)NTHeaders->OptionalHeader.AddressOfEntryPoint;
if (Module->EntryPoint != 0)
Module->EntryPoint = (PVOID)((ULONG_PTR)Module->EntryPoint + (ULONG_PTR)Module->DllBase);
Module->SizeOfImage = LdrpGetResidentSize(NTHeaders);
* loading while app is initializing
* dll must not be unloaded
*/
- Module->LoadCount = 0xFFFF;
+ Module->LoadCount = LDRP_PROCESS_CREATION_TIME;
}
Module->Flags = 0;
NULL) == 0)
return STATUS_DLL_NOT_FOUND;
-
if (!RtlDosPathNameToNtPathName_U (DosName,
&FullNtFileName,
NULL,
0,
FullNtFileName.Buffer);
- Status = NtReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- BlockBuffer,
- sizeof(BlockBuffer),
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
+ if (!MapAsDataFile)
{
- DPRINT("Dll header read failed: Status = 0x%08lx\n", Status);
- NtClose(FileHandle);
- return Status;
- }
- /*
- * Overlay DOS and NT headers structures to the
- * buffer with DLL's header raw data.
- */
- DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
- NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
- /*
- * Check it is a PE image file.
- */
- if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- || (DosHeader->e_lfanew == 0L)
- || (*(PULONG)(NTHeaders) != IMAGE_NT_SIGNATURE))
- {
- DPRINT("NTDLL format invalid\n");
- NtClose(FileHandle);
- return STATUS_UNSUCCESSFUL;
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ BlockBuffer,
+ sizeof(BlockBuffer),
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Dll header read failed: Status = 0x%08lx\n", Status);
+ NtClose(FileHandle);
+ return Status;
+ }
+
+ /*
+ * Overlay DOS and NT headers structures to the
+ * buffer with DLL's header raw data.
+ */
+ DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
+ NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
+ /*
+ * Check it is a PE image file.
+ */
+ if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ || (DosHeader->e_lfanew == 0L)
+ || (*(PULONG)(NTHeaders) != IMAGE_NT_SIGNATURE))
+ {
+ DPRINT("NTDLL format invalid\n");
+ NtClose(FileHandle);
+
+ return STATUS_UNSUCCESSFUL;
+ }
}
/*
NULL,
NULL,
PAGE_READONLY,
- SEC_COMMIT | (MapAsDataFile ? 0 : SEC_IMAGE),
+ MapAsDataFile ? SEC_COMMIT : SEC_IMAGE,
FileHandle);
NtClose(FileHandle);
LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
IN PULONG LoadFlags OPTIONAL,
IN PUNICODE_STRING Name,
- OUT PVOID *BaseAddress OPTIONAL)
+ OUT PVOID *BaseAddress /* also known as HMODULE*, and PHANDLE 'DllHandle' */)
{
NTSTATUS Status;
- PLDR_DATA_TABLE_ENTRY Module;
+ PLDR_DATA_TABLE_ENTRY Module;
+
+ PPEB Peb = NtCurrentPeb();
TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
Name,
- SearchPath ? " from " : "",
+ SearchPath ? L" from " : L"",
SearchPath ? SearchPath : L"");
- if (Name == NULL)
- {
- if (BaseAddress)
- *BaseAddress = NtCurrentPeb()->ImageBaseAddress;
- return STATUS_SUCCESS;
- }
-
- if (BaseAddress)
- *BaseAddress = NULL;
-
Status = LdrpLoadModule(SearchPath, LoadFlags ? *LoadFlags : 0, Name, &Module, BaseAddress);
- if (NT_SUCCESS(Status)
- && (!LoadFlags || 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE)))
+
+ if (NT_SUCCESS(Status) &&
+ (!LoadFlags || 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE)))
{
- RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
- Status = LdrpAttachProcess();
- RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
- if (NT_SUCCESS(Status) && BaseAddress)
+ if (!(Module->Flags & LDRP_PROCESS_ATTACH_CALLED))
{
- *BaseAddress = Module->DllBase;
+ RtlEnterCriticalSection(Peb->LoaderLock);
+ Status = LdrpAttachProcess();
+ RtlLeaveCriticalSection(Peb->LoaderLock);
}
- }
+ }
+
+ if ((!Module) && (NT_SUCCESS(Status)))
+ return Status;
+
+ *BaseAddress = NT_SUCCESS(Status) ? Module->DllBase : NULL;
+
return Status;
}
PLDR_DATA_TABLE_ENTRY ModulePtr;
BOOLEAN ContainsPath;
UNICODE_STRING AdjustedName;
- unsigned i;
DPRINT("LdrFindEntryForName(Name %wZ)\n", Name);
return(STATUS_SUCCESS);
}
- LdrAdjustDllName (&AdjustedName, Name, FALSE);
-
- ContainsPath = (AdjustedName.Length >= 2 * sizeof(WCHAR) && L':' == AdjustedName.Buffer[1]);
- for (i = 0; ! ContainsPath && i < AdjustedName.Length / sizeof(WCHAR); i++)
- {
- ContainsPath = L'\\' == AdjustedName.Buffer[i] ||
- L'/' == AdjustedName.Buffer[i];
- }
+ ContainsPath = (Name->Length >= 2 * sizeof(WCHAR) && L':' == Name->Buffer[1]);
+ LdrAdjustDllName (&AdjustedName, Name, !ContainsPath);
if (LdrpLastModule)
{
0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule;
- if (Ref && (*Module)->LoadCount != 0xFFFF)
+ if (Ref && (*Module)->LoadCount != LDRP_PROCESS_CREATION_TIME)
{
(*Module)->LoadCount++;
}
0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
{
*Module = LdrpLastModule = ModulePtr;
- if (Ref && ModulePtr->LoadCount != 0xFFFF)
+ if (Ref && ModulePtr->LoadCount != LDRP_PROCESS_CREATION_TIME)
{
ModulePtr->LoadCount++;
}
*/
if (!NT_SUCCESS(Status))
{
- ULONG Flags = LDRP_PROCESS_CREATION_TIME;
Status = LdrLoadDll(NULL,
- &Flags,
+ NULL,
&DllName,
&BaseAddress);
if (NT_SUCCESS(Status))
? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
: NULL);
- if (((ULONG)Function >= (ULONG)ExportDir) &&
- ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+ if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
+ ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + (ULONG_PTR)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
&ExportDirSize);
if (ExportDir == NULL)
{
- DPRINT1("LdrGetExportByName(): no export directory!\n");
+ DPRINT1("LdrGetExportByName(): no export directory, "
+ "can't lookup %s/%hu!\n", SymbolName, Hint);
return NULL;
}
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- if (((ULONG)Function >= (ULONG)ExportDir) &&
- ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+ if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
+ ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + (ULONG_PTR)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- if (((ULONG)Function >= (ULONG)ExportDir) &&
- ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+ if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
+ ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + (ULONG_PTR)ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrFixupForward((PCHAR)Function);
}
}
- DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
+ DPRINT("LdrGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
{
PIMAGE_DATA_DIRECTORY RelocationDDir;
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
- ULONG Count, ProtectSize, OldProtect, OldProtect2;
+ ULONG Count, OldProtect, OldProtect2;
+ SIZE_T ProtectSize;
PVOID Page, ProtectPage, ProtectPage2;
PUSHORT TypeOffset;
ULONG_PTR Delta;
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
{
- return STATUS_UNSUCCESSFUL;
+ return STATUS_SUCCESS;
}
RelocationDDir =
}
static NTSTATUS
-LdrpGetOrLoadModule(PWCHAR SerachPath,
+LdrpGetOrLoadModule(PWCHAR SearchPath,
PCHAR Name,
PLDR_DATA_TABLE_ENTRY* Module,
BOOLEAN Load)
{
+ ANSI_STRING AnsiDllName;
UNICODE_STRING DllName;
NTSTATUS Status;
DPRINT("LdrpGetOrLoadModule() called for %s\n", Name);
- RtlCreateUnicodeStringFromAsciiz (&DllName, Name);
+ RtlInitAnsiString(&AnsiDllName, Name);
+ Status = RtlAnsiStringToUnicodeString(&DllName, &AnsiDllName, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
Status = LdrFindEntryForName (&DllName, Module, Load);
if (Load && !NT_SUCCESS(Status))
{
- Status = LdrpLoadModule(SerachPath,
- NtCurrentPeb()->Ldr->Initialized ? 0 : LDRP_PROCESS_CREATION_TIME,
+ Status = LdrpLoadModule(SearchPath,
+ 0,
&DllName,
Module,
- NULL);
+ NULL);
if (NT_SUCCESS(Status))
{
Status = LdrFindEntryForName (&DllName, Module, FALSE);
}
if (!NT_SUCCESS(Status))
{
+ ULONG ErrorResponse;
+ ULONG_PTR ErrorParameter = (ULONG_PTR)&DllName;
+
DPRINT1("failed to load %wZ\n", &DllName);
+ NtRaiseHardError(STATUS_DLL_NOT_FOUND,
+ 1,
+ 1,
+ &ErrorParameter,
+ OptionOk,
+ &ErrorResponse);
}
}
RtlFreeUnicodeString (&DllName);
return Status;
}
+void
+RtlpRaiseImportNotFound(CHAR *FuncName, ULONG Ordinal, PUNICODE_STRING DllName)
+{
+ ULONG ErrorResponse;
+ ULONG_PTR ErrorParameters[2];
+ ANSI_STRING ProcNameAnsi;
+ UNICODE_STRING ProcName;
+ CHAR Buffer[8];
+
+ if (!FuncName)
+ {
+ _snprintf(Buffer, 8, "# %ld", Ordinal);
+ FuncName = Buffer;
+ }
+
+ RtlInitAnsiString(&ProcNameAnsi, FuncName);
+ RtlAnsiStringToUnicodeString(&ProcName, &ProcNameAnsi, TRUE);
+ ErrorParameters[0] = (ULONG_PTR)&ProcName;
+ ErrorParameters[1] = (ULONG_PTR)DllName;
+ NtRaiseHardError(STATUS_ENTRYPOINT_NOT_FOUND,
+ 2,
+ 3,
+ ErrorParameters,
+ OptionOk,
+ &ErrorResponse);
+ RtlFreeUnicodeString(&ProcName);
+}
+
static NTSTATUS
LdrpProcessImportDirectoryEntry(PLDR_DATA_TABLE_ENTRY Module,
PLDR_DATA_TABLE_ENTRY ImportedModule,
PVOID IATBase;
ULONG OldProtect;
ULONG Ordinal;
- ULONG IATSize;
+ SIZE_T IATSize;
if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
{
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
- return STATUS_UNSUCCESSFUL;
+ RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
+ return STATUS_ENTRYPOINT_NOT_FOUND;
}
}
else
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
- return STATUS_UNSUCCESSFUL;
+ RtlpRaiseImportNotFound((CHAR*)pe_name->Name, 0, &ImportedModule->FullDllName);
+ return STATUS_ENTRYPOINT_NOT_FOUND;
}
}
ImportAddressList++;
PVOID IATBase;
ULONG OldProtect;
ULONG Offset;
- ULONG IATSize;
+ SIZE_T IATSize;
PIMAGE_NT_HEADERS NTHeaders;
PCHAR Name;
ULONG Size;
NTSTATUS Status;
PLDR_DATA_TABLE_ENTRY ImportedModule;
PCHAR ImportedName;
+ PWSTR ModulePath;
ULONG Size;
DPRINT("LdrFixupImports(SearchPath %S, Module %p)\n", SearchPath, Module);
TlsSize = TlsDirectory->EndAddressOfRawData
- TlsDirectory->StartAddressOfRawData
+ TlsDirectory->SizeOfZeroFill;
- if (TlsSize > 0 &&
- NtCurrentPeb()->Ldr->Initialized)
+
+ if (TlsSize > 0 && NtCurrentPeb()->Ldr->Initialized)
{
- TRACE_LDR("Trying to load dynamicly %wZ which contains a tls directory\n",
+ TRACE_LDR("Trying to dynamically load %wZ which contains a TLS directory\n",
&Module->BaseDllName);
- return STATUS_UNSUCCESSFUL;
+ TlsDirectory = NULL;
}
}
+
/*
* Process each import module.
*/
else
{
TRACE_LDR("%wZ has correct binding to %wZ\n",
- &Module->BaseDllName, &ImportedModule->BaseDllName);
+ &Module->BaseDllName, &ImportedModule->BaseDllName);
}
if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
{
ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectoryCurrent->Name;
TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);
+ if (SearchPath == NULL)
+ {
+ ModulePath = LdrpQueryAppPaths(Module->BaseDllName.Buffer);
+
+ Status = LdrpGetOrLoadModule(ModulePath, ImportedName, &ImportedModule, TRUE);
+ if (ModulePath != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, ModulePath);
+ if (NT_SUCCESS(Status)) goto Success;
+ }
+
Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("failed to load %s\n", ImportedName);
return Status;
}
+Success:
if (Module == ImportedModule)
{
LdrpDecrementLoadCount(Module, FALSE);
NTSTATUS Status;
PLDR_DATA_TABLE_ENTRY tmpModule;
HANDLE SectionHandle;
- ULONG ViewSize;
+ SIZE_T ViewSize;
PVOID ImageBase;
PIMAGE_NT_HEADERS NtHeaders;
BOOLEAN MappedAsDataFile;
ImageBase = 0;
ArbitraryUserPointer = NtCurrentTeb()->Tib.ArbitraryUserPointer;
NtCurrentTeb()->Tib.ArbitraryUserPointer = FullDosName.Buffer;
- DPRINT1("POI. DAT: %p %S\n", NtCurrentTeb()->Tib.ArbitraryUserPointer, FullDosName.Buffer);
Status = NtMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&ImageBase,
0,
NULL,
&ViewSize,
+ ViewShare,
0,
- MEM_COMMIT,
PAGE_READONLY);
NtCurrentTeb()->Tib.ArbitraryUserPointer = ArbitraryUserPointer;
- DPRINT1("Poi gone!\n");
if (!NT_SUCCESS(Status))
{
DPRINT1("map view of section failed (Status 0x%08lx)\n", Status);
{
*BaseAddress = ImageBase;
}
- /* Get and check the NT headers */
- NtHeaders = RtlImageNtHeader(ImageBase);
- if (NtHeaders == NULL)
+ if (!MappedAsDataFile)
{
- DPRINT1("RtlImageNtHeaders() failed\n");
- NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
- NtClose (SectionHandle);
- RtlFreeUnicodeString(&FullDosName);
- return STATUS_UNSUCCESSFUL;
+ /* Get and check the NT headers */
+ NtHeaders = RtlImageNtHeader(ImageBase);
+ if (NtHeaders == NULL)
+ {
+ DPRINT1("RtlImageNtHeaders() failed\n");
+ NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
+ NtClose (SectionHandle);
+ RtlFreeUnicodeString(&FullDosName);
+ return STATUS_UNSUCCESSFUL;
+ }
}
DPRINT("Mapped %wZ at %x\n", &FullDosName, ImageBase);
if (MappedAsDataFile)
DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
return Status;
}
-#if defined(DBG) || defined(KDBG)
+#if DBG || defined(KDBG)
LdrpLoadUserModuleSymbols(*Module);
#endif /* DBG || KDBG */
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
- &(*Module)->InInitializationOrderModuleList);
+ &(*Module)->InInitializationOrderLinks);
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
}
return STATUS_SUCCESS;
IN ULONG Ordinal,
OUT PVOID *ProcedureAddress)
{
+ NTSTATUS Status = STATUS_PROCEDURE_NOT_FOUND;
if (Name && Name->Length)
{
TRACE_LDR("LdrGetProcedureAddress by NAME - %Z\n", Name);
DPRINT("LdrGetProcedureAddress (BaseAddress %p Name %Z Ordinal %lu ProcedureAddress %p)\n",
BaseAddress, Name, Ordinal, ProcedureAddress);
- if (Name && Name->Length)
+ _SEH2_TRY
+ {
+ if (Name && Name->Length)
{
/* by name */
*ProcedureAddress = LdrGetExportByName(BaseAddress, (PUCHAR)Name->Buffer, 0xffff);
if (*ProcedureAddress != NULL)
{
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
}
DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
}
- else
+ else
{
/* by ordinal */
Ordinal &= 0x0000FFFF;
*ProcedureAddress = LdrGetExportByOrdinal(BaseAddress, (WORD)Ordinal);
if (*ProcedureAddress)
{
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
}
DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%lu\n", Ordinal);
}
- return STATUS_PROCEDURE_NOT_FOUND;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = STATUS_DLL_NOT_FOUND;
+ }
+ _SEH2_END;
+
+ return Status;
}
/**********************************************************************
DPRINT("LdrpDetachProcess() called for %wZ\n",
&ExeModule->BaseDllName);
+ if (UnloadAll)
+ LdrpDllShutdownInProgress = TRUE;
+
CallingCount++;
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
- if (((UnloadAll && Module->LoadCount == 0xFFFF) || Module->LoadCount == 0) &&
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
+ if (((UnloadAll && Module->LoadCount == LDRP_PROCESS_CREATION_TIME) || Module->LoadCount == 0) &&
Module->Flags & LDRP_ENTRY_PROCESSED &&
!(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
{
{
TRACE_LDR("Unload %wZ - Calling entry point at %x\n",
&Module->BaseDllName, Module->EntryPoint);
- LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(Module->LoadCount == 0xFFFF ? 1 : 0));
+ LdrpCallDllEntry(Module, DLL_PROCESS_DETACH, (PVOID)(INT_PTR)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0));
}
else
{
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
Entry = Entry->Blink;
if (Module->Flags & LDRP_UNLOAD_IN_PROGRESS &&
- ((UnloadAll && Module->LoadCount != 0xFFFF) || Module->LoadCount == 0))
+ ((UnloadAll && Module->LoadCount != LDRP_PROCESS_CREATION_TIME) || Module->LoadCount == 0))
{
/* remove the module entry from the list */
RemoveEntryList (&Module->InLoadOrderLinks);
- RemoveEntryList (&Module->InInitializationOrderModuleList);
+ RemoveEntryList (&Module->InInitializationOrderLinks);
NtUnmapViewOfSection (NtCurrentProcess (), Module->DllBase);
NtClose (Module->SectionPointer);
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
if (!(Module->Flags & (LDRP_LOAD_IN_PROGRESS|LDRP_UNLOAD_IN_PROGRESS|LDRP_ENTRY_PROCESSED)))
{
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 == 0xFFFF ? 1 : 0));
+ Result = LdrpCallDllEntry(Module, DLL_PROCESS_ATTACH, (PVOID)(INT_PTR)(Module->LoadCount == LDRP_PROCESS_CREATION_TIME ? 1 : 0));
if (!Result)
{
Status = STATUS_DLL_INIT_FAILED;
return Status;
}
+/*
+ * @implemented
+ */
+BOOLEAN NTAPI
+RtlDllShutdownInProgress (VOID)
+{
+ return LdrpDllShutdownInProgress;
+}
+
/*
* @implemented
*/
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
!(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
!(Module->Flags & LDRP_UNLOAD_IN_PROGRESS))
Entry = ModuleListHead->Blink;
while (Entry != ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
if (Module->Flags & LDRP_PROCESS_ATTACH_CALLED &&
!(Module->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
FILE_STANDARD_INFORMATION FileInfo;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE SectionHandle;
- ULONG ViewSize;
+ SIZE_T ViewSize;
PVOID BaseAddress;
BOOLEAN Result;
NTSTATUS Status;
LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
*LongPtr += Delta;
break;
+#ifdef _WIN64
+ case IMAGE_REL_BASED_DIR64:
+ LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
+ *LongPtr += Delta;
+ break;
+#endif
case IMAGE_REL_BASED_HIGHADJ:
case IMAGE_REL_BASED_MIPS_JMPADDR:
return (PIMAGE_BASE_RELOCATION)TypeOffset;
}
-/* EOF */
+NTSTATUS
+NTAPI
+LdrLockLoaderLock(IN ULONG Flags,
+ OUT PULONG Disposition OPTIONAL,
+ OUT PULONG Cookie OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+LdrUnlockLoaderLock(IN ULONG Flags,
+ IN ULONG Cookie OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+BOOLEAN
+NTAPI
+LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}