diff --git a/dlls/kernel/kernel16_private.h b/dlls/kernel/kernel16_private.h index c2e50f73030..475dda3d39f 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 31fc86caced..644fcfa13eb 100644 --- a/dlls/kernel/ne_module.c +++ b/dlls/kernel/ne_module.c @@ -160,9 +160,9 @@ static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname ) 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 HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only ) */ 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 @@ static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr ) 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 @@ static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr ) 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) diff --git a/include/module.h b/include/module.h index 902bb14ee2a..119549f5e37 100644 --- a/include/module.h +++ b/include/module.h @@ -31,50 +31,6 @@ #include - /* 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; /* HRSRC 16->32 map (for 32-bit modules) */ - HANDLE fd; /* handle to the binary file */ -} NE_MODULE; - - typedef struct { BYTE type; BYTE flags; diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 41395dcc0fe..70e318445d0 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -113,16 +113,15 @@ static int BuildModule16( FILE *outfile, int max_code_offset, int max_data_offset, DLLSPEC *spec ) { int i; - char *buffer; - NE_MODULE *pModule; + char *buffer, *pstr; + IMAGE_OS2_HEADER *pModule; SEGTABLEENTRY *pSegment; OFSTRUCT *pFileInfo; - BYTE *pstr; ET_BUNDLE *bundle = 0; ET_ENTRY entry; /* Module layout: - * NE_MODULE Module + * IMAGE_OS2_HEADER Module * OFSTRUCT File information * SEGTABLEENTRY Segment 1 (code) * SEGTABLEENTRY Segment 2 (data) @@ -135,51 +134,26 @@ static int BuildModule16( FILE *outfile, int max_code_offset, buffer = xmalloc( 0x10000 ); memset( buffer, 0, 0x10000 ); - pModule = (NE_MODULE *)buffer; - pModule->magic = IMAGE_OS2_SIGNATURE; - pModule->count = 1; - pModule->next = 0; - pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE; - pModule->dgroup = 2; - pModule->heap_size = spec->heap_size; - pModule->stack_size = 0; - pModule->ip = 0; - pModule->cs = 0; - pModule->sp = 0; - pModule->ss = 0; - pModule->seg_count = 2; - pModule->modref_count = 0; - pModule->nrname_size = 0; - pModule->modref_table = 0; - pModule->nrname_fpos = 0; - pModule->moveable_entries = 0; - pModule->alignment = 0; - pModule->truetype = 0; - pModule->os_flags = NE_OSFLAGS_WINDOWS; - pModule->misc_flags = 0; - pModule->dlls_to_init = 0; - pModule->nrname_handle = 0; - pModule->min_swap_area = 0; - pModule->expected_version = 0; - pModule->module32 = 0; - pModule->self = 0; - pModule->self_loading_sel = 0; + pModule = (IMAGE_OS2_HEADER *)buffer; + pModule->ne_magic = IMAGE_OS2_SIGNATURE; + pModule->ne_flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE; + pModule->ne_autodata = 2; + pModule->ne_heap = spec->heap_size; + pModule->ne_cseg = 2; + pModule->ne_exetyp = NE_OSFLAGS_WINDOWS; /* File information */ pFileInfo = (OFSTRUCT *)(pModule + 1); - pModule->fileinfo = (int)pFileInfo - (int)pModule; - memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) ); pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) + strlen(spec->file_name); strcpy( pFileInfo->szPathName, spec->file_name ); - pstr = (char *)pFileInfo + pFileInfo->cBytes + 1; + /* note: we allocate the whole OFSTRUCT so that the loader has some extra space to play with */ /* Segment table */ - pstr = (char *)(((long)pstr + 3) & ~3); - pSegment = (SEGTABLEENTRY *)pstr; - pModule->seg_table = (int)pSegment - (int)pModule; + pSegment = (SEGTABLEENTRY *)(pFileInfo + 1); + pModule->ne_segtab = (char *)pSegment - buffer; pSegment->filepos = 0; pSegment->size = max_code_offset; pSegment->flags = 0; @@ -187,7 +161,6 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pSegment->hSeg = 0; pSegment++; - pModule->dgroup_entry = (int)pSegment - (int)pModule; pSegment->filepos = 0; pSegment->size = max_data_offset; pSegment->flags = NE_SEGFLAGS_DATA; @@ -199,20 +172,20 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pstr = (char *)pSegment; pstr = (char *)(((long)pstr + 3) & ~3); - pModule->res_table = (int)pstr - (int)pModule; + pModule->ne_rsrctab = pstr - buffer; pstr += output_res16_directory( pstr, spec ); /* Imported names table */ pstr = (char *)(((long)pstr + 3) & ~3); - pModule->import_table = (int)pstr - (int)pModule; + pModule->ne_imptab = pstr - buffer; *pstr++ = 0; *pstr++ = 0; /* Resident names table */ pstr = (char *)(((long)pstr + 3) & ~3); - pModule->name_table = (int)pstr - (int)pModule; + pModule->ne_restab = pstr - buffer; /* First entry is module name */ *pstr = strlen( spec->dll_name ); strcpy( pstr + 1, spec->dll_name ); @@ -238,7 +211,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, /* Entry table */ pstr = (char *)(((long)pstr + 3) & ~3); - pModule->entry_table = (int)pstr - (int)pModule; + pModule->ne_enttab = pstr - buffer; for (i = 1; i <= spec->limit; i++) { int selector = 0; @@ -276,7 +249,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, { pstr = (char *)(((long)pstr + 1) & ~1); if ( bundle ) - bundle->next = (char *)pstr - (char *)pModule; + bundle->next = pstr - buffer; bundle = (ET_BUNDLE *)pstr; bundle->first = i-1; @@ -298,8 +271,9 @@ static int BuildModule16( FILE *outfile, int max_code_offset, /* Dump the module content */ pstr = (char *)(((long)pstr + 3) & ~3); - dump_bytes( outfile, (char *)pModule, (int)pstr - (int)pModule, "Module", 0 ); - return (int)pstr - (int)pModule; + dump_bytes( outfile, buffer, pstr - buffer, "Module", 0 ); + free( buffer ); + return pstr - buffer; }