ntdll: Load the main binary directly in ntdll when possible.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
608d086f1b
commit
b0199ea2fe
|
@ -608,7 +608,8 @@ void * CDECL __wine_kernel_init(void)
|
||||||
|
|
||||||
set_library_argv( __wine_main_wargv );
|
set_library_argv( __wine_main_wargv );
|
||||||
|
|
||||||
if (!(peb->ImageBaseAddress = LoadLibraryExW( main_exe_name, 0, DONT_RESOLVE_DLL_REFERENCES )))
|
if (!peb->ImageBaseAddress &&
|
||||||
|
!(peb->ImageBaseAddress = LoadLibraryExW( main_exe_name, 0, DONT_RESOLVE_DLL_REFERENCES )))
|
||||||
{
|
{
|
||||||
DWORD_PTR args[1];
|
DWORD_PTR args[1];
|
||||||
WCHAR msgW[1024];
|
WCHAR msgW[1024];
|
||||||
|
@ -1500,7 +1501,6 @@ static BOOL create_process( HANDLE hFile, LPSECURITY_ATTRIBUTES psa, LPSECURITY_
|
||||||
DWORD startup_info_size;
|
DWORD startup_info_size;
|
||||||
int socketfd[2];
|
int socketfd[2];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* create the socket for the new process */
|
/* create the socket for the new process */
|
||||||
|
|
||||||
|
@ -1629,13 +1629,13 @@ static BOOL create_process( HANDLE hFile, LPSECURITY_ATTRIBUTES psa, LPSECURITY_
|
||||||
req->info = wine_server_obj_handle( process_info );
|
req->info = wine_server_obj_handle( process_info );
|
||||||
wine_server_call( req );
|
wine_server_call( req );
|
||||||
success = reply->success;
|
success = reply->success;
|
||||||
err = reply->exit_code;
|
status = reply->exit_code;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
SetLastError( err ? err : ERROR_INTERNAL_ERROR );
|
SetLastError( status ? RtlNtStatusToDosError(status) : ERROR_INTERNAL_ERROR );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
CloseHandle( process_info );
|
CloseHandle( process_info );
|
||||||
|
|
|
@ -165,7 +165,8 @@ static WINE_MODREF *cached_modref;
|
||||||
static WINE_MODREF *current_modref;
|
static WINE_MODREF *current_modref;
|
||||||
static WINE_MODREF *last_failed_modref;
|
static WINE_MODREF *last_failed_modref;
|
||||||
|
|
||||||
static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm );
|
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
||||||
|
DWORD flags, WINE_MODREF** pwm );
|
||||||
static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved );
|
static NTSTATUS process_attach( WINE_MODREF *wm, 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 );
|
||||||
|
@ -619,7 +620,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, 0, &wm ) == STATUS_SUCCESS &&
|
if (load_dll( load_path, mod_name, dllW, 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)
|
||||||
|
@ -790,7 +791,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
|
||||||
{
|
{
|
||||||
ascii_to_unicode( buffer, name, len );
|
ascii_to_unicode( buffer, name, len );
|
||||||
buffer[len] = 0;
|
buffer[len] = 0;
|
||||||
status = load_dll( load_path, buffer, 0, &wmImp );
|
status = load_dll( load_path, buffer, dllW, 0, &wmImp );
|
||||||
}
|
}
|
||||||
else /* need to allocate a larger buffer */
|
else /* need to allocate a larger buffer */
|
||||||
{
|
{
|
||||||
|
@ -798,7 +799,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
|
||||||
if (!ptr) return FALSE;
|
if (!ptr) return FALSE;
|
||||||
ascii_to_unicode( ptr, name, len );
|
ascii_to_unicode( ptr, name, len );
|
||||||
ptr[len] = 0;
|
ptr[len] = 0;
|
||||||
status = load_dll( load_path, ptr, 0, &wmImp );
|
status = load_dll( load_path, ptr, dllW, 0, &wmImp );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,7 +1086,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;
|
||||||
if (!(status = load_dll( load_path, mscoreeW, 0, &imp ))) wm->deps[0] = imp;
|
if (!(status = load_dll( load_path, mscoreeW, NULL, 0, &imp ))) wm->deps[0] = imp;
|
||||||
current_modref = prev;
|
current_modref = prev;
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
|
@ -2875,7 +2876,7 @@ 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,
|
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
||||||
UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
||||||
void **module, pe_image_info_t *image_info, struct stat *st )
|
void **module, pe_image_info_t *image_info, struct stat *st )
|
||||||
{
|
{
|
||||||
|
@ -2883,20 +2884,22 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG wow64_old_value = 0;
|
ULONG wow64_old_value = 0;
|
||||||
|
|
||||||
/* first append .dll if needed */
|
|
||||||
|
|
||||||
*pwm = NULL;
|
*pwm = NULL;
|
||||||
*module = NULL;
|
*module = NULL;
|
||||||
dllname = NULL;
|
dllname = NULL;
|
||||||
|
|
||||||
|
if (default_ext) /* first append default extension */
|
||||||
|
{
|
||||||
if (!(ext = strrchrW( libname, '.')) || strchrW( ext, '/' ) || strchrW( ext, '\\'))
|
if (!(ext = strrchrW( libname, '.')) || strchrW( ext, '/' ) || strchrW( ext, '\\'))
|
||||||
{
|
{
|
||||||
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
|
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||||
(strlenW(libname) * sizeof(WCHAR)) + sizeof(dllW) )))
|
(strlenW(libname)+strlenW(default_ext)+1) * sizeof(WCHAR))))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
strcpyW( dllname, libname );
|
strcpyW( dllname, libname );
|
||||||
strcatW( dllname, dllW );
|
strcatW( dllname, default_ext );
|
||||||
libname = dllname;
|
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 */
|
||||||
if (is_wow64) RtlWow64EnableFsRedirectionEx( 0, &wow64_old_value );
|
if (is_wow64) RtlWow64EnableFsRedirectionEx( 0, &wow64_old_value );
|
||||||
|
@ -2945,7 +2948,8 @@ 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( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
|
static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
||||||
|
DWORD flags, WINE_MODREF** pwm )
|
||||||
{
|
{
|
||||||
enum loadorder loadorder;
|
enum loadorder loadorder;
|
||||||
WINE_MODREF *main_exe;
|
WINE_MODREF *main_exe;
|
||||||
|
@ -2957,7 +2961,7 @@ 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) );
|
||||||
|
|
||||||
nts = find_dll_file( load_path, libname, &nt_name, pwm, &module, &image_info, &st );
|
nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &module, &image_info, &st );
|
||||||
|
|
||||||
if (*pwm) /* found already loaded module */
|
if (*pwm) /* found already loaded module */
|
||||||
{
|
{
|
||||||
|
@ -3085,7 +3089,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
|
|
||||||
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
||||||
nts = load_dll( path_name, libname->Buffer, flags, &wm );
|
nts = load_dll( path_name, libname->Buffer, dllW, flags, &wm );
|
||||||
|
|
||||||
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||||
{
|
{
|
||||||
|
@ -3119,7 +3123,7 @@ 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;
|
||||||
|
|
||||||
status = find_dll_file( load_path, name->Buffer, &nt_name, &wm, &module, &image_info, &st );
|
status = find_dll_file( load_path, name->Buffer, dllW, &nt_name, &wm, &module, &image_info, &st );
|
||||||
|
|
||||||
if (wm) *base = wm->ldr.BaseAddress;
|
if (wm) *base = wm->ldr.BaseAddress;
|
||||||
else
|
else
|
||||||
|
@ -4228,6 +4232,7 @@ void __wine_process_init(void)
|
||||||
static const WCHAR kernel32W[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
static const WCHAR kernel32W[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||||
's','y','s','t','e','m','3','2','\\',
|
's','y','s','t','e','m','3','2','\\',
|
||||||
'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ANSI_STRING func_name;
|
ANSI_STRING func_name;
|
||||||
|
@ -4275,6 +4280,19 @@ void __wine_process_init(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params = peb->ProcessParameters;
|
||||||
|
if (!(status = load_dll( params->DllPath.Buffer, params->ImagePathName.Buffer, NULL,
|
||||||
|
DONT_RESOLVE_DLL_REFERENCES, &wm )))
|
||||||
|
{
|
||||||
|
peb->ImageBaseAddress = wm->ldr.BaseAddress;
|
||||||
|
TRACE( "main exe loaded %s at %p\n", debugstr_us(¶ms->ImagePathName), peb->ImageBaseAddress );
|
||||||
|
}
|
||||||
|
else if (info_size)
|
||||||
|
{
|
||||||
|
WARN( "failed to load %s status %x\n", debugstr_us(¶ms->ImagePathName), status );
|
||||||
|
NtTerminateProcess( GetCurrentProcess(), status );
|
||||||
|
}
|
||||||
|
|
||||||
kernel32_start_process = init_func();
|
kernel32_start_process = init_func();
|
||||||
|
|
||||||
wm = get_modref( peb->ImageBaseAddress );
|
wm = get_modref( peb->ImageBaseAddress );
|
||||||
|
@ -4282,7 +4300,7 @@ void __wine_process_init(void)
|
||||||
if (wm->ldr.Flags & LDR_IMAGE_IS_DLL)
|
if (wm->ldr.Flags & LDR_IMAGE_IS_DLL)
|
||||||
{
|
{
|
||||||
MESSAGE( "wine: %s is a dll, not an executable\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
|
MESSAGE( "wine: %s is a dll, not an executable\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
|
||||||
exit(1);
|
NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual_set_large_address_space();
|
virtual_set_large_address_space();
|
||||||
|
|
|
@ -1386,7 +1386,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||||
char *unixdir = NULL, *winedebug = NULL;
|
char *unixdir = NULL, *winedebug = NULL;
|
||||||
startup_info_t *startup_info = NULL;
|
startup_info_t *startup_info = NULL;
|
||||||
ULONG startup_info_size, env_size;
|
ULONG startup_info_size, env_size;
|
||||||
int err, socketfd[2] = { -1, -1 };
|
int socketfd[2] = { -1, -1 };
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
pe_image_info_t pe_info;
|
pe_image_info_t pe_info;
|
||||||
|
|
||||||
|
@ -1496,7 +1496,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||||
req->info = wine_server_obj_handle( process_info );
|
req->info = wine_server_obj_handle( process_info );
|
||||||
wine_server_call( req );
|
wine_server_call( req );
|
||||||
success = reply->success;
|
success = reply->success;
|
||||||
err = reply->exit_code;
|
status = reply->exit_code;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
@ -1512,7 +1512,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||||
process_handle = thread_handle = 0;
|
process_handle = thread_handle = 0;
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else status = err ? err : STATUS_INTERNAL_ERROR;
|
else if (!status) status = STATUS_INTERNAL_ERROR;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (file_handle) NtClose( file_handle );
|
if (file_handle) NtClose( file_handle );
|
||||||
|
|
Loading…
Reference in New Issue