// Public NTLite syscall ABI declarations shared between kernel, drivers, and user mode. #pragma once #include #include #include #include #include #include #include #include #include #include #include // 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" #define SYS_TEB_MAGIC 0x30424554u // "TEB0" #define SYS_ENV_VERSION 1u #define SYS_CWD_MAX 520u #define SYS_PATH_MAX 1024u #ifndef SYS_USER_ENV_TYPES_DEFINED #define SYS_USER_ENV_TYPES_DEFINED 1 typedef struct SYS_PEB { uint32_t Magic; uint32_t Version; uint32_t ProcessId; SYS_STRING_VIEW ImagePath; SYS_STRING_VIEW CommandLine; SYS_STRING_VIEW CurrentDirectory; } SYS_PEB; typedef struct SYS_TEB { SYS_PEB* Peb; void* StackBase; void* StackLimit; struct SYS_TEB* Self; uint32_t ThreadId; uint32_t Magic; // The kernel leaves this NULL so personalities can attach per-thread state. void* SubsystemData; } SYS_TEB; #endif // SYS_USER_ENV_TYPES_DEFINED // Returns the current thread's process environment block. static inline SYS_PEB* SysGetPeb(void) { return (SYS_PEB*)(uintptr_t)__readgsqword(0); } // Returns the kernel-maintained current-directory cache from the PEB. static inline SYS_STRING_VIEW SysGetCurrentDirectoryView(void) { SYS_PEB* peb = SysGetPeb(); if (!peb || peb->Magic != SYS_PEB_MAGIC || peb->Version != SYS_ENV_VERSION) return SysSvFromParts("", 0); return peb->CurrentDirectory; } // Returns the current thread environment block. static inline SYS_TEB* SysGetTeb(void) { return (SYS_TEB*)(uintptr_t)__readgsqword(offsetof(SYS_TEB, Self)); } // APC and async I/O ABI. typedef struct SYS_IO_STATUS_BLOCK { volatile uint32_t Status; volatile uint64_t Information; } SYS_IO_STATUS_BLOCK; typedef void (*SYS_USER_APC_ROUTINE)(void* normalContext, SYS_IO_STATUS_BLOCK* iosb, uint64_t information); typedef struct SYS_FILE_IO_REQUEST { uint32_t FileHandle; uint32_t Flags; void* Buffer; size_t Size; size_t* TransferredOut; } SYS_FILE_IO_REQUEST; static inline SYS_FILE_IO_REQUEST SysMakeFileIoRequest(uint32_t fileHandle, const void* buffer, size_t size, size_t* transferredOut) { SYS_FILE_IO_REQUEST request; request.FileHandle = fileHandle; request.Flags = 0; request.Buffer = (void*)(uintptr_t)buffer; request.Size = size; request.TransferredOut = transferredOut; return request; } typedef struct SYS_ASYNC_FILE_REQUEST { uint32_t FileHandle; uint32_t EventHandle; // optional; 0 means no event signal uint32_t Flags; uint64_t Offset; // explicit byte offset; does not touch file pointer void* Buffer; size_t Size; 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 } SYS_ASYNC_FILE_REQUEST; // User APC frames are kernel-issued control records, not resume contexts. // User mode may read the routine and arguments, but SysApcReturn only accepts // the active frame token and restores the kernel-owned saved return state. typedef struct SYS_USER_APC_FRAME { uint64_t Magic; uint64_t ReturnToken; uint64_t Routine; uint64_t NormalContext; uint64_t SystemArgument1; uint64_t SystemArgument2; } SYS_USER_APC_FRAME; #define SYS_USER_APC_FRAME_MAGIC 0x3143504152455355ULL void SysUserApcDispatcher(void); // Trap-frame query ABI. typedef struct SYS_TRAP_FRAME_INFO { uint32_t Size; uint32_t Kind; uint32_t Vector; uint32_t PreviousMode; uint64_t Rip; uint64_t Cs; uint64_t Rflags; uint64_t Rsp; uint64_t Ss; uint64_t Rax; uint64_t Rcx; uint64_t Rdx; uint64_t R8; uint64_t R9; uint64_t R10; 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; SYS_STRING_VIEW CommandLine; uint32_t* HandleOut; } SYS_CREATE_PROCESS_REQUEST; typedef struct SYS_PATH_HANDLE_REQUEST { SYS_STRING_VIEW Path; uint32_t* HandleOut; } SYS_PATH_HANDLE_REQUEST; #define SYS_FILE_ACCESS_READ 0x00000001u #define SYS_FILE_ACCESS_WRITE 0x00000002u #define SYS_FILE_ACCESS_APPEND 0x00000004u #define SYS_FILE_ACCESS_QUERY 0x00000008u #define SYS_FILE_ACCESS_LOCK 0x00000010u #define SYS_FILE_OPEN_EXISTING 1u #define SYS_FILE_CREATE_NEW 2u #define SYS_FILE_CREATE_ALWAYS 3u #define SYS_FILE_OPEN_ALWAYS 4u #define SYS_FILE_TRUNCATE_EXISTING 5u #define SYS_FILE_FLAG_NONE 0x00000000u typedef struct SYS_OPEN_FILE_REQUEST { SYS_STRING_VIEW Path; uint32_t Access; uint32_t Disposition; uint32_t Flags; uint32_t* HandleOut; } SYS_OPEN_FILE_REQUEST; // Builds a flags-based file-open request. static inline SYS_OPEN_FILE_REQUEST SysMakeOpenFileRequest(SYS_STRING_VIEW path, uint32_t access, uint32_t disposition, uint32_t flags, uint32_t* handleOut) { SYS_OPEN_FILE_REQUEST request; request.Path = path; request.Access = access; request.Disposition = disposition; request.Flags = flags; request.HandleOut = handleOut; return request; } typedef struct SYS_PATH_REQUEST { SYS_STRING_VIEW Path; } SYS_PATH_REQUEST; #define SYS_REAL_PATH_FLAG_NONE 0x00000000u // SysRealPath returns a canonical native path of the form "N:/path". It uses // the kernel-owned process CWD for relative input, collapses '.', '..', and // repeated separators, and clamps parent traversal at the volume root. The // current filesystem model has no symlinks, so resolution is lexical and does // not require the final path to exist. RequiredSizeOut receives the byte count // including the terminating NUL; a NULL buffer with size zero only queries it. typedef struct SYS_REAL_PATH_REQUEST { uint32_t Size; uint32_t Flags; SYS_STRING_VIEW Path; char* Buffer; size_t BufferSize; size_t* RequiredSizeOut; } SYS_REAL_PATH_REQUEST; typedef struct SYS_STAT_FILE_REQUEST { SYS_STRING_VIEW Path; SYS_FILE_STAT* StatOut; } SYS_STAT_FILE_REQUEST; typedef struct SYS_RENAME_FILE_REQUEST { SYS_STRING_VIEW OldPath; SYS_STRING_VIEW NewPath; } SYS_RENAME_FILE_REQUEST; #define SYS_FILE_LOCK_SHARED 1u #define SYS_FILE_LOCK_EXCLUSIVE 2u #define SYS_FILE_LOCK_FLAG_NONE 0x00000000u #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 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. typedef struct SYS_LOCK_FILE_REQUEST { uint32_t Size; uint32_t FileHandle; uint32_t Mode; uint32_t Flags; uint64_t Offset; uint64_t Length; uint64_t TimeoutMilliseconds; } SYS_LOCK_FILE_REQUEST; typedef struct SYS_UNLOCK_FILE_REQUEST { uint32_t Size; uint32_t FileHandle; uint32_t Flags; uint64_t Offset; uint64_t Length; } SYS_UNLOCK_FILE_REQUEST; typedef struct SYS_WRITE_CONSOLE_REQUEST { SYS_STRING_VIEW Text; } SYS_WRITE_CONSOLE_REQUEST; 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; } SYS_OPEN_NAMED_QUEUE_REQUEST; typedef struct SYS_NAMED_QUEUE_OWNER_REQUEST { SYS_STRING_VIEW Name; uint32_t* ProcessHandleOut; } SYS_NAMED_QUEUE_OWNER_REQUEST; #define SYS_QUEUE_FLAG_NONE 0x00000000u #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 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 // pattern is a small control record with one pointer-sized payload token: the // shared address-space model means that token does not need translation when // both endpoints agree on the object lifetime. Queues order the token; they do // not copy storage behind it. typedef struct SYS_QUEUE_SEND_REQUEST { uint32_t Size; uint32_t QueueHandle; uint32_t Flags; uint64_t TimeoutMilliseconds; const void* Message; } SYS_QUEUE_SEND_REQUEST; typedef struct SYS_QUEUE_RECV_REQUEST { uint32_t Size; uint32_t QueueHandle; uint32_t Flags; uint64_t TimeoutMilliseconds; void* MessageOut; } SYS_QUEUE_RECV_REQUEST; #define SYS_WAIT_FLAG_NONE 0x00000000u #define SYS_WAIT_FLAG_ALERTABLE 0x00000001u #define SYS_WAIT_TIMEOUT_INFINITE UINT64_MAX // SysWaitMany copies handles through a fixed kernel stack buffer. This public // ABI/resource limit is intentionally small to keep wait setup bounded. #define SYS_WAIT_MANY_MAX_HANDLES 32u typedef struct SYS_WAIT_MANY_REQUEST { uint32_t Size; uint32_t Flags; const uint32_t* Handles; uint32_t Count; uint32_t* SignaledIndexOut; uint64_t TimeoutMilliseconds; } SYS_WAIT_MANY_REQUEST; typedef struct SYS_CREATE_THREAD_REQUEST { uintptr_t Entry; uintptr_t Argument; uint32_t Priority; uint32_t Flags; uint32_t* ThreadHandleOut; uint32_t* ThreadIdOut; } SYS_CREATE_THREAD_REQUEST; void SysExitProcess(int32_t exitCode); void SysExitThread(int32_t exitCode); 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. KSTATUS SysOpenInputQueue(uint32_t flags, uint32_t* handleOut); static inline KSTATUS SysWait(uint32_t handle, uint32_t flags) { return SysWaitSingle(handle, flags, SYS_WAIT_TIMEOUT_INFINITE); } 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 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 #define SYS_PROCESS_STATE_RUNNING 0u #define SYS_PROCESS_STATE_TERMINATING 1u #define SYS_PROCESS_STATE_EXITED 2u #define SYS_PROCESS_FLAG_SYSTEM 0x00000001u #define SYS_PROCESS_FLAG_CURRENT 0x00000002u #define SYS_PROCESS_FLAG_TERMINATING 0x00000004u #define SYS_PROCESS_FLAG_EXITED 0x00000008u #define SYS_PROCESS_FLAG_IDLE 0x00000010u #define SYS_PROCESS_FLAG_TERMINATION_PROTECTED 0x00000020u #define SYS_THREAD_STATE_READY 0u #define SYS_THREAD_STATE_RUNNING 1u #define SYS_THREAD_STATE_WAITING 2u #define SYS_THREAD_STATE_DEAD 3u #define SYS_THREAD_FLAG_CURRENT 0x00000001u #define SYS_THREAD_FLAG_IDLE 0x00000002u #define SYS_THREAD_FLAG_KERNEL 0x00000004u #define SYS_THREAD_FLAG_QUEUED 0x00000008u #define SYS_THREAD_FLAG_ALERTABLE_WAIT 0x00000010u #define SYS_THREAD_FLAG_KERNEL_APC_PENDING 0x00000020u #define SYS_THREAD_FLAG_USER_APC_PENDING 0x00000040u #define SYS_THREAD_WAIT_NONE 0u #define SYS_THREAD_WAIT_PROCESS 1u #define SYS_THREAD_WAIT_THREAD 2u #define SYS_THREAD_WAIT_MUTEX 3u #define SYS_THREAD_WAIT_SEMAPHORE 4u #define SYS_THREAD_WAIT_EVENT 5u #define SYS_THREAD_WAIT_QUEUE 6u #define SYS_THREAD_WAIT_FILE 7u #define SYS_THREAD_WAIT_DIR 8u #define SYS_THREAD_WAIT_ASYNC_IO 9u #define SYS_THREAD_WAIT_SOCKET 10u #define SYS_THREAD_WAIT_DEVICE 11u #define SYS_THREAD_WAIT_DRIVER 12u #define SYS_THREAD_WAIT_USB_DEVICE 13u #define SYS_THREAD_WAIT_USB_PIPE 14u #define SYS_THREAD_WAIT_FILE_MAPPING 15u #define SYS_THREAD_WAIT_SURFACE 16u #define SYS_THREAD_WAIT_TIMER 17u #define SYS_THREAD_WAIT_DISPLAY_CLOCK 18u #define SYS_THREAD_WAIT_UNKNOWN 0xffffffffu typedef struct SYS_THREAD_INFO { uint32_t Size; uint32_t ProcessId; uint32_t ThreadId; uint32_t State; uint32_t Priority; uint32_t Flags; uint32_t RunningCpu; uint32_t LastCpu; uint32_t QuantumRemaining; uint32_t QuantumTicks; uint32_t CpuBurstTicks; uint32_t LastRunTicks; uint32_t WaitObjectType; uint32_t WaitStatus; uint32_t KernelApcDisable; } SYS_THREAD_INFO; typedef struct SYS_PROCESS_INFO { uint32_t Size; uint32_t ProcessId; uint32_t State; uint32_t Flags; uint32_t ThreadCount; uint32_t HandleCount; // ModuleCount is the number of DLL-like process modules recorded by the loader. // The main executable image is reported separately through ImageBase/ImageSize. uint32_t ModuleCount; uint32_t CurrentDrive; int32_t ExitCode; uintptr_t ImageBase; size_t ImageSize; uintptr_t PebBase; size_t VadCount; 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; 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 #define SYS_LOAD_MODULE_FLAG_NONE 0u #define SYS_MODULE_FLAG_PUBLIC_REF 0x00000001u #define SYS_MODULE_FLAG_IMPORT_PINNED 0x00000002u #define SYS_MODULE_FLAG_UNLOADABLE 0x00000004u typedef struct SYS_MODULE_INFO { uint32_t Size; uint32_t Version; uint32_t Flags; uint32_t Reserved; uintptr_t Base; size_t ImageSize; uintptr_t EntryPoint; uint32_t PublicRefCount; uint32_t ImportRefCount; uint32_t TotalRefCount; uint32_t Reserved2; char Name[SYS_MODULE_NAME_MAX]; } SYS_MODULE_INFO; typedef struct SYS_LOAD_MODULE_REQUEST { uint32_t Size; uint32_t Flags; SYS_STRING_VIEW Path; uint32_t* ModuleHandleOut; SYS_MODULE_INFO* InfoOut; } SYS_LOAD_MODULE_REQUEST; typedef struct SYS_GET_MODULE_EXPORT_REQUEST { uint32_t Size; uint32_t ModuleHandle; SYS_STRING_VIEW Name; uintptr_t* AddressOut; } SYS_GET_MODULE_EXPORT_REQUEST; 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); KSTATUS SysCreateThread(const SYS_CREATE_THREAD_REQUEST* request); uint32_t SysGetCurrentTid(void); uint32_t SysGetCurrentPid(void); KSTATUS SysSetThreadPriority(uint32_t priority); KSTATUS SysYield(void); #define SYS_TIMER_FLAG_NONE 0u // Timer deadlines are relative millisecond delays. A zero due time makes the // timer signaled immediately; a zero period makes it one-shot. Setting an // already-set timer replaces the previous deadline and clears stale signal // state before applying the new schedule. typedef struct SYS_SET_TIMER_REQUEST { uint32_t Size; uint32_t TimerHandle; uint32_t Flags; uint64_t DueTimeMilliseconds; uint64_t PeriodMilliseconds; } SYS_SET_TIMER_REQUEST; 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. 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. 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 { SYS_VM_NOACCESS = 0, SYS_VM_READ = 1, SYS_VM_READWRITE = 2, SYS_VM_EXECUTE = 3, SYS_VM_EXECUTE_READ = 4, SYS_VM_EXECUTE_READWRITE = 5, } SYS_VM_PROTECTION; #define SYS_VM_FLAG_NONE 0u #define SYS_VM_FLAG_FIXED 1u typedef struct SYS_VM_REGION_INFO { void* Base; size_t PageCount; uint32_t Protect; uint32_t Flags; uint32_t Type; uint32_t OwnerPid; } SYS_VM_REGION_INFO; 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 #define SYS_MAP_ACCESS_COPY 0x00000004u #define SYS_MAP_ACCESS_EXECUTE 0x00000008u #define SYS_MAP_FLAG_NONE 0x00000000u KSTATUS SysCreateFileMapping(uint32_t fileHandle, uint32_t protect, uint32_t flags, uint64_t maximumSize, uint32_t* mappingHandleOut); KSTATUS SysMapFile(uint32_t mappingHandle, uint64_t offset, size_t size, uint32_t access, uint32_t flags, void** baseOut); KSTATUS SysCloseHandle(uint32_t handle); #define SYS_HANDLE_RIGHT_READ 0x00000001u #define SYS_HANDLE_RIGHT_WRITE 0x00000002u #define SYS_HANDLE_RIGHT_WAIT 0x00000004u #define SYS_HANDLE_RIGHT_SIGNAL 0x00000008u #define SYS_HANDLE_RIGHT_DUPLICATE 0x00000010u #define SYS_HANDLE_RIGHT_QUERY 0x00000020u #define SYS_HANDLE_RIGHT_TERMINATE 0x00000040u #define SYS_HANDLE_RIGHT_LOCK 0x00000080u #define SYS_HANDLE_RIGHT_ALL 0x000000FFu #define SYS_DUPLICATE_HANDLE_FLAG_NONE 0x00000000u #define SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS 0x00000001u typedef struct SYS_DUPLICATE_HANDLE_REQUEST { uint32_t SourceHandle; uint32_t TargetProcessHandle; uint32_t DesiredRights; uint32_t Flags; uint32_t* TargetHandleOut; } SYS_DUPLICATE_HANDLE_REQUEST; KSTATUS SysDuplicateHandle(const SYS_DUPLICATE_HANDLE_REQUEST* request); KSTATUS SysCreateMutex(uint32_t* handleOut); KSTATUS SysTryAcquireMutex(uint32_t handle); KSTATUS SysReleaseMutex(uint32_t handle); KSTATUS SysCreateSem(int32_t initial, int32_t max, uint32_t* handleOut); KSTATUS SysTryWaitSem(uint32_t handle); KSTATUS SysSignalSem(uint32_t handle); KSTATUS SysCreateEvent(uint32_t type, uint32_t initialState, uint32_t* handleOut); KSTATUS SysSignalEvent(uint32_t handle); KSTATUS SysClearEvent(uint32_t handle); 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); 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); 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 { uint32_t Columns; uint32_t Rows; uint32_t CursorX; uint32_t CursorY; uint16_t Attribute; } SYS_CONSOLE_INFO; 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); // Display clocks are waitable pacing objects. Providers with frame-event // support signal them once per submitted frame. Other providers use the BSP // scheduler tick, with PeriodMilliseconds rounded up to one or more ticks. #define SYS_DISPLAY_CLOCK_FLAG_NONE 0u #define SYS_DISPLAY_CLOCK_DEFAULT_PERIOD_MS 1ull typedef struct SYS_OPEN_DISPLAY_CLOCK_REQUEST { uint32_t Size; uint32_t Flags; uint64_t PeriodMilliseconds; uint32_t* HandleOut; } SYS_OPEN_DISPLAY_CLOCK_REQUEST; KSTATUS SysOpenDisplayClock(const SYS_OPEN_DISPLAY_CLOCK_REQUEST* request); // Input. #define SYS_INPUT_QUEUE_FLAG_NONE 0x00000000u #define SYS_INPUT_EVENT_FLAG_NONE 0x00000000u #define SYS_GLOBAL_INPUT_STATE_FLAG_NONE 0x00000000u #define SYS_GLOBAL_INPUT_KEY_BYTES 32u // SysQueryGlobalInputState snapshots the current physical input state. It does // not consume queued keyboard or mouse events and is intentionally global; a // later routed input context API should use a context handle instead. typedef struct SYS_GLOBAL_INPUT_STATE { uint32_t Size; uint32_t Flags; uint64_t Generation; uint32_t Modifiers; uint8_t KeyDown[SYS_GLOBAL_INPUT_KEY_BYTES]; int32_t MouseX; int32_t MouseY; int32_t MouseWheel; uint32_t MouseButtons; } SYS_GLOBAL_INPUT_STATE; // 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 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; uint32_t Flags; uint64_t TimeoutMilliseconds; INPUT_KEY_RECORD* RecordOut; } SYS_INPUT_EVENT_REQUEST; 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); KSTATUS SysQueryGlobalInputState(SYS_GLOBAL_INPUT_STATE* stateOut); KSTATUS SysReadInputEvent(const SYS_INPUT_EVENT_REQUEST* request); KSTATUS SysPeekInputEvent(const SYS_INPUT_EVENT_REQUEST* request); 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 #define SYS_AF_INET6 10u #define SYS_SOCK_STREAM 1u #define SYS_SOCK_DGRAM 2u #define SYS_SOCK_RAW 3u #define SYS_IPPROTO_ICMP 1u #define SYS_IPPROTO_TCP 6u #define SYS_IPPROTO_UDP 17u #define SYS_IPPROTO_ICMPV6 58u #define SYS_RESOLVE_HOST_NAME_MAX 255u #define SYS_SOCKET_OPT_RECV_TIMEOUT_MS 1u #define SYS_SOCKET_OPT_SEND_TIMEOUT_MS 2u #define SYS_SOCKET_OPT_NONBLOCKING 3u #define SYS_POLL_READ 0x0001u #define SYS_POLL_WRITE 0x0002u #define SYS_POLL_ERROR 0x0004u #define SYS_POLL_HANGUP 0x0008u #define SYS_POLL_INVALID 0x0010u #define SYS_POLL_TIMEOUT_INFINITE 0xFFFFFFFFu #define SYS_SHUTDOWN_READ 0u #define SYS_SHUTDOWN_WRITE 1u #define SYS_SHUTDOWN_BOTH 2u #define SYS_SOCKET_ADDRESS_SIZE 28u // 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; uint16_t Port; uint8_t Address[16]; uint32_t ScopeId; } SYS_SOCKET_ADDRESS; typedef struct SYS_SOCKET_SEND_TO_REQUEST { const void* Buffer; size_t Length; uint32_t Flags; const SYS_SOCKET_ADDRESS* RemoteAddress; size_t RemoteAddressSize; size_t* SentOut; } SYS_SOCKET_SEND_TO_REQUEST; typedef struct SYS_SOCKET_RECV_FROM_REQUEST { void* Buffer; size_t Length; uint32_t Flags; SYS_SOCKET_ADDRESS* RemoteAddressOut; size_t* RemoteAddressSizeInOut; size_t* ReceivedOut; } SYS_SOCKET_RECV_FROM_REQUEST; typedef struct SYS_RESOLVE_HOST_REQUEST { SYS_STRING_VIEW Name; uint32_t Family; uint32_t Flags; SYS_SOCKET_ADDRESS* AddressOut; size_t* AddressSizeInOut; } SYS_RESOLVE_HOST_REQUEST; typedef struct SYS_SOCKET_OPTION_REQUEST { uint32_t Option; void* Value; size_t ValueSize; size_t* ActualSizeOut; } SYS_SOCKET_OPTION_REQUEST; typedef struct SYS_POLLFD { uint32_t Handle; uint32_t Events; 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 #define SYS_ASYNC_SOCKET_OP_LISTEN 2u #define SYS_ASYNC_SOCKET_OP_ACCEPT 3u #define SYS_ASYNC_SOCKET_OP_CONNECT 4u #define SYS_ASYNC_SOCKET_OP_SEND 5u #define SYS_ASYNC_SOCKET_OP_RECV 6u #define SYS_ASYNC_SOCKET_OP_SEND_TO 7u #define SYS_ASYNC_SOCKET_OP_RECV_FROM 8u #define SYS_ASYNC_SOCKET_OP_SHUTDOWN 9u #define SYS_ASYNC_SOCKET_OP_SET_OPT 10u #define SYS_ASYNC_SOCKET_OP_GET_OPT 11u #define SYS_ASYNC_SOCKET_OP_POLL 12u // Async socket requests return operation-specific byte counts through Iosb. // Information is the byte count for send/receive, the accepted handle for // accept, returned poll events for poll, and the actual option byte count for // get-option. RequestHandleOut receives a waitable/cancellable async I/O handle // when the request is queued. A zero handle means the operation failed before // queueing. typedef struct SYS_ASYNC_SOCKET_REQUEST { uint32_t Size; uint32_t SocketHandle; uint32_t EventHandle; uint32_t Operation; uint32_t Flags; uint32_t SocketFlags; uint32_t Backlog; uint32_t ShutdownHow; uint32_t Option; uint32_t PollEvents; void* Buffer; size_t Length; const SYS_SOCKET_ADDRESS* Address; size_t AddressSize; SYS_SOCKET_ADDRESS* AddressOut; size_t* AddressSizeInOut; void* OptionValue; size_t OptionValueSize; size_t* OptionActualSizeOut; uint32_t* HandleOut; uint32_t* PollReturnedEventsOut; SYS_IO_STATUS_BLOCK* Iosb; SYS_USER_APC_ROUTINE ApcRoutine; void* ApcContext; uint32_t* RequestHandleOut; } SYS_ASYNC_SOCKET_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); // Cry some more, microkernel purists! 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; uint64_t KernelPoolBytes; uint64_t UserHeapBytes; uint64_t ReclaimablePhysicalBytes; uint64_t AvailablePhysicalBytes; uint64_t PinnedPhysicalBytes; uint64_t NonEvictablePhysicalBytes; uint64_t UserPhysicalBytes; uint64_t PageTablePhysicalBytes; } SYS_MEMORY_STATUS; #define SYS_KERNEL_STATS_SCHEDULER 1u #define SYS_KERNEL_STATS_PMM 2u #define SYS_KERNEL_STATS_CPU 3u #define SYS_KERNEL_STATS_PFN 4u #define SYS_KERNEL_STATS_PTE 5u #define SYS_KERNEL_STATS_VAD 6u #define SYS_KERNEL_STATS_SWAP 7u #define SYS_KERNEL_STATS_FILE_CACHE 8u #define SYS_KERNEL_STATS_SURFACE 9u #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; uint64_t Ticks; uint64_t ContextSwitches; uint64_t KeepCurrentDecisions; uint64_t IdleSelections; uint64_t Demotions; uint64_t AgingPromotions; uint64_t QuantumExpirations; uint64_t PriorityPreemptions; uint64_t VoluntaryBlocks; uint64_t CpuBurstDemotions; uint64_t SmtSiblingDeferrals; uint64_t SmtPrimaryPokes; } SYS_SCHEDULER_STATS; typedef struct SYS_PMM_STATS { uint32_t Size; uint32_t Version; uint64_t TotalFrames; uint64_t FreeFrames; uint64_t UsedFrames; uint64_t LargestFreeRun; uint64_t FreeRunCount; uint64_t FreeRunHistogram[8]; } SYS_PMM_STATS; #define SYS_CPU_THREAD_FLAG_IDLE 0x00000001u typedef struct SYS_CPU_STAT { uint32_t CpuIndex; uint32_t LapicId; uint32_t Flags; uint32_t CurrentTid; uint32_t CurrentThreadFlags; uint64_t SchedulerTicks; uint64_t ContextSwitches; } SYS_CPU_STAT; // CPU stats use trailing SYS_CPU_STAT records after the fixed header. typedef struct SYS_CPU_STATS { uint32_t Size; uint32_t Version; uint32_t HeaderSize; uint32_t CpuCount; uint32_t RecordSize; uint32_t RecordCount; } SYS_CPU_STATS; #define SYS_CPU_STATS_RECORDS(stats) ((SYS_CPU_STAT*)((uint8_t*)(stats) + sizeof(SYS_CPU_STATS))) #define SYS_CPU_STATS_CONST_RECORDS(stats) ((const SYS_CPU_STAT*)((const uint8_t*)(stats) + sizeof(SYS_CPU_STATS))) typedef struct SYS_PFN_STATS { uint32_t Size; uint32_t Version; uint64_t TotalFrames; uint64_t FreeFrames; uint64_t UsedFrames; uint64_t ReservedFrames; uint64_t ZeroedFrames; uint64_t ActiveFrames; uint64_t StandbyFrames; uint64_t ModifiedFrames; uint64_t PinnedFrames; uint64_t EvictableFrames; uint64_t NonEvictableFrames; uint64_t ReclaimableFrames; uint64_t AvailableFrames; uint64_t MappedFrames; uint64_t KernelFrames; uint64_t PageTableFrames; uint64_t UserFrames; uint64_t CleanFileCacheFrames; uint64_t ActiveCleanFileCacheFrames; uint64_t StandbyCleanFileCacheFrames; uint64_t ImageFrames; uint64_t ActiveImageFrames; uint64_t StandbyImageFrames; uint64_t MappedFileFrames; uint64_t AnonymousFrames; uint64_t CowFrames; uint64_t SurfaceFrames; uint64_t DriverFrames; uint64_t DmaFrames; uint64_t BootloaderFrames; uint64_t PfnDatabaseFrames; uint64_t MmioFrames; uint64_t AllocationCount; uint64_t FreeCount; uint64_t RetainCount; uint64_t ReleaseCount; uint64_t PinCount; uint64_t UnpinCount; uint64_t FailedAllocations; uint64_t FailedContiguousAllocations; uint64_t FailedInvalidRange; uint64_t FailedEmptyRange; uint64_t FailedReserveDenied; uint64_t FailedNoFrame; uint64_t FailedContiguousInvalidRequest; uint64_t FailedContiguousReserveDenied; uint64_t FailedContiguousNoRun; uint64_t ReclaimAttempts; uint64_t ReclaimPagesRequested; uint64_t ReclaimPagesSucceeded; uint64_t ReclaimPagesFailed; uint64_t ReclaimReentrantSkips; } SYS_PFN_STATS; typedef struct SYS_VAD_STATS { uint32_t Size; uint32_t Version; uint64_t ResolveFaultCalls; uint64_t ResolvedFaults; uint64_t FailedFaults; uint64_t ProtectionFaults; uint64_t NoVadFaults; uint64_t UncommittedFaults; uint64_t NoAccessFaults; uint64_t DemandZeroPages; uint64_t ZeroPageMaps; uint64_t ZeroPageCowSplits; uint64_t CowFaults; uint64_t CowPagesCopied; uint64_t CowViewsCreated; uint64_t CowPagesShared; uint64_t EnsureResidentCalls; uint64_t EnsureResidentPages; uint64_t AlreadyResidentPages; uint64_t FileBackedFaults; uint64_t FileBackedReads; uint64_t FileBackedReadFailures; uint64_t FileBackedDiscards; uint64_t FileBackedSharedWritableFaults; uint64_t FileBackedDirtyFaults; uint64_t FileBackedDirtySyncs; uint64_t ImageBackedFaults; uint64_t ImageBackedZeroFaults; uint64_t ImageBackedPrivateFaults; uint64_t ImageFixupPrivateCalls; uint64_t ImageFixupPrivatePages; uint64_t SwapPageOuts; uint64_t SwapPageIns; } SYS_VAD_STATS; typedef struct SYS_FILE_CACHE_STATS { uint32_t Size; uint32_t Version; uint64_t Lookups; uint64_t Hits; uint64_t Misses; uint64_t Loads; uint64_t LoadFailures; uint64_t RaceDiscards; uint64_t InflightWaits; uint64_t Invalidations; uint64_t DirtyPages; uint64_t MaxDirtyPages; uint64_t DirtyMarks; uint64_t WritebackRequests; uint64_t WritebackPages; uint64_t WritebackBytes; uint64_t WritebackFailures; uint64_t FlushFileCalls; uint64_t FlushFileFailures; uint64_t MappedDirtySyncs; uint64_t MappedDirtyPages; uint64_t Drops; uint64_t DropFailures; uint64_t StandbyTransitions; uint64_t StandbyHits; uint64_t ReadAheadRequests; uint64_t ReadAheadPagesRequested; uint64_t ReadAheadPagesQueued; uint64_t ReadAheadPagesLoaded; uint64_t ReadAheadPagesSkipped; uint64_t ReadAheadFailures; uint64_t ReadAheadPagesThrottled; uint64_t MaxReadAheadPagesPerRequest; uint64_t BatchReads; uint64_t BatchPagesRequested; uint64_t BatchPagesLoaded; uint64_t MaxBatchPagesRequested; uint64_t MaxBatchPagesLoaded; uint64_t ResidentPages; uint64_t ActivePages; uint64_t StandbyPages; uint64_t MaxResidentPages; } SYS_FILE_CACHE_STATS; // Filesystem stats are generic VFS/driver telemetry. Drivers should map // private metadata work onto these counters instead of exposing filesystem- // specific cache names through the public ABI. typedef struct SYS_FILESYSTEM_STATS { uint32_t Size; uint32_t Version; uint64_t PathLookups; uint64_t PathCacheHits; uint64_t PathCacheMisses; uint64_t PathCacheStores; uint64_t PathCacheInvalidations; uint64_t PathCacheGeneration; uint64_t DirectorySearches; uint64_t DirectoryBlocksRead; uint64_t DirectoryEntriesScanned; uint64_t DataReadRuns; uint64_t DataReadSectors; uint64_t DataReadRunMerges; uint64_t MaxDataReadSpanSectors; } SYS_FILESYSTEM_STATS; typedef struct SYS_DISK_STATS { uint32_t Size; uint32_t Version; uint64_t RegisteredDisks; uint64_t ReadRequests; uint64_t ReadSectors; uint64_t WriteRequests; uint64_t WriteSectors; uint64_t MaxReadSectors; uint64_t MaxWriteSectors; uint64_t ReadaheadHits; uint64_t ReadaheadMisses; uint64_t ReadaheadStores; uint64_t ReadaheadInvalidations; uint64_t ReadaheadBytesServed; uint64_t ReadaheadSectorsLoaded; uint64_t ReadaheadSequentialDetections; uint64_t ReadaheadSuppressed; uint64_t ReadaheadAllocFailures; uint64_t ReadaheadReadFailures; uint64_t MaxReadaheadSectors; } SYS_DISK_STATS; #define SYS_NET_IRP_OPERATION_COUNT 16u #define SYS_NET_IRP_OP_INVALID 0u #define SYS_NET_IRP_OP_CREATE 1u #define SYS_NET_IRP_OP_CLOSE 2u #define SYS_NET_IRP_OP_BIND 3u #define SYS_NET_IRP_OP_LISTEN 4u #define SYS_NET_IRP_OP_ACCEPT 5u #define SYS_NET_IRP_OP_CONNECT 6u #define SYS_NET_IRP_OP_SEND 7u #define SYS_NET_IRP_OP_RECEIVE 8u #define SYS_NET_IRP_OP_SEND_TO 9u #define SYS_NET_IRP_OP_RECEIVE_FROM 10u #define SYS_NET_IRP_OP_SHUTDOWN 11u #define SYS_NET_IRP_OP_SET_OPTION 12u #define SYS_NET_IRP_OP_GET_OPTION 13u #define SYS_NET_IRP_OP_POLL 14u #define SYS_NET_IRP_OP_RESOLVE_HOST 15u typedef struct SYS_NET_IRP_STATS { uint32_t Size; uint32_t Version; uint64_t Submitted; uint64_t Completed; uint64_t CompletedSynchronously; uint64_t CompletedAsynchronously; uint64_t Pending; uint64_t CancelRequested; uint64_t Cancelled; uint64_t WouldBlock; uint64_t Timeout; uint64_t Failed; uint64_t ByOperation[SYS_NET_IRP_OPERATION_COUNT]; } SYS_NET_IRP_STATS; typedef struct SYS_SWAP_STATS { uint32_t Size; uint32_t Version; uint64_t Enabled; uint64_t TotalSlots; uint64_t UsedSlots; uint64_t FreeSlots; uint64_t HighWaterSlots; uint64_t PageOuts; uint64_t PageIns; uint64_t PageOutFailures; uint64_t PageInFailures; uint64_t SlotAllocations; uint64_t SlotFrees; uint64_t SlotAllocationFailures; } SYS_SWAP_STATS; #define SYS_PTE_QUERY_GENERIC 0u #define SYS_PTE_QUERY_USER_PROBE 1u #define SYS_PTE_QUERY_HEAP 2u #define SYS_PTE_QUERY_VAD 3u #define SYS_PTE_QUERY_DEBUG 4u #define SYS_PTE_QUERY_SELF_TEST 5u #define SYS_PTE_QUERY_PURPOSE_COUNT 6u typedef struct SYS_PTE_STATS { uint32_t Size; uint32_t Version; uint64_t MapCalls; uint64_t MapFailures; uint64_t UnmapCalls; uint64_t UnmapFailures; uint64_t ProtectCalls; uint64_t ProtectFailures; uint64_t QueryCalls; uint64_t QueryFailures; uint64_t QueryByPurpose[SYS_PTE_QUERY_PURPOSE_COUNT]; uint64_t QueryFailuresByPurpose[SYS_PTE_QUERY_PURPOSE_COUNT]; uint64_t TranslateCalls; uint64_t LocalFlushes; uint64_t GlobalFlushes; uint64_t ShootdownRequests; uint64_t ShootdownTargetCpus; uint64_t ShootdownSkippedNoTargets; uint64_t ShootdownAcks; uint64_t ShootdownTimeouts; uint64_t NewMappingNoFlushes; uint64_t ReplacedMappingFlushes; uint64_t PageTablePagesAllocated; uint64_t CurrentLeafMappings; } SYS_PTE_STATS; #define SYS_CPU_FLAG_PRESENT 0x00000001u #define SYS_CPU_FLAG_STARTED 0x00000002u #define SYS_CPU_FLAG_PARKED 0x00000004u #define SYS_CPU_FLAG_ONLINE 0x00000008u #define SYS_CPU_FLAG_BSP 0x00000010u #define SYS_CPU_FLAG_PRIMARY 0x00000020u // Time and diagnostics. // SysGetTick returns monotonic ticks since boot. The tick unit is defined by // SysGetTickFrequency and is not a wall-clock timestamp. uint64_t SysGetTick(void); // 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) { if (!frequency) return 0; return (ticks / frequency) * 1000ull + ((ticks % frequency) * 1000ull) / frequency; } // Converts a tick delta to microseconds using the supplied tick frequency. static inline uint64_t SysTicksToMicroseconds(uint64_t ticks, uint64_t frequency) { if (!frequency) return 0; return (ticks / frequency) * 1000000ull + ((ticks % frequency) * 1000000ull) / frequency; } KSTATUS SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request); KSTATUS SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info); 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);