Commit b0199ea2 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Load the main binary directly in ntdll when possible.

parent 608d086f
...@@ -608,7 +608,8 @@ void * CDECL __wine_kernel_init(void) ...@@ -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_ ...@@ -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_ ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 * ...@@ -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: ...@@ -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, ...@@ -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: ...@@ -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_ ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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(&params->ImagePathName), peb->ImageBaseAddress );
}
else if (info_size)
{
WARN( "failed to load %s status %x\n", debugstr_us(&params->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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment