add display subsystem and vmwaresvga driver, support absolute mouse and qemu tablet, map pci mmio to private virtual aperture, better smp panic handling, remove legacy io publish/match, add sys query display info and display command to native shell

This commit is contained in:
maksw committed 2026-06-15 09:58:12 +02:00
1 parent e41bf6e2c0
commit 6260de0085
38 files changed
+4011 -467

No files matched your search

+7 -6
View File
@@ -866,8 +866,11 @@ EFI_STATUS EFIAPI UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable
for (UINTN i = 0; i < mapSize / descSz; i++) {
EFI_MEMORY_DESCRIPTOR* desc = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)efiMap + i * descSz);
// Map everything except unusable memory to the Physical Window.
if (desc->Type != EfiUnusableMemory && desc->Type != EfiMemoryMappedIOPortSpace) {
// Map normal firmware-described regions into the physical window.
// PCI/firmware MMIO is mapped explicitly by the owning driver.
if (desc->Type != EfiUnusableMemory &&
desc->Type != EfiMemoryMappedIO &&
desc->Type != EfiMemoryMappedIOPortSpace) {
UINT64 start = desc->PhysicalStart;
UINT64 end = start + (desc->NumberOfPages * PAGE_SIZE);
@@ -890,10 +893,8 @@ EFI_STATUS EFIAPI UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable
// We explicitly map the region from 0xFEC00000 up through 0xFEE00FFF
// to guarantee the HAL can access them via the physical window.
for (UINT64 phys = 0xFEC00000; phys < 0xFEE01000; phys += PAGE_SIZE) {
// In a production OS you'd use Cache-Disable flags (0x13 or 0x1B),
// but 0x03 is fine for hobby OS initialization before PAT is set up.
Map4K(phys, phys, 0x03); // Identity Map
Map4K(PHYS_MAP_BASE + phys, phys, 0x03); // Physical Window Map
Map4K(phys, phys, 0x13); // Identity Map, P|W|PCD
Map4K(PHYS_MAP_BASE + phys, phys, 0x13); // Physical Window Map, P|W|PCD
}
//Print(L"8\n");
+5 -3
View File
@@ -33,6 +33,7 @@ static const Driver_Target STANDALONE_DRIVERS[] = {
DRIVER_TARGET_LIBS("ata", "obj\\drivers\\ata", "code\\drivers\\storage\\ata\\ata.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("ahci", "obj\\drivers\\ahci", "code\\drivers\\storage\\ahci\\ahci.c code\\drivers\\storage\\ahci\\ahci_port.c", "bin\\pci.lib"),
DRIVER_TARGET("fat32", "obj\\drivers\\fat32", "code\\drivers\\fs\\fat32\\fat32.c code\\drivers\\fs\\fat32\\fat32_mount.c"),
DRIVER_TARGET_LIBS("vmwaresvga", "obj\\drivers\\vmwaresvga", "code\\drivers\\display\\vmwaresvga\\vmwaresvga.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("usb", "obj\\drivers\\usb", "code\\drivers\\bus\\usb\\usb.c code\\drivers\\bus\\usb\\usb_bus.c code\\drivers\\bus\\usb\\usb_composite.c code\\drivers\\bus\\usb\\usb_core.c code\\drivers\\bus\\usb\\usb_xhci.c code\\drivers\\bus\\usb\\usb_hid.c code\\drivers\\bus\\usb\\usb_storage.c code\\drivers\\bus\\usb\\usb_hub.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("rtl816x", "obj\\drivers\\rtl816x", "code\\drivers\\net\\rtl816x\\rtl816x.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("rtl8139", "obj\\drivers\\rtl8139", "code\\drivers\\net\\rtl8139\\rtl8139.c", "bin\\pci.lib"),
@@ -102,7 +103,7 @@ int main(int argc, char **argv) {
nob_temp_sprintf("cl %s /MP /c /Foobj\\hal\\ code\\kernel\\hal\\*.c && link %s /DLL /OUT:bin\\hal.dll /ENTRY:HalInitialize /IGNORE:4216 obj\\printf.obj obj\\libc.obj obj\\hal\\*.obj", CFLAGS, LFLAGS),
// Kernel
nob_temp_sprintf("cl %s /MP /c /Foobj\\kernel\\ code\\kernel\\*.c && link %s /SUBSYSTEM:NATIVE /ENTRY:KernelMain /OUT:bin\\kernel.exe bin\\hal.lib obj\\ini_parser.obj obj\\printf.obj obj\\libc.obj obj\\kernel\\*.obj", CFLAGS, LFLAGS),
nob_temp_sprintf("cl %s /DKE_DISPLAY_BUILD /MP /c /Foobj\\kernel\\ code\\kernel\\*.c && link %s /SUBSYSTEM:NATIVE /ENTRY:KernelMain /OUT:bin\\kernel.exe bin\\hal.lib obj\\ini_parser.obj obj\\printf.obj obj\\libc.obj obj\\kernel\\*.obj", CFLAGS, LFLAGS),
// Subsystem DLLs
"link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:bin\\syscall.dll obj\\syscall\\stubs.obj",
@@ -218,8 +219,9 @@ int main(int argc, char **argv) {
{"bin\\pci.sys", "Z:\\drivers\\pci.sys"}, {"bin\\ps2.sys", "Z:\\drivers\\ps2.sys"},
{"bin\\ata.sys", "Z:\\drivers\\ata.sys"}, {"bin\\ahci.sys", "Z:\\drivers\\ahci.sys"},
{"bin\\fat32.sys", "Z:\\drivers\\fat32.sys"}, {"bin\\lwip.sys", "Z:\\drivers\\lwip.sys"},
{"bin\\usb.sys", "Z:\\drivers\\usb.sys"}, {"bin\\rtl816x.sys", "Z:\\drivers\\rtl816x.sys"},
{"bin\\fat32.sys", "Z:\\drivers\\fat32.sys"}, {"bin\\vmwaresvga.sys", "Z:\\drivers\\vmwaresvga.sys"},
{"bin\\lwip.sys", "Z:\\drivers\\lwip.sys"}, {"bin\\usb.sys", "Z:\\drivers\\usb.sys"},
{"bin\\rtl816x.sys", "Z:\\drivers\\rtl816x.sys"},
{"bin\\rtl8139.sys", "Z:\\drivers\\rtl8139.sys"}, {"code\\drivers\\drivers.ini", "Z:\\drivers\\drivers.ini"},
{"code\\boot.ini", "Z:\\boot.ini"},
+51 -9
View File
@@ -20,6 +20,40 @@ static const HAL_API* gHal;
static DRIVER_OBJECT gPciDriver;
static uint32_t gPciDeviceCount;
/*
* PCI MMIO BARs use a private virtual aperture instead of the physical
* direct map. This avoids cacheability aliasing with large direct-map pages
* and keeps BAR mappings page-granular.
*/
#define PCI_MMIO_VA_BASE 0xFFFF900000000000ULL
#define PCI_MMIO_VA_LIMIT 0xFFFF980000000000ULL
static uintptr_t gPciMmioNext = PCI_MMIO_VA_BASE;
static uint64_t PciAlignUp64(uint64_t value, uint64_t alignment) {
return (value + alignment - 1u) & ~(alignment - 1u);
}
static uint64_t PciDefaultMmioFlags(void) {
return PAGE_PRESENT | PAGE_WRITE | PAGE_WRITETHROUGH | PAGE_NOCACHE | PAGE_NX;
}
static KSTATUS PciAllocateMmioVa(uint64_t length, uintptr_t* outVa) {
if (!outVa || !length)
return STATUS_INVALID_PARAMETER;
uint64_t alignedLength = PciAlignUp64(length, PAGE_SIZE);
uintptr_t va = (uintptr_t)PciAlignUp64((uint64_t)gPciMmioNext, PAGE_SIZE);
if (va < PCI_MMIO_VA_BASE || va >= PCI_MMIO_VA_LIMIT)
return STATUS_NO_MEMORY;
if (alignedLength > (uint64_t)(PCI_MMIO_VA_LIMIT - va))
return STATUS_NO_MEMORY;
gPciMmioNext = va + (uintptr_t)alignedLength;
*outVa = va;
return STATUS_SUCCESS;
}
static bool PciIsPdo(DEVICE_OBJECT* pdo, PCI_PDO_EXTENSION** outExt) {
if (!pdo || pdo->Type != DeviceObjectPhysical || pdo->u.Pdo.BusType != IoBusPci)
return false;
@@ -455,27 +489,35 @@ __declspec(dllexport) KSTATUS PciGetBar(DEVICE_OBJECT* pdo, uint8_t index, PCI_B
__declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint64_t pageFlags, void** outVirtual, uint64_t* outLength) {
PCI_BAR bar;
if (!outVirtual) return STATUS_INVALID_PARAMETER;
*outVirtual = NULL;
KSTATUS st = PciGetBar(pdo, index, &bar);
if (!KSUCCESS(st)) return st;
if (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64)
return STATUS_NOT_SUPPORTED;
if (!bar.Length)
return STATUS_DEVICE_ERROR;
if (bar.Base + bar.Length < bar.Base)
return STATUS_INVALID_PARAMETER;
uint64_t flags = pageFlags ? pageFlags : (PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE);
uint64_t pageBase = bar.Base & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t pageEnd = (bar.Base + bar.Length + PAGE_SIZE - 1u) & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t flags = pageFlags ? pageFlags : PciDefaultMmioFlags();
flags |= PAGE_PRESENT;
for (uint64_t phys = pageBase; phys < pageEnd; phys += PAGE_SIZE) {
uintptr_t virt = (uintptr_t)gHal->PhysToVirt(phys);
st = MmMapPage(virt, phys, flags, MmMapFailIfPresent);
if (st == STATUS_ALREADY_EXISTS)
st = MmSetPageProtect(virt, PAGE_SIZE, flags);
uint64_t physBase = bar.Base & ~(uint64_t)(PAGE_SIZE - 1u);
uint64_t physOffset = bar.Base - physBase;
uint64_t mapLength = PciAlignUp64(physOffset + bar.Length, PAGE_SIZE);
uintptr_t virtBase = 0;
st = PciAllocateMmioVa(mapLength, &virtBase);
if (!KSUCCESS(st))
return st;
for (uint64_t off = 0; off < mapLength; off += PAGE_SIZE) {
st = MmMapPage(virtBase + (uintptr_t)off, physBase + off, flags, MmMapFailIfPresent);
if (!KSUCCESS(st))
return st;
}
*outVirtual = (void*)((uintptr_t)gHal->PhysToVirt(pageBase) + (uintptr_t)(bar.Base - pageBase));
*outVirtual = (void*)(virtBase + (uintptr_t)physOffset);
if (outLength) *outLength = bar.Length;
return STATUS_SUCCESS;
}
+7 -5
View File
@@ -115,6 +115,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define XHCI_CC_SUCCESS 1u
#define XHCI_CC_SHORT_PACKET 13u
#define XHCI_TRB_ISP (1u << 2)
#define XHCI_TRB_IOC (1u << 5)
@@ -458,6 +459,7 @@ struct USB_URB {
PHYSICAL_ADDRESS BufferPhys;
uint32_t Length;
uint32_t ActualLength;
uint32_t HcdCompletionCode;
KSTATUS Status;
IRP* Irp;
USB_URB_COMPLETION Complete;
@@ -562,6 +564,11 @@ typedef struct USB_HID_EXTENSION {
bool Removed;
bool Keyboard;
bool Mouse;
bool AbsoluteMouse;
uint16_t AbsoluteMaxX;
uint16_t AbsoluteMaxY;
uint16_t LastAbsoluteX;
uint16_t LastAbsoluteY;
uint8_t InterfaceNumber;
uint8_t Protocol;
uint8_t EndpointAddress;
@@ -954,9 +961,6 @@ KSTATUS XhciStartHidInterrupts(XHCI_CONTROLLER* xhci);
KSTATUS XhciSetHidBootProtocol(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciAllocateHidMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
const IO_PUBLISHED_USB_ENDPOINT* UsbFindEndpoint(const IO_PUBLISHED_DEVICE* pub, uint8_t endpointType, bool wantIn);
bool UsbHidMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbHidBind(IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t trbCount, uint8_t cycle);
@@ -982,8 +986,6 @@ KSTATUS XhciAllocateMassStorageMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint8_t UsbFindFreeDiskIndex(void);
KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage);
bool UsbStorageMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbStorageBind(IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS XhciSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t configurationValue);
void XhciLogConfigurationTree(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_CONFIGURATION_DESCRIPTOR* config, uint16_t totalLength);
KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_DEVICE_DESCRIPTOR* devDesc);
+84 -90
View File
@@ -135,7 +135,7 @@ static void XhciHandleLegacyHidTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trb
return;
dev->HidArmed = false;
if (completionCode != XHCI_CC_SUCCESS) {
if (completionCode != XHCI_CC_SUCCESS && completionCode != XHCI_CC_SHORT_PACKET) {
DbgPrint("usb: HID transfer failed slot=%u ep=%u cc=%u residue=%u\n",
slotId, endpointId, completionCode, residue);
return;
@@ -298,73 +298,6 @@ KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) {
}
const IO_PUBLISHED_USB_ENDPOINT* UsbFindEndpoint(const IO_PUBLISHED_DEVICE* pub,
uint8_t endpointType,
bool wantIn) {
if (!pub || pub->BusType != IoBusUsb) return (const IO_PUBLISHED_USB_ENDPOINT*)0;
for (uint8_t i = 0; i < pub->u.Usb.EndpointCount; i++) {
const IO_PUBLISHED_USB_ENDPOINT* ep = &pub->u.Usb.Endpoints[i];
uint8_t type = ep->Attributes & USB_ENDPOINT_ATTR_TYPE_MASK;
bool in = (ep->Address & USB_ENDPOINT_DIR_IN) != 0;
if (type == endpointType && in == wantIn)
return ep;
}
return (const IO_PUBLISHED_USB_ENDPOINT*)0;
}
bool UsbHidMatch(const IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || pub->BusType != IoBusUsb)
return false;
if (pub->u.Usb.InterfaceClass != USB_CLASS_HID)
return false;
if (pub->u.Usb.InterfaceSubclass != USB_HID_SUBCLASS_BOOT)
return false;
if (pub->u.Usb.InterfaceProtocol != USB_HID_PROTOCOL_KEYBOARD &&
pub->u.Usb.InterfaceProtocol != USB_HID_PROTOCOL_MOUSE)
return false;
return UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_INTERRUPT, true) != (const IO_PUBLISHED_USB_ENDPOINT*)0;
}
KSTATUS UsbHidBind(IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || !pub->BusContext || !pub->DeviceContext)
return STATUS_INVALID_PARAMETER;
XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)pub->BusContext;
XHCI_DEVICE* dev = (XHCI_DEVICE*)pub->DeviceContext;
if (dev->HidActive || dev->HidCandidate)
return STATUS_ALREADY_EXISTS;
const IO_PUBLISHED_USB_ENDPOINT* ep = UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_INTERRUPT, true);
if (!ep)
return STATUS_NOT_FOUND;
dev->HidCandidate = true;
dev->HidKeyboard = (pub->u.Usb.InterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
dev->HidMouse = (pub->u.Usb.InterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
dev->HidInterface = pub->u.Usb.InterfaceNumber;
dev->HidProtocol = pub->u.Usb.InterfaceProtocol;
dev->HidEndpointAddress = ep->Address;
dev->HidEndpointId = XhciEndpointIdFromAddress(ep->Address);
dev->HidInterval = ep->Interval;
dev->HidMaxPacket = ep->MaxPacketSize;
KSTATUS st = XhciConfigureHidEndpoint(xhci, dev);
if (!KSUCCESS(st)) {
dev->HidCandidate = false;
dev->HidKeyboard = false;
dev->HidMouse = false;
}
return st;
}
// -------------------------------------------------------------------------
// PDO/FDO boot HID function driver path.
// -------------------------------------------------------------------------
@@ -374,6 +307,7 @@ DRIVER_OBJECT gUsbHidDriver;
static const IO_DEVICE_ID gUsbHidIds[] = {
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_01&PROT_01", sizeof("USB\\CLASS_03&SUBCLASS_01&PROT_01") - 1 } },
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_01&PROT_02", sizeof("USB\\CLASS_03&SUBCLASS_01&PROT_02") - 1 } },
{ IoBusUsb, { "USB\\CLASS_03&SUBCLASS_00&PROT_00", sizeof("USB\\CLASS_03&SUBCLASS_00&PROT_00") - 1 } },
};
static const IO_DRIVER_ID_TABLE gUsbHidIdTable = {
@@ -381,6 +315,26 @@ static const IO_DRIVER_ID_TABLE gUsbHidIdTable = {
sizeof(gUsbHidIds) / sizeof(gUsbHidIds[0]),
};
static bool UsbHidIsQemuAbsoluteTabletPdo(const USB_PDO_EXTENSION* pdoExt, const USB_ENDPOINT_DESCRIPTOR* ep) {
if (!pdoExt || !pdoExt->Device || !ep)
return false;
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID)
return false;
if (pdoExt->InterfaceDescriptor.bInterfaceSubClass != 0 ||
pdoExt->InterfaceDescriptor.bInterfaceProtocol != 0)
return false;
if (pdoExt->Device->VendorId != 0x0627u || pdoExt->Device->ProductId != 0x0001u)
return false;
/*
* QEMU's usb-kbd and usb-tablet commonly share VID:PID 0627:0001.
* Do not classify by VID:PID alone: the boot keyboard is subclass/protocol
* 01/01, while usb-tablet is the non-boot HID interface 00/00.
*/
return (ep->wMaxPacketSize & 0x07FFu) >= 6u;
}
static const USB_ENDPOINT_DESCRIPTOR* UsbHidFindInterruptInPdo(const USB_PDO_EXTENSION* ext) {
if (!ext) return (const USB_ENDPOINT_DESCRIPTOR*)0;
@@ -443,6 +397,24 @@ static void UsbHidProcessBootMouseReport(USB_HID_EXTENSION* ext, const uint8_t*
ext->LastButtons = buttons;
}
static void UsbHidProcessQemuTabletReport(USB_HID_EXTENSION* ext, const uint8_t* report, uint16_t len) {
if (!ext || len < 5) return;
uint8_t buttons = report[0] & 0x07u;
uint16_t x = (uint16_t)report[1] | ((uint16_t)report[2] << 8);
uint16_t y = (uint16_t)report[3] | ((uint16_t)report[4] << 8);
int wheel = (len >= 6) ? (int)(int8_t)report[5] : 0;
if (x != ext->LastAbsoluteX || y != ext->LastAbsoluteY ||
wheel || buttons != ext->LastButtons) {
KeInputSubmitMouseAbsoluteScaled(x, y, ext->AbsoluteMaxX, ext->AbsoluteMaxY, wheel, buttons);
}
ext->LastAbsoluteX = x;
ext->LastAbsoluteY = y;
ext->LastButtons = buttons;
}
static KSTATUS UsbHidArmInterrupt(USB_HID_EXTENSION* ext);
static void UsbHidInterruptComplete(USB_URB* urb, void* context) {
@@ -460,14 +432,19 @@ static void UsbHidInterruptComplete(USB_URB* urb, void* context) {
if (ext->Keyboard)
UsbHidProcessBootKeyboardReport(ext, ext->ReportBuffer, length);
else if (ext->AbsoluteMouse)
UsbHidProcessQemuTabletReport(ext, ext->ReportBuffer, length);
else if (ext->Mouse)
UsbHidProcessBootMouseReport(ext, ext->ReportBuffer, length);
} else if (urb->Status != STATUS_CANCELLED) {
DbgPrint("usb: HID interrupt URB failed slot=%u if=%u ep=%02x st=0x%x\n",
DbgPrint("usb: HID interrupt URB failed slot=%u if=%u ep=%02x st=0x%x cc=%u actual=%u/%u\n",
ext->Device ? ext->Device->SlotId : 0,
ext->InterfaceNumber,
ext->EndpointAddress,
urb->Status);
urb->Status,
urb->HcdCompletionCode,
urb->ActualLength,
urb->Length);
}
if (!ext->SurpriseRemoved && !ext->Removed)
@@ -563,8 +540,14 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (!ep)
return STATUS_NOT_FOUND;
ext->Keyboard = (pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
ext->Mouse = (pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
ext->Keyboard = (pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD);
ext->AbsoluteMouse = UsbHidIsQemuAbsoluteTabletPdo(pdoExt, ep);
ext->Mouse = ext->AbsoluteMouse ||
(pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE);
ext->AbsoluteMaxX = 0x7FFFu;
ext->AbsoluteMaxY = 0x7FFFu;
ext->InterfaceNumber = pdoExt->InterfaceDescriptor.bInterfaceNumber;
ext->Protocol = pdoExt->InterfaceDescriptor.bInterfaceProtocol;
ext->EndpointAddress = ep->bEndpointAddress;
@@ -572,9 +555,10 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
ext->Interval = ep->bInterval;
uint16_t reportLength = ext->MaxPacketSize & 0x07FFu;
if (reportLength == 0) reportLength = ext->Keyboard ? 8u : 4u;
if (reportLength == 0) reportLength = ext->Keyboard ? 8u : (ext->AbsoluteMouse ? 6u : 4u);
if (ext->Keyboard && reportLength < 8) reportLength = 8;
if (ext->Mouse && reportLength < 3) reportLength = 3;
if (ext->AbsoluteMouse && reportLength < 6) reportLength = 6;
if (ext->Mouse && !ext->AbsoluteMouse && reportLength < 3) reportLength = 3;
if (reportLength > XHCI_MAX_HID_REPORT) reportLength = XHCI_MAX_HID_REPORT;
ext->ReportLength = reportLength;
@@ -591,15 +575,17 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (!KSUCCESS(st))
return st;
st = UsbHidSendBootProtocol(ext);
if (!KSUCCESS(st))
return st;
if (!ext->AbsoluteMouse) {
st = UsbHidSendBootProtocol(ext);
if (!KSUCCESS(st))
return st;
}
memset(ext->LastKeys, 0, sizeof(ext->LastKeys));
ext->LastModifiers = 0;
ext->LastButtons = 0;
KeInputRegisterDevice(ext->Keyboard ? "usb-hid-keyboard" : "usb-hid-mouse", 0, &ext->InputDeviceId);
KeInputRegisterDevice(ext->Keyboard ? "usb-hid-keyboard" : (ext->AbsoluteMouse ? "usb-hid-tablet" : "usb-hid-mouse"), 0, &ext->InputDeviceId);
ext->Started = true;
device->PnpState = DevicePnpStarted;
@@ -616,8 +602,8 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext)
if (xhci)
xhci->HidDeviceCount++;
DbgPrint("usb: HID boot %s bound slot=%u if=%u ep=%02x maxpkt=%u interval=%u input=%u urb\n",
ext->Keyboard ? "keyboard" : "mouse",
DbgPrint("usb: HID %s bound slot=%u if=%u ep=%02x maxpkt=%u interval=%u input=%u urb\n",
ext->Keyboard ? "boot-keyboard" : (ext->AbsoluteMouse ? "qemu-tablet" : "boot-mouse"),
ext->Device->SlotId,
ext->InterfaceNumber,
ext->EndpointAddress,
@@ -720,24 +706,31 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje
USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension;
if (!pdoExt || pdoExt->Kind != UsbPdoInterface || !pdoExt->Device)
return STATUS_INVALID_PARAMETER;
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID ||
pdoExt->InterfaceDescriptor.bInterfaceSubClass != USB_HID_SUBCLASS_BOOT)
if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID)
return STATUS_INVALID_PARAMETER;
if (pdoExt->InterfaceDescriptor.bInterfaceProtocol != USB_HID_PROTOCOL_KEYBOARD &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol != USB_HID_PROTOCOL_MOUSE)
return STATUS_INVALID_PARAMETER;
if (!UsbHidFindInterruptInPdo(pdoExt))
const USB_ENDPOINT_DESCRIPTOR* ep = UsbHidFindInterruptInPdo(pdoExt);
if (!ep)
return STATUS_NOT_FOUND;
bool bootKeyboard = pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD;
bool bootMouse = pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT &&
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE;
bool qemuTablet = UsbHidIsQemuAbsoluteTabletPdo(pdoExt, ep);
if (!bootKeyboard && !bootMouse && !qemuTablet)
return STATUS_INVALID_PARAMETER;
DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0;
KSTATUS st = IoCreateDevice(driver, sizeof(USB_HID_EXTENSION), &fdo);
if (!KSUCCESS(st))
return st;
(void)IoSetDeviceName(fdo,
pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD
bootKeyboard
? SYS_SV_LITERAL("usb-hid-keyboard")
: SYS_SV_LITERAL("usb-hid-mouse"));
: (qemuTablet ? SYS_SV_LITERAL("usb-hid-tablet")
: SYS_SV_LITERAL("usb-hid-mouse")));
USB_HID_EXTENSION* ext = (USB_HID_EXTENSION*)fdo->DeviceExtension;
ext->Self = fdo;
@@ -758,10 +751,11 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje
return STATUS_FAILURE;
}
DbgPrint("usb: HID FDO attached slot=%u if=%u proto=%u\n",
DbgPrint("usb: HID FDO attached slot=%u if=%u proto=%u kind=%s\n",
ext->Device->SlotId,
pdoExt->InterfaceDescriptor.bInterfaceNumber,
pdoExt->InterfaceDescriptor.bInterfaceProtocol);
pdoExt->InterfaceDescriptor.bInterfaceProtocol,
qemuTablet ? "qemu-tablet" : (bootKeyboard ? "keyboard" : "mouse"));
return STATUS_SUCCESS;
}
-20
View File
@@ -764,26 +764,6 @@ KSTATUS UsbStorageDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
return STATUS_INVALID_PARAMETER;
}
bool UsbStorageMatch(const IO_PUBLISHED_DEVICE* pub, void* context) {
(void)context;
if (!pub || pub->BusType != IoBusUsb)
return false;
if (pub->u.Usb.InterfaceClass != USB_CLASS_MASS_STORAGE)
return false;
if (pub->u.Usb.InterfaceSubclass != USB_MASS_SUBCLASS_SCSI)
return false;
if (pub->u.Usb.InterfaceProtocol != USB_MASS_PROTOCOL_BOT)
return false;
return UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_BULK, true) &&
UsbFindEndpoint(pub, USB_ENDPOINT_TYPE_BULK, false);
}
KSTATUS UsbStorageBind(IO_PUBLISHED_DEVICE* pub, void* context) {
(void)pub;
(void)context;
return STATUS_NOT_SUPPORTED;
}
KSTATUS UsbStorageAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) {
if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical)
+4 -1
View File
@@ -1667,6 +1667,7 @@ static KSTATUS XhciHcdSubmitInterruptUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev
urb->Cancelled = false;
urb->Status = STATUS_PENDING;
urb->ActualLength = 0;
urb->HcdCompletionCode = 0;
XhciBarrier();
XhciWrite32(xhci->Doorbells, (uint32_t)dev->SlotId * 4u, ctx->EndpointId);
@@ -1699,7 +1700,8 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys,
KSTATUS st = STATUS_SUCCESS;
if (urb->Cancelled) {
st = STATUS_CANCELLED;
} else if (completionCode != XHCI_CC_SUCCESS) {
} else if (completionCode != XHCI_CC_SUCCESS &&
completionCode != XHCI_CC_SHORT_PACKET) {
st = STATUS_DEVICE_ERROR;
}
@@ -1711,6 +1713,7 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys,
urb->Pending = false;
urb->Status = st;
urb->ActualLength = actual;
urb->HcdCompletionCode = completionCode;
IRP* completeIrp = urb->Irp;
urb->Irp = (IRP*)0;
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,215 @@
#pragma once
// vmwaresvga.h - VMware SVGA-II display provider internals.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <intrin.h>
#include <ntlite/status.h>
#include <ntlite/ddi/hal_api.h>
#include <ntlite/ddi/io_driver.h>
#include <ntlite/ddi/pci.h>
#include <ntlite/ddi/display.h>
#include <kernel/ke_display.h>
#include <kernel/ke_debug.h>
#include <kernel/mm_virt.h>
#include <kernel/display_cursor.h>
#define VMWSVGA_VENDOR_VMWARE 0x15ADu
#define VMWSVGA_DEVICE_SVGA2 0x0405u
#define VMWSVGA_DEVICE_MAGIC 0x564D5356u /* VMSV */
#define SVGA_ID_INVALID 0xFFFFFFFFu
#define SVGA_ID_0 0x90000000u
#define SVGA_ID_1 0x90000001u
#define SVGA_ID_2 0x90000002u
#define SVGA_INDEX_PORT 0u
#define SVGA_VALUE_PORT 1u
#define SVGA_REG_ID 0u
#define SVGA_REG_ENABLE 1u
#define SVGA_REG_WIDTH 2u
#define SVGA_REG_HEIGHT 3u
#define SVGA_REG_MAX_WIDTH 4u
#define SVGA_REG_MAX_HEIGHT 5u
#define SVGA_REG_DEPTH 6u
#define SVGA_REG_BITS_PER_PIXEL 7u
#define SVGA_REG_BYTES_PER_LINE 12u
#define SVGA_REG_FB_START 13u
#define SVGA_REG_FB_OFFSET 14u
#define SVGA_REG_VRAM_SIZE 15u
#define SVGA_REG_FB_SIZE 16u
#define SVGA_REG_CAPABILITIES 17u
#define SVGA_REG_MEM_START 18u
#define SVGA_REG_MEM_SIZE 19u
#define SVGA_REG_CONFIG_DONE 20u
#define SVGA_REG_SYNC 21u
#define SVGA_REG_BUSY 22u
#define SVGA_REG_GUEST_ID 23u
#define SVGA_REG_CURSOR_ID 24u
#define SVGA_REG_CURSOR_X 25u
#define SVGA_REG_CURSOR_Y 26u
#define SVGA_REG_CURSOR_ON 27u
#define SVGA_REG_HOST_BITS_PER_PIXEL 28u
#define SVGA_REG_MEM_REGS 30u
#define SVGA_REG_NUM_GUEST_DISPLAYS 34u
#define SVGA_REG_DISPLAY_ID 35u
#define SVGA_REG_DISPLAY_IS_PRIMARY 36u
#define SVGA_REG_DISPLAY_POSITION_X 37u
#define SVGA_REG_DISPLAY_POSITION_Y 38u
#define SVGA_REG_DISPLAY_WIDTH 39u
#define SVGA_REG_DISPLAY_HEIGHT 40u
#define SVGA_REG_PITCHLOCK 32u
#define SVGA_CMD_INVALID_CMD 0u
#define SVGA_CMD_UPDATE 1u
#define SVGA_CMD_RECT_FILL 2u
#define SVGA_CMD_RECT_COPY 3u
#define SVGA_CMD_DEFINE_CURSOR 19u
#define SVGA_CMD_DISPLAY_CURSOR 20u
#define SVGA_CMD_DEFINE_ALPHA_CURSOR 22u
#define SVGA_CMD_DEFINE_SCREEN 34u
#define SVGA_CMD_DESTROY_SCREEN 35u
#define SVGA_CMD_DEFINE_GMRFB 36u
#define SVGA_CMD_BLIT_GMRFB_TO_SCREEN 37u
#define SVGA_FIFO_MIN 0u
#define SVGA_FIFO_MAX 1u
#define SVGA_FIFO_NEXT_CMD 2u
#define SVGA_FIFO_STOP 3u
#define SVGA_FIFO_CAPABILITIES 4u
#define SVGA_FIFO_FLAGS 5u
#define SVGA_FIFO_FENCE 6u
#define SVGA_FIFO_3D_HWVERSION 7u
#define SVGA_FIFO_PITCHLOCK 8u
#define SVGA_FIFO_CURSOR_ON 9u
#define SVGA_FIFO_CURSOR_X 10u
#define SVGA_FIFO_CURSOR_Y 11u
#define SVGA_FIFO_CURSOR_COUNT 12u
#define SVGA_FIFO_CURSOR_LAST_UPDATED 13u
#define SVGA_FIFO_RESERVED 14u
#define SVGA_FIFO_CURSOR_SCREEN_ID 15u
#define SVGA_FIFO_3D_CAPS 32u
#define SVGA_FIFO_3D_CAPS_LAST (SVGA_FIFO_3D_CAPS + 255u)
#define SVGA_FIFO_GUEST_3D_HWVERSION (SVGA_FIFO_3D_CAPS_LAST + 1u)
#define SVGA_FIFO_FENCE_GOAL (SVGA_FIFO_3D_CAPS_LAST + 2u)
#define SVGA_FIFO_BUSY (SVGA_FIFO_3D_CAPS_LAST + 3u)
#define SVGA_FIFO_NUM_LEGACY_REGS 4u
#define SVGA_FIFO_NUM_REGS_FALLBACK (SVGA_FIFO_BUSY + 3u)
#define SVGA_CAP_CURSOR 0x00000020u
#define SVGA_CAP_CURSOR_BYPASS 0x00000040u
#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080u
#define SVGA_CAP_ALPHA_CURSOR 0x00000200u
#define SVGA_CAP_EXTENDED_FIFO 0x00008000u
#define SVGA_CAP_MULTIMON 0x00010000u
#define SVGA_CAP_PITCHLOCK 0x00020000u
#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000u
#define SVGA_CAP_GMR 0x00100000u
#define SVGA_CAP_GMR2 0x00400000u
#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000u
#define SVGA_CURSOR_ON_HIDE 0u
#define SVGA_CURSOR_ON_SHOW 1u
#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 0x00000010u
#define SVGA_FIFO_CAP_SCREEN_OBJECT 0x00000080u
#define SVGA_FIFO_CAP_SCREEN_OBJECT_2 0x00000200u
#define SVGA_GMR_FRAMEBUFFER 0xFFFFFFFEu
#define SVGA_SCREEN_MUST_BE_SET 0x00000001u
#define SVGA_SCREEN_IS_PRIMARY 0x00000002u
#define SVGA_SCREEN_OBJECT_ID_PRIMARY 0u
#define SVGA_GMRFB_FORMAT_32BPP_24DEPTH ((32u) | (24u << 8))
/*
* The production path is legacy GFB + UPDATE. Screen objects are kept behind
* an opt-in switch until the SO/GMRFB path is independently validated on real
* VMware hosts.
*/
#ifndef VMWSVGA_ENABLE_SCREEN_OBJECTS
#define VMWSVGA_ENABLE_SCREEN_OBJECTS 0
#endif
#define VMWSVGA_MAX_WAIT_ITERS 1000000u
#define VMWSVGA_CURSOR_W DISPLAY_DEFAULT_CURSOR_W
#define VMWSVGA_CURSOR_H DISPLAY_DEFAULT_CURSOR_H
#define VMWSVGA_CAPS_MINIMAL (DISPLAY_CAP_FRAMEBUFFER | DISPLAY_CAP_SOFTWARE_CURSOR | DISPLAY_CAP_PRESENT_SYNC)
#define VMWSVGA_CAPS_HW_CURSOR (DISPLAY_CAP_FRAMEBUFFER | DISPLAY_CAP_HARDWARE_CURSOR | DISPLAY_CAP_PRESENT_SYNC)
typedef struct VMWSVGA_DEVICE {
uint32_t Magic;
DEVICE_OBJECT* Fdo;
DEVICE_OBJECT* Pdo;
DEVICE_OBJECT* LowerDevice;
PCI_DEVICE_INFO PciInfo;
PCI_BAR IoBar;
PCI_BAR FramebufferBar;
PCI_BAR FifoBar;
uint16_t IoBase;
volatile uint8_t* FramebufferMapping;
volatile uint8_t* Framebuffer;
volatile uint32_t* Fifo;
uint64_t FramebufferBytes;
uint32_t FramebufferOffset;
uint64_t FifoBytes;
uint32_t FifoDeviceBytes;
uint32_t DeviceId;
uint32_t Capabilities;
uint32_t Width;
uint32_t Height;
uint32_t Stride;
uint32_t BytesPerLine;
uint32_t BitsPerPixel;
uint32_t* Backbuffer;
size_t BackbufferBytes;
uint32_t FifoRegCount;
uint32_t FifoCaps;
bool UseScreenObject;
uint32_t ScreenId;
uint32_t ScreenSourceOffset;
uint32_t ScreenSourceBytes;
uint32_t ScreenBackingOffset;
uint32_t ScreenBackingBytes;
bool FifoReady;
bool HardwareCursor;
bool AlphaCursor;
bool CursorBypass3;
bool CursorImageDefined;
bool CursorVisible;
uint32_t* CursorImageArgb;
size_t CursorImageBytes;
int CursorImageWidth;
int CursorImageHeight;
int CursorHotX;
int CursorHotY;
bool Started;
bool Removed;
bool SurpriseRemoved;
int CursorX;
int CursorY;
int CursorDrawX;
int CursorDrawY;
bool CursorDrawn;
DISPLAY_STATS Stats;
DISPLAY_DEVICE DisplayDevice;
} VMWSVGA_DEVICE;
extern const HAL_API* gVmwSvgaHal;
KSTATUS VmwSvgaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
+1
View File
@@ -8,5 +8,6 @@ fat32.sys
[runtime]
lwip.sys
vmwaresvga.sys
rtl8139.sys
rtl816x.sys
+13
View File
@@ -115,6 +115,18 @@ static void ScreenBlit(int x, int y, int w, int h, const uint32_t* pixels) {
static void ScreenGetSize(int* w, int* h) { *w = gWidth; *h = gHeight; }
static KSTATUS ScreenGetFramebuffer(HAL_FRAMEBUFFER_INFO* outInfo) {
if (!outInfo || !gFb || gWidth <= 0 || gHeight <= 0 || gStride <= 0)
return STATUS_INVALID_PARAMETER;
outInfo->Base = (uintptr_t)gFb;
outInfo->Width = (uint32_t)gWidth;
outInfo->Height = (uint32_t)gHeight;
outInfo->Stride = (uint32_t)gStride;
outInfo->Format = 1; // X8R8G8B8
return STATUS_SUCCESS;
}
static void ScreenScroll(int lines) {
if (lines <= 0)
return;
@@ -327,6 +339,7 @@ void HalScreenInitialize(void* (*AllocatePool)(size_t size), uintptr_t fb, int w
out->PutPixel = ScreenPutPixel;
out->Blit = ScreenBlit;
out->GetSize = ScreenGetSize;
out->GetFramebuffer = ScreenGetFramebuffer;
out->Scroll = ScreenScroll;
out->PutChar = ScreenPutChar;
out->PrintChar = ScreenPrintChar;
@@ -0,0 +1,35 @@
#pragma once
// display_cursor.h - shared default software cursor image
#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 },
};
+1
View File
@@ -11,6 +11,7 @@
#define KE_DEBUG_FILE_LOG 0x00000004u
void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), uint32_t flags);
void KeSetDebugConsoleWriter(void (*PrintPtr)(char, uint32_t, uint32_t));
uint32_t KeGetDebugFlags(void);
__declspec(dllexport) void DbgPrint(const char* fmt, ...);
__declspec(dllexport) void KePrintConsole(const char* buf, size_t len);
+61
View File
@@ -0,0 +1,61 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <ntlite/status.h>
#include <ntlite/ddi/hal_api.h>
#ifndef DISPLAY_API
#ifdef KE_DISPLAY_BUILD
#define DISPLAY_API __declspec(dllexport)
#else
#define DISPLAY_API __declspec(dllimport)
#endif
#endif
#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;
void KeDisplayInitialize(const HAL_API* hal);
DISPLAY_API KSTATUS KeDisplayRegisterDevice(DISPLAY_DEVICE* device);
DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device);
DISPLAY_API void KeDisplaySuspendConsole(bool suspend);
DISPLAY_API KSTATUS KeDisplayGetMode(DISPLAY_MODE* outMode);
DISPLAY_API KSTATUS KeDisplayGetSize(int* outWidth, int* outHeight);
DISPLAY_API KSTATUS KeDisplayBlit(int x, int y, int w, int h, const uint32_t* pixels);
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);
void KeDisplayDebugPrintChar(char c, uint32_t fg, uint32_t bg);
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);
+2
View File
@@ -10,6 +10,8 @@ void KeInputInitialize(const HAL_API* hal);
__declspec(dllexport) KSTATUS KeInputRegisterDevice(const char* name, uint32_t flags, uint32_t* outDeviceId);
__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);
INPUT_KEY KeInputKbPoll(void);
bool KeInputIsKeyDown(INPUT_KEY key);
+1
View File
@@ -36,6 +36,7 @@ typedef enum USER_REGION_TYPE {
#define PAGE_PRESENT (1ULL << 0)
#define PAGE_WRITE (1ULL << 1)
#define PAGE_USER (1ULL << 2)
#define PAGE_WRITETHROUGH (1ULL << 3)
#define PAGE_NOCACHE (1ULL << 4)
#define PAGE_NX (1ULL << 63)
+39 -35
View File
@@ -66,38 +66,42 @@
#define SYS_REMOVE_DIR 57
#define SYS_SET_CWD 58
#define SYS_GET_CWD 59
#define SYS_WRITE_CONSOLE 60
#define SYS_BLIT_SCREEN 61
#define SYS_CLEAR_SCREEN 62
#define SYS_GET_SCREEN_SIZE 63
#define SYS_PUT_SCREEN_CHAR 64
#define SYS_POLL_KEYBOARD 65
#define SYS_IS_KEY_DOWN 66
#define SYS_READ_KEYBOARD_CHAR 67
#define SYS_READ_KEY 68
#define SYS_GET_KEY_MODIFIERS 69
#define SYS_POLL_MOUSE 70
#define SYS_READ_MOUSE 71
#define SYS_GET_MOUSE_POS 72
#define SYS_GET_TICK 73
#define SYS_PRINT_DEBUG 74
#define SYS_QUERY_TRAP_FRAME 75
#define SYS_CREATE_SOCKET 76
#define SYS_BIND_SOCKET 77
#define SYS_LISTEN_SOCKET 78
#define SYS_ACCEPT_SOCKET 79
#define SYS_CONNECT_SOCKET 80
#define SYS_SEND_SOCKET 81
#define SYS_RECV_SOCKET 82
#define SYS_SHUTDOWN_SOCKET 83
#define SYS_SEND_TO_SOCKET 84
#define SYS_RECV_FROM_SOCKET 85
#define SYS_RESOLVE_HOST 86
#define SYS_SET_SOCKET_OPTION 87
#define SYS_GET_SOCKET_OPTION 88
#define SYS_POLL 89
#define SYS_GET_MEMORY_STATUS 90
#define SYS_QUERY_KERNEL_STATS 91
#define SYS_GET_SYSTEM_TIME 92
#define SYS_MAX 93
#define SYS_WRITE_CONSOLE 60
#define SYS_GET_CONSOLE_INFO 61
#define SYS_SET_CONSOLE_CURSOR 62
#define SYS_FILL_CONSOLE_CHARACTER 63
#define SYS_FILL_CONSOLE_ATTRIBUTE 64
#define SYS_PUT_SCREEN_CHAR 65
#define SYS_BLIT_SCREEN 66
#define SYS_CLEAR_SCREEN 67
#define SYS_GET_SCREEN_SIZE 68
#define SYS_QUERY_DISPLAY_INFO 69
#define SYS_POLL_KEYBOARD 70
#define SYS_IS_KEY_DOWN 71
#define SYS_READ_KEYBOARD_CHAR 72
#define SYS_READ_KEY 73
#define SYS_GET_KEY_MODIFIERS 74
#define SYS_POLL_MOUSE 75
#define SYS_READ_MOUSE 76
#define SYS_GET_MOUSE_POS 77
#define SYS_GET_TICK 78
#define SYS_PRINT_DEBUG 79
#define SYS_QUERY_TRAP_FRAME 80
#define SYS_CREATE_SOCKET 81
#define SYS_BIND_SOCKET 82
#define SYS_LISTEN_SOCKET 83
#define SYS_ACCEPT_SOCKET 84
#define SYS_CONNECT_SOCKET 85
#define SYS_SEND_SOCKET 86
#define SYS_RECV_SOCKET 87
#define SYS_SHUTDOWN_SOCKET 88
#define SYS_SEND_TO_SOCKET 89
#define SYS_RECV_FROM_SOCKET 90
#define SYS_RESOLVE_HOST 91
#define SYS_SET_SOCKET_OPTION 92
#define SYS_GET_SOCKET_OPTION 93
#define SYS_POLL 94
#define SYS_GET_MEMORY_STATUS 95
#define SYS_QUERY_KERNEL_STATS 96
#define SYS_GET_SYSTEM_TIME 97
#define SYS_MAX 98
-100
View File
@@ -7,8 +7,6 @@
#include <kernel/ke_debug.h>
#include <kernel/ob_object.h>
#define MAX_PUBLISHED_DEVICES 64
#define MAX_DRIVER_MATCHERS 32
#define MAX_DRIVER_OBJECTS 64
#define MAX_PDO_OBJECTS 128
@@ -415,104 +413,6 @@ __declspec(dllexport) KSTATUS IoSendPnpIrpSync(DEVICE_OBJECT* device,
return st;
}
// -------------------------------------------------------------------------
// Legacy publish/matcher path
// -------------------------------------------------------------------------
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 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;
}
// -------------------------------------------------------------------------
// Disk namespace
// -------------------------------------------------------------------------
+52 -12
View File
@@ -61,6 +61,7 @@ static void KiDebugConsoleWrite(const char* text, size_t len) {
}
static volatile long gPanicInProgress = 0;
static volatile uintptr_t gPanicOwnerToken = 0;
static volatile long gPanicStoppedCpuCount = 0;
static _Noreturn void KiPanicSecondaryHalt(void) {
@@ -69,10 +70,36 @@ static _Noreturn void KiPanicSecondaryHalt(void) {
for (;;) __halt();
}
static uintptr_t KiPanicCurrentToken(void) {
THREAD* thread = KeGetCurrentThread();
if (thread)
return (uintptr_t)thread;
KCPU* cpu = KeGetCurrentCpu();
if (cpu)
return (uintptr_t)cpu;
return 1u;
}
static int KiPanicIsActive(void) {
return _InterlockedCompareExchange((volatile long*)&gPanicInProgress, 0, 0) != 0;
}
static int KiPanicCurrentCpuOwnsReport(void) {
uintptr_t token = KiPanicCurrentToken();
return token != 0 && gPanicOwnerToken == token;
}
static void KiBeginFatalReport(void) {
_disable();
uintptr_t token = KiPanicCurrentToken();
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) == 0) {
gPanicOwnerToken = token;
return;
}
if (gPanicOwnerToken != token)
KiPanicSecondaryHalt();
}
// Returning NMI handler used for SMP control IPIs. Panic NMIs stop the
// target CPU permanently; TLB shootdown NMIs flush and return. A genuinely
// unexpected NMI is not handled here and will fall through to the normal fault
@@ -88,7 +115,8 @@ __declspec(dllexport) int KeHandleNmiIpi(void) {
}
void KiKernelPutChar(char c) {
PrintChar(c, 0xCCCCCC, 0x012456);
if (PrintChar)
PrintChar(c, 0xCCCCCC, 0x012456);
}
void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), uint32_t flags) {
@@ -112,6 +140,13 @@ uint32_t KeGetDebugFlags(void) {
return gDebugFlags;
}
void KeSetDebugConsoleWriter(void (*PrintPtr)(char, uint32_t, uint32_t)) {
if (!PrintPtr)
return;
PrintChar = PrintPtr;
printf_set_putchar(KiKernelPutChar);
}
__declspec(dllexport) void DbgPrint(const char* fmt, ...) {
if (!gDebugEnabled || !fmt) return;
@@ -128,6 +163,14 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) {
len = sizeof(line) - 1u;
}
if (KiPanicIsActive()) {
if (!KiPanicCurrentCpuOwnsReport())
KiPanicSecondaryHalt();
if (gDebugFlags & KE_DEBUG_CONSOLE)
KiDebugConsoleWrite(line, len);
return;
}
uintptr_t flags = KeAcquireSpinlock(&gDebugPrintLock);
if (!_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 0, 0))
KiDebugLogAppendLocked(line, len);
@@ -187,17 +230,11 @@ __declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) {
// KePanic
__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...) {
// Silence this CPU first.
_disable();
KiBeginFatalReport();
// Only one CPU owns the visible panic report. CPUs that fault while the
// system is already panicking immediately join the stopped set.
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) != 0) {
KiPanicSecondaryHalt();
}
// Stop every other CPU as early as possible. This uses an NMI IPI so it
// still reaches CPUs with IF cleared inside spinlock/high-IRQL regions.
// Stop every other CPU for the final panic banner. Kernel fault dispatch
// claims panic ownership before its detailed dump, so this does not steal
// ownership from the CPU that found the fatal error.
HalApicSendPanicIpi();
if (PrintChar) {
@@ -550,7 +587,8 @@ static void KiDumpFaultFrame(PROCESS* proc, const KFAULT_FRAME* f) {
}
static void KiPrintCrashChar(char c) {
PrintChar(c, 0xFFAA00, 0x000000); // amber - distinct from green debug / red panic
if (PrintChar)
PrintChar(c, 0xFFAA00, 0x000000); // amber - distinct from green debug / red panic
}
static void KiPrintCrashHeader(PROCESS* proc, int vector, uintptr_t rip,
@@ -617,6 +655,8 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr
}
if ((frame->Cs & 3) == 0) {
KiBeginFatalReport();
int vector = (int)frame->Vector;
const char* name = KiFaultVectorName(vector);
File diff suppressed because it is too large. Load diff
+56 -15
View File
@@ -6,6 +6,7 @@
#include <kernel/ke_input.h>
#include <kernel/ke_debug.h>
#include <kernel/ke_display.h>
#define KEY_QUEUE_SIZE 256u
#define KEY_QUEUE_MASK (KEY_QUEUE_SIZE - 1u)
@@ -200,12 +201,15 @@ void KeInputInitialize(const HAL_API* hal) {
gMouseButtons = 0;
int w = 1920, h = 1080;
if (hal && hal->Screen.GetSize) hal->Screen.GetSize(&w, &h);
DISPLAY_MODE mode;
if (KSUCCESS(KeDisplayGetMode(&mode))) {
w = (int)mode.Width;
h = (int)mode.Height;
}
KeInputMouseSetBounds(w, h);
KeInputMouseSetPosition(w / 2, h / 2);
if (hal && hal->Screen.DrawCursor)
hal->Screen.DrawCursor(gMouseX, gMouseY);
KeDisplayShowCursor(true);
DbgPrint("Input: kernel input core initialized (%dx%d)\n", w, h);
}
@@ -247,11 +251,7 @@ __declspec(dllexport) void KeInputSubmitKey(const INPUT_KEY_EVENT* event) {
}
}
__declspec(dllexport) void KeInputSubmitMouse(const INPUT_MOUSE_EVENT* event) {
if (!event) return;
int nx = gMouseX + event->dx;
int ny = gMouseY + event->dy;
static void KiInputCommitMousePosition(int nx, int ny, uint8_t buttons) {
int bw = gMouseBoundsW;
int bh = gMouseBoundsH;
@@ -262,15 +262,21 @@ __declspec(dllexport) void KeInputSubmitMouse(const INPUT_MOUSE_EVENT* event) {
if (nx >= bw) nx = bw - 1;
if (ny >= bh) ny = bh - 1;
if (gInputHal && gInputHal->Screen.EraseCursor)
gInputHal->Screen.EraseCursor();
gMouseX = nx;
gMouseY = ny;
gMouseButtons = event->buttons;
gMouseButtons = buttons;
KeDisplaySetCursorPosition(nx, ny);
}
if (gInputHal && gInputHal->Screen.DrawCursor)
gInputHal->Screen.DrawCursor(nx, ny);
__declspec(dllexport) void KeInputSubmitMouse(const INPUT_MOUSE_EVENT* event) {
if (!event) return;
int oldX = gMouseX;
int oldY = gMouseY;
int nx = oldX + event->dx;
int ny = oldY + event->dy;
KiInputCommitMousePosition(nx, ny, event->buttons);
int next = (gMouseTail + 1) & (int)MOUSE_QUEUE_MASK;
if (next != gMouseHead) {
@@ -279,6 +285,40 @@ __declspec(dllexport) void KeInputSubmitMouse(const INPUT_MOUSE_EVENT* event) {
}
}
__declspec(dllexport) void KeInputSubmitMouseAbsolute(const INPUT_MOUSE_ABSOLUTE_EVENT* event) {
if (!event) return;
int oldX = gMouseX;
int oldY = gMouseY;
KiInputCommitMousePosition(event->x, event->y, event->buttons);
INPUT_MOUSE_EVENT rel;
rel.dx = gMouseX - oldX;
rel.dy = gMouseY - oldY;
rel.wheel = event->wheel;
rel.buttons = event->buttons;
int next = (gMouseTail + 1) & (int)MOUSE_QUEUE_MASK;
if (next != gMouseHead) {
gMouseQueue[gMouseTail] = rel;
gMouseTail = next;
}
}
__declspec(dllexport) void KeInputSubmitMouseAbsoluteScaled(uint32_t rawX, uint32_t rawY, uint32_t maxX, uint32_t maxY, int wheel, uint8_t buttons) {
int bw = gMouseBoundsW;
int bh = gMouseBoundsH;
if (bw < 1) bw = 1;
if (bh < 1) bh = 1;
INPUT_MOUSE_ABSOLUTE_EVENT ev;
ev.x = maxX ? (int)(((uint64_t)rawX * (uint64_t)(bw - 1)) / (uint64_t)maxX) : 0;
ev.y = maxY ? (int)(((uint64_t)rawY * (uint64_t)(bh - 1)) / (uint64_t)maxY) : 0;
ev.wheel = wheel;
ev.buttons = buttons;
KeInputSubmitMouseAbsolute(&ev);
}
INPUT_KEY KeInputKbPoll(void) {
if (gKeyHead == gKeyTail) KiInputServiceRepeat();
return (gKeyHead == gKeyTail) ? INPUT_KEY_NONE : gKeyQueue[gKeyHead].key;
@@ -341,6 +381,7 @@ void KeInputMouseSetPosition(int x, int y) {
if (y >= bh) y = bh - 1;
gMouseX = x;
gMouseY = y;
KeDisplaySetCursorPosition(x, y);
}
void KeInputMouseSetBounds(int w, int h) {
+157 -62
View File
@@ -61,6 +61,7 @@
#include <kernel/net_socket.h>
#include <kernel/ke_trap.h>
#include <kernel/ke_input.h>
#include <kernel/ke_display.h>
#include <kernel/ke_time.h>
#include <ntlite/syscall.h>
@@ -1204,12 +1205,12 @@ static uint64_t SyscallGetFileSize(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_BLIT_SCREEN (36) a0=x a1=y a2=w a3=h a4=*pixels
// SYS_BLIT_SCREEN (66) a0=x a1=y a2=w a3=h a4=*pixels
// ---------------------------------------------------------------------------
static uint64_t SyscallScreenBlit(uint64_t a0, uint64_t a1, uint64_t a2,
static uint64_t SyscallBlitScreen(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a5;
if (!gHal || !a4) return STATUS_FAILURE;
if (!a4) return STATUS_FAILURE;
int w = (int)a2;
int h = (int)a3;
@@ -1227,32 +1228,30 @@ static uint64_t SyscallScreenBlit(uint64_t a0, uint64_t a1, uint64_t a2,
KSTATUS s = CopyFromUser(kpixels, (const void*)(uintptr_t)a4, bytes);
if (KSUCCESS(s))
gHal->Screen.Blit((int)a0, (int)a1, w, h, kpixels);
s = KeDisplayBlit((int)a0, (int)a1, w, h, kpixels);
MmFreePool(kpixels);
return s;
}
// ---------------------------------------------------------------------------
// SYS_CLEAR_SCREEN (37) a0=color
// SYS_CLEAR_SCREEN (67) a0=color
// ---------------------------------------------------------------------------
static uint64_t SyscallScreenClear(uint64_t a0, uint64_t a1, uint64_t a2,
static uint64_t SyscallClearScreen(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
if (!gHal) return STATUS_FAILURE;
gHal->Screen.Clear((uint32_t)a0);
return STATUS_SUCCESS;
return KeDisplayClear((uint32_t)a0);
}
// ---------------------------------------------------------------------------
// SYS_GET_SCREEN_SIZE (38) a0=*widthOut a1=*heightOut
// SYS_GET_SCREEN_SIZE (68) a0=*widthOut a1=*heightOut
// ---------------------------------------------------------------------------
static uint64_t SyscallScreenGetSize(uint64_t a0, uint64_t a1, uint64_t a2,
static uint64_t SyscallGetScreenSize(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a2; (void)a3; (void)a4; (void)a5;
if (!gHal) return STATUS_FAILURE;
int w = 0, h = 0;
gHal->Screen.GetSize(&w, &h);
KSTATUS gs = KeDisplayGetSize(&w, &h);
if (!KSUCCESS(gs)) return gs;
if (a0) {
KSTATUS s = KiCopyIntToUser(a0, w);
if (!KSUCCESS(s)) return s;
@@ -1265,19 +1264,89 @@ static uint64_t SyscallScreenGetSize(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_PUT_SCREEN_CHAR (39) a0=c a1=x a2=y a3=fg a4=bg
// SYS_PUT_SCREEN_CHAR (65) a0=c a1=x a2=y a3=fg a4=bg
// ---------------------------------------------------------------------------
static uint64_t SyscallScreenPutChar(uint64_t a0, uint64_t a1, uint64_t a2,
static uint64_t SyscallPutScreenChar(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a5;
if (!gHal) return STATUS_FAILURE;
gHal->Screen.PutChar((char)a0, (int)a1, (int)a2,
(uint32_t)a3, (uint32_t)a4);
return STATUS_SUCCESS;
return KeDisplayPutChar((char)a0, (int)a1, (int)a2,
(uint32_t)a3, (uint32_t)a4);
}
// ---------------------------------------------------------------------------
// SYS_POLL_KEYBOARD (64) -> next INPUT_KEY or INPUT_KEY_NONE
// SYS_GET_CONSOLE_INFO (61) a0=*SYS_CONSOLE_INFO
// ---------------------------------------------------------------------------
static uint64_t SyscallGetConsoleInfo(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
if (!a0) return STATUS_INVALID_PARAMETER;
KE_CONSOLE_INFO ki;
KSTATUS s = KeDisplayGetConsoleInfo(&ki);
if (!KSUCCESS(s)) return s;
SYS_CONSOLE_INFO out;
memset(&out, 0, sizeof(out));
out.Columns = ki.Columns;
out.Rows = ki.Rows;
out.CursorX = ki.CursorX;
out.CursorY = ki.CursorY;
out.Attribute = ki.Attribute;
return CopyToUser((void*)(uintptr_t)a0, &out, sizeof(out));
}
// ---------------------------------------------------------------------------
// SYS_SET_CONSOLE_CURSOR (62) a0=column a1=row
// ---------------------------------------------------------------------------
static uint64_t SyscallSetConsoleCursor(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a2; (void)a3; (void)a4; (void)a5;
int col = (int)(int32_t)a0;
int row = (int)(int32_t)a1;
if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER;
return KeDisplaySetConsoleCursor(col, row);
}
// ---------------------------------------------------------------------------
// SYS_FILL_CONSOLE_CHARACTER (63) a0=char a1=column a2=row a3=count a4=*writtenOut
// ---------------------------------------------------------------------------
static uint64_t SyscallFillConsoleCharacter(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a5;
int col = (int)(int32_t)a1;
int row = (int)(int32_t)a2;
if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER;
size_t written = 0;
KSTATUS s = KeDisplayFillConsoleChars((char)a0, col, row, (size_t)a3, &written);
if (a4) {
KSTATUS cs = KiCopySizeToUser(a4, written);
if (KSUCCESS(s) && !KSUCCESS(cs)) s = cs;
}
return s;
}
// ---------------------------------------------------------------------------
// SYS_FILL_CONSOLE_ATTRIBUTE (64) a0=attribute a1=column a2=row a3=count a4=*writtenOut
// ---------------------------------------------------------------------------
static uint64_t SyscallFillConsoleAttribute(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a5;
int col = (int)(int32_t)a1;
int row = (int)(int32_t)a2;
if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER;
size_t written = 0;
KSTATUS s = KeDisplayFillConsoleAttrs((uint16_t)a0, col, row, (size_t)a3, &written);
if (a4) {
KSTATUS cs = KiCopySizeToUser(a4, written);
if (KSUCCESS(s) && !KSUCCESS(cs)) s = cs;
}
return s;
}
// ---------------------------------------------------------------------------
// SYS_POLL_KEYBOARD (70) -> next INPUT_KEY or INPUT_KEY_NONE
// ---------------------------------------------------------------------------
static uint64_t SyscallKbPoll(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1286,7 +1355,7 @@ static uint64_t SyscallKbPoll(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_IS_KEY_DOWN (65) a0=INPUT_KEY -> 1 or 0
// SYS_IS_KEY_DOWN (71) a0=INPUT_KEY -> 1 or 0
// ---------------------------------------------------------------------------
static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1295,7 +1364,7 @@ static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_READ_KEYBOARD_CHAR (66) -> char (blocks, yields while waiting)
// SYS_READ_KEYBOARD_CHAR (72) -> char (blocks, yields while waiting)
// ---------------------------------------------------------------------------
static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1305,7 +1374,7 @@ static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_READ_KEY (67) -> INPUT_KEY (blocks, yields while waiting)
// SYS_READ_KEY (73) -> INPUT_KEY (blocks, yields while waiting)
// ---------------------------------------------------------------------------
static uint64_t SyscallKbReadKey(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1315,7 +1384,7 @@ static uint64_t SyscallKbReadKey(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_GET_KEY_MODIFIERS (68) -> uint32_t INPUT_MOD_* flags
// SYS_GET_KEY_MODIFIERS (74) -> uint32_t INPUT_MOD_* flags
// ---------------------------------------------------------------------------
static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1324,7 +1393,7 @@ static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_POLL_MOUSE (69) -> 1 or 0
// SYS_POLL_MOUSE (75) -> 1 or 0
// ---------------------------------------------------------------------------
static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1333,7 +1402,7 @@ static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_READ_MOUSE (70) a0=*dx a1=*dy a2=*buttons -> 1 or 0
// SYS_READ_MOUSE (76) a0=*dx a1=*dy a2=*buttons -> 1 or 0
// ---------------------------------------------------------------------------
static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1351,7 +1420,7 @@ static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_GET_MOUSE_POS (71) a0=*x a1=*y
// SYS_GET_MOUSE_POS (77) a0=*x a1=*y
// ---------------------------------------------------------------------------
static uint64_t SyscallMouseGetPos(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1366,7 +1435,7 @@ static uint64_t SyscallMouseGetPos(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_GET_TICK (48) -> uint64_t microseconds
// SYS_GET_TICK (78) -> uint64_t microseconds
// ---------------------------------------------------------------------------
static uint64_t SyscallGetTick(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1389,7 +1458,7 @@ static uint64_t SyscallGetSystemTime(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_PRINT_DEBUG (49) a0=*str
// SYS_PRINT_DEBUG (79) a0=*str
// ---------------------------------------------------------------------------
static uint64_t SyscallDebugPrint(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
@@ -1607,7 +1676,7 @@ static uint64_t SyscallGetProcessExitCode(uint64_t a0, uint64_t a1, uint64_t a2,
}
// ---------------------------------------------------------------------------
// SYS_WRITE_CONSOLE (53) a0=*buf a1=len
// SYS_WRITE_CONSOLE (60) a0=*buf a1=len
// Writes user console text in white; distinct from green SYS_PRINT_DEBUG.
// ---------------------------------------------------------------------------
static uint64_t SyscallWriteConsole(uint64_t a0, uint64_t a1, uint64_t a2,
@@ -2716,6 +2785,27 @@ static KSTATUS KiReturnKernelStats(uint64_t bufferArg, size_t bufferSize,
return CopyToUser((void*)(uintptr_t)bufferArg, src, size);
}
static uint64_t SyscallQueryDisplayInfo(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
if (!a0) return STATUS_INVALID_PARAMETER;
KE_DISPLAY_INFO ki;
KSTATUS s = KeDisplayQueryInfo(&ki);
if (!KSUCCESS(s)) return s;
SYS_DISPLAY_INFO out;
memset(&out, 0, sizeof(out));
memcpy(out.PrimaryName, ki.PrimaryName, sizeof(out.PrimaryName));
out.Mode = ki.Mode;
out.Caps = ki.Caps;
out.DeviceCount = ki.DeviceCount;
out.ManagerStats = ki.ManagerStats;
out.DeviceStats = ki.DeviceStats;
return CopyToUser((void*)(uintptr_t)a0, &out, sizeof(out));
}
static uint64_t SyscallQueryKernelStats(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5) {
(void)a4; (void)a5;
@@ -2856,38 +2946,43 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
/* 58 SYS_SET_CWD */ SyscallSetCwd,
/* 59 SYS_GET_CWD */ SyscallGetCwd,
/* 60 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
/* 61 SYS_BLIT_SCREEN */ SyscallScreenBlit,
/* 62 SYS_CLEAR_SCREEN */ SyscallScreenClear,
/* 63 SYS_GET_SCREEN_SIZE */ SyscallScreenGetSize,
/* 64 SYS_PUT_SCREEN_CHAR */ SyscallScreenPutChar,
/* 65 SYS_POLL_KEYBOARD */ SyscallKbPoll,
/* 66 SYS_IS_KEY_DOWN */ SyscallKbIsKeyDown,
/* 67 SYS_READ_KEYBOARD_CHAR */ SyscallKbReadChar,
/* 68 SYS_READ_KEY */ SyscallKbReadKey,
/* 69 SYS_GET_KEY_MODIFIERS */ SyscallKbGetModifiers,
/* 70 SYS_POLL_MOUSE */ SyscallMousePoll,
/* 71 SYS_READ_MOUSE */ SyscallMouseRead,
/* 72 SYS_GET_MOUSE_POS */ SyscallMouseGetPos,
/* 73 SYS_GET_TICK */ SyscallGetTick,
/* 74 SYS_PRINT_DEBUG */ SyscallDebugPrint,
/* 75 SYS_QUERY_TRAP_FRAME */ SyscallQueryTrapFrame,
/* 76 SYS_CREATE_SOCKET */ SyscallSocket,
/* 77 SYS_BIND_SOCKET */ SyscallBind,
/* 78 SYS_LISTEN_SOCKET */ SyscallListen,
/* 79 SYS_ACCEPT_SOCKET */ SyscallAccept,
/* 80 SYS_CONNECT_SOCKET */ SyscallConnect,
/* 81 SYS_SEND_SOCKET */ SyscallSend,
/* 82 SYS_RECV_SOCKET */ SyscallRecv,
/* 83 SYS_SHUTDOWN_SOCKET */ SyscallShutdown,
/* 84 SYS_SEND_TO_SOCKET */ SyscallSendTo,
/* 85 SYS_RECV_FROM_SOCKET */ SyscallRecvFrom,
/* 86 SYS_RESOLVE_HOST */ SyscallResolveHost,
/* 87 SYS_SET_SOCKET_OPTION */ SyscallSetSocketOption,
/* 88 SYS_GET_SOCKET_OPTION */ SyscallGetSocketOption,
/* 89 SYS_POLL */ SyscallPoll,
/* 90 SYS_GET_MEMORY_STATUS */ SyscallGetMemoryStatus,
/* 91 SYS_QUERY_KERNEL_STATS */ SyscallQueryKernelStats,
/* 92 SYS_GET_SYSTEM_TIME */ SyscallGetSystemTime
/* 61 SYS_GET_CONSOLE_INFO */ SyscallGetConsoleInfo,
/* 62 SYS_SET_CONSOLE_CURSOR */ SyscallSetConsoleCursor,
/* 63 SYS_FILL_CONSOLE_CHARACTER */ SyscallFillConsoleCharacter,
/* 64 SYS_FILL_CONSOLE_ATTRIBUTE */ SyscallFillConsoleAttribute,
/* 65 SYS_PUT_SCREEN_CHAR */ SyscallPutScreenChar,
/* 66 SYS_BLIT_SCREEN */ SyscallBlitScreen,
/* 67 SYS_CLEAR_SCREEN */ SyscallClearScreen,
/* 68 SYS_GET_SCREEN_SIZE */ SyscallGetScreenSize,
/* 69 SYS_QUERY_DISPLAY_INFO */ SyscallQueryDisplayInfo,
/* 70 SYS_POLL_KEYBOARD */ SyscallKbPoll,
/* 71 SYS_IS_KEY_DOWN */ SyscallKbIsKeyDown,
/* 72 SYS_READ_KEYBOARD_CHAR */ SyscallKbReadChar,
/* 73 SYS_READ_KEY */ SyscallKbReadKey,
/* 74 SYS_GET_KEY_MODIFIERS */ SyscallKbGetModifiers,
/* 75 SYS_POLL_MOUSE */ SyscallMousePoll,
/* 76 SYS_READ_MOUSE */ SyscallMouseRead,
/* 77 SYS_GET_MOUSE_POS */ SyscallMouseGetPos,
/* 78 SYS_GET_TICK */ SyscallGetTick,
/* 79 SYS_PRINT_DEBUG */ SyscallDebugPrint,
/* 80 SYS_QUERY_TRAP_FRAME */ SyscallQueryTrapFrame,
/* 81 SYS_CREATE_SOCKET */ SyscallSocket,
/* 82 SYS_BIND_SOCKET */ SyscallBind,
/* 83 SYS_LISTEN_SOCKET */ SyscallListen,
/* 84 SYS_ACCEPT_SOCKET */ SyscallAccept,
/* 85 SYS_CONNECT_SOCKET */ SyscallConnect,
/* 86 SYS_SEND_SOCKET */ SyscallSend,
/* 87 SYS_RECV_SOCKET */ SyscallRecv,
/* 88 SYS_SHUTDOWN_SOCKET */ SyscallShutdown,
/* 89 SYS_SEND_TO_SOCKET */ SyscallSendTo,
/* 90 SYS_RECV_FROM_SOCKET */ SyscallRecvFrom,
/* 91 SYS_RESOLVE_HOST */ SyscallResolveHost,
/* 92 SYS_SET_SOCKET_OPTION */ SyscallSetSocketOption,
/* 93 SYS_GET_SOCKET_OPTION */ SyscallGetSocketOption,
/* 94 SYS_POLL */ SyscallPoll,
/* 95 SYS_GET_MEMORY_STATUS */ SyscallGetMemoryStatus,
/* 96 SYS_QUERY_KERNEL_STATS */ SyscallQueryKernelStats,
/* 97 SYS_GET_SYSTEM_TIME */ SyscallGetSystemTime
};
// ---------------------------------------------------------------------------
+3
View File
@@ -26,6 +26,7 @@
#include <kernel/ke_smp.h>
#include <kernel/ke_input.h>
#include <kernel/ke_time.h>
#include <kernel/ke_display.h>
#include <common/ini_parser.h>
typedef struct {
@@ -429,6 +430,8 @@ extern void KernelMain(BOOT_INFO* bootInfo) {
KeInitDebug(hal->Screen.PrintChar, bootInfo->Debug);
KeTimeInitialize(bootInfo, hal);
KeDisplayInitialize(hal);
KeSetDebugConsoleWriter(KeDisplayDebugPrintChar);
// CPU startup intentionally lives after HAL initialization but before IRQs
// and scheduler startup. HAL owns ACPI/MADT discovery and LAPIC INIT/SIPI;
+8
View File
@@ -248,11 +248,19 @@ __declspec(dllexport) KSTATUS MmSetPageProtect(uintptr_t virt, size_t size, uint
status = STATUS_NOT_FOUND;
break;
}
if (*e3 & PAGE_PS) {
status = STATUS_NOT_SUPPORTED;
break;
}
uint64_t* e2 = KiPtePtr(*e3 & PAGE_FRAME_4K_MASK, PDT_IDX(va));
if (!(*e2 & PAGE_PRESENT)) {
status = STATUS_NOT_FOUND;
break;
}
if (*e2 & PAGE_PS) {
status = STATUS_NOT_SUPPORTED;
break;
}
uint64_t* pte = KiPtePtr(*e2 & PAGE_FRAME_4K_MASK, PT_IDX(va));
if (!(*pte & PAGE_PRESENT)) {
status = STATUS_NOT_FOUND;
+67
View File
@@ -0,0 +1,67 @@
#pragma once
// display.h - display device DDI
//
// Display providers register DISPLAY_DEVICE objects with the kernel display
// manager. The boot framebuffer backend is registered by the kernel itself;
// PCI/virtual GPU drivers register additional providers later.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <ntlite/status.h>
#ifndef DISPLAY_API
#define DISPLAY_API __declspec(dllimport)
#endif
#include <ntlite/display.h>
typedef struct DISPLAY_DEVICE DISPLAY_DEVICE;
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,
const uint32_t* pixels);
KSTATUS (*FillRect)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
uint32_t color);
KSTATUS (*CopyRect)(DISPLAY_DEVICE* device,
int dstX, int dstY,
int srcX, int srcY,
int w, int h);
KSTATUS (*ReadRect)(DISPLAY_DEVICE* device,
int x, int y, int w, int h,
uint32_t* outPixels, uint32_t outStride);
KSTATUS (*Present)(DISPLAY_DEVICE* device,
const DISPLAY_RECT* rects,
size_t rectCount);
KSTATUS (*Sync)(DISPLAY_DEVICE* device);
KSTATUS (*SetCursorImage)(DISPLAY_DEVICE* device,
int width, int height,
int hotX, int hotY,
const uint32_t* argbPixels);
KSTATUS (*SetCursorPosition)(DISPLAY_DEVICE* device, int x, int y);
KSTATUS (*ShowCursor)(DISPLAY_DEVICE* device, bool show);
KSTATUS (*QueryStats)(DISPLAY_DEVICE* device, DISPLAY_STATS* outStats);
} DISPLAY_DEVICE_OPS;
struct DISPLAY_DEVICE {
const char* Name;
uint32_t Caps;
void* DriverContext;
const DISPLAY_DEVICE_OPS* Ops;
DISPLAY_DEVICE* Next;
};
DISPLAY_API KSTATUS KeDisplayRegisterDevice(DISPLAY_DEVICE* device);
DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device);
+11 -1
View File
@@ -7,15 +7,25 @@
typedef struct BOOT_INFO BOOT_INFO;
typedef struct HAL_FRAMEBUFFER_INFO {
uintptr_t Base; // kernel virtual address of the visible framebuffer
uint32_t Width;
uint32_t Height;
uint32_t Stride; // pixels per scanline
uint32_t Format; // currently 0x00RRGGBB / X8R8G8B8
} HAL_FRAMEBUFFER_INFO;
typedef struct HAL_SCREEN {
void (*Clear)(uint32_t color);
void (*PutPixel)(int x, int y, uint32_t color);
void (*Blit)(int x, int y, int w, int h, const uint32_t* pixels);
void (*GetSize)(int* width, int* height);
KSTATUS (*GetFramebuffer)(HAL_FRAMEBUFFER_INFO* outInfo);
void (*Scroll)(int lines);
void (*PutChar)(char c, int x, int y, uint32_t fg, uint32_t bg);
void (*PrintChar)(char c, uint32_t fg, uint32_t bg);
// Hardware mouse cursor: save/restore background and blit sprite
// Legacy software cursor hooks kept for early-boot/panic fallback only.
// Normal input cursor ownership lives in ke_display.
void (*DrawCursor)(int x, int y);
void (*EraseCursor)(void);
} HAL_SCREEN;
+2
View File
@@ -7,3 +7,5 @@
__declspec(dllexport) KSTATUS KeInputRegisterDevice(const char* name, uint32_t flags, uint32_t* outDeviceId);
__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);
-66
View File
@@ -165,72 +165,6 @@ __declspec(dllexport) uint8_t IoGetDeviceStackSize(DEVICE_OBJECT* device);
__declspec(dllexport) KSTATUS IoSendPnpIrpSync(DEVICE_OBJECT* device,
IO_PNP_MINOR_FUNCTION minor);
// -------------------------------------------------------------------------
// Legacy USB publish/matcher path. This remains only until USB is migrated to
// PDO/interface-PDO enumeration in the later USB stages.
// -------------------------------------------------------------------------
#define IO_PUBLISHED_USB_MAX_ENDPOINTS 8u
typedef struct IO_PUBLISHED_USB_ENDPOINT {
uint8_t Address;
uint8_t Attributes;
uint16_t MaxPacketSize;
uint8_t Interval;
} IO_PUBLISHED_USB_ENDPOINT;
typedef struct IO_PUBLISHED_USB_DEVICE {
uint16_t VendorId;
uint16_t ProductId;
uint16_t BcdUsb;
uint16_t BcdDevice;
uint8_t DeviceClass;
uint8_t DeviceSubclass;
uint8_t DeviceProtocol;
uint8_t SlotId;
uint8_t Port;
uint8_t Speed;
uint8_t ConfigurationValue;
uint8_t InterfaceNumber;
uint8_t AlternateSetting;
uint8_t InterfaceClass;
uint8_t InterfaceSubclass;
uint8_t InterfaceProtocol;
uint8_t EndpointCount;
IO_PUBLISHED_USB_ENDPOINT Endpoints[IO_PUBLISHED_USB_MAX_ENDPOINTS];
} IO_PUBLISHED_USB_DEVICE;
typedef struct IO_PUBLISHED_DEVICE {
IO_BUS_TYPE BusType;
const char* Name;
void* BusContext;
void* DeviceContext;
uint32_t Flags;
bool Bound;
const char* BoundDriverName;
union {
IO_PUBLISHED_USB_DEVICE Usb;
} u;
} IO_PUBLISHED_DEVICE;
typedef bool (*IO_DRIVER_MATCH_CALLBACK)(const IO_PUBLISHED_DEVICE* device,
void* context);
typedef KSTATUS (*IO_DRIVER_BIND_CALLBACK)(IO_PUBLISHED_DEVICE* device,
void* context);
__declspec(dllexport) KSTATUS IoRegisterDriverMatcher(const char* driverName,
IO_BUS_TYPE busType,
IO_DRIVER_MATCH_CALLBACK match,
IO_DRIVER_BIND_CALLBACK bind,
void* context);
__declspec(dllexport) KSTATUS IoPublishDevice(const IO_PUBLISHED_DEVICE* device);
__declspec(dllexport) uint32_t IoPublishedDeviceCount(void);
// -------------------------------------------------------------------------
// Disk namespace above storage DEVICE_OBJECTs
// -------------------------------------------------------------------------
+71
View File
@@ -0,0 +1,71 @@
#pragma once
// display.h - user/kernel shared display ABI types
//
// This header is safe for user-mode code. It contains only plain syscall ABI
// data types and capability bits. Kernel/driver provider interfaces live in
// <ntlite/ddi/display.h>.
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum DISPLAY_PIXEL_FORMAT {
DisplayPixelFormatUnknown = 0,
DisplayPixelFormatX8R8G8B8 = 1,
} DISPLAY_PIXEL_FORMAT;
typedef struct DISPLAY_MODE {
uint32_t Width;
uint32_t Height;
uint32_t Stride; // pixels per scanline
DISPLAY_PIXEL_FORMAT Format;
} DISPLAY_MODE;
typedef struct DISPLAY_RECT {
int32_t X;
int32_t Y;
int32_t W;
int32_t H;
} DISPLAY_RECT;
typedef struct DISPLAY_STATS {
uint64_t BlitCount;
uint64_t FillRectCount;
uint64_t CopyRectCount;
uint64_t ReadRectCount;
uint64_t PresentCount;
uint64_t PresentRectCount;
uint64_t DirtyRectCount;
uint64_t DirtyAllCount;
uint64_t BytesCopied;
uint64_t SyncCount;
uint64_t CursorMoveCount;
uint64_t CursorShowCount;
uint64_t CursorHideCount;
} DISPLAY_STATS;
#define DISPLAY_CAP_FRAMEBUFFER 0x00000001u
#define DISPLAY_CAP_SOFTWARE_CURSOR 0x00000002u
#define DISPLAY_CAP_HARDWARE_CURSOR 0x00000004u
#define DISPLAY_CAP_ACCEL_FILL 0x00000008u
#define DISPLAY_CAP_ACCEL_COPY 0x00000010u
#define DISPLAY_CAP_PRESENT_SYNC 0x00000020u
#define DISPLAY_CAP_VBLANK 0x00000040u
#define DISPLAY_CAP_3D 0x00000080u
#define SYS_DISPLAY_NAME_MAX 32u
typedef struct SYS_DISPLAY_INFO {
char PrimaryName[SYS_DISPLAY_NAME_MAX];
DISPLAY_MODE Mode;
uint32_t Caps;
uint32_t DeviceCount;
DISPLAY_STATS ManagerStats;
DISPLAY_STATS DeviceStats;
} SYS_DISPLAY_INFO;
#ifdef __cplusplus
}
#endif
+7
View File
@@ -140,3 +140,10 @@ typedef struct INPUT_MOUSE_EVENT {
int 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;
uint8_t buttons; // bit0=left, bit1=right, bit2=middle
} INPUT_MOUSE_ABSOLUTE_EVENT;
+18 -4
View File
@@ -9,6 +9,7 @@
#include <ntlite/dirent.h>
#include <ntlite/input.h>
#include <ntlite/time.h>
#include <ntlite/display.h>
#define SYS_STATUS_SUCCESS 0u
#define SYS_STATUS_TIMEOUT 3u
@@ -329,16 +330,29 @@ uint32_t SysSetCwd(const SYS_PATH_REQUEST* request);
uint32_t SysGetCwd(const SYS_GET_CWD_REQUEST* request);
// ---------------------------------------------------------------------------
// Console and graphics (57-61)
// Console and graphics.
// ---------------------------------------------------------------------------
typedef struct SYS_CONSOLE_INFO {
uint32_t Columns;
uint32_t Rows;
uint32_t CursorX;
uint32_t CursorY;
uint16_t Attribute;
} SYS_CONSOLE_INFO;
uint32_t SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request);
uint32_t SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut);
uint32_t SysSetConsoleCursor(int x, int y);
uint32_t SysFillConsoleCharacter(char c, int x, int y, size_t length, size_t* writtenOut);
uint32_t SysFillConsoleAttribute(uint16_t attr, int x, int y, size_t length, size_t* writtenOut);
uint32_t SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg);
uint32_t SysBlitScreen(int x, int y, int w, int h, const uint32_t* pixels);
uint32_t SysClearScreen(uint32_t color);
uint32_t SysGetScreenSize(int* widthOut, int* heightOut);
uint32_t SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg);
uint32_t SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut);
// ---------------------------------------------------------------------------
// Input (62-69)
// Input.
// ---------------------------------------------------------------------------
uint64_t SysPollKeyboard(void);
uint64_t SysIsKeyDown(INPUT_KEY key);
@@ -501,9 +515,9 @@ typedef struct SYS_CPU_STATS {
// Time and diagnostics
// ---------------------------------------------------------------------------
uint64_t SysGetTick(void);
uint32_t SysGetSystemTime(SYS_SYSTEM_TIME* timeOut);
uint32_t SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request);
uint32_t SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info);
uint32_t SysGetMemoryStatus(SYS_MEMORY_STATUS* statusOut);
uint32_t SysQueryKernelStats(uint32_t classId, void* buffer, size_t bufferSize, size_t* requiredSizeOut);
uint32_t SysGetSystemTime(SYS_SYSTEM_TIME* timeOut);
@@ -89,6 +89,17 @@ static void printUInt64Width(uint64_t n, size_t width) {
printUInt64(n);
}
static void printHex32(uint32_t v) {
static const char hex[] = "0123456789abcdef";
char buf[9];
for (int i = 7; i >= 0; i--) {
buf[i] = hex[v & 0xFu];
v >>= 4;
}
buf[8] = '\0';
print(buf);
}
static void printDirTime(const SYS_SYSTEM_TIME* t) {
if (!t || !(t->Flags & SYS_TIME_FLAG_VALID)) {
print("---- -- -- --:-- ");
@@ -144,6 +155,7 @@ static void cmd_help() {
" help - Show this list\n"
" mem - Show memory usage\n"
" time - Show system wall-clock time\n"
" display - Show display provider and counters\n"
" stats - Show scheduler/CPU/PMM telemetry\n"
" ps - List processes\n"
" dir [path] - List directory contents\n"
@@ -278,6 +290,54 @@ static void cmd_time(void) {
print("\n");
}
static void printDisplayCaps(uint32_t caps) {
bool any = false;
if (caps & DISPLAY_CAP_FRAMEBUFFER) { print("framebuffer"); any = true; }
if (caps & DISPLAY_CAP_SOFTWARE_CURSOR) { if (any) print(","); print("software-cursor"); any = true; }
if (caps & DISPLAY_CAP_HARDWARE_CURSOR) { if (any) print(","); print("hardware-cursor"); any = true; }
if (caps & DISPLAY_CAP_ACCEL_FILL) { if (any) print(","); print("accel-fill"); any = true; }
if (caps & DISPLAY_CAP_ACCEL_COPY) { if (any) print(","); print("accel-copy"); any = true; }
if (caps & DISPLAY_CAP_PRESENT_SYNC) { if (any) print(","); print("present-sync"); any = true; }
if (caps & DISPLAY_CAP_VBLANK) { if (any) print(","); print("vblank"); any = true; }
if (caps & DISPLAY_CAP_3D) { if (any) print(","); print("3d"); any = true; }
if (!any) print("none");
}
static void printDisplayStats(const char* title, const DISPLAY_STATS* st) {
print(title); print(":\n");
print(" blit: "); printUInt64(st->BlitCount); print("\n");
print(" fill: "); printUInt64(st->FillRectCount); print("\n");
print(" copy: "); printUInt64(st->CopyRectCount); print("\n");
print(" read: "); printUInt64(st->ReadRectCount); print("\n");
print(" present: "); printUInt64(st->PresentCount); print(" rects="); printUInt64(st->PresentRectCount); print("\n");
print(" dirty: "); printUInt64(st->DirtyRectCount); print(" all="); printUInt64(st->DirtyAllCount); print("\n");
print(" bytes: "); printUInt64(st->BytesCopied); print("\n");
print(" sync: "); printUInt64(st->SyncCount); print("\n");
print(" cursor: move="); printUInt64(st->CursorMoveCount);
print(" show="); printUInt64(st->CursorShowCount);
print(" hide="); printUInt64(st->CursorHideCount); print("\n");
}
static void cmd_display(void) {
SYS_DISPLAY_INFO info;
uint32_t status = SysQueryDisplayInfo(&info);
if (status != 0) {
print("display: query failed: ");
printUInt(status);
print("\n");
return;
}
print("Display:\n");
print(" primary: "); print(info.PrimaryName[0] ? info.PrimaryName : "?"); print("\n");
print(" devices: "); printUInt(info.DeviceCount); print("\n");
print(" mode: "); printUInt(info.Mode.Width); print("x"); printUInt(info.Mode.Height);
print(" stride="); printUInt(info.Mode.Stride); print(" format="); printUInt((uint32_t)info.Mode.Format); print("\n");
print(" caps: 0x"); printHex32(info.Caps); print(" ["); printDisplayCaps(info.Caps); print("]\n");
printDisplayStats("Manager counters", &info.ManagerStats);
printDisplayStats("Provider counters", &info.DeviceStats);
}
static void cmd_mem(void) {
SYS_MEMORY_STATUS st;
if (SysGetMemoryStatus(&st) != 0) {
@@ -492,6 +552,7 @@ static int runCommand(const char* cmd) {
}
if (strcmp(cmd, "mem") == 0) { cmd_mem(); return 0; }
if (strcmp(cmd, "time") == 0 || strcmp(cmd, "date") == 0) { cmd_time(); return 0; }
if (strcmp(cmd, "display") == 0 || strcmp(cmd, "gpu") == 0) { cmd_display(); return 0; }
if (strcmp(cmd, "stats") == 0 || strcmp(cmd, "telemetry") == 0) { cmd_stats(); return 0; }
if (strcmp(cmd, "ps") == 0) { cmd_ps(); return 0; }
if (strcmp(cmd, "dir") == 0) { cmd_dir("."); return 0; }
+168
View File
@@ -32,11 +32,22 @@
// ---------------------------------------------------------------------------
typedef void* HANDLE;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef short SHORT;
typedef long LONG;
typedef struct { LONG x; LONG y; } POINT;
typedef struct { SHORT X; SHORT Y; } COORD;
typedef struct { SHORT Left; SHORT Top; SHORT Right; SHORT Bottom; } SMALL_RECT;
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize;
COORD dwCursorPosition;
WORD wAttributes;
SMALL_RECT srWindow;
COORD dwMaximumWindowSize;
} CONSOLE_SCREEN_BUFFER_INFO;
#define MAX_PATH 260
#define TRUE 1
@@ -959,6 +970,20 @@ __declspec(dllexport) HANDLE LoadLibraryA(const char* lpLibFileName) {
// in this win32.dll image. Full dynamic DLL loading remains a kernel-loader job.
__declspec(dllexport) BOOL FreeLibrary(HANDLE hLibModule);
__declspec(dllexport) void Sleep(DWORD dwMilliseconds);
__declspec(dllexport) BOOL GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
CONSOLE_SCREEN_BUFFER_INFO* lpConsoleScreenBufferInfo);
__declspec(dllexport) BOOL FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
char cCharacter,
DWORD nLength,
COORD dwWriteCoord,
DWORD* lpNumberOfCharsWritten);
__declspec(dllexport) BOOL FillConsoleOutputAttribute(HANDLE hConsoleOutput,
WORD wAttribute,
DWORD nLength,
COORD dwWriteCoord,
DWORD* lpNumberOfAttrsWritten);
__declspec(dllexport) BOOL SetConsoleCursorPosition(HANDLE hConsoleOutput,
COORD dwCursorPosition);
__declspec(dllexport) void* GetProcAddress(HANDLE hModule, const char* lpProcName) {
if (hModule != WIN32_HMODULE_WIN32 || !lpProcName) { gLastError = 127; return NULL; }
@@ -975,6 +1000,8 @@ __declspec(dllexport) void* GetProcAddress(HANDLE hModule, const char* lpProcNam
GP(FreeLibrary); GP(VirtualAlloc); GP(VirtualFree); GP(VirtualProtect);
GP(VirtualQuery); GP(GetTickCount); GP(GetTickCount64); GP(Sleep);
GP(TlsAlloc); GP(TlsFree); GP(TlsGetValue); GP(TlsSetValue);
GP(GetConsoleScreenBufferInfo); GP(FillConsoleOutputCharacterA);
GP(FillConsoleOutputAttribute); GP(SetConsoleCursorPosition);
#undef GP
KiDbgWriteA("GetProcAddress miss: ");
KiDbgWriteA(lpProcName);
@@ -1250,6 +1277,34 @@ __declspec(dllexport) void Sleep(DWORD dwMilliseconds) {
#define STD_OUTPUT_HANDLE ((DWORD)-11)
#define STD_ERROR_HANDLE ((DWORD)-12)
static BOOL K32IsStdHandleValue(HANDLE h, DWORD stdHandle) {
uintptr_t value = (uintptr_t)h;
return value == (uintptr_t)stdHandle || value == (uintptr_t)(intptr_t)(int32_t)stdHandle;
}
static BOOL K32IsConsoleOutputHandle(HANDLE h) {
return h && h != INVALID_HANDLE_VALUE &&
(K32IsStdHandleValue(h, STD_OUTPUT_HANDLE) ||
K32IsStdHandleValue(h, STD_ERROR_HANDLE));
}
static void K32SetConsoleLastError(uint32_t status) {
switch (status) {
case SYS_STATUS_SUCCESS:
gLastError = 0;
break;
case SYS_STATUS_INVALID_PARAMETER:
gLastError = 87;
break;
case SYS_STATUS_NO_MEMORY:
gLastError = 8;
break;
default:
gLastError = 1;
break;
}
}
// We have no real console handles; return a sentinel the other APIs recognise.
__declspec(dllexport) HANDLE GetStdHandle(DWORD nStdHandle) {
return (HANDLE)(uintptr_t)nStdHandle;
@@ -1309,6 +1364,115 @@ __declspec(dllexport) BOOL WriteConsoleA(HANDLE hConsoleOutput,
return TRUE;
}
__declspec(dllexport) BOOL GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
CONSOLE_SCREEN_BUFFER_INFO* lpConsoleScreenBufferInfo) {
if (!K32IsConsoleOutputHandle(hConsoleOutput)) {
gLastError = 6;
return FALSE;
}
if (!lpConsoleScreenBufferInfo) {
gLastError = 87;
return FALSE;
}
SYS_CONSOLE_INFO info;
uint32_t s = SysGetConsoleInfo(&info);
if (s != SYS_STATUS_SUCCESS) {
K32SetConsoleLastError(s);
return FALSE;
}
memset(lpConsoleScreenBufferInfo, 0, sizeof(*lpConsoleScreenBufferInfo));
lpConsoleScreenBufferInfo->dwSize.X = (SHORT)info.Columns;
lpConsoleScreenBufferInfo->dwSize.Y = (SHORT)info.Rows;
lpConsoleScreenBufferInfo->dwCursorPosition.X = (SHORT)info.CursorX;
lpConsoleScreenBufferInfo->dwCursorPosition.Y = (SHORT)info.CursorY;
lpConsoleScreenBufferInfo->wAttributes = (WORD)info.Attribute;
lpConsoleScreenBufferInfo->srWindow.Left = 0;
lpConsoleScreenBufferInfo->srWindow.Top = 0;
lpConsoleScreenBufferInfo->srWindow.Right = info.Columns ? (SHORT)(info.Columns - 1u) : 0;
lpConsoleScreenBufferInfo->srWindow.Bottom = info.Rows ? (SHORT)(info.Rows - 1u) : 0;
lpConsoleScreenBufferInfo->dwMaximumWindowSize = lpConsoleScreenBufferInfo->dwSize;
return TRUE;
}
__declspec(dllexport) BOOL SetConsoleCursorPosition(HANDLE hConsoleOutput,
COORD dwCursorPosition) {
if (!K32IsConsoleOutputHandle(hConsoleOutput)) {
gLastError = 6;
return FALSE;
}
if (dwCursorPosition.X < 0 || dwCursorPosition.Y < 0) {
gLastError = 87;
return FALSE;
}
uint32_t s = SysSetConsoleCursor((int)dwCursorPosition.X, (int)dwCursorPosition.Y);
if (s != SYS_STATUS_SUCCESS) {
K32SetConsoleLastError(s);
return FALSE;
}
return TRUE;
}
__declspec(dllexport) BOOL FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
char cCharacter,
DWORD nLength,
COORD dwWriteCoord,
DWORD* lpNumberOfCharsWritten) {
if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = 0;
if (!K32IsConsoleOutputHandle(hConsoleOutput)) {
gLastError = 6;
return FALSE;
}
if (dwWriteCoord.X < 0 || dwWriteCoord.Y < 0) {
gLastError = 87;
return FALSE;
}
if (nLength == 0)
return TRUE;
size_t written = 0;
uint32_t s = SysFillConsoleCharacter(cCharacter, (int)dwWriteCoord.X,
(int)dwWriteCoord.Y, (size_t)nLength,
&written);
if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = (DWORD)written;
if (s != SYS_STATUS_SUCCESS) {
K32SetConsoleLastError(s);
return FALSE;
}
return TRUE;
}
__declspec(dllexport) BOOL FillConsoleOutputAttribute(HANDLE hConsoleOutput,
WORD wAttribute,
DWORD nLength,
COORD dwWriteCoord,
DWORD* lpNumberOfAttrsWritten) {
if (lpNumberOfAttrsWritten) *lpNumberOfAttrsWritten = 0;
if (!K32IsConsoleOutputHandle(hConsoleOutput)) {
gLastError = 6;
return FALSE;
}
if (dwWriteCoord.X < 0 || dwWriteCoord.Y < 0) {
gLastError = 87;
return FALSE;
}
if (nLength == 0)
return TRUE;
size_t written = 0;
uint32_t s = SysFillConsoleAttribute(wAttribute, (int)dwWriteCoord.X,
(int)dwWriteCoord.Y, (size_t)nLength,
&written);
if (lpNumberOfAttrsWritten) *lpNumberOfAttrsWritten = (DWORD)written;
if (s != SYS_STATUS_SUCCESS) {
K32SetConsoleLastError(s);
return FALSE;
}
return TRUE;
}
// ---------------------------------------------------------------------------
// Directory enumeration (FindFirstFileA / FindNextFileA / FindClose)
// ---------------------------------------------------------------------------
@@ -1973,6 +2137,10 @@ __declspec(dllexport) unsigned int SetHandleCount(unsigned int uNumber) {
__declspec(dllexport) DWORD GetFileType(HANDLE hFile) {
if (!hFile || hFile == INVALID_HANDLE_VALUE) return FILE_TYPE_UNKNOWN;
if (K32IsStdHandleValue(hFile, STD_INPUT_HANDLE) ||
K32IsStdHandleValue(hFile, STD_OUTPUT_HANDLE) ||
K32IsStdHandleValue(hFile, STD_ERROR_HANDLE))
return FILE_TYPE_CHAR;
return FILE_TYPE_DISK;
}
+39 -35
View File
@@ -60,38 +60,42 @@ SYS_CREATE_DIR EQU 56
SYS_REMOVE_DIR EQU 57
SYS_SET_CWD EQU 58
SYS_GET_CWD EQU 59
SYS_WRITE_CONSOLE EQU 60
SYS_BLIT_SCREEN EQU 61
SYS_CLEAR_SCREEN EQU 62
SYS_GET_SCREEN_SIZE EQU 63
SYS_PUT_SCREEN_CHAR EQU 64
SYS_POLL_KEYBOARD EQU 65
SYS_IS_KEY_DOWN EQU 66
SYS_READ_KEYBOARD_CHAR EQU 67
SYS_READ_KEY EQU 68
SYS_GET_KEY_MODIFIERS EQU 69
SYS_POLL_MOUSE EQU 70
SYS_READ_MOUSE EQU 71
SYS_GET_MOUSE_POS EQU 72
SYS_GET_TICK EQU 73
SYS_PRINT_DEBUG EQU 74
SYS_QUERY_TRAP_FRAME EQU 75
SYS_CREATE_SOCKET EQU 76
SYS_BIND_SOCKET EQU 77
SYS_LISTEN_SOCKET EQU 78
SYS_ACCEPT_SOCKET EQU 79
SYS_CONNECT_SOCKET EQU 80
SYS_SEND_SOCKET EQU 81
SYS_RECV_SOCKET EQU 82
SYS_SHUTDOWN_SOCKET EQU 83
SYS_SEND_TO_SOCKET EQU 84
SYS_RECV_FROM_SOCKET EQU 85
SYS_RESOLVE_HOST EQU 86
SYS_SET_SOCKET_OPTION EQU 87
SYS_GET_SOCKET_OPTION EQU 88
SYS_POLL EQU 89
SYS_GET_MEMORY_STATUS EQU 90
SYS_QUERY_KERNEL_STATS EQU 91
SYS_GET_SYSTEM_TIME EQU 92
SYS_MAX EQU 93
SYS_WRITE_CONSOLE EQU 60
SYS_GET_CONSOLE_INFO EQU 61
SYS_SET_CONSOLE_CURSOR EQU 62
SYS_FILL_CONSOLE_CHARACTER EQU 63
SYS_FILL_CONSOLE_ATTRIBUTE EQU 64
SYS_PUT_SCREEN_CHAR EQU 65
SYS_BLIT_SCREEN EQU 66
SYS_CLEAR_SCREEN EQU 67
SYS_GET_SCREEN_SIZE EQU 68
SYS_QUERY_DISPLAY_INFO EQU 69
SYS_POLL_KEYBOARD EQU 70
SYS_IS_KEY_DOWN EQU 71
SYS_READ_KEYBOARD_CHAR EQU 72
SYS_READ_KEY EQU 73
SYS_GET_KEY_MODIFIERS EQU 74
SYS_POLL_MOUSE EQU 75
SYS_READ_MOUSE EQU 76
SYS_GET_MOUSE_POS EQU 77
SYS_GET_TICK EQU 78
SYS_PRINT_DEBUG EQU 79
SYS_QUERY_TRAP_FRAME EQU 80
SYS_CREATE_SOCKET EQU 81
SYS_BIND_SOCKET EQU 82
SYS_LISTEN_SOCKET EQU 83
SYS_ACCEPT_SOCKET EQU 84
SYS_CONNECT_SOCKET EQU 85
SYS_SEND_SOCKET EQU 86
SYS_RECV_SOCKET EQU 87
SYS_SHUTDOWN_SOCKET EQU 88
SYS_SEND_TO_SOCKET EQU 89
SYS_RECV_FROM_SOCKET EQU 90
SYS_RESOLVE_HOST EQU 91
SYS_SET_SOCKET_OPTION EQU 92
SYS_GET_SOCKET_OPTION EQU 93
SYS_POLL EQU 94
SYS_GET_MEMORY_STATUS EQU 95
SYS_QUERY_KERNEL_STATS EQU 96
SYS_GET_SYSTEM_TIME EQU 97
SYS_MAX EQU 98
+7 -2
View File
@@ -173,10 +173,15 @@ SYSCALL_STUB2 GetCwd, SYS_GET_CWD
; Console and graphics
; ---------------------------------------------------------------------------
SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE
SYSCALL_STUB2 GetConsoleInfo, SYS_GET_CONSOLE_INFO
SYSCALL_STUB2 SetConsoleCursor, SYS_SET_CONSOLE_CURSOR
SYSCALL_STUB6 FillConsoleCharacter, SYS_FILL_CONSOLE_CHARACTER
SYSCALL_STUB6 FillConsoleAttribute, SYS_FILL_CONSOLE_ATTRIBUTE
SYSCALL_STUB6 PutScreenChar, SYS_PUT_SCREEN_CHAR
SYSCALL_STUB6 BlitScreen, SYS_BLIT_SCREEN
SYSCALL_STUB2 ClearScreen, SYS_CLEAR_SCREEN
SYSCALL_STUB2 GetScreenSize, SYS_GET_SCREEN_SIZE
SYSCALL_STUB6 PutScreenChar, SYS_PUT_SCREEN_CHAR
SYSCALL_STUB2 QueryDisplayInfo, SYS_QUERY_DISPLAY_INFO
; ---------------------------------------------------------------------------
; Input
@@ -195,7 +200,6 @@ SYSCALL_STUB2 GetMousePos, SYS_GET_MOUSE_POS
; Time and debug
; ---------------------------------------------------------------------------
SYSCALL_STUB2 GetTick, SYS_GET_TICK
SYSCALL_STUB2 GetSystemTime, SYS_GET_SYSTEM_TIME
SYSCALL_STUB2 PrintDebug, SYS_PRINT_DEBUG
SYSCALL_STUB2 QueryTrapFrame, SYS_QUERY_TRAP_FRAME
@@ -219,5 +223,6 @@ SYSCALL_STUB2 Poll, SYS_POLL
SYSCALL_STUB2 GetMemoryStatus, SYS_GET_MEMORY_STATUS
SYSCALL_STUB2 QueryKernelStats, SYS_QUERY_KERNEL_STATS
SYSCALL_STUB2 GetSystemTime, SYS_GET_SYSTEM_TIME
END