From: Paul Gofman <pgofman(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6470