Add comprehensive README covering architecture, API usage, build instructions, tested drivers, binary patching details, and DGROUP layout. Expand file header comments in all library sources and headers to document module responsibilities, data flow, and key constraints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
267 lines
9.8 KiB
C
267 lines
9.8 KiB
C
#ifndef WINSTUB_H
|
|
#define WINSTUB_H
|
|
|
|
// ============================================================================
|
|
// winstub.h - Windows API stub layer
|
|
//
|
|
// Declares the stub context, initialization/shutdown, and import
|
|
// resolution functions. Also defines the ordinal numbers for all
|
|
// stubbed KERNEL, GDI, USER, KEYBOARD, and DIBENG functions.
|
|
//
|
|
// The stub context (StubContextT) tracks:
|
|
// - GlobalAlloc memory blocks and their selectors
|
|
// - Extra selectors from AllocSelector/AllocCStoDSAlias
|
|
// - A pre-allocated DOS memory pool for GlobalDOSAlloc
|
|
// - Well-known memory region selectors (__A000H, __0040H, etc.)
|
|
// - A lookup table mapping module+ordinal to 16-bit far pointers
|
|
//
|
|
// Import resolution flow:
|
|
// 1. NE loader encounters an imported reference
|
|
// 2. Calls importResolver -> stubResolveImport
|
|
// 3. For variable imports (__WINFLAGS, __A000H, etc.): returns the
|
|
// value directly (selector or constant) in the far pointer
|
|
// 4. For function imports: looks up the stub table for a matching
|
|
// module+ordinal entry and returns the 16-bit callback address
|
|
// 5. Unknown imports: logs a warning and returns FARPTR16_NULL
|
|
// ============================================================================
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "wintypes.h"
|
|
#include "thunk.h"
|
|
#include "neload.h"
|
|
|
|
// ============================================================================
|
|
// 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
|