Commit 2df3ad64 authored by Alexandre Julliard's avatar Alexandre Julliard

kernel: Use LoadLibrary to load the main exe in all cases.

parent ca311b3f
...@@ -989,9 +989,12 @@ static void start_process( void *arg ) ...@@ -989,9 +989,12 @@ static void start_process( void *arg )
*/ */
void __wine_kernel_init(void) void __wine_kernel_init(void)
{ {
WCHAR *main_exe_name, *p; static const WCHAR dotW[] = {'.',0};
char error[1024]; static const WCHAR exeW[] = {'.','e','x','e',0};
int file_exists;
WCHAR *p, main_exe_name[MAX_PATH];
HMODULE module;
DWORD type, error = 0;
PEB *peb = NtCurrentTeb()->Peb; PEB *peb = NtCurrentTeb()->Peb;
/* Initialize everything */ /* Initialize everything */
...@@ -1000,9 +1003,12 @@ void __wine_kernel_init(void) ...@@ -1000,9 +1003,12 @@ void __wine_kernel_init(void)
__wine_main_argv++; /* remove argv[0] (wine itself) */ __wine_main_argv++; /* remove argv[0] (wine itself) */
__wine_main_argc--; __wine_main_argc--;
if (!(main_exe_name = peb->ProcessParameters->ImagePathName.Buffer)) if (peb->ProcessParameters->ImagePathName.Buffer)
{
strcpyW( main_exe_name, peb->ProcessParameters->ImagePathName.Buffer );
}
else
{ {
WCHAR buffer[MAX_PATH];
WCHAR exe_nameW[MAX_PATH]; WCHAR exe_nameW[MAX_PATH];
if (!__wine_main_argv[0]) usage(); if (!__wine_main_argv[0]) usage();
...@@ -1013,97 +1019,52 @@ void __wine_kernel_init(void) ...@@ -1013,97 +1019,52 @@ void __wine_kernel_init(void)
} }
MultiByteToWideChar( CP_UNIXCP, 0, __wine_main_argv[0], -1, exe_nameW, MAX_PATH ); MultiByteToWideChar( CP_UNIXCP, 0, __wine_main_argv[0], -1, exe_nameW, MAX_PATH );
if (!find_exe_file( exe_nameW, buffer, MAX_PATH, &main_exe_file )) if (!SearchPathW( NULL, exe_nameW, exeW, MAX_PATH, main_exe_name, NULL ) &&
!get_builtin_path( exe_nameW, exeW, main_exe_name, MAX_PATH ))
{ {
MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] ); MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] );
ExitProcess(1); ExitProcess(1);
} }
if (main_exe_file == INVALID_HANDLE_VALUE)
{
MESSAGE( "wine: cannot open %s\n", debugstr_w(main_exe_name) );
ExitProcess(1);
}
RtlCreateUnicodeString( &peb->ProcessParameters->ImagePathName, buffer );
main_exe_name = peb->ProcessParameters->ImagePathName.Buffer;
} }
/* if there's no extension, append a dot to prevent LoadLibrary from appending .dll */
p = strrchrW( main_exe_name, '.' );
if (!p || strchrW( p, '/' ) || strchrW( p, '\\' )) strcatW( main_exe_name, dotW );
TRACE( "starting process name=%s file=%p argv[0]=%s\n", TRACE( "starting process name=%s file=%p argv[0]=%s\n",
debugstr_w(main_exe_name), main_exe_file, debugstr_a(__wine_main_argv[0]) ); debugstr_w(main_exe_name), main_exe_file, debugstr_a(__wine_main_argv[0]) );
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath, RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath,
MODULE_get_dll_load_path(NULL) ); MODULE_get_dll_load_path(NULL) );
if (!main_exe_file) /* no file handle -> Winelib app */ if (!(module = LoadLibraryExW( main_exe_name, 0, DONT_RESOLVE_DLL_REFERENCES )))
{ {
TRACE( "starting Winelib app %s\n", debugstr_w(main_exe_name) ); error = GetLastError();
if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0, &file_exists ) && /* check for a DOS binary and start winevdm if needed */
NtCurrentTeb()->Peb->ImageBaseAddress) if (error == ERROR_BAD_EXE_FORMAT && GetBinaryTypeW( main_exe_name, &type ))
goto found;
MESSAGE( "wine: cannot open builtin exe for %s: %s\n",
debugstr_w(main_exe_name), error );
ExitProcess(1);
}
switch( MODULE_GetBinaryType( main_exe_file, NULL, NULL ))
{ {
case BINARY_PE_EXE: if (type == SCS_WOW_BINARY || type == SCS_DOS_BINARY ||
TRACE( "starting Win32 binary %s\n", debugstr_w(main_exe_name) ); type == SCS_OS216_BINARY || type == SCS_PIF_BINARY)
if ((peb->ImageBaseAddress = LoadLibraryExW( main_exe_name, 0, DONT_RESOLVE_DLL_REFERENCES )))
goto found;
MESSAGE( "wine: could not load %s as Win32 binary\n", debugstr_w(main_exe_name) );
ExitProcess(1);
case BINARY_PE_DLL:
MESSAGE( "wine: %s is a DLL, not an executable\n", debugstr_w(main_exe_name) );
ExitProcess(1);
case BINARY_UNKNOWN:
/* check for .com extension */
if (!(p = strrchrW( main_exe_name, '.' )) || strcmpiW( p, comW ))
{ {
MESSAGE( "wine: cannot determine executable type for %s\n",
debugstr_w(main_exe_name) );
ExitProcess(1);
}
/* fall through */
case BINARY_OS216:
case BINARY_WIN16:
case BINARY_DOS:
TRACE( "starting Win16/DOS binary %s\n", debugstr_w(main_exe_name) );
__wine_main_argv--; __wine_main_argv--;
__wine_main_argc++; __wine_main_argc++;
__wine_main_argv[0] = "winevdm.exe"; __wine_main_argv[0] = "winevdm.exe";
if (open_builtin_exe_file( winevdmW, error, sizeof(error), 0, &file_exists )) module = LoadLibraryExW( winevdmW, 0, DONT_RESOLVE_DLL_REFERENCES );
goto found;
MESSAGE( "wine: trying to run %s, cannot open builtin library for 'winevdm.exe': %s\n",
debugstr_w(main_exe_name), error );
ExitProcess(1);
case BINARY_UNIX_EXE:
MESSAGE( "wine: %s is a Unix binary, not supported\n", debugstr_w(main_exe_name) );
ExitProcess(1);
case BINARY_UNIX_LIB:
{
char *unix_name;
TRACE( "starting Winelib app %s\n", debugstr_w(main_exe_name) );
if ((unix_name = wine_get_unix_file_name( main_exe_name )) &&
wine_dlopen( unix_name, RTLD_NOW, error, sizeof(error) ))
{
static const WCHAR soW[] = {'.','s','o',0};
if ((p = strrchrW( main_exe_name, '.' )) && !strcmpW( p, soW ))
{
*p = 0;
/* update the unicode string */
RtlInitUnicodeString( &peb->ProcessParameters->ImagePathName, main_exe_name );
} }
HeapFree( GetProcessHeap(), 0, unix_name );
goto found;
} }
MESSAGE( "wine: could not load %s: %s\n", debugstr_w(main_exe_name), error );
ExitProcess(1);
} }
if (main_exe_file) CloseHandle( main_exe_file );
if (!module)
{
char msg[1024];
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, msg, sizeof(msg), NULL );
MESSAGE( "wine: could not load %s: %s", debugstr_w(main_exe_name), msg );
ExitProcess(1);
} }
found: peb->ImageBaseAddress = module;
CloseHandle( main_exe_file );
/* build command line */ /* build command line */
set_library_wargv( __wine_main_argv ); set_library_wargv( __wine_main_argv );
......
...@@ -1271,16 +1271,6 @@ static void load_builtin_callback( void *module, const char *filename ) ...@@ -1271,16 +1271,6 @@ static void load_builtin_callback( void *module, const char *filename )
addr = module; addr = module;
NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &nt->OptionalHeader.SizeOfImage, NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &nt->OptionalHeader.SizeOfImage,
MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY ); MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
/* if we already have an executable, ignore this one */
if (!NtCurrentTeb()->Peb->ImageBaseAddress)
{
NtCurrentTeb()->Peb->ImageBaseAddress = module;
return; /* don't create the modref here, will be done later on */
}
}
/* create the MODREF */ /* create the MODREF */
if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename ))) if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename )))
...@@ -1300,6 +1290,13 @@ static void load_builtin_callback( void *module, const char *filename ) ...@@ -1300,6 +1290,13 @@ static void load_builtin_callback( void *module, const char *filename )
} }
wm->ldr.Flags |= LDR_WINE_INTERNAL; wm->ldr.Flags |= LDR_WINE_INTERNAL;
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
!NtCurrentTeb()->Peb->ImageBaseAddress) /* if we already have an executable, ignore this one */
{
NtCurrentTeb()->Peb->ImageBaseAddress = module;
}
else
{
/* fixup imports */ /* fixup imports */
load_path = builtin_load_info->load_path; load_path = builtin_load_info->load_path;
...@@ -1314,6 +1311,8 @@ static void load_builtin_callback( void *module, const char *filename ) ...@@ -1314,6 +1311,8 @@ static void load_builtin_callback( void *module, const char *filename )
builtin_load_info->status = STATUS_DLL_NOT_FOUND; builtin_load_info->status = STATUS_DLL_NOT_FOUND;
return; return;
} }
}
builtin_load_info->wm = wm; builtin_load_info->wm = wm;
TRACE( "loaded %s %p %p\n", filename, wm, module ); TRACE( "loaded %s %p %p\n", filename, wm, module );
...@@ -2039,11 +2038,12 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3, ...@@ -2039,11 +2038,12 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3,
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress ); IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
/* allocate the modref for the main exe (if not already done) */ /* allocate the modref for the main exe (if not already done) */
if (!(wm = get_modref( peb->ImageBaseAddress )) && wm = get_modref( peb->ImageBaseAddress );
!(wm = alloc_module( peb->ImageBaseAddress, peb->ProcessParameters->ImagePathName.Buffer ))) assert( wm );
if (wm->ldr.Flags & LDR_IMAGE_IS_DLL)
{ {
status = STATUS_NO_MEMORY; ERR("%s is a dll, not an executable\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
goto error; exit(1);
} }
wm->ldr.LoadCount = -1; /* can't unload main exe */ wm->ldr.LoadCount = -1; /* can't unload main exe */
......
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