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

Alexandre Julliard julliard at wine.codeweavers.com
Tue Feb 21 13:13:05 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 2df3ad64eb9e1a4018b1cc49b1525464c939fc43
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=2df3ad64eb9e1a4018b1cc49b1525464c939fc43

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Feb 21 19:48:18 2006 +0100

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 5a7678d..8df05af 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 2607b17..547eb51 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1271,16 +1271,6 @@ static void load_builtin_callback( void 
     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 
     }
     wm->ldr.Flags |= LDR_WINE_INTERNAL;
 
-    /* fixup imports */
+    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 */
 
-    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;
+        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 un
     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 */
 




More information about the wine-cvs mailing list