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

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

No files matched your search

+82 -64
View File
@@ -63,7 +63,7 @@ static bool IoTryAddDeviceForDriver(DRIVER_OBJECT* driver, DEVICE_OBJECT* pdo) {
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), IoBusTypeName(pdo->u.Pdo.BusType));
KSTATUS start = IoSendPnpIrpSync(pdo, IRP_MN_START_DEVICE);
if (!KSUCCESS(start) && start != STATUS_NOT_SUPPORTED) {
if (!KSUCCESS(start) && start != NTLSTATUS_NOT_SUPPORTED) {
DbgPrint("io: START_DEVICE failed driver=%v pdo=%v st=0x%x\n",
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), start);
}
@@ -87,9 +87,9 @@ __declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver,
// Registers driver Object.
__declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) {
if (!driver) return STATUS_INVALID_PARAMETER;
if (!driver) return NTLSTATUS_INVALID_PARAMETER;
if (gDriverObjectCount >= MAX_DRIVER_OBJECTS)
return STATUS_NO_MEMORY;
return NTLSTATUS_NO_MEMORY;
if (driver->Header.Type != ObjectTypeDriver) {
driver->Header.Type = ObjectTypeDriver;
@@ -102,7 +102,7 @@ __declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) {
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++)
(void)IoTryAddDeviceForDriver(driver, gPhysicalDevices[i]);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Device object lifetime.
@@ -144,11 +144,11 @@ static KSTATUS IoCreateDeviceInternal(DRIVER_OBJECT* driver,
DEVICE_OBJECT_TYPE type,
size_t extensionSize,
DEVICE_OBJECT** outDevice) {
if (!driver || !outDevice) return STATUS_INVALID_PARAMETER;
if (!driver || !outDevice) return NTLSTATUS_INVALID_PARAMETER;
size_t total = sizeof(DEVICE_OBJECT) + extensionSize;
DEVICE_OBJECT* dev = (DEVICE_OBJECT*)ObAllocateObject(ObjectTypeDevice, total);
if (!dev) return STATUS_NO_MEMORY;
if (!dev) return NTLSTATUS_NO_MEMORY;
dev->Header.Destroy = IoDeviceDestroy;
dev->DriverObject = driver;
@@ -169,7 +169,7 @@ static KSTATUS IoCreateDeviceInternal(DRIVER_OBJECT* driver,
dev->DeviceExtension = (void*)((uint8_t*)dev + sizeof(DEVICE_OBJECT));
*outDevice = dev;
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS IoCreateDevice(DRIVER_OBJECT* driver,
@@ -184,8 +184,8 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver,
size_t idCount,
size_t extensionSize,
DEVICE_OBJECT** outPdo) {
if (!busDriver || !outPdo) return STATUS_INVALID_PARAMETER;
if (idCount > IO_MAX_DEVICE_IDS) return STATUS_INVALID_PARAMETER;
if (!busDriver || !outPdo) return NTLSTATUS_INVALID_PARAMETER;
if (idCount > IO_MAX_DEVICE_IDS) return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* pdo = (DEVICE_OBJECT*)0;
KSTATUS st = IoCreateDeviceInternal(busDriver, DeviceObjectPhysical, extensionSize, &pdo);
@@ -195,7 +195,7 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver,
for (size_t i = 0; i < idCount; i++) {
if (!SysSvIsValid(ids[i].Id) || ids[i].Id.Length >= IO_MAX_DEVICE_ID_CHARS) {
IoDeleteDevice(pdo);
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
}
char* dst = pdo->u.Pdo.IdStorage[i];
@@ -221,21 +221,21 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver,
}
*outPdo = pdo;
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Registers physical Device.
__declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) {
if (!pdo || pdo->Type != DeviceObjectPhysical)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
if (gPhysicalDevices[i] == pdo)
return STATUS_ALREADY_EXISTS;
return NTLSTATUS_ALREADY_EXISTS;
}
if (gPhysicalDeviceCount >= MAX_PDO_OBJECTS)
return STATUS_NO_MEMORY;
return NTLSTATUS_NO_MEMORY;
gPhysicalDevices[gPhysicalDeviceCount++] = pdo;
@@ -250,21 +250,21 @@ __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) {
DbgPrint("io: no function driver for pdo=%v id=%v bus=%s\n",
IoSvOrUnnamed(pdo->Name), id, IoBusTypeName(pdo->u.Pdo.BusType));
}
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS IoSetDeviceName(DEVICE_OBJECT* device,
SYS_STRING_VIEW name) {
if (!device || !SysSvIsValid(name))
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (name.Length >= IO_MAX_DEVICE_NAME_CHARS)
return STATUS_BUFFER_TOO_SMALL;
return NTLSTATUS_BUFFER_TOO_SMALL;
if (name.Length)
memcpy(device->NameStorage, name.Data, name.Length);
device->NameStorage[name.Length] = '\0';
device->Name = SysSvFromParts(device->NameStorage, name.Length);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Implements the reference Device Object operation.
@@ -378,12 +378,12 @@ __declspec(dllexport) uint8_t IoGetDeviceStackSize(DEVICE_OBJECT* device) {
// Implements the forward Irp To Lower operation.
__declspec(dllexport) KSTATUS IoForwardIrpToLower(DEVICE_OBJECT* device, IRP* irp) {
if (!device || !irp || !device->LowerDevice)
return STATUS_NOT_SUPPORTED;
return NTLSTATUS_NOT_SUPPORTED;
IO_STACK_LOCATION* cur = IoGetCurrentIrpStackLocation(irp);
IO_STACK_LOCATION* next = IoGetNextIrpStackLocation(irp);
if (!cur || !next)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* currentDevice = cur->DeviceObject;
memcpy(next, cur, sizeof(*next));
@@ -400,10 +400,10 @@ __declspec(dllexport) KSTATUS IoForwardIrpToLower(DEVICE_OBJECT* device, IRP* ir
__declspec(dllexport) KSTATUS IoSendPnpIrpSync(DEVICE_OBJECT* device,
IO_PNP_MINOR_FUNCTION minor) {
if (!device) return STATUS_INVALID_PARAMETER;
if (!device) return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* top = IoGetAttachedDeviceReference(device);
if (!top) return STATUS_INVALID_PARAMETER;
if (!top) return NTLSTATUS_INVALID_PARAMETER;
uint8_t stackCount = IoGetDeviceStackSize(top);
IRP* irp = (IRP*)0;
@@ -611,14 +611,28 @@ static void IoDiskReadAheadNoteWrite(uint8_t driveIndex, uint32_t count) {
static void IoNotifyDiskChange(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEVICE_CHANGE change) {
for (uint32_t i = 0; i < gDiskChangeCallbackCount; i++) {
IO_DISK_CHANGE_CALLBACK_ENTRY* entry = &gDiskChangeCallbacks[i];
if (entry->Used && entry->Callback)
entry->Callback(driveIndex, device, change, entry->Context);
IO_DISK_CHANGE_CALLBACK callback = entry->Callback;
void* context = entry->Context;
if (entry->Used && callback) {
callback(driveIndex, device, change, context);
} else if (entry->Used) {
KePanic(KE_PANIC_CODE_DRIVER,
"io: disk change callback entry has null callback index=%u ctx=0x%016llX change=%u drive=%u dev=0x%016llX\n",
i, context, (uint32_t)change, driveIndex, device);
}
}
if (change == IoDeviceArrived) {
for (uint32_t i = 0; i < gDiskArrivalCallbackCount; i++) {
IO_DISK_ARRIVAL_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[i];
if (entry->Used && entry->Callback)
entry->Callback(driveIndex, device, entry->Context);
IO_DISK_ARRIVAL_CALLBACK callback = entry->Callback;
void* context = entry->Context;
if (entry->Used && callback) {
callback(driveIndex, device, context);
} else if (entry->Used) {
KePanic(KE_PANIC_CODE_DRIVER,
"io: disk arrival callback entry has null callback index=%u ctx=0x%016llX drive=%u dev=0x%016llX\n",
i, context, driveIndex, device);
}
}
}
}
@@ -626,9 +640,9 @@ static void IoNotifyDiskChange(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEV
__declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex,
DEVICE_OBJECT* device) {
if (driveIndex >= MAX_DISK_DEVICES || !device || !device->DriverObject)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (gDiskDevices[driveIndex])
return STATUS_ALREADY_EXISTS;
return NTLSTATUS_ALREADY_EXISTS;
device->Flags |= DEVICE_OBJECT_DISK;
device->u.Disk.DiskIndex = driveIndex;
@@ -636,9 +650,9 @@ __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex,
device->u.Disk.SectorSize = 512;
KSTATUS pnpStatus = IoSendPnpIrpSync(device, IRP_MN_START_DEVICE);
if (!KSUCCESS(pnpStatus) && pnpStatus != STATUS_NOT_SUPPORTED)
if (!KSUCCESS(pnpStatus) && pnpStatus != NTLSTATUS_NOT_SUPPORTED)
return pnpStatus;
if (pnpStatus == STATUS_NOT_SUPPORTED)
if (pnpStatus == NTLSTATUS_NOT_SUPPORTED)
device->PnpState = DevicePnpStarted;
IoDiskReadAheadPrepare(driveIndex);
@@ -646,35 +660,35 @@ __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex,
IoReferenceDeviceObject(device);
gDiskDevices[driveIndex] = device;
IoNotifyDiskChange(driveIndex, device, IoDeviceArrived);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Implements the notify Disk Surprise Removed operation.
__declspec(dllexport) KSTATUS IoNotifyDiskSurpriseRemoved(uint8_t driveIndex) {
if (driveIndex >= MAX_DISK_DEVICES)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* dev = gDiskDevices[driveIndex];
if (!dev) return STATUS_NOT_FOUND;
if (!dev) return NTLSTATUS_NOT_FOUND;
IoDiskReadAheadInvalidate(driveIndex);
dev->PnpState = DevicePnpSurpriseRemoved;
IoNotifyDiskChange(driveIndex, dev, IoDeviceSurpriseRemoved);
(void)IoSendPnpIrpSync(dev, IRP_MN_SURPRISE_REMOVAL);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Implements the unregister Disk Device operation.
__declspec(dllexport) KSTATUS IoUnregisterDiskDevice(uint8_t driveIndex) {
if (driveIndex >= MAX_DISK_DEVICES)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* dev = gDiskDevices[driveIndex];
if (!dev) return STATUS_NOT_FOUND;
if (!dev) return NTLSTATUS_NOT_FOUND;
if (dev->PnpState != DevicePnpSurpriseRemoved) {
IoNotifyDiskChange(driveIndex, dev, IoDeviceQueryRemove);
KSTATUS queryStatus = IoSendPnpIrpSync(dev, IRP_MN_QUERY_REMOVE_DEVICE);
if (!KSUCCESS(queryStatus) && queryStatus != STATUS_NOT_SUPPORTED)
if (!KSUCCESS(queryStatus) && queryStatus != NTLSTATUS_NOT_SUPPORTED)
return queryStatus;
dev->PnpState = DevicePnpSurpriseRemoved;
@@ -689,54 +703,58 @@ __declspec(dllexport) KSTATUS IoUnregisterDiskDevice(uint8_t driveIndex) {
IoDiskReadAheadRelease(driveIndex);
IoNotifyDiskChange(driveIndex, dev, IoDeviceRemoved);
IoDereferenceDeviceObject(dev);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS IoRegisterDiskArrivalCallback(IO_DISK_ARRIVAL_CALLBACK callback,
void* context) {
if (!callback)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (gDiskArrivalCallbackCount >= MAX_DISK_CALLBACKS)
return STATUS_NO_MEMORY;
return NTLSTATUS_NO_MEMORY;
IO_DISK_ARRIVAL_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[gDiskArrivalCallbackCount++];
memset(entry, 0, sizeof(*entry));
entry->Used = true;
entry->Callback = callback;
entry->Context = context;
DbgPrint("io: registered disk arrival callback index=%u cb=0x%016llX ctx=0x%016llX\n",
gDiskArrivalCallbackCount - 1u, callback, context);
for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) {
if (gDiskDevices[i])
callback(i, gDiskDevices[i], context);
}
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS IoRegisterDiskChangeCallback(IO_DISK_CHANGE_CALLBACK callback,
void* context) {
if (!callback)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (gDiskChangeCallbackCount >= MAX_DISK_CALLBACKS)
return STATUS_NO_MEMORY;
return NTLSTATUS_NO_MEMORY;
IO_DISK_CHANGE_CALLBACK_ENTRY* entry = &gDiskChangeCallbacks[gDiskChangeCallbackCount++];
memset(entry, 0, sizeof(*entry));
entry->Used = true;
entry->Callback = callback;
entry->Context = context;
return STATUS_SUCCESS;
DbgPrint("io: registered disk change callback index=%u cb=0x%016llX ctx=0x%016llX\n",
gDiskChangeCallbackCount - 1u, callback, context);
return NTLSTATUS_SUCCESS;
}
__declspec(dllexport) KSTATUS IoEnumerateDiskDevices(IO_DISK_ARRIVAL_CALLBACK callback,
void* context) {
if (!callback)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) {
if (gDiskDevices[i])
callback(i, gDiskDevices[i], context);
}
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
// Returns disk Device.
@@ -767,31 +785,31 @@ __declspec(dllexport) uint64_t IoDiskSectorCount(uint8_t driveIndex) {
__declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp) {
if (!device || !device->DriverObject || !irp)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
if (!ios)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
IO_MAJOR_FUNCTION major = ios->MajorFunction;
if (major >= IRP_MJ_MAXIMUM_FUNCTION)
return STATUS_INVALID_PARAMETER;
return NTLSTATUS_INVALID_PARAMETER;
if (major != IRP_MJ_PNP &&
(device->DeletePending || device->PnpState == DevicePnpSurpriseRemoved ||
device->PnpState == DevicePnpRemovePending || device->PnpState == DevicePnpDeleted))
return STATUS_OBJECT_DEAD;
return NTLSTATUS_OBJECT_DEAD;
PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[major];
if (!dispatch)
return STATUS_NOT_SUPPORTED;
return NTLSTATUS_NOT_SUPPORTED;
ios->DeviceObject = device;
IoReferenceDeviceObject(device);
_InterlockedIncrement(&device->OutstandingIrps);
KSTATUS st = dispatch(device, irp);
if (st != STATUS_PENDING) {
if (st != NTLSTATUS_PENDING) {
if (ios->DeviceObject == device) {
ios->DeviceObject = (DEVICE_OBJECT*)0;
_InterlockedDecrement(&device->OutstandingIrps);
@@ -803,17 +821,17 @@ __declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp) {
// Validates that a sector range fits the disk and IRP byte length.
static KSTATUS IoValidateDiskSectorRange(DEVICE_OBJECT* dev, uint64_t lba, uint32_t count) {
if (!dev || count == 0) return STATUS_INVALID_PARAMETER;
if (count > (0xffffffffu / IO_DISK_SECTOR_BYTES)) return STATUS_INVALID_PARAMETER;
if (lba > dev->u.Disk.SectorCount) return STATUS_INVALID_PARAMETER;
if ((uint64_t)count > dev->u.Disk.SectorCount - lba) return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
if (!dev || count == 0) return NTLSTATUS_INVALID_PARAMETER;
if (count > (0xffffffffu / IO_DISK_SECTOR_BYTES)) return NTLSTATUS_INVALID_PARAMETER;
if (lba > dev->u.Disk.SectorCount) return NTLSTATUS_INVALID_PARAMETER;
if ((uint64_t)count > dev->u.Disk.SectorCount - lba) return NTLSTATUS_INVALID_PARAMETER;
return NTLSTATUS_SUCCESS;
}
// Submits one raw disk read IRP.
static KSTATUS IoReadDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba,
uint32_t count, void* buffer) {
if (!dev || !buffer || count == 0) return STATUS_INVALID_PARAMETER;
if (!dev || !buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER;
IRP irp;
IoBuildReadWriteIrp(&irp, IRP_MJ_READ, lba * 512ull, count * 512u, buffer);
@@ -823,7 +841,7 @@ static KSTATUS IoReadDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba,
// Submits one raw disk write IRP.
static KSTATUS IoWriteDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba,
uint32_t count, void* buffer) {
if (!dev || !buffer || count == 0) return STATUS_INVALID_PARAMETER;
if (!dev || !buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER;
IRP irp;
IoBuildReadWriteIrp(&irp, IRP_MJ_WRITE, lba * 512ull, count * 512u, buffer);
@@ -911,10 +929,10 @@ __declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex,
uint64_t lba,
uint32_t count,
void* buffer) {
if (!buffer || count == 0) return STATUS_INVALID_PARAMETER;
if (!buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* dev = IoReferenceDiskDevice(driveIndex);
if (!dev) return STATUS_NOT_FOUND;
if (!dev) return NTLSTATUS_NOT_FOUND;
KSTATUS rangeStatus = IoValidateDiskSectorRange(dev, lba, count);
if (!KSUCCESS(rangeStatus)) {
@@ -926,7 +944,7 @@ __declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex,
uint32_t score = IoDiskReadAheadNoteRead(driveIndex, lba, count);
IoDiskMaybeReadAhead(driveIndex, dev, lba + count, count, score);
IoDereferenceDeviceObject(dev);
return STATUS_SUCCESS;
return NTLSTATUS_SUCCESS;
}
KSTATUS st = IoReadDiskSectorsRaw(dev, lba, count, buffer);
@@ -942,10 +960,10 @@ __declspec(dllexport) KSTATUS IoWriteDiskSectors(uint8_t driveIndex,
uint64_t lba,
uint32_t count,
const void* buffer) {
if (!buffer || count == 0) return STATUS_INVALID_PARAMETER;
if (!buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER;
DEVICE_OBJECT* dev = IoReferenceDiskDevice(driveIndex);
if (!dev) return STATUS_NOT_FOUND;
if (!dev) return NTLSTATUS_NOT_FOUND;
KSTATUS rangeStatus = IoValidateDiskSectorRange(dev, lba, count);
if (!KSUCCESS(rangeStatus)) {