completely redesign how user mode memory is allocated, fix a few smp and scheduler bugs, terminating a process now terminates the process, telemetry, optimize text editor, new font, new color scheme

This commit is contained in:
maksw committed 2026-06-09 18:02:28 +02:00
1 parent 27b31f62b6
commit 325149006c
45 files changed
+2091 -760

No files matched your search

+335 -111
View File
@@ -34,6 +34,7 @@
#include <stdbool.h>
#include <string.h>
#include <kernel/ke_thread.h>
#include <kernel/ke_cpu.h>
#include <kernel/ke_sched.h>
#include <kernel/ke_process.h>
#include <kernel/ke_mutex.h>
@@ -354,33 +355,147 @@ static uint64_t SyscallSetThreadPriority(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_ALLOC (8) a0 = size -> void*
// SYS_VM_* page-granular user virtual memory
// ---------------------------------------------------------------------------
static uint64_t SyscallAlloc(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;
if (!a0) return 0;
return (uint64_t)(uintptr_t)MmAllocateUserMemory((size_t)a0);
static KSTATUS KiVmProtectToPageFlags(uint32_t protect, uint64_t* flagsOut) {
if (!flagsOut) return STATUS_INVALID_PARAMETER;
switch (protect) {
case SYS_VM_NOACCESS:
*flagsOut = 0;
return STATUS_SUCCESS;
case SYS_VM_READ:
*flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_NX;
return STATUS_SUCCESS;
case SYS_VM_READWRITE:
*flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_WRITE | PAGE_NX;
return STATUS_SUCCESS;
case SYS_VM_EXECUTE:
case SYS_VM_EXECUTE_READ:
*flagsOut = PAGE_PRESENT | PAGE_USER;
return STATUS_SUCCESS;
case SYS_VM_EXECUTE_READWRITE:
*flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_WRITE;
return STATUS_SUCCESS;
default:
return STATUS_INVALID_PARAMETER;
}
}
// ---------------------------------------------------------------------------
// SYS_FREE a0 = ptr
// ---------------------------------------------------------------------------
static uint64_t SyscallFree(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;
if (a0) MmFreeUserMemory((void*)(uintptr_t)a0);
static uint32_t KiPageFlagsToVmProtect(uint64_t flags) {
if (!(flags & PAGE_PRESENT)) return SYS_VM_NOACCESS;
bool writable = (flags & PAGE_WRITE) != 0;
bool executable = (flags & PAGE_NX) == 0;
if (executable && writable) return SYS_VM_EXECUTE_READWRITE;
if (executable) return SYS_VM_EXECUTE_READ;
if (writable) return SYS_VM_READWRITE;
return SYS_VM_READ;
}
static uint64_t SyscallVmAlloc(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a5;
void* preferredBase = (void*)(uintptr_t)a0;
size_t pageCount = (size_t)a1;
uint32_t protect = (uint32_t)a2;
uint32_t flags = (uint32_t)a3;
void** baseOut = (void**)(uintptr_t)a4;
if (!pageCount || !baseOut) return STATUS_INVALID_PARAMETER;
if (pageCount > ((size_t)-1) / PAGE_SIZE) return STATUS_NO_MEMORY;
if (preferredBase || (flags & SYS_VM_FLAG_FIXED)) return STATUS_NOT_SUPPORTED;
uint64_t pageFlags = 0;
KSTATUS s = KiVmProtectToPageFlags(protect, &pageFlags);
if (!KSUCCESS(s)) return s;
PROCESS* process = KeGetCurrentProcess();
if (!process) return STATUS_FAILURE;
void* base = (void*)0;
s = MmCreateUserRegion(process, pageCount * PAGE_SIZE, PAGE_SIZE,
pageFlags ? pageFlags : (PAGE_PRESENT | PAGE_WRITE | PAGE_USER | PAGE_NX),
USER_REGION_ZERO,
UserRegionGeneric,
&base);
if (!KSUCCESS(s)) return s;
if (protect == SYS_VM_NOACCESS) {
s = MmProtectUserRegion(process, base, pageCount * PAGE_SIZE, 0);
if (!KSUCCESS(s)) {
MmDestroyUserRegion(process, base);
return s;
}
}
s = CopyToUser(baseOut, &base, sizeof(base));
if (!KSUCCESS(s)) {
MmDestroyUserRegion(process, base);
return s;
}
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// SYS_REALLOC (10) a0 = ptr, a1 = newSize -> void*
// ---------------------------------------------------------------------------
static uint64_t SyscallRealloc(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
static uint64_t SyscallVmFree(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;
PROCESS* process = KeGetCurrentProcess();
if (!process || !a0) return STATUS_INVALID_PARAMETER;
return MmDestroyUserRegion(process, (void*)(uintptr_t)a0);
}
static uint64_t SyscallVmProtect(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a4; (void)a5;
if (!a0 || !a1) return STATUS_INVALID_PARAMETER;
if ((size_t)a1 > ((size_t)-1) / PAGE_SIZE) return STATUS_NO_MEMORY;
uint64_t pageFlags = 0;
KSTATUS s = KiVmProtectToPageFlags((uint32_t)a2, &pageFlags);
if (!KSUCCESS(s)) return s;
PROCESS* process = KeGetCurrentProcess();
if (!process) return STATUS_FAILURE;
if (a3) {
void* regionBase = (void*)0;
size_t regionSize = 0;
uint64_t oldFlags = 0;
USER_REGION_TYPE type = UserRegionGeneric;
uint32_t regionFlags = 0;
s = MmQueryUserRegion(process, (void*)(uintptr_t)a0, &regionBase, &regionSize, &oldFlags, &type, &regionFlags);
if (!KSUCCESS(s)) return s;
uint32_t oldProtect = KiPageFlagsToVmProtect(oldFlags);
s = CopyToUser((void*)(uintptr_t)a3, &oldProtect, sizeof(oldProtect));
if (!KSUCCESS(s)) return s;
}
return MmProtectUserRegion(process, (void*)(uintptr_t)a0, (size_t)a1 * PAGE_SIZE, pageFlags);
}
static uint64_t SyscallVmQuery(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a2; (void)a3; (void)a4; (void)a5;
return (uint64_t)(uintptr_t)MmReallocateUserMemory(
(void*)(uintptr_t)a0, (size_t)a1);
if (!a0 || !a1) return STATUS_INVALID_PARAMETER;
PROCESS* process = KeGetCurrentProcess();
if (!process) return STATUS_FAILURE;
void* base = (void*)0;
size_t size = 0;
uint64_t pageFlags = 0;
USER_REGION_TYPE type = UserRegionGeneric;
uint32_t regionFlags = 0;
KSTATUS s = MmQueryUserRegion(process, (void*)(uintptr_t)a0, &base, &size, &pageFlags, &type, &regionFlags);
if (!KSUCCESS(s)) return s;
SYS_VM_REGION_INFO info;
info.Base = base;
info.PageCount = size / PAGE_SIZE;
info.Protect = KiPageFlagsToVmProtect(pageFlags);
info.Flags = regionFlags;
info.Type = (uint32_t)type;
info.OwnerPid = process->ProcessId;
return CopyToUser((void*)(uintptr_t)a1, &info, sizeof(info));
}
// ---------------------------------------------------------------------------
@@ -2565,6 +2680,99 @@ static uint64_t SyscallGetMemoryStatus(uint64_t a0, uint64_t a1, uint64_t a2,
return CopyToUser((void*)(uintptr_t)a0, &status, sizeof(status));
}
// ---------------------------------------------------------------------------
// SYS_QUERY_KERNEL_STATS a0=classId a1=buffer a2=bufferSize a3=*requiredSizeOut
// ---------------------------------------------------------------------------
static KSTATUS KiReturnKernelStats(uint64_t bufferArg, size_t bufferSize,
uint64_t requiredArg,
const void* src, size_t size) {
if (requiredArg) {
KSTATUS s = KiCopySizeToUser(requiredArg, size);
if (!KSUCCESS(s)) return s;
}
if (!bufferArg)
return STATUS_SUCCESS;
if (bufferSize < size)
return STATUS_BUFFER_TOO_SMALL;
return CopyToUser((void*)(uintptr_t)bufferArg, src, size);
}
static uint64_t SyscallQueryKernelStats(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a4; (void)a5;
switch ((uint32_t)a0) {
case SYS_KERNEL_STATS_SCHEDULER: {
KE_SCHED_STATS ks;
SYS_SCHEDULER_STATS us;
KeGetSchedulerStats(&ks);
memset(&us, 0, sizeof(us));
us.Ticks = ks.Ticks;
us.ContextSwitches = ks.ContextSwitches;
us.KeepCurrentDecisions = ks.KeepCurrentDecisions;
us.IdleSelections = ks.IdleSelections;
us.Demotions = ks.Demotions;
us.AgingPromotions = ks.AgingPromotions;
us.QuantumExpirations = ks.QuantumExpirations;
us.PriorityPreemptions = ks.PriorityPreemptions;
us.VoluntaryBlocks = ks.VoluntaryBlocks;
us.CpuBurstDemotions = ks.CpuBurstDemotions;
us.SmtSiblingDeferrals = ks.SmtSiblingDeferrals;
us.SmtPrimaryPokes = ks.SmtPrimaryPokes;
return KiReturnKernelStats(a1, (size_t)a2, a3, &us, sizeof(us));
}
case SYS_KERNEL_STATS_PMM: {
MM_PHYSICAL_STATS km;
SYS_PMM_STATS um;
MmQueryPhysicalStats(&km);
memset(&um, 0, sizeof(um));
um.TotalFrames = km.TotalFrames;
um.FreeFrames = km.FreeFrames;
um.UsedFrames = km.UsedFrames;
um.LargestFreeRun = km.LargestFreeRun;
um.FreeRunCount = km.FreeRunCount;
for (size_t i = 0; i < 8; i++)
um.FreeRunHistogram[i] = km.FreeRunHistogram[i];
return KiReturnKernelStats(a1, (size_t)a2, a3, &um, sizeof(um));
}
case SYS_KERNEL_STATS_CPU: {
SYS_CPU_STATS stats;
memset(&stats, 0, sizeof(stats));
stats.CpuCount = gCpuCount;
uint32_t n = gCpuCount;
if (n > SYS_KERNEL_STATS_MAX_CPUS)
n = SYS_KERNEL_STATS_MAX_CPUS;
for (uint32_t i = 0; i < n; i++) {
KCPU* cpu = &gCpus[i];
SYS_CPU_STAT* out = &stats.Cpu[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;
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;
out->SchedulerTicks = cpu->SchedulerTicks;
out->ContextSwitches = cpu->ContextSwitches;
}
return KiReturnKernelStats(a1, (size_t)a2, a3, &stats, sizeof(stats));
}
default:
return STATUS_INVALID_PARAMETER;
}
}
// ===========================================================================
// Dispatch table - index must match SYS_* in syscall_nr.h exactly.
// ===========================================================================
@@ -2572,96 +2780,98 @@ typedef uint64_t (*SYSCALL_HANDLER)(uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t);
static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
/* 00 SYS_EXIT_PROCESS */ SyscallExitProcess,
/* 01 SYS_EXIT_THREAD */ SyscallExitThread,
/* 02 SYS_CREATE_PROCESS */ SyscallCreateProcess,
/* 03 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess,
/* 04 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode,
/* 05 SYS_KILL_PROCESS */ SyscallKillProcess,
/* 06 SYS_GET_PROCESS_LIST */ SyscallGetProcessList,
/* 07 SYS_GET_PROCESS_PID */ SyscallGetProcessPid,
/* 08 SYS_CREATE_THREAD */ SyscallCreateThread,
/* 09 SYS_WAIT_THREAD */ SyscallWaitThread,
/* 10 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid,
/* 11 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid,
/* 12 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority,
/* 13 SYS_YIELD */ SyscallYield,
/* 14 SYS_SLEEP */ SyscallSleep,
/* 15 SYS_SET_USER_APC_DISPATCHER */ SyscallSetUserApcDispatcher,
/* 16 SYS_APC_RETURN */ SyscallApcReturn,
/* 17 SYS_ALLOC */ SyscallAlloc,
/* 18 SYS_FREE */ SyscallFree,
/* 19 SYS_REALLOC */ SyscallRealloc,
/* 20 SYS_CLOSE_HANDLE */ SyscallCloseHandle,
/* 21 SYS_MUTEX_CREATE */ SyscallMutexCreate,
/* 22 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire,
/* 23 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire,
/* 24 SYS_MUTEX_RELEASE */ SyscallMutexRelease,
/* 25 SYS_SEM_CREATE */ SyscallSemCreate,
/* 26 SYS_SEM_WAIT */ SyscallSemWait,
/* 27 SYS_SEM_TRY_WAIT */ SyscallSemTryWait,
/* 28 SYS_SEM_SIGNAL */ SyscallSemSignal,
/* 29 SYS_EVENT_CREATE */ SyscallEventCreate,
/* 30 SYS_EVENT_SIGNAL */ SyscallEventSignal,
/* 31 SYS_EVENT_CLEAR */ SyscallEventClear,
/* 32 SYS_EVENT_WAIT */ SyscallEventWait,
/* 33 SYS_QUEUE_CREATE */ SyscallQueueCreate,
/* 34 SYS_QUEUE_SEND */ SyscallQueueSend,
/* 35 SYS_QUEUE_RECV */ SyscallQueueRecv,
/* 36 SYS_PUBLISH_QUEUE */ SyscallPublishQueue,
/* 37 SYS_OPEN_NAMED_QUEUE */ SyscallOpenNamedQueue,
/* 38 SYS_QUEUE_DUPLICATE */ SyscallQueueDuplicate,
/* 39 SYS_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid,
/* 40 SYS_OPEN_FILE */ SyscallOpenFile,
/* 41 SYS_CREATE_FILE */ SyscallCreateFile,
/* 42 SYS_READ_FILE */ SyscallReadFile,
/* 43 SYS_WRITE_FILE */ SyscallWriteFile,
/* 44 SYS_READ_FILE_ASYNC */ SyscallReadFileAsync,
/* 45 SYS_WRITE_FILE_ASYNC */ SyscallWriteFileAsync,
/* 46 SYS_CANCEL_IO */ SyscallCancelIo,
/* 47 SYS_SEEK_FILE */ SyscallSeekFile,
/* 48 SYS_GET_FILE_POS */ SyscallGetFilePos,
/* 49 SYS_GET_FILE_SIZE */ SyscallGetFileSize,
/* 50 SYS_TRUNCATE_FILE */ SyscallTruncateFile,
/* 51 SYS_DELETE_FILE */ SyscallDeleteFile,
/* 52 SYS_RENAME_FILE */ SyscallRenameFile,
/* 53 SYS_OPEN_DIR */ SyscallOpenDir,
/* 54 SYS_READ_DIR */ SyscallReadDir,
/* 55 SYS_CREATE_DIR */ SyscallCreateDir,
/* 56 SYS_REMOVE_DIR */ SyscallRemoveDir,
/* 57 SYS_SET_CWD */ SyscallSetCwd,
/* 58 SYS_GET_CWD */ SyscallGetCwd,
/* 59 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
/* 60 SYS_SCREEN_BLIT */ SyscallScreenBlit,
/* 61 SYS_SCREEN_CLEAR */ SyscallScreenClear,
/* 62 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize,
/* 63 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar,
/* 64 SYS_KB_POLL */ SyscallKbPoll,
/* 65 SYS_KB_IS_KEY_DOWN */ SyscallKbIsKeyDown,
/* 66 SYS_KB_READ_CHAR */ SyscallKbReadChar,
/* 67 SYS_KB_READ_KEY */ SyscallKbReadKey,
/* 68 SYS_KB_GET_MODIFIERS */ SyscallKbGetModifiers,
/* 69 SYS_MOUSE_POLL */ SyscallMousePoll,
/* 70 SYS_MOUSE_READ */ SyscallMouseRead,
/* 71 SYS_MOUSE_GET_POS */ SyscallMouseGetPos,
/* 72 SYS_GET_TICK */ SyscallGetTick,
/* 73 SYS_DEBUG_PRINT */ SyscallDebugPrint,
/* 74 SYS_QUERY_TRAP_FRAME */ SyscallQueryTrapFrame,
/* 75 SYS_SOCKET */ SyscallSocket,
/* 76 SYS_BIND */ SyscallBind,
/* 77 SYS_LISTEN */ SyscallListen,
/* 78 SYS_ACCEPT */ SyscallAccept,
/* 79 SYS_CONNECT */ SyscallConnect,
/* 80 SYS_SEND */ SyscallSend,
/* 81 SYS_RECV */ SyscallRecv,
/* 82 SYS_SHUTDOWN */ SyscallShutdown,
/* 83 SYS_SEND_TO */ SyscallSendTo,
/* 84 SYS_RECV_FROM */ SyscallRecvFrom,
/* 85 SYS_RESOLVE_HOST */ SyscallResolveHost,
/* 86 SYS_SET_SOCKET_OPTION */ SyscallSetSocketOption,
/* 87 SYS_GET_SOCKET_OPTION */ SyscallGetSocketOption,
/* 88 SYS_POLL */ SyscallPoll,
/* 89 SYS_GET_MEMORY_STATUS */ SyscallGetMemoryStatus
/* 00 SYS_EXIT_PROCESS */ SyscallExitProcess,
/* 01 SYS_EXIT_THREAD */ SyscallExitThread,
/* 02 SYS_CREATE_PROCESS */ SyscallCreateProcess,
/* 03 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess,
/* 04 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode,
/* 05 SYS_KILL_PROCESS */ SyscallKillProcess,
/* 06 SYS_GET_PROCESS_LIST */ SyscallGetProcessList,
/* 07 SYS_GET_PROCESS_PID */ SyscallGetProcessPid,
/* 08 SYS_CREATE_THREAD */ SyscallCreateThread,
/* 09 SYS_WAIT_THREAD */ SyscallWaitThread,
/* 10 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid,
/* 11 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid,
/* 12 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority,
/* 13 SYS_YIELD */ SyscallYield,
/* 14 SYS_SLEEP */ SyscallSleep,
/* 15 SYS_SET_USER_APC_DISPATCHER */ SyscallSetUserApcDispatcher,
/* 16 SYS_APC_RETURN */ SyscallApcReturn,
/* 17 SYS_VM_ALLOC */ SyscallVmAlloc,
/* 18 SYS_VM_FREE */ SyscallVmFree,
/* 19 SYS_VM_PROTECT */ SyscallVmProtect,
/* 20 SYS_VM_QUERY */ SyscallVmQuery,
/* 21 SYS_CLOSE_HANDLE */ SyscallCloseHandle,
/* 22 SYS_MUTEX_CREATE */ SyscallMutexCreate,
/* 23 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire,
/* 24 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire,
/* 25 SYS_MUTEX_RELEASE */ SyscallMutexRelease,
/* 26 SYS_SEM_CREATE */ SyscallSemCreate,
/* 27 SYS_SEM_WAIT */ SyscallSemWait,
/* 28 SYS_SEM_TRY_WAIT */ SyscallSemTryWait,
/* 29 SYS_SEM_SIGNAL */ SyscallSemSignal,
/* 30 SYS_EVENT_CREATE */ SyscallEventCreate,
/* 31 SYS_EVENT_SIGNAL */ SyscallEventSignal,
/* 32 SYS_EVENT_CLEAR */ SyscallEventClear,
/* 33 SYS_EVENT_WAIT */ SyscallEventWait,
/* 34 SYS_QUEUE_CREATE */ SyscallQueueCreate,
/* 35 SYS_QUEUE_SEND */ SyscallQueueSend,
/* 36 SYS_QUEUE_RECV */ SyscallQueueRecv,
/* 37 SYS_PUBLISH_QUEUE */ SyscallPublishQueue,
/* 38 SYS_OPEN_NAMED_QUEUE */ SyscallOpenNamedQueue,
/* 39 SYS_QUEUE_DUPLICATE */ SyscallQueueDuplicate,
/* 40 SYS_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid,
/* 41 SYS_OPEN_FILE */ SyscallOpenFile,
/* 42 SYS_CREATE_FILE */ SyscallCreateFile,
/* 43 SYS_READ_FILE */ SyscallReadFile,
/* 44 SYS_WRITE_FILE */ SyscallWriteFile,
/* 45 SYS_READ_FILE_ASYNC */ SyscallReadFileAsync,
/* 46 SYS_WRITE_FILE_ASYNC */ SyscallWriteFileAsync,
/* 47 SYS_CANCEL_IO */ SyscallCancelIo,
/* 48 SYS_SEEK_FILE */ SyscallSeekFile,
/* 49 SYS_GET_FILE_POS */ SyscallGetFilePos,
/* 50 SYS_GET_FILE_SIZE */ SyscallGetFileSize,
/* 51 SYS_TRUNCATE_FILE */ SyscallTruncateFile,
/* 52 SYS_DELETE_FILE */ SyscallDeleteFile,
/* 53 SYS_RENAME_FILE */ SyscallRenameFile,
/* 54 SYS_OPEN_DIR */ SyscallOpenDir,
/* 55 SYS_READ_DIR */ SyscallReadDir,
/* 56 SYS_CREATE_DIR */ SyscallCreateDir,
/* 57 SYS_REMOVE_DIR */ SyscallRemoveDir,
/* 58 SYS_SET_CWD */ SyscallSetCwd,
/* 59 SYS_GET_CWD */ SyscallGetCwd,
/* 60 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
/* 61 SYS_SCREEN_BLIT */ SyscallScreenBlit,
/* 62 SYS_SCREEN_CLEAR */ SyscallScreenClear,
/* 63 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize,
/* 64 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar,
/* 65 SYS_KB_POLL */ SyscallKbPoll,
/* 66 SYS_KB_IS_KEY_DOWN */ SyscallKbIsKeyDown,
/* 67 SYS_KB_READ_CHAR */ SyscallKbReadChar,
/* 68 SYS_KB_READ_KEY */ SyscallKbReadKey,
/* 69 SYS_KB_GET_MODIFIERS */ SyscallKbGetModifiers,
/* 70 SYS_MOUSE_POLL */ SyscallMousePoll,
/* 71 SYS_MOUSE_READ */ SyscallMouseRead,
/* 72 SYS_MOUSE_GET_POS */ SyscallMouseGetPos,
/* 73 SYS_GET_TICK */ SyscallGetTick,
/* 74 SYS_DEBUG_PRINT */ SyscallDebugPrint,
/* 75 SYS_QUERY_TRAP_FRAME */ SyscallQueryTrapFrame,
/* 76 SYS_SOCKET */ SyscallSocket,
/* 77 SYS_BIND */ SyscallBind,
/* 78 SYS_LISTEN */ SyscallListen,
/* 79 SYS_ACCEPT */ SyscallAccept,
/* 80 SYS_CONNECT */ SyscallConnect,
/* 81 SYS_SEND */ SyscallSend,
/* 82 SYS_RECV */ SyscallRecv,
/* 83 SYS_SHUTDOWN */ SyscallShutdown,
/* 84 SYS_SEND_TO */ SyscallSendTo,
/* 85 SYS_RECV_FROM */ SyscallRecvFrom,
/* 86 SYS_RESOLVE_HOST */ SyscallResolveHost,
/* 87 SYS_SET_SOCKET_OPTION */ SyscallSetSocketOption,
/* 88 SYS_GET_SOCKET_OPTION */ SyscallGetSocketOption,
/* 89 SYS_POLL */ SyscallPoll,
/* 90 SYS_GET_MEMORY_STATUS */ SyscallGetMemoryStatus,
/* 91 SYS_QUERY_KERNEL_STATS */ SyscallQueryKernelStats
};
// ---------------------------------------------------------------------------
@@ -2681,5 +2891,19 @@ uint64_t KeSyscallDispatch(uint64_t nr, uint64_t a0, uint64_t a1,
}
if (nr >= SYS_MAX || !gSyscallTable[nr]) return STATUS_NOT_SUPPORTED;
return gSyscallTable[nr](a0, a1, a2, a3, a4, a5);
uint64_t result = gSyscallTable[nr](a0, a1, a2, a3, a4, a5);
// A process may be terminated while one of its threads is already inside a
// syscall. Do not allow that thread to return to userspace after the owner
// has been marked terminating.
owner = self ? self->Owner : (PROCESS*)0;
if (owner && KeIsProcessTerminating(owner) &&
nr != SYS_EXIT_PROCESS && nr != SYS_EXIT_THREAD) {
int exitCode = owner->ExitCode;
KeExitThread(self, exitCode);
while (true) ;
}
return result;
}