Built-in DLLs resources are now specified in spec file.
Removed unnecessary flags in built-in DLLs tables.

diff --git a/dlls/comctl32/comctl32.spec b/dlls/comctl32/comctl32.spec
index 3fe9162..dbe440f 100644
--- a/dlls/comctl32/comctl32.spec
+++ b/dlls/comctl32/comctl32.spec
@@ -1,6 +1,7 @@
 name	comctl32
 type	win32
 init	COMCTL32_LibMain
+rsrc	comctl32
 
 # Functions exported by the Win95 comctl32.dll 
 # (these need to have these exact ordinals, because some win95 dlls 
diff --git a/dlls/commdlg/comdlg32.spec b/dlls/commdlg/comdlg32.spec
index 25c6fac..779b598 100644
--- a/dlls/commdlg/comdlg32.spec
+++ b/dlls/commdlg/comdlg32.spec
@@ -1,6 +1,7 @@
 name	comdlg32
 type	win32
 init	COMDLG32_DllEntryPoint
+rsrc	comdlg32
 
  0 stub ArrowBtnWndProc
  1 stdcall ChooseColorA(ptr) ChooseColorA
diff --git a/dlls/display/display.spec b/dlls/display/display.spec
index c475a95..d1fdab9 100644
--- a/dlls/display/display.spec
+++ b/dlls/display/display.spec
@@ -1,5 +1,6 @@
 name	display
 type	win16
+rsrc	display
 
 1   stub BitBlt
 2   stub ColorInfo
diff --git a/dlls/mouse/mouse.spec b/dlls/mouse/mouse.spec
index 4bda02c..e9b2ca4 100644
--- a/dlls/mouse/mouse.spec
+++ b/dlls/mouse/mouse.spec
@@ -1,5 +1,6 @@
 name	mouse
 type	win16
+rsrc	mouse
 
 1 pascal16 Inquire(ptr) MOUSE_Inquire
 2 pascal16 Enable(segptr) WIN16_MOUSE_Enable
diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index 115867f..2462622 100644
--- a/dlls/shell32/shell32.spec
+++ b/dlls/shell32/shell32.spec
@@ -1,6 +1,7 @@
 name	shell32
 type	win32
 init	Shell32LibMain
+rsrc	shell32
 
 # Functions exported by the Win95 shell32.dll 
 # (these need to have these exact ordinals, for some 
diff --git a/dlls/winmm/winmm.spec b/dlls/winmm/winmm.spec
index cca5e09..54e1a0b 100644
--- a/dlls/winmm/winmm.spec
+++ b/dlls/winmm/winmm.spec
@@ -1,6 +1,7 @@
 name winmm
 type win32
 init WINMM_LibMain
+rsrc winmm
 
 # ordinal exports
 1 stdcall @(ptr long long) PlaySoundA
diff --git a/if1632/builtin.c b/if1632/builtin.c
index 6836d28..93de025 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -24,7 +24,7 @@
 #include "debugtools.h"
 #include "toolhelp.h"
 
-DEFAULT_DEBUG_CHANNEL(module)
+DEFAULT_DEBUG_CHANNEL(module);
 
 typedef struct
 {
@@ -33,16 +33,6 @@
     DWORD   res_size;           /* size of resource data */
 } BUILTIN16_RESOURCE;
 
-typedef struct
-{
-    const WIN16_DESCRIPTOR *descr;     /* DLL descriptor */
-    int                     flags;     /* flags (see below) */
-    const BUILTIN16_RESOURCE *res;     /* resource descriptor */
-} BUILTIN16_DLL;
-
-/* DLL flags */
-#define DLL_FLAG_NOT_USED    0x01  /* Use original Windows DLL if possible */
-#define DLL_FLAG_ALWAYS_USED 0x02  /* Always use built-in DLL */
 
 /* 16-bit DLLs */
 
@@ -89,57 +79,60 @@
 extern const WIN16_DESCRIPTOR WINSOCK_Descriptor;
 extern const WIN16_DESCRIPTOR WPROCS_Descriptor;
 
-extern const BUILTIN16_RESOURCE display_ResourceDescriptor;
-extern const BUILTIN16_RESOURCE mouse_ResourceDescriptor;
-
 /* Table of all built-in DLLs */
 
-static BUILTIN16_DLL BuiltinDLLs[] =
+static const WIN16_DESCRIPTOR *BuiltinDLLs[] =
 {
-    { &KERNEL_Descriptor,   0, NULL },
-    { &USER_Descriptor,     0, NULL },
-    { &GDI_Descriptor,      0, NULL },
-    { &SYSTEM_Descriptor,   DLL_FLAG_ALWAYS_USED, NULL },
-    { &DISPLAY_Descriptor,  DLL_FLAG_ALWAYS_USED, &display_ResourceDescriptor },
-    { &WPROCS_Descriptor,   DLL_FLAG_ALWAYS_USED, NULL },
-    { &WINDEBUG_Descriptor, DLL_FLAG_NOT_USED, NULL },
-    { &AVIFILE_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &COMMDLG_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &COMPOBJ_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &DDEML_Descriptor,    DLL_FLAG_NOT_USED, NULL },
-    { &DISPDIB_Descriptor,  0, NULL },
-    { &KEYBOARD_Descriptor, 0, NULL },
-    { &COMM_Descriptor,     0, NULL },
-    { &LZEXPAND_Descriptor, 0, NULL },
-    { &MMSYSTEM_Descriptor, 0, NULL },
-    { &MOUSE_Descriptor,    0, &mouse_ResourceDescriptor },
-    { &MSACM_Descriptor,    0, NULL },
-    { &MSVIDEO_Descriptor,  0, NULL },
-    { &OLE2CONV_Descriptor, DLL_FLAG_NOT_USED, NULL },
-    { &OLE2DISP_Descriptor, DLL_FLAG_NOT_USED, NULL },
-    { &OLE2NLS_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &OLE2PROX_Descriptor, DLL_FLAG_NOT_USED, NULL },
-    { &OLE2THK_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &OLE2_Descriptor,     DLL_FLAG_NOT_USED, NULL },
-    { &OLECLI_Descriptor,   DLL_FLAG_NOT_USED, NULL },
-    { &OLESVR_Descriptor,   DLL_FLAG_NOT_USED, NULL },
-    { &RASAPI16_Descriptor, 0, NULL },
-    { &SHELL_Descriptor,    0, NULL },
-    { &SOUND_Descriptor,    0, NULL },
-    { &STORAGE_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &STRESS_Descriptor,   0, NULL },
-    { &TOOLHELP_Descriptor, 0, NULL },
-    { &TYPELIB_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &VER_Descriptor,      0, NULL },
-    { &W32SYS_Descriptor,   DLL_FLAG_NOT_USED, NULL },
-    { &WIN32S16_Descriptor, DLL_FLAG_NOT_USED, NULL },
-    { &WIN87EM_Descriptor,  DLL_FLAG_NOT_USED, NULL },
-    { &WINASPI_Descriptor,  0, NULL },
-    { &WINEPS_Descriptor,   DLL_FLAG_ALWAYS_USED, NULL },
-    { &WING_Descriptor,     0, NULL },
-    { &WINSOCK_Descriptor,  0, NULL },
+    &KERNEL_Descriptor,
+    &USER_Descriptor,
+    &GDI_Descriptor,
+    &SYSTEM_Descriptor,
+    &DISPLAY_Descriptor,
+    &WPROCS_Descriptor,
+    &WINDEBUG_Descriptor,
+    &AVIFILE_Descriptor,
+    &COMMDLG_Descriptor,
+    &COMPOBJ_Descriptor,
+    &DDEML_Descriptor,
+    &DISPDIB_Descriptor,
+    &KEYBOARD_Descriptor,
+    &COMM_Descriptor,
+    &LZEXPAND_Descriptor,
+    &MMSYSTEM_Descriptor,
+    &MOUSE_Descriptor,
+    &MSACM_Descriptor,
+    &MSVIDEO_Descriptor,
+    &OLE2CONV_Descriptor,
+    &OLE2DISP_Descriptor,
+    &OLE2NLS_Descriptor,
+    &OLE2PROX_Descriptor,
+    &OLE2THK_Descriptor,
+    &OLE2_Descriptor,
+    &OLECLI_Descriptor,
+    &OLESVR_Descriptor,
+    &RASAPI16_Descriptor,
+    &SHELL_Descriptor,
+    &SOUND_Descriptor,
+    &STORAGE_Descriptor,
+    &STRESS_Descriptor,
+    &TOOLHELP_Descriptor,
+    &TYPELIB_Descriptor,
+    &VER_Descriptor,
+    &W32SYS_Descriptor,
+    &WIN32S16_Descriptor,
+    &WIN87EM_Descriptor,
+    &WINASPI_Descriptor,
+    &WINEPS_Descriptor,
+    &WING_Descriptor,
+    &WINSOCK_Descriptor,
     /* Last entry */
-    { NULL, 0, NULL }
+    NULL
+};
+
+/* list of DLLs that should always be loaded at startup */
+static const char * const always_load[] =
+{
+    "system", "display", "wprocs", "wineps", NULL
 };
 
   /* Ordinal number for interrupt 0 handler in WPROCS.DLL */
@@ -152,63 +145,64 @@
  * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule
  * and BUILTIN_Init.
  */
-static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DLL *dll )
+static HMODULE16 BUILTIN_DoLoadModule16( const WIN16_DESCRIPTOR *descr )
 {
     NE_MODULE *pModule;
     int minsize, res_off;
     SEGTABLEENTRY *pSegTable;
     HMODULE16 hModule;
+    const BUILTIN16_RESOURCE *rsrc = descr->rsrc;
 
-    if ( !dll->res )
+    if (!rsrc)
     {
-        hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, dll->descr->module_start,
-                                      dll->descr->module_size, 0,
+        hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
+                                      descr->module_size, 0,
                                             FALSE, FALSE, FALSE, NULL );
-    if (!hModule) return 0;
-    FarSetOwner16( hModule, hModule );
+        if (!hModule) return 0;
+        FarSetOwner16( hModule, hModule );
 
-    pModule = (NE_MODULE *)GlobalLock16( hModule );
+        pModule = (NE_MODULE *)GlobalLock16( hModule );
     }
     else
     {
         ET_BUNDLE *bundle;
 
         hModule = GLOBAL_Alloc( GMEM_MOVEABLE, 
-                                dll->descr->module_size + dll->res->res_size, 
+                                descr->module_size + rsrc->res_size, 
                                 0, FALSE, FALSE, FALSE );
         if (!hModule) return 0;
         FarSetOwner16( hModule, hModule );
 
         pModule = (NE_MODULE *)GlobalLock16( hModule );
-        res_off = ((NE_MODULE *)dll->descr->module_start)->res_table;
+        res_off = ((NE_MODULE *)descr->module_start)->res_table;
 
-        memcpy( (LPBYTE)pModule, dll->descr->module_start, res_off );
-        memcpy( (LPBYTE)pModule + res_off, dll->res->res_start, dll->res->res_size );
-        memcpy( (LPBYTE)pModule + res_off + dll->res->res_size, 
-                dll->descr->module_start + res_off, dll->descr->module_size - res_off );
+        memcpy( (LPBYTE)pModule, descr->module_start, res_off );
+        memcpy( (LPBYTE)pModule + res_off, rsrc->res_start, rsrc->res_size );
+        memcpy( (LPBYTE)pModule + res_off + rsrc->res_size, 
+                descr->module_start + res_off, descr->module_size - res_off );
 
         /* Have to fix up various pModule-based near pointers.  Ugh! */
-        pModule->name_table   += dll->res->res_size;
-        pModule->modref_table += dll->res->res_size;
-        pModule->import_table += dll->res->res_size;
-        pModule->entry_table  += dll->res->res_size;
+        pModule->name_table   += rsrc->res_size;
+        pModule->modref_table += rsrc->res_size;
+        pModule->import_table += rsrc->res_size;
+        pModule->entry_table  += rsrc->res_size;
 
         for ( bundle = (ET_BUNDLE *)((LPBYTE)pModule + pModule->entry_table);
               bundle->next;
               bundle = (ET_BUNDLE *)((LPBYTE)pModule + bundle->next) )
-            bundle->next += dll->res->res_size;
+            bundle->next += rsrc->res_size;
 
         /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
-        pModule->hRsrcMap = dll->res->res_start;
+        pModule->hRsrcMap = rsrc->res_start;
     }
     pModule->self = hModule;
 
-    TRACE( "Built-in %s: hmodule=%04x\n", dll->descr->name, hModule );
+    TRACE( "Built-in %s: hmodule=%04x\n", descr->name, hModule );
 
     /* Allocate the code segment */
 
     pSegTable = NE_SEG_TABLE( pModule );
-    pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, dll->descr->code_start,
+    pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
                                               pSegTable->minsize, hModule,
                                               TRUE, TRUE, FALSE, NULL );
     if (!pSegTable->hSeg) return 0;
@@ -223,12 +217,12 @@
                                         hModule, FALSE, FALSE, FALSE );
     if (!pSegTable->hSeg) return 0;
     if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
-                                    dll->descr->data_start, pSegTable->minsize);
+                                    descr->data_start, pSegTable->minsize);
     if (pModule->heap_size)
         LocalInit16( GlobalHandleToSel16(pSegTable->hSeg),
 		pSegTable->minsize, minsize );
 
-	if (dll->res)
+	if (rsrc)
 		NE_InitResourceHandler(hModule);
 
     NE_RegisterModule( pModule );
@@ -243,14 +237,14 @@
  */
 BOOL BUILTIN_Init(void)
 {
-    BUILTIN16_DLL *dll;
     WORD vector;
     HMODULE16 hModule;
+    const char * const *ptr = always_load;
 
-    for (dll = BuiltinDLLs; dll->descr; dll++)
+    while (*ptr)
     {
-        if (dll->flags & DLL_FLAG_ALWAYS_USED)
-            if (!BUILTIN_DoLoadModule16( dll )) return FALSE;
+        if (!BUILTIN_LoadModule( *ptr )) return FALSE;
+        ptr++;
     }
 
     /* Set interrupt vectors from entry points in WPROCS.DLL */
@@ -271,12 +265,11 @@
 /***********************************************************************
  *           BUILTIN_LoadModule
  *
- * Load a built-in module. If the 'force' parameter is FALSE, we only
- * load the module if it has not been disabled via the -dll option.
+ * Load a built-in module.
  */
-HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
+HMODULE16 BUILTIN_LoadModule( LPCSTR name )
 {
-    BUILTIN16_DLL *table;
+    const WIN16_DESCRIPTOR **table;
     char dllname[16], *p;
 
     /* Fix the name in case we have a full path and extension */
@@ -287,18 +280,15 @@
 	 
     if (!p) strcat( dllname, ".dll" );
 
-    for (table = BuiltinDLLs; table->descr; table++)
+    for (table = BuiltinDLLs; *table; table++)
     {
-       NE_MODULE *pModule = (NE_MODULE *)table->descr->module_start;
+       NE_MODULE *pModule = (NE_MODULE *)(*table)->module_start;
        OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
        if (!lstrcmpiA( pOfs->szPathName, dllname )) break;
     }
 
-    if (!table->descr) return (HMODULE16)2;
-
-    if ((table->flags & DLL_FLAG_NOT_USED) && !force) return (HMODULE16)2;
-
-    return BUILTIN_DoLoadModule16( table );
+    if (!*table) return (HMODULE16)2;
+    return BUILTIN_DoLoadModule16( *table );
 }
 
 
diff --git a/include/builtin16.h b/include/builtin16.h
index 3aac33e..373d0f7 100644
--- a/include/builtin16.h
+++ b/include/builtin16.h
@@ -14,7 +14,7 @@
 struct _STACK16FRAME;
 
 extern BOOL BUILTIN_Init(void);
-extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force );
+extern HMODULE16 BUILTIN_LoadModule( LPCSTR name );
 extern LPCSTR BUILTIN_GetEntryPoint16( struct _STACK16FRAME *frame, LPSTR name, WORD *pOrd );
 
 extern void RELAY_Unimplemented16(void);
@@ -82,6 +82,7 @@
     int         module_size;       /* Size of the module data */
     const BYTE *code_start;        /* 32-bit address of DLL code */
     const BYTE *data_start;        /* 32-bit address of DLL data */
+    const void *rsrc;              /* resources data */
 } WIN16_DESCRIPTOR;
 
 
diff --git a/include/builtin32.h b/include/builtin32.h
index 8719756..659a5c2 100644
--- a/include/builtin32.h
+++ b/include/builtin32.h
@@ -25,6 +25,7 @@
     const unsigned int   *argtypes;     /* Pointer to argument types bitmask */
     const char * const   *imports;      /* Pointer to imports */
     const ENTRYPOINT32    dllentrypoint;/* Pointer to LibMain function */
+    const void           *rsrc;         /* Resource descriptor */
 } BUILTIN32_DESCRIPTOR;
 
 extern ENTRYPOINT32 BUILTIN32_GetEntryPoint( char *buffer, void *relay,
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 856c18a..89ca1dd 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -928,7 +928,7 @@
 
 		case MODULE_LOADORDER_BI:
 			TRACE("Trying built-in '%s'\n", libname);
-			hinst = BUILTIN_LoadModule(libname, TRUE);
+			hinst = BUILTIN_LoadModule(libname);
 			break;
 
 		default:
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index bbbc11e..581fdf9 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -17,9 +17,8 @@
 #include "winerror.h"
 #include "debugtools.h"
 
-DECLARE_DEBUG_CHANNEL(relay)
-DECLARE_DEBUG_CHANNEL(win32)
-DECLARE_DEBUG_CHANNEL(module)
+DEFAULT_DEBUG_CHANNEL(module);
+DECLARE_DEBUG_CHANNEL(relay);
 
 typedef struct
 {
@@ -40,14 +39,9 @@
 typedef struct
 {
 	const BUILTIN32_DESCRIPTOR	*descr;	/* DLL descriptor */
-	DWORD				flags;
 	HMODULE				hModule;
-	const BUILTIN32_RESOURCE	*rsc;	
 } BUILTIN32_DLL;
 
-#define BI32_INSTANTIATED	0x01
-#define BI32_DANGER		0x02
-
 extern const BUILTIN32_DESCRIPTOR ADVAPI32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR AVIFIL32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR COMCTL32_Descriptor;
@@ -98,70 +92,91 @@
 extern const BUILTIN32_DESCRIPTOR WOW32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR WSOCK32_Descriptor;
 
-extern const BUILTIN32_RESOURCE comctl32_ResourceDescriptor;
-extern const BUILTIN32_RESOURCE comdlg32_ResourceDescriptor;
-extern const BUILTIN32_RESOURCE shell32_ResourceDescriptor;
-extern const BUILTIN32_RESOURCE user32_ResourceDescriptor;
-extern const BUILTIN32_RESOURCE winmm_ResourceDescriptor;
 
 static BUILTIN32_DLL BuiltinDLLs[] =
 {
-    { &ADVAPI32_Descriptor, 0, 0, NULL },
-    { &AVIFIL32_Descriptor, 0, 0, NULL },
-    { &COMCTL32_Descriptor, BI32_DANGER, 0, &comctl32_ResourceDescriptor },
-    { &COMDLG32_Descriptor, BI32_DANGER, 0, &comdlg32_ResourceDescriptor },
-    { &CRTDLL_Descriptor,   BI32_DANGER, 0, NULL },
-    { &DCIMAN32_Descriptor, 0, 0, NULL },
-    { &DDRAW_Descriptor,    0, 0, NULL },
-    { &DINPUT_Descriptor,   0, 0, NULL },
-    { &DPLAY_Descriptor,    0, 0, NULL },
-    { &DPLAYX_Descriptor,   0, 0, NULL },
-    { &DSOUND_Descriptor,   0, 0, NULL },
-    { &GDI32_Descriptor,    0, 0, NULL },
-    { &ICMP_Descriptor,    0, 0, NULL },
-    { &IMAGEHLP_Descriptor, BI32_DANGER, 0, NULL },
-    { &IMM32_Descriptor,    0, 0, NULL },
-    { &KERNEL32_Descriptor, 0, 0, NULL },
-    { &LZ32_Descriptor,     0, 0, NULL },
-    { &MCIANIM_Descriptor,  0, 0, NULL },
-    { &MCIAVI_Descriptor,   0, 0, NULL },
-    { &MCICDA_Descriptor,   0, 0, NULL },
-    { &MCISEQ_Descriptor,   0, 0, NULL },
-    { &MCIWAVE_Descriptor,  0, 0, NULL },
-    { &MIDIMAP_Descriptor,  0, 0, NULL },
-    { &MPR_Descriptor,      0, 0, NULL },
-    { &MSACM32_Descriptor,  BI32_DANGER, 0, NULL },
-    { &MSACMMAP_Descriptor, 0, 0, NULL },
-    { &MSNET32_Descriptor,  0, 0, NULL },
-    { &MSVFW32_Descriptor,  0, 0, NULL },
-    { &NTDLL_Descriptor,    0, 0, NULL },
-    { &ODBC32_Descriptor,   0, 0, NULL },
-    { &OLE32_Descriptor,    0, 0, NULL },
-    { &OLEAUT32_Descriptor, 0, 0, NULL },
-    { &OLECLI32_Descriptor, 0, 0, NULL },
-    { &OLEDLG_Descriptor,   0, 0, NULL },
-    { &OLESVR32_Descriptor, 0, 0, NULL },
-    { &PSAPI_Descriptor,    0, 0, NULL },
-    { &RASAPI32_Descriptor, 0, 0, NULL },
-    { &SHELL32_Descriptor,  BI32_DANGER, 0, &shell32_ResourceDescriptor },
-    { &SHLWAPI_Descriptor,  0, 0, NULL },
-    { &TAPI32_Descriptor,   0, 0, NULL },
-    { &USER32_Descriptor,   0, 0, &user32_ResourceDescriptor },
-    { &VERSION_Descriptor,  0, 0, NULL },
-    { &W32SKRNL_Descriptor, 0, 0, NULL },
-    { &WINMM_Descriptor,    0, 0, &winmm_ResourceDescriptor },
-    { &WINSPOOL_Descriptor, 0, 0, NULL },
-    { &WINEOSS_Descriptor,  0, 0, NULL },
-    { &WNASPI32_Descriptor, 0, 0, NULL },
-    { &WOW32_Descriptor,    0, 0, NULL },
-    { &WSOCK32_Descriptor,  0, 0, NULL },
+    { &ADVAPI32_Descriptor, 0 },
+    { &AVIFIL32_Descriptor, 0 },
+    { &COMCTL32_Descriptor, 0 },
+    { &COMDLG32_Descriptor, 0 },
+    { &CRTDLL_Descriptor,   0 },
+    { &DCIMAN32_Descriptor, 0 },
+    { &DDRAW_Descriptor,    0 },
+    { &DINPUT_Descriptor,   0 },
+    { &DPLAY_Descriptor,    0 },
+    { &DPLAYX_Descriptor,   0 },
+    { &DSOUND_Descriptor,   0 },
+    { &GDI32_Descriptor,    0 },
+    { &ICMP_Descriptor,     0 },
+    { &IMAGEHLP_Descriptor, 0 },
+    { &IMM32_Descriptor,    0 },
+    { &KERNEL32_Descriptor, 0 },
+    { &LZ32_Descriptor,     0 },
+    { &MCIANIM_Descriptor,  0 },
+    { &MCIAVI_Descriptor,   0 },
+    { &MCICDA_Descriptor,   0 },
+    { &MCISEQ_Descriptor,   0 },
+    { &MCIWAVE_Descriptor,  0 },
+    { &MIDIMAP_Descriptor,  0 },
+    { &MPR_Descriptor,      0 },
+    { &MSACM32_Descriptor,  0 },
+    { &MSACMMAP_Descriptor, 0 },
+    { &MSNET32_Descriptor,  0 },
+    { &MSVFW32_Descriptor,  0 },
+    { &NTDLL_Descriptor,    0 },
+    { &ODBC32_Descriptor,   0 },
+    { &OLE32_Descriptor,    0 },
+    { &OLEAUT32_Descriptor, 0 },
+    { &OLECLI32_Descriptor, 0 },
+    { &OLEDLG_Descriptor,   0 },
+    { &OLESVR32_Descriptor, 0 },
+    { &PSAPI_Descriptor,    0 },
+    { &RASAPI32_Descriptor, 0 },
+    { &SHELL32_Descriptor,  0 },
+    { &SHLWAPI_Descriptor,  0 },
+    { &TAPI32_Descriptor,   0 },
+    { &USER32_Descriptor,   0 },
+    { &VERSION_Descriptor,  0 },
+    { &W32SKRNL_Descriptor, 0 },
+    { &WINMM_Descriptor,    0 },
+    { &WINSPOOL_Descriptor, 0 },
+    { &WINEOSS_Descriptor,  0 },
+    { &WNASPI32_Descriptor, 0 },
+    { &WOW32_Descriptor,    0 },
+    { &WSOCK32_Descriptor,  0 },
     /* Last entry */
-    { NULL, 0, 0, NULL }
+    { NULL, 0 }
 };
 
 extern void RELAY_CallFrom32();
 extern void RELAY_CallFrom32Regs();
 
+
+/***********************************************************************
+ *           BUILTIN32_WarnSecondInstance
+ *
+ * Emit a warning when we are creating a second instance for a DLL
+ * that is known to not support this.
+ */
+static void BUILTIN32_WarnSecondInstance( const char *name )
+{
+    static const char * const warning_list[] =
+    { "comctl32", "comdlg32", "crtdll", "imagehlp", "msacm32", "shell32", NULL };
+
+    const char * const *ptr = warning_list;
+
+    while (*ptr)
+    {
+        if (!strcasecmp( *ptr, name ))
+        {
+            ERR( "Attempt to instantiate built-in dll '%s' twice "
+                 "in the same address space. Expect trouble!\n", name );
+            return;
+        }
+        ptr++;
+    }
+}
+
 /***********************************************************************
  *           BUILTIN32_DoLoadImage
  *
@@ -306,16 +321,17 @@
     sec++;
 
     /* Build the resource directory */
-    if(dll->rsc)
+    if(dll->descr->rsrc)
     {
+	const BUILTIN32_RESOURCE *rsrc = dll->descr->rsrc;
 	int i;
 	void *rtab;
 	IMAGE_RESOURCE_DATA_ENTRY *rdep;
 
-	rtab = HeapAlloc(GetProcessHeap(), 0, dll->rsc->restabsize);
+	rtab = HeapAlloc(GetProcessHeap(), 0, rsrc->restabsize);
 	if(!rtab)
 	{
-		ERR_(module)("Failed to get memory for resource directory\n");
+		ERR("Failed to get memory for resource directory\n");
 		VirtualFree(addr, size, MEM_RELEASE);
 		return 0;
 	}
@@ -324,15 +340,15 @@
 	 * The resource directory has to be copied because it contains
 	 * RVAs. These would be invalid if the dll is instantiated twice.
 	 */
-	memcpy(rtab, dll->rsc->restab, dll->rsc->restabsize);
+	memcpy(rtab, rsrc->restab, rsrc->restabsize);
 
 	dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
 	dir->VirtualAddress = (DWORD)rtab - (DWORD)addr;
-	dir->Size = dll->rsc->restabsize;
-	rdep = (IMAGE_RESOURCE_DATA_ENTRY *)((DWORD)rtab + (DWORD)dll->rsc->entries - (DWORD)dll->rsc->restab);
-	for(i = 0; i < dll->rsc->nresources; i++)
+	dir->Size = rsrc->restabsize;
+	rdep = (IMAGE_RESOURCE_DATA_ENTRY *)((DWORD)rtab + (DWORD)rsrc->entries - (DWORD)rsrc->restab);
+	for(i = 0; i < rsrc->nresources; i++)
 	{
-		rdep[i].OffsetToData += (DWORD)dll->rsc->restab - (DWORD)addr;
+		rdep[i].OffsetToData += (DWORD)rsrc->restab - (DWORD)addr;
 	}
     }
 
@@ -444,20 +460,15 @@
     }
 
     /* Load built-in module */
-    if ( (table->flags & BI32_INSTANTIATED) && (table->flags & BI32_DANGER) )
-        ERR_(module)( "Attempt to instantiate built-in dll '%s' twice "
-                      "in the same address-space. Expect trouble!\n",
-                      table->descr->name );
-
-    if ( !table->hModule )
-        table->hModule = BUILTIN32_DoLoadImage( table );
-    if ( table->hModule )
-        table->flags |= BI32_INSTANTIATED;
-    else
+    if (!table->hModule)
     {
-        *err = ERROR_FILE_NOT_FOUND;
-        return NULL;
+        if (!(table->hModule = BUILTIN32_DoLoadImage( table )))
+        {
+            *err = ERROR_FILE_NOT_FOUND;
+            return NULL;
+        }
     }
+    else BUILTIN32_WarnSecondInstance( table->descr->name );
 
     /* Create 16-bit dummy module */
     if ((hModule16 = MODULE_CreateDummyModule( dllname, 0 )) < 32)
@@ -473,7 +484,7 @@
     /* Create 32-bit MODREF */
     if ( !(wm = PE_CreateModule( table->hModule, dllname, flags, TRUE )) )
     {
-        ERR_(win32)( "can't load %s\n", path );
+        ERR( "can't load %s\n", path );
         FreeLibrary16( hModule16 );	/* FIXME: Should unload the builtin module */
         *err = ERROR_OUTOFMEMORY;
         return NULL;
@@ -516,7 +527,7 @@
     /* First find the module */
 
     for (dll = BuiltinDLLs; dll->descr; dll++)
-        if ( dll->flags & BI32_INSTANTIATED ) 
+        if (dll->hModule)
         {
             IMAGE_SECTION_HEADER *sec = PE_SECTIONS(dll->hModule);
             DEBUG_ENTRY_POINT *debug = 
@@ -559,8 +570,7 @@
     for (dll = BuiltinDLLs; dll->descr; dll++) {
 	IMAGE_SECTION_HEADER *sec;
 	DEBUG_ENTRY_POINT *debug;
-        if (!(dll->flags & BI32_INSTANTIATED))
-	    continue;
+        if (!dll->hModule) continue;
 
 	sec = PE_SECTIONS(dll->hModule);
 	debug = (DEBUG_ENTRY_POINT *)((DWORD)dll->hModule + sec[1].VirtualAddress);
@@ -608,4 +618,3 @@
     MESSAGE( "\n" );
     ExitProcess(1);
 }
-
diff --git a/relay32/user32.spec b/relay32/user32.spec
index e840e6d..ffe001e 100644
--- a/relay32/user32.spec
+++ b/relay32/user32.spec
@@ -1,6 +1,7 @@
 name	user32
 type	win32
 init	MAIN_UserInit
+rsrc	user32
 
   1 stdcall ActivateKeyboardLayout(long long) ActivateKeyboardLayout
   2 stdcall AdjustWindowRect(ptr long long) AdjustWindowRect
diff --git a/tools/build.c b/tools/build.c
index 8b60e95..f9c117a 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -153,6 +153,7 @@
 static WORD Code_Selector, Data_Selector;
 static char DLLInitFunc[80];
 static char *DLLImports[MAX_IMPORTS];
+static char rsrc_name[80];
 static int nb_imports;
 static int nb_entry_points;
 static int nb_names;
@@ -715,6 +716,11 @@
                 fatal_error( "Imports not supported for Win16\n" );
             DLLImports[nb_imports++] = xstrdup(GetToken());
         }
+        else if (strcmp(token, "rsrc") == 0)
+        {
+            strcpy( rsrc_name, GetToken() );
+            strcat( rsrc_name, "_ResourceDescriptor" );
+        }
         else if (strcmp(token, "@") == 0)
 	{
             if (SpecType != SPEC_WIN32)
@@ -1184,6 +1190,8 @@
 
     /* Output the DLL descriptor */
 
+    if (rsrc_name[0]) fprintf( outfile, "extern const char %s[];\n\n", rsrc_name );
+
     fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n",
              DLLName );
     fprintf( outfile, "    \"%s\",\n", DLLName );
@@ -1200,8 +1208,9 @@
              "    FuncArgs,\n"
              "    ArgTypes,\n");
     fprintf( outfile, "    %s,\n", nb_imports ? "Imports" : "0" );
-    fprintf( outfile, "    %s\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
-    fprintf( outfile, "};\n" );             
+    fprintf( outfile, "    %s,\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
+    fprintf( outfile, "    %s\n", rsrc_name[0] ? rsrc_name : "0" );
+    fprintf( outfile, "};\n" );
     return 0;
 }
 
@@ -1440,12 +1449,15 @@
 
     /* Output the DLL descriptor */
 
-    fprintf( outfile, "\nWIN16_DESCRIPTOR %s_Descriptor = \n{\n", DLLName );
+    if (rsrc_name[0]) fprintf( outfile, "extern const char %s[];\n\n", rsrc_name );
+
+    fprintf( outfile, "\nconst WIN16_DESCRIPTOR %s_Descriptor = \n{\n", DLLName );
     fprintf( outfile, "    \"%s\",\n", DLLName );
     fprintf( outfile, "    Module,\n" );
     fprintf( outfile, "    sizeof(Module),\n" );
     fprintf( outfile, "    (BYTE *)&Code_Segment,\n" );
-    fprintf( outfile, "    (BYTE *)Data_Segment\n" );
+    fprintf( outfile, "    (BYTE *)Data_Segment,\n" );
+    fprintf( outfile, "    %s\n", rsrc_name[0] ? rsrc_name : "0" );
     fprintf( outfile, "};\n" );
     
     return 0;
@@ -1768,6 +1780,7 @@
     fprintf( outfile, ".stabs \"CallFrom16%s:F1\",36,0,0," PREFIX "CallFrom16%s\n", 
 	     name, name);
 #endif
+    fprintf( outfile, "\t.type " PREFIX "CallFrom16%s,@function\n", name );
     fprintf( outfile, "\t.globl " PREFIX "CallFrom16%s\n", name );
     fprintf( outfile, PREFIX "CallFrom16%s:\n", name );