=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: ntdll: Call system hook in LdrResolveDelayLoadedAPI when dll hook is missing.

Alexandre Julliard julliard at winehq.org
Sun Mar 3 13:21:31 CST 2019


Module: wine
Branch: oldstable
Commit: 71c9a0f604c534af060c8fd175ffec21db0596ea
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=71c9a0f604c534af060c8fd175ffec21db0596ea

Author: André Hentschel <nerv at dawncrow.de>
Date:   Sat Nov 10 22:29:27 2018 +0100

ntdll: Call system hook in LdrResolveDelayLoadedAPI when dll hook is missing.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46089
Signed-off-by: André Hentschel <nerv at dawncrow.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 95fa795fa1f8b416af097b6186859ec32ea316d9)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/kernel32/tests/loader.c | 53 +++++++++++++++++++++++++++++++++++++++-----
 dlls/ntdll/loader.c          | 18 +++++++++++++--
 include/delayloadhandler.h   |  1 +
 3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 7066bca..2551d48 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -47,7 +47,7 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE
 };
 
 static LONG *child_failures;
-static WORD cb_count;
+static WORD cb_count, cb_count_sys;
 static DWORD page_size;
 
 static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
@@ -67,7 +67,8 @@ static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR);
 static void (WINAPI *pRtlAcquirePebLock)(void);
 static void (WINAPI *pRtlReleasePebLock)(void);
 static PVOID    (WINAPI *pResolveDelayLoadedAPI)(PVOID, PCIMAGE_DELAYLOAD_DESCRIPTOR,
-                                                 PDELAYLOAD_FAILURE_DLL_CALLBACK, PVOID,
+                                                 PDELAYLOAD_FAILURE_DLL_CALLBACK,
+                                                 PDELAYLOAD_FAILURE_SYSTEM_ROUTINE,
                                                  PIMAGE_THUNK_DATA ThunkAddress,ULONG);
 static PVOID (WINAPI *pRtlImageDirectoryEntryToData)(HMODULE,BOOL,WORD,ULONG *);
 static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
@@ -2986,6 +2987,14 @@ static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO* pd)
     return (void*)0xdeadbeef;
 }
 
+static PVOID WINAPI failuresyshook(const char *dll, const char *function)
+{
+    ok(!strcmp(dll, "secur32.dll"), "wrong dll: %s\n", dll);
+    ok(!((ULONG_PTR)function >> 16), "expected ordinal, got %p\n", function);
+    cb_count_sys++;
+    return (void*)0x12345678;
+}
+
 static void test_ResolveDelayLoadedAPI(void)
 {
     static const char test_dll[] = "secur32.dll";
@@ -3220,8 +3229,9 @@ static void test_ResolveDelayLoadedAPI(void)
                 load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
             }
 
-            cb_count = 0;
-            ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, NULL, &itda[i], 0);
+            /* test without failure dll callback */
+            cb_count = cb_count_sys = 0;
+            ret = pResolveDelayLoadedAPI(hlib, delaydir, NULL, failuresyshook, &itda[i], 0);
             if (td[i].succeeds)
             {
                 ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i);
@@ -3229,11 +3239,42 @@ static void test_ResolveDelayLoadedAPI(void)
                 ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n",
                    i, ret, (void*)itda[i].u1.AddressOfData);
                 ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                ok(!cb_count_sys, "Test %u: Wrong sys callback count: %d\n", i, cb_count_sys);
             }
             else
             {
-                ok(ret == (void*)0xdeadbeef, "Test %u: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
-                ok(cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                ok(ret == (void*)0x12345678, "Test %u: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
+                ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                ok(cb_count_sys == 1, "Test %u: Wrong sys callback count: %d\n", i, cb_count_sys);
+            }
+
+            /* test with failure dll callback */
+            cb_count = cb_count_sys = 0;
+            ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, failuresyshook, &itda[i], 0);
+            if (td[i].succeeds)
+            {
+                ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i);
+                ok(ret == load, "Test %u: expected %p, got %p\n", i, load, ret);
+                ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n",
+                   i, ret, (void*)itda[i].u1.AddressOfData);
+                ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                ok(!cb_count_sys, "Test %u: Wrong sys callback count: %d\n", i, cb_count_sys);
+            }
+            else
+            {
+                if (ret == (void*)0x12345678)
+                {
+                    /* Win10+ sometimes buffers the address of the stub function */
+                    ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                    ok(!cb_count_sys, "Test %u: Wrong sys callback count: %d\n", i, cb_count_sys);
+                }
+                else if (ret == (void*)0xdeadbeef)
+                {
+                    ok(cb_count == 1, "Test %u: Wrong callback count: %d\n", i, cb_count);
+                    ok(!cb_count_sys, "Test %u: Wrong sys callback count: %d\n", i, cb_count_sys);
+                }
+                else
+                    ok(0, "Test %u: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
             }
         }
         delaydir++;
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 53280a4..3972ac6 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2683,7 +2683,8 @@ BOOLEAN WINAPI RtlDllShutdownInProgress(void)
  *              LdrResolveDelayLoadedAPI   (NTDLL.@)
  */
 void* WINAPI LdrResolveDelayLoadedAPI( void* base, const IMAGE_DELAYLOAD_DESCRIPTOR* desc,
-                                       PDELAYLOAD_FAILURE_DLL_CALLBACK dllhook, void* syshook,
+                                       PDELAYLOAD_FAILURE_DLL_CALLBACK dllhook,
+                                       PDELAYLOAD_FAILURE_SYSTEM_ROUTINE syshook,
                                        IMAGE_THUNK_DATA* addr, ULONG flags )
 {
     IMAGE_THUNK_DATA *pIAT, *pINT;
@@ -2741,7 +2742,20 @@ fail:
     delayinfo.TargetModuleBase = *phmod;
     delayinfo.Unused = NULL;
     delayinfo.LastError = nts;
-    return dllhook(4, &delayinfo);
+
+    if (dllhook)
+        return dllhook(4, &delayinfo);
+
+    if (IMAGE_SNAP_BY_ORDINAL(pINT[id].u1.Ordinal))
+    {
+        DWORD_PTR ord = LOWORD(pINT[id].u1.Ordinal);
+        return syshook(name, (const char *)ord);
+    }
+    else
+    {
+        const IMAGE_IMPORT_BY_NAME* iibn = get_rva(base, pINT[id].u1.AddressOfData);
+        return syshook(name, (const char *)iibn->Name);
+    }
 }
 
 /******************************************************************
diff --git a/include/delayloadhandler.h b/include/delayloadhandler.h
index 06b6589..e833611 100644
--- a/include/delayloadhandler.h
+++ b/include/delayloadhandler.h
@@ -47,6 +47,7 @@ typedef struct _DELAYLOAD_INFO
 } DELAYLOAD_INFO, *PDELAYLOAD_INFO;
 
 typedef PVOID (WINAPI *PDELAYLOAD_FAILURE_DLL_CALLBACK)(ULONG, PDELAYLOAD_INFO);
+typedef PVOID (WINAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)(LPCSTR, LPCSTR);
 
 #ifdef __cplusplus
 }




More information about the wine-cvs mailing list