From 2df3ad64eb9e1a4018b1cc49b1525464c939fc43 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 21 Feb 2006 19:48:18 +0100 Subject: [PATCH] kernel: Use LoadLibrary to load the main exe in all cases. --- dlls/kernel/process.c | 115 ++++++++++++++---------------------------- dlls/ntdll/loader.c | 52 +++++++++---------- 2 files changed, 64 insertions(+), 103 deletions(-) diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 5a7678daf5d..8df05af72dd 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -989,9 +989,12 @@ static void start_process( void *arg ) */ void __wine_kernel_init(void) { - WCHAR *main_exe_name, *p; - char error[1024]; - int file_exists; + static const WCHAR dotW[] = {'.',0}; + static const WCHAR exeW[] = {'.','e','x','e',0}; + + WCHAR *p, main_exe_name[MAX_PATH]; + HMODULE module; + DWORD type, error = 0; PEB *peb = NtCurrentTeb()->Peb; /* Initialize everything */ @@ -1000,9 +1003,12 @@ void __wine_kernel_init(void) __wine_main_argv++; /* remove argv[0] (wine itself) */ __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]; if (!__wine_main_argv[0]) usage(); @@ -1013,97 +1019,52 @@ void __wine_kernel_init(void) } 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] ); 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", debugstr_w(main_exe_name), main_exe_file, debugstr_a(__wine_main_argv[0]) ); RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath, 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) ); - if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0, &file_exists ) && - NtCurrentTeb()->Peb->ImageBaseAddress) - 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: - TRACE( "starting Win32 binary %s\n", debugstr_w(main_exe_name) ); - 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 )) + error = GetLastError(); + /* check for a DOS binary and start winevdm if needed */ + if (error == ERROR_BAD_EXE_FORMAT && GetBinaryTypeW( main_exe_name, &type )) { - 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_argc++; - __wine_main_argv[0] = "winevdm.exe"; - if (open_builtin_exe_file( winevdmW, error, sizeof(error), 0, &file_exists )) - 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) )) + if (type == SCS_WOW_BINARY || type == SCS_DOS_BINARY || + type == SCS_OS216_BINARY || type == SCS_PIF_BINARY) { - 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; + __wine_main_argv--; + __wine_main_argc++; + __wine_main_argv[0] = "winevdm.exe"; + module = LoadLibraryExW( winevdmW, 0, DONT_RESOLVE_DLL_REFERENCES ); } - MESSAGE( "wine: could not load %s: %s\n", debugstr_w(main_exe_name), error ); - ExitProcess(1); } } - found: - CloseHandle( main_exe_file ); + 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); + } + + peb->ImageBaseAddress = module; /* build command line */ set_library_wargv( __wine_main_argv ); diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 2607b177352..547eb5100d3 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1271,16 +1271,6 @@ static void load_builtin_callback( void *module, const char *filename ) addr = module; NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &nt->OptionalHeader.SizeOfImage, 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 */ if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename ))) @@ -1300,20 +1290,29 @@ static void load_builtin_callback( void *module, const char *filename ) } wm->ldr.Flags |= LDR_WINE_INTERNAL; - /* fixup imports */ - - load_path = builtin_load_info->load_path; - if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; - if (!load_path) load_path = emptyW; - if (fixup_imports( wm, load_path ) != STATUS_SUCCESS) + if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) && + !NtCurrentTeb()->Peb->ImageBaseAddress) /* if we already have an executable, ignore this one */ { - /* the module has only be inserted in the load & memory order lists */ - RemoveEntryList(&wm->ldr.InLoadOrderModuleList); - RemoveEntryList(&wm->ldr.InMemoryOrderModuleList); - /* FIXME: free the modref */ - builtin_load_info->status = STATUS_DLL_NOT_FOUND; - return; + NtCurrentTeb()->Peb->ImageBaseAddress = module; } + else + { + /* fixup imports */ + + load_path = builtin_load_info->load_path; + if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; + if (!load_path) load_path = emptyW; + if (fixup_imports( wm, load_path ) != STATUS_SUCCESS) + { + /* the module has only be inserted in the load & memory order lists */ + RemoveEntryList(&wm->ldr.InLoadOrderModuleList); + RemoveEntryList(&wm->ldr.InMemoryOrderModuleList); + /* FIXME: free the modref */ + builtin_load_info->status = STATUS_DLL_NOT_FOUND; + return; + } + } + builtin_load_info->wm = wm; TRACE( "loaded %s %p %p\n", filename, wm, module ); @@ -2039,11 +2038,12 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3, IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress ); /* allocate the modref for the main exe (if not already done) */ - if (!(wm = get_modref( peb->ImageBaseAddress )) && - !(wm = alloc_module( peb->ImageBaseAddress, peb->ProcessParameters->ImagePathName.Buffer ))) + wm = get_modref( peb->ImageBaseAddress ); + assert( wm ); + if (wm->ldr.Flags & LDR_IMAGE_IS_DLL) { - status = STATUS_NO_MEMORY; - goto error; + ERR("%s is a dll, not an executable\n", debugstr_w(wm->ldr.FullDllName.Buffer) ); + exit(1); } wm->ldr.LoadCount = -1; /* can't unload main exe */