move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.
This commit is contained in:
1 parent
b970d7f59c
commit
b838f8d83d
130 files changed
+8137
-2932
No files matched your search
@@ -48439,7 +48439,7 @@ void Z_DumpHeap(int lowtag, int hightag)
|
||||
{
|
||||
memblock_t* block;
|
||||
|
||||
//doom_print("zone size: %i location: %p\n",
|
||||
//doom_print("zone size: %i location: 0x%016llX\n",
|
||||
// mainzone->size, mainzone);
|
||||
doom_print("zone size: ");
|
||||
doom_print(doom_itoa(mainzone->size, 10));
|
||||
@@ -48459,7 +48459,7 @@ void Z_DumpHeap(int lowtag, int hightag)
|
||||
{
|
||||
if (block->tag >= lowtag && block->tag <= hightag)
|
||||
{
|
||||
//doom_print("block:%p size:%7i user:%p tag:%3i\n", block, block->size, block->user, block->tag);
|
||||
//doom_print("block:0x%016llX size:%7i user:0x%016llX tag:%3i\n", block, block->size, block->user, block->tag);
|
||||
doom_print("block");
|
||||
doom_print(doom_ptoa(block));
|
||||
doom_print(" size:");
|
||||
@@ -48496,7 +48496,7 @@ void Z_FileDumpHeap(void* f)
|
||||
{
|
||||
memblock_t* block;
|
||||
|
||||
//fprintf(f, "zone size: %i location: %p\n", mainzone->size, mainzone);
|
||||
//fprintf(f, "zone size: %i location: 0x%016llX\n", mainzone->size, mainzone);
|
||||
doom_fprint(f, "zone size: ");
|
||||
doom_fprint(f, doom_itoa(mainzone->size, 10));
|
||||
doom_fprint(f, " location: ");
|
||||
@@ -48505,7 +48505,7 @@ void Z_FileDumpHeap(void* f)
|
||||
|
||||
for (block = mainzone->blocklist.next; ; block = block->next)
|
||||
{
|
||||
//fprintf(f, "block:%p size:%7i user:%p tag:%3i\n",
|
||||
//fprintf(f, "block:0x%016llX size:%7i user:0x%016llX tag:%3i\n",
|
||||
// block, block->size, block->user, block->tag);
|
||||
doom_fprint(f, "block:");
|
||||
doom_fprint(f, doom_ptoa(block));
|
||||
|
||||
+46
-46
@@ -180,67 +180,67 @@ static char* doom_getenv_wrapper(const char* name)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Input — Maps Scancode Set 1 values to PureDOOM
|
||||
// Input — Maps canonical input keys to PureDOOM
|
||||
// ---------------------------------------------------------------------------
|
||||
typedef struct { uint8_t scancode; bool extended; doom_key_t key; } KeyMap;
|
||||
typedef struct { INPUT_KEY inputKey; doom_key_t key; } KeyMap;
|
||||
|
||||
static const KeyMap g_keymap[] = {
|
||||
// Letters
|
||||
{ 0x11, false, DOOM_KEY_W },
|
||||
{ 0x1E, false, DOOM_KEY_A },
|
||||
{ 0x1F, false, DOOM_KEY_S },
|
||||
{ 0x20, false, DOOM_KEY_D },
|
||||
{ 0x12, false, DOOM_KEY_E },
|
||||
{ 0x10, false, DOOM_KEY_Q },
|
||||
{ 0x15, false, DOOM_KEY_Y },
|
||||
{ 0x31, false, DOOM_KEY_N },
|
||||
{ INPUT_KEY_W, DOOM_KEY_W },
|
||||
{ INPUT_KEY_A, DOOM_KEY_A },
|
||||
{ INPUT_KEY_S, DOOM_KEY_S },
|
||||
{ INPUT_KEY_D, DOOM_KEY_D },
|
||||
{ INPUT_KEY_E, DOOM_KEY_E },
|
||||
{ INPUT_KEY_Q, DOOM_KEY_Q },
|
||||
{ INPUT_KEY_Y, DOOM_KEY_Y },
|
||||
{ INPUT_KEY_N, DOOM_KEY_N },
|
||||
|
||||
// Arrow keys
|
||||
{ 0x48, true, DOOM_KEY_UP_ARROW },
|
||||
{ 0x50, true, DOOM_KEY_DOWN_ARROW },
|
||||
{ 0x4B, true, DOOM_KEY_LEFT_ARROW },
|
||||
{ 0x4D, true, DOOM_KEY_RIGHT_ARROW },
|
||||
{ INPUT_KEY_UP, DOOM_KEY_UP_ARROW },
|
||||
{ INPUT_KEY_DOWN, DOOM_KEY_DOWN_ARROW },
|
||||
{ INPUT_KEY_LEFT, DOOM_KEY_LEFT_ARROW },
|
||||
{ INPUT_KEY_RIGHT, DOOM_KEY_RIGHT_ARROW },
|
||||
|
||||
// Action keys
|
||||
{ 0x1D, false, DOOM_KEY_CTRL },
|
||||
{ 0x39, false, DOOM_KEY_SPACE },
|
||||
{ 0x2A, false, DOOM_KEY_SHIFT },
|
||||
{ 0x38, false, DOOM_KEY_ALT },
|
||||
{ INPUT_KEY_LEFT_CTRL, DOOM_KEY_CTRL },
|
||||
{ INPUT_KEY_SPACE, DOOM_KEY_SPACE },
|
||||
{ INPUT_KEY_LEFT_SHIFT, DOOM_KEY_SHIFT },
|
||||
{ INPUT_KEY_LEFT_ALT, DOOM_KEY_ALT },
|
||||
|
||||
// Navigation
|
||||
{ 0x01, false, DOOM_KEY_ESCAPE },
|
||||
{ 0x1C, false, DOOM_KEY_ENTER },
|
||||
{ 0x0F, false, DOOM_KEY_TAB },
|
||||
{ 0x0E, false, DOOM_KEY_BACKSPACE },
|
||||
{ INPUT_KEY_ESCAPE, DOOM_KEY_ESCAPE },
|
||||
{ INPUT_KEY_ENTER, DOOM_KEY_ENTER },
|
||||
{ INPUT_KEY_TAB, DOOM_KEY_TAB },
|
||||
{ INPUT_KEY_BACKSPACE, DOOM_KEY_BACKSPACE },
|
||||
|
||||
// Weapon slots
|
||||
{ 0x02, false, DOOM_KEY_1 },
|
||||
{ 0x03, false, DOOM_KEY_2 },
|
||||
{ 0x04, false, DOOM_KEY_3 },
|
||||
{ 0x05, false, DOOM_KEY_4 },
|
||||
{ 0x06, false, DOOM_KEY_5 },
|
||||
{ 0x07, false, DOOM_KEY_6 },
|
||||
{ 0x08, false, DOOM_KEY_7 },
|
||||
{ INPUT_KEY_1, DOOM_KEY_1 },
|
||||
{ INPUT_KEY_2, DOOM_KEY_2 },
|
||||
{ INPUT_KEY_3, DOOM_KEY_3 },
|
||||
{ INPUT_KEY_4, DOOM_KEY_4 },
|
||||
{ INPUT_KEY_5, DOOM_KEY_5 },
|
||||
{ INPUT_KEY_6, DOOM_KEY_6 },
|
||||
{ INPUT_KEY_7, DOOM_KEY_7 },
|
||||
|
||||
// Misc
|
||||
{ 0x0C, false, DOOM_KEY_MINUS },
|
||||
{ 0x0D, false, DOOM_KEY_EQUALS },
|
||||
{ 0x33, false, DOOM_KEY_COMMA },
|
||||
{ 0x34, false, DOOM_KEY_PERIOD },
|
||||
{ INPUT_KEY_MINUS, DOOM_KEY_MINUS },
|
||||
{ INPUT_KEY_EQUAL, DOOM_KEY_EQUALS },
|
||||
{ INPUT_KEY_COMMA, DOOM_KEY_COMMA },
|
||||
{ INPUT_KEY_PERIOD, DOOM_KEY_PERIOD },
|
||||
|
||||
// Function keys
|
||||
{ 0x3B, false, DOOM_KEY_F1 },
|
||||
{ 0x3C, false, DOOM_KEY_F2 },
|
||||
{ 0x3D, false, DOOM_KEY_F3 },
|
||||
{ 0x3E, false, DOOM_KEY_F4 },
|
||||
{ 0x3F, false, DOOM_KEY_F5 },
|
||||
{ 0x40, false, DOOM_KEY_F6 },
|
||||
{ 0x41, false, DOOM_KEY_F7 },
|
||||
{ 0x42, false, DOOM_KEY_F8 },
|
||||
{ 0x43, false, DOOM_KEY_F9 },
|
||||
{ 0x44, false, DOOM_KEY_F10 },
|
||||
{ 0x57, false, DOOM_KEY_F11 },
|
||||
{ 0x58, false, DOOM_KEY_F12 },
|
||||
{ INPUT_KEY_F1, DOOM_KEY_F1 },
|
||||
{ INPUT_KEY_F2, DOOM_KEY_F2 },
|
||||
{ INPUT_KEY_F3, DOOM_KEY_F3 },
|
||||
{ INPUT_KEY_F4, DOOM_KEY_F4 },
|
||||
{ INPUT_KEY_F5, DOOM_KEY_F5 },
|
||||
{ INPUT_KEY_F6, DOOM_KEY_F6 },
|
||||
{ INPUT_KEY_F7, DOOM_KEY_F7 },
|
||||
{ INPUT_KEY_F8, DOOM_KEY_F8 },
|
||||
{ INPUT_KEY_F9, DOOM_KEY_F9 },
|
||||
{ INPUT_KEY_F10, DOOM_KEY_F10 },
|
||||
{ INPUT_KEY_F11, DOOM_KEY_F11 },
|
||||
{ INPUT_KEY_F12, DOOM_KEY_F12 },
|
||||
};
|
||||
|
||||
#define KEYMAP_COUNT (sizeof(g_keymap) / sizeof(g_keymap[0]))
|
||||
@@ -250,7 +250,7 @@ static bool g_prev_key[KEYMAP_COUNT];
|
||||
static void poll_input(void)
|
||||
{
|
||||
for (int i = 0; i < (int)KEYMAP_COUNT; i++) {
|
||||
bool cur_down = (SysKbIsKeyDown(g_keymap[i].scancode, g_keymap[i].extended) != 0);
|
||||
bool cur_down = (SysKbIsKeyDown(g_keymap[i].inputKey) != 0);
|
||||
bool prev_down = g_prev_key[i];
|
||||
|
||||
if (cur_down && !prev_down) doom_key_down(g_keymap[i].key);
|
||||
|
||||
+60
-65
@@ -27,29 +27,21 @@
|
||||
#define COL_CURSOR 0xE0E0E0u
|
||||
#define COL_CURSORF 0x000000u
|
||||
|
||||
#define MOD_LSHIFT (1u << 0)
|
||||
#define MOD_RSHIFT (1u << 1)
|
||||
#define MOD_LCTRL (1u << 2)
|
||||
#define MOD_RCTRL (1u << 3)
|
||||
#define MOD_CAPS (1u << 6)
|
||||
#define MOD_SHIFT (MOD_LSHIFT | MOD_RSHIFT)
|
||||
#define MOD_CTRL (MOD_LCTRL | MOD_RCTRL)
|
||||
|
||||
#define SC_ESC 0x01u
|
||||
#define SC_BACKSPACE 0x0Eu
|
||||
#define SC_TAB 0x0Fu
|
||||
#define SC_Q 0x10u
|
||||
#define SC_S 0x1Fu
|
||||
#define SC_ENTER 0x1Cu
|
||||
#define SC_HOME 0x47u
|
||||
#define SC_UP 0x48u
|
||||
#define SC_PGUP 0x49u
|
||||
#define SC_LEFT 0x4Bu
|
||||
#define SC_RIGHT 0x4Du
|
||||
#define SC_END 0x4Fu
|
||||
#define SC_DOWN 0x50u
|
||||
#define SC_PGDN 0x51u
|
||||
#define SC_DEL 0x53u
|
||||
#define EDIT_KEY_ESC INPUT_KEY_ESCAPE
|
||||
#define EDIT_KEY_BACKSPACE INPUT_KEY_BACKSPACE
|
||||
#define EDIT_KEY_TAB INPUT_KEY_TAB
|
||||
#define EDIT_KEY_Q INPUT_KEY_Q
|
||||
#define EDIT_KEY_S INPUT_KEY_S
|
||||
#define EDIT_KEY_ENTER INPUT_KEY_ENTER
|
||||
#define EDIT_KEY_HOME INPUT_KEY_HOME
|
||||
#define EDIT_KEY_UP INPUT_KEY_UP
|
||||
#define EDIT_KEY_PGUP INPUT_KEY_PAGE_UP
|
||||
#define EDIT_KEY_LEFT INPUT_KEY_LEFT
|
||||
#define EDIT_KEY_RIGHT INPUT_KEY_RIGHT
|
||||
#define EDIT_KEY_END INPUT_KEY_END
|
||||
#define EDIT_KEY_DOWN INPUT_KEY_DOWN
|
||||
#define EDIT_KEY_PGDN INPUT_KEY_PAGE_DOWN
|
||||
#define EDIT_KEY_DEL INPUT_KEY_DELETE
|
||||
|
||||
typedef struct LINE {
|
||||
int len;
|
||||
@@ -69,22 +61,6 @@ static bool gQuitArmed = false;
|
||||
static char gFilename[PATH_MAX2] = "untitled.txt";
|
||||
static char gMessage[MSG_MAX] = "ready";
|
||||
|
||||
static const char gUnshifted[128] = {
|
||||
0, 0, '1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
|
||||
'q','w','e','r','t','y','u','i','o','p','[',']','\n', 0, 'a','s',
|
||||
'd','f','g','h','j','k','l',';','\'','`', 0, '\\','z','x','c','v',
|
||||
'b','n','m',',','.','/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, '7','8','9','-', '4','5','6','+', '1','2','3','0','.'
|
||||
};
|
||||
|
||||
static const char gShifted[128] = {
|
||||
0, 0, '!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
|
||||
'Q','W','E','R','T','Y','U','I','O','P','{','}','\n', 0, 'A','S',
|
||||
'D','F','G','H','J','K','L',':','"','~', 0, '|','Z','X','C','V',
|
||||
'B','N','M','<','>','?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, '7','8','9','-', '4','5','6','+', '1','2','3','0','.'
|
||||
};
|
||||
|
||||
static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
|
||||
SysScreenPutChar(c ? c : ' ', col * GLYPH_W, row * GLYPH_H, fg, bg);
|
||||
}
|
||||
@@ -124,14 +100,33 @@ static void append_u32(char* b, size_t cap, size_t* p, uint32_t v) {
|
||||
while (n > 0) append_char(b, cap, p, tmp[--n]);
|
||||
}
|
||||
|
||||
static char key_to_char(uint8_t sc, uint32_t mods) {
|
||||
if (sc >= 128) return 0;
|
||||
bool shifted = (mods & MOD_SHIFT) != 0;
|
||||
if (mods & MOD_CAPS) {
|
||||
char base = gUnshifted[sc];
|
||||
if (base >= 'a' && base <= 'z') shifted = !shifted;
|
||||
static char key_to_char(INPUT_KEY key, uint32_t mods) {
|
||||
if (key >= INPUT_KEY_A && key <= INPUT_KEY_Z) {
|
||||
bool shifted = (mods & INPUT_MOD_SHIFT) != 0;
|
||||
bool caps = (mods & INPUT_MOD_CAPS_LOCK) != 0;
|
||||
char c = (char)('a' + (key - INPUT_KEY_A));
|
||||
return (shifted ^ caps) ? (char)(c - 'a' + 'A') : c;
|
||||
}
|
||||
return shifted ? gShifted[sc] : gUnshifted[sc];
|
||||
|
||||
typedef struct { INPUT_KEY key; char normal; char shifted; } PAIR;
|
||||
static const PAIR map[] = {
|
||||
{ INPUT_KEY_1, '1', '!' }, { INPUT_KEY_2, '2', '@' },
|
||||
{ INPUT_KEY_3, '3', '#' }, { INPUT_KEY_4, '4', '$' },
|
||||
{ INPUT_KEY_5, '5', '%' }, { INPUT_KEY_6, '6', '^' },
|
||||
{ INPUT_KEY_7, '7', '&' }, { INPUT_KEY_8, '8', '*' },
|
||||
{ INPUT_KEY_9, '9', '(' }, { INPUT_KEY_0, '0', ')' },
|
||||
{ INPUT_KEY_MINUS, '-', '_' }, { INPUT_KEY_EQUAL, '=', '+' },
|
||||
{ INPUT_KEY_LEFT_BRACKET, '[', '{' }, { INPUT_KEY_RIGHT_BRACKET, ']', '}' },
|
||||
{ INPUT_KEY_BACKSLASH, '\\', '|' }, { INPUT_KEY_SEMICOLON, ';', ':' },
|
||||
{ INPUT_KEY_APOSTROPHE, '\'', '"' }, { INPUT_KEY_GRAVE, '`', '~' },
|
||||
{ INPUT_KEY_COMMA, ',', '<' }, { INPUT_KEY_PERIOD, '.', '>' },
|
||||
{ INPUT_KEY_SLASH, '/', '?' }, { INPUT_KEY_SPACE, ' ', ' ' },
|
||||
};
|
||||
bool shifted = (mods & INPUT_MOD_SHIFT) != 0;
|
||||
for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
|
||||
if (map[i].key == key) return shifted ? map[i].shifted : map[i].normal;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clamp_cursor(void) {
|
||||
@@ -423,11 +418,11 @@ static void editor_loop(void) {
|
||||
while (true) {
|
||||
render();
|
||||
|
||||
uint8_t sc = SysKbReadScancode();
|
||||
INPUT_KEY key = SysKbReadKey();
|
||||
uint32_t mods = SysKbGetModifiers();
|
||||
bool ctrl = (mods & MOD_CTRL) != 0;
|
||||
bool ctrl = (mods & INPUT_MOD_CTRL) != 0;
|
||||
|
||||
if (ctrl && sc == SC_Q) {
|
||||
if (ctrl && key == EDIT_KEY_Q) {
|
||||
if (gDirty && !gQuitArmed) {
|
||||
gQuitArmed = true;
|
||||
msg_set("unsaved changes: press Ctrl+Q again to quit");
|
||||
@@ -438,38 +433,38 @@ static void editor_loop(void) {
|
||||
|
||||
gQuitArmed = false;
|
||||
|
||||
if (ctrl && sc == SC_S) { save_file(); continue; }
|
||||
if (sc == SC_ESC) { msg_set("Ctrl+Q quits, Ctrl+S saves"); continue; }
|
||||
if (ctrl && key == EDIT_KEY_S) { save_file(); continue; }
|
||||
if (key == EDIT_KEY_ESC) { msg_set("Ctrl+Q quits, Ctrl+S saves"); continue; }
|
||||
|
||||
switch (sc) {
|
||||
case SC_LEFT: move_left(); break;
|
||||
case SC_RIGHT: move_right(); break;
|
||||
case SC_UP: move_up(); break;
|
||||
case SC_DOWN: move_down(); break;
|
||||
case SC_HOME: gCx = 0; break;
|
||||
case SC_END: gCx = gLines[gCy].len; break;
|
||||
case SC_PGUP: {
|
||||
switch (key) {
|
||||
case EDIT_KEY_LEFT: move_left(); break;
|
||||
case EDIT_KEY_RIGHT: move_right(); break;
|
||||
case EDIT_KEY_UP: move_up(); break;
|
||||
case EDIT_KEY_DOWN: move_down(); break;
|
||||
case EDIT_KEY_HOME: gCx = 0; break;
|
||||
case EDIT_KEY_END: gCx = gLines[gCy].len; break;
|
||||
case EDIT_KEY_PGUP: {
|
||||
int n = gRows - 2;
|
||||
if (n < 1) n = 1;
|
||||
gCy -= n;
|
||||
clamp_cursor();
|
||||
break;
|
||||
}
|
||||
case SC_PGDN: {
|
||||
case EDIT_KEY_PGDN: {
|
||||
int n = gRows - 2;
|
||||
if (n < 1) n = 1;
|
||||
gCy += n;
|
||||
clamp_cursor();
|
||||
break;
|
||||
}
|
||||
case SC_BACKSPACE: backspace_at_cursor(); break;
|
||||
case SC_DEL: delete_at_cursor(); break;
|
||||
case SC_ENTER: newline_at_cursor(); break;
|
||||
case SC_TAB:
|
||||
case EDIT_KEY_BACKSPACE: backspace_at_cursor(); break;
|
||||
case EDIT_KEY_DEL: delete_at_cursor(); break;
|
||||
case EDIT_KEY_ENTER: newline_at_cursor(); break;
|
||||
case EDIT_KEY_TAB:
|
||||
for (int i = 0; i < 4; i++) insert_char_at_cursor(' ');
|
||||
break;
|
||||
default: {
|
||||
char c = key_to_char(sc, mods);
|
||||
char c = key_to_char(key, mods);
|
||||
if (!ctrl && c >= 0x20 && c <= 0x7E) insert_char_at_cursor(c);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ typedef struct BINKSND {
|
||||
// will do it's own threading)
|
||||
// 2 = No background thread processing at all, but setup
|
||||
// thread mutexes, so that BinkServiceSound() can be
|
||||
// call from an external background thread.
|
||||
// call from an external background thread.
|
||||
|
||||
U32 SoundDroppedOut;
|
||||
U32 sndconvert8; // convert back to 8-bit sound at runtime
|
||||
|
||||
@@ -50,7 +50,7 @@ static void PthreadTrampoline(uintptr_t raw) {
|
||||
uint32_t pid = tr->Pid;
|
||||
uint32_t tid = SysGetCurrentTid();
|
||||
|
||||
// Create the join slot from inside the new thread. KeCreateThread makes the
|
||||
// Create the join slot from inside the new thread. KeCreateThread makes the
|
||||
// thread runnable before the creator regains control, so the old design
|
||||
// raced on tr->Tid and could observe zero/stale memory.
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
|
||||
|
||||
@@ -107,7 +107,7 @@ typedef struct _WIN32_FIND_DATAA {
|
||||
static inline HANDLE KH_TO_HANDLE(uint32_t kh) { return (HANDLE)(uintptr_t)kh; }
|
||||
static inline uint32_t HANDLE_TO_KH(HANDLE h) { return (uint32_t)(uintptr_t)h; }
|
||||
|
||||
// Thread IDs are not kernel handles. Keep Win32 thread pseudo-handles out of
|
||||
// Thread IDs are not kernel handles. Keep Win32 thread pseudo-handles out of
|
||||
// the low numeric handle namespace so CloseHandle/WaitForSingleObject cannot
|
||||
// accidentally operate on an unrelated file/process handle with the same value.
|
||||
#define WIN32_THREAD_HANDLE_TAG ((uintptr_t)1ULL << 63)
|
||||
@@ -133,7 +133,7 @@ static void TranslatePath(const char* input, char* output) {
|
||||
if (!input) { output[0] = '\0'; return; }
|
||||
|
||||
if (input[0] != '\0' && input[1] == ':' && (input[2] == '\\' || input[2] == '/')) {
|
||||
// Translate "C:\" -> "0:/". Native nt-lite paths such as
|
||||
// Translate "C:\" -> "0:/". Native nt-lite paths such as
|
||||
// "0:/system/foo.dll" are already drive-indexed and pass through.
|
||||
char drive = input[0];
|
||||
if (drive >= 'a' && drive <= 'z') drive -= ('a' - 'A'); // To uppercase
|
||||
@@ -440,61 +440,60 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress,
|
||||
|
||||
// --- Win32 API ---
|
||||
|
||||
// Updated GetAsyncKeyState implementation
|
||||
// GetAsyncKeyState implementation over the canonical input key namespace.
|
||||
__declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
|
||||
static const struct { int vk; uint8_t sc; bool ext; } vk_to_sc[] = {
|
||||
if (vKey == 0x11) { // VK_CONTROL
|
||||
return (SysKbIsKeyDown(INPUT_KEY_LEFT_CTRL) || SysKbIsKeyDown(INPUT_KEY_RIGHT_CTRL)) ? (SHORT)0x8000 : 0;
|
||||
}
|
||||
if (vKey == 0x10) { // VK_SHIFT
|
||||
return (SysKbIsKeyDown(INPUT_KEY_LEFT_SHIFT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_SHIFT)) ? (SHORT)0x8000 : 0;
|
||||
}
|
||||
if (vKey == 0x12) { // VK_MENU / ALT
|
||||
return (SysKbIsKeyDown(INPUT_KEY_LEFT_ALT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_ALT)) ? (SHORT)0x8000 : 0;
|
||||
}
|
||||
|
||||
static const struct { int vk; INPUT_KEY key; } vk_to_key[] = {
|
||||
// Letters
|
||||
{ 0x41, 0x1E, false }, { 0x42, 0x30, false }, { 0x43, 0x2E, false },
|
||||
{ 0x44, 0x20, false }, { 0x45, 0x12, false }, { 0x46, 0x21, false },
|
||||
{ 0x47, 0x22, false }, { 0x48, 0x23, false }, { 0x49, 0x17, false },
|
||||
{ 0x4A, 0x24, false }, { 0x4B, 0x25, false }, { 0x4C, 0x26, false },
|
||||
{ 0x4D, 0x32, false }, { 0x4E, 0x31, false }, { 0x4F, 0x18, false },
|
||||
{ 0x50, 0x19, false }, { 0x51, 0x10, false }, { 0x52, 0x13, false },
|
||||
{ 0x53, 0x1F, false }, { 0x54, 0x14, false }, { 0x55, 0x16, false },
|
||||
{ 0x56, 0x2F, false }, { 0x57, 0x11, false }, { 0x58, 0x2D, false },
|
||||
{ 0x59, 0x15, false }, { 0x5A, 0x2C, false },
|
||||
{ 0x41, INPUT_KEY_A }, { 0x42, INPUT_KEY_B }, { 0x43, INPUT_KEY_C },
|
||||
{ 0x44, INPUT_KEY_D }, { 0x45, INPUT_KEY_E }, { 0x46, INPUT_KEY_F },
|
||||
{ 0x47, INPUT_KEY_G }, { 0x48, INPUT_KEY_H }, { 0x49, INPUT_KEY_I },
|
||||
{ 0x4A, INPUT_KEY_J }, { 0x4B, INPUT_KEY_K }, { 0x4C, INPUT_KEY_L },
|
||||
{ 0x4D, INPUT_KEY_M }, { 0x4E, INPUT_KEY_N }, { 0x4F, INPUT_KEY_O },
|
||||
{ 0x50, INPUT_KEY_P }, { 0x51, INPUT_KEY_Q }, { 0x52, INPUT_KEY_R },
|
||||
{ 0x53, INPUT_KEY_S }, { 0x54, INPUT_KEY_T }, { 0x55, INPUT_KEY_U },
|
||||
{ 0x56, INPUT_KEY_V }, { 0x57, INPUT_KEY_W }, { 0x58, INPUT_KEY_X },
|
||||
{ 0x59, INPUT_KEY_Y }, { 0x5A, INPUT_KEY_Z },
|
||||
|
||||
// Numbers
|
||||
{ 0x31, 0x02, false }, { 0x32, 0x03, false }, { 0x33, 0x04, false },
|
||||
{ 0x34, 0x05, false }, { 0x35, 0x06, false }, { 0x36, 0x07, false },
|
||||
{ 0x37, 0x08, false }, { 0x38, 0x09, false }, { 0x39, 0x0A, false },
|
||||
{ 0x30, 0x0B, false },
|
||||
{ 0x31, INPUT_KEY_1 }, { 0x32, INPUT_KEY_2 }, { 0x33, INPUT_KEY_3 },
|
||||
{ 0x34, INPUT_KEY_4 }, { 0x35, INPUT_KEY_5 }, { 0x36, INPUT_KEY_6 },
|
||||
{ 0x37, INPUT_KEY_7 }, { 0x38, INPUT_KEY_8 }, { 0x39, INPUT_KEY_9 },
|
||||
{ 0x30, INPUT_KEY_0 },
|
||||
|
||||
// Arrows (Extended)
|
||||
{ 0x26, 0x48, true }, // VK_UP
|
||||
{ 0x28, 0x50, true }, // VK_DOWN
|
||||
{ 0x25, 0x4B, true }, // VK_LEFT
|
||||
{ 0x27, 0x4D, true }, // VK_RIGHT
|
||||
// Arrows
|
||||
{ 0x26, INPUT_KEY_UP }, { 0x28, INPUT_KEY_DOWN },
|
||||
{ 0x25, INPUT_KEY_LEFT }, { 0x27, INPUT_KEY_RIGHT },
|
||||
|
||||
// Controls
|
||||
{ 0x1B, 0x01, false }, // ESC
|
||||
{ 0x0D, 0x1C, false }, // ENTER
|
||||
{ 0x20, 0x39, false }, // SPACE
|
||||
{ 0x11, 0x1D, false }, // CTRL (Generic)
|
||||
{ 0x10, 0x2A, false }, // SHIFT (Generic)
|
||||
{ 0x12, 0x38, false }, // ALT (Generic)
|
||||
{ 0x08, 0x0E, false }, // BACKSPACE
|
||||
{ 0x09, 0x0F, false }, // TAB
|
||||
{ 0x1B, INPUT_KEY_ESCAPE }, { 0x0D, INPUT_KEY_ENTER },
|
||||
{ 0x20, INPUT_KEY_SPACE },
|
||||
{ 0x08, INPUT_KEY_BACKSPACE }, { 0x09, INPUT_KEY_TAB },
|
||||
|
||||
// Function Keys
|
||||
{ 0x70, 0x3B, false }, { 0x71, 0x3C, false }, { 0x72, 0x3D, false },
|
||||
{ 0x73, 0x3E, false }, { 0x74, 0x3F, false }, { 0x75, 0x40, false },
|
||||
{ 0x76, 0x41, false }, { 0x77, 0x42, false }, { 0x78, 0x43, false },
|
||||
{ 0x79, 0x44, false }, { 0x7A, 0x57, false }, { 0x7B, 0x58, false },
|
||||
{ 0x70, INPUT_KEY_F1 }, { 0x71, INPUT_KEY_F2 }, { 0x72, INPUT_KEY_F3 },
|
||||
{ 0x73, INPUT_KEY_F4 }, { 0x74, INPUT_KEY_F5 }, { 0x75, INPUT_KEY_F6 },
|
||||
{ 0x76, INPUT_KEY_F7 }, { 0x77, INPUT_KEY_F8 }, { 0x78, INPUT_KEY_F9 },
|
||||
{ 0x79, INPUT_KEY_F10 }, { 0x7A, INPUT_KEY_F11 }, { 0x7B, INPUT_KEY_F12 },
|
||||
|
||||
// Symbols
|
||||
{ 0xBD, 0x0C, false }, // MINUS '-'
|
||||
{ 0xBB, 0x0D, false }, // EQUALS '='
|
||||
{ 0xBC, 0x33, false }, // COMMA ','
|
||||
{ 0xBE, 0x34, false }, // PERIOD '.'
|
||||
{ 0xBD, INPUT_KEY_MINUS }, { 0xBB, INPUT_KEY_EQUAL },
|
||||
{ 0xBC, INPUT_KEY_COMMA }, { 0xBE, INPUT_KEY_PERIOD },
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(vk_to_sc)/sizeof(vk_to_sc[0]); ++i) {
|
||||
if (vk_to_sc[i].vk == vKey) {
|
||||
// Check the hardware state array via our HAL helper
|
||||
if (SysKbIsKeyDown(vk_to_sc[i].sc, vk_to_sc[i].ext)) {
|
||||
for (size_t i = 0; i < sizeof(vk_to_key) / sizeof(vk_to_key[0]); ++i) {
|
||||
if (vk_to_key[i].vk == vKey) {
|
||||
if (SysKbIsKeyDown(vk_to_key[i].key))
|
||||
return (SHORT)0x8000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -668,7 +667,7 @@ __declspec(dllexport) BOOL ReadFile(HANDLE hFile, void* buf, DWORD toRead,
|
||||
uint32_t s = SysReadFile(HANDLE_TO_KH(hFile), buf, (size_t)toRead, &got);
|
||||
if (bytesRead) *bytesRead = (DWORD)got;
|
||||
|
||||
// Harden callers that accidentally look past *bytesRead. EOF/short reads
|
||||
// Harden callers that accidentally look past *bytesRead. EOF/short reads
|
||||
// are legal for files, but consuming stale stack/heap bytes after them makes
|
||||
// the failure mode look like random game-data corruption.
|
||||
if (got < (size_t)toRead)
|
||||
@@ -899,13 +898,13 @@ __declspec(dllexport) HANDLE LoadLibraryA(const char* lpLibFileName) {
|
||||
}
|
||||
|
||||
// Minimal GetProcAddress for code that probes kernel32 functions already present
|
||||
// in this win32.dll image. Full dynamic DLL loading remains a kernel-loader job.
|
||||
// in this win32.dll image. Full dynamic DLL loading remains a kernel-loader job.
|
||||
__declspec(dllexport) BOOL FreeLibrary(HANDLE hLibModule);
|
||||
__declspec(dllexport) void Sleep(DWORD dwMilliseconds);
|
||||
__declspec(dllexport) void* GetProcAddress(HANDLE hModule, const char* lpProcName) {
|
||||
if (hModule != WIN32_HMODULE_WIN32 || !lpProcName) { gLastError = 127; return NULL; }
|
||||
|
||||
// Ordinal probes are represented as small integer pointers. Do not treat
|
||||
// Ordinal probes are represented as small integer pointers. Do not treat
|
||||
// them as strings while debugging misses.
|
||||
if ((uintptr_t)lpProcName < 0x10000) {
|
||||
KiDbgWriteA("GetProcAddress ordinal miss\n");
|
||||
@@ -1116,7 +1115,7 @@ __declspec(dllexport) BOOL CreateProcessA(
|
||||
}
|
||||
|
||||
uint32_t kh = 0;
|
||||
// Call the syscall.dll stub. The kernel snapshots the current CWD into
|
||||
// Call the syscall.dll stub. The kernel snapshots the current CWD into
|
||||
// the child process, so the temporary lpCurrentDirectory switch can be
|
||||
// restored immediately after creation.
|
||||
uint32_t s = K32CreateProcessNative(translatedPath, &kh, cmdline);
|
||||
@@ -1469,11 +1468,11 @@ __declspec(dllexport) BOOL SetCurrentDirectoryA(const char* lpPathName) {
|
||||
|
||||
__declspec(dllexport) DWORD GetCurrentDirectoryA(DWORD nBufferLength, char* lpBuffer) {
|
||||
if (!lpBuffer || nBufferLength == 0) {
|
||||
// Return required size (including NUL). Max CWD is 512 bytes + "C:\\".
|
||||
// Return required size (including NUL). Max CWD is 512 bytes + "C:\\".
|
||||
return 515;
|
||||
}
|
||||
|
||||
// Kernel returns native "N:/path". Present it as a Win32 drive letter.
|
||||
// Kernel returns native "N:/path". Present it as a Win32 drive letter.
|
||||
char raw[512];
|
||||
uint32_t s = K32GetCwdNative(raw, sizeof(raw), NULL);
|
||||
if (s != 0) { gLastError = 1; return 0; }
|
||||
|
||||
@@ -1,94 +1,94 @@
|
||||
; syscall_nr.inc
|
||||
|
||||
SYS_EXIT_PROCESS EQU 0
|
||||
SYS_EXIT_THREAD EQU 1
|
||||
SYS_CREATE_PROCESS EQU 2
|
||||
SYS_WAIT_FOR_PROCESS EQU 3
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 4
|
||||
SYS_KILL_PROCESS EQU 5
|
||||
SYS_GET_PROCESS_LIST EQU 6
|
||||
SYS_GET_PROCESS_PID EQU 7
|
||||
SYS_CREATE_THREAD EQU 8
|
||||
SYS_WAIT_THREAD EQU 9
|
||||
SYS_GET_CURRENT_TID EQU 10
|
||||
SYS_GET_CURRENT_PID EQU 11
|
||||
SYS_SET_THREAD_PRIORITY EQU 12
|
||||
SYS_YIELD EQU 13
|
||||
SYS_SLEEP EQU 14
|
||||
SYS_SET_USER_APC_DISPATCHER EQU 15
|
||||
SYS_APC_RETURN EQU 16
|
||||
SYS_ALLOC EQU 17
|
||||
SYS_FREE EQU 18
|
||||
SYS_REALLOC EQU 19
|
||||
SYS_CLOSE_HANDLE EQU 20
|
||||
SYS_MUTEX_CREATE EQU 21
|
||||
SYS_MUTEX_ACQUIRE EQU 22
|
||||
SYS_MUTEX_TRY_ACQUIRE EQU 23
|
||||
SYS_MUTEX_RELEASE EQU 24
|
||||
SYS_SEM_CREATE EQU 25
|
||||
SYS_SEM_WAIT EQU 26
|
||||
SYS_SEM_TRY_WAIT EQU 27
|
||||
SYS_SEM_SIGNAL EQU 28
|
||||
SYS_EVENT_CREATE EQU 29
|
||||
SYS_EVENT_SIGNAL EQU 30
|
||||
SYS_EVENT_CLEAR EQU 31
|
||||
SYS_EVENT_WAIT EQU 32
|
||||
SYS_QUEUE_CREATE EQU 33
|
||||
SYS_QUEUE_SEND EQU 34
|
||||
SYS_QUEUE_RECV EQU 35
|
||||
SYS_PUBLISH_QUEUE EQU 36
|
||||
SYS_OPEN_NAMED_QUEUE EQU 37
|
||||
SYS_QUEUE_DUPLICATE EQU 38
|
||||
SYS_NAMED_QUEUE_OWNER_PID EQU 39
|
||||
SYS_OPEN_FILE EQU 40
|
||||
SYS_CREATE_FILE EQU 41
|
||||
SYS_READ_FILE EQU 42
|
||||
SYS_WRITE_FILE EQU 43
|
||||
SYS_READ_FILE_ASYNC EQU 44
|
||||
SYS_WRITE_FILE_ASYNC EQU 45
|
||||
SYS_CANCEL_IO EQU 46
|
||||
SYS_SEEK_FILE EQU 47
|
||||
SYS_GET_FILE_POS EQU 48
|
||||
SYS_GET_FILE_SIZE EQU 49
|
||||
SYS_TRUNCATE_FILE EQU 50
|
||||
SYS_DELETE_FILE EQU 51
|
||||
SYS_RENAME_FILE EQU 52
|
||||
SYS_OPEN_DIR EQU 53
|
||||
SYS_READ_DIR EQU 54
|
||||
SYS_CREATE_DIR EQU 55
|
||||
SYS_REMOVE_DIR EQU 56
|
||||
SYS_SET_CWD EQU 57
|
||||
SYS_GET_CWD EQU 58
|
||||
SYS_WRITE_CONSOLE EQU 59
|
||||
SYS_SCREEN_BLIT EQU 60
|
||||
SYS_SCREEN_CLEAR EQU 61
|
||||
SYS_SCREEN_GET_SIZE EQU 62
|
||||
SYS_SCREEN_PUT_CHAR EQU 63
|
||||
SYS_KB_POLL EQU 64
|
||||
SYS_KB_IS_KEY_DOWN EQU 65
|
||||
SYS_KB_READ_CHAR EQU 66
|
||||
SYS_KB_READ_SCANCODE EQU 67
|
||||
SYS_KB_GET_MODIFIERS EQU 68
|
||||
SYS_MOUSE_POLL EQU 69
|
||||
SYS_MOUSE_READ EQU 70
|
||||
SYS_MOUSE_GET_POS EQU 71
|
||||
SYS_GET_TICK EQU 72
|
||||
SYS_DEBUG_PRINT EQU 73
|
||||
SYS_QUERY_TRAP_FRAME EQU 74
|
||||
SYS_SOCKET EQU 75
|
||||
SYS_BIND EQU 76
|
||||
SYS_LISTEN EQU 77
|
||||
SYS_ACCEPT EQU 78
|
||||
SYS_CONNECT EQU 79
|
||||
SYS_SEND EQU 80
|
||||
SYS_RECV EQU 81
|
||||
SYS_SHUTDOWN EQU 82
|
||||
SYS_SEND_TO EQU 83
|
||||
SYS_RECV_FROM EQU 84
|
||||
SYS_RESOLVE_HOST EQU 85
|
||||
SYS_SET_SOCKET_OPTION EQU 86
|
||||
SYS_GET_SOCKET_OPTION EQU 87
|
||||
SYS_POLL EQU 88
|
||||
SYS_GET_MEMORY_STATUS EQU 89
|
||||
SYS_EXIT_PROCESS EQU 0
|
||||
SYS_EXIT_THREAD EQU 1
|
||||
SYS_CREATE_PROCESS EQU 2
|
||||
SYS_WAIT_FOR_PROCESS EQU 3
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 4
|
||||
SYS_KILL_PROCESS EQU 5
|
||||
SYS_GET_PROCESS_LIST EQU 6
|
||||
SYS_GET_PROCESS_PID EQU 7
|
||||
SYS_CREATE_THREAD EQU 8
|
||||
SYS_WAIT_THREAD EQU 9
|
||||
SYS_GET_CURRENT_TID EQU 10
|
||||
SYS_GET_CURRENT_PID EQU 11
|
||||
SYS_SET_THREAD_PRIORITY EQU 12
|
||||
SYS_YIELD EQU 13
|
||||
SYS_SLEEP EQU 14
|
||||
SYS_SET_USER_APC_DISPATCHER EQU 15
|
||||
SYS_APC_RETURN EQU 16
|
||||
SYS_ALLOC EQU 17
|
||||
SYS_FREE EQU 18
|
||||
SYS_REALLOC EQU 19
|
||||
SYS_CLOSE_HANDLE EQU 20
|
||||
SYS_MUTEX_CREATE EQU 21
|
||||
SYS_MUTEX_ACQUIRE EQU 22
|
||||
SYS_MUTEX_TRY_ACQUIRE EQU 23
|
||||
SYS_MUTEX_RELEASE EQU 24
|
||||
SYS_SEM_CREATE EQU 25
|
||||
SYS_SEM_WAIT EQU 26
|
||||
SYS_SEM_TRY_WAIT EQU 27
|
||||
SYS_SEM_SIGNAL EQU 28
|
||||
SYS_EVENT_CREATE EQU 29
|
||||
SYS_EVENT_SIGNAL EQU 30
|
||||
SYS_EVENT_CLEAR EQU 31
|
||||
SYS_EVENT_WAIT EQU 32
|
||||
SYS_QUEUE_CREATE EQU 33
|
||||
SYS_QUEUE_SEND EQU 34
|
||||
SYS_QUEUE_RECV EQU 35
|
||||
SYS_PUBLISH_QUEUE EQU 36
|
||||
SYS_OPEN_NAMED_QUEUE EQU 37
|
||||
SYS_QUEUE_DUPLICATE EQU 38
|
||||
SYS_NAMED_QUEUE_OWNER_PID EQU 39
|
||||
SYS_OPEN_FILE EQU 40
|
||||
SYS_CREATE_FILE EQU 41
|
||||
SYS_READ_FILE EQU 42
|
||||
SYS_WRITE_FILE EQU 43
|
||||
SYS_READ_FILE_ASYNC EQU 44
|
||||
SYS_WRITE_FILE_ASYNC EQU 45
|
||||
SYS_CANCEL_IO EQU 46
|
||||
SYS_SEEK_FILE EQU 47
|
||||
SYS_GET_FILE_POS EQU 48
|
||||
SYS_GET_FILE_SIZE EQU 49
|
||||
SYS_TRUNCATE_FILE EQU 50
|
||||
SYS_DELETE_FILE EQU 51
|
||||
SYS_RENAME_FILE EQU 52
|
||||
SYS_OPEN_DIR EQU 53
|
||||
SYS_READ_DIR EQU 54
|
||||
SYS_CREATE_DIR EQU 55
|
||||
SYS_REMOVE_DIR EQU 56
|
||||
SYS_SET_CWD EQU 57
|
||||
SYS_GET_CWD EQU 58
|
||||
SYS_WRITE_CONSOLE EQU 59
|
||||
SYS_SCREEN_BLIT EQU 60
|
||||
SYS_SCREEN_CLEAR EQU 61
|
||||
SYS_SCREEN_GET_SIZE EQU 62
|
||||
SYS_SCREEN_PUT_CHAR EQU 63
|
||||
SYS_KB_POLL EQU 64
|
||||
SYS_KB_IS_KEY_DOWN EQU 65
|
||||
SYS_KB_READ_CHAR EQU 66
|
||||
SYS_KB_READ_KEY EQU 67
|
||||
SYS_KB_GET_MODIFIERS EQU 68
|
||||
SYS_MOUSE_POLL EQU 69
|
||||
SYS_MOUSE_READ EQU 70
|
||||
SYS_MOUSE_GET_POS EQU 71
|
||||
SYS_GET_TICK EQU 72
|
||||
SYS_DEBUG_PRINT EQU 73
|
||||
SYS_QUERY_TRAP_FRAME EQU 74
|
||||
SYS_SOCKET EQU 75
|
||||
SYS_BIND EQU 76
|
||||
SYS_LISTEN EQU 77
|
||||
SYS_ACCEPT EQU 78
|
||||
SYS_CONNECT EQU 79
|
||||
SYS_SEND EQU 80
|
||||
SYS_RECV EQU 81
|
||||
SYS_SHUTDOWN EQU 82
|
||||
SYS_SEND_TO EQU 83
|
||||
SYS_RECV_FROM EQU 84
|
||||
SYS_RESOLVE_HOST EQU 85
|
||||
SYS_SET_SOCKET_OPTION EQU 86
|
||||
SYS_GET_SOCKET_OPTION EQU 87
|
||||
SYS_POLL EQU 88
|
||||
SYS_GET_MEMORY_STATUS EQU 89
|
||||
|
||||
SYS_MAX EQU 90
|
||||
SYS_MAX EQU 90
|
||||
@@ -83,8 +83,8 @@ SYSCALL_STUB2 ApcReturn, SYS_APC_RETURN
|
||||
; ---------------------------------------------------------------------------
|
||||
PUBLIC SysUserApcDispatcher
|
||||
SysUserApcDispatcher PROC EXPORT
|
||||
; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no
|
||||
; return address because this is an IRET redirection. Preserve RBX because
|
||||
; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no
|
||||
; return address because this is an IRET redirection. Preserve RBX because
|
||||
; the original user context resumes after SysApcReturn.
|
||||
push rbx
|
||||
lea rbx, [rsp + 8] ; original injected RSP = frame pointer
|
||||
@@ -183,7 +183,7 @@ SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR
|
||||
SYSCALL_STUB2 KbPoll, SYS_KB_POLL
|
||||
SYSCALL_STUB2 KbIsKeyDown, SYS_KB_IS_KEY_DOWN
|
||||
SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR
|
||||
SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE
|
||||
SYSCALL_STUB2 KbReadKey, SYS_KB_READ_KEY
|
||||
SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS
|
||||
|
||||
SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL
|
||||
|
||||
Reference in new issue
Block a user