move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.
This commit is contained in:
1 parent
b970d7f59c
commit
b838f8d83d
130 files changed
+8137
-2932
No files matched your search
@@ -3,10 +3,137 @@
|
||||
#include <ntlite/ddi/io_driver.h>
|
||||
#include <kernel/ke_irp.h>
|
||||
#include <kernel/mm_virt.h>
|
||||
#include <kernel/ke_debug.h>
|
||||
|
||||
|
||||
#define MAX_PUBLISHED_DEVICES 64
|
||||
#define MAX_DRIVER_MATCHERS 32
|
||||
|
||||
typedef struct IO_DRIVER_MATCHER_ENTRY {
|
||||
bool Used;
|
||||
const char* DriverName;
|
||||
IO_BUS_TYPE BusType;
|
||||
IO_DRIVER_MATCH_CALLBACK Match;
|
||||
IO_DRIVER_BIND_CALLBACK Bind;
|
||||
void* Context;
|
||||
} IO_DRIVER_MATCHER_ENTRY;
|
||||
|
||||
static IO_PUBLISHED_DEVICE gPublishedDevices[MAX_PUBLISHED_DEVICES];
|
||||
static uint32_t gPublishedDeviceCount;
|
||||
static IO_DRIVER_MATCHER_ENTRY gDriverMatchers[MAX_DRIVER_MATCHERS];
|
||||
static uint32_t gDriverMatcherCount;
|
||||
|
||||
static const char* IoBusTypeName(IO_BUS_TYPE busType) {
|
||||
switch (busType) {
|
||||
case IoBusPci: return "pci";
|
||||
case IoBusUsb: return "usb";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static bool IoTryBindDevice(IO_PUBLISHED_DEVICE* device,
|
||||
IO_DRIVER_MATCHER_ENTRY* matcher) {
|
||||
if (!device || !matcher || !matcher->Used || device->Bound)
|
||||
return false;
|
||||
if (matcher->BusType != IoBusUnknown && matcher->BusType != device->BusType)
|
||||
return false;
|
||||
if (!matcher->Match || !matcher->Bind)
|
||||
return false;
|
||||
if (!matcher->Match(device, matcher->Context))
|
||||
return false;
|
||||
|
||||
KSTATUS st = matcher->Bind(device, matcher->Context);
|
||||
if (KSUCCESS(st)) {
|
||||
device->Bound = true;
|
||||
device->BoundDriverName = matcher->DriverName;
|
||||
DbgPrint("io: %s device %s bound by %s\n",
|
||||
IoBusTypeName(device->BusType),
|
||||
device->Name ? device->Name : "<unnamed>",
|
||||
matcher->DriverName ? matcher->DriverName : "<unnamed>");
|
||||
return true;
|
||||
}
|
||||
|
||||
DbgPrint("io: %s matcher %s accepted %s but bind failed st=0x%x\n",
|
||||
IoBusTypeName(device->BusType),
|
||||
matcher->DriverName ? matcher->DriverName : "<unnamed>",
|
||||
device->Name ? device->Name : "<unnamed>",
|
||||
st);
|
||||
return false;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoRegisterDriverMatcher(const char* driverName,
|
||||
IO_BUS_TYPE busType,
|
||||
IO_DRIVER_MATCH_CALLBACK match,
|
||||
IO_DRIVER_BIND_CALLBACK bind,
|
||||
void* context) {
|
||||
if (!driverName || !match || !bind)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (gDriverMatcherCount >= MAX_DRIVER_MATCHERS)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
IO_DRIVER_MATCHER_ENTRY* entry = &gDriverMatchers[gDriverMatcherCount++];
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->Used = true;
|
||||
entry->DriverName = driverName;
|
||||
entry->BusType = busType;
|
||||
entry->Match = match;
|
||||
entry->Bind = bind;
|
||||
entry->Context = context;
|
||||
|
||||
DbgPrint("io: registered %s matcher %s\n",
|
||||
IoBusTypeName(busType), driverName);
|
||||
|
||||
for (uint32_t i = 0; i < gPublishedDeviceCount; i++) {
|
||||
IoTryBindDevice(&gPublishedDevices[i], entry);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoPublishDevice(const IO_PUBLISHED_DEVICE* device) {
|
||||
if (!device || device->BusType == IoBusUnknown)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (gPublishedDeviceCount >= MAX_PUBLISHED_DEVICES)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
IO_PUBLISHED_DEVICE* stored = &gPublishedDevices[gPublishedDeviceCount++];
|
||||
memcpy(stored, device, sizeof(*stored));
|
||||
stored->Bound = false;
|
||||
stored->BoundDriverName = (const char*)0;
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < gDriverMatcherCount; i++) {
|
||||
if (IoTryBindDevice(stored, &gDriverMatchers[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) uint32_t IoPublishedDeviceCount(void) {
|
||||
return gPublishedDeviceCount;
|
||||
}
|
||||
|
||||
#define MAX_DISK_DEVICES 8
|
||||
#define MAX_DISK_ARRIVAL_CALLBACKS 16
|
||||
|
||||
typedef struct IO_DISK_CALLBACK_ENTRY {
|
||||
bool Used;
|
||||
IO_DISK_ARRIVAL_CALLBACK Callback;
|
||||
void* Context;
|
||||
} IO_DISK_CALLBACK_ENTRY;
|
||||
|
||||
static DEVICE_OBJECT* gDiskDevices[MAX_DISK_DEVICES];
|
||||
static IO_DISK_CALLBACK_ENTRY gDiskArrivalCallbacks[MAX_DISK_ARRIVAL_CALLBACKS];
|
||||
static uint32_t gDiskArrivalCallbackCount;
|
||||
|
||||
static void IoNotifyDiskArrived(uint8_t driveIndex, DEVICE_OBJECT* device) {
|
||||
for (uint32_t i = 0; i < gDiskArrivalCallbackCount; i++) {
|
||||
IO_DISK_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[i];
|
||||
if (entry->Used && entry->Callback)
|
||||
entry->Callback(driveIndex, device, entry->Context);
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoCreateDevice(DRIVER_OBJECT* driver,
|
||||
size_t extensionSize,
|
||||
@@ -43,6 +170,41 @@ __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex,
|
||||
device->Flags |= DEVICE_OBJECT_DISK;
|
||||
device->DiskIndex = driveIndex;
|
||||
gDiskDevices[driveIndex] = device;
|
||||
IoNotifyDiskArrived(driveIndex, device);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoRegisterDiskArrivalCallback(IO_DISK_ARRIVAL_CALLBACK callback,
|
||||
void* context) {
|
||||
if (!callback)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (gDiskArrivalCallbackCount >= MAX_DISK_ARRIVAL_CALLBACKS)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
IO_DISK_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[gDiskArrivalCallbackCount++];
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->Used = true;
|
||||
entry->Callback = callback;
|
||||
entry->Context = context;
|
||||
|
||||
for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) {
|
||||
if (gDiskDevices[i])
|
||||
callback(i, gDiskDevices[i], context);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS IoEnumerateDiskDevices(IO_DISK_ARRIVAL_CALLBACK callback,
|
||||
void* context) {
|
||||
if (!callback)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) {
|
||||
if (gDiskDevices[i])
|
||||
callback(i, gDiskDevices[i], context);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user