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)
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,20 +2884,22 @@ 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 (default_ext) /* first append default extension */
{
if (!(ext = strrchrW( libname, '.')) || strchrW( ext, '/' ) || strchrW( ext, '\\'))
{
if (!(dllname = RtlAllocateHeap( GetProcessHeap(), 0,
(strlenW(libname) * sizeof(WCHAR)) + sizeof(dllW) )))
(strlenW(libname)+strlenW(default_ext)+1) * sizeof(WCHAR))))
return STATUS_NO_MEMORY;
strcpyW( dllname, libname );
strcatW( dllname, dllW );
strcatW( dllname, default_ext );
libname = dllname;
}
}
/* Win 7/2008R2 and up seem to re-enable WoW64 FS redirection when loading libraries */
if (is_wow64) RtlWow64EnableFsRedirectionEx( 0, &wow64_old_value );
......@@ -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(&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();
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 );
......
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