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 );
|
||||
|
||||
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];
|
||||
WCHAR msgW[1024];
|
||||
|
@ -1500,7 +1501,6 @@ static BOOL create_process( HANDLE hFile, LPSECURITY_ATTRIBUTES psa, LPSECURITY_
|
|||
DWORD startup_info_size;
|
||||
int socketfd[2];
|
||||
pid_t pid;
|
||||
int err;
|
||||
|
||||
/* 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 );
|
||||
wine_server_call( req );
|
||||
success = reply->success;
|
||||
err = reply->exit_code;
|
||||
status = reply->exit_code;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
SetLastError( err ? err : ERROR_INTERNAL_ERROR );
|
||||
SetLastError( status ? RtlNtStatusToDosError(status) : ERROR_INTERNAL_ERROR );
|
||||
goto error;
|
||||
}
|
||||
CloseHandle( process_info );
|
||||
|
|
|
@ -165,7 +165,8 @@ static WINE_MODREF *cached_modref;
|
|||
static WINE_MODREF *current_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 FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
||||
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 )))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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 );
|
||||
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 */
|
||||
{
|
||||
|
@ -798,7 +799,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
|
|||
if (!ptr) return FALSE;
|
||||
ascii_to_unicode( ptr, name, len );
|
||||
ptr[len] = 0;
|
||||
status = load_dll( load_path, ptr, 0, &wmImp );
|
||||
status = load_dll( load_path, ptr, dllW, 0, &wmImp );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
|
@ -1085,7 +1086,7 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
|
|||
|
||||
prev = current_modref;
|
||||
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;
|
||||
if (status)
|
||||
{
|
||||
|
@ -2875,7 +2876,7 @@ done:
|
|||
*
|
||||
* 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,
|
||||
void **module, pe_image_info_t *image_info, struct stat *st )
|
||||
{
|
||||
|
@ -2883,19 +2884,21 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
|
|||
NTSTATUS status;
|
||||
ULONG wow64_old_value = 0;
|
||||
|
||||
/* first append .dll if needed */
|
||||
|
||||
*pwm = NULL;
|
||||
*module = NULL;
|
||||
dllname = NULL;
|
||||
if (!(ext = strrchrW( libname, '.')) || strchrW( ext, '/' ) || strchrW( ext, '\\'))
|
||||
|
||||
if (default_ext) /* first append default extension */
|
||||
{
|
||||
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
(strlenW(libname) * sizeof(WCHAR)) + sizeof(dllW) )))
|
||||
return STATUS_NO_MEMORY;
|
||||
strcpyW( dllname, libname );
|
||||
strcatW( dllname, dllW );
|
||||
libname = dllname;
|
||||
if (!(ext = strrchrW( libname, '.')) || strchrW( ext, '/' ) || strchrW( ext, '\\'))
|
||||
{
|
||||
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
(strlenW(libname)+strlenW(default_ext)+1) * sizeof(WCHAR))))
|
||||
return STATUS_NO_MEMORY;
|
||||
strcpyW( dllname, libname );
|
||||
strcatW( dllname, default_ext );
|
||||
libname = dllname;
|
||||
}
|
||||
}
|
||||
|
||||
/* Win 7/2008R2 and up seem to re-enable WoW64 FS redirection when loading libraries */
|
||||
|
@ -2945,7 +2948,8 @@ done:
|
|||
* Load a PE style module according to the load order.
|
||||
* 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;
|
||||
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) );
|
||||
|
||||
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 */
|
||||
{
|
||||
|
@ -3085,7 +3089,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
|||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
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;
|
||||
else
|
||||
|
@ -4228,6 +4232,7 @@ void __wine_process_init(void)
|
|||
static const WCHAR kernel32W[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\',
|
||||
'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
||||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
WINE_MODREF *wm;
|
||||
NTSTATUS status;
|
||||
ANSI_STRING func_name;
|
||||
|
@ -4275,6 +4280,19 @@ void __wine_process_init(void)
|
|||
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();
|
||||
|
||||
wm = get_modref( peb->ImageBaseAddress );
|
||||
|
@ -4282,7 +4300,7 @@ void __wine_process_init(void)
|
|||
if (wm->ldr.Flags & LDR_IMAGE_IS_DLL)
|
||||
{
|
||||
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();
|
||||
|
|
|
@ -1386,7 +1386,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
|||
char *unixdir = NULL, *winedebug = NULL;
|
||||
startup_info_t *startup_info = NULL;
|
||||
ULONG startup_info_size, env_size;
|
||||
int err, socketfd[2] = { -1, -1 };
|
||||
int socketfd[2] = { -1, -1 };
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
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 );
|
||||
wine_server_call( req );
|
||||
success = reply->success;
|
||||
err = reply->exit_code;
|
||||
status = reply->exit_code;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
|
@ -1512,7 +1512,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
|||
process_handle = thread_handle = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else status = err ? err : STATUS_INTERNAL_ERROR;
|
||||
else if (!status) status = STATUS_INTERNAL_ERROR;
|
||||
|
||||
done:
|
||||
if (file_handle) NtClose( file_handle );
|
||||
|
|
Loading…
Reference in New Issue