ntdll: Reimplement LdrGetDllHandle to use the same search algorithm as LdrLoadDll.
This commit is contained in:
parent
4de936e181
commit
b64530eee4
|
@ -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.@)
|
* LdrGetProcedureAddress (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1642,7 +1584,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
if (len >= *size) goto overflow;
|
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 ))
|
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 */
|
len = nt_name.Length - 4*sizeof(WCHAR); /* for \??\ prefix */
|
||||||
if (len >= *size) goto overflow;
|
if (len >= *size) goto overflow;
|
||||||
memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) );
|
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.Length = sizeof(attr);
|
||||||
attr.RootDirectory = 0;
|
attr.RootDirectory = 0;
|
||||||
|
@ -1839,6 +1781,45 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||||
return nts;
|
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
|
* LdrQueryProcessModuleInformation
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
# @ stub LdrFindResourceEx_U
|
# @ stub LdrFindResourceEx_U
|
||||||
@ stdcall LdrFindResource_U(long ptr long ptr)
|
@ stdcall LdrFindResource_U(long ptr long ptr)
|
||||||
@ stub LdrFlushAlternateResourceModules
|
@ stub LdrFlushAlternateResourceModules
|
||||||
@ stdcall LdrGetDllHandle(long long ptr ptr)
|
@ stdcall LdrGetDllHandle(wstr long ptr ptr)
|
||||||
# @ stub LdrGetDllHandleEx
|
# @ stub LdrGetDllHandleEx
|
||||||
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
|
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
|
||||||
# @ stub LdrHotPatchRoutine
|
# @ stub LdrHotPatchRoutine
|
||||||
|
|
|
@ -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 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 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 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**);
|
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
||||||
void WINAPI LdrInitializeThunk(ULONG,ULONG,ULONG,ULONG);
|
void WINAPI LdrInitializeThunk(ULONG,ULONG,ULONG,ULONG);
|
||||||
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
||||||
|
|
Loading…
Reference in New Issue