diff --git a/dlls/commdlg/cdlg32.c b/dlls/commdlg/cdlg32.c
index 547e4d370b533ba26e4258356f9a5d8d50a329d7..b3bfa20cce8b67f8af08319cf5349e57814d9e38 100644
--- a/dlls/commdlg/cdlg32.c
+++ b/dlls/commdlg/cdlg32.c
@@ -31,7 +31,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
 
 HINSTANCE	COMDLG32_hInstance = 0;
-HINSTANCE16	COMDLG32_hInstance16 = 0;
+static HINSTANCE16 COMDLG32_hInstance16;
 
 static DWORD	COMDLG32_TlsIndex;
 
@@ -78,15 +78,7 @@ BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Res
 		COMDLG32_hInstance = hInstance;
 		DisableThreadLibraryCalls(hInstance);
 
-		if(!COMDLG32_hInstance16)
-		{
-			if(!(COMDLG32_hInstance16 = LoadLibrary16("commdlg.dll")))
-			{
-				ERR("Could not load sibling commdlg.dll\n");
-				return FALSE;
-			}
-		}
-
+		COMDLG32_hInstance16 = LoadLibrary16("commdlg.dll");
 		COMDLG32_TlsIndex = 0xffffffff;
 
 		SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL");
@@ -128,8 +120,6 @@ BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Res
 
 	case DLL_PROCESS_DETACH:
             if (COMDLG32_TlsIndex != 0xffffffff) TlsFree(COMDLG32_TlsIndex);
-            COMDLG32_TlsIndex = 0xffffffff;
-            COMDLG32_hInstance = 0;
             if(COMDLG32_hInstance16) FreeLibrary16(COMDLG32_hInstance16);
             if(SHFOLDER_hInstance) FreeLibrary(SHFOLDER_hInstance);
             break;
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 555a9315113e8bcc4b91ce77bb325b2fc1962b48..3fa26f25b097a67a1b10f5a72223db5013df392a 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -68,40 +68,41 @@ static BOOL process_attach(void)
     /* Initialize DOS memory */
     if (!DOSMEM_Init(0)) return FALSE;
 
-    if ((hModule = LoadLibrary16( "krnl386.exe" )) < 32) return FALSE;
-
-    /* Initialize special KERNEL entry points */
+    if ((hModule = LoadLibrary16( "krnl386.exe" )) >= 32)
+    {
+        /* Initialize special KERNEL entry points */
 
-    /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
-    NE_SetEntryPoint( hModule, 178, GetWinFlags16() );
+        /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
+        NE_SetEntryPoint( hModule, 178, GetWinFlags16() );
 
-    /* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
-    NE_SetEntryPoint( hModule, 454, wine_get_cs() );
-    NE_SetEntryPoint( hModule, 455, wine_get_ds() );
+        /* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
+        NE_SetEntryPoint( hModule, 454, wine_get_cs() );
+        NE_SetEntryPoint( hModule, 455, wine_get_ds() );
 
-    /* Initialize KERNEL.THHOOK */
-    TASK_InstallTHHook(MapSL((SEGPTR)GetProcAddress16( hModule, (LPCSTR)332 )));
+        /* Initialize KERNEL.THHOOK */
+        TASK_InstallTHHook(MapSL((SEGPTR)GetProcAddress16( hModule, (LPCSTR)332 )));
 
-    /* Initialize the real-mode selector entry points */
+        /* Initialize the real-mode selector entry points */
 #define SET_ENTRY_POINT( num, addr ) \
     NE_SetEntryPoint( hModule, (num), GLOBAL_CreateBlock( GMEM_FIXED, \
                       DOSMEM_MapDosToLinear(addr), 0x10000, hModule, \
                       WINE_LDT_FLAGS_DATA ))
 
-    SET_ENTRY_POINT( 174, 0xa0000 );  /* KERNEL.174: __A000H */
-    SET_ENTRY_POINT( 181, 0xb0000 );  /* KERNEL.181: __B000H */
-    SET_ENTRY_POINT( 182, 0xb8000 );  /* KERNEL.182: __B800H */
-    SET_ENTRY_POINT( 195, 0xc0000 );  /* KERNEL.195: __C000H */
-    SET_ENTRY_POINT( 179, 0xd0000 );  /* KERNEL.179: __D000H */
-    SET_ENTRY_POINT( 190, 0xe0000 );  /* KERNEL.190: __E000H */
-    NE_SetEntryPoint( hModule, 183, DOSMEM_0000H );       /* KERNEL.183: __0000H */
-    NE_SetEntryPoint( hModule, 173, DOSMEM_BiosSysSeg );  /* KERNEL.173: __ROMBIOS */
-    NE_SetEntryPoint( hModule, 193, DOSMEM_BiosDataSeg ); /* KERNEL.193: __0040H */
-    NE_SetEntryPoint( hModule, 194, DOSMEM_BiosSysSeg );  /* KERNEL.194: __F000H */
+        SET_ENTRY_POINT( 174, 0xa0000 );  /* KERNEL.174: __A000H */
+        SET_ENTRY_POINT( 181, 0xb0000 );  /* KERNEL.181: __B000H */
+        SET_ENTRY_POINT( 182, 0xb8000 );  /* KERNEL.182: __B800H */
+        SET_ENTRY_POINT( 195, 0xc0000 );  /* KERNEL.195: __C000H */
+        SET_ENTRY_POINT( 179, 0xd0000 );  /* KERNEL.179: __D000H */
+        SET_ENTRY_POINT( 190, 0xe0000 );  /* KERNEL.190: __E000H */
+        NE_SetEntryPoint( hModule, 183, DOSMEM_0000H );       /* KERNEL.183: __0000H */
+        NE_SetEntryPoint( hModule, 173, DOSMEM_BiosSysSeg );  /* KERNEL.173: __ROMBIOS */
+        NE_SetEntryPoint( hModule, 193, DOSMEM_BiosDataSeg ); /* KERNEL.193: __0040H */
+        NE_SetEntryPoint( hModule, 194, DOSMEM_BiosSysSeg );  /* KERNEL.194: __F000H */
 #undef SET_ENTRY_POINT
+    }
 
     /* Force loading of some dlls */
-    if (LoadLibrary16( "system" ) < 32) return FALSE;
+    LoadLibrary16( "system" );
 
     /* Create 16-bit task */
     TASK_CreateMainTask();
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index f57fdc83f33f06671a1e7bc77edc8b8f9e188723..bf4d862599d295fa425ff5acf101c05204b32597 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -214,8 +214,12 @@ static BOOL process_attach(void)
     HINSTANCE16 instance;
 
     /* Create USER heap */
-    if ((instance = LoadLibrary16( "USER.EXE" )) < 32) return FALSE;
-    USER_HeapSel = instance | 7;
+    if ((instance = LoadLibrary16( "USER.EXE" )) >= 32) USER_HeapSel = instance | 7;
+    else
+    {
+        USER_HeapSel = GlobalAlloc16( GMEM_FIXED, 65536 );
+        LocalInit16( USER_HeapSel, 32, 65534 );
+    }
 
     /* Load the graphics driver */
     tweak_init();
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 2a3c8422e45e959ed519b8eec6620b50b4dbb516..8c1e140e1136bae825571c0c812e7d19e9bbf0f4 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -584,8 +584,7 @@ BOOL GDI_Init(void)
         hkey = 0;
 
     /* create GDI heap */
-    if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE;
-    GDI_HeapSel = instance | 7;
+    if ((instance = LoadLibrary16( "GDI.EXE" )) >= 32) GDI_HeapSel = instance | 7;
 
     /* create stock objects */
     stock_objects[WHITE_BRUSH]  = CreateBrushIndirect( &WhiteBrush );
@@ -680,7 +679,16 @@ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_
     _EnterSysLevel( &GDI_level );
     switch(magic)
     {
-        /* allocate DCs on the larger heap */
+    default:
+        if (GDI_HeapSel)
+        {
+            if (!(hlocal = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
+            assert( hlocal & 2 );
+            obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hlocal );
+            *handle = (HGDIOBJ)(ULONG_PTR)hlocal;
+            break;
+        }
+        /* fall through */
     case DC_MAGIC:
     case DISABLED_DC_MAGIC:
     case META_DC_MAGIC:
@@ -691,12 +699,6 @@ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_
     case BITMAP_MAGIC:
         if (!(obj = alloc_large_heap( size, handle ))) goto error;
         break;
-    default:
-        if (!(hlocal = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error;
-        assert( hlocal & 2 );
-        obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, hlocal );
-        *handle = (HGDIOBJ)(ULONG_PTR)hlocal;
-        break;
     }
 
     obj->hNext   = 0;
@@ -724,16 +726,32 @@ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
 {
     HGDIOBJ new_handle;
 
-    assert( handle & 2 );  /* no realloc for large handles */
-    LOCAL_Unlock( GDI_HeapSel, handle );
-    if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE )))
+    if (handle & 2)  /* GDI heap handle */
     {
-        TRACE_SEC( handle, "leave" );
-        _LeaveSysLevel( &GDI_level );
-        return NULL;
+        LOCAL_Unlock( GDI_HeapSel, handle );
+        if ((new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE )))
+        {
+            assert( new_handle == handle );  /* moveable handle cannot change */
+            return LOCAL_Lock( GDI_HeapSel, handle );
+        }
     }
-    assert( new_handle == handle );  /* moveable handle cannot change */
-    return LOCAL_Lock( GDI_HeapSel, handle );
+    else
+    {
+        int i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
+        if (i >= 0 && i < MAX_LARGE_HANDLES && large_handles[i])
+        {
+            void *new_ptr = HeapReAlloc( GetProcessHeap(), 0, large_handles[i], size );
+            if (new_ptr)
+            {
+                large_handles[i] = new_ptr;
+                return new_ptr;
+            }
+        }
+        else ERR( "Invalid handle %x\n", handle );
+    }
+    TRACE_SEC( handle, "leave" );
+    _LeaveSysLevel( &GDI_level );
+    return NULL;
 }
 
 
diff --git a/windows/syscolor.c b/windows/syscolor.c
index 62c84acc568e0e427e645fb465f8bf2118d91740..ce8a302df46038239c697dd43a1e3d77f4f91754 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -125,23 +125,20 @@ static HPEN   SysColorPens[NUM_SYS_COLORS];
  */
 static void SYSCOLOR_MakeObjectSystem( HGDIOBJ handle, BOOL set)
 {
-    static WORD GDI_heap_sel = 0;
+    WORD heap_sel;
     LPWORD ptr;
 
-    if (!GDI_heap_sel)
+    if ((heap_sel = GetModuleHandle16( "gdi" )))
     {
-	GDI_heap_sel = LoadLibrary16("gdi");
-	FreeLibrary16(GDI_heap_sel);
+        ptr = (LPWORD)LOCAL_Lock(heap_sel, handle);
+
+        /* touch the "system" bit of the wMagic field of a GDIOBJHDR */
+        if (set)
+            *(ptr+1) &= ~OBJECT_NOSYSTEM;
+        else
+            *(ptr+1) |= OBJECT_NOSYSTEM;
+        LOCAL_Unlock( heap_sel, handle );
     }
-
-    ptr = (LPWORD)LOCAL_Lock(GDI_heap_sel, handle);
-
-    /* touch the "system" bit of the wMagic field of a GDIOBJHDR */
-    if (set)
-        *(ptr+1) &= ~OBJECT_NOSYSTEM;
-    else
-	*(ptr+1) |= OBJECT_NOSYSTEM;
-    LOCAL_Unlock( GDI_heap_sel, handle );
 }
 
 /*************************************************************************