2017-03-08 13:56:02 -08:00
|
|
|
From 7221933818afc91b76f6b12ead544570d8ff336a Mon Sep 17 00:00:00 2001
|
2017-02-05 04:58:44 -08:00
|
|
|
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
|
|
|
Date: Fri, 3 Feb 2017 00:05:10 +0100
|
|
|
|
Subject: ntdll: Implement LdrEnumerateLoadedModules.
|
|
|
|
|
|
|
|
---
|
|
|
|
dlls/ntdll/loader.c | 31 +++++++++++++++++++++++++++++
|
|
|
|
dlls/ntdll/ntdll.spec | 2 +-
|
|
|
|
dlls/ntdll/tests/rtl.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
3 files changed, 86 insertions(+), 1 deletion(-)
|
|
|
|
|
|
|
|
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
2017-03-08 13:56:02 -08:00
|
|
|
index cf758505a4c..0b507da9a08 100644
|
2017-02-05 04:58:44 -08:00
|
|
|
--- a/dlls/ntdll/loader.c
|
|
|
|
+++ b/dlls/ntdll/loader.c
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -1393,6 +1393,37 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
|
2017-02-05 04:58:44 -08:00
|
|
|
return STATUS_NO_MORE_ENTRIES;
|
|
|
|
}
|
|
|
|
|
|
|
|
+typedef void (WINAPI LDR_ENUM_CALLBACK)(LDR_MODULE*, void*, BOOLEAN*);
|
|
|
|
+
|
|
|
|
+/******************************************************************
|
|
|
|
+ * LdrEnumerateLoadedModules (NTDLL.@)
|
|
|
|
+ */
|
|
|
|
+NTSTATUS WINAPI LdrEnumerateLoadedModules(void *unknown, LDR_ENUM_CALLBACK *callback, void *context)
|
|
|
|
+{
|
|
|
|
+ PLIST_ENTRY mark, entry;
|
|
|
|
+ PLDR_MODULE mod;
|
|
|
|
+ BOOLEAN stop = FALSE;
|
|
|
|
+
|
|
|
|
+ TRACE("(%p, %p, %p)\n", unknown, callback, context);
|
|
|
|
+
|
|
|
|
+ if (unknown || !callback)
|
|
|
|
+ return STATUS_INVALID_PARAMETER;
|
|
|
|
+
|
|
|
|
+ RtlEnterCriticalSection( &loader_section );
|
|
|
|
+
|
|
|
|
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
|
|
|
+ for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
|
|
|
+ {
|
|
|
|
+ mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
|
|
|
|
+ callback(mod, context, &stop);
|
|
|
|
+ if (stop) break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ RtlLeaveCriticalSection( &loader_section );
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/******************************************************************
|
|
|
|
* LdrLockLoaderLock (NTDLL.@)
|
|
|
|
*
|
|
|
|
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
2017-03-08 13:56:02 -08:00
|
|
|
index b4269a679fc..66ecb7d0f37 100644
|
2017-02-05 04:58:44 -08:00
|
|
|
--- a/dlls/ntdll/ntdll.spec
|
|
|
|
+++ b/dlls/ntdll/ntdll.spec
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -62,7 +62,7 @@
|
2017-02-05 04:58:44 -08:00
|
|
|
# @ stub LdrDestroyOutOfProcessImage
|
|
|
|
@ stdcall LdrDisableThreadCalloutsForDll(long)
|
|
|
|
@ stub LdrEnumResources
|
|
|
|
-# @ stub LdrEnumerateLoadedModules
|
|
|
|
+@ stdcall LdrEnumerateLoadedModules(ptr ptr ptr)
|
|
|
|
# @ stub LdrFindCreateProcessManifest
|
|
|
|
@ stdcall LdrFindEntryForAddress(ptr ptr)
|
|
|
|
@ stdcall LdrFindResourceDirectory_U(long ptr long ptr)
|
|
|
|
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
|
2017-03-08 13:56:02 -08:00
|
|
|
index 940c44a05bd..873437e7f4b 100644
|
2017-02-05 04:58:44 -08:00
|
|
|
--- a/dlls/ntdll/tests/rtl.c
|
|
|
|
+++ b/dlls/ntdll/tests/rtl.c
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -102,6 +102,7 @@ static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *);
|
2017-02-05 04:58:44 -08:00
|
|
|
static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *);
|
|
|
|
static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG);
|
|
|
|
static NTSTATUS (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*);
|
|
|
|
+static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void*, void*, void*);
|
|
|
|
|
|
|
|
static HMODULE hkernel32 = 0;
|
|
|
|
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -156,6 +157,7 @@ static void InitFunctionPtrs(void)
|
2017-02-05 04:58:44 -08:00
|
|
|
pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread");
|
|
|
|
pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx");
|
|
|
|
pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity");
|
|
|
|
+ pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
|
|
|
|
}
|
|
|
|
hkernel32 = LoadLibraryA("kernel32.dll");
|
|
|
|
ok(hkernel32 != 0, "LoadLibrary failed\n");
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -2228,6 +2230,57 @@ done:
|
2017-02-05 04:58:44 -08:00
|
|
|
CoUninitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
+static BOOL enum_abort = FALSE;
|
|
|
|
+static BOOL ntdll_found = FALSE;
|
|
|
|
+static int module_count = 0;
|
|
|
|
+
|
|
|
|
+void WINAPI ldr_enum_callback(LDR_MODULE *module, void *context, BOOLEAN *stop)
|
|
|
|
+{
|
|
|
|
+ static const WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0};
|
|
|
|
+ ok(context == (void *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", context);
|
|
|
|
+
|
|
|
|
+ module_count++;
|
|
|
|
+
|
|
|
|
+ if (!lstrcmpiW(module->BaseDllName.Buffer, ntdllW))
|
|
|
|
+ ntdll_found = TRUE;
|
|
|
|
+
|
|
|
|
+ *stop = enum_abort;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void test_LdrEnumerateLoadedModules(void)
|
|
|
|
+{
|
|
|
|
+ NTSTATUS status;
|
|
|
|
+
|
|
|
|
+ if (!pLdrEnumerateLoadedModules)
|
|
|
|
+ {
|
|
|
|
+ win_skip("LdrEnumerateLoadedModules not available\n");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ enum_abort = FALSE;
|
|
|
|
+ ntdll_found = FALSE;
|
|
|
|
+ module_count = 0;
|
|
|
|
+ status = pLdrEnumerateLoadedModules(NULL, ldr_enum_callback, (void *)0xdeadbeef);
|
|
|
|
+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status);
|
|
|
|
+ ok(ntdll_found, "Could not find ntdll!\n");
|
|
|
|
+ ok(module_count > 1, "Expected more than one module, got %d\n", module_count);
|
|
|
|
+
|
|
|
|
+ enum_abort = TRUE;
|
|
|
|
+ module_count = 0;
|
|
|
|
+ status = pLdrEnumerateLoadedModules(NULL, ldr_enum_callback, (void *)0xdeadbeef);
|
|
|
|
+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status);
|
|
|
|
+ ok(module_count == 1, "Expected exactly one module, got %d\n", module_count);
|
|
|
|
+
|
|
|
|
+ status = pLdrEnumerateLoadedModules((void *)0x1, ldr_enum_callback, (void *)0xdeadbeef);
|
|
|
|
+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status);
|
|
|
|
+
|
|
|
|
+ status = pLdrEnumerateLoadedModules((void *)0xdeadbeef, ldr_enum_callback, (void *)0xdeadbeef);
|
|
|
|
+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status);
|
|
|
|
+
|
|
|
|
+ status = pLdrEnumerateLoadedModules(NULL, NULL, (void *)0xdeadbeef);
|
|
|
|
+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
START_TEST(rtl)
|
|
|
|
{
|
|
|
|
InitFunctionPtrs();
|
2017-03-08 13:56:02 -08:00
|
|
|
@@ -2261,4 +2314,5 @@ START_TEST(rtl)
|
2017-02-05 04:58:44 -08:00
|
|
|
test_RtlInitializeCriticalSectionEx();
|
2017-03-08 13:56:02 -08:00
|
|
|
test_RtlLeaveCriticalSection();
|
2017-02-05 04:58:44 -08:00
|
|
|
test_RtlQueryPackageIdentity();
|
|
|
|
+ test_LdrEnumerateLoadedModules();
|
|
|
|
}
|
|
|
|
--
|
|
|
|
2.11.0
|
|
|
|
|