ntdll: Return an NT filename in find_dll_file().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a6e4c814b6
commit
3099b04a89
|
@ -2384,18 +2384,66 @@ static HANDLE open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm, struct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* search_dll_file
|
||||||
|
*
|
||||||
|
* Search for dll in the specified paths.
|
||||||
|
*/
|
||||||
|
static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *nt_name )
|
||||||
|
{
|
||||||
|
WCHAR *name;
|
||||||
|
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||||
|
ULONG len = strlenW( paths );
|
||||||
|
|
||||||
|
if (len < strlenW( system_dir )) len = strlenW( system_dir );
|
||||||
|
len += strlenW( search ) + 2;
|
||||||
|
|
||||||
|
if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
while (*paths)
|
||||||
|
{
|
||||||
|
LPCWSTR ptr = paths;
|
||||||
|
|
||||||
|
while (*ptr && *ptr != ';') ptr++;
|
||||||
|
len = ptr - paths;
|
||||||
|
if (*ptr == ';') ptr++;
|
||||||
|
memcpy( name, paths, len * sizeof(WCHAR) );
|
||||||
|
if (len && name[len - 1] != '\\') name[len++] = '\\';
|
||||||
|
strcpyW( name + len, search );
|
||||||
|
if (RtlDoesFileExists_U( name ))
|
||||||
|
{
|
||||||
|
if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL ))
|
||||||
|
status = STATUS_NO_MEMORY;
|
||||||
|
else
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
paths = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found, return file in the system dir to be loaded as builtin */
|
||||||
|
strcpyW( name, system_dir );
|
||||||
|
strcatW( name, search );
|
||||||
|
if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL )) status = STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
done:
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, name );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* find_dll_file
|
* find_dll_file
|
||||||
*
|
*
|
||||||
* Find the file (or already loaded module) for a given dll name.
|
* Find the file (or already loaded module) for a given dll name.
|
||||||
*/
|
*/
|
||||||
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
||||||
WCHAR *filename, ULONG *size, WINE_MODREF **pwm,
|
UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
||||||
HANDLE *handle, struct stat *st )
|
HANDLE *handle, struct stat *st )
|
||||||
{
|
{
|
||||||
UNICODE_STRING nt_name;
|
WCHAR *ext, *dllname;
|
||||||
WCHAR *file_part, *ext, *dllname;
|
NTSTATUS status;
|
||||||
ULONG len;
|
|
||||||
|
|
||||||
/* first append .dll if needed */
|
/* first append .dll if needed */
|
||||||
|
|
||||||
|
@ -2411,11 +2459,10 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
||||||
libname = dllname;
|
libname = dllname;
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_name.Buffer = NULL;
|
nt_name->Buffer = NULL;
|
||||||
|
|
||||||
if (!contains_path( libname ))
|
if (!contains_path( libname ))
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
|
||||||
WCHAR *fullname = NULL;
|
WCHAR *fullname = NULL;
|
||||||
|
|
||||||
if ((*pwm = find_basename_module( libname )) != NULL) goto found;
|
if ((*pwm = find_basename_module( libname )) != NULL) goto found;
|
||||||
|
@ -2437,48 +2484,30 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
||||||
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
|
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
|
||||||
{
|
{
|
||||||
/* we need to search for it */
|
/* we need to search for it */
|
||||||
len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part );
|
if (!(status = search_dll_file( load_path, libname, nt_name )))
|
||||||
if (len)
|
|
||||||
{
|
{
|
||||||
if (len >= *size) goto overflow;
|
*handle = open_dll_file( nt_name, pwm, st );
|
||||||
if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL ))
|
|
||||||
{
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
*handle = open_dll_file( &nt_name, pwm, st );
|
|
||||||
}
|
}
|
||||||
else /* not found, return the name as is, to be loaded as builtin */
|
else if (status != STATUS_DLL_NOT_FOUND)
|
||||||
{
|
{
|
||||||
len = strlenW(libname) * sizeof(WCHAR);
|
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
||||||
if (len >= *size) goto overflow;
|
return status;
|
||||||
strcpyW( filename, libname );
|
|
||||||
}
|
}
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* absolute path name */
|
/* absolute path name */
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U( libname, &nt_name, &file_part, NULL ))
|
if (!RtlDosPathNameToNtPathName_U( libname, nt_name, NULL, NULL ))
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
len = nt_name.Length - 4*sizeof(WCHAR); /* for \??\ prefix */
|
*handle = open_dll_file( nt_name, pwm, st );
|
||||||
if (len >= *size) goto overflow;
|
|
||||||
memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) );
|
|
||||||
*handle = open_dll_file( &nt_name, pwm, st );
|
|
||||||
|
|
||||||
found:
|
found:
|
||||||
RtlFreeUnicodeString( &nt_name );
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
overflow:
|
|
||||||
RtlFreeUnicodeString( &nt_name );
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
|
||||||
*size = len + sizeof(WCHAR);
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2491,10 +2520,9 @@ overflow:
|
||||||
static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
|
static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
|
||||||
{
|
{
|
||||||
enum loadorder loadorder;
|
enum loadorder loadorder;
|
||||||
WCHAR buffer[64];
|
|
||||||
WCHAR *filename;
|
WCHAR *filename;
|
||||||
ULONG size;
|
|
||||||
WINE_MODREF *main_exe;
|
WINE_MODREF *main_exe;
|
||||||
|
UNICODE_STRING nt_name;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
NTSTATUS nts;
|
NTSTATUS nts;
|
||||||
|
@ -2502,17 +2530,8 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||||
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
|
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
|
||||||
|
|
||||||
*pwm = NULL;
|
*pwm = NULL;
|
||||||
filename = buffer;
|
nts = find_dll_file( load_path, libname, &nt_name, pwm, &handle, &st );
|
||||||
size = sizeof(buffer);
|
if (nts) return nts;
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle, &st );
|
|
||||||
if (nts == STATUS_SUCCESS) break;
|
|
||||||
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
|
|
||||||
if (nts != STATUS_BUFFER_TOO_SMALL) return nts;
|
|
||||||
/* grow the buffer and retry */
|
|
||||||
if (!(filename = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*pwm) /* found already loaded module */
|
if (*pwm) /* found already loaded module */
|
||||||
{
|
{
|
||||||
|
@ -2521,10 +2540,11 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||||
TRACE("Found %s for %s at %p, count=%d\n",
|
TRACE("Found %s for %s at %p, count=%d\n",
|
||||||
debugstr_w((*pwm)->ldr.FullDllName.Buffer), debugstr_w(libname),
|
debugstr_w((*pwm)->ldr.FullDllName.Buffer), debugstr_w(libname),
|
||||||
(*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount);
|
(*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount);
|
||||||
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filename = nt_name.Buffer + 4; /* \??\ prefix */
|
||||||
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
|
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
|
||||||
loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
|
loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
|
||||||
|
|
||||||
|
@ -2578,19 +2598,13 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nts == STATUS_SUCCESS)
|
if (nts == STATUS_SUCCESS)
|
||||||
{
|
|
||||||
/* Initialize DLL just loaded */
|
|
||||||
TRACE("Loaded module %s (%s) at %p\n", debugstr_w(filename),
|
TRACE("Loaded module %s (%s) at %p\n", debugstr_w(filename),
|
||||||
((*pwm)->ldr.Flags & LDR_WINE_INTERNAL) ? "builtin" : "native",
|
((*pwm)->ldr.Flags & LDR_WINE_INTERNAL) ? "builtin" : "native", (*pwm)->ldr.BaseAddress);
|
||||||
(*pwm)->ldr.BaseAddress);
|
else
|
||||||
if (handle) NtClose( handle );
|
WARN("Failed to load module %s; status=%x\n", debugstr_w(libname), nts);
|
||||||
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
|
|
||||||
return nts;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("Failed to load module %s; status=%x\n", debugstr_w(libname), nts);
|
|
||||||
if (handle) NtClose( handle );
|
if (handle) NtClose( handle );
|
||||||
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return nts;
|
return nts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2630,9 +2644,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||||
NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base )
|
NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
WCHAR buffer[128];
|
UNICODE_STRING nt_name;
|
||||||
WCHAR *filename;
|
|
||||||
ULONG size;
|
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -2641,21 +2653,9 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
|
||||||
|
|
||||||
if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
||||||
|
|
||||||
filename = buffer;
|
status = find_dll_file( load_path, name->Buffer, &nt_name, &wm, &handle, &st );
|
||||||
size = sizeof(buffer);
|
if (handle) NtClose( handle );
|
||||||
for (;;)
|
RtlFreeUnicodeString( &nt_name );
|
||||||
{
|
|
||||||
status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, &handle, &st );
|
|
||||||
if (handle) NtClose( handle );
|
|
||||||
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 )))
|
|
||||||
{
|
|
||||||
status = STATUS_NO_MEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue