replace the VHD/diskpart disk image pipeline with a directory-based vvfat root, we'll see when it breaks, fix /O2, add an all_tests, generalize the fat32 driver into a fat 16+32 driver, change policy on volume drivers, collapse KCPU's fields into a single atomic KE_CPU_STATE state machine, move scheduler ticking to per-CPU LAPIC timers, gate verbose SMP topology logging behind selftest diagnostics and add SMP pool-checkpoint validation around AP admission, add checked intrusive list helpers behind a new KE_DEBUG_LIST_CHECKS flag, add ObInitializeObjectHeader/ObTryReferenceObject, add waitable display clock objects and a SYS_OPEN_DISPLAY_CLOCK syscall for vsync-style waits, refactor kernel input into a per-queue KE_INPUT_CONTEXT with its own key/mouse ring buffers and DPC-driven key repeat, add KeInputQueuePeekEvent/ReadEvent/WaitKey and a SYS_QUERY_GLOBAL_INPUT_STATE syscall, split the kernel pool allocator out of mm_virt, new video files!

This commit is contained in:
maksw committed 2026-07-12 00:10:21 +02:00
1 parent 485a6bbfe7
commit 8b254f84f4
74 files changed
+4488 -2503

No files matched your search

+105 -23
View File
@@ -616,6 +616,9 @@ static KSTATUS KiHandleToWaitEvent(PROCESS* proc, uint32_t handle, EVENT** event
case ObjectTypeTimer:
event = KeTimerWaitEvent(CONTAINING_RECORD(obj, KTIMER, Header));
break;
case ObjectTypeDisplayClock:
event = KeDisplayClockWaitEvent((DISPLAY_CLOCK_OBJECT*)obj);
break;
default:
ObDereferenceObject(obj);
return NTLSTATUS_NOT_SUPPORTED;
@@ -2189,6 +2192,35 @@ static uint64_t SyscallStatFile(uint64_t a0, uint64_t a1, uint64_t a2,
return CopyToUser(req.StatOut, &stat, sizeof(stat));
}
// SYS_OPEN_DISPLAY_CLOCK a0=*SYS_OPEN_DISPLAY_CLOCK_REQUEST.
static uint64_t SyscallOpenDisplayClock(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
SYS_OPEN_DISPLAY_CLOCK_REQUEST req;
KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req));
if (!KSUCCESS(s)) return s;
if (req.Size != sizeof(req) || req.Flags != SYS_DISPLAY_CLOCK_FLAG_NONE || !req.HandleOut)
return NTLSTATUS_INVALID_PARAMETER;
DISPLAY_CLOCK_OBJECT* clock = (DISPLAY_CLOCK_OBJECT*)0;
s = KeDisplayOpenClock(req.PeriodMilliseconds, &clock);
if (!KSUCCESS(s))
return s;
uint32_t handle = 0;
s = KiAllocHandleForCurrentWithRights(&clock->Header, HANDLE_RIGHT_WAIT | HANDLE_RIGHT_QUERY, &handle);
if (!KSUCCESS(s))
return s;
s = KiCopyHandleToUser((uint64_t)(uintptr_t)req.HandleOut, handle);
if (!KSUCCESS(s)) {
PROCESS* proc = KeGetCurrentProcess();
if (proc) KeCloseHandle(proc, handle);
}
return s;
}
// SYS_CREATE_SURFACE a0=*SYS_CREATE_SURFACE_REQUEST.
static uint64_t SyscallCreateSurface(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -2569,13 +2601,15 @@ static uint64_t SyscallFillConsoleAttribute(uint64_t a0, uint64_t a1, uint64_t a
return s;
}
// Validates a user input queue handle. Handle zero means the default queue.
static KSTATUS KiValidateInputQueueHandle(uint32_t handle) {
// References a user input queue handle. Handle zero selects the default context.
static KSTATUS KiReferenceInputQueueHandle(uint32_t handle, INPUT_QUEUE** queueOut) {
if (!queueOut) return NTLSTATUS_INVALID_PARAMETER;
*queueOut = (INPUT_QUEUE*)0;
if (handle == 0) return NTLSTATUS_SUCCESS;
OBJECT* obj = KiHandleToObject(handle, ObjectTypeInputQueue, HANDLE_RIGHT_READ);
if (!obj) return NTLSTATUS_INVALID_HANDLE;
ObDereferenceObject(obj);
OBJECT* object = KiHandleToObject(handle, ObjectTypeInputQueue, HANDLE_RIGHT_READ);
if (!object) return NTLSTATUS_INVALID_HANDLE;
*queueOut = CONTAINING_RECORD(object, INPUT_QUEUE, Header);
return NTLSTATUS_SUCCESS;
}
@@ -2592,7 +2626,7 @@ static KSTATUS KiCopyInputEventRequest(uint64_t arg, SYS_INPUT_EVENT_REQUEST* re
if (req->Size != sizeof(*req)) return NTLSTATUS_INVALID_PARAMETER;
if (req->Flags != SYS_INPUT_EVENT_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER;
if (!req->RecordOut) return NTLSTATUS_INVALID_PARAMETER;
return KiValidateInputQueueHandle(req->QueueHandle);
return NTLSTATUS_SUCCESS;
}
// SYS_POLL_KEYBOARD a0=*INPUT_KEY -> KSTATUS.
@@ -2658,6 +2692,22 @@ static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
return (uint64_t)KeInputGetModifiers();
}
// SYS_QUERY_GLOBAL_INPUT_STATE a0=*SYS_GLOBAL_INPUT_STATE -> KSTATUS.
static uint64_t SyscallQueryGlobalInputState(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
SYS_GLOBAL_INPUT_STATE state;
KSTATUS s = KiCopyUserRequest(a0, &state, sizeof(state));
if (!KSUCCESS(s)) return s;
if (state.Size != sizeof(state)) return NTLSTATUS_INVALID_PARAMETER;
if (state.Flags != SYS_GLOBAL_INPUT_STATE_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER;
s = KeInputQueryGlobalState(&state);
if (!KSUCCESS(s)) return s;
return CopyToUser((void*)(uintptr_t)a0, &state, sizeof(state));
}
// SYS_READ_INPUT_EVENT a0=*SYS_INPUT_EVENT_REQUEST -> KSTATUS.
static uint64_t SyscallKbReadInputEvent(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -2667,18 +2717,32 @@ static uint64_t SyscallKbReadInputEvent(uint64_t a0, uint64_t a1, uint64_t a2,
KSTATUS s = KiCopyInputEventRequest(a0, &req);
if (!KSUCCESS(s)) return s;
INPUT_QUEUE* queue = (INPUT_QUEUE*)0;
s = KiReferenceInputQueueHandle(req.QueueHandle, &queue);
if (!KSUCCESS(s)) return s;
INPUT_KEY_RECORD record;
for (;;) {
if (KeInputReadEvent(&record))
return KiCopyInputRecordToUser(req.RecordOut, &record);
bool available = queue ? KeInputQueueReadEvent(queue, &record)
: KeInputReadEvent(&record);
if (available) {
s = KiCopyInputRecordToUser(req.RecordOut, &record);
break;
}
if (req.TimeoutMilliseconds == 0)
return NTLSTATUS_WOULD_BLOCK;
if (req.TimeoutMilliseconds == 0) {
s = NTLSTATUS_WOULD_BLOCK;
break;
}
s = KeInputWaitKey(0, req.TimeoutMilliseconds);
s = queue ? KeInputQueueWaitKey(queue, 0, req.TimeoutMilliseconds)
: KeInputWaitKey(0, req.TimeoutMilliseconds);
if (!KSUCCESS(s))
return s;
break;
}
if (queue) ObDereferenceObject(&queue->Header);
return s;
}
// SYS_PEEK_INPUT_EVENT a0=*SYS_INPUT_EVENT_REQUEST -> KSTATUS.
@@ -2690,18 +2754,32 @@ static uint64_t SyscallKbPeekInputEvent(uint64_t a0, uint64_t a1, uint64_t a2,
KSTATUS s = KiCopyInputEventRequest(a0, &req);
if (!KSUCCESS(s)) return s;
INPUT_QUEUE* queue = (INPUT_QUEUE*)0;
s = KiReferenceInputQueueHandle(req.QueueHandle, &queue);
if (!KSUCCESS(s)) return s;
INPUT_KEY_RECORD record;
for (;;) {
if (KeInputPeekEvent(&record))
return KiCopyInputRecordToUser(req.RecordOut, &record);
bool available = queue ? KeInputQueuePeekEvent(queue, &record)
: KeInputPeekEvent(&record);
if (available) {
s = KiCopyInputRecordToUser(req.RecordOut, &record);
break;
}
if (req.TimeoutMilliseconds == 0)
return NTLSTATUS_WOULD_BLOCK;
if (req.TimeoutMilliseconds == 0) {
s = NTLSTATUS_WOULD_BLOCK;
break;
}
s = KeInputWaitKey(0, req.TimeoutMilliseconds);
s = queue ? KeInputQueueWaitKey(queue, 0, req.TimeoutMilliseconds)
: KeInputWaitKey(0, req.TimeoutMilliseconds);
if (!KSUCCESS(s))
return s;
break;
}
if (queue) ObDereferenceObject(&queue->Header);
return s;
}
// SYS_PEEK_MOUSE a0=*INPUT_MOUSE_EVENT -> KSTATUS.
@@ -3345,7 +3423,8 @@ static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2,
for (int i = 0; i < NAMED_QUEUE_MAX; i++) {
if (KiNamedQueueNameEquals(&gNamedQueues[i], nameView)) {
q = gNamedQueues[i].Queue;
ObReferenceObject(&q->Header);
if (q && !ObTryReferenceObject(&q->Header))
q = (QUEUE*)0;
break;
}
}
@@ -5274,10 +5353,11 @@ static uint64_t SyscallQueryKernelStats(uint64_t a0, uint64_t a1, uint64_t a2,
SYS_CPU_STAT* out = &stats.Records[i];
out->CpuIndex = cpu->CpuIndex;
out->LapicId = cpu->LapicId;
if (cpu->Present) out->Flags |= SYS_CPU_FLAG_PRESENT;
if (cpu->Started) out->Flags |= SYS_CPU_FLAG_STARTED;
if (cpu->Parked) out->Flags |= SYS_CPU_FLAG_PARKED;
if (cpu->Online) out->Flags |= SYS_CPU_FLAG_ONLINE;
KE_CPU_STATE state = (KE_CPU_STATE)cpu->State;
if (state >= KeCpuPresent) out->Flags |= SYS_CPU_FLAG_PRESENT;
if (state >= KeCpuStarted) out->Flags |= SYS_CPU_FLAG_STARTED;
if (state == KeCpuParked) out->Flags |= SYS_CPU_FLAG_PARKED;
if (state == KeCpuOnline) out->Flags |= SYS_CPU_FLAG_ONLINE;
if (cpu->IsBsp) out->Flags |= SYS_CPU_FLAG_BSP;
if (cpu->IsPrimaryThread) out->Flags |= SYS_CPU_FLAG_PRIMARY;
out->CurrentTid = cpu->CurrentThread ? cpu->CurrentThread->ThreadId : 0;
@@ -5394,6 +5474,7 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
[SYS_CLEAR_SCREEN] = SyscallClearScreen,
[SYS_GET_SCREEN_SIZE] = SyscallGetScreenSize,
[SYS_QUERY_DISPLAY_INFO] = SyscallQueryDisplayInfo,
[SYS_OPEN_DISPLAY_CLOCK] = SyscallOpenDisplayClock,
[SYS_CREATE_SURFACE] = SyscallCreateSurface,
[SYS_MAP_SURFACE] = SyscallMapSurface,
[SYS_QUERY_SURFACE] = SyscallQuerySurface,
@@ -5405,6 +5486,7 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
[SYS_READ_KEYBOARD_CHAR] = SyscallKbReadChar,
[SYS_READ_KEY] = SyscallKbReadKey,
[SYS_GET_KEY_MODIFIERS] = SyscallKbGetModifiers,
[SYS_QUERY_GLOBAL_INPUT_STATE] = SyscallQueryGlobalInputState,
[SYS_OPEN_INPUT_QUEUE] = SyscallOpenInputQueue,
[SYS_READ_INPUT_EVENT] = SyscallKbReadInputEvent,
[SYS_PEEK_INPUT_EVENT] = SyscallKbPeekInputEvent,