#ifndef WINSTUB_H #define WINSTUB_H #include #include #include "wintypes.h" #include "thunk.h" #include "neload.h" // ============================================================================ // Windows API stub layer // // Provides minimal implementations of KERNEL, GDI, and USER functions // that Windows 3.x display drivers import. These stubs are registered as // 16-bit callbacks via the thunking layer so the driver can call them. // // Supported modules: // KERNEL - Memory management (GlobalAlloc/Lock/Free), module queries, // selector management, system info // GDI - Minimal DC management, palette, object stubs // USER - GetSystemMetrics, MessageBox (stub) // ============================================================================ // ============================================================================ // Stub context // ============================================================================ #define STUB_MAX_ALLOCS 64 // Max GlobalAlloc blocks #define STUB_MAX_SELECTORS 32 // Extra selector allocations // Pre-allocated DOS memory pool for GlobalDOSAlloc. // Avoids calling __dpmi_allocate_dos_memory at runtime (which uses INT // 21h AH=48h and walks the MCB chain) by bump-allocating from a single // block allocated at init time. #define STUB_DOS_POOL_SIZE 0x4000 // 16KB pool #define STUB_MAX_DOS_ALLOCS 8 typedef struct { // Memory allocation tracking struct { uint16_t handle; // HGLOBAL16 uint32_t linearAddr; // Linear address uint16_t selector; // PM selector for the block uint32_t size; // Block size uint16_t lockCount; // Lock count bool inUse; } allocs[STUB_MAX_ALLOCS]; uint16_t nextHandle; // Next handle value to assign // Extra selectors (for AllocSelector, AllocCStoDSAlias, etc.) struct { uint16_t selector; bool inUse; } selectors[STUB_MAX_SELECTORS]; // DOS memory pool for GlobalDOSAlloc (pre-allocated at init) struct { uint16_t paraOff; // Paragraph offset from pool base uint16_t paragraphs; // Size in paragraphs uint16_t selector; // PM selector for this sub-block bool inUse; } dosAllocs[STUB_MAX_DOS_ALLOCS]; uint16_t dosPoolSeg; // Real-mode segment of pool uint16_t dosPoolSel; // DPMI selector for pool (for freeing) uint16_t dosPoolParas; // Total pool size in paragraphs uint16_t dosPoolNextPara; // Next free paragraph offset (bump allocator) // Well-known memory region selectors uint16_t biosDataSel; // 0040:0000 BIOS data area uint16_t vramSel; // A000:0000 VGA graphics RAM uint16_t monoTextSel; // B000:0000 Mono text video uint16_t colorTextSel; // B800:0000 Color text video uint16_t videoBiosSel; // C000:0000 Video BIOS ROM uint16_t upperMemD000Sel; // D000:0000 Upper memory uint16_t upperMemE000Sel; // E000:0000 Upper memory uint16_t sysBiosSel; // F000:0000 System BIOS ROM // Thunk context reference ThunkContextT *thunkCtx; // NE module reference (for GetProcAddress lookups) NeModuleT *neModule; // Lookup table: module name + ordinal -> FarPtr16T // Built during stub registration struct { char module[16]; uint16_t ordinal; FarPtr16T addr; } stubTable[256]; uint16_t stubCount; bool initialized; } StubContextT; // ============================================================================ // Stub layer functions // ============================================================================ // Initialize the stub layer. Must be called after thunkInit(). bool stubInit(StubContextT *ctx, ThunkContextT *thunkCtx); // Enable or disable verbose stub logging. void stubSetDebug(bool debug); // Shut down the stub layer. void stubShutdown(StubContextT *ctx); // Set the NE module reference for GetProcAddress lookups. void stubSetModule(StubContextT *ctx, NeModuleT *mod); // Resolve an imported function. Called by the NE loader's import resolver. // Returns the 16-bit far pointer to the stub function, or FARPTR16_NULL // if the import is unknown. FarPtr16T stubResolveImport(StubContextT *ctx, const char *moduleName, uint16_t ordinal, const char *funcName); // ============================================================================ // KERNEL stubs - ordinal numbers // These are the most commonly imported KERNEL functions by display drivers. // ============================================================================ // Error handling #define KERNEL_ORD_FATALEXIT 1 #define KERNEL_ORD_FATALAPPEXIT 137 // Memory management - Global #define KERNEL_ORD_GLOBALALLOC 15 #define KERNEL_ORD_GLOBALREALLOC 16 #define KERNEL_ORD_GLOBALFREE 17 #define KERNEL_ORD_GLOBALLOCK 18 #define KERNEL_ORD_GLOBALUNLOCK 19 #define KERNEL_ORD_GLOBALSIZE 20 #define KERNEL_ORD_GLOBALFLAGS 22 #define KERNEL_ORD_GLOBALDOSALLOC 84 #define KERNEL_ORD_GLOBALDOSFREE 85 #define KERNEL_ORD_GLOBALDOSALLOC2 184 // Duplicate ordinal for GlobalDOSAlloc #define KERNEL_ORD_GLOBALDOSFREE2 185 // Duplicate ordinal for GlobalDOSFree // Memory management - Local #define KERNEL_ORD_LOCALINIT 4 #define KERNEL_ORD_LOCALALLOC 5 #define KERNEL_ORD_LOCALREALLOC 6 #define KERNEL_ORD_LOCALFREE 7 #define KERNEL_ORD_LOCALLOCK 8 #define KERNEL_ORD_LOCALUNLOCK 9 #define KERNEL_ORD_LOCALSIZE 10 // Memory info #define KERNEL_ORD_GETFREESPACE 102 #define KERNEL_ORD_LOCKSEGMENT 23 #define KERNEL_ORD_UNLOCKSEGMENT 24 #define KERNEL_ORD_SETSWAPAREA 81 #define KERNEL_ORD_GETCURRENTPDB 82 // Module management #define KERNEL_ORD_GETMODULEHANDLE 47 #define KERNEL_ORD_GETMODULEUSAGE 35 #define KERNEL_ORD_GETPROFILEINT 48 #define KERNEL_ORD_GETPROFILEINT2 57 // Alternate ordinal used by some drivers #define KERNEL_ORD_WRITEPROFILESTRING 59 #define KERNEL_ORD_GETMODULEFILENAME 49 #define KERNEL_ORD_GETPROCADDRESS 50 #define KERNEL_ORD_LOADLIBRARY 95 #define KERNEL_ORD_FREELIBRARY 96 #define KERNEL_ORD_INITTASK 91 #define KERNEL_ORD_GETEXEPTR 133 // Resource management #define KERNEL_ORD_FINDRESOURCE 60 #define KERNEL_ORD_LOADRESOURCE 61 #define KERNEL_ORD_FREERESOURCE 63 #define KERNEL_ORD_LOCKRESOURCE 62 #define KERNEL_ORD_SIZEOFRESOURCE 65 // Selector management #define KERNEL_ORD_ALLOCSELECTOR 175 #define KERNEL_ORD_FREESELECTOR 176 #define KERNEL_ORD_ALLOCCSTODSALIAS 170 #define KERNEL_ORD_ALLOCDSTOCSALIAS 171 #define KERNEL_ORD_SETSELECTORBASE 187 #define KERNEL_ORD_GETSELECTORBASE 186 #define KERNEL_ORD_SETSELECTORLIMIT 189 #define KERNEL_ORD_PRESTOCHANGOSELECTOR 177 #define KERNEL_ORD_SELECTORACCESSRIGHTS 196 #define KERNEL_ORD_ALLOCSELECTORARRAY 206 // System info #define KERNEL_ORD_GETVERSION 3 #define KERNEL_ORD_GETWINFLAGS 132 #define KERNEL_ORD_GETSYSTEMDIRECTORY 135 #define KERNEL_ORD_GETDOSENVIRONMENT 131 #define KERNEL_ORD_GETPRIVATEPROFILEINT 127 #define KERNEL_ORD_GETPRIVATEPROFILESTRING 128 #define KERNEL_ORD_WRITEPRIVATEPROFILESTRING 129 // Selector arithmetic (variables, not functions) #define KERNEL_ORD___AHSHIFT 113 #define KERNEL_ORD___AHINCR 114 #define KERNEL_ORD___WINFLAGS 178 // Segment selectors to well-known memory regions (variables, not functions) #define KERNEL_ORD___0000H 183 #define KERNEL_ORD___0040H 193 #define KERNEL_ORD___A000H 174 #define KERNEL_ORD___B000H 181 #define KERNEL_ORD___B800H 182 #define KERNEL_ORD___C000H 195 #define KERNEL_ORD___D000H 179 #define KERNEL_ORD___E000H 190 #define KERNEL_ORD___F000H 194 #define KERNEL_ORD___ROMBIOS 173 // Selector query #define KERNEL_ORD_GETSELECTORLIMIT 188 #define KERNEL_ORD_GETSELECTORBASE2 186 // Debug #define KERNEL_ORD_OUTPUTDEBUGSTRING 115 // ============================================================================ // GDI stubs - ordinal numbers // ============================================================================ #define GDI_ORD_CREATEDC 53 #define GDI_ORD_DELETEDC 68 #define GDI_ORD_SELECTOBJECT 45 #define GDI_ORD_DELETEOBJECT 69 #define GDI_ORD_GETDEVICECAPS 80 #define GDI_ORD_SETBKCOLOR 1 #define GDI_ORD_SETTEXTCOLOR 6 #define GDI_ORD_GETPALETTE_GDI 5 // DIB Engine exports (from DIBENG.DLL or built into GDI) #define DIBENG_ORD_DIBBITBLT 1 #define DIBENG_ORD_DIBOUTPUT 2 #define DIBENG_ORD_DIBPIXEL 3 #define DIBENG_ORD_DIBSTRBLT 4 #define DIBENG_ORD_DIBCOLORINFO 5 #define DIBENG_ORD_DIBREALIZE 6 #define DIBENG_ORD_DIBCREATEBITMAP 7 #define DIBENG_ORD_DIBSCANLR 8 #define DIBENG_ORD_DIBEXTOUT 9 // ============================================================================ // USER stubs - ordinal numbers // ============================================================================ #define USER_ORD_GETSYSTEMMETRICS 179 #define USER_ORD_MESSAGEBOX 1 // ============================================================================ // KEYBOARD stubs - ordinal numbers // ============================================================================ #define KEYBOARD_ORD_SCREENSWITCHENABLE 100 #endif // WINSTUB_H