clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.

This commit is contained in:
maksw committed 2026-10-12 18:17:43 +02:00
1 parent 899225f551
commit c0ad63c27f
226 files changed
+6562 -4147

No files matched your search

+39 -38
View File
@@ -1,5 +1,6 @@
// Kernel debugging and bugcheck support. This file owns panic reporting, process fault reporting, and diagnostic queries.
#include <ntlite/atomic.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
@@ -36,7 +37,7 @@ static char* gDebugLogBuffer;
static size_t gDebugLogSize;
static size_t gDebugLogWrite;
static size_t gDebugLogUsed;
static volatile long gDebugLogFlushing;
static volatile int32_t gDebugLogFlushing;
// Appends bytes to the in-memory debug log while its lock is held.
static void KiDebugLogAppendLocked(const char* text, size_t len) {
@@ -97,13 +98,13 @@ static void KiOutputVPrintf(uint32_t stream, uint32_t flags,
KiOutputWrite(stream, flags, foreground, background, line, length);
}
static volatile long gPanicInProgress;
static volatile int32_t gPanicInProgress;
static volatile uintptr_t gPanicOwnerToken;
static volatile long gPanicStoppedCpuCount;
static volatile int32_t gPanicStoppedCpuCount;
// Permanently stops a secondary processor that entered an active panic.
static _Noreturn void KiPanicSecondaryHalt(void) {
_InterlockedIncrement(&gPanicStoppedCpuCount);
NtlAtomicIncrement32(&gPanicStoppedCpuCount);
KeStopProcessor();
}
@@ -119,12 +120,12 @@ static uintptr_t KiPanicCurrentToken(void) {
}
// Returns whether a fatal report is active.
static int KiPanicIsActive(void) {
return _InterlockedCompareExchange((volatile long*)&gPanicInProgress, 0, 0) != 0;
static bool KiPanicIsActive(void) {
return NtlAtomicLoad32(&gPanicInProgress) != 0;
}
// Returns whether the current processor owns the active fatal report.
static int KiPanicCurrentCpuOwnsReport(void) {
static bool KiPanicCurrentCpuOwnsReport(void) {
uintptr_t token = KiPanicCurrentToken();
return token != 0 && gPanicOwnerToken == token;
}
@@ -133,7 +134,7 @@ static int KiPanicCurrentCpuOwnsReport(void) {
static void KiBeginFatalReport(void) {
(void)KeDisableInterrupts();
uintptr_t token = KiPanicCurrentToken();
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) == 0) {
if (NtlAtomicCompareExchange32(&gPanicInProgress, 1, 0) == 0) {
gPanicOwnerToken = token;
return;
}
@@ -142,14 +143,14 @@ static void KiBeginFatalReport(void) {
}
// Handles NMI-based panic stops and TLB shootdowns.
__declspec(dllexport) int KeHandleNmiIpi(void) {
__declspec(dllexport) bool KeHandleNmiIpi(void) {
if (KiPanicIsActive())
KiPanicSecondaryHalt();
if (MmPteHandleShootdownNmi())
return 1;
return true;
return 0;
return false;
}
// Initializes debug logging and initial output subscriptions.
@@ -208,7 +209,7 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) {
if (!panic) {
uintptr_t lockFlags = KeAcquireSpinlock(&gDebugPrintLock);
if (!_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 0, 0))
if (!NtlAtomicLoad32(&gDebugLogFlushing))
KiDebugLogAppendLocked(line, length);
KeReleaseSpinlock(&gDebugPrintLock, lockFlags);
}
@@ -249,7 +250,7 @@ KSTATUS KeFlushDebugLogToSystemRoot(const char* relativePath) {
if (!KeCanWait())
return NTLSTATUS_INVALID_IRQL;
if (_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 1, 0) != 0)
if (NtlAtomicCompareExchange32(&gDebugLogFlushing, 1, 0) != 0)
return NTLSTATUS_PENDING;
size_t used;
@@ -264,7 +265,7 @@ KSTATUS KeFlushDebugLogToSystemRoot(const char* relativePath) {
FILE_OBJECT* file = (FILE_OBJECT*)0;
KSTATUS st = KeCreateSystemRootFile(relativePath, &file);
if (!KSUCCESS(st)) {
_InterlockedExchange((volatile long*)&gDebugLogFlushing, 0);
NtlAtomicExchange32(&gDebugLogFlushing, 0);
return st;
}
@@ -292,7 +293,7 @@ KSTATUS KeFlushDebugLogToSystemRoot(const char* relativePath) {
st = IoFlushFile(file);
IoCloseFile(file);
_InterlockedExchange((volatile long*)&gDebugLogFlushing, 0);
NtlAtomicExchange32(&gDebugLogFlushing, 0);
return st;
}
@@ -318,7 +319,7 @@ static void KiPanicPrintf(const char* format, ...) {
}
// Stops the system after reporting a fatal kernel error.
__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...) {
__declspec(dllexport) _Noreturn void KePanic(int32_t code, const char* fmt, ...) {
KiBeginFatalReport();
// Stop every other CPU before writing the final report. Panic-safe endpoints
@@ -443,9 +444,9 @@ static void KiPrintAddressValue(PROCESS* proc, uintptr_t addr) {
}
// Checks whether a kernel virtual range is mapped before diagnostic reads.
static int KiKernelRangeReadable(uintptr_t addr, size_t size) {
if (!addr || size == 0) return 0;
if (size - 1u > (size_t)(UINTPTR_MAX - addr)) return 0;
static bool KiKernelRangeReadable(uintptr_t addr, size_t size) {
if (!addr || size == 0) return false;
if (size - 1u > (size_t)(UINTPTR_MAX - addr)) return false;
uintptr_t start = addr & PAGE_MASK;
uintptr_t last = (addr + size - 1u) & PAGE_MASK;
@@ -454,41 +455,41 @@ static int KiKernelRangeReadable(uintptr_t addr, size_t size) {
PHYSICAL_ADDRESS phys = 0;
uint64_t flags = 0;
if (!KSUCCESS(MmPteQueryPageFor(MmPteQueryDebug, page, &phys, &flags)))
return 0;
return false;
if ((flags & PAGE_PRESENT) == 0)
return 0;
return false;
if (page == last)
break;
if (page > UINTPTR_MAX - PAGE_SIZE)
return 0;
return false;
}
return 1;
return true;
}
// Reads diagnostic memory from either user space or a mapped kernel range.
static int KiReadDiagnosticMemory(uintptr_t addr, void* out, size_t size) {
if (!out || !addr || size == 0) return 0;
static bool KiReadDiagnosticMemory(uintptr_t addr, void* out, size_t size) {
if (!out || !addr || size == 0) return false;
if (addr >= KERNEL_BASE) {
if (!KiKernelRangeReadable(addr, size))
return 0;
return false;
memcpy(out, (const void*)addr, size);
return 1;
return true;
}
if (!KSUCCESS(MmProbeUserRead((const void*)addr, size)))
return 0;
return false;
memcpy(out, (const void*)addr, size);
return 1;
return true;
}
// Reads one diagnostic uint64_t.
static int KiUserReadU64(uintptr_t addr, uint64_t* out) {
static bool KiUserReadU64(uintptr_t addr, uint64_t* out) {
return KiReadDiagnosticMemory(addr, out, sizeof(*out));
}
// Reads one diagnostic byte.
static int KiUserReadU8(uintptr_t addr, uint8_t* out) {
static bool KiUserReadU8(uintptr_t addr, uint8_t* out) {
return KiReadDiagnosticMemory(addr, out, sizeof(*out));
}
@@ -518,7 +519,7 @@ static void KiDumpBytes(PROCESS* proc, const char* label, uintptr_t center) {
}
// Reads one diagnostic int32_t.
static int KiUserReadI32(uintptr_t addr, int32_t* out) {
static bool KiUserReadI32(uintptr_t addr, int32_t* out) {
return KiReadDiagnosticMemory(addr, out, sizeof(*out));
}
@@ -585,11 +586,11 @@ static void KiDumpModules(PROCESS* proc) {
#if 0
// Returns whether a range is inside the current kernel stack.
static int KiKernelStackContains(const THREAD* thread, uintptr_t addr, size_t size) {
static bool KiKernelStackContains(const THREAD* thread, uintptr_t addr, size_t size) {
if (!thread || !thread->KernelStackBase || !thread->KernelStackTop || !addr || size == 0)
return 0;
return false;
if (size - 1u > (size_t)(UINTPTR_MAX - addr))
return 0;
return false;
uintptr_t base = (uintptr_t)thread->KernelStackBase;
uintptr_t top = thread->KernelStackTop;
@@ -598,9 +599,9 @@ static int KiKernelStackContains(const THREAD* thread, uintptr_t addr, size_t si
}
// Returns whether the fault frame is using the current kernel stack.
static int KiFaultFrameOnKernelStack(const THREAD* thread, const KFAULT_FRAME* f) {
static bool KiFaultFrameOnKernelStack(const THREAD* thread, const KFAULT_FRAME* f) {
if (!f || !thread)
return 0;
return false;
return KiKernelStackContains(thread, (uintptr_t)f->Rsp, sizeof(uint64_t));
}
@@ -896,7 +897,7 @@ __declspec(dllexport) KSTATUS KeFaultDispatchFrame(KFAULT_FRAME* frame) {
// The asm stubs collect the CPU exception frame values and call here.
// KeFaultDispatchFrame owns the mode split and default unhandled policy.
__declspec(dllexport) _Noreturn void KeFaultDispatch(int vector, uintptr_t rip,
__declspec(dllexport) _Noreturn void KeFaultDispatch(uint32_t vector, uintptr_t rip,
uintptr_t errCode, uintptr_t cr2,
uintptr_t cs) {
KFAULT_FRAME frame;