add /IGNORE:4216 to HAL link step, add writing and directory listing to the FAT32 driver, add the concept of current working directory to the VFS, add writing to the VFS, more operations in the shell, rename KeCurrentThread to KeGetCurrentThread and add KeGetCurrentProcess, add STATUS_NO_MORE_FILES, change KeFault* to KePanic, add syscalls for writing to files, add a proper syscall to writing to the console, move Screen.Clear to after memory status debug print, add ObjectTypeDir to OBJECT_TYPE, extend kernel32 by file operations and upgrade user32 (and add gdi32) to match windows a bit more closely, change CreateProcessA to accept the first argument as NULL.
This commit is contained in:
1 parent
a5f0acfac8
commit
8c7564d5e1
33 files changed
+2343
-429
No files matched your search
+185
-21
@@ -58,7 +58,7 @@ void KeSyscallSetHal(const HAL_API* hal) { gHal = hal; }
|
||||
// Helper: get the current process, or NULL if unavailable.
|
||||
// ---------------------------------------------------------------------------
|
||||
static inline PROCESS* CurrentProcess(void) {
|
||||
THREAD* t = KeCurrentThread();
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
return t ? t->Owner : NULL;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ static KSTATUS AllocHandleForCurrent(OBJECT* obj, uint32_t* handleOut) {
|
||||
static uint64_t SyscallExitProcess(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;
|
||||
THREAD* t = KeCurrentThread();
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
PROCESS* proc = t ? t->Owner : NULL;
|
||||
if (proc) KeExitProcess(proc, (int)a0);
|
||||
if (t) KeExitThread(t, (int)a0);
|
||||
@@ -115,7 +115,7 @@ static uint64_t SyscallExitProcess(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
static uint64_t SyscallExitThread(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;
|
||||
THREAD* t = KeCurrentThread();
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
if (t) KeExitThread(t, (int)a0);
|
||||
while (true) ;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ static uint64_t SyscallCreateThread(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
static uint64_t SyscallGetCurrentTid(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;
|
||||
THREAD* t = KeCurrentThread();
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
return t ? t->ThreadId : 0;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ static uint64_t SyscallSetThreadPriority(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 >= PriorityCount) return STATUS_INVALID_PARAMETER;
|
||||
THREAD* t = KeCurrentThread();
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
if (!t) return STATUS_FAILURE;
|
||||
t->Priority = (THREAD_PRIORITY)a0;
|
||||
return STATUS_SUCCESS;
|
||||
@@ -492,6 +492,78 @@ static uint64_t SyscallReadFile(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_WRITE_FILE (43) a0=handle a1=buf a2=size a3=*bytesWrittenOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallWriteFile(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a4; (void)a5;
|
||||
if (!a1) return STATUS_INVALID_PARAMETER;
|
||||
FILE_OBJECT* file = (FILE_OBJECT*)HandleToObject((uint32_t)a0, ObjectTypeFile);
|
||||
if (!file) return STATUS_NOT_FOUND;
|
||||
size_t written = 0;
|
||||
KSTATUS s = IoWriteFile(file, (const void*)(uintptr_t)a1, (size_t)a2, &written);
|
||||
if (a3) *(size_t*)(uintptr_t)a3 = written;
|
||||
ObDereferenceObject(&file->Header);
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_CREATE_FILE (44) a0=*path a1=*handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallCreateFile(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 (!a0 || !a1) return STATUS_INVALID_PARAMETER;
|
||||
FILE_OBJECT* file = NULL;
|
||||
KSTATUS s = IoCreateFile((const char*)(uintptr_t)a0, &file);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
uint32_t h = 0;
|
||||
s = AllocHandleForCurrent(&file->Header, &h);
|
||||
if (!KSUCCESS(s)) {
|
||||
ObDereferenceObject(&file->Header);
|
||||
return s;
|
||||
}
|
||||
*(uint32_t*)(uintptr_t)a1 = h;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_DELETE_FILE (45) a0=*path
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallDeleteFile(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 STATUS_INVALID_PARAMETER;
|
||||
return IoDeleteFile((const char*)(uintptr_t)a0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_TRUNCATE_FILE (46) a0=handle a1=newSize
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallTruncateFile(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;
|
||||
FILE_OBJECT* file = (FILE_OBJECT*)HandleToObject((uint32_t)a0, ObjectTypeFile);
|
||||
if (!file) return STATUS_NOT_FOUND;
|
||||
KSTATUS s = IoTruncateFile(file, (uint64_t)a1);
|
||||
ObDereferenceObject(&file->Header);
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_GET_FILE_POS (47) a0=handle -> current seek offset
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallGetFilePos(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;
|
||||
FILE_OBJECT* file = (FILE_OBJECT*)HandleToObject((uint32_t)a0, ObjectTypeFile);
|
||||
if (!file) return (uint64_t)-1;
|
||||
uint64_t pos = file->Offset;
|
||||
ObDereferenceObject(&file->Header);
|
||||
return pos;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEEK_FILE (29) a0=handle a1=offset
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -704,6 +776,88 @@ static uint64_t SyscallGetProcessExitCode(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_WRITE_CONSOLE (48) a0=*buf a1=len
|
||||
// Writes user console text in white; distinct from green SYS_DEBUG_PRINT.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallWriteConsole(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* buf = (const char*)(uintptr_t)a0;
|
||||
size_t len = (size_t)a1;
|
||||
if (buf && len) KePrintConsole(buf, len);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_OPEN_DIR (49) a0=*dirPath a1=*handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallOpenDir(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* dirPath = (const char*)(uintptr_t)a0;
|
||||
uint32_t* handleOut = (uint32_t*)(uintptr_t)a1;
|
||||
|
||||
if (!handleOut) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
DIR_OBJECT* dir = NULL;
|
||||
KSTATUS s = IoOpenDir(dirPath, &dir);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
|
||||
// Put the object in the handle table and get a valid index (1-255)
|
||||
s = KeAllocateHandle(KeGetCurrentProcess(), &dir->Header, handleOut);
|
||||
|
||||
// Drop the reference KeAllocateHandle took, so that when user space
|
||||
// calls CloseHandle, the refcount drops to 0 and the object is destroyed.
|
||||
ObDereferenceObject(&dir->Header);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_READ_DIR (50) a0=handle a1=*KDIR_ENTRY
|
||||
// Returns STATUS_NO_MORE_FILES when the directory is exhausted.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallReadDir(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;
|
||||
|
||||
// a0 = handle from user mode
|
||||
// a1 = KDIR_ENTRY* buffer
|
||||
|
||||
// Look up a DIR_OBJECT using ObjectTypeDir (not ObjectTypeFile)
|
||||
DIR_OBJECT* dir = (DIR_OBJECT*)HandleToObject((uint32_t)a0, ObjectTypeDir);
|
||||
if (!dir) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
KSTATUS s = IoReadDir(dir, (void*)(uintptr_t)a1);
|
||||
|
||||
ObDereferenceObject(&dir->Header); // Drop the ref taken by HandleToObject
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SET_CWD (51) a0=*path
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSetCwd(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;
|
||||
const char* path = (const char*)(uintptr_t)a0;
|
||||
if (!path) return STATUS_INVALID_PARAMETER;
|
||||
return IoSetCwd(path);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_GET_CWD (52) a0=*buf a1=size
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallGetCwd(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;
|
||||
char* buf = (char*)(uintptr_t)a0;
|
||||
size_t size = (size_t)a1;
|
||||
if (!buf || size == 0) return STATUS_INVALID_PARAMETER;
|
||||
return IoGetCwd(buf, size);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Dispatch table - index must match SYS_* in syscall_nr.h exactly.
|
||||
// ===========================================================================
|
||||
@@ -738,22 +892,32 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
|
||||
/* 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,
|
||||
/* 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,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user