diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index a7d7f0fec4e..7fee9bce57d 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1135,64 +1135,6 @@ NTSTATUS WINAPI LdrUnlockLoaderLock( ULONG flags, ULONG magic ) } -/****************************************************************** - * LdrGetDllHandle (NTDLL.@) - */ -NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, const UNICODE_STRING *name, HMODULE *base) -{ - NTSTATUS status = STATUS_DLL_NOT_FOUND; - WCHAR dllname[MAX_PATH+4], *p; - UNICODE_STRING str; - PLIST_ENTRY mark, entry; - PLDR_MODULE mod; - - if (x != 0 || y != 0) - FIXME("Unknown behavior, please report\n"); - - /* Append .DLL to name if no extension present */ - if (!(p = strrchrW( name->Buffer, '.')) || strchrW( p, '/' ) || strchrW( p, '\\')) - { - if (name->Length >= MAX_PATH) return STATUS_NAME_TOO_LONG; - strcpyW( dllname, name->Buffer ); - strcatW( dllname, dllW ); - RtlInitUnicodeString( &str, dllname ); - name = &str; - } - - RtlEnterCriticalSection( &loader_section ); - - if (cached_modref) - { - if (RtlEqualUnicodeString( name, &cached_modref->ldr.FullDllName, TRUE ) || - RtlEqualUnicodeString( name, &cached_modref->ldr.BaseDllName, TRUE )) - { - *base = cached_modref->ldr.BaseAddress; - status = STATUS_SUCCESS; - goto done; - } - } - - mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList; - for (entry = mark->Flink; entry != mark; entry = entry->Flink) - { - mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList); - - if (RtlEqualUnicodeString( name, &mod->FullDllName, TRUE ) || - RtlEqualUnicodeString( name, &mod->BaseDllName, TRUE )) - { - cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr); - *base = mod->BaseAddress; - status = STATUS_SUCCESS; - break; - } - } -done: - RtlLeaveCriticalSection( &loader_section ); - TRACE("%x %x %s -> %p\n", x, y, debugstr_us(name), status ? NULL : *base); - return status; -} - - /****************************************************************** * LdrGetProcedureAddress (NTDLL.@) */ @@ -1642,7 +1584,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, if (len) { if (len >= *size) goto overflow; - if ((*pwm = find_fullname_module( filename )) != NULL) goto found; + if ((*pwm = find_fullname_module( filename )) || !handle) goto found; if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL )) { @@ -1682,7 +1624,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, len = nt_name.Length - 4*sizeof(WCHAR); /* for \??\ prefix */ if (len >= *size) goto overflow; memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) ); - if (!(*pwm = find_fullname_module( filename ))) + if (!(*pwm = find_fullname_module( filename )) && handle) { attr.Length = sizeof(attr); attr.RootDirectory = 0; @@ -1839,6 +1781,45 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags, return nts; } + +/****************************************************************** + * LdrGetDllHandle (NTDLL.@) + */ +NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base ) +{ + NTSTATUS status; + WCHAR buffer[128]; + WCHAR *filename; + ULONG size; + WINE_MODREF *wm; + + RtlEnterCriticalSection( &loader_section ); + + if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; + + filename = buffer; + size = sizeof(buffer); + for (;;) + { + status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, NULL ); + if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); + if (status != STATUS_BUFFER_TOO_SMALL) break; + /* grow the buffer and retry */ + if (!(filename = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY; + } + + if (status == STATUS_SUCCESS) + { + if (wm) *base = wm->ldr.BaseAddress; + else status = STATUS_DLL_NOT_FOUND; + } + + RtlLeaveCriticalSection( &loader_section ); + TRACE( "%s -> %p (load path %s)\n", debugstr_us(name), status ? NULL : *base, debugstr_w(load_path) ); + return status; +} + + /****************************************************************** * LdrQueryProcessModuleInformation * diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 346f002c65e..eeba2e175ff 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -63,7 +63,7 @@ # @ stub LdrFindResourceEx_U @ stdcall LdrFindResource_U(long ptr long ptr) @ stub LdrFlushAlternateResourceModules -@ stdcall LdrGetDllHandle(long long ptr ptr) +@ stdcall LdrGetDllHandle(wstr long ptr ptr) # @ stub LdrGetDllHandleEx @ stdcall LdrGetProcedureAddress(ptr ptr long ptr) # @ stub LdrHotPatchRoutine diff --git a/include/winternl.h b/include/winternl.h index fa3696f5988..b75519e91ab 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1733,7 +1733,7 @@ NTSTATUS WINAPIV DbgPrintEx(ULONG iComponentId, ULONG Level, LPCSTR fmt, ...); NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG); NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY**); NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**); -NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*); +NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**); void WINAPI LdrInitializeThunk(ULONG,ULONG,ULONG,ULONG); NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);