Make behavior of builtin executables closer to that of builtin dlls.
Fixed case sensitivity of builtin executables.

diff --git a/include/module.h b/include/module.h
index 748fbe6..c953a9f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -259,6 +259,7 @@
 extern DWORD PE_fixup_imports(WINE_MODREF *wm);
 
 /* loader/loadorder.c */
+extern BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size );
 extern void MODULE_GetLoadOrder( enum loadorder_type plo[], const char *path, BOOL win32 );
 extern void MODULE_AddLoadOrderOption( const char *option );
 
diff --git a/loader/loadorder.c b/loader/loadorder.c
index a08a134..2f1107a 100644
--- a/loader/loadorder.c
+++ b/loader/loadorder.c
@@ -418,6 +418,62 @@
 
 
 /***************************************************************************
+ *	MODULE_GetBuiltinPath
+ *
+ * Get the path of a builtin module when the native file does not exist.
+ */
+BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size )
+{
+    char *p;
+    BOOL ret = FALSE;
+    UINT len = GetSystemDirectoryA( filename, size );
+
+    if (FILE_contains_path( libname ))
+    {
+        char *tmp;
+
+        /* if the library name contains a path and can not be found,
+         * return an error.
+         * exception: if the path is the system directory, proceed,
+         * so that modules which are not PE modules can be loaded.
+         * If the library name does not contain a path and can not
+         * be found, assume the system directory is meant */
+
+        if (strlen(libname) >= size) return FALSE;  /* too long */
+        if (strchr( libname, '/' ))  /* need to convert slashes */
+        {
+            if (!(tmp = HeapAlloc( GetProcessHeap(), 0, strlen(libname)+1 ))) return FALSE;
+            strcpy( tmp, libname );
+            for (p = tmp; *p; p++) if (*p == '/') *p = '\\';
+        }
+        else tmp = (char *)libname;
+
+        if (!FILE_strncasecmp( filename, tmp, len ) && tmp[len] == '\\')
+        {
+            strcpy( filename, tmp );
+            ret = TRUE;
+        }
+        if (tmp != libname) HeapFree( GetProcessHeap(), 0, tmp );
+        if (!ret) return FALSE;
+    }
+    else
+    {
+        if (strlen(libname) >= size - len - 1) return FALSE;
+        filename[len] = '\\';
+        strcpy( filename+len+1, libname );
+    }
+
+    /* if the filename doesn't have an extension, append the default */
+    if (!(p = strrchr( filename, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
+    {
+        if (strlen(filename) + strlen(ext) >= size) return FALSE;
+        strcat( filename, ext );
+    }
+    return TRUE;
+}
+
+
+/***************************************************************************
  *	MODULE_GetLoadOrder	(internal)
  *
  * Locate the loadorder of a module.
diff --git a/loader/module.c b/loader/module.c
index 19a7a8e..637c693 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1194,7 +1194,7 @@
 	WINE_MODREF *pwm;
 	int i;
 	enum loadorder_type loadorder[LOADORDER_NTYPES];
-	LPSTR filename, p;
+	LPSTR filename;
         const char *filetype = "";
         DWORD found;
         BOOL allocated_libdir = FALSE;
@@ -1222,28 +1222,7 @@
 	/* build the modules filename */
         if (!found)
 	{
-	    if ( ! GetSystemDirectoryA ( filename, MAX_PATH ) )
-  	        goto error;
-
-	    /* if the library name contains a path and can not be found,
-	     * return an error.
-	     * exception: if the path is the system directory, proceed,
-	     * so that modules which are not PE modules can be loaded.
-	     * If the library name does not contain a path and can not
-	     * be found, assume the system directory is meant */
-
-	    if ( ! FILE_strncasecmp ( filename, libname, strlen ( filename ) ))
-	        strcpy ( filename, libname );
-	    else
-	    {
-                if (FILE_contains_path(libname)) goto error;
-                strcat ( filename, "\\" );
-                strcat ( filename, libname );
-	    }
-
-	    /* if the filename doesn't have an extension, append .DLL */
-	    if (!(p = strrchr( filename, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
-	        strcat( filename, ".dll" );
+            if (!MODULE_GetBuiltinPath( libname, ".dll", filename, MAX_PATH )) goto error;
 	}
 
 	/* Check for already loaded module */
diff --git a/scheduler/process.c b/scheduler/process.c
index 3d35141..2aacce8 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -255,18 +255,46 @@
 
 
 /***********************************************************************
+ *           open_builtin_exe_file
+ *
+ * Open an exe file for a builtin exe.
+ */
+static void *open_builtin_exe_file( const char *name, char *error, int error_size, int test_only )
+{
+    char exename[MAX_PATH], *p;
+    const char *basename = get_basename(name);
+
+    if (strlen(basename) >= sizeof(exename)) return NULL;
+    strcpy( exename, basename );
+    for (p = exename; *p; p++) *p = FILE_tolower(*p);
+    return wine_dll_load_main_exe( exename, error, error_size, test_only );
+}
+
+
+/***********************************************************************
  *           open_exe_file
  *
- * Open an exe file, taking load order into account.
+ * Open a specific exe file, taking load order into account.
  * Returns the file handle or 0 for a builtin exe.
  */
 static HANDLE open_exe_file( const char *name )
 {
     enum loadorder_type loadorder[LOADORDER_NTYPES];
+    char buffer[MAX_PATH];
     HANDLE handle;
     int i;
 
-    SetLastError( ERROR_FILE_NOT_FOUND );
+    TRACE("looking for %s\n", debugstr_a(name) );
+
+    if ((handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
+                               NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
+    {
+        /* file doesn't exist, check for builtin */
+        if (!FILE_contains_path( name )) goto error;
+        if (!MODULE_GetBuiltinPath( name, "", buffer, sizeof(buffer) )) goto error;
+        name = buffer;
+    }
+
     MODULE_GetLoadOrder( loadorder, name, TRUE );
 
     for(i = 0; i < LOADORDER_NTYPES; i++)
@@ -276,19 +304,23 @@
         {
         case LOADORDER_DLL:
             TRACE( "Trying native exe %s\n", debugstr_a(name) );
-            if ((handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
-                                       NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
-                return handle;
-            if (GetLastError() != ERROR_FILE_NOT_FOUND) return INVALID_HANDLE_VALUE;
+            if (handle != INVALID_HANDLE_VALUE) return handle;
             break;
         case LOADORDER_BI:
             TRACE( "Trying built-in exe %s\n", debugstr_a(name) );
-            if (wine_dll_load_main_exe( get_basename(name), NULL, 0, 1 )) return 0;
-            break;
+            if (open_builtin_exe_file( name, NULL, 0, 1 ))
+            {
+                if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
+                return 0;
+            }
         default:
             break;
         }
     }
+    if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
+
+ error:
+    SetLastError( ERROR_FILE_NOT_FOUND );
     return INVALID_HANDLE_VALUE;
 }
 
@@ -308,46 +340,48 @@
 
     TRACE("looking for %s\n", debugstr_a(name) );
 
-    if (SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ))
+    if (!SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ) &&
+        !MODULE_GetBuiltinPath( name, ".exe", buffer, buflen ))
     {
-        *handle = open_exe_file( buffer );
-        return TRUE;
-    }
+        /* no builtin found, try native without extension in case it is a Unix app */
 
-    /* no such file in path, try builtin with .exe extension */
-
-    lstrcpynA( buffer, get_basename(name), buflen );
-    if (!strchr( buffer, '.' ))
-    {
-        char *p = buffer + strlen(buffer);
-        lstrcpynA( p, ".exe", buflen - (p - buffer) );
+        if (SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
+        {
+            TRACE( "Trying native/Unix binary %s\n", debugstr_a(buffer) );
+            if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
+                                        NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
+                return TRUE;
+        }
+        return FALSE;
     }
 
     MODULE_GetLoadOrder( loadorder, buffer, TRUE );
-    for (i = 0; i < LOADORDER_NTYPES; i++)
+
+    for(i = 0; i < LOADORDER_NTYPES; i++)
     {
-        if (loadorder[i] == LOADORDER_BI)
+        if (loadorder[i] == LOADORDER_INVALID) break;
+        switch(loadorder[i])
         {
+        case LOADORDER_DLL:
+            TRACE( "Trying native exe %s\n", debugstr_a(buffer) );
+            if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
+                                        NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
+                return TRUE;
+            if (GetLastError() != ERROR_FILE_NOT_FOUND) return TRUE;
+            break;
+        case LOADORDER_BI:
             TRACE( "Trying built-in exe %s\n", debugstr_a(buffer) );
-            if (wine_dll_load_main_exe( buffer, NULL, 0, 1 ))
+            if (open_builtin_exe_file( buffer, NULL, 0, 1 ))
             {
                 *handle = 0;
                 return TRUE;
             }
             break;
+        default:
+            break;
         }
-        if (loadorder[i] == LOADORDER_INVALID) break;
     }
-
-    /* no builtin found, try native without extension in case it is a Unix app */
-
-    if (SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
-    {
-        TRACE( "Trying native/Unix binary %s\n", debugstr_a(buffer) );
-        if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
-                                    NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
-            return TRUE;
-    }
+    SetLastError( ERROR_FILE_NOT_FOUND );
     return FALSE;
 }
 
@@ -569,7 +603,7 @@
     if (!main_exe_file)  /* no file handle -> Winelib app */
     {
         TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) );
-        if (wine_dll_load_main_exe( get_basename(main_exe_name), error, sizeof(error), 0 ))
+        if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0 ))
             goto found;
         MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error );
         ExitProcess(1);