From 3920464d8ebca26bb394d420a786f0c6c2d5c696 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 8 Sep 2001 12:06:59 +0000 Subject: [PATCH] Implemented LdrFindEntryForAddress() and LdrQueryProcessModuleInformation(). svn path=/trunk/; revision=2239 --- reactos/include/ntdll/ldr.h | 107 ++++++++++----- reactos/lib/ntdll/def/ntdll.def | 14 +- reactos/lib/ntdll/def/ntdll.edf | 6 +- reactos/lib/ntdll/ldr/utils.c | 236 ++++++++++++++++++++++++++------ reactos/lib/ntdll/stubs/stubs.c | 5 - 5 files changed, 276 insertions(+), 92 deletions(-) diff --git a/reactos/include/ntdll/ldr.h b/reactos/include/ntdll/ldr.h index 998584e7ba6..2e84869ba96 100644 --- a/reactos/include/ntdll/ldr.h +++ b/reactos/include/ntdll/ldr.h @@ -28,6 +28,28 @@ typedef struct _LDR_MODULE #define RVA(m, b) ((ULONG)b + m) +typedef struct _MODULE_ENTRY +{ + ULONG Unknown0; + ULONG Unknown1; + PVOID BaseAddress; + ULONG SizeOfImage; + ULONG Flags; + USHORT Unknown2; + USHORT Unknown3; + SHORT LoadCount; + USHORT PathLength; + CHAR ModuleName[256]; +} MODULE_ENTRY, *PMODULE_ENTRY; + +typedef struct _MODULE_INFORMATION +{ + ULONG ModuleCount; + MODULE_ENTRY ModuleEntry[1]; +} MODULE_INFORMATION, *PMODULE_INFORMATION; + + + PEPFUNC LdrPEStartup(PVOID ImageBase, HANDLE SectionHandle); NTSTATUS LdrMapSections(HANDLE ProcessHandle, PVOID ImageBase, @@ -36,44 +58,53 @@ NTSTATUS LdrMapSections(HANDLE ProcessHandle, NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle, PHANDLE NTDllSectionHandle); - - -NTSTATUS STDCALL -LdrDisableThreadCalloutsForDll (IN PVOID BaseAddress); - -NTSTATUS STDCALL -LdrGetDllHandle (IN ULONG Unknown1, - IN ULONG Unknown2, - IN PUNICODE_STRING DllName, - OUT PVOID *BaseAddress); - -NTSTATUS STDCALL -LdrGetProcedureAddress (IN PVOID BaseAddress, - IN PANSI_STRING Name, - IN ULONG Ordinal, - OUT PVOID *ProcedureAddress); - -VOID STDCALL -LdrInitializeThunk (ULONG Unknown1, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4); - -NTSTATUS STDCALL -LdrLoadDll (IN PWSTR SearchPath OPTIONAL, - IN ULONG LoadFlags, - IN PUNICODE_STRING Name, - OUT PVOID *BaseAddress OPTIONAL); - -NTSTATUS STDCALL -LdrShutdownProcess (VOID); - -NTSTATUS STDCALL -LdrShutdownThread (VOID); - -NTSTATUS STDCALL -LdrUnloadDll (IN PVOID BaseAddress); - VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject); + + +NTSTATUS STDCALL +LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress); + +NTSTATUS STDCALL +LdrGetDllHandle(IN ULONG Unknown1, + IN ULONG Unknown2, + IN PUNICODE_STRING DllName, + OUT PVOID *BaseAddress); + +NTSTATUS STDCALL +LdrFindEntryForAddress(PVOID Address, + PLDR_MODULE *Module); + +NTSTATUS STDCALL +LdrGetProcedureAddress(IN PVOID BaseAddress, + IN PANSI_STRING Name, + IN ULONG Ordinal, + OUT PVOID *ProcedureAddress); + +VOID STDCALL +LdrInitializeThunk(ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4); + +NTSTATUS STDCALL +LdrLoadDll(IN PWSTR SearchPath OPTIONAL, + IN ULONG LoadFlags, + IN PUNICODE_STRING Name, + OUT PVOID *BaseAddress OPTIONAL); + +NTSTATUS STDCALL +LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL, + IN ULONG Size OPTIONAL, + OUT PULONG ReturnedSize); + +NTSTATUS STDCALL +LdrShutdownProcess(VOID); + +NTSTATUS STDCALL +LdrShutdownThread(VOID); + +NTSTATUS STDCALL +LdrUnloadDll(IN PVOID BaseAddress); + /* EOF */ diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index 5b1a727aa81..3cb35cf4cbe 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.78 2001/06/19 15:09:16 ekohl Exp $ +; $Id: ntdll.def,v 1.79 2001/09/08 12:05:30 ekohl Exp $ ; ; ReactOS Operating System ; @@ -34,17 +34,17 @@ KiUserCallbackDispatcher KiUserExceptionDispatcher LdrAccessResource@16 LdrDisableThreadCalloutsForDll@4 -;LdrEnumResources -;LdrFindEntryForAddress -;LdrFindResourceDirectory_U +;LdrEnumResources@20 +LdrFindEntryForAddress@8 +;LdrFindResourceDirectory_U@16 LdrFindResource_U@16 LdrGetDllHandle@16 LdrGetProcedureAddress@16 LdrInitializeThunk@16 LdrLoadDll@16 -;LdrProcessRelocationBlock -;LdrQueryImageFileExecutionOptions -;LdrQueryProcessModuleInformation +;LdrProcessRelocationBlock@16 +;LdrQueryImageFileExecutionOptions@24 +LdrQueryProcessModuleInformation@12 LdrShutdownProcess@0 LdrShutdownThread@0 LdrUnloadDll@4 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index ec7522f4c95..aa998a8e912 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.67 2001/06/19 15:09:16 ekohl Exp $ +; $Id: ntdll.edf,v 1.68 2001/09/08 12:05:30 ekohl Exp $ ; ; ReactOS Operating System ; @@ -35,7 +35,7 @@ KiUserExceptionDispatcher=KiUserExceptionDispatcher@8 LdrAccessResource=LdrAccessResource@16 LdrDisableThreadCalloutsForDll=LdrDisableThreadCalloutsForDll@4 ;LdrEnumResources -;LdrFindEntryForAddress +LdrFindEntryForAddress=LdrFindEntryForAddress@8 ;LdrFindResourceDirectory_U LdrFindResource_U=LdrFindResource_U@16 LdrGetDllHandle=LdrGetDllHandle@16 @@ -44,7 +44,7 @@ LdrInitializeThunk=LdrInitializeThunk@16 LdrLoadDll=LdrLoadDll@16 ;LdrProcessRelocationBlock ;LdrQueryImageFileExecutionOptions -;LdrQueryProcessModuleInformation +LdrQueryProcessModuleInformation=LdrQueryProcessModuleInformation@12 LdrShutdownProcess=LdrShutdownProcess@0 LdrShutdownThread=LdrShutdownThread@0 LdrUnloadDll=LdrUnloadDll@4 diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 19e639b2ca2..2e22e9712ea 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.47 2001/09/01 19:36:30 rex Exp $ +/* $Id: utils.c,v 1.48 2001/09/08 12:06:33 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -36,16 +36,12 @@ /* Type for a DLL's entry point */ -typedef -WINBOOL -STDCALL -(* PDLLMAIN_FUNC) ( - HANDLE hInst, - ULONG ul_reason_for_call, - LPVOID lpReserved - ); +typedef WINBOOL STDCALL +(* PDLLMAIN_FUNC)(HANDLE hInst, + ULONG ul_reason_for_call, + LPVOID lpReserved); -static NTSTATUS LdrFindDll(PLDR_MODULE *Dll,PUNICODE_STRING Name); +static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module); static PVOID LdrFixupForward(PCHAR ForwardName); static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint); @@ -209,7 +205,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, /* * Test if dll is already loaded. */ - if (LdrFindDll(&Module, &AdjustedName) == STATUS_SUCCESS) + if (LdrFindEntryForName(&AdjustedName, &Module) == STATUS_SUCCESS) { DPRINT("DLL %wZ already loaded.\n", &AdjustedName); if (Module->LoadCount != -1) @@ -444,8 +440,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, /*************************************************************************** - * NAME LOCAL - * LdrFindDll + * NAME EXPORTED + * LdrFindEntryForAddress * * DESCRIPTION * @@ -458,42 +454,104 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, * NOTE * */ -static NTSTATUS LdrFindDll(PLDR_MODULE *Dll, PUNICODE_STRING Name) +NTSTATUS STDCALL +LdrFindEntryForAddress(PVOID Address, + PLDR_MODULE *Module) { - PLIST_ENTRY ModuleListHead; - PLIST_ENTRY Entry; - PLDR_MODULE Module; + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE ModulePtr; - DPRINT("NTDLL.LdrFindDll(Name %wZ)\n", Name); + DPRINT("NTDLL.LdrFindEntryForAddress(Address %p)\n", Address); - ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; - Entry = ModuleListHead->Flink; + if (NtCurrentPeb()->Ldr == NULL) + return(STATUS_NO_MORE_ENTRIES); - // NULL is the current process - if ( Name == NULL ) - { - *Dll = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - return STATUS_SUCCESS; - } + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + if (Entry == ModuleListHead) + return(STATUS_NO_MORE_ENTRIES); - while (Entry != ModuleListHead) - { - Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + while (Entry != ModuleListHead) + { + ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); - DPRINT("Scanning %wZ %wZ\n", &Module->BaseDllName, Name); + DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->BaseAddress); - if (RtlCompareUnicodeString(&Module->BaseDllName, Name, TRUE) == 0) - { - *Dll = Module; - return STATUS_SUCCESS; - } + if ((Address >= ModulePtr->BaseAddress) && + (Address <= (ModulePtr->BaseAddress + ModulePtr->SizeOfImage))) + { + *Module = ModulePtr; + return(STATUS_SUCCESS); + } - Entry = Entry->Flink; - } + Entry = Entry->Flink; + } - DPRINT("Failed to find dll %wZ\n", Name); + DPRINT("Failed to find module entry.\n"); - return STATUS_UNSUCCESSFUL; + return(STATUS_NO_MORE_ENTRIES); +} + + +/*************************************************************************** + * NAME LOCAL + * LdrFindEntryForName + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + * NOTE + * + */ +static NTSTATUS +LdrFindEntryForName(PUNICODE_STRING Name, + PLDR_MODULE *Module) +{ + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE ModulePtr; + + DPRINT("NTDLL.LdrFindEntryForName(Name %wZ)\n", Name); + + if (NtCurrentPeb()->Ldr == NULL) + return(STATUS_NO_MORE_ENTRIES); + + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + if (Entry == ModuleListHead) + return(STATUS_NO_MORE_ENTRIES); + + // NULL is the current process + if (Name == NULL) + { + *Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + return(STATUS_SUCCESS); + } + + while (Entry != ModuleListHead) + { + ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + + DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, Name); + + if (RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE) == 0) + { + *Module = ModulePtr; + return(STATUS_SUCCESS); + } + + Entry = Entry->Flink; + } + + DPRINT("Failed to find dll %wZ\n", Name); + + return(STATUS_NO_MORE_ENTRIES); } /********************************************************************** @@ -1658,4 +1716,104 @@ LdrShutdownThread (VOID) return STATUS_SUCCESS; } + +/*************************************************************************** + * NAME EXPORTED + * LdrQueryProcessModuleInformation + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + * NOTE + */ +NTSTATUS STDCALL +LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL, + IN ULONG Size OPTIONAL, + OUT PULONG ReturnedSize) + +{ + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE Module; + PMODULE_ENTRY ModulePtr = NULL; + NTSTATUS Status = STATUS_SUCCESS; + ULONG UsedSize = sizeof(ULONG); + ANSI_STRING AnsiString; + PCHAR p; + + DPRINT("LdrQueryProcessModuleInformation() called\n"); + + RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); + + if (ModuleInformation == NULL || Size == 0) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + ModuleInformation->ModuleCount = 0; + ModulePtr = &ModuleInformation->ModuleEntry[0]; + Status = STATUS_SUCCESS; + } + + ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + Entry = ModuleListHead->Flink; + + while (Entry != ModuleListHead) + { + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); + + DPRINT(" Module %wZ\n", + &Module->FullDllName); + + if (UsedSize > Size) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else if (ModuleInformation != NULL) + { + ModulePtr->Unknown0 = 0; // FIXME: ?? + ModulePtr->Unknown1 = 0; // FIXME: ?? + ModulePtr->BaseAddress = Module->BaseAddress; + ModulePtr->SizeOfImage = Module->SizeOfImage; + ModulePtr->Flags = Module->Flags; + ModulePtr->Unknown2 = 0; // FIXME: load order index ?? + ModulePtr->Unknown3 = 0; // FIXME: ?? + ModulePtr->LoadCount = Module->LoadCount; + + AnsiString.Length = 0; + AnsiString.MaximumLength = 256; + AnsiString.Buffer = ModulePtr->ModuleName; + RtlUnicodeStringToAnsiString(&AnsiString, + &Module->FullDllName, + FALSE); + p = strrchr(ModulePtr->ModuleName, '\\'); + if (p != NULL) + ModulePtr->PathLength = p - ModulePtr->ModuleName + 1; + else + ModulePtr->PathLength = 0; + + ModulePtr++; + ModuleInformation->ModuleCount++; + } + UsedSize += sizeof(MODULE_ENTRY); + + Entry = Entry->Flink; + } + + RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); + + if (ReturnedSize != 0) + *ReturnedSize = UsedSize; + + DPRINT("LdrQueryProcessModuleInformation() done\n"); + + return(Status); +} + /* EOF */ diff --git a/reactos/lib/ntdll/stubs/stubs.c b/reactos/lib/ntdll/stubs/stubs.c index 93f7d769816..78493d3a75b 100644 --- a/reactos/lib/ntdll/stubs/stubs.c +++ b/reactos/lib/ntdll/stubs/stubs.c @@ -12,11 +12,9 @@ STUB(KiRaiseUserExceptionDispatcher) STUB(LdrEnumResources) -STUB(LdrFindEntryForAddress) STUB(LdrFindResourceDirectory_U) STUB(LdrProcessRelocationBlock) STUB(LdrQueryImageFileExecutionOptions) -STUB(LdrQueryProcessModuleInformation) STUB(LdrVerifyImageMatchesChecksum) STUB(NPXEMULATORTABLE) STUB(PfxFindPrefix) @@ -26,9 +24,6 @@ STUB(PfxRemovePrefix) STUB(RestoreEm87Context) STUB(RtlWalkHeap) STUB(RtlZeroHeap) -STUB(RtlpNtEnumerateSubKey) -STUB(RtlpNtQueryValueKey) -STUB(RtlpNtSetValueKey) STUB(RtlpUnWaitCriticalSection) STUB(RtlpWaitForCriticalSection) STUB(SaveEm87Context)