[PATCH v2 4/4] krnl386.exe16: NE files with linker major version 4 use a discard
Martin Payne
development at martinpayne.me.uk
Sat Dec 16 15:04:47 CST 2017
priority rather than a DISCARDABLE flag.
Tested on Fedora 26 x86
---
dlls/krnl386.exe16/ne_module.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/dlls/krnl386.exe16/ne_module.c b/dlls/krnl386.exe16/ne_module.c
index b3c0b75a4d..72043a90ff 100644
--- a/dlls/krnl386.exe16/ne_module.c
+++ b/dlls/krnl386.exe16/ne_module.c
@@ -662,6 +662,24 @@ static HMODULE16 build_module( const void *mapping, SIZE_T mapping_size, LPCSTR
for (i = ne_header->ne_cseg; i > 0; i--, pSeg++)
{
memcpy( pData, pSeg, sizeof(*pSeg) );
+
+ /* The original NE spec (which link4 version 4.x follows) uses the top four bits of the segment flags to set a
+ discard priority (0 = not discardable, 15 = highest priority). Later specs repurpose the top three bits and
+ use a single bit for the discardable flag. The top three bits must be masked off and discardable flag set
+ appropriately, otherwise a discard priority could get misinterpreted as a 32 bit segment flag which results
+ in an application crash. */
+ if (ne_header->ne_ver == 0x04)
+ {
+ WORD* seg_flags;
+ BOOL isDiscardable;
+
+ seg_flags = (WORD*)(pData + FIELD_OFFSET(SEGTABLEENTRY, flags));
+ isDiscardable = ((*seg_flags & 0xF000) > 0);
+
+ if (isDiscardable)
+ *seg_flags = ((*seg_flags & 0x0FFF) | NE_SEGFLAGS_DISCARDABLE);
+ }
+
pData += sizeof(SEGTABLEENTRY);
}
--
2.15.1.windows.2
More information about the wine-devel
mailing list