implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.

This commit is contained in:
maksw committed 2026-06-27 20:38:43 +02:00
1 parent 1f5477cf66
commit b7fcfce6f7
140 files changed
+7649 -3943

No files matched your search

+4 -1
View File
@@ -35,7 +35,10 @@
#define SYS_POLL_INVALID 0x0010u
#define SYS_POLL_TIMEOUT_INFINITE 0xFFFFFFFFu
// Kernel socket providers use the same tagged native address shape as syscalls.
// Kernel socket providers use the same fixed-size tagged native address shape as syscalls.
// Input requests use the syscall pointer-length parameter as the definitive
// buffer bound and require Size to equal SYS_SOCKET_ADDRESS_SIZE after copying.
// Address stores textual-order bytes; Port is host byte order.
typedef struct SYS_SOCKET_ADDRESS_K {
uint16_t Family;
uint16_t Size;
+24
View File
@@ -0,0 +1,24 @@
// Native user-mode exception runtime declarations shared by applications and personalities.
#pragma once
#include <stdint.h>
#include <ntlite/syscall.h>
#if defined(NTL_EXCEPTION_EXPORTS)
#define NTL_EXCEPTION_API __declspec(dllexport)
#else
#define NTL_EXCEPTION_API
#endif
#define NTL_EXCEPTION_CONTINUE_EXECUTION ((int)SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION)
#define NTL_EXCEPTION_CONTINUE_SEARCH ((int)SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH)
#define NTL_EXCEPTION_TERMINATE_PROCESS ((int)SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS)
typedef int (*NTL_EXCEPTION_HANDLER)(SYS_EXCEPTION_RECORD* record,
SYS_USER_CONTEXT* context,
void* userContext);
NTL_EXCEPTION_API uint32_t NtlInitializeExceptionRuntime(void);
NTL_EXCEPTION_API void* NtlAddExceptionHandler(int first, NTL_EXCEPTION_HANDLER handler, void* context);
NTL_EXCEPTION_API uint32_t NtlRemoveExceptionHandler(void* handle);
+41 -41
View File
@@ -24,52 +24,52 @@ typedef uint32_t KSTATUS;
#define KSTATUS_FACILITY(status) ((((KSTATUS)(status)) >> KSTATUS_FACILITY_SHIFT) & KSTATUS_FACILITY_MASK)
#define KSTATUS_CODE(status) (((KSTATUS)(status)) & KSTATUS_CODE_MASK)
#define STATUS_FACILITY_WAIT 0x00u
#define STATUS_FACILITY_SYSTEM 0x01u
#define STATUS_FACILITY_PROCESS 0x61u
#define NTLSTATUS_FACILITY_WAIT 0x00u
#define NTLSTATUS_FACILITY_SYSTEM 0x01u
#define NTLSTATUS_FACILITY_PROCESS 0x61u
// Wait-completion statuses are non-error statuses. STATUS_SUCCESS is exactly
// Wait-completion statuses are non-error statuses. NTLSTATUS_SUCCESS is exactly
// zero so old zero-initialisation and direct syscall success checks stay valid.
#define STATUS_SUCCESS ((KSTATUS)0x00000000u)
#define STATUS_TIMEOUT KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000001u)
#define STATUS_PENDING KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000002u)
#define STATUS_ALERTED KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000003u)
#define STATUS_KERNEL_APC KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000004u)
#define STATUS_USER_APC KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000005u)
#define NTLSTATUS_SUCCESS ((KSTATUS)0x00000000u)
#define NTLSTATUS_TIMEOUT KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000001u)
#define NTLSTATUS_PENDING KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000002u)
#define NTLSTATUS_ALERTED KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000003u)
#define NTLSTATUS_KERNEL_APC KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000004u)
#define NTLSTATUS_USER_APC KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000005u)
// System-facility failures.
// STATUS_WOULD_BLOCK is the canonical result for immediate nonblocking operations that cannot make progress.
// STATUS_TIMEOUT is reserved for finite waits whose deadline expires.
#define STATUS_FAILURE KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000001u)
#define STATUS_NOT_SUPPORTED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000002u)
#define STATUS_INVALID_PARAMETER KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000003u)
#define STATUS_INVALID_HANDLE KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000004u)
#define STATUS_BUFFER_TOO_SMALL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000005u)
#define STATUS_CHECKSUM_MISMATCH KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000006u)
#define STATUS_NO_MEMORY KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000007u)
#define STATUS_ACCESS_DENIED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000008u)
#define STATUS_NOT_FOUND KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000009u)
#define STATUS_ALREADY_EXISTS KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Au)
#define STATUS_OBJECT_NAME_COLLISION KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Bu)
#define STATUS_OBJECT_DEAD KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Cu)
#define STATUS_QUEUE_FULL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Du)
#define STATUS_QUEUE_EMPTY KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Eu)
#define STATUS_CANCELLED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Fu)
#define STATUS_DEVICE_ERROR KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000010u)
#define STATUS_NO_MORE_FILES KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000011u)
#define STATUS_INVALID_IRQL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000012u)
#define STATUS_WOULD_BLOCK KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000013u)
// NTLSTATUS_WOULD_BLOCK is the canonical result for immediate nonblocking operations that cannot make progress.
// NTLSTATUS_TIMEOUT is reserved for finite waits whose deadline expires.
#define NTLSTATUS_FAILURE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000001u)
#define NTLSTATUS_NOT_SUPPORTED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000002u)
#define NTLSTATUS_INVALID_PARAMETER KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000003u)
#define NTLSTATUS_INVALID_HANDLE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000004u)
#define NTLSTATUS_BUFFER_TOO_SMALL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000005u)
#define NTLSTATUS_CHECKSUM_MISMATCH KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000006u)
#define NTLSTATUS_NO_MEMORY KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000007u)
#define NTLSTATUS_ACCESS_DENIED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000008u)
#define NTLSTATUS_NOT_FOUND KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000009u)
#define NTLSTATUS_ALREADY_EXISTS KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Au)
#define NTLSTATUS_OBJECT_NAME_COLLISION KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Bu)
#define NTLSTATUS_OBJECT_DEAD KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Cu)
#define NTLSTATUS_QUEUE_FULL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Du)
#define NTLSTATUS_QUEUE_EMPTY KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Eu)
#define NTLSTATUS_CANCELLED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Fu)
#define NTLSTATUS_DEVICE_ERROR KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000010u)
#define NTLSTATUS_NO_MORE_FILES KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000011u)
#define NTLSTATUS_INVALID_IRQL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000012u)
#define NTLSTATUS_WOULD_BLOCK KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000013u)
// Process termination and fault statuses use the process facility.
#define STATUS_PROCESS_BASE KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000000u)
#define STATUS_PROCESS_KILLED KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000000u)
#define STATUS_PROCESS_PAGE_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000010u)
#define STATUS_PROCESS_GENERAL_PROTECTION KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000011u)
#define STATUS_PROCESS_ILLEGAL_OPCODE KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000012u)
#define STATUS_PROCESS_DIVIDE_BY_ZERO KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000013u)
#define STATUS_PROCESS_BREAKPOINT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000014u)
#define STATUS_PROCESS_ALIGNMENT_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000015u)
#define STATUS_PROCESS_UNKNOWN_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x00001Fu)
#define NTLSTATUS_PROCESS_BASE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000000u)
#define NTLSTATUS_PROCESS_KILLED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000000u)
#define NTLSTATUS_PROCESS_PAGE_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000010u)
#define NTLSTATUS_PROCESS_GENERAL_PROTECTION KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000011u)
#define NTLSTATUS_PROCESS_ILLEGAL_OPCODE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000012u)
#define NTLSTATUS_PROCESS_DIVIDE_BY_ZERO KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000013u)
#define NTLSTATUS_PROCESS_BREAKPOINT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000014u)
#define NTLSTATUS_PROCESS_ALIGNMENT_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000015u)
#define NTLSTATUS_PROCESS_UNKNOWN_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x00001Fu)
#define KSUCCESS(status) (((KSTATUS)(status)) == STATUS_SUCCESS)
#define KSUCCESS(status) (((KSTATUS)(status)) == NTLSTATUS_SUCCESS)
#define KFAILED(status) KSTATUS_IS_ERROR(status)
+351 -125
View File
@@ -13,6 +13,10 @@
#include <ntlite/display.h>
#include <ntlite/status.h>
// Syscall ABI convention: status-returning calls use KSTATUS. New or revised
// operations use a request struct when they need five or more logical arguments
// or when a pointer/length pair would otherwise be split across flat arguments.
// User process/thread environment.
// GS base points at SYS_TEB. GS:[0] is the process PEB pointer.
#define SYS_PEB_MAGIC 0x30424550u // "PEB0"
@@ -104,7 +108,7 @@ typedef struct SYS_ASYNC_FILE_REQUEST {
uint64_t Offset; // explicit byte offset; does not touch file pointer
void* Buffer;
size_t Size;
SYS_IO_STATUS_BLOCK* Iosb; // required; initialized to STATUS_PENDING
SYS_IO_STATUS_BLOCK* Iosb; // required; initialized to NTLSTATUS_PENDING
SYS_USER_APC_ROUTINE ApcRoutine; // optional; requires SysSetUserApcDispatcher
void* ApcContext;
uint32_t* RequestHandleOut; // optional; receives cancel/query handle
@@ -148,6 +152,155 @@ typedef struct SYS_TRAP_FRAME_INFO {
uint64_t R11;
} SYS_TRAP_FRAME_INFO;
// Structured exception delivery ABI. The kernel owns capture, delivery, and
// context validation; personalities own VEH, SEH, signal, and unwind policy.
#define SYS_EXCEPTION_ABI_VERSION 1u
#define SYS_EXCEPTION_MAXIMUM_PARAMETERS 15u
#define SYS_EXCEPTION_FLAG_NONE 0x00000000u
#define SYS_EXCEPTION_FLAG_NONCONTINUABLE 0x00000001u
#define SYS_EXCEPTION_FLAG_FIRST_CHANCE 0x00000002u
#define SYS_EXCEPTION_DISPATCH_FLAG_NONE 0x00000000u
#define SYS_EXCEPTION_CONTINUE_FLAG_NONE 0x00000000u
#define SYS_RAISE_EXCEPTION_FLAG_NONE 0x00000000u
#define SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE 0x00000001u
// Common exception codes intentionally match the Windows values used by user
// VEH/SEH code. The native ABI remains policy-neutral; the matching numbers
// only avoid needless translation in the Win32 personality.
#define SYS_EXCEPTION_CODE_GUARD_PAGE_VIOLATION 0x80000001u
#define SYS_EXCEPTION_CODE_DATATYPE_MISALIGNMENT 0x80000002u
#define SYS_EXCEPTION_CODE_BREAKPOINT 0x80000003u
#define SYS_EXCEPTION_CODE_SINGLE_STEP 0x80000004u
#define SYS_EXCEPTION_CODE_ACCESS_VIOLATION 0xC0000005u
#define SYS_EXCEPTION_CODE_ILLEGAL_INSTRUCTION 0xC000001Du
#define SYS_EXCEPTION_CODE_NONCONTINUABLE_EXCEPTION 0xC0000025u
#define SYS_EXCEPTION_CODE_INVALID_DISPOSITION 0xC0000026u
#define SYS_EXCEPTION_CODE_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
#define SYS_EXCEPTION_CODE_FLT_DENORMAL_OPERAND 0xC000008Du
#define SYS_EXCEPTION_CODE_FLT_DIVIDE_BY_ZERO 0xC000008Eu
#define SYS_EXCEPTION_CODE_FLT_INEXACT_RESULT 0xC000008Fu
#define SYS_EXCEPTION_CODE_FLT_INVALID_OPERATION 0xC0000090u
#define SYS_EXCEPTION_CODE_FLT_OVERFLOW 0xC0000091u
#define SYS_EXCEPTION_CODE_FLT_STACK_CHECK 0xC0000092u
#define SYS_EXCEPTION_CODE_FLT_UNDERFLOW 0xC0000093u
#define SYS_EXCEPTION_CODE_INT_DIVIDE_BY_ZERO 0xC0000094u
#define SYS_EXCEPTION_CODE_INT_OVERFLOW 0xC0000095u
#define SYS_EXCEPTION_CODE_PRIVILEGED_INSTRUCTION 0xC0000096u
#define SYS_EXCEPTION_CODE_STACK_OVERFLOW 0xC00000FDu
#define SYS_EXCEPTION_CODE_NTLITE_UNKNOWN 0xE0000001u
#define SYS_EXCEPTION_CODE_NTLITE_USER_RAISED 0xE0000002u
#define SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION 0u
#define SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH 1u
#define SYS_EXCEPTION_DISPOSITION_EXECUTE_HANDLER 2u
#define SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS 3u
#define SYS_CONTEXT_FLAG_NONE 0x0000000000000000ull
#define SYS_CONTEXT_FLAG_CONTROL 0x0000000000000001ull
#define SYS_CONTEXT_FLAG_INTEGER 0x0000000000000002ull
#define SYS_CONTEXT_FLAG_SEGMENTS 0x0000000000000004ull
#define SYS_CONTEXT_FLAG_ALL (SYS_CONTEXT_FLAG_CONTROL | \
SYS_CONTEXT_FLAG_INTEGER | \
SYS_CONTEXT_FLAG_SEGMENTS)
typedef struct SYS_USER_CONTEXT {
uint32_t Size;
uint32_t Version;
uint64_t Flags;
uint64_t Rip;
uint64_t Rsp;
uint64_t Rflags;
uint64_t Rax;
uint64_t Rcx;
uint64_t Rdx;
uint64_t Rbx;
uint64_t Rbp;
uint64_t Rsi;
uint64_t Rdi;
uint64_t R8;
uint64_t R9;
uint64_t R10;
uint64_t R11;
uint64_t R12;
uint64_t R13;
uint64_t R14;
uint64_t R15;
uint32_t SegCs;
uint32_t SegSs;
uint32_t SegDs;
uint32_t SegEs;
uint32_t SegFs;
uint32_t SegGs;
uint32_t Reserved0;
uint32_t Reserved1;
} SYS_USER_CONTEXT;
typedef struct SYS_EXCEPTION_RECORD {
uint32_t Size;
uint32_t Version;
uint32_t Code;
uint32_t Flags;
uintptr_t ExceptionAddress;
uintptr_t FaultAddress;
uint64_t ErrorCode;
uint32_t ParameterCount;
uint32_t Reserved;
uint64_t Parameters[SYS_EXCEPTION_MAXIMUM_PARAMETERS];
} SYS_EXCEPTION_RECORD;
typedef struct SYS_EXCEPTION_FRAME {
uint32_t Size;
uint32_t Version;
uint32_t Flags;
uint32_t Reserved;
SYS_EXCEPTION_RECORD ExceptionRecord;
SYS_USER_CONTEXT ContextRecord;
void* DispatcherContext;
} SYS_EXCEPTION_FRAME;
typedef void (*SYS_USER_EXCEPTION_DISPATCHER)(SYS_EXCEPTION_FRAME* frame);
typedef struct SYS_EXCEPTION_DISPATCHER_REQUEST {
uint32_t Size;
uint32_t Flags;
// A null routine unregisters the dispatcher and clears the optional stack.
SYS_USER_EXCEPTION_DISPATCHER DispatcherRoutine;
// Opaque user-mode value passed back to the dispatcher.
void* DispatcherContext;
// Optional user-mode stack extent. Base is the low address and size is the
// byte length; delivery will consume it from high addresses downward.
void* ExceptionStackBase;
size_t ExceptionStackSize;
} SYS_EXCEPTION_DISPATCHER_REQUEST;
typedef struct SYS_CONTINUE_EXCEPTION_REQUEST {
uint32_t Size;
uint32_t Flags;
uint32_t Disposition;
uint32_t Reserved;
const SYS_USER_CONTEXT* Context;
} SYS_CONTINUE_EXCEPTION_REQUEST;
typedef struct SYS_RAISE_EXCEPTION_REQUEST {
uint32_t Size;
uint32_t Flags;
uint32_t Code;
uint32_t ParameterCount;
const uint64_t* Parameters;
} SYS_RAISE_EXCEPTION_REQUEST;
// String-view based syscall request structures.
typedef struct SYS_CREATE_PROCESS_REQUEST {
SYS_STRING_VIEW Path;
@@ -234,8 +387,8 @@ typedef struct SYS_RENAME_FILE_REQUEST {
#define SYS_FILE_LOCK_TO_EOF UINT64_MAX
// File locks are advisory, process-owned byte-range locks keyed by filesystem
// identity. A zero timeout is an immediate try and returns STATUS_WOULD_BLOCK
// on conflict. A finite timeout returns STATUS_TIMEOUT only when its deadline
// identity. A zero timeout is an immediate try and returns NTLSTATUS_WOULD_BLOCK
// on conflict. A finite timeout returns NTLSTATUS_TIMEOUT only when its deadline
// expires. SYS_WAIT_TIMEOUT_INFINITE waits without a deadline. Length must be
// nonzero; SYS_FILE_LOCK_TO_EOF locks from Offset through end-of-file growth.
// Unlock removes this process's overlapping locks for the file identity.
@@ -265,11 +418,18 @@ typedef struct SYS_PRINT_DEBUG_REQUEST {
SYS_STRING_VIEW Text;
} SYS_PRINT_DEBUG_REQUEST;
// Published queue names are owned by the publishing process and QueueHandle.
// SysUnpublishQueue withdraws a name explicitly. Closing the publishing handle
// or exiting the process withdraws every name published through that handle.
typedef struct SYS_PUBLISH_QUEUE_REQUEST {
SYS_STRING_VIEW Name;
uint32_t QueueHandle;
} SYS_PUBLISH_QUEUE_REQUEST;
typedef struct SYS_UNPUBLISH_QUEUE_REQUEST {
SYS_STRING_VIEW Name;
} SYS_UNPUBLISH_QUEUE_REQUEST;
typedef struct SYS_OPEN_NAMED_QUEUE_REQUEST {
SYS_STRING_VIEW Name;
uint32_t* HandleOut;
@@ -284,7 +444,7 @@ typedef struct SYS_NAMED_QUEUE_OWNER_REQUEST {
#define SYS_QUEUE_MESSAGE_SIZE 56u
// Queue send and receive requests use wait-style timeouts. A zero timeout is
// an immediate try operation and returns STATUS_WOULD_BLOCK if the queue cannot
// an immediate try operation and returns NTLSTATUS_WOULD_BLOCK if the queue cannot
// make progress without waiting. SYS_WAIT_TIMEOUT_INFINITE requests a blocking
// wait without a deadline. Message pointers reference SYS_QUEUE_MESSAGE_SIZE
// bytes owned by the caller for the duration of the syscall. The common IPC
@@ -336,24 +496,24 @@ typedef struct SYS_CREATE_THREAD_REQUEST {
void SysExitProcess(int32_t exitCode);
void SysExitThread(int32_t exitCode);
uint32_t SysCreateProcess(const SYS_CREATE_PROCESS_REQUEST* request);
uint32_t SysWaitSingle(uint32_t handle, uint32_t flags, uint64_t timeoutMilliseconds);
uint32_t SysWaitMany(const SYS_WAIT_MANY_REQUEST* request);
KSTATUS SysCreateProcess(const SYS_CREATE_PROCESS_REQUEST* request);
KSTATUS SysWaitSingle(uint32_t handle, uint32_t flags, uint64_t timeoutMilliseconds);
KSTATUS SysWaitMany(const SYS_WAIT_MANY_REQUEST* request);
// SysOpenInputQueue returns a readable and waitable handle to the default
// keyboard input queue. The handle does not create a second event stream;
// SysReadInputEvent, SysPeekInputEvent, SysReadKey, and SysReadKeyboardChar
// consume the same queue. SysWaitSingle succeeds for this handle when a
// keyboard input event can be read.
uint32_t SysOpenInputQueue(uint32_t flags, uint32_t* handleOut);
KSTATUS SysOpenInputQueue(uint32_t flags, uint32_t* handleOut);
static inline uint32_t SysWait(uint32_t handle, uint32_t flags) {
static inline KSTATUS SysWait(uint32_t handle, uint32_t flags) {
return SysWaitSingle(handle, flags, SYS_WAIT_TIMEOUT_INFINITE);
}
uint32_t SysGetProcessExitCode(uint32_t handle, int32_t* exitCodeOut);
uint32_t SysOpenProcess(uint32_t pid, uint32_t* handleOut);
KSTATUS SysGetProcessExitCode(uint32_t handle, int32_t* exitCodeOut);
KSTATUS SysOpenProcess(uint32_t pid, uint32_t* handleOut);
// Protected kernel processes remain openable for query and wait operations,
// but SysKillProcess returns STATUS_ACCESS_DENIED for them.
uint32_t SysKillProcess(uint32_t processHandle, int32_t exitCode);
// but SysKillProcess returns NTLSTATUS_ACCESS_DENIED for them.
KSTATUS SysKillProcess(uint32_t processHandle, int32_t exitCode);
#define SYS_PROCESS_NAME_MAX 64u
#define SYS_PROCESS_CWD_MAX 128u
@@ -446,13 +606,23 @@ typedef struct SYS_PROCESS_INFO {
size_t UserReservedBytes;
size_t UserCommittedBytes;
uint64_t ExceptionDelivered;
uint64_t ExceptionUserRaised;
uint64_t ExceptionContinued;
uint64_t ExceptionUnhandled;
uint64_t ExceptionInvalidContinue;
uint32_t ExceptionMaxNestedDispatch;
uint32_t LastExceptionCode;
uintptr_t LastExceptionAddress;
uintptr_t LastExceptionFaultAddress;
char Name[SYS_PROCESS_NAME_MAX];
char CurrentDirectory[SYS_PROCESS_CWD_MAX];
} SYS_PROCESS_INFO;
uint32_t SysGetProcessList(SYS_PROCESS_INFO* processesOut, size_t maxCount, size_t* countOut);
uint32_t SysGetProcessPid(uint32_t handle, uint32_t* pidOut);
uint32_t SysGetThreadList(uint32_t pid, SYS_THREAD_INFO* threadsOut, size_t maxCount, size_t* countOut);
KSTATUS SysGetProcessList(SYS_PROCESS_INFO* processesOut, size_t maxCount, size_t* countOut);
KSTATUS SysGetProcessPid(uint32_t handle, uint32_t* pidOut);
KSTATUS SysGetThreadList(uint32_t pid, SYS_THREAD_INFO* threadsOut, size_t maxCount, size_t* countOut);
#define SYS_MODULE_NAME_MAX 64u
#define SYS_MODULE_INFO_VERSION 1u
@@ -496,17 +666,17 @@ typedef struct SYS_GET_MODULE_EXPORT_REQUEST {
uintptr_t* AddressOut;
} SYS_GET_MODULE_EXPORT_REQUEST;
uint32_t SysLoadModule(const SYS_LOAD_MODULE_REQUEST* request);
uint32_t SysUnloadModule(uint32_t moduleHandle);
uint32_t SysGetModuleInfo(uint32_t moduleHandle, SYS_MODULE_INFO* infoOut);
uint32_t SysGetModuleExport(const SYS_GET_MODULE_EXPORT_REQUEST* request);
uint32_t SysGetModuleList(SYS_MODULE_INFO* modulesOut, size_t maxCount, size_t* countOut);
KSTATUS SysLoadModule(const SYS_LOAD_MODULE_REQUEST* request);
KSTATUS SysUnloadModule(uint32_t moduleHandle);
KSTATUS SysGetModuleInfo(uint32_t moduleHandle, SYS_MODULE_INFO* infoOut);
KSTATUS SysGetModuleExport(const SYS_GET_MODULE_EXPORT_REQUEST* request);
KSTATUS SysGetModuleList(SYS_MODULE_INFO* modulesOut, size_t maxCount, size_t* countOut);
uint32_t SysCreateThread(const SYS_CREATE_THREAD_REQUEST* request);
KSTATUS SysCreateThread(const SYS_CREATE_THREAD_REQUEST* request);
uint32_t SysGetCurrentTid(void);
uint32_t SysGetCurrentPid(void);
uint32_t SysSetThreadPriority(uint32_t priority);
uint32_t SysYield(void);
KSTATUS SysSetThreadPriority(uint32_t priority);
KSTATUS SysYield(void);
#define SYS_TIMER_FLAG_NONE 0u
@@ -522,19 +692,26 @@ typedef struct SYS_SET_TIMER_REQUEST {
uint64_t PeriodMilliseconds;
} SYS_SET_TIMER_REQUEST;
uint32_t SysCreateTimer(uint32_t* handleOut);
uint32_t SysSetTimer(const SYS_SET_TIMER_REQUEST* request);
uint32_t SysCancelTimer(uint32_t timerHandle);
KSTATUS SysCreateTimer(uint32_t* handleOut);
KSTATUS SysSetTimer(const SYS_SET_TIMER_REQUEST* request);
KSTATUS SysCancelTimer(uint32_t timerHandle);
// SysSleep blocks the current thread through the same timer backend used by
// waitable timer handles. A zero-length sleep yields the processor.
uint32_t SysSleep(uint64_t ms);
uint32_t SysSetUserApcDispatcher(void* dispatcher);
KSTATUS SysSleep(uint64_t ms);
KSTATUS SysSetUserApcDispatcher(void* dispatcher);
// Returns from the active user APC dispatcher. The frame pointer must identify
// the kernel-issued frame for the current delivery; it is not a general resume
// or context-switch syscall.
uint32_t SysApcReturn(const SYS_USER_APC_FRAME* frame);
KSTATUS SysApcReturn(const SYS_USER_APC_FRAME* frame);
// Registers or queries the native user-mode exception dispatcher. Actual fault
// delivery, validated continuation, and user-raised exceptions are later cuts.
KSTATUS SysSetExceptionDispatcher(const SYS_EXCEPTION_DISPATCHER_REQUEST* request);
KSTATUS SysGetExceptionDispatcher(SYS_EXCEPTION_DISPATCHER_REQUEST* request);
KSTATUS SysContinueException(const SYS_CONTINUE_EXCEPTION_REQUEST* request);
KSTATUS SysRaiseException(const SYS_RAISE_EXCEPTION_REQUEST* request);
// Virtual memory and handles.
typedef enum SYS_VM_PROTECTION {
@@ -558,10 +735,20 @@ typedef struct SYS_VM_REGION_INFO {
uint32_t OwnerPid;
} SYS_VM_REGION_INFO;
uint32_t SysAllocVm(void* preferredBase, size_t pageCount, uint32_t protect, uint32_t flags, void** baseOut);
uint32_t SysFreeVm(void* base);
uint32_t SysProtectVm(void* base, size_t pageCount, uint32_t protect, uint32_t* oldProtectOut);
uint32_t SysQueryVm(void* address, SYS_VM_REGION_INFO* out);
typedef struct SYS_ALLOC_VM_REQUEST {
uint32_t Size;
uint32_t Protect;
uint32_t Flags;
uint32_t Reserved;
void* PreferredBase;
size_t PageCount;
void** BaseOut;
} SYS_ALLOC_VM_REQUEST;
KSTATUS SysAllocVm(const SYS_ALLOC_VM_REQUEST* request);
KSTATUS SysFreeVm(void* base);
KSTATUS SysProtectVm(void* base, size_t pageCount, uint32_t protect, uint32_t* oldProtectOut);
KSTATUS SysQueryVm(void* address, SYS_VM_REGION_INFO* out);
#define SYS_MAP_ACCESS_READ 0x00000001u
#define SYS_MAP_ACCESS_WRITE 0x00000002u
@@ -569,11 +756,11 @@ uint32_t SysQueryVm(void* address, SYS_VM_REGION_INFO* out);
#define SYS_MAP_ACCESS_EXECUTE 0x00000008u
#define SYS_MAP_FLAG_NONE 0x00000000u
uint32_t SysCreateFileMapping(uint32_t fileHandle, uint32_t protect, uint32_t flags,
KSTATUS SysCreateFileMapping(uint32_t fileHandle, uint32_t protect, uint32_t flags,
uint64_t maximumSize, uint32_t* mappingHandleOut);
uint32_t SysMapFile(uint32_t mappingHandle, uint64_t offset, size_t size,
KSTATUS SysMapFile(uint32_t mappingHandle, uint64_t offset, size_t size,
uint32_t access, uint32_t flags, void** baseOut);
uint32_t SysCloseHandle(uint32_t handle);
KSTATUS SysCloseHandle(uint32_t handle);
#define SYS_HANDLE_RIGHT_READ 0x00000001u
#define SYS_HANDLE_RIGHT_WRITE 0x00000002u
@@ -596,51 +783,52 @@ typedef struct SYS_DUPLICATE_HANDLE_REQUEST {
uint32_t* TargetHandleOut;
} SYS_DUPLICATE_HANDLE_REQUEST;
uint32_t SysDuplicateHandle(const SYS_DUPLICATE_HANDLE_REQUEST* request);
KSTATUS SysDuplicateHandle(const SYS_DUPLICATE_HANDLE_REQUEST* request);
uint32_t SysCreateMutex(uint32_t* handleOut);
uint32_t SysTryAcquireMutex(uint32_t handle);
uint32_t SysReleaseMutex(uint32_t handle);
KSTATUS SysCreateMutex(uint32_t* handleOut);
KSTATUS SysTryAcquireMutex(uint32_t handle);
KSTATUS SysReleaseMutex(uint32_t handle);
uint32_t SysCreateSem(int32_t initial, int32_t max, uint32_t* handleOut);
uint32_t SysTryWaitSem(uint32_t handle);
uint32_t SysSignalSem(uint32_t handle);
KSTATUS SysCreateSem(int32_t initial, int32_t max, uint32_t* handleOut);
KSTATUS SysTryWaitSem(uint32_t handle);
KSTATUS SysSignalSem(uint32_t handle);
uint32_t SysCreateEvent(uint32_t type, uint32_t initialState, uint32_t* handleOut);
uint32_t SysSignalEvent(uint32_t handle);
uint32_t SysClearEvent(uint32_t handle);
KSTATUS SysCreateEvent(uint32_t type, uint32_t initialState, uint32_t* handleOut);
KSTATUS SysSignalEvent(uint32_t handle);
KSTATUS SysClearEvent(uint32_t handle);
uint32_t SysCreateQueue(uint32_t* handleOut);
uint32_t SysSendQueue(const SYS_QUEUE_SEND_REQUEST* request);
uint32_t SysRecvQueue(const SYS_QUEUE_RECV_REQUEST* request);
uint32_t SysPublishQueue(const SYS_PUBLISH_QUEUE_REQUEST* request);
uint32_t SysOpenNamedQueue(const SYS_OPEN_NAMED_QUEUE_REQUEST* request);
uint32_t SysOpenNamedQueueOwnerProcess(const SYS_NAMED_QUEUE_OWNER_REQUEST* request);
KSTATUS SysCreateQueue(uint32_t* handleOut);
KSTATUS SysSendQueue(const SYS_QUEUE_SEND_REQUEST* request);
KSTATUS SysRecvQueue(const SYS_QUEUE_RECV_REQUEST* request);
KSTATUS SysPublishQueue(const SYS_PUBLISH_QUEUE_REQUEST* request);
KSTATUS SysUnpublishQueue(const SYS_UNPUBLISH_QUEUE_REQUEST* request);
KSTATUS SysOpenNamedQueue(const SYS_OPEN_NAMED_QUEUE_REQUEST* request);
KSTATUS SysOpenNamedQueueOwnerProcess(const SYS_NAMED_QUEUE_OWNER_REQUEST* request);
uint32_t SysOpenFile(const SYS_OPEN_FILE_REQUEST* request);
uint32_t SysReadFile(const SYS_FILE_IO_REQUEST* request);
uint32_t SysWriteFile(const SYS_FILE_IO_REQUEST* request);
uint32_t SysReadFileAsync(const SYS_ASYNC_FILE_REQUEST* request);
uint32_t SysWriteFileAsync(const SYS_ASYNC_FILE_REQUEST* request);
uint32_t SysCancelIo(uint32_t asyncRequestHandle);
uint32_t SysSeekFile(uint32_t handle, uint64_t offset);
uint32_t SysGetFilePos(uint32_t handle, uint64_t* positionOut);
uint32_t SysGetFileSize(uint32_t handle, uint64_t* sizeOut);
uint32_t SysGetFileStat(uint32_t handle, SYS_FILE_STAT* statOut);
uint32_t SysStatFile(const SYS_STAT_FILE_REQUEST* request);
uint32_t SysTruncateFile(uint32_t handle, uint64_t newSize);
uint32_t SysFlushFile(uint32_t handle);
uint32_t SysDeleteFile(const SYS_PATH_REQUEST* request);
uint32_t SysRenameFile(const SYS_RENAME_FILE_REQUEST* request);
uint32_t SysLockFile(const SYS_LOCK_FILE_REQUEST* request);
uint32_t SysUnlockFile(const SYS_UNLOCK_FILE_REQUEST* request);
KSTATUS SysOpenFile(const SYS_OPEN_FILE_REQUEST* request);
KSTATUS SysReadFile(const SYS_FILE_IO_REQUEST* request);
KSTATUS SysWriteFile(const SYS_FILE_IO_REQUEST* request);
KSTATUS SysReadFileAsync(const SYS_ASYNC_FILE_REQUEST* request);
KSTATUS SysWriteFileAsync(const SYS_ASYNC_FILE_REQUEST* request);
KSTATUS SysCancelIo(uint32_t asyncRequestHandle);
KSTATUS SysSeekFile(uint32_t handle, uint64_t offset);
KSTATUS SysGetFilePos(uint32_t handle, uint64_t* positionOut);
KSTATUS SysGetFileSize(uint32_t handle, uint64_t* sizeOut);
KSTATUS SysGetFileStat(uint32_t handle, SYS_FILE_STAT* statOut);
KSTATUS SysStatFile(const SYS_STAT_FILE_REQUEST* request);
KSTATUS SysTruncateFile(uint32_t handle, uint64_t newSize);
KSTATUS SysFlushFile(uint32_t handle);
KSTATUS SysDeleteFile(const SYS_PATH_REQUEST* request);
KSTATUS SysRenameFile(const SYS_RENAME_FILE_REQUEST* request);
KSTATUS SysLockFile(const SYS_LOCK_FILE_REQUEST* request);
KSTATUS SysUnlockFile(const SYS_UNLOCK_FILE_REQUEST* request);
uint32_t SysOpenDir(const SYS_PATH_HANDLE_REQUEST* request);
uint32_t SysReadDir(uint32_t handle, SYS_DIR_ENTRY* entryOut);
uint32_t SysCreateDir(const SYS_PATH_REQUEST* request);
uint32_t SysRemoveDir(const SYS_PATH_REQUEST* request);
uint32_t SysSetCwd(const SYS_PATH_REQUEST* request);
uint32_t SysRealPath(const SYS_REAL_PATH_REQUEST* request);
KSTATUS SysOpenDir(const SYS_PATH_HANDLE_REQUEST* request);
KSTATUS SysReadDir(uint32_t handle, SYS_DIR_ENTRY* entryOut);
KSTATUS SysCreateDir(const SYS_PATH_REQUEST* request);
KSTATUS SysRemoveDir(const SYS_PATH_REQUEST* request);
KSTATUS SysSetCwd(const SYS_PATH_REQUEST* request);
KSTATUS SysRealPath(const SYS_REAL_PATH_REQUEST* request);
// Console and graphics.
typedef struct SYS_CONSOLE_INFO {
@@ -651,19 +839,29 @@ typedef struct SYS_CONSOLE_INFO {
uint16_t Attribute;
} SYS_CONSOLE_INFO;
uint32_t SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request);
uint32_t SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut);
uint32_t SysSetConsoleCursor(int x, int y);
uint32_t SysFillConsoleCharacter(char c, int x, int y, size_t length, size_t* writtenOut);
uint32_t SysFillConsoleAttribute(uint16_t attr, int x, int y, size_t length, size_t* writtenOut);
uint32_t SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg);
uint32_t SysCreateSurface(uint32_t width, uint32_t height, uint32_t format, uint32_t flags, uint32_t* handleOut);
uint32_t SysMapSurface(uint32_t surfaceHandle, void** baseOut, uint32_t* pitchBytesOut);
uint32_t SysQuerySurface(uint32_t surfaceHandle, SYS_SURFACE_DESC* descOut);
uint32_t SysPresentSurface(uint32_t surfaceHandle, const DISPLAY_RECT* rects, uint32_t rectCount);
uint32_t SysClearScreen(uint32_t color);
uint32_t SysGetScreenSize(int* widthOut, int* heightOut);
uint32_t SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut);
KSTATUS SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request);
KSTATUS SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut);
KSTATUS SysSetConsoleCursor(int x, int y);
KSTATUS SysFillConsoleCharacter(char c, int x, int y, size_t length, size_t* writtenOut);
KSTATUS SysFillConsoleAttribute(uint16_t attr, int x, int y, size_t length, size_t* writtenOut);
KSTATUS SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg);
typedef struct SYS_CREATE_SURFACE_REQUEST {
uint32_t Size;
uint32_t Width;
uint32_t Height;
uint32_t Format;
uint32_t Flags;
uint32_t* HandleOut;
} SYS_CREATE_SURFACE_REQUEST;
KSTATUS SysCreateSurface(const SYS_CREATE_SURFACE_REQUEST* request);
KSTATUS SysMapSurface(uint32_t surfaceHandle, void** baseOut, uint32_t* pitchBytesOut);
KSTATUS SysQuerySurface(uint32_t surfaceHandle, SYS_SURFACE_DESC* descOut);
KSTATUS SysPresentSurface(uint32_t surfaceHandle, const DISPLAY_RECT* rects, uint32_t rectCount);
KSTATUS SysClearScreen(uint32_t color);
KSTATUS SysGetScreenSize(int* widthOut, int* heightOut);
KSTATUS SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut);
// Input.
#define SYS_INPUT_QUEUE_FLAG_NONE 0x00000000u
@@ -671,8 +869,8 @@ uint32_t SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut);
// A zero QueueHandle means the default keyboard input queue. A
// nonzero QueueHandle must be a handle returned by SysOpenInputQueue. A zero
// timeout is an immediate try and returns STATUS_WOULD_BLOCK when the queue is
// empty. A finite timeout returns STATUS_TIMEOUT only when its deadline expires.
// timeout is an immediate try and returns NTLSTATUS_WOULD_BLOCK when the queue is
// empty. A finite timeout returns NTLSTATUS_TIMEOUT only when its deadline expires.
typedef struct SYS_INPUT_EVENT_REQUEST {
uint32_t Size;
uint32_t QueueHandle;
@@ -681,17 +879,17 @@ typedef struct SYS_INPUT_EVENT_REQUEST {
INPUT_KEY_RECORD* RecordOut;
} SYS_INPUT_EVENT_REQUEST;
uint32_t SysPollKeyboard(INPUT_KEY* keyOut);
uint32_t SysIsKeyDown(INPUT_KEY key, bool* downOut);
uint32_t SysReadKeyboardChar(char* charOut);
uint32_t SysReadKey(INPUT_KEY* keyOut);
KSTATUS SysPollKeyboard(INPUT_KEY* keyOut);
KSTATUS SysIsKeyDown(INPUT_KEY key, bool* downOut);
KSTATUS SysReadKeyboardChar(char* charOut);
KSTATUS SysReadKey(INPUT_KEY* keyOut);
uint32_t SysGetKeyModifiers(void);
uint32_t SysReadInputEvent(const SYS_INPUT_EVENT_REQUEST* request);
uint32_t SysPeekInputEvent(const SYS_INPUT_EVENT_REQUEST* request);
KSTATUS SysReadInputEvent(const SYS_INPUT_EVENT_REQUEST* request);
KSTATUS SysPeekInputEvent(const SYS_INPUT_EVENT_REQUEST* request);
uint32_t SysPeekMouse(INPUT_MOUSE_EVENT* eventOut);
uint32_t SysReadMouse(INPUT_MOUSE_EVENT* eventOut);
uint32_t SysGetMousePos(int* xOut, int* yOut);
KSTATUS SysPeekMouse(INPUT_MOUSE_EVENT* eventOut);
KSTATUS SysReadMouse(INPUT_MOUSE_EVENT* eventOut);
KSTATUS SysGetMousePos(int* xOut, int* yOut);
// Native sockets.
#define SYS_AF_INET 2u
@@ -722,9 +920,13 @@ uint32_t SysGetMousePos(int* xOut, int* yOut);
#define SYS_SOCKET_ADDRESS_SIZE 28u
// Socket addresses are tagged native records. For IPv4, Address[0..3]
// contains the address bytes. For IPv6, all 16 address bytes are used and
// ScopeId carries the zone index for scoped addresses. Port is host byte order.
// Socket addresses are tagged native records with one fixed ABI size. The
// syscall pointer-length parameter is the user-buffer bound and must be exactly
// SYS_SOCKET_ADDRESS_SIZE for input addresses; Size must also equal
// SYS_SOCKET_ADDRESS_SIZE after the kernel copies the fixed record. The macro is
// only the compile-time ABI constant. Address stores textual-order bytes
// (for example, 127,0,0,1), not an integer requiring byte-order conversion. Port
// is host byte order.
typedef struct SYS_SOCKET_ADDRESS {
uint16_t Family;
uint16_t Size;
@@ -772,6 +974,14 @@ typedef struct SYS_POLLFD {
uint32_t ReturnedEvents;
} SYS_POLLFD;
typedef struct SYS_POLL_REQUEST {
uint32_t Size;
uint32_t TimeoutMs;
SYS_POLLFD* Fds;
size_t Count;
size_t* ReadyOut;
} SYS_POLL_REQUEST;
#define SYS_ASYNC_SOCKET_FLAG_NONE 0x00000000u
#define SYS_ASYNC_SOCKET_OP_BIND 1u
@@ -826,21 +1036,21 @@ typedef struct SYS_ASYNC_SOCKET_REQUEST {
uint32_t* RequestHandleOut;
} SYS_ASYNC_SOCKET_REQUEST;
uint32_t SysCreateSocket(uint32_t domain, uint32_t type, uint32_t protocol, uint32_t* handleOut);
uint32_t SysBindSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize);
uint32_t SysListenSocket(uint32_t socket, uint32_t backlog);
uint32_t SysAcceptSocket(uint32_t socket, SYS_SOCKET_ADDRESS* remoteAddressOut, size_t* remoteAddressSizeInOut, uint32_t* acceptedHandleOut);
uint32_t SysConnectSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize);
uint32_t SysSendSocket(uint32_t socket, const void* buffer, size_t length, uint32_t flags, size_t* sentOut);
uint32_t SysRecvSocket(uint32_t socket, void* buffer, size_t length, uint32_t flags, size_t* receivedOut);
uint32_t SysShutdownSocket(uint32_t socket, uint32_t how);
uint32_t SysSendToSocket(uint32_t socket, const SYS_SOCKET_SEND_TO_REQUEST* request);
uint32_t SysRecvFromSocket(uint32_t socket, const SYS_SOCKET_RECV_FROM_REQUEST* request);
uint32_t SysResolveHost(const SYS_RESOLVE_HOST_REQUEST* request);
uint32_t SysSetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request);
uint32_t SysGetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request);
uint32_t SysPoll(SYS_POLLFD* fds, size_t count, uint32_t timeoutMs, size_t* readyOut);
uint32_t SysSocketIoAsync(const SYS_ASYNC_SOCKET_REQUEST* request);
KSTATUS SysCreateSocket(uint32_t domain, uint32_t type, uint32_t protocol, uint32_t* handleOut);
KSTATUS SysBindSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize);
KSTATUS SysListenSocket(uint32_t socket, uint32_t backlog);
KSTATUS SysAcceptSocket(uint32_t socket, SYS_SOCKET_ADDRESS* remoteAddressOut, size_t* remoteAddressSizeInOut, uint32_t* acceptedHandleOut);
KSTATUS SysConnectSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize);
KSTATUS SysSendSocket(uint32_t socket, const void* buffer, size_t length, uint32_t flags, size_t* sentOut);
KSTATUS SysRecvSocket(uint32_t socket, void* buffer, size_t length, uint32_t flags, size_t* receivedOut);
KSTATUS SysShutdownSocket(uint32_t socket, uint32_t how);
KSTATUS SysSendToSocket(uint32_t socket, const SYS_SOCKET_SEND_TO_REQUEST* request);
KSTATUS SysRecvFromSocket(uint32_t socket, const SYS_SOCKET_RECV_FROM_REQUEST* request);
KSTATUS SysResolveHost(const SYS_RESOLVE_HOST_REQUEST* request);
KSTATUS SysSetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request);
KSTATUS SysGetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request);
KSTATUS SysPoll(const SYS_POLL_REQUEST* request);
KSTATUS SysSocketIoAsync(const SYS_ASYNC_SOCKET_REQUEST* request);
typedef struct SYS_MEMORY_STATUS {
uint64_t FreePhysicalBytes;
@@ -866,12 +1076,28 @@ typedef struct SYS_MEMORY_STATUS {
#define SYS_KERNEL_STATS_FILESYSTEM 10u
#define SYS_KERNEL_STATS_DISK 11u
#define SYS_KERNEL_STATS_NET_IRP 12u
#define SYS_KERNEL_STATS_EXCEPTION 13u
// Public stats payloads start with Size and Version. Size is the byte count
// returned for that payload, including any trailing records. Version describes
// the field layout for fixed fields in the named payload.
#define SYS_STATS_VERSION 1u
typedef struct SYS_EXCEPTION_STATS {
uint32_t Size;
uint32_t Version;
uint64_t Delivered;
uint64_t UserRaised;
uint64_t Continued;
uint64_t Unhandled;
uint64_t InvalidContinue;
uint32_t MaxNestedDispatch;
uint32_t LastCode;
uintptr_t LastExceptionAddress;
uintptr_t LastFaultAddress;
} SYS_EXCEPTION_STATS;
typedef struct SYS_SCHEDULER_STATS {
uint32_t Size;
uint32_t Version;
@@ -1211,8 +1437,8 @@ typedef struct SYS_PTE_STATS {
// SysGetTickFrequency and is not a wall-clock timestamp.
uint64_t SysGetTick(void);
// SysGetTickFrequency returns the number of SysGetTick ticks per second.
uint32_t SysGetTickFrequency(uint64_t* frequencyOut);
// SysGetTickFrequency writes the number of SysGetTick ticks per second to frequencyOut.
KSTATUS SysGetTickFrequency(uint64_t* frequencyOut);
// Converts a tick delta to milliseconds using the supplied tick frequency.
static inline uint64_t SysTicksToMilliseconds(uint64_t ticks, uint64_t frequency) {
@@ -1226,9 +1452,9 @@ static inline uint64_t SysTicksToMicroseconds(uint64_t ticks, uint64_t frequency
return (ticks / frequency) * 1000000ull + ((ticks % frequency) * 1000000ull) / frequency;
}
uint32_t SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request);
uint32_t SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info);
KSTATUS SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request);
KSTATUS SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info);
uint32_t SysGetMemoryStatus(SYS_MEMORY_STATUS* statusOut);
uint32_t SysQueryKernelStats(uint32_t classId, void* buffer, size_t bufferSize, size_t* requiredSizeOut);
uint32_t SysGetSystemTime(SYS_SYSTEM_TIME* timeOut);
KSTATUS SysGetMemoryStatus(SYS_MEMORY_STATUS* statusOut);
KSTATUS SysQueryKernelStats(uint32_t classId, void* buffer, size_t bufferSize, size_t* requiredSizeOut);
KSTATUS SysGetSystemTime(SYS_SYSTEM_TIME* timeOut);