#ifndef NEFORMAT_H #define NEFORMAT_H #include // ============================================================================ // MZ (DOS) executable header - precedes the NE header // ============================================================================ #define MZ_SIGNATURE 0x5A4D // 'MZ' typedef struct __attribute__((packed)) { uint16_t signature; // 0x00: 'MZ' uint16_t lastPageBytes; // 0x02: bytes on last page uint16_t pageCount; // 0x04: pages in file (512 bytes each) uint16_t relocationCount; // 0x06: relocation entries uint16_t headerParagraphs;// 0x08: header size in paragraphs uint16_t minAlloc; // 0x0A: minimum extra paragraphs uint16_t maxAlloc; // 0x0C: maximum extra paragraphs uint16_t initSS; // 0x0E: initial SS uint16_t initSP; // 0x10: initial SP uint16_t checksum; // 0x12: checksum uint16_t initIP; // 0x14: initial IP uint16_t initCS; // 0x16: initial CS uint16_t relocationOff; // 0x18: relocation table offset uint16_t overlayNum; // 0x1A: overlay number uint16_t reserved1[4]; // 0x1C: reserved uint16_t oemId; // 0x24: OEM identifier uint16_t oemInfo; // 0x26: OEM information uint16_t reserved2[10]; // 0x28: reserved uint32_t neHeaderOffset; // 0x3C: offset to NE header } MzHeaderT; // ============================================================================ // NE (New Executable) header // ============================================================================ #define NE_SIGNATURE 0x454E // 'NE' typedef struct __attribute__((packed)) { uint16_t signature; // 0x00: 'NE' uint8_t linkerMajor; // 0x02: linker version uint8_t linkerMinor; // 0x03: linker revision uint16_t entryTableOffset; // 0x04: offset to entry table (from NE header) uint16_t entryTableSize; // 0x06: size of entry table uint32_t fileCrc; // 0x08: file CRC uint16_t moduleFlags; // 0x0C: module flags uint16_t autoDataSegIndex; // 0x0E: auto data segment index (1-based) uint16_t initialHeapSize; // 0x10: initial heap size uint16_t initialStackSize; // 0x12: initial stack size uint16_t entryPointIP; // 0x14: CS:IP entry point (IP) uint16_t entryPointCS; // 0x16: CS:IP entry point (CS segment index) uint16_t initialSP; // 0x18: SS:SP initial stack (SP) uint16_t initialSS; // 0x1A: SS:SP initial stack (SS segment index) uint16_t segmentCount; // 0x1C: number of segment table entries uint16_t moduleRefCount; // 0x1E: number of module reference table entries uint16_t nonResNameSize; // 0x20: size of non-resident name table uint16_t segmentTableOffset; // 0x22: offset to segment table (from NE header) uint16_t resourceTableOffset; // 0x24: offset to resource table (from NE header) uint16_t resNameTableOffset; // 0x26: offset to resident name table (from NE) uint16_t modRefTableOffset; // 0x28: offset to module reference table (from NE) uint16_t importNameTableOffset; // 0x2A: offset to imported names table (from NE) uint32_t nonResNameTableFileOffset; // 0x2C: file offset of non-resident name table uint16_t movableEntryCount; // 0x30: number of movable entry points uint16_t sectorAlignShift; // 0x32: sector alignment shift count uint16_t resourceSegCount; // 0x34: number of resource segments uint8_t targetOS; // 0x36: target operating system uint8_t otherFlags; // 0x37: additional flags uint16_t gangLoadAreaOffset; // 0x38: offset to gang-load area uint16_t gangLoadAreaSize; // 0x3A: size of gang-load area uint16_t swapAreaSize; // 0x3C: minimum code swap area size uint16_t expectedWinVer; // 0x3E: expected Windows version } NeHeaderT; // NE module flags (moduleFlags field) #define NE_FFLAGS_SINGLEDATA 0x0001 // Single shared DGROUP #define NE_FFLAGS_MULTIPLEDATA 0x0002 // Multiple DGROUP (DLL with per-instance data) #define NE_FFLAGS_GLOBALINIT 0x0004 // Global initialization #define NE_FFLAGS_PROTMODE 0x0008 // Protected mode only #define NE_FFLAGS_8086 0x0010 // 8086 instructions #define NE_FFLAGS_80286 0x0020 // 80286 instructions #define NE_FFLAGS_80386 0x0040 // 80386 instructions #define NE_FFLAGS_80x87 0x0080 // uses 80x87 #define NE_FFLAGS_FULLSCREEN 0x0100 // full-screen application (not a DLL) #define NE_FFLAGS_DLL 0x8000 // DLL or driver (not a task) // NE target OS values #define NE_OS_UNKNOWN 0x00 #define NE_OS_OS2 0x01 #define NE_OS_WINDOWS 0x02 #define NE_OS_DOS4 0x03 #define NE_OS_WIN386 0x04 // ============================================================================ // NE segment table entry // ============================================================================ typedef struct __attribute__((packed)) { uint16_t fileSectorOffset; // Logical sector offset in file (0 = no data) uint16_t fileLength; // Length of segment in file (0 = 64K) uint16_t flags; // Segment flags uint16_t minAllocSize; // Minimum allocation size (0 = 64K) } NeSegEntryT; // Segment flags #define NE_SEGF_DATA 0x0001 // Data segment (0 = code) #define NE_SEGF_ALLOCATED 0x0002 // Loader has allocated memory #define NE_SEGF_LOADED 0x0004 // Segment is loaded #define NE_SEGF_MOVEABLE 0x0010 // Moveable segment #define NE_SEGF_SHAREABLE 0x0020 // Shareable segment #define NE_SEGF_PRELOAD 0x0040 // Preload segment #define NE_SEGF_READONLY 0x0080 // Read-only (code) or execute-only (data) #define NE_SEGF_HASRELOC 0x0100 // Has relocation data #define NE_SEGF_DISCARD 0x1000 // Discardable // ============================================================================ // NE relocation record // ============================================================================ typedef struct __attribute__((packed)) { uint8_t srcType; // Source (fixup) type uint8_t flags; // Relocation flags uint16_t srcOffset; // Offset within segment of the fixup location uint16_t target1; // Module index (1-based) or segment number uint16_t target2; // Ordinal/offset or offset within segment } NeRelocT; // Relocation source types (srcType field) #define NE_RELOC_LOBYTE 0x00 // Low byte fixup #define NE_RELOC_SEGMENT 0x02 // 16-bit segment fixup #define NE_RELOC_FAR_ADDR 0x03 // 32-bit far pointer (seg:off) fixup #define NE_RELOC_OFFSET 0x05 // 16-bit offset fixup #define NE_RELOC_FAR48_ADDR 0x0B // 48-bit far pointer fixup #define NE_RELOC_OFFSET32 0x0D // 32-bit offset fixup // Relocation target flags (flags field) #define NE_RELF_INTERNALREF 0x00 // Internal reference #define NE_RELF_IMPORTORD 0x01 // Import by ordinal #define NE_RELF_IMPORTNAME 0x02 // Import by name #define NE_RELF_OSFIXUP 0x03 // OS fixup #define NE_RELF_TARGET_MASK 0x03 // Mask for target type #define NE_RELF_ADDITIVE 0x04 // Additive fixup (don't zero target first) // ============================================================================ // NE entry table structures // ============================================================================ // Entry table is a series of bundles. Each bundle starts with: // BYTE count - number of entries in this bundle (0 = end of table) // BYTE indicator - 0x00 = empty, 0xFF = moveable, else fixed segment number // Fixed entry (indicator = segment number 1-254) typedef struct __attribute__((packed)) { uint8_t flags; // Entry flags uint16_t offset; // Offset within segment } NeFixedEntryT; // Moveable entry (indicator = 0xFF) typedef struct __attribute__((packed)) { uint8_t flags; // Entry flags uint16_t int3fh; // INT 3Fh instruction (0xCD3F) uint8_t segIndex; // Segment number (1-based) uint16_t offset; // Offset within segment } NeMoveableEntryT; // Entry flags #define NE_ENTRY_EXPORTED 0x01 // Entry is exported #define NE_ENTRY_SHDATA 0x02 // Entry uses shared data segment // ============================================================================ // Display driver ordinal numbers (standard DDI exports) // ============================================================================ #define DDI_ORD_BITBLT 1 #define DDI_ORD_COLORINFO 2 #define DDI_ORD_CONTROL 3 #define DDI_ORD_DISABLE 4 #define DDI_ORD_ENABLE 5 #define DDI_ORD_ENUMDFFONTS 6 #define DDI_ORD_ENUMOBJ 7 #define DDI_ORD_OUTPUT 8 #define DDI_ORD_PIXEL 9 #define DDI_ORD_REALIZEOBJECT 10 #define DDI_ORD_STRBLT 11 #define DDI_ORD_SCANLR 12 #define DDI_ORD_DEVICEMODE 13 #define DDI_ORD_EXTTEXTOUT 14 #define DDI_ORD_GETCHARWIDTH 15 #define DDI_ORD_DEVICEBITMAP 16 #define DDI_ORD_FASTBORDER 17 #define DDI_ORD_SETATTRIBUTE 18 #define DDI_ORD_DIBTODEVICE 19 #define DDI_ORD_CREATEBITMAP 20 #define DDI_ORD_DELETEBITMAP 21 #define DDI_ORD_SELECTBITMAP 22 #define DDI_ORD_BITMAPBITS 23 #define DDI_ORD_RECLIP 24 #define DDI_ORD_GETPALETTE 25 #define DDI_ORD_SETPALETTE 26 #define DDI_ORD_SETPALETTETRANS 27 #define DDI_ORD_UPDATECOLORS 28 #define DDI_ORD_STRETCHBLT 29 #define DDI_ORD_STRETCHDIBITS 30 #define DDI_ORD_SELECTPALETTE 31 #define DDI_ORD_INQUIRE 101 #define DDI_ORD_SETCURSOR 102 #define DDI_ORD_MOVECURSOR 103 #define DDI_ORD_CHECKCRSR 104 #define DDI_ORD_GETDRIVERRESID 450 // Maximum DDI ordinal we track #define DDI_MAX_ORDINAL 500 #endif // NEFORMAT_H