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:
1 parent
e41bf6e2c0
commit
6260de0085
38 files changed
+4011
-467
No files matched your search
@@ -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
@@ -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"},
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
@@ -8,5 +8,6 @@ fat32.sys
|
||||
|
||||
[runtime]
|
||||
lwip.sys
|
||||
vmwaresvga.sys
|
||||
rtl8139.sys
|
||||
rtl816x.sys
|
||||
@@ -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 },
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user