a few new syscalls, init process
This commit is contained in:
1 parent
320a24e1a5
commit
cdf7ed4cea
12 files changed
+830
-480
No files matched your search
+270
-52
@@ -664,7 +664,50 @@ static uint64_t SyscallKbReadScancode(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_GET_TICK (38) -> uint64_t milliseconds
|
||||
// SYS_KB_GET_MODIFIERS (43) -> uint32_t
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a0; (void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
|
||||
if (!gHal) return 0;
|
||||
return (uint64_t)gHal->Keyboard.GetModifiers();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_POLL (44) -> 1 or 0
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a0; (void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
|
||||
if (!gHal) return 0;
|
||||
return gHal->Mouse.Poll() ? 1u : 0u;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_READ (45) a0=*dx a1=*dy a2=*buttons -> 1 or 0
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a3; (void)a4; (void)a5;
|
||||
if (!gHal) return 0;
|
||||
return gHal->Mouse.Read((int*)(uintptr_t)a0,
|
||||
(int*)(uintptr_t)a1,
|
||||
(uint8_t*)(uintptr_t)a2) ? 1u : 0u;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_GET_POS (46) a0=*x a1=*y
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMouseGetPos(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;
|
||||
if (!gHal) return 0;
|
||||
gHal->Mouse.GetPosition((int*)(uintptr_t)a0, (int*)(uintptr_t)a1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_GET_TICK (47) -> uint64_t milliseconds
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallGetTick(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -931,6 +974,173 @@ static uint64_t SyscallGetProcessPid(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Named Queue Registry
|
||||
//
|
||||
// A flat, fixed-size table of { name -> QUEUE* } pairs protected by a
|
||||
// spinlock. The registry holds one reference to each published queue for
|
||||
// the lifetime of the entry, so the queue object cannot be destroyed while
|
||||
// it is registered even if every process closes its own handle to it.
|
||||
//
|
||||
// Limits: NAMED_QUEUE_MAX names, each up to NAMED_QUEUE_NAME_MAX bytes.
|
||||
// These are generous for the intended usage (a handful of system servers).
|
||||
// ===========================================================================
|
||||
|
||||
#define NAMED_QUEUE_MAX 16
|
||||
#define NAMED_QUEUE_NAME_MAX 64
|
||||
|
||||
typedef struct {
|
||||
char Name[NAMED_QUEUE_NAME_MAX];
|
||||
QUEUE* Queue; // NULL = slot free; non-NULL = occupied
|
||||
uint32_t PublisherPid; // ProcessId of whoever called SysPublishQueue
|
||||
} NAMED_QUEUE_ENTRY;
|
||||
|
||||
static NAMED_QUEUE_ENTRY gNamedQueues[NAMED_QUEUE_MAX];
|
||||
static SPINLOCK gNamedQueueLock;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_PUBLISH_QUEUE (55) a0=*name a1=queueHandle
|
||||
//
|
||||
// Registers the queue identified by 'queueHandle' under 'name'.
|
||||
// Fails with STATUS_ALREADY_EXISTS if the name is already taken.
|
||||
// The registry bumps the queue's refcount so it outlives the handle.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallPublishQueue(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;
|
||||
|
||||
const char* name = (const char*)(uintptr_t)a0;
|
||||
if (!name || !name[0]) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
// Resolve the handle to a QUEUE object. HandleToObject bumps the
|
||||
// refcount by one; we keep that ref in the registry slot.
|
||||
QUEUE* q = (QUEUE*)HandleToObject((uint32_t)a1, ObjectTypeQueue);
|
||||
if (!q) return STATUS_INVALID_HANDLE;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock);
|
||||
|
||||
// Reject duplicate names.
|
||||
for (int i = 0; i < NAMED_QUEUE_MAX; i++) {
|
||||
if (gNamedQueues[i].Queue &&
|
||||
strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) {
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
ObDereferenceObject(&q->Header); // drop the ref we just took
|
||||
return STATUS_ALREADY_EXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a free slot.
|
||||
for (int i = 0; i < NAMED_QUEUE_MAX; i++) {
|
||||
if (!gNamedQueues[i].Queue) {
|
||||
strncpy(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX - 1);
|
||||
gNamedQueues[i].Name[NAMED_QUEUE_NAME_MAX - 1] = '\0';
|
||||
gNamedQueues[i].Queue = q; // ref transferred to registry
|
||||
gNamedQueues[i].PublisherPid = KeGetCurrentProcess()->ProcessId;
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
ObDereferenceObject(&q->Header); // no room - drop the ref
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_OPEN_NAMED_QUEUE (56) a0=*name a1=*handleOut
|
||||
//
|
||||
// Looks up 'name' in the registry and allocates a handle to the queue in the
|
||||
// calling process's handle table. Returns STATUS_NOT_FOUND if no match.
|
||||
// Callers that race against the publisher should retry on NOT_FOUND.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallOpenNamedQueue(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;
|
||||
|
||||
const char* name = (const char*)(uintptr_t)a0;
|
||||
uint32_t* handleOut = (uint32_t*)(uintptr_t)a1;
|
||||
if (!name || !name[0] || !handleOut) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock);
|
||||
|
||||
QUEUE* q = NULL;
|
||||
for (int i = 0; i < NAMED_QUEUE_MAX; i++) {
|
||||
if (gNamedQueues[i].Queue &&
|
||||
strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) {
|
||||
q = gNamedQueues[i].Queue;
|
||||
ObReferenceObject(&q->Header); // one ref for the new handle
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
|
||||
if (!q) return STATUS_NOT_FOUND;
|
||||
|
||||
// AllocHandleForCurrent consumes the ref we just bumped.
|
||||
// On failure it calls ObDereferenceObject internally.
|
||||
return AllocHandleForCurrent(&q->Header, handleOut);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_QUEUE_DUPLICATE (61) a0=handle a1=targetPid a2=*handleOut
|
||||
//
|
||||
// Looks up the QUEUE behind 'handle' in the CALLER's table, then allocates
|
||||
// a new handle for the same object in the TARGET process's table.
|
||||
// Both processes share the same underlying QUEUE (refcount bumped).
|
||||
// The caller's own handle is unchanged.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallQueueDuplicate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a3; (void)a4; (void)a5;
|
||||
if (!a2) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
QUEUE* q = (QUEUE*)HandleToObject((uint32_t)a0, ObjectTypeQueue);
|
||||
if (!q) return STATUS_NOT_FOUND;
|
||||
|
||||
PROCESS* target = KeGetProcessById((uint32_t)a1);
|
||||
if (!target) {
|
||||
ObDereferenceObject(&q->Header);
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
uint32_t newHandle = 0;
|
||||
KSTATUS s = KeAllocateHandle(target, &q->Header, &newHandle);
|
||||
ObDereferenceObject(&target->Header);
|
||||
ObDereferenceObject(&q->Header);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
|
||||
*(uint32_t*)(uintptr_t)a2 = newHandle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_NAMED_QUEUE_OWNER_PID (62) a0=*name a1=*pidOut
|
||||
//
|
||||
// Returns the ProcessId of whoever published the named queue.
|
||||
// Lets a client get the publisher's PID so it can duplicate one of its
|
||||
// own handles into that process via SYS_QUEUE_DUPLICATE.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallNamedQueueOwnerPid(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;
|
||||
const char* name = (const char*)(uintptr_t)a0;
|
||||
uint32_t* pidOut = (uint32_t*)(uintptr_t)a1;
|
||||
if (!name || !name[0] || !pidOut) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock);
|
||||
for (int i = 0; i < NAMED_QUEUE_MAX; i++) {
|
||||
if (gNamedQueues[i].Queue &&
|
||||
strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) {
|
||||
*pidOut = gNamedQueues[i].PublisherPid;
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinlock(&gNamedQueueLock, flags);
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Dispatch table - index must match SYS_* in syscall_nr.h exactly.
|
||||
// ===========================================================================
|
||||
@@ -938,61 +1148,69 @@ 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_THREAD */ SyscallCreateThread,
|
||||
/* 03 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid,
|
||||
/* 04 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid,
|
||||
/* 05 SYS_YIELD */ SyscallYield,
|
||||
/* 06 SYS_SLEEP */ SyscallSleep,
|
||||
/* 07 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority,
|
||||
/* 08 SYS_ALLOC */ SyscallAlloc,
|
||||
/* 09 SYS_FREE */ SyscallFree,
|
||||
/* 10 SYS_REALLOC */ SyscallRealloc,
|
||||
/* 11 SYS_MUTEX_CREATE */ SyscallMutexCreate,
|
||||
/* 12 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire,
|
||||
/* 13 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire,
|
||||
/* 14 SYS_MUTEX_RELEASE */ SyscallMutexRelease,
|
||||
/* 15 SYS_SEM_CREATE */ SyscallSemCreate,
|
||||
/* 16 SYS_SEM_WAIT */ SyscallSemWait,
|
||||
/* 17 SYS_SEM_TRY_WAIT */ SyscallSemTryWait,
|
||||
/* 18 SYS_SEM_SIGNAL */ SyscallSemSignal,
|
||||
/* 19 SYS_EVENT_CREATE */ SyscallEventCreate,
|
||||
/* 20 SYS_EVENT_SIGNAL */ SyscallEventSignal,
|
||||
/* 21 SYS_EVENT_CLEAR */ SyscallEventClear,
|
||||
/* 22 SYS_EVENT_WAIT */ SyscallEventWait,
|
||||
/* 23 SYS_QUEUE_CREATE */ SyscallQueueCreate,
|
||||
/* 24 SYS_QUEUE_SEND */ SyscallQueueSend,
|
||||
/* 25 SYS_QUEUE_RECV */ SyscallQueueRecv,
|
||||
/* 26 SYS_CLOSE_HANDLE */ SyscallCloseHandle,
|
||||
/* 00 SYS_EXIT_PROCESS */ SyscallExitProcess,
|
||||
/* 01 SYS_EXIT_THREAD */ SyscallExitThread,
|
||||
/* 02 SYS_CREATE_THREAD */ SyscallCreateThread,
|
||||
/* 03 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid,
|
||||
/* 04 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid,
|
||||
/* 05 SYS_YIELD */ SyscallYield,
|
||||
/* 06 SYS_SLEEP */ SyscallSleep,
|
||||
/* 07 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority,
|
||||
/* 08 SYS_ALLOC */ SyscallAlloc,
|
||||
/* 09 SYS_FREE */ SyscallFree,
|
||||
/* 10 SYS_REALLOC */ SyscallRealloc,
|
||||
/* 11 SYS_MUTEX_CREATE */ SyscallMutexCreate,
|
||||
/* 12 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire,
|
||||
/* 13 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire,
|
||||
/* 14 SYS_MUTEX_RELEASE */ SyscallMutexRelease,
|
||||
/* 15 SYS_SEM_CREATE */ SyscallSemCreate,
|
||||
/* 16 SYS_SEM_WAIT */ SyscallSemWait,
|
||||
/* 17 SYS_SEM_TRY_WAIT */ SyscallSemTryWait,
|
||||
/* 18 SYS_SEM_SIGNAL */ SyscallSemSignal,
|
||||
/* 19 SYS_EVENT_CREATE */ SyscallEventCreate,
|
||||
/* 20 SYS_EVENT_SIGNAL */ SyscallEventSignal,
|
||||
/* 21 SYS_EVENT_CLEAR */ SyscallEventClear,
|
||||
/* 22 SYS_EVENT_WAIT */ SyscallEventWait,
|
||||
/* 23 SYS_QUEUE_CREATE */ SyscallQueueCreate,
|
||||
/* 24 SYS_QUEUE_SEND */ SyscallQueueSend,
|
||||
/* 25 SYS_QUEUE_RECV */ SyscallQueueRecv,
|
||||
/* 26 SYS_CLOSE_HANDLE */ SyscallCloseHandle,
|
||||
/* 27 SYS_OPEN_FILE */ SyscallOpenFile,
|
||||
/* 28 SYS_READ_FILE */ SyscallReadFile,
|
||||
/* 29 SYS_SEEK_FILE */ SyscallSeekFile,
|
||||
/* 30 SYS_GET_FILE_SIZE */ SyscallGetFileSize,
|
||||
/* 31 SYS_SCREEN_BLIT */ SyscallScreenBlit,
|
||||
/* 32 SYS_SCREEN_CLEAR */ SyscallScreenClear,
|
||||
/* 33 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize,
|
||||
/* 34 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar,
|
||||
/* 35 SYS_KB_POLL */ SyscallKbPoll,
|
||||
/* 36 SYS_KB_READ_CHAR */ SyscallKbReadChar,
|
||||
/* 37 SYS_KB_READ_SCANCODE */ SyscallKbReadScancode,
|
||||
/* 38 SYS_GET_TICK */ SyscallGetTick,
|
||||
/* 39 SYS_DEBUG_PRINT */ SyscallDebugPrint,
|
||||
/* 40 SYS_CREATE_PROCESS */ SyscallCreateProcess,
|
||||
/* 41 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess,
|
||||
/* 42 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode,
|
||||
/* 43 SYS_WRITE_FILE */ SyscallWriteFile,
|
||||
/* 44 SYS_CREATE_FILE */ SyscallCreateFile,
|
||||
/* 45 SYS_DELETE_FILE */ SyscallDeleteFile,
|
||||
/* 46 SYS_TRUNCATE_FILE */ SyscallTruncateFile,
|
||||
/* 47 SYS_GET_FILE_POS */ SyscallGetFilePos,
|
||||
/* 48 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
|
||||
/* 49 SYS_OPEN_DIR */ SyscallOpenDir,
|
||||
/* 50 SYS_READ_DIR */ SyscallReadDir,
|
||||
/* 51 SYS_SET_CWD */ SyscallSetCwd,
|
||||
/* 52 SYS_GET_CWD */ SyscallGetCwd,
|
||||
/* 53 SYS_WAIT_THREAD */ SyscallWaitThread,
|
||||
/* 54 SYS_GET_PROCESS_PID */ SyscallGetProcessPid,
|
||||
/* 31 SYS_WRITE_FILE */ SyscallWriteFile,
|
||||
/* 32 SYS_CREATE_FILE */ SyscallCreateFile,
|
||||
/* 33 SYS_DELETE_FILE */ SyscallDeleteFile,
|
||||
/* 34 SYS_TRUNCATE_FILE */ SyscallTruncateFile,
|
||||
/* 35 SYS_GET_FILE_POS */ SyscallGetFilePos,
|
||||
/* 36 SYS_SCREEN_BLIT */ SyscallScreenBlit,
|
||||
/* 37 SYS_SCREEN_CLEAR */ SyscallScreenClear,
|
||||
/* 38 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize,
|
||||
/* 39 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar,
|
||||
/* 40 SYS_KB_POLL */ SyscallKbPoll,
|
||||
/* 41 SYS_KB_READ_CHAR */ SyscallKbReadChar,
|
||||
/* 42 SYS_KB_READ_SCANCODE */ SyscallKbReadScancode,
|
||||
/* 43 SYS_KB_GET_MODIFIERS */ SyscallKbGetModifiers,
|
||||
/* 44 SYS_MOUSE_POLL */ SyscallMousePoll,
|
||||
/* 45 SYS_MOUSE_READ */ SyscallMouseRead,
|
||||
/* 46 SYS_MOUSE_GET_POS */ SyscallMouseGetPos,
|
||||
/* 47 SYS_GET_TICK */ SyscallGetTick,
|
||||
/* 48 SYS_DEBUG_PRINT */ SyscallDebugPrint,
|
||||
/* 49 SYS_CREATE_PROCESS */ SyscallCreateProcess,
|
||||
/* 50 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess,
|
||||
/* 51 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode,
|
||||
/* 52 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
|
||||
/* 53 SYS_OPEN_DIR */ SyscallOpenDir,
|
||||
/* 54 SYS_READ_DIR */ SyscallReadDir,
|
||||
/* 55 SYS_SET_CWD */ SyscallSetCwd,
|
||||
/* 56 SYS_GET_CWD */ SyscallGetCwd,
|
||||
/* 57 SYS_WAIT_THREAD */ SyscallWaitThread,
|
||||
/* 58 SYS_GET_PROCESS_PID */ SyscallGetProcessPid,
|
||||
/* 59 SYS_PUBLISH_QUEUE */ SyscallPublishQueue,
|
||||
/* 60 SYS_OPEN_NAMED_QUEUE */ SyscallOpenNamedQueue,
|
||||
/* 61 SYS_QUEUE_DUPLICATE */ SyscallQueueDuplicate,
|
||||
/* 62 SYS_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user