From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/loader.c | 11 +++++++++++ dlls/ntdll/loader.c | 2 ++ 2 files changed, 13 insertions(+)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 8b332e479e6..9b0f8f6bff2 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -87,6 +87,7 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **); static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *); static HMODULE (WINAPI *pLoadPackagedLibrary)(LPCWSTR lpwLibFileName, DWORD Reserved); +static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module) { @@ -3314,6 +3315,13 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param) return TRUE; }
+static void CALLBACK ldr_notify_callback(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context) +{ + /* If some DLL happens to be loaded during process shutdown load notification is called but never unload + * notification. */ + ok(reason == LDR_DLL_NOTIFICATION_REASON_LOADED, "got reason %lu.\n", reason); +} + static void child_process(const char *dll_name, DWORD target_offset) { void *target; @@ -3322,6 +3330,7 @@ static void child_process(const char *dll_name, DWORD target_offset) HMODULE hmod; struct PROCESS_BASIC_INFORMATION_PRIVATE pbi; DWORD_PTR affinity; + void *cookie;
trace("phase %d: writing %p at %#lx\n", test_dll_phase, dll_entry_point, target_offset);
@@ -3472,6 +3481,7 @@ static void child_process(const char *dll_name, DWORD target_offset) ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
trace("call LdrShutdownProcess()\n"); + pLdrRegisterDllNotification(0, ldr_notify_callback, NULL, &cookie); pLdrShutdownProcess();
ret = pRtlDllShutdownInProgress(); @@ -4671,6 +4681,7 @@ START_TEST(loader) pRtlReleasePebLock = (void *)GetProcAddress(ntdll, "RtlReleasePebLock"); pRtlImageDirectoryEntryToData = (void *)GetProcAddress(ntdll, "RtlImageDirectoryEntryToData"); pRtlImageNtHeader = (void *)GetProcAddress(ntdll, "RtlImageNtHeader"); + pLdrRegisterDllNotification = (void *)GetProcAddress(ntdll, "LdrRegisterDllNotification"); pFlsAlloc = (void *)GetProcAddress(kernel32, "FlsAlloc"); pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue"); pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue"); diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 5f84ca7e23b..24652d5a663 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -538,6 +538,8 @@ static void call_ldr_notifications( ULONG reason, LDR_DATA_TABLE_ENTRY *module ) struct ldr_notification *notify, *notify_next; LDR_DLL_NOTIFICATION_DATA data;
+ if (process_detaching && reason == LDR_DLL_NOTIFICATION_REASON_UNLOADED) return; + data.Loaded.Flags = 0; data.Loaded.FullDllName = &module->FullDllName; data.Loaded.BaseDllName = &module->BaseDllName;