clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.

This commit is contained in:
maksw committed 2026-10-12 18:17:43 +02:00
1 parent 899225f551
commit c0ad63c27f
226 files changed
+6562 -4147

No files matched your search

+17
View File
@@ -2,20 +2,37 @@
#pragma once
#include <stdint.h>
unsigned __int64 __readgsqword(unsigned long offset);
long _InterlockedCompareExchange(long volatile* destination, long exchange, long comparand);
long _InterlockedExchange(long volatile* target, long value);
long _InterlockedIncrement(long volatile* addend);
long _InterlockedDecrement(long volatile* addend);
__int64 _InterlockedCompareExchange64(__int64 volatile* destination, __int64 exchange, __int64 comparand);
__int64 _InterlockedIncrement64(__int64 volatile* addend);
__int64 _InterlockedDecrement64(__int64 volatile* addend);
__int64 _InterlockedExchangeAdd64(__int64 volatile* addend, __int64 value);
void* _InterlockedCompareExchangePointer(void* volatile* destination, void* exchange, void* comparand);
void* _InterlockedExchangePointer(void* volatile* target, void* value);
void _ReadWriteBarrier(void);
void _mm_pause(void);
_Static_assert(sizeof(long) == sizeof(int32_t), "MSVC long must be 32-bit");
_Static_assert(sizeof(__int64) == sizeof(int64_t), "MSVC __int64 must be 64-bit");
#ifdef _MSC_VER
#pragma intrinsic(__readgsqword)
#pragma intrinsic(_InterlockedCompareExchange)
#pragma intrinsic(_InterlockedExchange)
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
#pragma intrinsic(_InterlockedCompareExchange64)
#pragma intrinsic(_InterlockedIncrement64)
#pragma intrinsic(_InterlockedDecrement64)
#pragma intrinsic(_InterlockedExchangeAdd64)
#pragma intrinsic(_InterlockedCompareExchangePointer)
#pragma intrinsic(_InterlockedExchangePointer)
#pragma intrinsic(_ReadWriteBarrier)
#pragma intrinsic(_mm_pause)
#endif
+4
View File
@@ -10,5 +10,9 @@ typedef __int64 ptrdiff_t;
#endif
#ifndef offsetof
#if defined(__clang__) || defined(__GNUC__)
#define offsetof(type, member) __builtin_offsetof(type, member)
#else
#define offsetof(type, member) ((size_t)&(((type*)0)->member))
#endif
#endif
+98
View File
@@ -0,0 +1,98 @@
// Fixed-width atomic operations for nt-lite-owned storage.
#pragma once
#include <stdint.h>
#include <intrin.h>
_Static_assert(sizeof(long) == sizeof(int32_t), "MSVC long must be 32-bit");
_Static_assert(sizeof(__int64) == sizeof(int64_t), "MSVC __int64 must be 64-bit");
// Atomically compares and exchanges a signed 32-bit value.
static __forceinline int32_t NtlAtomicCompareExchange32(volatile int32_t* destination,
int32_t exchange,
int32_t comparand) {
return (int32_t)_InterlockedCompareExchange((volatile long*)destination,
(long)exchange,
(long)comparand);
}
// Atomically loads a signed 32-bit value.
static __forceinline int32_t NtlAtomicLoad32(const volatile int32_t* source) {
return (int32_t)_InterlockedCompareExchange((volatile long*)source, 0, 0);
}
// Atomically compares and exchanges an unsigned 32-bit value.
static __forceinline uint32_t NtlAtomicCompareExchangeU32(volatile uint32_t* destination,
uint32_t exchange,
uint32_t comparand) {
return (uint32_t)_InterlockedCompareExchange((volatile long*)destination,
(long)exchange,
(long)comparand);
}
// Atomically loads an unsigned 32-bit value.
static __forceinline uint32_t NtlAtomicLoadU32(const volatile uint32_t* source) {
return (uint32_t)_InterlockedCompareExchange((volatile long*)source, 0, 0);
}
// Atomically exchanges an unsigned 32-bit value.
static __forceinline uint32_t NtlAtomicExchangeU32(volatile uint32_t* destination, uint32_t value) {
return (uint32_t)_InterlockedExchange((volatile long*)destination, (long)value);
}
// Atomically exchanges a signed 32-bit value.
static __forceinline int32_t NtlAtomicExchange32(volatile int32_t* destination, int32_t value) {
return (int32_t)_InterlockedExchange((volatile long*)destination, (long)value);
}
// Atomically increments a signed 32-bit value.
static __forceinline int32_t NtlAtomicIncrement32(volatile int32_t* destination) {
return (int32_t)_InterlockedIncrement((volatile long*)destination);
}
// Atomically decrements a signed 32-bit value.
static __forceinline int32_t NtlAtomicDecrement32(volatile int32_t* destination) {
return (int32_t)_InterlockedDecrement((volatile long*)destination);
}
// Atomically compares and exchanges a signed 64-bit value.
static __forceinline int64_t NtlAtomicCompareExchange64(volatile int64_t* destination,
int64_t exchange,
int64_t comparand) {
return (int64_t)_InterlockedCompareExchange64((volatile __int64*)destination,
(__int64)exchange,
(__int64)comparand);
}
// Atomically loads a signed 64-bit value.
static __forceinline int64_t NtlAtomicLoad64(const volatile int64_t* source) {
return (int64_t)_InterlockedCompareExchange64((volatile __int64*)source, 0, 0);
}
// Atomically increments a signed 64-bit value.
static __forceinline int64_t NtlAtomicIncrement64(volatile int64_t* destination) {
return (int64_t)_InterlockedIncrement64((volatile __int64*)destination);
}
// Atomically decrements a signed 64-bit value.
static __forceinline int64_t NtlAtomicDecrement64(volatile int64_t* destination) {
return (int64_t)_InterlockedDecrement64((volatile __int64*)destination);
}
// Atomically adds to a signed 64-bit value and returns the previous value.
static __forceinline int64_t NtlAtomicExchangeAdd64(volatile int64_t* destination, int64_t value) {
return (int64_t)_InterlockedExchangeAdd64((volatile __int64*)destination, (__int64)value);
}
// Atomically compares and exchanges a pointer value.
static __forceinline void* NtlAtomicCompareExchangePointer(void* volatile* destination,
void* exchange,
void* comparand) {
return _InterlockedCompareExchangePointer((void* volatile*)destination, exchange, comparand);
}
// Atomically exchanges a pointer value.
static __forceinline void* NtlAtomicExchangePointer(void* volatile* destination, void* value) {
return _InterlockedExchangePointer((void* volatile*)destination, value);
}
+6 -5
View File
@@ -3,10 +3,11 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/status.h>
#include <ntlite/handle.h>
#define SYS_AUDIO_ABI_VERSION 4u
#define SYS_AUDIO_ABI_VERSION 5u
#define SYS_AUDIO_MAX_ENDPOINTS 32u
#define SYS_AUDIO_STREAM_CAPACITY_FRAMES 4096u
@@ -64,7 +65,7 @@ typedef struct SYS_AUDIO_ENDPOINT_INFO {
uint32_t PeriodCount;
uint32_t FramesPerPeriod;
uint32_t MasterVolumeQ16;
uint32_t MasterMuted;
bool MasterMuted;
KSTATUS FailureStatus;
uint32_t Reserved;
} SYS_AUDIO_ENDPOINT_INFO;
@@ -157,7 +158,7 @@ typedef struct SYS_AUDIO_STREAM_INFO {
uint64_t DiscontinuityGeneration;
uint32_t VolumeQ16;
int32_t PanQ16;
uint8_t Muted;
bool Muted;
uint8_t ReservedBytes[7];
} SYS_AUDIO_STREAM_INFO;
@@ -167,7 +168,7 @@ typedef struct SYS_AUDIO_SET_VOLUME_REQUEST {
uint32_t Size;
uint32_t Flags;
SYS_HANDLE StreamHandle;
uint32_t Muted;
bool Muted;
uint32_t VolumeQ16;
int32_t PanQ16;
} SYS_AUDIO_SET_VOLUME_REQUEST;
@@ -177,7 +178,7 @@ typedef struct SYS_AUDIO_SET_MASTER_VOLUME_REQUEST {
uint32_t Size;
uint32_t Flags;
uint32_t EndpointId;
uint32_t Muted;
bool Muted;
uint32_t VolumeQ16;
} SYS_AUDIO_SET_MASTER_VOLUME_REQUEST;
+14
View File
@@ -2,6 +2,7 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/memory_map.h>
@@ -97,3 +98,16 @@ typedef struct BOOT_INFO {
// Firmware wall-clock snapshot taken before ExitBootServices.
BOOT_TIME BootTime;
} BOOT_INFO;
// BOOT_INFO is an x64 firmware-to-kernel binary handoff, not a private C structure.
_Static_assert(sizeof(uintptr_t) == 8u, "BOOT_INFO requires x64 pointers");
_Static_assert(sizeof(BOOT_TIME) == 20u, "BOOT_TIME ABI size changed");
_Static_assert(sizeof(BOOT_BLOB) == 16u, "BOOT_BLOB ABI size changed");
_Static_assert(sizeof(BOOT_FILE) == 80u, "BOOT_FILE ABI size changed");
_Static_assert(sizeof(BOOT_FILE_LIST) == 16u, "BOOT_FILE_LIST ABI size changed");
_Static_assert(sizeof(BOOT_IMAGE) == 32u, "BOOT_IMAGE ABI size changed");
_Static_assert(offsetof(BOOT_INFO, MemoryMap) == 16u, "BOOT_INFO MemoryMap offset changed");
_Static_assert(offsetof(BOOT_INFO, KernelImage) == 6200u, "BOOT_INFO KernelImage offset changed");
_Static_assert(offsetof(BOOT_INFO, BootDrivers) == 6280u, "BOOT_INFO BootDrivers offset changed");
_Static_assert(offsetof(BOOT_INFO, BootTime) == 6320u, "BOOT_INFO BootTime offset changed");
_Static_assert(sizeof(BOOT_INFO) == 6344u, "BOOT_INFO ABI size changed");
+17 -6
View File
@@ -55,7 +55,7 @@ typedef struct NTL_CONSOLE_REQUEST {
int32_t Y;
} Cursor;
struct {
char Character;
char Character; // One legacy ASCII display cell, never one UTF-8 code point.
uint8_t Reserved[3];
int32_t X;
int32_t Y;
@@ -69,7 +69,7 @@ typedef struct NTL_CONSOLE_REQUEST {
uint32_t Length;
} FillAttribute;
struct {
char Character;
char Character; // One legacy ASCII display cell, never one UTF-8 code point.
uint8_t Reserved[3];
int32_t X;
int32_t Y;
@@ -93,6 +93,14 @@ typedef struct NTL_CONSOLE_REPLY {
NTL_CONSOLE_INFO Info;
} NTL_CONSOLE_REPLY;
// RSSRV console IPC layout must agree with every native console client.
_Static_assert(sizeof(NTL_CONSOLE_INFO) == 48u, "NTL_CONSOLE_INFO ABI size changed");
_Static_assert(offsetof(NTL_CONSOLE_INFO, Generation) == 40u, "NTL_CONSOLE_INFO generation offset changed");
_Static_assert(sizeof(NTL_CONSOLE_REQUEST) == 544u, "NTL_CONSOLE_REQUEST ABI size changed");
_Static_assert(offsetof(NTL_CONSOLE_REQUEST, Data) == 24u, "NTL_CONSOLE_REQUEST payload offset changed");
_Static_assert(sizeof(NTL_CONSOLE_REPLY) == 80u, "NTL_CONSOLE_REPLY ABI size changed");
_Static_assert(offsetof(NTL_CONSOLE_REPLY, Status) == 16u, "NTL_CONSOLE_REPLY status offset changed");
#if defined(NTL_SYSCALL_STATIC)
#define NTL_CONSOLE_API
#elif defined(NTL_SYSCALL_BUILD)
@@ -105,12 +113,14 @@ NTL_CONSOLE_API KSTATUS NtlConsoleConnect(SYS_HANDLE* sessionOut);
NTL_CONSOLE_API KSTATUS NtlConsoleClose(SYS_HANDLE session);
NTL_CONSOLE_API KSTATUS NtlConsoleWrite(SYS_HANDLE session, const void* data, size_t length, size_t* writtenOut);
NTL_CONSOLE_API KSTATUS NtlConsoleQueryInfo(SYS_HANDLE session, NTL_CONSOLE_INFO* infoOut);
NTL_CONSOLE_API KSTATUS NtlConsoleSetCursor(SYS_HANDLE session, int x, int y);
NTL_CONSOLE_API KSTATUS NtlConsoleFillCharacter(SYS_HANDLE session, char character, int x, int y,
NTL_CONSOLE_API KSTATUS NtlConsoleSetCursor(SYS_HANDLE session, int32_t x, int32_t y);
// Legacy cell operations accept ASCII glyph codes only. Unicode text uses
// NtlConsoleWrite's byte stream until the RSSRV text renderer is upgraded.
NTL_CONSOLE_API KSTATUS NtlConsoleFillCharacter(SYS_HANDLE session, char character, int32_t x, int32_t y,
size_t length, size_t* writtenOut);
NTL_CONSOLE_API KSTATUS NtlConsoleFillAttribute(SYS_HANDLE session, uint16_t attribute, int x, int y,
NTL_CONSOLE_API KSTATUS NtlConsoleFillAttribute(SYS_HANDLE session, uint16_t attribute, int32_t x, int32_t y,
size_t length, size_t* writtenOut);
NTL_CONSOLE_API KSTATUS NtlConsolePutCharacter(SYS_HANDLE session, char character, int x, int y,
NTL_CONSOLE_API KSTATUS NtlConsolePutCharacter(SYS_HANDLE session, char character, int32_t x, int32_t y,
uint32_t foreground, uint32_t background);
NTL_CONSOLE_API KSTATUS NtlConsoleClear(SYS_HANDLE session, uint32_t color);
NTL_CONSOLE_API KSTATUS NtlConsoleReadInput(SYS_HANDLE session, uint64_t timeoutMilliseconds,
@@ -118,4 +128,5 @@ NTL_CONSOLE_API KSTATUS NtlConsoleReadInput(SYS_HANDLE session, uint64_t timeout
NTL_CONSOLE_API KSTATUS NtlConsolePeekInput(SYS_HANDLE session, uint64_t timeoutMilliseconds,
INPUT_KEY_RECORD* recordOut);
NTL_CONSOLE_API KSTATUS NtlConsoleFlushInput(SYS_HANDLE session);
// ASCII-only legacy key convenience function; use NtlConsoleReadInput for key events.
NTL_CONSOLE_API KSTATUS NtlConsoleReadCharacter(SYS_HANDLE session, char* characterOut);
+10 -10
View File
@@ -24,26 +24,26 @@ typedef struct DISPLAY_DEVICE_OPS {
KSTATUS (*GetMode)(DISPLAY_DEVICE* device, DISPLAY_MODE* outMode);
KSTATUS (*Blit)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
int32_t x, int32_t y, int32_t w, int32_t h,
const uint32_t* pixels,
uint32_t pitchBytes);
KSTATUS (*PresentPitched)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
int32_t x, int32_t y, int32_t w, int32_t h,
const uint32_t* pixels,
uint32_t pitchBytes);
KSTATUS (*FillRect)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
int32_t x, int32_t y, int32_t w, int32_t h,
uint32_t color);
KSTATUS (*CopyRect)(DISPLAY_DEVICE* device,
int dstX, int dstY,
int srcX, int srcY,
int w, int h);
int32_t dstX, int32_t dstY,
int32_t srcX, int32_t srcY,
int32_t w, int32_t h);
KSTATUS (*ReadRect)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
int32_t x, int32_t y, int32_t w, int32_t h,
uint32_t* outPixels, uint32_t outStride);
KSTATUS (*Present)(DISPLAY_DEVICE* device,
@@ -53,11 +53,11 @@ typedef struct DISPLAY_DEVICE_OPS {
KSTATUS (*Sync)(DISPLAY_DEVICE* device);
KSTATUS (*SetCursorImage)(DISPLAY_DEVICE* device,
int width, int height,
int hotX, int hotY,
int32_t width, int32_t height,
int32_t hotX, int32_t hotY,
const uint32_t* argbPixels);
KSTATUS (*SetCursorPosition)(DISPLAY_DEVICE* device, int x, int y);
KSTATUS (*SetCursorPosition)(DISPLAY_DEVICE* device, int32_t x, int32_t y);
KSTATUS (*ShowCursor)(DISPLAY_DEVICE* device, bool show);
KSTATUS (*QueryStats)(DISPLAY_DEVICE* device, DISPLAY_STATS* outStats);
+1 -1
View File
@@ -10,4 +10,4 @@ __declspec(dllexport) KSTATUS KeInputRegisterDevice(const char* name, uint32_t f
__declspec(dllexport) void KeInputSubmitKey(const INPUT_KEY_EVENT* event);
__declspec(dllexport) void KeInputSubmitMouse(const INPUT_MOUSE_EVENT* event);
__declspec(dllexport) void KeInputSubmitMouseAbsolute(const INPUT_MOUSE_ABSOLUTE_EVENT* event);
__declspec(dllexport) void KeInputSubmitMouseAbsoluteScaled(uint32_t rawX, uint32_t rawY, uint32_t maxX, uint32_t maxY, int wheel, uint8_t buttons);
__declspec(dllexport) void KeInputSubmitMouseAbsoluteScaled(uint32_t rawX, uint32_t rawY, uint32_t maxX, uint32_t maxY, int32_t wheel, uint8_t buttons);
+1 -1
View File
@@ -97,7 +97,7 @@ struct DEVICE_OBJECT {
uint32_t AlignmentRequirement;
SPINLOCK Lock;
volatile long OutstandingIrps;
volatile int32_t OutstandingIrps;
bool DeletePending;
SYS_STRING_VIEW Name;
+2 -1
View File
@@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
@@ -36,7 +37,7 @@ struct IO_ASYNC_REQUEST_OBJECT {
OBJECT Header;
LIST_ENTRY Link;
IO_ASYNC_REQUEST_STATE State;
uint8_t CancelRequested;
bool CancelRequested;
struct EVENT* WaitEvent;
struct EVENT* CompletionEvent;
struct KAPC* CompletionApc;
+4 -3
View File
@@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/status.h>
struct DEVICE_OBJECT;
@@ -52,7 +53,7 @@ typedef struct IO_AUDIO_PROVIDER_OPERATIONS {
// Stops DMA before unregister permits provider storage to be released.
void (*Stop)(void* providerContext);
// Applies endpoint gain and mute only with IO_AUDIO_ENDPOINT_CAP_HARDWARE_GAIN.
KSTATUS (*SetGain)(void* providerContext, int32_t gainMilliDb, uint8_t muted);
KSTATUS (*SetGain)(void* providerContext, int32_t gainMilliDb, bool muted);
} IO_AUDIO_PROVIDER_OPERATIONS;
// Registers one fixed-format render ring owned by a hardware provider.
@@ -61,7 +62,7 @@ typedef struct IO_AUDIO_ENDPOINT_REGISTRATION {
struct DEVICE_OBJECT* Device;
IO_AUDIO_ENDPOINT_KIND Kind;
uint32_t Capabilities;
uint8_t InitiallyAvailable;
bool InitiallyAvailable;
void* ProviderContext;
IO_AUDIO_PROVIDER_OPERATIONS Operations;
void* PeriodBuffer;
@@ -96,7 +97,7 @@ typedef struct NTL_DDK_AUDIO {
uint64_t timestampTicks);
// Updates jack-derived endpoint availability without changing endpoint identity.
void (*SetEndpointAvailable)(IO_AUDIO_ENDPOINT* endpoint, uint8_t available);
void (*SetEndpointAvailable)(IO_AUDIO_ENDPOINT* endpoint, bool available);
// Fails an endpoint and wakes every stream owner.
void (*ReportEndpointFailure)(IO_AUDIO_ENDPOINT* endpoint,
+1 -1
View File
@@ -43,4 +43,4 @@ typedef enum KE_PANIC_CODE {
__declspec(dllexport) void DbgPrint(const char* fmt, ...);
// Stops the system with a formatted diagnostic message.
__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...);
__declspec(dllexport) _Noreturn void KePanic(int32_t code, const char* fmt, ...);
+13 -13
View File
@@ -40,24 +40,24 @@ DISPLAY_API void KeDisplaySuspendConsole(bool suspend);
DISPLAY_API KSTATUS KeDisplayGetMode(DISPLAY_MODE* outMode);
// Queries the current display size.
DISPLAY_API KSTATUS KeDisplayGetSize(int* outWidth, int* outHeight);
DISPLAY_API KSTATUS KeDisplayGetSize(int32_t* outWidth, int32_t* outHeight);
DISPLAY_API KSTATUS KeDisplayBlit(int x, int y, int w, int h, const uint32_t* pixels);
DISPLAY_API KSTATUS KeDisplayBlitPitched(int x, int y, int w, int h, const uint32_t* pixels, uint32_t pitchBytes);
DISPLAY_API KSTATUS KeDisplayPresentPitched(int x, int y, int w, int h, const uint32_t* pixels, uint32_t pitchBytes);
DISPLAY_API KSTATUS KeDisplayFillRect(int x, int y, int w, int h, uint32_t color);
DISPLAY_API KSTATUS KeDisplayBlit(int32_t x, int32_t y, int32_t w, int32_t h, const uint32_t* pixels);
DISPLAY_API KSTATUS KeDisplayBlitPitched(int32_t x, int32_t y, int32_t w, int32_t h, const uint32_t* pixels, uint32_t pitchBytes);
DISPLAY_API KSTATUS KeDisplayPresentPitched(int32_t x, int32_t y, int32_t w, int32_t h, const uint32_t* pixels, uint32_t pitchBytes);
DISPLAY_API KSTATUS KeDisplayFillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
DISPLAY_API KSTATUS KeDisplayClear(uint32_t color);
DISPLAY_API KSTATUS KeDisplayCopyRect(int dstX, int dstY, int srcX, int srcY, int w, int h);
DISPLAY_API KSTATUS KeDisplayScroll(int lines);
DISPLAY_API KSTATUS KeDisplayPutChar(char c, int x, int y, uint32_t fg, uint32_t bg);
DISPLAY_API KSTATUS KeDisplayCopyRect(int32_t dstX, int32_t dstY, int32_t srcX, int32_t srcY, int32_t w, int32_t h);
DISPLAY_API KSTATUS KeDisplayScroll(int32_t lines);
DISPLAY_API KSTATUS KeDisplayPutChar(char c, int32_t x, int32_t y, uint32_t fg, uint32_t bg);
DISPLAY_API KSTATUS KeDisplayPrintChar(char c, uint32_t fg, uint32_t bg);
DISPLAY_API KSTATUS KeDisplayGetConsoleInfo(KE_CONSOLE_INFO* outInfo);
DISPLAY_API KSTATUS KeDisplaySetConsoleCursor(int col, int row);
DISPLAY_API KSTATUS KeDisplayFillConsoleChars(char c, int col, int row, size_t length, size_t* writtenOut);
DISPLAY_API KSTATUS KeDisplayFillConsoleAttrs(uint16_t attr, int col, int row, size_t length, size_t* writtenOut);
DISPLAY_API KSTATUS KeDisplaySetConsoleCursor(int32_t col, int32_t row);
DISPLAY_API KSTATUS KeDisplayFillConsoleChars(char c, int32_t col, int32_t row, size_t length, size_t* writtenOut);
DISPLAY_API KSTATUS KeDisplayFillConsoleAttrs(uint16_t attr, int32_t col, int32_t row, size_t length, size_t* writtenOut);
DISPLAY_API KSTATUS KeDisplayPresent(const DISPLAY_RECT* rects, size_t rectCount);
DISPLAY_API KSTATUS KeDisplaySync(void);
DISPLAY_API KSTATUS KeDisplayQueryInfo(KE_DISPLAY_INFO* outInfo);
DISPLAY_API KSTATUS KeDisplaySetCursorImage(int width, int height, int hotX, int hotY, const uint32_t* argbPixels);
DISPLAY_API KSTATUS KeDisplaySetCursorPosition(int x, int y);
DISPLAY_API KSTATUS KeDisplaySetCursorImage(int32_t width, int32_t height, int32_t hotX, int32_t hotY, const uint32_t* argbPixels);
DISPLAY_API KSTATUS KeDisplaySetCursorPosition(int32_t x, int32_t y);
DISPLAY_API KSTATUS KeDisplayShowCursor(bool show);
+1 -1
View File
@@ -21,7 +21,7 @@ struct KDPC {
void* Context;
void* SystemArgument1;
void* SystemArgument2;
volatile long Inserted;
volatile int32_t Inserted;
};
// Initializes a DPC object.
+5 -4
View File
@@ -3,6 +3,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
@@ -17,13 +18,13 @@ typedef struct EVENT {
OBJECT Header;
SPINLOCK Lock;
EVENT_TYPE Type;
uint32_t Signaled;
bool Signaled;
LIST_ENTRY WaitList;
LIST_ENTRY MultiWaitList;
} EVENT;
// Creates an event object.
__declspec(dllexport) KSTATUS KeEventCreate(EVENT_TYPE type, uint32_t initialState, EVENT** out);
__declspec(dllexport) KSTATUS KeEventCreate(EVENT_TYPE type, bool initialState, EVENT** out);
// Signals an event.
__declspec(dllexport) void KeSignalEvent(EVENT* event);
@@ -32,7 +33,7 @@ __declspec(dllexport) void KeSignalEvent(EVENT* event);
__declspec(dllexport) void KeClearEvent(EVENT* event);
// Waits for an event.
__declspec(dllexport) KSTATUS KeWaitForEvent(EVENT* event, uint8_t alertable);
__declspec(dllexport) KSTATUS KeWaitForEvent(EVENT* event, bool alertable);
// Attempts to wait for an event without blocking.
__declspec(dllexport) KSTATUS KeTryWaitEvent(EVENT* event);
@@ -40,6 +41,6 @@ __declspec(dllexport) KSTATUS KeTryWaitEvent(EVENT* event);
// Waits for one of several events.
__declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events,
uint32_t count,
uint8_t alertable,
bool alertable,
uint64_t timeoutMs,
uint32_t* signaledIndexOut);
+1 -1
View File
@@ -121,7 +121,7 @@ typedef struct IRP {
// Current remove-lock layout.
typedef struct IO_REMOVE_LOCK {
SPINLOCK Lock;
volatile long IoCount;
volatile int32_t IoCount;
bool Removing;
struct EVENT* RemovedEvent;
} IO_REMOVE_LOCK;
+2 -1
View File
@@ -3,6 +3,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
// Interrupt request level value used by DDK synchronization and IRP state.
typedef uint8_t KIRQL;
@@ -35,7 +36,7 @@ __declspec(dllexport) void KeAssertIrql(KIRQL expected);
__declspec(dllexport) void KeAssertIrqlAtOrBelow(KIRQL maxIrql);
// Returns nonzero when the current context may block.
__declspec(dllexport) int KeCanWait(void);
__declspec(dllexport) bool KeCanWait(void);
// Returns a diagnostic name for an IRQL.
__declspec(dllexport) const char* KeIrqlName(KIRQL irql);
+3 -2
View File
@@ -2,6 +2,7 @@
#pragma once
#include <stdbool.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
@@ -16,8 +17,8 @@ typedef struct MUTEX {
LIST_ENTRY OwnerLink;
KE_SCHEDULING_CLASS DonationClass;
uint32_t DonationPriority;
uint8_t HasDonation;
uint8_t Abandoned;
bool HasDonation;
bool Abandoned;
} MUTEX;
// Tests whether a mutex acquisition transferred ownership to the caller.
+3 -4
View File
@@ -24,7 +24,6 @@ typedef enum OBJECT_TYPE {
ObjectTypeUsbPipe = 14,
ObjectTypeFileMapping = 15,
ObjectTypeSurface = 16,
ObjectTypeInputQueue = 17,
ObjectTypeImageSection = 18,
ObjectTypeTimer = 19,
ObjectTypeDisplayClock = 20,
@@ -51,9 +50,9 @@ typedef enum OBJECT_LIFETIME_STATE {
// Object header embedded by kernel and driver-owned reference-counted objects.
typedef struct OBJECT {
OBJECT_TYPE Type;
volatile long RefCount;
volatile long LifetimeState;
volatile long Flags;
volatile int32_t RefCount;
volatile int32_t LifetimeState;
volatile uint32_t Flags;
void (*Destroy)(struct OBJECT* self);
} OBJECT;
+9 -7
View File
@@ -2,13 +2,15 @@
#pragma once
#include <ntlite/atomic.h>
#include <stdint.h>
#include <stdbool.h>
#include <intrin.h>
#include <ntlite/ddk/irql.h>
// Legacy spinlock storage used by current driver-visible objects.
typedef struct SPINLOCK {
volatile long Locked;
volatile int32_t Locked;
} SPINLOCK;
#define SPINLOCK_INIT { 0 }
@@ -43,7 +45,7 @@ static __forceinline uintptr_t KeAcquireSpinlock(SPINLOCK* sl) {
if (oldIrql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL);
while (_InterlockedCompareExchange(&sl->Locked, 1, 0) != 0)
while (NtlAtomicCompareExchange32(&sl->Locked, 1, 0) != 0)
_mm_pause();
return KiPackSpinlockCookie(flags, oldIrql);
@@ -54,7 +56,7 @@ static __forceinline void KeReleaseSpinlock(SPINLOCK* sl, uintptr_t cookie) {
uintptr_t flags = KiSpinlockCookieFlags(cookie);
KIRQL oldIrql = KiSpinlockCookieIrql(cookie);
_InterlockedExchange(&sl->Locked, 0);
NtlAtomicExchange32(&sl->Locked, 0);
// Restore the caller's hardware interrupt state before dropping to an
// IRQL that can dispatch APCs. PASSIVE_LEVEL with IF still clear is not a
@@ -64,23 +66,23 @@ static __forceinline void KeReleaseSpinlock(SPINLOCK* sl, uintptr_t cookie) {
}
// Attempts to acquire a spinlock without blocking.
static __forceinline int KeTryAcquireSpinlock(SPINLOCK* sl, uintptr_t* outCookie) {
static __forceinline bool KeTryAcquireSpinlock(SPINLOCK* sl, uintptr_t* outCookie) {
uintptr_t flags = KeDisableInterrupts();
KIRQL oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL);
if (_InterlockedCompareExchange(&sl->Locked, 1, 0) == 0) {
if (NtlAtomicCompareExchange32(&sl->Locked, 1, 0) == 0) {
*outCookie = KiPackSpinlockCookie(flags, oldIrql);
return 1;
return true;
}
// Keep the failed-acquire unwind consistent with normal release: restore
// IF before a PASSIVE transition can dispatch pending APCs.
KeRestoreInterrupts(flags);
KeLowerIrql(oldIrql);
return 0;
return false;
}
// Acquires a spinlock for DPC-level code.
+18 -6
View File
@@ -2,13 +2,15 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/display.h>
#include <ntlite/handle.h>
#include <ntlite/input.h>
#include <ntlite/status.h>
#define NTL_DESKTOP_PROTOCOL_VERSION 1u
#define NTL_DESKTOP_PROTOCOL_VERSION 2u
#define NTL_DESKTOP_SERVICE_PATH "/Sessions/0/Desktop"
#define NTL_DESKTOP_FLAG_NONE 0x00000000u
@@ -58,10 +60,10 @@ typedef struct NTL_DESKTOP_REPLY {
uint32_t Reserved;
NTL_WINDOW_ID WindowId;
DISPLAY_RECT Bounds;
uint32_t Visible;
uint32_t Focused;
uint32_t Captured;
uint32_t HasSurface;
bool Visible;
bool Focused;
bool Captured;
bool HasSurface;
uint32_t SurfaceWidth;
uint32_t SurfaceHeight;
} NTL_DESKTOP_REPLY;
@@ -79,6 +81,16 @@ typedef struct NTL_DESKTOP_EVENT {
INPUT_MOUSE_EVENT Mouse;
} NTL_DESKTOP_EVENT;
// DWM and clients exchange these versioned fixed-layout protocol messages.
_Static_assert(sizeof(NTL_DESKTOP_REQUEST) == 48u, "NTL_DESKTOP_REQUEST ABI size changed");
_Static_assert(offsetof(NTL_DESKTOP_REQUEST, WindowId) == 16u, "NTL_DESKTOP_REQUEST window offset changed");
_Static_assert(offsetof(NTL_DESKTOP_REPLY, Visible) == 48u, "NTL_DESKTOP_REPLY Visible offset changed");
_Static_assert(offsetof(NTL_DESKTOP_REPLY, SurfaceWidth) == 52u, "NTL_DESKTOP_REPLY SurfaceWidth offset changed");
_Static_assert(sizeof(NTL_DESKTOP_REPLY) == 64u, "NTL_DESKTOP_REPLY ABI size changed");
_Static_assert(offsetof(NTL_DESKTOP_REPLY, Status) == 16u, "NTL_DESKTOP_REPLY status offset changed");
_Static_assert(sizeof(NTL_DESKTOP_EVENT) == 56u, "NTL_DESKTOP_EVENT ABI size changed");
_Static_assert(offsetof(NTL_DESKTOP_EVENT, Key) == 32u, "NTL_DESKTOP_EVENT key offset changed");
#if defined(NTL_SYSCALL_STATIC)
#define NTL_DESKTOP_API
#elif defined(NTL_SYSCALL_BUILD)
@@ -100,7 +112,7 @@ NTL_DESKTOP_API KSTATUS NtlDesktopDestroyWindow(SYS_HANDLE session, NTL_WINDOW_I
NTL_DESKTOP_API KSTATUS NtlDesktopSetBounds(SYS_HANDLE session, NTL_WINDOW_ID window, const DISPLAY_RECT* bounds);
// Shows or hides one window without changing its z-order.
NTL_DESKTOP_API KSTATUS NtlDesktopSetVisible(SYS_HANDLE session, NTL_WINDOW_ID window, uint32_t visible);
NTL_DESKTOP_API KSTATUS NtlDesktopSetVisible(SYS_HANDLE session, NTL_WINDOW_ID window, bool visible);
// Moves one window to the top of the z-order.
NTL_DESKTOP_API KSTATUS NtlDesktopRaiseWindow(SYS_HANDLE session, NTL_WINDOW_ID window);
+9 -1
View File
@@ -7,7 +7,9 @@
// data types and capability bits. Kernel/driver provider interfaces live in
// <ntlite/ddi/display.h>.
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -55,7 +57,7 @@ typedef struct SYS_SURFACE_DESC {
uint64_t CommitClippedRectCount;
uint64_t CommitEmptyClipCount;
DISPLAY_RECT LastDamageBounds;
uint32_t LastDamageValid;
bool LastDamageValid;
uint32_t Reserved;
} SYS_SURFACE_DESC;
@@ -119,6 +121,12 @@ typedef struct SYS_DISPLAY_INFO {
DISPLAY_STATS DeviceStats;
} SYS_DISPLAY_INFO;
// Surfaces and damage rectangles are shared between DWM and native clients.
_Static_assert(sizeof(DISPLAY_PIXEL_FORMAT) == 4u, "DISPLAY_PIXEL_FORMAT ABI width changed");
_Static_assert(sizeof(DISPLAY_RECT) == 16u, "DISPLAY_RECT ABI size changed");
_Static_assert(offsetof(SYS_SURFACE_DESC, LastDamageBounds) == 80u, "SYS_SURFACE_DESC damage offset changed");
_Static_assert(sizeof(SYS_SURFACE_DESC) == 104u, "SYS_SURFACE_DESC ABI size changed");
#ifdef __cplusplus
}
#endif
+8 -7
View File
@@ -3,6 +3,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/syscall.h>
#if defined(NTL_EXCEPTION_EXPORTS)
@@ -11,14 +12,14 @@
#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)
#define NTL_EXCEPTION_CONTINUE_EXECUTION ((uint32_t)SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION)
#define NTL_EXCEPTION_CONTINUE_SEARCH ((uint32_t)SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH)
#define NTL_EXCEPTION_TERMINATE_PROCESS ((uint32_t)SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS)
typedef int (*NTL_EXCEPTION_HANDLER)(SYS_EXCEPTION_RECORD* record,
typedef uint32_t (*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);
NTL_EXCEPTION_API KSTATUS NtlInitializeExceptionRuntime(void);
NTL_EXCEPTION_API void* NtlAddExceptionHandler(bool first, NTL_EXCEPTION_HANDLER handler, void* context);
NTL_EXCEPTION_API KSTATUS NtlRemoveExceptionHandler(void* handle);
+6
View File
@@ -1,6 +1,7 @@
// Public NTLite file metadata ABI declarations shared between kernel, drivers, and user mode.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/time.h>
@@ -29,3 +30,8 @@ typedef struct SYS_FILE_STAT {
SYS_SYSTEM_TIME LastWriteTime;
SYS_SYSTEM_TIME ChangeTime;
} SYS_FILE_STAT;
// Native file metadata is copied between independently built modules.
_Static_assert(offsetof(SYS_FILE_STAT, FileId) == 32u, "SYS_FILE_STAT FileId offset changed");
_Static_assert(offsetof(SYS_FILE_STAT, CreationTime) == 40u, "SYS_FILE_STAT CreationTime offset changed");
_Static_assert(sizeof(SYS_FILE_STAT) == 200u, "SYS_FILE_STAT ABI size changed");
+4 -4
View File
@@ -43,7 +43,6 @@ typedef uint32_t SYS_RIGHTS;
// Queue-specific rights.
#define SYS_QUEUE_RIGHT_SEND 0x00000100u
#define SYS_QUEUE_RIGHT_RECEIVE 0x00000200u
#define SYS_QUEUE_RIGHT_PUBLISH 0x00000400u
// File-specific rights.
#define SYS_FILE_RIGHT_READ_DATA 0x00000100u
@@ -104,9 +103,6 @@ typedef uint32_t SYS_RIGHTS;
#define SYS_SURFACE_RIGHT_MAP_WRITE 0x00000200u
#define SYS_SURFACE_RIGHT_COMMIT 0x00000400u
// Input-queue rights.
#define SYS_INPUT_QUEUE_RIGHT_READ 0x00000100u
// Timer rights.
#define SYS_TIMER_RIGHT_SET 0x00000100u
@@ -118,3 +114,7 @@ typedef uint32_t SYS_RIGHTS;
// Rights normally retained by a newly created root capability.
#define SYS_RIGHT_MANAGE (SYS_RIGHT_DUPLICATE | SYS_RIGHT_DERIVE | SYS_RIGHT_REVOKE | SYS_RIGHT_TRANSFER)
// Native capability identifiers and access masks are 32-bit values.
_Static_assert(sizeof(SYS_HANDLE) == 4u, "SYS_HANDLE ABI width changed");
_Static_assert(sizeof(SYS_RIGHTS) == 4u, "SYS_RIGHTS ABI width changed");
+12 -7
View File
@@ -138,20 +138,25 @@ typedef struct INPUT_KEY_EVENT {
typedef struct INPUT_KEY_RECORD {
INPUT_KEY Key;
char Char;
char Char; // Legacy ASCII key translation, not a UTF-8 character.
uint32_t Modifiers;
} INPUT_KEY_RECORD;
typedef struct INPUT_MOUSE_EVENT {
int dx;
int dy;
int wheel;
int32_t dx;
int32_t dy;
int32_t wheel;
uint8_t buttons; // bit0=left, bit1=right, bit2=middle
} INPUT_MOUSE_EVENT;
typedef struct INPUT_MOUSE_ABSOLUTE_EVENT {
int x;
int y;
int wheel;
int32_t x;
int32_t y;
int32_t wheel;
uint8_t buttons; // bit0=left, bit1=right, bit2=middle
} INPUT_MOUSE_ABSOLUTE_EVENT;
_Static_assert(sizeof(INPUT_KEY_EVENT) == 4u, "INPUT_KEY_EVENT ABI size changed");
_Static_assert(sizeof(INPUT_KEY_RECORD) == 8u, "INPUT_KEY_RECORD ABI size changed");
_Static_assert(sizeof(INPUT_MOUSE_EVENT) == 16u, "INPUT_MOUSE_EVENT ABI size changed");
_Static_assert(sizeof(INPUT_MOUSE_ABSOLUTE_EVENT) == 16u, "INPUT_MOUSE_ABSOLUTE_EVENT ABI size changed");
+1 -1
View File
@@ -87,6 +87,6 @@ NTL_INPUT_API KSTATUS NtlInputReadKeyboardChar(char* charOut);
NTL_INPUT_API KSTATUS NtlInputReadKey(INPUT_KEY* keyOut);
NTL_INPUT_API uint32_t NtlInputGetKeyModifiers(void);
NTL_INPUT_API KSTATUS NtlInputQueryDefaultState(NTL_INPUT_STATE* stateOut);
NTL_INPUT_API KSTATUS NtlInputGetMousePos(int* xOut, int* yOut);
NTL_INPUT_API KSTATUS NtlInputGetMousePos(int32_t* xOut, int32_t* yOut);
#undef NTL_INPUT_API
+8
View File
@@ -3,6 +3,7 @@
#pragma once
// memory_map.h - shared between bootx64.efi and kernel.exe
// Describes physical memory layout passed from bootloader to kernel.
#include <stddef.h>
#include <stdint.h>
#define MEMORY_MAP_MAGIC 0x4D454D4D41500000ULL // 'MEMMAP\0\0'
@@ -30,3 +31,10 @@ typedef struct MEMORY_MAP {
uint32_t _pad;
MEMORY_REGION Regions[MEMORY_MAX_REGIONS];
} MEMORY_MAP;
// The bootloader and kernel must agree on physical memory handoff layout.
_Static_assert(sizeof(MEMORY_TYPE) == 4u, "MEMORY_TYPE ABI width changed");
_Static_assert(sizeof(MEMORY_REGION) == 24u, "MEMORY_REGION ABI size changed");
_Static_assert(offsetof(MEMORY_REGION, Type) == 16u, "MEMORY_REGION Type offset changed");
_Static_assert(offsetof(MEMORY_MAP, Regions) == 16u, "MEMORY_MAP Regions offset changed");
_Static_assert(sizeof(MEMORY_MAP) == 6160u, "MEMORY_MAP ABI size changed");
+7
View File
@@ -151,3 +151,10 @@ typedef struct SYS_REPLY_PORT_REQUEST {
const SYS_PORT_HANDLE_TRANSFER* Handles;
uint32_t HandleCount;
} SYS_REPLY_PORT_REQUEST;
// Port metadata and transfer descriptors cross the kernel/userspace boundary.
_Static_assert(sizeof(SYS_PORT_HANDLE_TRANSFER) == 12u, "SYS_PORT_HANDLE_TRANSFER ABI size changed");
_Static_assert(sizeof(SYS_PORT_MESSAGE_INFO) == 36u, "SYS_PORT_MESSAGE_INFO ABI size changed");
_Static_assert(offsetof(SYS_PORT_MESSAGE_INFO, SenderSecurityId) == 32u,
"SYS_PORT_MESSAGE_INFO sender identity offset changed");
_Static_assert(sizeof(SYS_PORT_CONNECTION_INFO) == 20u, "SYS_PORT_CONNECTION_INFO ABI size changed");
+9 -1
View File
@@ -2,6 +2,7 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/syscall.h>
@@ -155,13 +156,20 @@ typedef struct NTL_POSIX_SHARED_OPEN_DESCRIPTION {
uint32_t Type;
uint32_t Reserved;
uint64_t DescriptionId;
volatile long StatusFlags;
volatile uint32_t StatusFlags;
uint32_t Reserved2;
// Optional server-owned userspace data-plane pointer. Pipe endpoint
// descriptions use this for SYS_PIPE_SHARED_STATE; other types leave it zero.
uint64_t SharedObjectData;
} NTL_POSIX_SHARED_OPEN_DESCRIPTION;
_Static_assert(offsetof(NTL_POSIX_SHARED_OPEN_DESCRIPTION, StatusFlags) == 24u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION status layout changed");
_Static_assert(offsetof(NTL_POSIX_SHARED_OPEN_DESCRIPTION, SharedObjectData) == 32u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION data layout changed");
_Static_assert(sizeof(NTL_POSIX_SHARED_OPEN_DESCRIPTION) == 40u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION ABI size changed");
// Server-owned spawn/exec builders place this opaque personality payload
// in the generic userspace process-loader startup data. Zero token/PID/generation
// means an ordinary process is self-registering for the first time.
+2 -1
View File
@@ -3,6 +3,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#define NTL_POSIX_SIGNAL_HUP 1
#define NTL_POSIX_SIGNAL_INT 2
@@ -24,6 +25,6 @@
#define NTL_POSIX_SIGNAL_VALID_MASK ((1ull << NTL_POSIX_SIGNAL_MAX) - 1ull)
#define NTL_POSIX_SIGNAL_UNBLOCKABLE_MASK NTL_POSIX_SIGNAL_BIT(NTL_POSIX_SIGNAL_KILL)
static inline int NtlPosixSignalValid(int signalNumber) {
static inline bool NtlPosixSignalValid(int signalNumber) {
return signalNumber >= NTL_POSIX_SIGNAL_HUP && signalNumber <= NTL_POSIX_SIGNAL_MAX;
}
+25 -25
View File
@@ -13,7 +13,7 @@
#define NTL_PROCESS_LOAD_FLAG_NONE 0x00000000u
#define NTL_PROCESS_STARTUP_DATA_MAX 1024u
// Generic userspace process vectors. The builder copies every view into the
// Generic userspace process vectors. The loader copies every view into the
// child loader block; callers retain ownership of the source arrays/strings.
typedef struct NTL_PROCESS_STRING_VECTOR {
const SYS_STRING_VIEW* Entries;
@@ -28,16 +28,13 @@ typedef struct NTL_PROCESS_STARTUP_CAPABILITY {
uint32_t DuplicateFlags;
} NTL_PROCESS_STARTUP_CAPABILITY;
// Reusable inert-process builder used by policy services such as posixsrv.
// The storage is opaque to callers; initialize it to zero before first use.
#define NTL_PROCESS_BUILDER_OPAQUE_WORDS 160u
typedef struct NTL_PROCESS_BUILDER {
uintptr_t Opaque[NTL_PROCESS_BUILDER_OPAQUE_WORDS];
} NTL_PROCESS_BUILDER;
// Opaque preparation owned by the userspace process loader. A successful
// prepare returns one allocation consumed by Start or Abort; never copy it.
typedef struct NTL_PROCESS_PREPARATION NTL_PROCESS_PREPARATION;
// Describes construction of an inert child. Unlike NTL_CREATE_PROCESS_AT_REQUEST,
// preparation does not start the process and therefore has no output handle field.
typedef struct NTL_PROCESS_BUILDER_REQUEST {
typedef struct NTL_PREPARE_PROCESS_REQUEST {
uint32_t Size;
uint32_t Flags;
SYS_HANDLE RootHandle;
@@ -55,7 +52,7 @@ typedef struct NTL_PROCESS_BUILDER_REQUEST {
NTL_PROCESS_STRING_VECTOR Environment;
const void* StartupData;
size_t StartupDataSize;
} NTL_PROCESS_BUILDER_REQUEST;
} NTL_PREPARE_PROCESS_REQUEST;
// Creates and starts one PE32+ process entirely through the userspace image loader.
typedef struct NTL_CREATE_PROCESS_AT_REQUEST {
@@ -113,25 +110,28 @@ typedef struct NTL_CREATE_SYSTEM_PROCESS_REQUEST {
#define NTL_PROCESS_LOADER_API
#endif
// Prepares an inert child and materializes its image/dependencies/bootstrap data.
// imageFile may be SYS_HANDLE_INVALID to open request->Path relative to RootHandle.
NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderPrepare(NTL_PROCESS_BUILDER* builder,
const NTL_PROCESS_BUILDER_REQUEST* request,
SYS_HANDLE imageFile);
// Returns the prepared process capability without transferring ownership from the builder.
// The borrowed handle remains valid only until Start or Abort consumes the builder.
NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderGetProcessHandle(NTL_PROCESS_BUILDER* builder,
SYS_HANDLE* processHandleOut);
// Starts a prepared child and returns the retained process capability to the caller.
// On success the builder is consumed and reset to the empty state.
NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderStart(NTL_PROCESS_BUILDER* builder,
SYS_HANDLE* processHandleOut);
// Aborts a prepared child, terminating the inert native process and releasing loader state.
NTL_PROCESS_LOADER_API void NtlProcessBuilderAbort(NTL_PROCESS_BUILDER* builder);
// Allocates and prepares an inert child, including image, dependencies, inherited
// capabilities, and bootstrap data. On failure *preparationOut is NULL and no
// prepared process or child handle is retained. imageFile may be invalid to
// open request->Path relative to RootHandle.
NTL_PROCESS_LOADER_API KSTATUS NtlPrepareProcess(const NTL_PREPARE_PROCESS_REQUEST* request,
SYS_HANDLE imageFile,
NTL_PROCESS_PREPARATION** preparationOut);
// Borrows the native process capability without transferring ownership. This
// handle must not be closed by the caller and is valid only until Start/Abort.
NTL_PROCESS_LOADER_API KSTATUS NtlPreparedProcessGetHandle(
const NTL_PROCESS_PREPARATION* preparation, SYS_HANDLE* processHandleOut);
// Consumes one valid preparation on both success and ordinary start failure.
// On success returns the caller-owned native process capability. On failure
// the inert child is discarded and *processHandleOut is invalid.
NTL_PROCESS_LOADER_API KSTATUS NtlStartPreparedProcess(
NTL_PROCESS_PREPARATION* preparation, SYS_HANDLE* processHandleOut);
// Consumes one prepared child without starting it. NULL is accepted.
NTL_PROCESS_LOADER_API void NtlAbortPreparedProcess(NTL_PROCESS_PREPARATION* preparation);
NTL_PROCESS_LOADER_API KSTATUS NtlCreateProcessAt(const NTL_CREATE_PROCESS_AT_REQUEST* request);
NTL_PROCESS_LOADER_API KSTATUS NtlCreateSystemProcess(const NTL_CREATE_SYSTEM_PROCESS_REQUEST* request);
// Copies the optional opaque startup data supplied by the userspace process builder.
// Copies the optional opaque startup data supplied at process construction.
NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessStartupData(void* buffer,
size_t bufferSize,
size_t* sizeOut);
+1 -4
View File
@@ -14,7 +14,6 @@ typedef uint32_t SYS_SERVICE_CLAIMS;
#define SYS_PRIV_PROCESS_ENUMERATE 0x00000002u
#define SYS_PRIV_THREAD_ENUMERATE_ANY 0x00000004u
#define SYS_PRIV_KERNEL_DIAGNOSTICS 0x00000008u
#define SYS_PRIV_GLOBAL_INPUT 0x00000010u
#define SYS_PRIV_AUDIO_ACCESS 0x00000020u
#define SYS_PRIV_AUDIO_MASTER_CONTROL 0x00000040u
#define SYS_PRIV_CONSOLE_ACCESS 0x00000080u
@@ -24,9 +23,7 @@ typedef uint32_t SYS_SERVICE_CLAIMS;
#define SYS_PRIV_RAW_STORAGE 0x00000800u
#define SYS_PRIV_FILESYSTEM_PROVIDER 0x00001000u
#define SYS_PRIV_NETWORK_ACCESS 0x00002000u
// Allows publication into the legacy global named-queue registry; opening an explicitly published queue stays public.
#define SYS_PRIV_NAMED_QUEUE_PUBLISH 0x00004000u
#define SYS_PRIV_ALL 0x00007FFFu
#define SYS_PRIV_ALL 0x00003FEFu
// Service claims constrain which well-known service identities a privileged context may register.
#define SYS_SERVICE_CLAIM_RESOURCE 0x00000001u
+3
View File
@@ -92,3 +92,6 @@ typedef uint32_t KSTATUS;
#define KSUCCESS(status) (((KSTATUS)(status)) == NTLSTATUS_SUCCESS)
#define KFAILED(status) KSTATUS_IS_ERROR(status)
// Keep status codes as a fixed-width native ABI value.
_Static_assert(sizeof(KSTATUS) == 4u, "KSTATUS ABI width changed");
+123 -25
View File
@@ -2,11 +2,14 @@
#pragma once
// sys_string.h - shared native string-view ABI.
// A SYS_STRING_VIEW is a borrowed byte span. It is not NUL-terminated by
// contract and it does not own the pointed-to storage.
// A SYS_STRING_VIEW is a borrowed byte span. Length counts bytes, never Unicode
// scalar values or characters. The view is not NUL-terminated and owns no storage.
// Native names/text must contain strict UTF-8 (no normalization or case folding);
// generic byte payloads may use the same representation without becoming text.
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#ifndef SYS_STRING_VIEW_DEFINED
@@ -37,20 +40,114 @@ static inline SYS_STRING_VIEW SysSvFromCstr(const char* s) {
}
// Implements the sv Is Empty operation.
static inline int SysSvIsEmpty(SYS_STRING_VIEW s) {
static inline bool SysSvIsEmpty(SYS_STRING_VIEW s) {
return s.Length == 0;
}
// Implements the sv Is Valid operation.
static inline int SysSvIsValid(SYS_STRING_VIEW s) {
static inline bool SysSvIsValid(SYS_STRING_VIEW s) {
return s.Data != (const char*)0 || s.Length == 0;
}
// Validates well-formed UTF-8 bytes (RFC 3629). No normalization is performed.
// Rejects overlong encodings, surrogates, truncated sequences and > U+10FFFF.
static inline bool SysSvIsUtf8(SYS_STRING_VIEW view) {
if (!SysSvIsValid(view)) return false;
const uint8_t* data = (const uint8_t*)view.Data;
size_t i = 0;
while (i < view.Length) {
uint8_t lead = data[i++];
if (lead <= 0x7Fu) continue;
uint32_t scalar;
size_t continuation;
if (lead >= 0xC2u && lead <= 0xDFu) {
scalar = lead & 0x1Fu;
continuation = 1;
} else if (lead >= 0xE0u && lead <= 0xEFu) {
scalar = lead & 0x0Fu;
continuation = 2;
} else if (lead >= 0xF0u && lead <= 0xF4u) {
scalar = lead & 0x07u;
continuation = 3;
} else {
return false;
}
if (continuation > view.Length - i) return false;
for (size_t j = 0; j < continuation; ++j) {
uint8_t byte = data[i++];
if ((byte & 0xC0u) != 0x80u) return false;
scalar = (scalar << 6) | (uint32_t)(byte & 0x3Fu);
}
if ((continuation == 1 && scalar < 0x80u) ||
(continuation == 2 && scalar < 0x800u) ||
(continuation == 3 && scalar < 0x10000u) ||
(scalar >= 0xD800u && scalar <= 0xDFFFu) || scalar > 0x10FFFFu)
return false;
}
return true;
}
// Names and other retained native text forbid embedded NUL as well as bad UTF-8.
// Empty views, including the canonical null view, are valid text.
static inline bool SysSvIsUtf8Text(SYS_STRING_VIEW view) {
if (!SysSvIsUtf8(view)) return false;
for (size_t i = 0; i < view.Length; ++i)
if (view.Data[i] == '\0') return false;
return true;
}
// Copies external filename bytes into display-only UTF-8, replacing each invalid
// byte (including embedded NUL) with U+FFFD. Never splits a valid scalar or a
// replacement at the output capacity; always NUL-terminates when capacity > 0.
// This is a lossy display projection, not a native namespace identity mapping.
static inline size_t SysSvCopyUtf8WithReplacement(SYS_STRING_VIEW source,
char* destination,
size_t capacity) {
if (!destination || capacity == 0) return 0;
size_t read = 0;
size_t written = 0;
if (!SysSvIsValid(source)) {
destination[0] = '\0';
return 0;
}
while (read < source.Length) {
uint8_t first = (uint8_t)source.Data[read];
size_t sequenceLength = 0;
if (first >= 1u && first <= 0x7Fu) {
sequenceLength = 1;
} else if (first >= 0xC2u && first <= 0xDFu) {
sequenceLength = 2;
} else if (first >= 0xE0u && first <= 0xEFu) {
sequenceLength = 3;
} else if (first >= 0xF0u && first <= 0xF4u) {
sequenceLength = 4;
}
bool valid = sequenceLength && sequenceLength <= source.Length - read &&
SysSvIsUtf8(SysSvFromParts(source.Data + read, sequenceLength));
size_t appendLength = valid ? sequenceLength : 3u;
if (appendLength > capacity - written - 1u) break;
if (valid) {
memcpy(destination + written, source.Data + read, sequenceLength);
read += sequenceLength;
} else {
destination[written] = (char)0xEF;
destination[written + 1u] = (char)0xBF;
destination[written + 2u] = (char)0xBD;
++read;
}
written += appendLength;
}
destination[written] = '\0';
return written;
}
// Implements the sv Equal operation.
static inline int SysSvEqual(SYS_STRING_VIEW a, SYS_STRING_VIEW b) {
if (a.Length != b.Length) return 0;
if (a.Length == 0) return 1;
if (!a.Data || !b.Data) return 0;
static inline bool SysSvEqual(SYS_STRING_VIEW a, SYS_STRING_VIEW b) {
if (a.Length != b.Length) return false;
if (a.Length == 0) return true;
if (!a.Data || !b.Data) return false;
return memcmp(a.Data, b.Data, a.Length) == 0;
}
@@ -60,33 +157,33 @@ static inline char SysAsciiLower(char c) {
}
// Implements the sv Equal Ascii I operation.
static inline int SysSvEqualAsciiI(SYS_STRING_VIEW a, SYS_STRING_VIEW b) {
if (a.Length != b.Length) return 0;
if (a.Length == 0) return 1;
if (!a.Data || !b.Data) return 0;
static inline bool SysSvEqualAsciiI(SYS_STRING_VIEW a, SYS_STRING_VIEW b) {
if (a.Length != b.Length) return false;
if (a.Length == 0) return true;
if (!a.Data || !b.Data) return false;
for (size_t i = 0; i < a.Length; i++) {
if (SysAsciiLower(a.Data[i]) != SysAsciiLower(b.Data[i])) return 0;
if (SysAsciiLower(a.Data[i]) != SysAsciiLower(b.Data[i])) return false;
}
return 1;
return true;
}
// Implements the sv Equal Lit operation.
static inline int SysSvEqualLit(SYS_STRING_VIEW a, const char* lit) {
static inline bool SysSvEqualLit(SYS_STRING_VIEW a, const char* lit) {
return SysSvEqual(a, SysSvFromCstr(lit));
}
// Implements the sv Equal Lit Ascii I operation.
static inline int SysSvEqualLitAsciiI(SYS_STRING_VIEW a, const char* lit) {
static inline bool SysSvEqualLitAsciiI(SYS_STRING_VIEW a, const char* lit) {
return SysSvEqualAsciiI(a, SysSvFromCstr(lit));
}
// Implements the sv Contains Byte operation.
static inline int SysSvContainsByte(SYS_STRING_VIEW s, char ch) {
if (!s.Data && s.Length) return 0;
static inline bool SysSvContainsByte(SYS_STRING_VIEW s, char ch) {
if (!s.Data && s.Length) return false;
for (size_t i = 0; i < s.Length; i++) {
if (s.Data[i] == ch) return 1;
if (s.Data[i] == ch) return true;
}
return 0;
return false;
}
// Implements the sv Slice operation.
@@ -98,6 +195,7 @@ static inline SYS_STRING_VIEW SysSvSlice(SYS_STRING_VIEW s, size_t off, size_t l
// Implements the sv Trim Ascii operation.
static inline SYS_STRING_VIEW SysSvTrimAscii(SYS_STRING_VIEW s) {
if (!SysSvIsValid(s)) return SYS_SV_NULL;
size_t begin = 0;
size_t end = s.Length;
while (begin < end) {
@@ -114,14 +212,14 @@ static inline SYS_STRING_VIEW SysSvTrimAscii(SYS_STRING_VIEW s) {
}
// Implements the sv Copy Z operation.
static inline int SysSvCopyZ(char* dst, size_t dstSize, SYS_STRING_VIEW src) {
if (!dst || dstSize == 0) return 0;
if (src.Length && !src.Data) return 0;
static inline bool SysSvCopyZ(char* dst, size_t dstSize, SYS_STRING_VIEW src) {
if (!dst || dstSize == 0) return false;
if (src.Length && !src.Data) return false;
if (src.Length + 1 > dstSize) {
dst[0] = '\0';
return 0;
return false;
}
if (src.Length) memcpy(dst, src.Data, src.Length);
dst[src.Length] = '\0';
return 1;
return true;
}
+32 -92
View File
@@ -75,6 +75,15 @@ typedef struct SYS_TEB {
void* SubsystemData;
} SYS_TEB;
// User bootstrap is consumed by the kernel, loader and personalities.
_Static_assert(sizeof(SYS_STARTUP_CAPABILITY) == 8u, "SYS_STARTUP_CAPABILITY ABI size changed");
_Static_assert(offsetof(SYS_PEB, ImagePath) == 16u, "SYS_PEB ImagePath offset changed");
_Static_assert(offsetof(SYS_PEB, LoaderData) == 64u, "SYS_PEB LoaderData offset changed");
_Static_assert(sizeof(SYS_PEB) == 72u, "SYS_PEB ABI size changed");
_Static_assert(offsetof(SYS_TEB, Peb) == 0u, "SYS_TEB GS:[0] PEB pointer changed");
_Static_assert(offsetof(SYS_TEB, SubsystemData) == 40u, "SYS_TEB personality slot offset changed");
_Static_assert(sizeof(SYS_TEB) == 48u, "SYS_TEB ABI size changed");
#endif // SYS_USER_ENV_TYPES_DEFINED
// Returns the current thread's process environment block.
@@ -104,9 +113,13 @@ static inline SYS_TEB* SysGetTeb(void) {
// APC and async I/O ABI.
typedef struct SYS_IO_STATUS_BLOCK {
volatile uint32_t Status;
volatile KSTATUS Status;
volatile uint64_t Information;
} SYS_IO_STATUS_BLOCK;
// A completion status is a native KSTATUS even when written asynchronously.
_Static_assert(sizeof(SYS_IO_STATUS_BLOCK) == 16u, "SYS_IO_STATUS_BLOCK size changed");
_Static_assert(offsetof(SYS_IO_STATUS_BLOCK, Information) == 8u, "SYS_IO_STATUS_BLOCK Information offset changed");
typedef void (*SYS_USER_APC_ROUTINE)(void* normalContext,
SYS_IO_STATUS_BLOCK* iosb,
@@ -549,20 +562,27 @@ typedef struct SYS_PIPE_SHARED_STATE {
uint32_t Version;
uint32_t Capacity;
uint32_t HeaderBytes;
volatile long ReaderOpen;
volatile long WriterOpen;
volatile int32_t ReaderOpen;
volatile int32_t WriterOpen;
uint8_t HeaderReserved[SYS_PIPE_SHARED_HEADER_BYTES - 24u];
volatile uint64_t ReadPosition;
volatile uint64_t WritePosition;
volatile long ReadLock;
volatile long WriteLock;
volatile long ReadWaiters;
volatile long WriteWaiters;
volatile int32_t ReadLock;
volatile int32_t WriteLock;
volatile int32_t ReadWaiters;
volatile int32_t WriteWaiters;
uint8_t RingReserved[16];
uint8_t Buffer[SYS_PIPE_BUFFER_CAPACITY];
} SYS_PIPE_SHARED_STATE;
_Static_assert(offsetof(SYS_PIPE_SHARED_STATE, ReadPosition) == SYS_PIPE_SHARED_HEADER_BYTES,
"SYS_PIPE_SHARED_STATE control page layout changed");
_Static_assert(offsetof(SYS_PIPE_SHARED_STATE, Buffer) == SYS_PIPE_SHARED_HEADER_BYTES + 48u,
"SYS_PIPE_SHARED_STATE ring layout changed");
_Static_assert(sizeof(SYS_PIPE_SHARED_STATE) == SYS_PIPE_SHARED_HEADER_BYTES + 48u + SYS_PIPE_BUFFER_CAPACITY,
"SYS_PIPE_SHARED_STATE ABI size changed");
typedef struct SYS_CREATE_PIPE_REQUEST {
uint32_t Size;
uint32_t Flags;
@@ -581,32 +601,6 @@ 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 {
uint32_t Size;
SYS_STRING_VIEW Name;
SYS_HANDLE QueueHandle;
} SYS_PUBLISH_QUEUE_REQUEST;
typedef struct SYS_UNPUBLISH_QUEUE_REQUEST {
uint32_t Size;
SYS_STRING_VIEW Name;
} SYS_UNPUBLISH_QUEUE_REQUEST;
typedef struct SYS_OPEN_NAMED_QUEUE_REQUEST {
uint32_t Size;
SYS_STRING_VIEW Name;
SYS_HANDLE* HandleOut;
} SYS_OPEN_NAMED_QUEUE_REQUEST;
typedef struct SYS_NAMED_QUEUE_OWNER_REQUEST {
uint32_t Size;
SYS_STRING_VIEW Name;
SYS_RIGHTS DesiredAccess;
SYS_HANDLE* ProcessHandleOut;
} SYS_NAMED_QUEUE_OWNER_REQUEST;
#define SYS_QUEUE_FLAG_NONE 0x00000000u
#define SYS_QUEUE_MESSAGE_SIZE 56u
@@ -695,12 +689,6 @@ KSTATUS SysProtectProcessVm(SYS_HANDLE processHandle, void* base, size_t pageCou
KSTATUS SysStartProcess(const SYS_START_PROCESS_REQUEST* request);
KSTATUS SysWaitSingle(SYS_HANDLE 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, SYS_HANDLE* handleOut);
static inline KSTATUS SysWait(SYS_HANDLE handle, uint32_t flags) {
return SysWaitSingle(handle, flags, SYS_WAIT_TIMEOUT_INFINITE);
@@ -997,10 +985,6 @@ KSTATUS SysClearEvent(SYS_HANDLE handle);
KSTATUS SysCreateQueue(SYS_HANDLE* 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 SysCreatePort(const SYS_CREATE_PORT_REQUEST* request);
KSTATUS SysConnectPort(const SYS_CONNECT_PORT_REQUEST* request);
@@ -1058,7 +1042,7 @@ typedef struct SYS_CONSOLE_INFO {
KSTATUS SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request);
KSTATUS SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut);
KSTATUS SysSetConsoleCursor(int x, int y);
KSTATUS SysSetConsoleCursor(int32_t x, int32_t y);
typedef struct SYS_FILL_CONSOLE_CHARACTER_REQUEST {
uint32_t Size;
@@ -1109,7 +1093,7 @@ KSTATUS SysUnmapSurface(void* base);
KSTATUS SysQuerySurface(SYS_HANDLE surfaceHandle, SYS_SURFACE_DESC* descOut);
KSTATUS SysCommitSurface(SYS_HANDLE surfaceHandle, const DISPLAY_RECT* rects, uint32_t rectCount, uint64_t* generationOut);
KSTATUS SysClearScreen(uint32_t color);
KSTATUS SysGetScreenSize(int* widthOut, int* heightOut);
KSTATUS SysGetScreenSize(int32_t* widthOut, int32_t* heightOut);
KSTATUS SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut);
#define SYS_DISPLAY_MANAGER_CURSOR_FLAG_NONE 0x00000000u
@@ -1131,7 +1115,7 @@ KSTATUS SysPresentDisplayManagerSurface(SYS_HANDLE managerHandle, SYS_HANDLE sur
const DISPLAY_RECT* rects, uint32_t rectCount);
KSTATUS SysWriteDisplayManagerConsole(SYS_HANDLE managerHandle, const SYS_WRITE_CONSOLE_REQUEST* request);
KSTATUS SysQueryDisplayManagerConsoleInfo(SYS_HANDLE managerHandle, SYS_CONSOLE_INFO* infoOut);
KSTATUS SysSetDisplayManagerConsoleCursor(SYS_HANDLE managerHandle, int x, int y);
KSTATUS SysSetDisplayManagerConsoleCursor(SYS_HANDLE managerHandle, int32_t x, int32_t y);
KSTATUS SysFillDisplayManagerConsoleCharacter(SYS_HANDLE managerHandle, const SYS_FILL_CONSOLE_CHARACTER_REQUEST* request);
KSTATUS SysFillDisplayManagerConsoleAttribute(SYS_HANDLE managerHandle, const SYS_FILL_CONSOLE_ATTRIBUTE_REQUEST* request);
KSTATUS SysPutDisplayManagerConsoleCharacter(SYS_HANDLE managerHandle, const SYS_PUT_SCREEN_CHAR_REQUEST* request);
@@ -1178,50 +1162,6 @@ typedef struct SYS_INPUT_MANAGER_READ_REQUEST {
// Reads the next normalized physical input event through an input-manager capability.
KSTATUS SysReadInputManagerEvent(const SYS_INPUT_MANAGER_READ_REQUEST* request);
#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
// Legacy kernel-global input snapshot retained for compatibility. Normal interactive
// clients should consume RSSRV logical input through <ntlite/input_service.h>.
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;
SYS_HANDLE 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
@@ -1438,7 +1378,7 @@ typedef struct SYS_MEMORY_STATUS {
// 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 3u
#define SYS_STATS_VERSION 4u
typedef struct SYS_EXCEPTION_STATS {
@@ -1748,7 +1688,7 @@ typedef struct SYS_NET_IRP_STATS {
typedef struct SYS_SWAP_STATS {
uint32_t Size;
uint32_t Version;
uint64_t Enabled;
bool Enabled;
uint64_t TotalSlots;
uint64_t UsedSlots;
uint64_t FreeSlots;
+5
View File
@@ -1,6 +1,7 @@
// Public NTLite time ABI declarations shared between kernel, drivers, and user mode.
#pragma once
#include <stddef.h>
#include <stdint.h>
#define SYS_TIME_FLAG_VALID 0x0001u
@@ -31,3 +32,7 @@ typedef struct SYS_SYSTEM_TIME {
uint64_t EpochSeconds;
uint64_t TickMicroseconds;
} SYS_SYSTEM_TIME;
// File metadata and time syscalls share this fixed wall-clock representation.
_Static_assert(offsetof(SYS_SYSTEM_TIME, EpochSeconds) == 24u, "SYS_SYSTEM_TIME EpochSeconds offset changed");
_Static_assert(sizeof(SYS_SYSTEM_TIME) == 40u, "SYS_SYSTEM_TIME ABI size changed");