WinDriver/win31drv/winstub.h
2026-02-21 18:01:54 -06:00

257 lines
9.3 KiB
C

#ifndef WINSTUB_H
#define WINSTUB_H
#include <stdint.h>
#include <stdbool.h>
#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