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@dawncrow.de> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
27ff04e2ab
commit
95fa795fa1
|
@ -48,7 +48,7 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE
|
||||||
};
|
};
|
||||||
|
|
||||||
static LONG *child_failures;
|
static LONG *child_failures;
|
||||||
static WORD cb_count;
|
static WORD cb_count, cb_count_sys;
|
||||||
static DWORD page_size;
|
static DWORD page_size;
|
||||||
static BOOL is_win64 = sizeof(void *) > sizeof(int);
|
static BOOL is_win64 = sizeof(void *) > sizeof(int);
|
||||||
static BOOL is_wow64;
|
static BOOL is_wow64;
|
||||||
|
@ -70,7 +70,8 @@ static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR);
|
||||||
static void (WINAPI *pRtlAcquirePebLock)(void);
|
static void (WINAPI *pRtlAcquirePebLock)(void);
|
||||||
static void (WINAPI *pRtlReleasePebLock)(void);
|
static void (WINAPI *pRtlReleasePebLock)(void);
|
||||||
static PVOID (WINAPI *pResolveDelayLoadedAPI)(PVOID, PCIMAGE_DELAYLOAD_DESCRIPTOR,
|
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);
|
PIMAGE_THUNK_DATA ThunkAddress,ULONG);
|
||||||
static PVOID (WINAPI *pRtlImageDirectoryEntryToData)(HMODULE,BOOL,WORD,ULONG *);
|
static PVOID (WINAPI *pRtlImageDirectoryEntryToData)(HMODULE,BOOL,WORD,ULONG *);
|
||||||
static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
|
static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
|
||||||
|
@ -3339,6 +3340,14 @@ static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO* pd)
|
||||||
return (void*)0xdeadbeef;
|
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 void test_ResolveDelayLoadedAPI(void)
|
||||||
{
|
{
|
||||||
static const char test_dll[] = "secur32.dll";
|
static const char test_dll[] = "secur32.dll";
|
||||||
|
@ -3573,8 +3582,9 @@ static void test_ResolveDelayLoadedAPI(void)
|
||||||
load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
|
load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
cb_count = 0;
|
/* test without failure dll callback */
|
||||||
ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, NULL, &itda[i], 0);
|
cb_count = cb_count_sys = 0;
|
||||||
|
ret = pResolveDelayLoadedAPI(hlib, delaydir, NULL, failuresyshook, &itda[i], 0);
|
||||||
if (td[i].succeeds)
|
if (td[i].succeeds)
|
||||||
{
|
{
|
||||||
ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i);
|
ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i);
|
||||||
|
@ -3582,11 +3592,42 @@ static void test_ResolveDelayLoadedAPI(void)
|
||||||
ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n",
|
ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n",
|
||||||
i, ret, (void*)itda[i].u1.AddressOfData);
|
i, ret, (void*)itda[i].u1.AddressOfData);
|
||||||
ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
|
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
|
else
|
||||||
{
|
{
|
||||||
ok(ret == (void*)0xdeadbeef, "Test %u: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
|
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, "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++;
|
delaydir++;
|
||||||
|
|
|
@ -2934,7 +2934,8 @@ BOOLEAN WINAPI RtlDllShutdownInProgress(void)
|
||||||
* LdrResolveDelayLoadedAPI (NTDLL.@)
|
* LdrResolveDelayLoadedAPI (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
void* WINAPI LdrResolveDelayLoadedAPI( void* base, const IMAGE_DELAYLOAD_DESCRIPTOR* desc,
|
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* addr, ULONG flags )
|
||||||
{
|
{
|
||||||
IMAGE_THUNK_DATA *pIAT, *pINT;
|
IMAGE_THUNK_DATA *pIAT, *pINT;
|
||||||
|
@ -2992,7 +2993,20 @@ fail:
|
||||||
delayinfo.TargetModuleBase = *phmod;
|
delayinfo.TargetModuleBase = *phmod;
|
||||||
delayinfo.Unused = NULL;
|
delayinfo.Unused = NULL;
|
||||||
delayinfo.LastError = nts;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct _DELAYLOAD_INFO
|
||||||
} DELAYLOAD_INFO, *PDELAYLOAD_INFO;
|
} DELAYLOAD_INFO, *PDELAYLOAD_INFO;
|
||||||
|
|
||||||
typedef PVOID (WINAPI *PDELAYLOAD_FAILURE_DLL_CALLBACK)(ULONG, PDELAYLOAD_INFO);
|
typedef PVOID (WINAPI *PDELAYLOAD_FAILURE_DLL_CALLBACK)(ULONG, PDELAYLOAD_INFO);
|
||||||
|
typedef PVOID (WINAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)(LPCSTR, LPCSTR);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue