Use the exported IMAGE_OS2_HEADER to generate the module header in the
spec file, and moved the NE_MODULE structure definition to
kernel16_private.h.

diff --git a/dlls/kernel/kernel16_private.h b/dlls/kernel/kernel16_private.h
index c2e50f7..475dda3 100644
--- a/dlls/kernel/kernel16_private.h
+++ b/dlls/kernel/kernel16_private.h
@@ -28,6 +28,49 @@
 
 #include "pshpack1.h"
 
+/* In-memory module structure. See 'Windows Internals' p. 219 */
+typedef struct _NE_MODULE
+{
+    WORD      magic;            /* 00 'NE' signature */
+    WORD      count;            /* 02 Usage count */
+    WORD      entry_table;      /* 04 Near ptr to entry table */
+    HMODULE16 next;             /* 06 Selector to next module */
+    WORD      dgroup_entry;     /* 08 Near ptr to segment entry for DGROUP */
+    WORD      fileinfo;         /* 0a Near ptr to file info (OFSTRUCT) */
+    WORD      flags;            /* 0c Module flags */
+    WORD      dgroup;           /* 0e Logical segment for DGROUP */
+    WORD      heap_size;        /* 10 Initial heap size */
+    WORD      stack_size;       /* 12 Initial stack size */
+    WORD      ip;               /* 14 Initial ip */
+    WORD      cs;               /* 16 Initial cs (logical segment) */
+    WORD      sp;               /* 18 Initial stack pointer */
+    WORD      ss;               /* 1a Initial ss (logical segment) */
+    WORD      seg_count;        /* 1c Number of segments in segment table */
+    WORD      modref_count;     /* 1e Number of module references */
+    WORD      nrname_size;      /* 20 Size of non-resident names table */
+    WORD      seg_table;        /* 22 Near ptr to segment table */
+    WORD      res_table;        /* 24 Near ptr to resource table */
+    WORD      name_table;       /* 26 Near ptr to resident names table */
+    WORD      modref_table;     /* 28 Near ptr to module reference table */
+    WORD      import_table;     /* 2a Near ptr to imported names table */
+    DWORD     nrname_fpos;      /* 2c File offset of non-resident names table */
+    WORD      moveable_entries; /* 30 Number of moveable entries in entry table*/
+    WORD      alignment;        /* 32 Alignment shift count */
+    WORD      truetype;         /* 34 Set to 2 if TrueType font */
+    BYTE      os_flags;         /* 36 Operating system flags */
+    BYTE      misc_flags;       /* 37 Misc. flags */
+    HANDLE16  dlls_to_init;     /* 38 List of DLLs to initialize */
+    HANDLE16  nrname_handle;    /* 3a Handle to non-resident name table */
+    WORD      min_swap_area;    /* 3c Min. swap area size */
+    WORD      expected_version; /* 3e Expected Windows version */
+    /* From here, these are extra fields not present in normal Windows */
+    HMODULE   module32;         /* 40 PE module handle for Win32 modules */
+    HMODULE16 self;             /* 44 Handle for this module */
+    WORD      self_loading_sel; /* 46 Selector used for self-loading apps. */
+    LPVOID    hRsrcMap;         /* 48 HRSRC 16->32 map (for 32-bit modules) */
+    HANDLE    fd;               /* 4c handle to the binary file */
+} NE_MODULE;
+
 /* this structure is always located at offset 0 of the DGROUP segment */
 typedef struct
 {
diff --git a/dlls/kernel/ne_module.c b/dlls/kernel/ne_module.c
index 31fc86c..644fcfa 100644
--- a/dlls/kernel/ne_module.c
+++ b/dlls/kernel/ne_module.c
@@ -160,9 +160,9 @@
         const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
         if (descr)
         {
-            NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
-            OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
-            BYTE *name_table = (BYTE *)pModule + pModule->name_table;
+            IMAGE_OS2_HEADER *pModule = descr->module_start;
+            OFSTRUCT *pOfs = (OFSTRUCT *)(pModule + 1);
+            BYTE *name_table = (BYTE *)pModule + pModule->ne_restab;
 
             /* check the dll file name */
             if (!NE_strcasecmp( pOfs->szPathName, dllname )) return descr;
@@ -1097,7 +1097,9 @@
  */
 static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr )
 {
+    IMAGE_OS2_HEADER *header;
     NE_MODULE *pModule;
+    OFSTRUCT *ofs;
     int minsize;
     SEGTABLEENTRY *pSegTable;
     HMODULE16 hModule;
@@ -1107,7 +1109,19 @@
     if (!hModule) return ERROR_NOT_ENOUGH_MEMORY;
     FarSetOwner16( hModule, hModule );
 
-    pModule = (NE_MODULE *)GlobalLock16( hModule );
+    header = GlobalLock16( hModule );
+    pModule = (NE_MODULE *)header;
+    ofs = (OFSTRUCT *)(header + 1);
+    /* move the fileinfo structure a bit further to make space for the Wine-specific fields */
+    if (sizeof(*header) + sizeof(*ofs) < sizeof(*pModule) + ofs->cBytes + 1)
+    {
+        FIXME( "module name %s too long\n", debugstr_a(ofs->szPathName) );
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
+    memmove( pModule + 1, ofs, ofs->cBytes + 1 );
+
+    pModule->count = 1;
+    pModule->fileinfo = sizeof(*pModule);
     pModule->self = hModule;
     /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
     pModule->hRsrcMap = (void *)descr->rsrc;
@@ -1130,6 +1144,7 @@
     pSegTable->hSeg = GlobalAlloc16( GMEM_FIXED, minsize );
     if (!pSegTable->hSeg) return ERROR_NOT_ENOUGH_MEMORY;
     FarSetOwner16( pSegTable->hSeg, hModule );
+    pModule->dgroup_entry = (char *)pSegTable - (char *)pModule;
     if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
                                     descr->data_start, pSegTable->minsize);
     if (pModule->heap_size)