introduce a stable NTL_DDK driver ABI to replace direct HAL_API and kernel-header access in drivers, add code/kernel/io_ddk.c and code/public/ntlite/ddk/ headers, change DriverEntry to take (const NTL_DDK*, NTL_DRIVER_INIT*), update kmain to build the DDK once via IoInitializeDdk/IoGetDdk and hand it to both boot and runtime drivers, downgrade code/public/ntlite/ddi/io_driver.h to a legacy I/O model header pulling from ntlite/ddk instead of kernel internals, move code/third_party/lwip into code/drivers/net/lwip/third_party, fix up lwip_sources.txt and build.c include paths to match, split build.c's single CFLAGS macro into COMMON/KERNEL/USER/BOOT/DRIVER cflags.

This commit is contained in:
maksw committed 2026-07-01 23:19:11 +02:00
1 parent 08329516ba
commit 485a6bbfe7
385 files changed
+1822 -1079

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
// Public nt-lite DDK asynchronous request declarations.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
struct EVENT;
struct KAPC;
struct IRP;
typedef struct MM_LOCKED_USER_BUFFER MM_LOCKED_USER_BUFFER;
typedef struct IO_STATUS_BLOCK {
volatile KSTATUS Status;
volatile size_t Information;
} IO_STATUS_BLOCK;
typedef enum IO_ASYNC_REQUEST_STATE {
IoAsyncRequestQueued = 0,
IoAsyncRequestRunning = 1,
IoAsyncRequestCompleted = 2,
IoAsyncRequestCancelled = 3,
} IO_ASYNC_REQUEST_STATE;
typedef struct IO_ASYNC_REQUEST_OBJECT IO_ASYNC_REQUEST_OBJECT;
typedef void (*IO_ASYNC_REQUEST_CLEANUP_ROUTINE)(IO_ASYNC_REQUEST_OBJECT* request,
void* context);
typedef KSTATUS (*IO_ASYNC_REQUEST_CANCEL_ROUTINE)(IO_ASYNC_REQUEST_OBJECT* request,
void* context);
struct IO_ASYNC_REQUEST_OBJECT {
OBJECT Header;
LIST_ENTRY Link;
IO_ASYNC_REQUEST_STATE State;
uint8_t CancelRequested;
struct EVENT* WaitEvent;
struct EVENT* CompletionEvent;
struct KAPC* CompletionApc;
IO_STATUS_BLOCK* Iosb;
IO_STATUS_BLOCK IosbSnapshot;
MM_LOCKED_USER_BUFFER* LockedBuffer;
MM_LOCKED_USER_BUFFER* LockedIosb;
struct IRP* Irp;
IO_ASYNC_REQUEST_CLEANUP_ROUTINE CleanupRoutine;
void* CleanupContext;
IO_ASYNC_REQUEST_CANCEL_ROUTINE CancelRoutine;
void* CancelContext;
};
+44
View File
@@ -0,0 +1,44 @@
// Public nt-lite DDK root declarations.
#pragma once
#include <stdint.h>
#include <ntlite/ddk/async.h>
#include <ntlite/ddk/debug.h>
#include <ntlite/ddk/display.h>
#include <ntlite/ddk/dpc.h>
#include <ntlite/ddk/driver.h>
#include <ntlite/ddk/event.h>
#include <ntlite/ddk/file.h>
#include <ntlite/ddk/interrupt.h>
#include <ntlite/ddk/irql.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/memory.h>
#include <ntlite/ddk/mutex.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/platform.h>
#include <ntlite/ddk/scheduler.h>
#include <ntlite/ddk/semaphore.h>
#include <ntlite/ddk/settings.h>
#include <ntlite/ddk/sync.h>
#include <ntlite/ddk/thread.h>
#include <ntlite/ddk/time.h>
#include <ntlite/ddk/timer.h>
#define NTL_DDK_VERSION 1u
// Root DDK table passed to kernel drivers by the driver loader.
typedef struct NTL_DDK {
uint32_t Version;
const NTL_DDK_DEBUG* Debug;
const NTL_DDK_INTERRUPT* Interrupt;
const NTL_DDK_MEMORY* Memory;
const NTL_DDK_PLATFORM* Platform;
const NTL_DDK_SCHEDULER* Scheduler;
const NTL_DDK_TIMER* Timer;
} NTL_DDK;
// Driver initialization record filled by DriverEntry in the DDK-table model.
typedef struct NTL_DRIVER_INIT {
const char* Name;
} NTL_DRIVER_INIT;
+28
View File
@@ -0,0 +1,28 @@
// Public nt-lite DDK debugging declarations.
#pragma once
#include <ntlite/status.h>
// Driver-visible debug output service table passed through NTL_DDK.
typedef struct NTL_DDK_DEBUG {
void (*Print)(const char* fmt, ...);
} NTL_DDK_DEBUG;
// Current fatal categories used by kernel-mode driver diagnostics.
typedef enum KE_PANIC_CODE {
KE_PANIC_CODE_GENERIC = 0,
KE_PANIC_CODE_FAULT = 1,
KE_PANIC_CODE_IRQL = 2,
KE_PANIC_CODE_SELFTEST = 3,
KE_PANIC_CODE_TRAP = 4,
KE_PANIC_CODE_DRIVER = 5,
KE_PANIC_CODE_INIT = 6,
KE_PANIC_CODE_SCHEDULER = 7,
} KE_PANIC_CODE;
// Emits a formatted debug message on the active kernel debug outputs.
__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, ...);
+62
View File
@@ -0,0 +1,62 @@
// Public nt-lite DDK display-miniport declarations.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <ntlite/status.h>
#include <ntlite/ddi/display.h>
typedef struct KE_CONSOLE_INFO {
uint32_t Columns;
uint32_t Rows;
uint32_t CursorX;
uint32_t CursorY;
uint16_t Attribute;
} KE_CONSOLE_INFO;
typedef struct KE_DISPLAY_INFO {
char PrimaryName[32];
DISPLAY_MODE Mode;
uint32_t Caps;
uint32_t DeviceCount;
DISPLAY_STATS ManagerStats;
DISPLAY_STATS DeviceStats;
} KE_DISPLAY_INFO;
// Registers a display miniport device with the kernel display manager.
DISPLAY_API KSTATUS KeDisplayRegisterDevice(DISPLAY_DEVICE* device);
// Sets the primary display device.
DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device);
// Suspends or resumes fallback console drawing.
DISPLAY_API void KeDisplaySuspendConsole(bool suspend);
// Queries the current display mode.
DISPLAY_API KSTATUS KeDisplayGetMode(DISPLAY_MODE* outMode);
// Queries the current display size.
DISPLAY_API KSTATUS KeDisplayGetSize(int* outWidth, int* outHeight);
typedef KSTATUS (*KE_DISPLAY_ROW_SOURCE)(void* context, int rowIndex, uint32_t* scratch, size_t pixelCount);
DISPLAY_API KSTATUS KeDisplayBlit(int x, int y, int w, int h, const uint32_t* pixels);
DISPLAY_API KSTATUS KeDisplayBlitRows(int x, int y, int w, int h, KE_DISPLAY_ROW_SOURCE source, void* context, uint32_t* scratch);
DISPLAY_API KSTATUS KeDisplayFillRect(int x, int y, int w, int 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 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 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 KeDisplayShowCursor(bool show);
+35
View File
@@ -0,0 +1,35 @@
// Public nt-lite DDK default cursor declarations.
#pragma once
#include <stdint.h>
#define DISPLAY_DEFAULT_CURSOR_W 16
#define DISPLAY_DEFAULT_CURSOR_H 25
static const uint32_t gDisplayDefaultCursorArgb[DISPLAY_DEFAULT_CURSOR_H][DISPLAY_DEFAULT_CURSOR_W] = {
{ 0x7F575757, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFAFAFA, 0x855D5D5D, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFEFEFE, 0xFFFFFFFF, 0x865E5E5E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFDFDFD, 0xFFFDFDFD, 0xFFFFFFFF, 0x8A626262, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFDFDFD, 0xFFFFFFFF, 0x8D656565, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFDFDFD, 0xFFFFFFFF, 0x8E666666, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0x91696969, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFDFDFD, 0xFFFFFFFF, 0x946C6C6C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0x956D6D6D, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0x99717171, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0x9B737373, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0x9D757575, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFFFFFFF, 0xA0787878, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFDFDFD, 0xFFFDFDFD, 0xFFFCFCFC, 0xFFF9F9F9, 0xFFFFFFFF, 0xA1797979, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFEFEFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xAE868686, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFFFFFF, 0xFDD5D5D5, 0xF4CCCCCC, 0xF4CCCCCC, 0xF4CCCCCC, 0xF3CBCBCB, 0xF1C9C9C9, 0xFAD2D2D2, 0x7E565656 },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFEFEFE, 0xFFFCFCFC, 0xFFEFEFEF, 0xFFFCFCFC, 0xFFFFFFFF, 0x9A727272, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0xFFFEFEFE, 0xFFFDFDFD, 0xFFFFFFFF, 0x7F575757, 0x8F676767, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE0E0E0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFEFEFE, 0xFFFDFDFD, 0xFFFFFFFF, 0x90686868, 0x00000000, 0x00000000, 0xFFEBEBEB, 0xFFFFFFFF, 0xFFFFFFFF, 0x81595959, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFDFDFD, 0xFFFFFFFF, 0x8C646464, 0x00000000, 0x00000000, 0x00000000, 0xB78F8F8F, 0xFFFFFFFF, 0xFFFEFEFE, 0xECC4C4C4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xFFFFFFFF, 0x90686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x50282828, 0xFFF9F9F9, 0xFFFFFFFF, 0xFFFFFFFF, 0x623A3A3A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x865E5E5E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xD8B0B0B0, 0xFFFFFFFF, 0xFFFFFFFF, 0xCDA5A5A5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6C444444, 0xFFFFFFFF, 0xFFFCFCFC, 0xFFF4F4F4, 0x4D252525, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF2CACACA, 0xFFFFFFFF, 0xFFFFFFFF, 0x99717171, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8E666666, 0xEFC7C7C7, 0x7D555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
+35
View File
@@ -0,0 +1,35 @@
// Public nt-lite DDK deferred procedure call declarations.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/sync.h>
typedef struct KDPC KDPC;
typedef void (*KDEFERRED_ROUTINE)(KDPC* dpc,
void* context,
void* systemArgument1,
void* systemArgument2);
// Legacy DPC storage used by current kernel-mode drivers.
struct KDPC {
LIST_ENTRY Link;
KDEFERRED_ROUTINE Routine;
void* Context;
void* SystemArgument1;
void* SystemArgument2;
volatile long Inserted;
};
// Initializes a DPC object.
__declspec(dllexport) void KeInitializeDpc(KDPC* dpc,
KDEFERRED_ROUTINE routine,
void* context);
// Queues a DPC if it is not already queued.
__declspec(dllexport) bool KeInsertQueueDpc(KDPC* dpc,
void* systemArgument1,
void* systemArgument2);
+12
View File
@@ -0,0 +1,12 @@
// Public nt-lite DDK driver entry declarations.
#pragma once
#include <ntlite/status.h>
struct NTL_DDK;
struct NTL_DRIVER_INIT;
// Kernel driver entrypoint used by the future DDK-table driver model.
typedef KSTATUS (*NTL_DRIVER_ENTRY_FN)(const struct NTL_DDK* ddk,
struct NTL_DRIVER_INIT* init);
+45
View File
@@ -0,0 +1,45 @@
// Public nt-lite DDK event declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/sync.h>
typedef enum EVENT_TYPE {
EventAutoReset,
EventManualReset,
} EVENT_TYPE;
typedef struct EVENT {
OBJECT Header;
SPINLOCK Lock;
EVENT_TYPE Type;
uint32_t Signaled;
LIST_ENTRY WaitList;
LIST_ENTRY MultiWaitList;
} EVENT;
// Creates an event object.
__declspec(dllexport) KSTATUS KeEventCreate(EVENT_TYPE type, uint32_t initialState, EVENT** out);
// Signals an event.
__declspec(dllexport) void KeSignalEvent(EVENT* event);
// Clears an event.
__declspec(dllexport) void KeClearEvent(EVENT* event);
// Waits for an event.
__declspec(dllexport) KSTATUS KeWaitForEvent(EVENT* event, uint8_t alertable);
// Attempts to wait for an event without blocking.
__declspec(dllexport) KSTATUS KeTryWaitEvent(EVENT* event);
// Waits for one of several events.
__declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events,
uint32_t count,
uint8_t alertable,
uint64_t timeoutMs,
uint32_t* signaledIndexOut);
+132
View File
@@ -0,0 +1,132 @@
// Public nt-lite DDK filesystem declarations.
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <ntlite/status.h>
#include <ntlite/string_view.h>
#include <ntlite/dirent.h>
#include <ntlite/file_stat.h>
#include <ntlite/ddk/async.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/sync.h>
typedef SYS_DIR_ENTRY KDIR_ENTRY;
#define KDIR_NAME_MAX SYS_DIR_NAME_MAX
typedef void (*IO_FS_ASYNC_COMPLETE)(void* completeContext,
KSTATUS status,
size_t information);
typedef struct IO_FILESYSTEM_STATS {
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;
} IO_FILESYSTEM_STATS;
typedef struct IO_FILE_IDENTITY {
uint64_t VolumeId;
uint64_t FileId;
uint64_t Generation;
uint64_t Size;
} IO_FILE_IDENTITY;
typedef struct IO_FILESYSTEM {
KSTATUS (*Open)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void** fileCtx);
KSTATUS (*Read)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, void* buf, size_t size, size_t* bytesRead);
KSTATUS (*Write)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten);
KSTATUS (*ReadAsync)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext);
KSTATUS (*WriteAsync)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, const void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext);
KSTATUS (*Create)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void** fileCtx);
KSTATUS (*Delete)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path);
KSTATUS (*Rename)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath);
KSTATUS (*CreateDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path);
KSTATUS (*RemoveDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path);
KSTATUS (*Truncate)(struct IO_FILESYSTEM* fs, void* fileCtx, uint64_t newSize, uint32_t fileFlags);
uint64_t (*GetSize)(struct IO_FILESYSTEM* fs, void* fileCtx);
KSTATUS (*QueryInfo)(struct IO_FILESYSTEM* fs, void* fileCtx, SYS_FILE_STAT* out);
KSTATUS (*Stat)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW path, SYS_FILE_STAT* out);
KSTATUS (*QueryIdentity)(struct IO_FILESYSTEM* fs, void* fileCtx, IO_FILE_IDENTITY* out);
void (*Close)(struct IO_FILESYSTEM* fs, void* fileCtx);
void (*QueryStats)(struct IO_FILESYSTEM* fs, IO_FILESYSTEM_STATS* out);
void* DriverCtx;
KSTATUS (*OpenDir)(struct IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** dirCtx);
KSTATUS (*ReadDir)(struct IO_FILESYSTEM* fs, void* dirCtx, KDIR_ENTRY* out);
void (*CloseDir)(struct IO_FILESYSTEM* fs, void* dirCtx);
} IO_FILESYSTEM;
struct EVENT;
struct KAPC;
typedef struct MM_LOCKED_USER_BUFFER MM_LOCKED_USER_BUFFER;
typedef struct IO_ASYNC_FILE_REQUEST_OBJECT IO_ASYNC_FILE_REQUEST_OBJECT;
#define IO_FILE_FLAG_NO_CACHE 0x00000001u
#define IO_FILE_FLAG_SKIP_ZERO_EXTEND 0x00000002u
#define IO_FILE_FLAG_APPEND 0x00000004u
typedef struct FILE_OBJECT {
OBJECT Header;
IO_FILESYSTEM* Fs;
void* FileCtx;
SPINLOCK Lock;
uint64_t Size;
uint64_t Offset;
uint32_t Flags;
uint32_t ReadaheadScore;
uint64_t ReadaheadNextOffset;
uint64_t ReadaheadIssuedUntil;
uint64_t ReadaheadSuppressedUntil;
} FILE_OBJECT;
typedef struct DIR_OBJECT {
OBJECT Header;
IO_FILESYSTEM* Fs;
void* DirCtx;
} DIR_OBJECT;
typedef struct IO_VOLUME_PARAMS {
uint8_t DiskIndex;
uint64_t PartitionLba;
uint64_t PartitionSize;
} IO_VOLUME_PARAMS;
__declspec(dllexport) KSTATUS IoRegisterFilesystem(uint8_t driveIndex, IO_FILESYSTEM* fs, const IO_VOLUME_PARAMS* vol);
__declspec(dllexport) KSTATUS IoUnregisterFilesystem(uint8_t driveIndex);
__declspec(dllexport) KSTATUS IoUnregisterFilesystemsForDisk(uint8_t diskIndex);
__declspec(dllexport) bool IoFilesystemPresent(uint8_t driveIndex);
__declspec(dllexport) void IoQueryFilesystemStats(IO_FILESYSTEM_STATS* out);
__declspec(dllexport) KSTATUS IoOpenFile(SYS_STRING_VIEW path, FILE_OBJECT** out);
__declspec(dllexport) KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, size_t size, size_t* bytesRead);
__declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, void* buf, size_t size, size_t* bytesRead);
__declspec(dllexport) KSTATUS IoWriteFile(FILE_OBJECT* file, const void* buf, size_t size, size_t* bytesWritten);
__declspec(dllexport) KSTATUS IoWriteFileAt(FILE_OBJECT* file, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten);
__declspec(dllexport) KSTATUS IoFlushFile(FILE_OBJECT* file);
__declspec(dllexport) KSTATUS IoCreateFile(SYS_STRING_VIEW path, FILE_OBJECT** out);
__declspec(dllexport) KSTATUS IoDeleteFile(SYS_STRING_VIEW path);
__declspec(dllexport) KSTATUS IoRenameFile(SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath);
__declspec(dllexport) KSTATUS IoCreateDir(SYS_STRING_VIEW path);
__declspec(dllexport) KSTATUS IoRemoveDir(SYS_STRING_VIEW path);
__declspec(dllexport) KSTATUS IoTruncateFile(FILE_OBJECT* file, uint64_t newSize);
__declspec(dllexport) KSTATUS IoSeekFile(FILE_OBJECT* file, uint64_t offset);
__declspec(dllexport) uint64_t IoGetFileSize(FILE_OBJECT* file);
__declspec(dllexport) KSTATUS IoGetFileStat(FILE_OBJECT* file, SYS_FILE_STAT* out);
__declspec(dllexport) KSTATUS IoStatFile(SYS_STRING_VIEW path, SYS_FILE_STAT* out);
__declspec(dllexport) KSTATUS IoQueryFileIdentity(FILE_OBJECT* file, IO_FILE_IDENTITY* out);
__declspec(dllexport) void IoCloseFile(FILE_OBJECT* file);
__declspec(dllexport) KSTATUS IoOpenDir(SYS_STRING_VIEW dirPath, DIR_OBJECT** out);
__declspec(dllexport) KSTATUS IoReadDir(DIR_OBJECT* dir, KDIR_ENTRY* entryOut);
__declspec(dllexport) void IoCloseDir(DIR_OBJECT* dir);
__declspec(dllexport) KSTATUS IoSetCwd(SYS_STRING_VIEW path);
__declspec(dllexport) KSTATUS IoRealPath(SYS_STRING_VIEW path, char* buffer, size_t bufferSize, size_t* requiredSizeOut);
+17
View File
@@ -0,0 +1,17 @@
// Public nt-lite DDK interrupt declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
// Driver-visible interrupt services.
typedef struct NTL_DDK_INTERRUPT {
KSTATUS (*AllocateMsiVector)(uint8_t* outIrq);
} NTL_DDK_INTERRUPT;
// Allocates one kernel IRQ slot for MSI delivery.
__declspec(dllexport) KSTATUS KeIrqAllocateMsiVector(uint8_t* outIrq);
// Registers a legacy interrupt handler for an IRQ slot.
__declspec(dllexport) void KeIrqRegister(uint8_t irq, void (*handler)(void));
+226
View File
@@ -0,0 +1,226 @@
// Public nt-lite DDK IRP declarations.
#pragma once
// This is the legacy IRP shape made self-contained for DDK users. The next
// architectural step is to hide this layout behind request accessors.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/sync.h>
struct EVENT;
struct SEMAPHORE;
struct KAPC;
typedef struct DEVICE_OBJECT DEVICE_OBJECT;
// IRP major functions.
typedef enum IO_MAJOR_FUNCTION {
IRP_MJ_CREATE = 0,
IRP_MJ_CLOSE = 1,
IRP_MJ_READ = 2,
IRP_MJ_WRITE = 3,
IRP_MJ_DEVICE_CONTROL = 4,
IRP_MJ_INTERNAL_DEVICE_CONTROL = 5,
IRP_MJ_PNP = 6,
IRP_MJ_POWER = 7,
IRP_MJ_MAXIMUM_FUNCTION = 8,
} IO_MAJOR_FUNCTION;
// PnP minor functions.
typedef enum IO_PNP_MINOR_FUNCTION {
IRP_MN_START_DEVICE = 0,
IRP_MN_QUERY_REMOVE_DEVICE = 1,
IRP_MN_CANCEL_REMOVE_DEVICE = 2,
IRP_MN_SURPRISE_REMOVAL = 3,
IRP_MN_REMOVE_DEVICE = 4,
IRP_MN_QUERY_DEVICE_RELATIONS = 5,
IRP_MN_QUERY_ID = 6,
IRP_MN_QUERY_CAPABILITIES = 7,
} IO_PNP_MINOR_FUNCTION;
// Device relation query types.
typedef enum IO_DEVICE_RELATION_TYPE {
IoBusRelations = 0,
IoRemovalRelations = 1,
} IO_DEVICE_RELATION_TYPE;
#define IRP_FLAG_PRIORITY (1u << 0)
#define IRP_FLAG_CANCELLED (1u << 1)
#define IRP_FLAG_COMPLETED (1u << 2)
// Current public IRP stack location layout.
typedef struct IO_STACK_LOCATION {
IO_MAJOR_FUNCTION MajorFunction;
uint8_t MinorFunction;
DEVICE_OBJECT* DeviceObject;
union {
struct {
uint64_t ByteOffset;
uint32_t Length;
} ReadWrite;
struct {
uint32_t IoControlCode;
void* InputBuffer;
uint32_t InputLength;
void* OutputBuffer;
uint32_t OutputLength;
} DeviceIoControl;
struct {
IO_DEVICE_RELATION_TYPE RelationType;
} QueryDeviceRelations;
struct {
uint32_t IdType;
} QueryId;
} Parameters;
} IO_STACK_LOCATION;
typedef struct IRP IRP;
typedef void (*IRP_COMPLETION_FN)(IRP* irp, void* ctx);
typedef void (*IRP_CANCEL_ROUTINE)(DEVICE_OBJECT* device, IRP* irp);
// Current public IRP layout.
typedef struct IRP {
LIST_ENTRY Link;
volatile KSTATUS Status;
volatile size_t Information;
uint32_t Flags;
volatile bool Cancel;
SPINLOCK CancelLock;
KIRQL CancelIrql;
IRP_CANCEL_ROUTINE CancelRoutine;
struct EVENT* CompletionEvent;
struct KAPC* CompletionApc;
IRP_COMPLETION_FN CompletionFn;
void* CompletionCtx;
void* UserBuffer;
void* SystemBuffer;
uint8_t StackCount;
uint8_t CurrentLocation;
uint8_t HwSlot;
void* DriverCtx;
IO_STACK_LOCATION Stack[1];
} IRP;
// Current remove-lock layout.
typedef struct IO_REMOVE_LOCK {
SPINLOCK Lock;
volatile long IoCount;
bool Removing;
struct EVENT* RemovedEvent;
} IO_REMOVE_LOCK;
// Current per-driver IRP queue layout.
typedef struct IRP_QUEUE {
SPINLOCK Lock;
LIST_ENTRY Head;
struct SEMAPHORE* Semaphore;
} IRP_QUEUE;
typedef void (*IRP_QUEUE_CANCEL_CALLBACK)(IRP* irp, void* context);
// Initializes a remove lock before it is used by a device.
__declspec(dllexport) KSTATUS IoInitializeRemoveLock(IO_REMOVE_LOCK* lock);
// Destroys a remove lock after the owning device has drained I/O.
__declspec(dllexport) void IoDestroyRemoveLock(IO_REMOVE_LOCK* lock);
// Acquires a remove lock for a request.
__declspec(dllexport) KSTATUS IoAcquireRemoveLock(IO_REMOVE_LOCK* lock, IRP* irp);
// Releases a remove lock for a request.
__declspec(dllexport) void IoReleaseRemoveLock(IO_REMOVE_LOCK* lock, IRP* irp);
// Releases a remove lock and waits for outstanding requests to drain.
__declspec(dllexport) void IoReleaseRemoveLockAndWait(IO_REMOVE_LOCK* lock, IRP* removeIrp);
// Initializes a driver-internal IRP queue.
__declspec(dllexport) void IrpQueueInit(IRP_QUEUE* q, struct SEMAPHORE* sem);
// Enqueues an IRP into a driver-internal queue.
__declspec(dllexport) void IrpQueueEnqueue(IRP_QUEUE* q, IRP* irp);
// Dequeues an IRP from a driver-internal queue.
__declspec(dllexport) IRP* IrpQueueDequeue(IRP_QUEUE* q);
// Cancels every IRP in a queue and invokes a callback for each one.
__declspec(dllexport) void IrpQueueCancelAllEx(IRP_QUEUE* q,
KSTATUS status,
IRP_QUEUE_CANCEL_CALLBACK callback,
void* context);
// Cancels every IRP in a queue.
__declspec(dllexport) void IrpQueueCancelAll(IRP_QUEUE* q, KSTATUS status);
// Allocates an IRP with the requested stack depth.
__declspec(dllexport) KSTATUS IoAllocateIrp(uint8_t stackCount, IRP** outIrp);
// Frees an IRP allocated by IoAllocateIrp.
__declspec(dllexport) void IoFreeIrp(IRP* irp);
// Reinitializes an existing IRP for reuse.
__declspec(dllexport) void IoInitializeIrp(IRP* irp, uint8_t stackCount);
// Returns the current IRP stack location.
__declspec(dllexport) IO_STACK_LOCATION* IoGetCurrentIrpStackLocation(IRP* irp);
// Returns the next lower IRP stack location.
__declspec(dllexport) IO_STACK_LOCATION* IoGetNextIrpStackLocation(IRP* irp);
// Advances the IRP without copying stack parameters.
__declspec(dllexport) void IoSkipCurrentIrpStackLocation(IRP* irp);
// Copies the current stack location to the next lower location.
__declspec(dllexport) void IoCopyCurrentIrpStackLocationToNext(IRP* irp);
// Registers a completion callback for an IRP.
__declspec(dllexport) void IoSetCompletionRoutine(IRP* irp, IRP_COMPLETION_FN fn, void* ctx);
// Sets the cancel routine and returns the previous one.
__declspec(dllexport) IRP_CANCEL_ROUTINE IoSetCancelRoutine(IRP* irp, IRP_CANCEL_ROUTINE routine);
// Marks an IRP cancelled and invokes its cancel routine when present.
__declspec(dllexport) void IoCancelIrp(IRP* irp);
// Builds a read or write IRP.
__declspec(dllexport) void IoBuildReadWriteIrp(IRP* irp,
IO_MAJOR_FUNCTION major,
uint64_t byteOffset,
uint32_t length,
void* buffer);
// Builds a PnP IRP.
__declspec(dllexport) void IoBuildPnpIrp(IRP* irp, IO_PNP_MINOR_FUNCTION minor);
// Builds a device-control IRP.
__declspec(dllexport) void IoBuildDeviceIoControlIrp(IRP* irp,
IO_MAJOR_FUNCTION major,
uint32_t ioControlCode,
void* inputBuffer,
uint32_t inputLength,
void* outputBuffer,
uint32_t outputLength);
// Completes an IRP exactly once.
__declspec(dllexport) KSTATUS IoCompleteRequest(IRP* irp, KSTATUS status, size_t information);
// Submits an IRP to a specific top-of-stack device object.
__declspec(dllexport) KSTATUS IoSubmitIrp(DEVICE_OBJECT* device, IRP* irp);
// Submits an IRP and waits for completion.
__declspec(dllexport) KSTATUS IoSubmitIrpSync(DEVICE_OBJECT* device, IRP* irp);
+35
View File
@@ -0,0 +1,35 @@
// Public nt-lite DDK IRQL declarations.
#pragma once
#include <stdint.h>
// Interrupt request level value used by DDK synchronization and IRP state.
typedef uint8_t KIRQL;
#define PASSIVE_LEVEL ((KIRQL)0)
#define APC_LEVEL ((KIRQL)1)
#define DISPATCH_LEVEL ((KIRQL)2)
#define DIRQL_BASE ((KIRQL)16)
#define HIGH_LEVEL ((KIRQL)31)
// Returns the current processor's software IRQL.
__declspec(dllexport) KIRQL KeGetCurrentIrql(void);
// Raises to newIrql and returns the previous level.
__declspec(dllexport) KIRQL KeRaiseIrql(KIRQL newIrql);
// Restores a previously returned level.
__declspec(dllexport) void KeLowerIrql(KIRQL oldIrql);
// Asserts that the current IRQL exactly matches expected.
__declspec(dllexport) void KeAssertIrql(KIRQL expected);
// Asserts that the current IRQL is at or below maxIrql.
__declspec(dllexport) void KeAssertIrqlAtOrBelow(KIRQL maxIrql);
// Returns nonzero when the current context may block.
__declspec(dllexport) int KeCanWait(void);
// Returns a diagnostic name for an IRQL.
__declspec(dllexport) const char* KeIrqlName(KIRQL irql);
+51
View File
@@ -0,0 +1,51 @@
// Public nt-lite DDK intrusive list declarations.
#pragma once
#include <stddef.h>
// Doubly-linked intrusive list node.
typedef struct LIST_ENTRY {
struct LIST_ENTRY* Fwd;
struct LIST_ENTRY* Bwd;
} LIST_ENTRY;
#define LIST_INIT(head) ((head)->Fwd = (head)->Bwd = (head))
#define LIST_IS_EMPTY(head) ((head)->Fwd == (head))
// Recover the containing struct pointer from an embedded list node.
#define CONTAINING_RECORD(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
// Inserts a node at the tail of a list.
static inline void ListInsertTail(LIST_ENTRY* head, LIST_ENTRY* node) {
node->Bwd = head->Bwd;
node->Fwd = head;
head->Bwd->Fwd = node;
head->Bwd = node;
}
// Inserts a node at the head of a list.
static inline void ListInsertHead(LIST_ENTRY* head, LIST_ENTRY* node) {
node->Fwd = head->Fwd;
node->Bwd = head;
head->Fwd->Bwd = node;
head->Fwd = node;
}
// Removes a node from its current list.
static inline void ListRemove(LIST_ENTRY* node) {
node->Bwd->Fwd = node->Fwd;
node->Fwd->Bwd = node->Bwd;
node->Fwd = node->Bwd = node;
}
// Removes and returns the first node in a list, or NULL when empty.
static inline LIST_ENTRY* ListPopHead(LIST_ENTRY* head) {
if (LIST_IS_EMPTY(head))
return (LIST_ENTRY*)0;
LIST_ENTRY* node = head->Fwd;
ListRemove(node);
return node;
}
+186
View File
@@ -0,0 +1,186 @@
// Public nt-lite DDK memory declarations.
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <ntlite/status.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096ULL
#endif
#ifndef PAGE_MASK
#define PAGE_MASK (~(PAGE_SIZE - 1ULL))
#endif
#define NTL_DDK_PAGE_SIZE PAGE_SIZE
#define NTL_DDK_PAGE_PRESENT (1ULL << 0)
#define NTL_DDK_PAGE_WRITE (1ULL << 1)
#define NTL_DDK_PAGE_WRITETHROUGH (1ULL << 3)
#define NTL_DDK_PAGE_NOCACHE (1ULL << 4)
#define NTL_DDK_PAGE_NX (1ULL << 63)
#ifndef PAGE_PRESENT
#define PAGE_PRESENT (1ULL << 0)
#endif
#ifndef PAGE_WRITE
#define PAGE_WRITE (1ULL << 1)
#endif
#ifndef PAGE_USER
#define PAGE_USER (1ULL << 2)
#endif
#ifndef PAGE_WRITETHROUGH
#define PAGE_WRITETHROUGH (1ULL << 3)
#endif
#ifndef PAGE_NOCACHE
#define PAGE_NOCACHE (1ULL << 4)
#endif
#ifndef PAGE_ACCESSED
#define PAGE_ACCESSED (1ULL << 5)
#endif
#ifndef PAGE_DIRTY
#define PAGE_DIRTY (1ULL << 6)
#endif
#ifndef PAGE_NX
#define PAGE_NX (1ULL << 63)
#endif
#ifndef NTL_PHYSICAL_ADDRESS_DEFINED
typedef uint64_t PHYSICAL_ADDRESS;
#define NTL_PHYSICAL_ADDRESS_DEFINED 1
#endif
typedef enum NTL_DDK_MAP_MODE {
NtlDdkMapFailIfPresent = 0,
NtlDdkMapReplaceExisting = 1,
} NTL_DDK_MAP_MODE;
#ifndef NTL_MM_PTE_MAP_MODE_DEFINED
typedef enum MM_PTE_MAP_MODE {
MmPteMapFailIfPresent = 0,
MmPteMapReplaceExisting = 1,
} MM_PTE_MAP_MODE;
#define NTL_MM_PTE_MAP_MODE_DEFINED 1
#endif
#ifndef NTL_MM_PFN_TYPES_DEFINED
typedef enum MM_PFN_STATE {
MmPfnStateInvalid = 0,
MmPfnStateReserved,
MmPfnStateFree,
MmPfnStateZeroed,
MmPfnStateActive,
MmPfnStateStandby,
MmPfnStateModified,
} MM_PFN_STATE;
typedef enum MM_PFN_USAGE {
MmPfnUseNone = 0,
MmPfnUseKernel,
MmPfnUsePageTable,
MmPfnUseUser,
MmPfnUseCleanFileCache,
MmPfnUseImage,
MmPfnUseMappedFile,
MmPfnUseAnonymous,
MmPfnUseCow,
MmPfnUseSurface,
MmPfnUseDriver,
MmPfnUseDma,
MmPfnUseBootloader,
MmPfnUsePfnDatabase,
MmPfnUseMmio,
} MM_PFN_USAGE;
typedef struct MM_PFN {
uint16_t State;
uint16_t Usage;
uint16_t RefCount;
uint16_t PinCount;
uint32_t Flags;
uint32_t MappedCount;
void* Owner;
uint64_t BackingPage;
} MM_PFN;
#define NTL_MM_PFN_TYPES_DEFINED 1
#endif
#define MM_POOL_TAG(a, b, c, d) \
((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | \
((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24))
// Driver-visible memory services. These are intentionally narrower than the
// kernel memory-manager surface.
typedef struct NTL_DDK_MEMORY {
void* (*PhysToVirt)(uint64_t physicalAddress);
KSTATUS (*MapPage)(uintptr_t virtualAddress,
uint64_t physicalAddress,
uint64_t pageFlags,
NTL_DDK_MAP_MODE mode);
} NTL_DDK_MEMORY;
// Allocates from kernel pool for current kernel-mode drivers.
__declspec(dllexport) void* MmAllocatePool(size_t size);
// Allocates tagged memory from kernel pool for current kernel-mode drivers.
__declspec(dllexport) void* MmAllocatePoolTag(size_t size, uint32_t tag);
// Frees kernel pool memory.
__declspec(dllexport) void MmFreePool(void* ptr);
// Reallocates kernel pool memory.
__declspec(dllexport) void* MmReallocatePool(void* ptr, size_t newSize);
// Allocates one physical frame for a specific driver-visible usage.
__declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocate(MM_PFN_USAGE usage);
// Allocates one physical frame below maxExclusive.
__declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateBelow(PHYSICAL_ADDRESS maxExclusive, MM_PFN_USAGE usage);
// Allocates one physical frame in a range.
__declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateInRange(PHYSICAL_ADDRESS minInclusive,
PHYSICAL_ADDRESS maxExclusive,
MM_PFN_USAGE usage);
// Allocates contiguous physical frames.
__declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateContiguous(size_t count, MM_PFN_USAGE usage);
// Releases a frame reference.
__declspec(dllexport) KSTATUS MmPfnFree(PHYSICAL_ADDRESS frame);
// Retains a physical frame.
__declspec(dllexport) KSTATUS MmPfnRetain(PHYSICAL_ADDRESS frame);
// Releases a retained physical frame.
__declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame);
// Pins a physical frame.
__declspec(dllexport) KSTATUS MmPfnPin(PHYSICAL_ADDRESS frame);
// Unpins a physical frame.
__declspec(dllexport) KSTATUS MmPfnUnpin(PHYSICAL_ADDRESS frame);
// Returns the PFN database entry for a frame.
__declspec(dllexport) MM_PFN* MmPfnGet(PHYSICAL_ADDRESS frame);
// Returns the direct-map alias for a physical frame.
__declspec(dllexport) void* MmPfnToVirtual(PHYSICAL_ADDRESS frame);
// Maps one page into the shared kernel address space.
__declspec(dllexport) KSTATUS MmPteMapPage(uintptr_t virt,
PHYSICAL_ADDRESS phys,
uint64_t flags,
MM_PTE_MAP_MODE mode);
// Removes one page mapping from the shared kernel address space.
__declspec(dllexport) KSTATUS MmPteUnmapPage(uintptr_t virt);
// Replaces flags on a mapped range.
__declspec(dllexport) KSTATUS MmPteProtectRange(uintptr_t virt, size_t size, uint64_t flags);
// Translates a virtual address through the shared kernel page tables.
__declspec(dllexport) PHYSICAL_ADDRESS MmPteTranslate(uintptr_t virt);
// Returns the physical address and flags for a mapped page.
__declspec(dllexport) KSTATUS MmPteQueryPage(uintptr_t virt, PHYSICAL_ADDRESS* physOut, uint64_t* flagsOut);
+28
View File
@@ -0,0 +1,28 @@
// Public nt-lite DDK mutex declarations.
#pragma once
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/sync.h>
#include <ntlite/ddk/thread.h>
typedef struct MUTEX {
OBJECT Header;
SPINLOCK Lock;
THREAD* Owner;
LIST_ENTRY WaitList;
} MUTEX;
// Creates a mutex object.
__declspec(dllexport) KSTATUS KeMutexCreate(MUTEX** out);
// Acquires a mutex, blocking when necessary.
__declspec(dllexport) KSTATUS KeAcquireMutex(MUTEX* mutex);
// Attempts to acquire a mutex without blocking.
__declspec(dllexport) KSTATUS KeTryAcquireMutex(MUTEX* mutex);
// Releases a mutex.
__declspec(dllexport) void KeReleaseMutex(MUTEX* mutex);
+46
View File
@@ -0,0 +1,46 @@
// Public nt-lite DDK object declarations.
#pragma once
#include <stddef.h>
#include <stdint.h>
// Kernel object type identifiers used by the legacy object header.
typedef enum OBJECT_TYPE {
ObjectTypeProcess = 1,
ObjectTypeThread = 2,
ObjectTypeMutex = 3,
ObjectTypeSemaphore = 4,
ObjectTypeEvent = 5,
ObjectTypeQueue = 6,
ObjectTypeFile = 7,
ObjectTypeDir = 8,
ObjectTypeAsyncIo = 9,
ObjectTypeSocket = 10,
ObjectTypeDevice = 11,
ObjectTypeDriver = 12,
ObjectTypeUsbDevice = 13,
ObjectTypeUsbPipe = 14,
ObjectTypeFileMapping = 15,
ObjectTypeSurface = 16,
ObjectTypeInputQueue = 17,
ObjectTypeImageSection = 18,
ObjectTypeTimer = 19,
ObjectTypeModule = 20,
} OBJECT_TYPE;
// Legacy object header embedded by current driver/device objects.
typedef struct OBJECT {
OBJECT_TYPE Type;
volatile long RefCount;
void (*Destroy)(struct OBJECT* self);
} OBJECT;
// Increments an object's reference count.
__declspec(dllexport) void ObReferenceObject(OBJECT* object);
// Decrements an object's reference count and destroys it when it reaches zero.
__declspec(dllexport) void ObDereferenceObject(OBJECT* object);
// Allocates a zeroed object of the given size.
__declspec(dllexport) OBJECT* ObAllocateObject(OBJECT_TYPE type, size_t size);
+23
View File
@@ -0,0 +1,23 @@
// Public nt-lite DDK platform declarations.
#pragma once
#include <stdint.h>
// Driver-visible platform services. PCI bus policy stays in pci.sys; these are
// only the raw platform hooks needed by the PCI bus driver itself.
typedef struct NTL_DDK_PLATFORM {
uint32_t (*PciRead32)(uint16_t segment,
uint8_t bus,
uint8_t device,
uint8_t function,
uint16_t offset);
void (*PciWrite32)(uint16_t segment,
uint8_t bus,
uint8_t device,
uint8_t function,
uint16_t offset,
uint32_t value);
uint32_t (*GetBspLapicId)(void);
uint8_t (*IsX2ApicEnabled)(void);
} NTL_DDK_PLATFORM;
+13
View File
@@ -0,0 +1,13 @@
// Public nt-lite DDK scheduler declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/ddk/thread.h>
// Driver-visible scheduler services.
typedef struct NTL_DDK_SCHEDULER {
KSTATUS (*DelayThread)(uint64_t milliseconds);
void (*Yield)(void);
} NTL_DDK_SCHEDULER;
+29
View File
@@ -0,0 +1,29 @@
// Public nt-lite DDK semaphore declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/ddk/list.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/sync.h>
typedef struct SEMAPHORE {
OBJECT Header;
SPINLOCK Lock;
int32_t Count;
int32_t MaxCount;
LIST_ENTRY WaitList;
} SEMAPHORE;
// Creates a counting semaphore.
__declspec(dllexport) KSTATUS KeSemaphoreCreate(int32_t initial, int32_t max, SEMAPHORE** out);
// Waits for a semaphore count to become available.
__declspec(dllexport) KSTATUS KeWaitSemaphore(SEMAPHORE* semaphore);
// Attempts to take a semaphore without blocking.
__declspec(dllexport) KSTATUS KeTrySemaphore(SEMAPHORE* semaphore);
// Releases one semaphore count.
__declspec(dllexport) void KeSignalSemaphore(SEMAPHORE* semaphore);
+14
View File
@@ -0,0 +1,14 @@
// Public nt-lite DDK settings declarations.
#pragma once
#include <stddef.h>
#include <ntlite/status.h>
#define KE_SETTINGS_PATH "system\\settings.ini"
// Reads one string setting from the system settings file.
__declspec(dllexport) KSTATUS KeGetSettingString(const char* section,
const char* key,
char* buffer,
size_t bufferSize);
+86
View File
@@ -0,0 +1,86 @@
// Public nt-lite DDK synchronization declarations.
#pragma once
#include <stdint.h>
#include <intrin.h>
#include <ntlite/ddi/hal_api.h>
#include <ntlite/ddk/irql.h>
// Legacy spinlock storage used by current driver-visible objects.
typedef struct SPINLOCK {
volatile long Locked;
} SPINLOCK;
#define SPINLOCK_INIT { 0 }
#define KI_SPINLOCK_IRQL_SHIFT ((unsigned)(sizeof(uintptr_t) * 8u - 8u))
#define KI_SPINLOCK_FLAGS_MASK (~(((uintptr_t)0xFFu) << KI_SPINLOCK_IRQL_SHIFT))
// Packs the interrupt flags and prior IRQL into a spinlock cookie.
static __forceinline uintptr_t KiPackSpinlockCookie(uintptr_t flags, KIRQL oldIrql) {
return (flags & KI_SPINLOCK_FLAGS_MASK) |
(((uintptr_t)oldIrql) << KI_SPINLOCK_IRQL_SHIFT);
}
// Extracts the saved interrupt flags from a spinlock cookie.
static __forceinline uintptr_t KiSpinlockCookieFlags(uintptr_t cookie) {
return cookie & KI_SPINLOCK_FLAGS_MASK;
}
// Extracts the saved IRQL from a spinlock cookie.
static __forceinline KIRQL KiSpinlockCookieIrql(uintptr_t cookie) {
return (KIRQL)(cookie >> KI_SPINLOCK_IRQL_SHIFT);
}
// Acquires a spinlock and raises to at least DISPATCH_LEVEL.
static __forceinline uintptr_t KeAcquireSpinlock(SPINLOCK* sl) {
uintptr_t flags = HalDisableInterrupts();
KIRQL oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL);
while (_InterlockedCompareExchange(&sl->Locked, 1, 0) != 0)
_mm_pause();
return KiPackSpinlockCookie(flags, oldIrql);
}
// Releases a spinlock and restores the caller's saved IRQL and interrupt state.
static __forceinline void KeReleaseSpinlock(SPINLOCK* sl, uintptr_t cookie) {
uintptr_t flags = KiSpinlockCookieFlags(cookie);
KIRQL oldIrql = KiSpinlockCookieIrql(cookie);
_InterlockedExchange(&sl->Locked, 0);
KeLowerIrql(oldIrql);
HalRestoreInterrupts(flags);
}
// Attempts to acquire a spinlock without blocking.
static __forceinline int KeTryAcquireSpinlock(SPINLOCK* sl, uintptr_t* outCookie) {
uintptr_t flags = HalDisableInterrupts();
KIRQL oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL);
if (_InterlockedCompareExchange(&sl->Locked, 1, 0) == 0) {
*outCookie = KiPackSpinlockCookie(flags, oldIrql);
return 1;
}
KeLowerIrql(oldIrql);
HalRestoreInterrupts(flags);
return 0;
}
// Acquires a spinlock for DPC-level code.
static __forceinline uintptr_t KeAcquireSpinlockRaiseToDpc(SPINLOCK* sl) {
return KeAcquireSpinlock(sl);
}
// Releases a spinlock acquired for DPC-level code.
static __forceinline void KeReleaseSpinlockFromDpc(SPINLOCK* sl, uintptr_t cookie) {
KeReleaseSpinlock(sl, cookie);
}
+34
View File
@@ -0,0 +1,34 @@
// Public nt-lite DDK system-thread declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
typedef struct THREAD THREAD;
#ifndef NTL_THREAD_PRIORITY_DEFINED
typedef enum THREAD_PRIORITY {
PriorityLow = 0,
PriorityNormal = 1,
PriorityHigh = 2,
PriorityCount = 3,
} THREAD_PRIORITY;
#define NTL_THREAD_PRIORITY_DEFINED 1
#endif
// Creates a system-process kernel thread for a kernel-mode driver.
__declspec(dllexport) KSTATUS KeCreateKernelThread(uintptr_t fn,
uintptr_t arg,
THREAD_PRIORITY priority,
THREAD** out);
// Creates a system-process kernel thread with an explicit affinity mask.
__declspec(dllexport) KSTATUS KeCreateKernelThreadWithAffinity(uintptr_t fn,
uintptr_t arg,
THREAD_PRIORITY priority,
uint64_t affinityMask,
THREAD** out);
// Yields the current processor to another runnable thread.
__declspec(dllexport) void KeYield(void);
+13
View File
@@ -0,0 +1,13 @@
// Public nt-lite DDK time declarations.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/time.h>
// Queries the current wall-clock time.
__declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime);
// Queries the current Unix time in seconds.
__declspec(dllexport) uint64_t KeQueryUnixTimeSeconds(void);
+11
View File
@@ -0,0 +1,11 @@
// Public nt-lite DDK timer declarations.
#pragma once
#include <stdint.h>
// Driver-visible timing services.
typedef struct NTL_DDK_TIMER {
uint64_t (*QueryTicks)(void);
void (*Stall)(uint32_t microseconds);
} NTL_DDK_TIMER;