diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 08b225f48d..7779a7514a 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1030,6 +1030,7 @@ @ stdcall RequestWakeupLatency(long) @ stdcall ResetEvent(long) @ stdcall ResetWriteWatch(ptr long) +@ stdcall ResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) ntdll.LdrResolveDelayLoadedAPI @ stdcall RestoreLastError(long) ntdll.RtlRestoreLastWin32Error @ stdcall ResumeThread(long) @ cdecl -arch=arm,x86_64 RtlAddFunctionTable(ptr long long) ntdll.RtlAddFunctionTable diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 0455df43db..a4552bb766 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -36,6 +36,7 @@ #include "windef.h" #include "winnt.h" #include "winternl.h" +#include "delayloadhandler.h" #include "wine/exception.h" #include "wine/library.h" @@ -2383,6 +2384,70 @@ BOOLEAN WINAPI RtlDllShutdownInProgress(void) return process_detaching; } +/**************************************************************************** + * LdrResolveDelayLoadedAPI (NTDLL.@) + */ +void* WINAPI LdrResolveDelayLoadedAPI( void* base, const IMAGE_DELAYLOAD_DESCRIPTOR* desc, + PDELAYLOAD_FAILURE_DLL_CALLBACK dllhook, void* syshook, + IMAGE_THUNK_DATA* addr, ULONG flags ) +{ + IMAGE_THUNK_DATA *pIAT, *pINT; + DELAYLOAD_INFO delayinfo; + UNICODE_STRING mod; + const CHAR* name; + HMODULE *phmod; + NTSTATUS nts; + FARPROC fp; + DWORD id; + + FIXME("(%p, %p, %p, %p, %p, 0x%08x), partial stub\n", base, desc, dllhook, syshook, addr, flags); + + phmod = get_rva(base, desc->ModuleHandleRVA); + pIAT = get_rva(base, desc->ImportAddressTableRVA); + pINT = get_rva(base, desc->ImportNameTableRVA); + name = get_rva(base, desc->DllNameRVA); + id = addr - pIAT; + + if (!*phmod) + { + if (!RtlCreateUnicodeStringFromAsciiz(&mod, name)) + { + nts = STATUS_NO_MEMORY; + goto fail; + } + nts = LdrLoadDll(NULL, 0, &mod, phmod); + RtlFreeUnicodeString(&mod); + if (nts) goto fail; + } + + if (IMAGE_SNAP_BY_ORDINAL(pINT[id].u1.Ordinal)) + nts = LdrGetProcedureAddress(*phmod, NULL, LOWORD(pINT[id].u1.Ordinal), (void**)&fp); + else + { + const IMAGE_IMPORT_BY_NAME* iibn = get_rva(base, pINT[id].u1.AddressOfData); + ANSI_STRING fnc; + + RtlInitAnsiString(&fnc, (char*)iibn->Name); + nts = LdrGetProcedureAddress(*phmod, &fnc, 0, (void**)&fp); + } + if (!nts) + { + pIAT[id].u1.Function = (ULONG_PTR)fp; + return fp; + } + +fail: + delayinfo.Size = sizeof(delayinfo); + delayinfo.DelayloadDescriptor = desc; + delayinfo.ThunkAddress = addr; + delayinfo.TargetDllName = name; + delayinfo.TargetApiDescriptor.ImportDescribedByName = !IMAGE_SNAP_BY_ORDINAL(pINT[id].u1.Ordinal); + delayinfo.TargetApiDescriptor.Description.Ordinal = LOWORD(pINT[id].u1.Ordinal); + delayinfo.TargetModuleBase = *phmod; + delayinfo.Unused = NULL; + delayinfo.LastError = nts; + return dllhook(4, &delayinfo); +} /****************************************************************** * LdrShutdownProcess (NTDLL.@) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 860b4c628b..70bf94f4c9 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -75,6 +75,7 @@ @ stdcall LdrProcessRelocationBlock(ptr long ptr long) @ stdcall LdrQueryImageFileExecutionOptions(ptr wstr long ptr long ptr) @ stdcall LdrQueryProcessModuleInformation(ptr long ptr) +@ stdcall LdrResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) @ stub LdrSetAppCompatDllRedirectionCallback @ stub LdrSetDllManifestProber @ stdcall LdrShutdownProcess()