#ifndef NELOAD_H #define NELOAD_H #include #include #include #include "neformat.h" #include "wintypes.h" // ============================================================================ // Loaded segment descriptor // ============================================================================ typedef struct { uint32_t linearAddr; // Linear (physical) address of segment data uint16_t selector; // DPMI selector for this segment uint16_t flags; // Original NE segment flags uint32_t size; // Actual size in memory (from minAllocSize or fileLength) uint32_t fileSize; // Size of data in the file (0 if no file data) bool isCode; // true = code segment, false = data segment } LoadedSegT; // ============================================================================ // Resolved export entry // ============================================================================ typedef struct { uint16_t segIndex; // 1-based segment index uint16_t offset; // Offset within segment uint16_t selector; // DPMI selector (resolved at load time) uint8_t flags; // Entry flags } ExportEntryT; // ============================================================================ // Import resolution callback // // Called by the NE loader when it encounters an imported reference. // The callback should return the far pointer (selector:offset) that the // import should resolve to. Return FARPTR16_NULL if the import cannot // be resolved (the loader will log a warning and patch in a stub). // ============================================================================ typedef FarPtr16T (*ImportResolverT)(const char *moduleName, uint16_t ordinal, const char *funcName); // ============================================================================ // Loaded NE module // ============================================================================ #define NE_MAX_SEGMENTS 64 #define NE_MAX_EXPORTS 2048 #define NE_MAX_MODREFS 16 typedef struct { // Header info NeHeaderT neHeader; uint32_t neHeaderFileOffset; // File offset of NE header uint16_t sectorAlignShift; // Sector alignment // Module name (from resident name table) char moduleName[64]; // Segments uint16_t segmentCount; LoadedSegT segments[NE_MAX_SEGMENTS]; // Exports (indexed by ordinal) uint16_t exportCount; ExportEntryT exports[NE_MAX_EXPORTS]; // Module references (imported module names) uint16_t modRefCount; char modRefNames[NE_MAX_MODREFS][32]; // Auto data segment selector (DGROUP) uint16_t autoDataSel; // DOS memory block (for conventional memory allocations) int dosMemSeg; // DOS memory segment (real mode) int dosMemSel; // DOS memory selector (PM) uint32_t dosMemSize; // Size in bytes // Is the module valid/loaded? bool loaded; } NeModuleT; // ============================================================================ // NE loader functions // ============================================================================ // Load a NE executable from a file. // importResolver is called for each imported reference. // Returns true on success. bool neLoadModule(NeModuleT *mod, const char *filePath, ImportResolverT resolver); // Unload a previously loaded module, freeing all segments and selectors. void neUnloadModule(NeModuleT *mod); // Look up an export by ordinal number. // Returns true and fills seg/off/sel if found. bool neLookupExport(const NeModuleT *mod, uint16_t ordinal, uint16_t *seg, uint16_t *off, uint16_t *sel); // Look up an export by name (searches the resident name table in the loaded file). // Returns the ordinal if found, 0 if not found. uint16_t neLookupExportByName(const NeModuleT *mod, const char *name, const char *filePath); // Extend a loaded segment by extraSize bytes. // The new space is zeroed. *oldSizeOut receives the original size // (i.e., the offset of the new area within the segment). // Returns true on success. Fails if the result would exceed 64K. bool neExtendSegment(NeModuleT *mod, int segIdx, uint32_t extraSize, uint32_t *oldSizeOut); // Debug: dump module information to stderr. void neDumpModule(const NeModuleT *mod); // Enable or disable verbose debug output. void neSetDebug(bool enable); #endif // NELOAD_H