major version 4 must have their imported modules checked to determine whether they are Windows or OS/2 or Multitasking DOS 4 executables.
Tested on Fedora 26 x86 --- dlls/krnl386.exe16/ne_module.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/dlls/krnl386.exe16/ne_module.c b/dlls/krnl386.exe16/ne_module.c index 14f8075166..e9009677d0 100644 --- a/dlls/krnl386.exe16/ne_module.c +++ b/dlls/krnl386.exe16/ne_module.c @@ -697,6 +697,46 @@ static HMODULE16 build_module( const void *mapping, SIZE_T mapping_size, LPCSTR ne_header->ne_enttab - ne_header->ne_imptab )) goto failed; pData += ne_header->ne_enttab - ne_header->ne_imptab;
+ /* If the linker version is 4.x or the executable type is unknown, it is necessary to check the import table for + known Windows and OS/2 libraries to determine whether it's a Windows executable. Executables with no module table + or which don't import known Windows or OS/2 libraries are also assumed to be Windows. */ + if (((ne_header->ne_ver == 0x04) || (ne_header->ne_exetyp == 0x00)) && pModule->ne_modtab) + { + /* Array of offsets into the imported names table where module names are located */ + WORD* module_table; + + /* Series of Pascal strings containing the module names */ + LPCSTR imported_names; + + int i; + BOOL importsDosCalls = FALSE; + BOOL importsKernel = FALSE; + + /* Get address of module table and imported names table from their offsets */ + module_table = (WORD*)(((BYTE*)pModule) + pModule->ne_modtab); + imported_names = (LPCSTR)(((BYTE*)pModule) + pModule->ne_imptab); + + /* Look for imports from DOSCALLS and KERNEL */ + for (i = 0; i < pModule->ne_cmod; i++) + { + /* Module name is a Pascal string with byte length prefix */ + LPCSTR module_name = imported_names + module_table[i]; + + if (!importsDosCalls && !strncmp("DOSCALLS", &module_name[1], module_name[0])) + importsDosCalls = TRUE; + + else if (!importsKernel && !strncmp("KERNEL", &module_name[1], module_name[0])) + importsKernel = TRUE; + + if (importsDosCalls && importsKernel) + break; + } + + /* If the module has imports from DOSCALLS but not KERNEL, assume it's for OS/2 or Multitasking DOS 4. */ + if (importsDosCalls && !importsKernel) + goto failed; + } + /* Load entry table, convert it to the optimized version used by Windows */
pModule->ne_enttab = pData - (BYTE *)pModule;