Always try to load the 32-bit owner dll instead of directly loading
the .so file for 16-bit builtins. Make the load order for 16-bit dlls
always match the load order of their 32-bit owner (if any).

diff --git a/dlls/kernel/ne_module.c b/dlls/kernel/ne_module.c
index e92d7ab..e386904 100644
--- a/dlls/kernel/ne_module.c
+++ b/dlls/kernel/ne_module.c
@@ -38,7 +38,6 @@
 #include "wine/winbase16.h"
 #include "winerror.h"
 #include "wownt32.h"
-#include "wine/library.h"
 #include "module.h"
 #include "toolhelp.h"
 #include "file.h"
@@ -157,25 +156,6 @@
 
 
 /***********************************************************************
- *           is_builtin_present
- *
- * Check if a builtin dll descriptor is present (because we loaded its 32-bit counterpart).
- */
-static BOOL is_builtin_present( LPCSTR name )
-{
-    char dllname[20], *p;
-
-    if (strlen(name) >= sizeof(dllname)-4) return FALSE;
-    strcpy( dllname, name );
-    p = strrchr( dllname, '.' );
-    if (!p) strcat( dllname, ".dll" );
-    for (p = dllname; *p; p++) *p = FILE_tolower(*p);
-
-    return (find_dll_descr( dllname ) != NULL);
-}
-
-
-/***********************************************************************
  *           __wine_register_dll_16 (KERNEL32.@)
  *
  * Register a built-in DLL descriptor.
@@ -1048,7 +1028,7 @@
 
     /* Open file */
     if ((hFile = OpenFile16( name, &ofs, OF_READ|OF_SHARE_DENY_WRITE )) == HFILE_ERROR16)
-        return (HMODULE16)2;  /* File not found */
+        return ERROR_FILE_NOT_FOUND;
 
     hModule = NE_LoadExeHeader( DosFileHandleToWin32Handle(hFile), ofs.szPathName );
     if (hModule < 32)
@@ -1096,7 +1076,7 @@
 
     hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
                                   descr->module_size, 0, WINE_LDT_FLAGS_DATA );
-    if (!hModule) return 0;
+    if (!hModule) return ERROR_NOT_ENOUGH_MEMORY;
     FarSetOwner16( hModule, hModule );
 
     pModule = (NE_MODULE *)GlobalLock16( hModule );
@@ -1110,7 +1090,7 @@
     pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
                                           pSegTable->minsize, hModule,
                                           WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
-    if (!pSegTable->hSeg) return 0;
+    if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
     patch_code_segment( descr->code_start );
     pSegTable++;
 
@@ -1120,7 +1100,7 @@
     minsize += pModule->heap_size;
     if (minsize > 0x10000) minsize = 0x10000;
     pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
-    if (!pSegTable->hSeg) return 0;
+    if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
     FarSetOwner16( pSegTable->hSeg, hModule );
     if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
                                     descr->data_start, pSegTable->minsize);
@@ -1131,57 +1111,10 @@
 
     NE_RegisterModule( pModule );
 
-    /* make sure the 32-bit library containing this one is loaded too */
-    LoadLibraryA( descr->owner );
-
     return hModule;
 }
 
 
-/***********************************************************************
- *           NE_LoadBuiltinModule
- *
- * Load a built-in module.
- */
-static HMODULE16 NE_LoadBuiltinModule( LPCSTR name )
-{
-    const BUILTIN16_DESCRIPTOR *descr;
-    char error[256], dllname[20], *p;
-    int file_exists;
-    void *handle;
-
-    /* Fix the name in case we have a full path and extension */
-
-    if ((p = strrchr( name, '\\' ))) name = p + 1;
-    if ((p = strrchr( name, '/' ))) name = p + 1;
-
-    if (strlen(name) >= sizeof(dllname)-4) return (HMODULE16)2;
-
-    strcpy( dllname, name );
-    p = strrchr( dllname, '.' );
-    if (!p) strcat( dllname, ".dll" );
-    for (p = dllname; *p; p++) *p = FILE_tolower(*p);
-
-    if ((descr = find_dll_descr( dllname )))
-        return NE_DoLoadBuiltinModule( descr );
-
-    if ((handle = wine_dll_load( dllname, error, sizeof(error), &file_exists )))
-    {
-        if ((descr = find_dll_descr( dllname )))
-            return NE_DoLoadBuiltinModule( descr );
-        if (GetModuleHandleA( dllname ))
-            return 21;  /* Win32 module */
-        ERR( "loaded .so but dll %s still not found\n", dllname );
-    }
-    else
-    {
-        if (!file_exists) WARN("cannot open .so lib for 16-bit builtin %s: %s\n", name, error);
-        else ERR("failed to load .so lib for 16-bit builtin %s: %s\n", name, error );
-    }
-    return (HMODULE16)2;
-}
-
-
 /**********************************************************************
  *	    MODULE_LoadModule16
  *
@@ -1192,107 +1125,101 @@
 static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only )
 {
     HINSTANCE16 hinst = 2;
-    enum loadorder_type loadorder[LOADORDER_NTYPES];
-    int i;
-    const char *filetype = "";
-    const char *ptr, *basename;
+    HMODULE16 hModule;
+    NE_MODULE *pModule;
+    const BUILTIN16_DESCRIPTOR *descr = NULL;
+    char dllname[20], owner[20], *p;
+    const char *basename;
 
     /* strip path information */
 
     basename = libname;
     if (basename[0] && basename[1] == ':') basename += 2;  /* strip drive specification */
-    if ((ptr = strrchr( basename, '\\' ))) basename = ptr + 1;
-    if ((ptr = strrchr( basename, '/' ))) basename = ptr + 1;
+    if ((p = strrchr( basename, '\\' ))) basename = p + 1;
+    if ((p = strrchr( basename, '/' ))) basename = p + 1;
 
-    if (is_builtin_present(basename))
+    if (strlen(basename) < sizeof(dllname)-4)
     {
-        TRACE( "forcing loadorder to builtin for %s\n", debugstr_a(basename) );
-        /* force builtin loadorder since the dll is already in memory */
-        loadorder[0] = LOADORDER_BI;
-        loadorder[1] = LOADORDER_INVALID;
+        strcpy( dllname, basename );
+        p = strrchr( dllname, '.' );
+        if (!p) strcat( dllname, ".dll" );
+        for (p = dllname; *p; p++) *p = FILE_tolower(*p);
+
+        if (!(descr = find_dll_descr( dllname )))
+        {
+            int file_exists;
+
+            if (wine_dll_get_owner( dllname, owner, sizeof(owner), &file_exists ) == -1)
+            {
+                if (file_exists) return 21;  /* it may be a Win32 module then */
+            }
+            else  /* found 32-bit owner, try to load it */
+            {
+                HMODULE mod32 = LoadLibraryA( owner );
+                if (mod32)
+                {
+                    if (!(descr = find_dll_descr( dllname ))) FreeLibrary( mod32 );
+                    /* loading the 32-bit library can have the side effect of loading the module */
+                    /* if so, simply incr the ref count and return the module */
+                    if ((hModule = GetModuleHandle16( libname )))
+                    {
+                        TRACE( "module %s already loaded by owner\n", libname );
+                        pModule = NE_GetPtr( hModule );
+                        if (pModule) pModule->count++;
+                        return hModule;
+                    }
+                }
+                else
+                {
+                    /* it's probably disabled by the load order config */
+                    WARN( "couldn't load owner %s for 16-bit dll %s\n", owner, dllname );
+                    return ERROR_FILE_NOT_FOUND;
+                }
+            }
+        }
+    }
+
+    if (descr)
+    {
+        TRACE("Trying built-in '%s'\n", libname);
+        hinst = NE_DoLoadBuiltinModule( descr );
+        if (hinst > 32) TRACE_(loaddll)("Loaded module %s : builtin\n", debugstr_a(libname));
     }
     else
     {
-        UNICODE_STRING pathW;
-        WCHAR buffer[MAX_PATH], *p;
-
-        if (!GetModuleFileNameW( 0, buffer, MAX_PATH )) p = NULL;
-        else
-        {
-            if ((p = strrchrW( buffer, '\\' ))) p++;
-            else p = buffer;
-        }
-        RtlCreateUnicodeStringFromAsciiz( &pathW, basename );
-        MODULE_GetLoadOrderW( loadorder, p, pathW.Buffer );
-        RtlFreeUnicodeString( &pathW );
+        TRACE("Trying native dll '%s'\n", libname);
+        hinst = NE_LoadModule(libname, lib_only);
+        if (hinst > 32) TRACE_(loaddll)("Loaded module %s : native\n", debugstr_a(libname));
     }
 
-    for(i = 0; i < LOADORDER_NTYPES; i++)
+    if (hinst > 32 && !implicit)
     {
-        if (loadorder[i] == LOADORDER_INVALID) break;
-
-        switch(loadorder[i])
+        hModule = GetModuleHandle16(libname);
+        if(!hModule)
         {
-        case LOADORDER_DLL:
-            TRACE("Trying native dll '%s'\n", libname);
-            hinst = NE_LoadModule(libname, lib_only);
-            filetype = "native";
-            break;
-
-        case LOADORDER_BI:
-            TRACE("Trying built-in '%s'\n", libname);
-            hinst = NE_LoadBuiltinModule(libname);
-            filetype = "builtin";
-            break;
-
-        default:
-            hinst = 2;
-            break;
+            ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get module handle. Filename too long ?\n",
+                libname, hinst);
+            return ERROR_INVALID_HANDLE;
         }
 
-        if(hinst >= 32)
+        pModule = NE_GetPtr(hModule);
+        if(!pModule)
         {
-            TRACE_(loaddll)("Loaded module '%s' : %s\n", libname, filetype);
-            if(!implicit)
-            {
-                HMODULE16 hModule;
-                NE_MODULE *pModule;
-
-                hModule = GetModuleHandle16(libname);
-                if(!hModule)
-                {
-                    ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get module handle. Filename too long ?\n",
-                        libname, hinst);
-                    return 6;   /* ERROR_INVALID_HANDLE seems most appropriate */
-                }
-
-                pModule = NE_GetPtr(hModule);
-                if(!pModule)
-                {
-                    ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get NE_MODULE pointer\n",
-                        libname, hinst);
-                    return 6;   /* ERROR_INVALID_HANDLE seems most appropriate */
-                }
-
-                TRACE("Loaded module '%s' at 0x%04x.\n", libname, hinst);
-
-                /*
-                 * Call initialization routines for all loaded DLLs. Note that
-                 * when we load implicitly linked DLLs this will be done by InitTask().
-                 */
-                if(pModule->flags & NE_FFLAGS_LIBMODULE)
-                {
-                    NE_InitializeDLLs(hModule);
-                    NE_DllProcessAttach(hModule);
-                }
-            }
-            return hinst;
+            ERR("Serious trouble. Just loaded module '%s' (hinst=0x%04x), but can't get NE_MODULE pointer\n",
+                libname, hinst);
+            return ERROR_INVALID_HANDLE;
         }
 
-        if(hinst != 2)
+        TRACE("Loaded module '%s' at 0x%04x.\n", libname, hinst);
+
+        /*
+         * Call initialization routines for all loaded DLLs. Note that
+         * when we load implicitly linked DLLs this will be done by InitTask().
+         */
+        if(pModule->flags & NE_FFLAGS_LIBMODULE)
         {
-            /* We quit searching when we get another error than 'File not found' */
-            break;
+            NE_InitializeDLLs(hModule);
+            NE_DllProcessAttach(hModule);
         }
     }
     return hinst;       /* The last error that occurred */