ntdll: Add a helper function to append .dll to a module name.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
eb6a9151d6
commit
afb6f1696e
|
@ -184,8 +184,7 @@ static WINE_MODREF *last_failed_modref;
|
||||||
|
|
||||||
static LDR_DDAG_NODE *node_ntdll, *node_kernel32;
|
static LDR_DDAG_NODE *node_ntdll, *node_kernel32;
|
||||||
|
|
||||||
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD flags, WINE_MODREF** pwm );
|
||||||
DWORD flags, WINE_MODREF** pwm );
|
|
||||||
static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved );
|
static NTSTATUS process_attach( LDR_DDAG_NODE *node, LPVOID lpReserved );
|
||||||
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
|
DWORD exp_size, DWORD ordinal, LPCWSTR load_path );
|
||||||
|
@ -602,6 +601,26 @@ static NTSTATUS build_import_name( WCHAR buffer[256], const char *import, int le
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* append_dll_ext
|
||||||
|
*/
|
||||||
|
static WCHAR *append_dll_ext( const WCHAR *name )
|
||||||
|
{
|
||||||
|
const WCHAR *ext = wcsrchr( name, '.' );
|
||||||
|
|
||||||
|
if (!ext || wcschr( ext, '/' ) || wcschr( ext, '\\'))
|
||||||
|
{
|
||||||
|
WCHAR *ret = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||||
|
wcslen(name) * sizeof(WCHAR) + sizeof(L".dll") );
|
||||||
|
if (!ret) return NULL;
|
||||||
|
wcscpy( ret, name );
|
||||||
|
wcscat( ret, L".dll" );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* is_import_dll_system
|
* is_import_dll_system
|
||||||
*/
|
*/
|
||||||
|
@ -741,7 +760,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
|
||||||
if (!(wm = find_basename_module( mod_name )))
|
if (!(wm = find_basename_module( mod_name )))
|
||||||
{
|
{
|
||||||
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
|
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
|
||||||
if (load_dll( load_path, mod_name, NULL, 0, &wm ) == STATUS_SUCCESS &&
|
if (load_dll( load_path, mod_name, 0, &wm ) == STATUS_SUCCESS &&
|
||||||
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||||
{
|
{
|
||||||
if (!imports_fixup_done && current_modref)
|
if (!imports_fixup_done && current_modref)
|
||||||
|
@ -934,7 +953,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
|
||||||
}
|
}
|
||||||
|
|
||||||
status = build_import_name( buffer, name, len );
|
status = build_import_name( buffer, name, len );
|
||||||
if (!status) status = load_dll( load_path, buffer, NULL, 0, &wmImp );
|
if (!status) status = load_dll( load_path, buffer, 0, &wmImp );
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
|
@ -1204,7 +1223,7 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
|
||||||
prev = current_modref;
|
prev = current_modref;
|
||||||
current_modref = wm;
|
current_modref = wm;
|
||||||
assert( !wm->ldr.DdagNode->Dependencies.Tail );
|
assert( !wm->ldr.DdagNode->Dependencies.Tail );
|
||||||
if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp ))
|
if (!(status = load_dll( load_path, L"mscoree.dll", 0, &imp ))
|
||||||
&& !add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, NULL ))
|
&& !add_module_dependency_after( wm->ldr.DdagNode, imp->ldr.DdagNode, NULL ))
|
||||||
status = STATUS_NO_MEMORY;
|
status = STATUS_NO_MEMORY;
|
||||||
current_modref = prev;
|
current_modref = prev;
|
||||||
|
@ -2882,29 +2901,15 @@ done:
|
||||||
*
|
*
|
||||||
* 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, const WCHAR *default_ext,
|
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, UNICODE_STRING *nt_name,
|
||||||
UNICODE_STRING *nt_name, WINE_MODREF **pwm, HANDLE *mapping,
|
WINE_MODREF **pwm, HANDLE *mapping, SECTION_IMAGE_INFORMATION *image_info,
|
||||||
SECTION_IMAGE_INFORMATION *image_info, struct file_id *id )
|
struct file_id *id )
|
||||||
{
|
{
|
||||||
WCHAR *ext, *dllname;
|
WCHAR *fullname = NULL;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG wow64_old_value = 0;
|
ULONG wow64_old_value = 0;
|
||||||
|
|
||||||
*pwm = NULL;
|
*pwm = NULL;
|
||||||
dllname = NULL;
|
|
||||||
|
|
||||||
if (default_ext) /* first append default extension */
|
|
||||||
{
|
|
||||||
if (!(ext = wcsrchr( libname, '.')) || wcschr( ext, '/' ) || wcschr( ext, '\\'))
|
|
||||||
{
|
|
||||||
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
|
|
||||||
(wcslen(libname)+wcslen(default_ext)+1) * sizeof(WCHAR))))
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
wcscpy( dllname, libname );
|
|
||||||
wcscat( dllname, default_ext );
|
|
||||||
libname = dllname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Win 7/2008R2 and up seem to re-enable WoW64 FS redirection when loading libraries */
|
/* Win 7/2008R2 and up seem to re-enable WoW64 FS redirection when loading libraries */
|
||||||
RtlWow64EnableFsRedirectionEx( 0, &wow64_old_value );
|
RtlWow64EnableFsRedirectionEx( 0, &wow64_old_value );
|
||||||
|
@ -2913,14 +2918,11 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
|
||||||
|
|
||||||
if (!contains_path( libname ))
|
if (!contains_path( libname ))
|
||||||
{
|
{
|
||||||
WCHAR *fullname = NULL;
|
|
||||||
|
|
||||||
status = find_actctx_dll( libname, &fullname );
|
status = find_actctx_dll( libname, &fullname );
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
TRACE ("found %s for %s\n", debugstr_w(fullname), debugstr_w(libname) );
|
TRACE ("found %s for %s\n", debugstr_w(fullname), debugstr_w(libname) );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
libname = fullname;
|
||||||
libname = dllname = fullname;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2945,7 +2947,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
|
||||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) status = STATUS_INVALID_IMAGE_FORMAT;
|
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) status = STATUS_INVALID_IMAGE_FORMAT;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
RtlFreeHeap( GetProcessHeap(), 0, fullname );
|
||||||
if (wow64_old_value) RtlWow64EnableFsRedirectionEx( 1, &wow64_old_value );
|
if (wow64_old_value) RtlWow64EnableFsRedirectionEx( 1, &wow64_old_value );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2957,8 +2959,7 @@ done:
|
||||||
* Load a PE style module according to the load order.
|
* Load a PE style module according to the load order.
|
||||||
* The loader_section must be locked while calling this function.
|
* The loader_section must be locked while calling this function.
|
||||||
*/
|
*/
|
||||||
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD flags, WINE_MODREF** pwm )
|
||||||
DWORD flags, WINE_MODREF** pwm )
|
|
||||||
{
|
{
|
||||||
UNICODE_STRING nt_name;
|
UNICODE_STRING nt_name;
|
||||||
struct file_id id;
|
struct file_id id;
|
||||||
|
@ -2969,7 +2970,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
||||||
|
|
||||||
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) );
|
||||||
|
|
||||||
nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
|
nts = find_dll_file( load_path, libname, &nt_name, pwm, &mapping, &image_info, &id );
|
||||||
|
|
||||||
if (*pwm) /* found already loaded module */
|
if (*pwm) /* found already loaded module */
|
||||||
{
|
{
|
||||||
|
@ -3060,10 +3061,11 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
NTSTATUS nts;
|
NTSTATUS nts;
|
||||||
|
WCHAR *dllname = append_dll_ext( libname->Buffer );
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
|
|
||||||
nts = load_dll( path_name, libname->Buffer, L".dll", flags, &wm );
|
nts = load_dll( path_name, dllname ? dllname : libname->Buffer, flags, &wm );
|
||||||
|
|
||||||
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||||
{
|
{
|
||||||
|
@ -3077,6 +3079,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||||
*hModule = (wm) ? wm->ldr.DllBase : NULL;
|
*hModule = (wm) ? wm->ldr.DllBase : NULL;
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &loader_section );
|
RtlLeaveCriticalSection( &loader_section );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
||||||
return nts;
|
return nts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3122,6 +3125,7 @@ NTSTATUS WINAPI LdrGetDllHandleEx( ULONG flags, LPCWSTR load_path, ULONG *dll_ch
|
||||||
struct file_id id;
|
struct file_id id;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
|
WCHAR *dllname;
|
||||||
HANDLE mapping;
|
HANDLE mapping;
|
||||||
|
|
||||||
TRACE( "flag %#x, load_path %p, dll_characteristics %p, name %p, base %p.\n",
|
TRACE( "flag %#x, load_path %p, dll_characteristics %p, name %p, base %p.\n",
|
||||||
|
@ -3136,9 +3140,12 @@ NTSTATUS WINAPI LdrGetDllHandleEx( ULONG flags, LPCWSTR load_path, ULONG *dll_ch
|
||||||
if (flags & ~supported_flags) FIXME( "Unsupported flags %#x.\n", flags );
|
if (flags & ~supported_flags) FIXME( "Unsupported flags %#x.\n", flags );
|
||||||
if (dll_characteristics) FIXME( "dll_characteristics unsupported.\n" );
|
if (dll_characteristics) FIXME( "dll_characteristics unsupported.\n" );
|
||||||
|
|
||||||
|
dllname = append_dll_ext( name->Buffer );
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
|
|
||||||
status = find_dll_file( load_path, name->Buffer, L".dll", &nt_name, &wm, &mapping, &image_info, &id );
|
status = find_dll_file( load_path, dllname ? dllname : name->Buffer,
|
||||||
|
&nt_name, &wm, &mapping, &image_info, &id );
|
||||||
|
|
||||||
if (wm) *base = wm->ldr.DllBase;
|
if (wm) *base = wm->ldr.DllBase;
|
||||||
else
|
else
|
||||||
|
@ -3157,6 +3164,7 @@ NTSTATUS WINAPI LdrGetDllHandleEx( ULONG flags, LPCWSTR load_path, ULONG *dll_ch
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &loader_section );
|
RtlLeaveCriticalSection( &loader_section );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, dllname );
|
||||||
TRACE( "%s -> %p (load path %s)\n", debugstr_us(name), status ? NULL : *base, debugstr_w(load_path) );
|
TRACE( "%s -> %p (load path %s)\n", debugstr_us(name), status ? NULL : *base, debugstr_w(load_path) );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -3839,7 +3847,7 @@ static void init_wow64( CONTEXT *context )
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
static const WCHAR wow64_path[] = L"C:\\windows\\system32\\wow64.dll";
|
static const WCHAR wow64_path[] = L"C:\\windows\\system32\\wow64.dll";
|
||||||
|
|
||||||
if ((status = load_dll( NULL, wow64_path, NULL, 0, &wm )))
|
if ((status = load_dll( NULL, wow64_path, 0, &wm )))
|
||||||
{
|
{
|
||||||
ERR( "could not load %s, status %x\n", debugstr_w(wow64_path), status );
|
ERR( "could not load %s, status %x\n", debugstr_w(wow64_path), status );
|
||||||
NtTerminateProcess( GetCurrentProcess(), status );
|
NtTerminateProcess( GetCurrentProcess(), status );
|
||||||
|
@ -3987,7 +3995,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
|
||||||
|
|
||||||
if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
|
if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
|
||||||
|
|
||||||
if ((status = load_dll( NULL, L"kernel32.dll", NULL, 0, &kernel32 )) != STATUS_SUCCESS)
|
if ((status = load_dll( NULL, L"kernel32.dll", 0, &kernel32 )) != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
|
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
|
||||||
NtTerminateProcess( GetCurrentProcess(), status );
|
NtTerminateProcess( GetCurrentProcess(), status );
|
||||||
|
|
Loading…
Reference in New Issue