808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * VBox NT4 Mouse Driver
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Copyright (C) 2011-2012 Oracle Corporation
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * available from http://www.virtualbox.org. This file is free software;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * you can redistribute it and/or modify it under the terms of the GNU
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * General Public License (GPL) as published by the Free Software
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7519a1c4323fa86fbb19a36a91cd25abfd7af714vboxsync#define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
7519a1c4323fa86fbb19a36a91cd25abfd7af714vboxsync#undef _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* not available on NT4 */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* i8042 mouse status bits */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define MOUSE_SIGN_OVERFLOW_MASK (X_DATA_SIGN | Y_DATA_SIGN | X_OVERFLOW | Y_OVERFLOW)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define I8X_PUT_COMMAND_BYTE(Address, Byte) WRITE_PORT_UCHAR(Address, (UCHAR) Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define I8X_PUT_DATA_BYTE(Address, Byte) WRITE_PORT_UCHAR(Address, (UCHAR) Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define I8X_GET_STATUS_BYTE(Address) READ_PORT_UCHAR(Address)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define I8X_GET_DATA_BYTE(Address) READ_PORT_UCHAR(Address)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* commands to the i8042 controller */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* i8042 Controller Command Byte */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* i8042 Controller Status Register bits */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* i8042 responses */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* commands to the keyboard (through the 8042 data port) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* commands to the mouse (through the 8042 data port) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* mouse responses */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* maximum number of pointer/keyboard port names the port driver */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* NtDeviceIoControlFile internal IoControlCode values for keyboard device */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_KEYBOARD_CONNECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_KEYBOARD_ENABLE CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_KEYBOARD_DISABLE CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* NtDeviceIoControlFile internal IoControlCode values for mouse device */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_MOUSE_CONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_MOUSE_DISCONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_MOUSE_ENABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync#define IOCTL_INTERNAL_MOUSE_DISABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* i8042 controller input/output ports */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* device types attached to the i8042 controller */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* keyboard output states */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* keyboard scan code input states */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* mouse states */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsynctypedef VOID (*PSERVICECALLBACK)(PVOID Ctx, PVOID pArg1, PVOID pArg2, PVOID pArg3);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync INTERFACE_TYPE InterfaceType; /**< bus interface type */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CM_PARTIAL_RESOURCE_DESCRIPTOR aPorts[i8042MaxPorts];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync BOOLEAN fFloatSave; /**< weather to save floating point context */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync USHORT PollingIterations; /**< number of polling iterations */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync {10, 3, 84}, /* PC/XT 83- 84-key keyboard (and compatibles) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync {12, 3, 102}, /* Olivetti M24 102-key keyboard (and compatibles) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync {10, 3, 84}, /* All AT type keyboards (84-86 keys) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync {12, 3, 101} /* Enhanced 101- or 102-key keyboards (and compatibles) */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouFindWheel(PDEVICE_OBJECT pDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID MouGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID KbdGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID HwGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CreateResList(PDEVEXT pDevExt, PCM_RESOURCE_LIST *pResList, PULONG pResListSize);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouCallOut(PVOID pCtx, PUNICODE_STRING PathName,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync INTERFACE_TYPE BusType, ULONG uBusNr, PKEY_VALUE_FULL_INFORMATION *pBusInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uCtrlType, ULONG uCtrlNr, PKEY_VALUE_FULL_INFORMATION *pCtrlInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uPrfType, ULONG uPrfNr, PKEY_VALUE_FULL_INFORMATION *pPrfInf);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS KbdCallOut(PVOID pCtx, PUNICODE_STRING PathName,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync INTERFACE_TYPE BusType, ULONG uBusNr, PKEY_VALUE_FULL_INFORMATION *pBusInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uCtrlType, ULONG uCtrlNr, PKEY_VALUE_FULL_INFORMATION *pCtrlInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uPrfType, ULONG uPrfNr, PKEY_VALUE_FULL_INFORMATION *pPrfInf);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync/* */ NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING RegistryPath);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic BOOLEAN MouDataToQueue(PPORTMOUEXT MouExt, PMOUSE_INPUT_DATA InputData)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic BOOLEAN KbdDataToQueue(PPORTKBDEXT KbdExt, PKEYBOARD_INPUT_DATA InputData)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync previousDataIn->MakeCode = KEYBOARD_OVERRUN_MAKE_CODE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Queues the current input data to be processed by a DPC outside the ISR
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.UnitId = pDevExt->MouExt.UnitId;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!MouDataToQueue(&pDevExt->MouExt, &pDevExt->MouExt.CurrentInput))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInsertQueueDpc(&pDevExt->MouseIsrDpc, pDevObj->CurrentIrp, NULL);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Drain the i8042 controller buffer.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID DrainOutBuf(PUCHAR DataAddress, PUCHAR CommandAddress)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < 2000; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(I8X_GET_STATUS_BYTE(CommandAddress) & INPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync while (I8X_GET_STATUS_BYTE(CommandAddress) & OUTPUT_BUFFER_FULL)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Read a data byte from the controller, keyboard or mouse in polling mode.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS GetBytePoll(int DevType, PDEVEXT pDevExt, PUCHAR Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync UCHAR fMask = (DevType == MouDevType) ? (UCHAR)(OUTPUT_BUFFER_FULL | MOUSE_OUTPUT_BUFFER_FULL)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync while ( (i < (ULONG)pDevExt->Cfg.PollingIterations)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync && ((UCHAR)((byte = I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd])) & fMask) != fMask))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *Byte = I8X_GET_DATA_BYTE(pDevExt->DevRegs[i8042Dat]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeStallExecutionProcessor(pDevExt->Cfg.StallMicroseconds);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *Byte = I8X_GET_DATA_BYTE(pDevExt->DevRegs[i8042Dat]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Send a command or data byte to the controller, keyboard or mouse.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS PutBytePoll(CCHAR PortType, BOOLEAN fWaitForAck, int AckDevType, PDEVEXT pDevExt, UCHAR Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* switch to AUX device */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_WRITE_TO_AUXILIARY_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUCHAR commandAddress = pDevExt->DevRegs[i8042Cmd];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned j = 0; j < (unsigned)pDevExt->Cfg.iResend; j++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync unsigned i = 0;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync while ( i++ < (ULONG)pDevExt->Cfg.PollingIterations
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync && (I8X_GET_STATUS_BYTE(commandAddress) & INPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeStallExecutionProcessor(pDevExt->Cfg.StallMicroseconds);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync while ((status = GetBytePoll(AckDevType, pDevExt, &byte)) == STATUS_SUCCESS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_WRITE_TO_AUXILIARY_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Read a byte from controller, keyboard or mouse
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID GetByteAsync(int DevType, PDEVEXT pDevExt, PUCHAR pByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ? (UCHAR) (OUTPUT_BUFFER_FULL | MOUSE_OUTPUT_BUFFER_FULL)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync && ((UCHAR)((byte = I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd])) & fMask) != fMask))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *pByte = I8X_GET_DATA_BYTE(pDevExt->DevRegs[i8042Dat]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *pByte = I8X_GET_DATA_BYTE(pDevExt->DevRegs[i8042Dat]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Send a command or data byte to the controller, keyboard or mouse
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * asynchronously.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID PutByteAsync(CCHAR PortType, PDEVEXT pDevExt, UCHAR Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync unsigned i = 0;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync while (I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & INPUT_BUFFER_FULL)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync I8X_PUT_COMMAND_BYTE(pDevExt->DevRegs[i8042Cmd], Byte);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync I8X_PUT_DATA_BYTE(pDevExt->DevRegs[i8042Dat], Byte);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Initiaze an I/O operation for the keyboard device.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KBDSETPACKET keyboardPacket = pDevExt->KbdExt.CurrentOutput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->KbdExt.CurrentOutput.State == SendFirstByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Dat, pDevExt, keyboardPacket.FirstByte);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (pDevExt->KbdExt.CurrentOutput.State == SendLastByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Dat, pDevExt, keyboardPacket.LastByte);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVICE_OBJECT pDevObj = ((PKBDINITIATECTX)pCtx)->pDevObj;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.CurrentOutput.State = SendFirstByte;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.CurrentOutput.FirstByte = ((PKBDINITIATECTX)pCtx)->FirstByte;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.CurrentOutput.LastByte = ((PKBDINITIATECTX)pCtx)->LastByte;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Perform an operation on the InterlockedDpcVariable.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)((PGETDATAPTRCTX)pCtx)->pDevExt;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CCHAR DevType = (CCHAR)((PGETDATAPTRCTX)pCtx)->DevType;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->DataIn = pDevExt->KbdExt.DataIn;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->DataOut = pDevExt->KbdExt.DataOut;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->cInput = pDevExt->KbdExt.cInput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->DataIn = pDevExt->MouExt.DataIn;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->DataOut = pDevExt->MouExt.DataOut;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PGETDATAPTRCTX)pCtx)->cInput = pDevExt->MouExt.cInput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)((PI8042INITDATACTX)pCtx)->pDevExt;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CCHAR DevType = (CCHAR) ((PI8042INITDATACTX)pCtx)->DevType;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.DataIn = pDevExt->KbdExt.InputData;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.DataOut = pDevExt->KbdExt.InputData;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.DataIn = pDevExt->MouExt.InputData;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.DataOut = pDevExt->MouExt.InputData;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)((PSETDATAPTRCTX)pCtx)->pDevExt;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CCHAR DevType = (CCHAR) ((PSETDATAPTRCTX)pCtx)->DevType;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.DataOut = (PKEYBOARD_INPUT_DATA)((PSETDATAPTRCTX)pCtx)->DataOut;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.cInput -= ((PSETDATAPTRCTX)pCtx)->cInput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.DataOut = (PMOUSE_INPUT_DATA)((PSETDATAPTRCTX)pCtx)->DataOut;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.cInput -= ((PSETDATAPTRCTX)pCtx)->cInput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * DISPATCH_LEVEL IRQL: Complete requests.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CompleteDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PIRP Irp, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->Cfg.KbdInd = *(PKEYBOARD_INDICATOR_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->Cfg.KeyRepeatCurrent = *(PKEYBOARD_TYPEMATIC_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS I8042Flush(PDEVICE_OBJECT pDevObj, PIRP Irp)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Dispatch internal device control requests.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS I8042DevCtrl(PDEVICE_OBJECT pDevObj, PIRP Irp)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT) != KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, InitDataQueue, &initDataCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT) != MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, InitDataQueue, &initDataCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *(PKEYBOARD_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer = pDevExt->Cfg.KbdAttr;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync + (sizeof(INDICATOR_LIST) * (pDevExt->Cfg.KbdAttr.NumberOfIndicators - 1));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < cbTrans)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->AssociatedIrp.SystemBuffer)->NumberOfIndicatorKeys = pDevExt->Cfg.KbdAttr.NumberOfIndicators;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->AssociatedIrp.SystemBuffer)->IndicatorList, (PCHAR)s_aIndicators, cbTrans);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *(PKEYBOARD_INDICATOR_PARAMETERS)Irp->AssociatedIrp.SystemBuffer = pDevExt->Cfg.KbdInd;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ( (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync || ( (((PKEYBOARD_INDICATOR_PARAMETERS)Irp->AssociatedIrp.SystemBuffer)->LedFlags
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync & ~(KEYBOARD_SCROLL_LOCK_ON | KEYBOARD_NUM_LOCK_ON | KEYBOARD_CAPS_LOCK_ON)) != 0))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *(PKEYBOARD_TYPEMATIC_PARAMETERS)Irp->AssociatedIrp.SystemBuffer = pDevExt->Cfg.KeyRepeatCurrent;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->IoStatus.Information = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ( irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync || ((PKEYBOARD_TYPEMATIC_PARAMETERS)pParams)->Rate < KbdAttr->KeyRepeatMinimum.Rate
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync || ((PKEYBOARD_TYPEMATIC_PARAMETERS)pParams)->Rate > KbdAttr->KeyRepeatMaximum.Rate
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync || ((PKEYBOARD_TYPEMATIC_PARAMETERS)pParams)->Delay < KbdAttr->KeyRepeatMinimum.Delay
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync || ((PKEYBOARD_TYPEMATIC_PARAMETERS)pParams)->Delay > KbdAttr->KeyRepeatMaximum.Delay)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *(PMOUSE_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer = pDevExt->Cfg.MouAttr;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Dispatch routine for create/open and close requests.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS I8042OpenClose(PDEVICE_OBJECT pDevObj, PIRP Irp)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * DISPATCH_LEVEL IRQL: Complete requests that have exceeded the maximum
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * number of retries.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CtrlRetriesExceededDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PIRP Irp, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync 31, 31, 28, 26, 23, 20, 18, 17, 15, 13, 12, 11, 10, 9,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Convert typematic rate/delay to a value expected by the keyboard:
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * - bit 7 is zero
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * - bits 5...6 indicate the delay
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * - bits 0...4 indicate the rate
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic UCHAR ConvertTypematic(USHORT Rate, USHORT Delay)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Start an I/O operation for the device.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID I8042StartIo(PDEVICE_OBJECT pDevObj, PIRP Irp)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync interlockedResult = ASMAtomicIncU32(&pDevExt->KeyboardEnableCount);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync keyboardInitiateContext.FirstByte = SET_KEYBOARD_INDICATORS;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (UCHAR) ((PKEYBOARD_INDICATOR_PARAMETERS)Irp->AssociatedIrp.SystemBuffer)->LedFlags;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, KbdStartWrapper, &keyboardInitiateContext);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSetTimer(&pDevExt->CommandTimer, deltaTime, &pDevExt->TimeOutDpc);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync keyboardInitiateContext.FirstByte = SET_KEYBOARD_TYPEMATIC;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ConvertTypematic(((PKEYBOARD_TYPEMATIC_PARAMETERS)Irp->AssociatedIrp.SystemBuffer)->Rate,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ((PKEYBOARD_TYPEMATIC_PARAMETERS)Irp->AssociatedIrp.SystemBuffer)->Delay);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, KbdStartWrapper, &keyboardInitiateContext);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSetTimer(&pDevExt->CommandTimer, deltaTime, &pDevExt->TimeOutDpc);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Driver's command timeout routine.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CtrlTimeoutDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PVOID SystemContext1, PVOID SystemContext2)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, DecTimer, &timerContext);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevObj->CurrentIrp->IoStatus.Status = STATUS_IO_TIMEOUT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSetTimer(&pDevExt->CommandTimer, deltaTime, &pDevExt->TimeOutDpc);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * DISPATCH_LEVEL IRQL: Finish processing for keyboard interrupts.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CtrlKbdIsrDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PIRP Irp, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync opCtx.VariableAddress = &pDevExt->DpcInterlockKeyboard;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, DpcVarOp, (PVOID)&opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync BOOLEAN fContinue = (interlockedResult == 0) ? TRUE : FALSE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, GetDataQueuePtr, &getPtrCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PVOID classDeviceObject = pDevExt->KbdExt.ConnectData.ClassDeviceObject;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PSERVICECALLBACK classService = pDevExt->KbdExt.ConnectData.ClassService;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync classService(classDeviceObject, getPtrCtx.DataOut, pDevExt->KbdExt.DataEnd, &inputDataConsumed);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync cbNotConsumed = (((PUCHAR) pDevExt->KbdExt.DataEnd - (PUCHAR) getPtrCtx.DataOut)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync / sizeof(KEYBOARD_INPUT_DATA)) - inputDataConsumed;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync + (inputDataConsumed * sizeof(KEYBOARD_INPUT_DATA));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync classService(classDeviceObject, getPtrCtx.DataOut, getPtrCtx.DataIn, &inputDataConsumed);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync cbNotConsumed = (((PUCHAR) getPtrCtx.DataIn - (PUCHAR) getPtrCtx.DataOut)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync / sizeof(KEYBOARD_INPUT_DATA)) - inputDataConsumed;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, SetDataQueuePtr, &setPtrCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSetTimer(&pDevExt->KbdExt.DataConsumptionTimer, deltaTime, &pDevExt->KeyboardIsrDpcRetry);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->KbdIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * DISPATCH_LEVEL IRQL: Finish processing of mouse interrupts
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CtrlMouIsrDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PIRP Irp, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync opCtx.VariableAddress = &pDevExt->DpcInterlockMouse;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync BOOLEAN fContinue = (interlockedResult == 0) ? TRUE : FALSE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, GetDataQueuePtr, &getPtrCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PVOID classDeviceObject = pDevExt->MouExt.ConnectData.ClassDeviceObject;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PSERVICECALLBACK classService = pDevExt->MouExt.ConnectData.ClassService;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync classService(classDeviceObject, getPtrCtx.DataOut, pDevExt->MouExt.DataEnd, &inputDataConsumed);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync cbNotConsumed = (((PUCHAR)pDevExt->MouExt.DataEnd - (PUCHAR) getPtrCtx.DataOut)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync setPtrCtx.DataOut = ((PUCHAR)getPtrCtx.DataOut) + (inputDataConsumed * sizeof(MOUSE_INPUT_DATA));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync classService(classDeviceObject, getPtrCtx.DataOut, getPtrCtx.DataIn, &inputDataConsumed);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync cbNotConsumed = (((PUCHAR) getPtrCtx.DataIn - (PUCHAR) getPtrCtx.DataOut)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync setPtrCtx.DataOut = ((PUCHAR)getPtrCtx.DataOut) + (inputDataConsumed * sizeof(MOUSE_INPUT_DATA));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, SetDataQueuePtr, &setPtrCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSetTimer(&pDevExt->MouExt.DataConsumptionTimer, deltaTime, &pDevExt->MouseIsrDpcRetry);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeSynchronizeExecution(pDevExt->MouIntObj, DpcVarOp, &opCtx);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Interrupt service routine for the mouse device.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic BOOLEAN MouIntHandler(PKINTERRUPT Interrupt, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent &= ~WHEELMOUSE_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Cmd, pDevExt, I8042_WRITE_TO_AUXILIARY_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Dat, pDevExt, ENABLE_MOUSE_TRANSMISSION);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync tickDelta.QuadPart = newTick.QuadPart - pDevExt->MouExt.PreviousTick.QuadPart;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync && (tickDelta.LowPart >= pDevExt->MouExt.SynchTickCount || tickDelta.HighPart != 0))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((!(fPrevBtns & LEFT_BUTTON_DOWN)) && (byte & LEFT_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if ((fPrevBtns & LEFT_BUTTON_DOWN) && !(byte & LEFT_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_LEFT_BUTTON_UP;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((!(fPrevBtns & RIGHT_BUTTON_DOWN)) && (byte & RIGHT_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if ((fPrevBtns & RIGHT_BUTTON_DOWN) && !(byte & RIGHT_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_RIGHT_BUTTON_UP;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((!(fPrevBtns & MIDDLE_BUTTON_DOWN)) && (byte & MIDDLE_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if ((fPrevBtns & MIDDLE_BUTTON_DOWN) && !(byte & MIDDLE_BUTTON_DOWN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.PreviousButtons = byte & (RIGHT_BUTTON_DOWN|MIDDLE_BUTTON_DOWN|LEFT_BUTTON_DOWN);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.uCurrSignAndOverflow = (UCHAR) (byte & MOUSE_SIGN_OVERFLOW_MASK);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & X_OVERFLOW)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync uPrevSignAndOverflow = pDevExt->MouExt.uPrevSignAndOverflow;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((uPrevSignAndOverflow & X_DATA_SIGN) != (pDevExt->MouExt.uCurrSignAndOverflow & X_DATA_SIGN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.uCurrSignAndOverflow ^= X_DATA_SIGN;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & X_DATA_SIGN)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastX = MOUSE_MAXIMUM_NEGATIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastX = MOUSE_MAXIMUM_POSITIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & X_DATA_SIGN)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastX |= MOUSE_MAXIMUM_NEGATIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & Y_OVERFLOW)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync uPrevSignAndOverflow = pDevExt->MouExt.uPrevSignAndOverflow;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((uPrevSignAndOverflow & Y_DATA_SIGN) != (pDevExt->MouExt.uCurrSignAndOverflow & Y_DATA_SIGN))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.uCurrSignAndOverflow ^= Y_DATA_SIGN;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & Y_DATA_SIGN)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY = MOUSE_MAXIMUM_POSITIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY = MOUSE_MAXIMUM_NEGATIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->MouExt.uCurrSignAndOverflow & Y_DATA_SIGN)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY |= MOUSE_MAXIMUM_NEGATIVE_DELTA;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY = -pDevExt->MouExt.CurrentInput.LastY;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.uPrevSignAndOverflow = pDevExt->MouExt.uCurrSignAndOverflow;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & WHEELMOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.Flags = MOUSE_MOVE_RELATIVE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pReq->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* make it an absolute move */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.Flags = MOUSE_MOVE_ABSOLUTE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastX = pReq->pointerXPos;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY = pReq->pointerYPos;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Log(("VBoxMouseNT: ERROR querying mouse capabilities from VMMDev. rc = %Rrc\n", rc));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (byte && pDevExt->MouExt.CurrentInput.Buttons == 0)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.ButtonFlags |= MOUSE_WHEEL;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.Flags = MOUSE_MOVE_RELATIVE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pReq->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* make it an absolute move */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.Flags = MOUSE_MOVE_ABSOLUTE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastX = pReq->pointerXPos;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.CurrentInput.LastY = pReq->pointerYPos;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Log(("VBoxMouseNT: ERROR querying mouse capabilities from VMMDev. rc = %Rrc\n", rc));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Cmd, pDevExt, I8042_WRITE_TO_AUXILIARY_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutByteAsync(i8042Dat, pDevExt, ENABLE_MOUSE_TRANSMISSION);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Interrupt service routine.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic BOOLEAN KbdIntHandler(PKINTERRUPT Interrupt, PVOID pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < (ULONG)pDevExt->Cfg.PollStatusIterations; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync UCHAR scanCode = I8X_GET_DATA_BYTE(pDevExt->DevRegs[i8042Dat]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (pDevExt->KbdExt.ResendCount < pDevExt->Cfg.iResend)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInsertQueueDpc(&pDevExt->RetriesExceededDpc, pDevObj->CurrentIrp, NULL);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->KbdExt.CurrentOutput.State == SendFirstByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.CurrentOutput.State = SendLastByte;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (pDevExt->KbdExt.CurrentOutput.State == SendLastByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PKEYBOARD_INPUT_DATA input = &pDevExt->KbdExt.CurrentInput;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KBDSCANSTATE *pScanState = &pDevExt->KbdExt.CurrentScanState;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* fall through */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.CurrentInput.UnitId = pDevExt->KbdExt.UnitId;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInsertQueueDpc(&pDevExt->KeyboardIsrDpc, pDevObj->CurrentIrp, NULL);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouEnableTrans(PDEVICE_OBJECT pDevObj)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, FALSE /*=wait*/, MouDevType, pDevExt, ENABLE_MOUSE_TRANSMISSION);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Configuration information for the keyboard.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID KbdGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < MaximumInterfaceType; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE controllerType = KeyboardController;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE peripheralType = KeyboardPeripheral;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync NTSTATUS status = IoQueryDeviceDescription(&interfaceType, NULL,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync HwGetRegstry(pInit, RegistryPath, KeyboardDeviceName, PointerDeviceName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PKEYBOARD_ID keyboardId = &pCfg->KbdAttr.KeyboardIdentifier;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollingIterations = pCfg->PollingIterationsMaximum;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.NumberOfFunctionKeys = s_aKeybType[keyboardId->Type-1].cFunctionKeys;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.NumberOfIndicators = s_aKeybType[keyboardId->Type-1].cIndicators;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.NumberOfKeysTotal = s_aKeybType[keyboardId->Type-1].cKeysTotal;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Retrieve the configuration information for the mouse.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID MouGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE controllerType = PointerController;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE peripheralType = PointerPeripheral;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < MaximumInterfaceType; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = IoQueryDeviceDescription(&interfaceType, NULL,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pInit->DevExt.HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(pInit->DevExt.HardwarePresent & KEYBOARD_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync HwGetRegstry(pInit, RegistryPath, KeyboardDeviceName, PointerDeviceName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pInit->DevExt.Cfg.MouAttr.MouseIdentifier = MOUSE_I8042_HARDWARE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Initialize the driver.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncNTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING RegistryPath)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PINITEXT pInit = (PINITEXT)ExAllocatePool(NonPagedPool, sizeof(INITEXT));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(keyboardBuffer, NAME_MAX * sizeof(WCHAR));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KbdNameBase.MaximumLength = NAME_MAX * sizeof(WCHAR);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(pointerBuffer, NAME_MAX * sizeof(WCHAR));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync MouNameBase.MaximumLength = NAME_MAX * sizeof(WCHAR);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync registryPath.Buffer = (PWSTR)ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(UNICODE_NULL));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync registryPath.Length = RegistryPath->Length + sizeof(UNICODE_NULL);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(registryPath.Buffer, registryPath.Length);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlMoveMemory(registryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KbdGetRegstry(pInit, ®istryPath, &KbdNameBase, &MouNameBase);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync MouGetRegstry(pInit, ®istryPath, &KbdNameBase, &MouNameBase);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync else if (!(pInit->DevExt.HardwarePresent & KEYBOARD_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync DevNameSuff.MaximumLength = (KEYBOARD_PORTS_MAXIMUM > POINTER_PORTS_MAXIMUM)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync DevNameSuff.Buffer = (PWSTR)ExAllocatePool(PagedPool, DevNameSuff.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(DevNameSuff.Buffer, DevNameSuff.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KbdNameFull.MaximumLength = sizeof(L"\\Device\\") + KbdNameBase.Length + DevNameSuff.MaximumLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KbdNameFull.Buffer = (PWSTR)ExAllocatePool(PagedPool, KbdNameFull.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(KbdNameFull.Buffer, KbdNameFull.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(&KbdNameFull, L"\\Device\\");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(&KbdNameFull, KbdNameBase.Buffer);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < KEYBOARD_PORTS_MAXIMUM; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlIntegerToUnicodeString(i, 10, &DevNameSuff);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeStringToString(&KbdNameFull, &DevNameSuff);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync LogFlow(("VBoxMouseNT::DriverEntry: Creating device object named %S\n", KbdNameFull.Buffer));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = IoCreateDevice(pDrvObj, sizeof(DEVEXT), &KbdNameFull,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pPortDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CreateResList(pDevExt, &resources, &resourceListSize);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync resourceDeviceClass.MaximumLength = KbdNameBase.Length + sizeof(L"/") + MouNameBase.Length;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync resourceDeviceClass.Buffer = (PWSTR)ExAllocatePool(PagedPool, resourceDeviceClass.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(resourceDeviceClass.Buffer, resourceDeviceClass.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeStringToString(&resourceDeviceClass, &KbdNameBase);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(&resourceDeviceClass, L"/");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeStringToString(&resourceDeviceClass, &MouNameBase);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync IoReportResourceUsage(&resourceDeviceClass, pDrvObj, NULL, 0, pPortDevObj,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync addressSpace = (pDevExt->Cfg.aPorts[i].Flags & CM_RESOURCE_PORT_IO) == CM_RESOURCE_PORT_IO ? 1 : 0;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!HalTranslateBusAddress(pDevExt->Cfg.InterfaceType,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->DevRegs[i] = (PUCHAR)MmMapIoSpace(Phys, pDevExt->Cfg.aPorts[i].u.Port.Length,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ExAllocatePool(NonPagedPool, pDevExt->Cfg.KbdAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (PKEYBOARD_INPUT_DATA)((PCHAR) (pDevExt->KbdExt.InputData) + pDevExt->Cfg.KbdAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(pDevExt->KbdExt.InputData, pDevExt->Cfg.KbdAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync MouNameFull.MaximumLength = sizeof(L"\\Device\\") + MouNameBase.Length + DevNameSuff.MaximumLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync MouNameFull.Buffer = (PWSTR)ExAllocatePool(PagedPool, MouNameFull.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(MouNameFull.Buffer, MouNameFull.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(&MouNameFull, L"\\Device\\");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(&MouNameFull, MouNameBase.Buffer);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(DevNameSuff.Buffer, DevNameSuff.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < POINTER_PORTS_MAXIMUM; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlIntegerToUnicodeString(i, 10, &DevNameSuff);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeStringToString(&MouNameFull, &DevNameSuff);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync LogFlow(("VBoxMouseNT::DriverEntry: pointer port name (symbolic link) = %S\n", MouNameFull.Buffer));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = IoCreateSymbolicLink(&MouNameFull, &KbdNameFull);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (PMOUSE_INPUT_DATA)ExAllocatePool(NonPagedPool, pDevExt->Cfg.MouAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.DataEnd = (PMOUSE_INPUT_DATA)((PCHAR) (pDevExt->MouExt.InputData) + pDevExt->Cfg.MouAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(pDevExt->MouExt.InputData, pDevExt->Cfg.MouAttr.InputDataQueueLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->KbdExt.ConnectData.ClassDeviceObject = NULL;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->MouExt.ConnectData.ClassDeviceObject = NULL;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->RetriesExceededDpc, (PKDEFERRED_ROUTINE)CtrlRetriesExceededDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->KeyboardIsrDpc, (PKDEFERRED_ROUTINE)CtrlKbdIsrDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->KeyboardIsrDpcRetry, (PKDEFERRED_ROUTINE)CtrlKbdIsrDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->MouseIsrDpc, (PKDEFERRED_ROUTINE)CtrlMouIsrDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->MouseIsrDpcRetry, (PKDEFERRED_ROUTINE)CtrlMouIsrDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeDpc(&pDevExt->TimeOutDpc, (PKDEFERRED_ROUTINE)CtrlTimeoutDpc, pPortDevObj);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeTimer(&pDevExt->KbdExt.DataConsumptionTimer);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync KeInitializeTimer(&pDevExt->MouExt.DataConsumptionTimer);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync IntVecKbd = HalGetInterruptVector(pDevExt->Cfg.InterfaceType,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync IntVecMou = HalGetInterruptVector(pDevExt->Cfg.InterfaceType,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ( (pDevExt->HardwarePresent & (KEYBOARD_HARDWARE_PRESENT | MOUSE_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync == (KEYBOARD_HARDWARE_PRESENT | MOUSE_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = IoConnectInterrupt(&pDevExt->MouIntObj, MouIntHandler, pPortDevObj,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (KIRQL) ((IrqlCoord == (KIRQL)0) ? IrqlMou : IrqlCoord),
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->Cfg.MouInt.Flags == CM_RESOURCE_INTERRUPT_LATCHED
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = IoConnectInterrupt(&pDevExt->KbdIntObj, KbdIntHandler, pPortDevObj,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (KIRQL) ((IrqlCoord == (KIRQL)0) ? IrqlKbd : IrqlCoord),
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->Cfg.KbdInt.Flags == CM_RESOURCE_INTERRUPT_LATCHED
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Log(("VBoxMouseNT::DriverEntry: could not initialize guest library, rc = %Rrc\n", rcVBox));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* Continue working in non-VBox mode. */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&pReq, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* Inform host that we support absolute */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pReq->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Log(("VBoxMouseNT::DriverEntry: ERROR communicating new mouse capabilities to VMMDev. rc = %Rrc\n", rcVBox));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* We will use the allocated request buffer in the ServiceCallback to GET mouse status. */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pReq->header.requestType = VMMDevReq_GetMouseStatus;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Log(("VBoxMouseNT::DriverEntry: could not allocate request buffer, rc = %Rrc\n", rcVBox));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* Continue working in non-VBox mode. */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDrvObj->MajorFunction[IRP_MJ_CREATE] = I8042OpenClose;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDrvObj->MajorFunction[IRP_MJ_CLOSE] = I8042OpenClose;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDrvObj->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = I8042Flush;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = I8042DevCtrl;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync IoReportResourceUsage(&resourceDeviceClass, pDrvObj, NULL,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync 0, pPortDevObj, resources, resourceListSize, FALSE, &fConflict);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync MmUnmapIoSpace(pDevExt->DevRegs[i], pDevExt->Cfg.aPorts[i].u.Port.Length);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync LogFlow(("VBoxMouseNT::DriverEntry: leave, status = %d\n", status));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Build a resource list.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID CreateResList(PDEVEXT pDevExt, PCM_RESOURCE_LIST *pResList, PULONG pResListSize)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->Cfg.KbdInt.Type == CmResourceTypeInterrupt)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->Cfg.MouInt.Type == CmResourceTypeInterrupt)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *pResListSize = sizeof(CM_RESOURCE_LIST) + ((cPorts - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *pResList = (PCM_RESOURCE_LIST)ExAllocatePool(PagedPool, *pResListSize);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].InterfaceType = pDevExt->Cfg.InterfaceType;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].BusNumber = pDevExt->Cfg.uBusNr;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].PartialResourceList.Count = cPorts;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->Cfg.KbdInt.Type == CmResourceTypeInterrupt)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].PartialResourceList.PartialDescriptors[i++] = pDevExt->Cfg.KbdInt;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->Cfg.MouInt.Type == CmResourceTypeInterrupt)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].PartialResourceList.PartialDescriptors[i++] = pDevExt->Cfg.MouInt;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (*pResList)->List[0].PartialResourceList.PartialDescriptors[i++] = pDevExt->Cfg.aPorts[j];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Read the i8042 controller command byte
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS GetCtrlCmd(ULONG HwDisEnMask, PDEVEXT pDevExt, PUCHAR pByte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_DISABLE_KEYBOARD_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_DISABLE_MOUSE_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutBytePoll(i8042Cmd, FALSE/*=wait*/, NoDevice, pDevExt, I8042_ENABLE_KEYBOARD_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_READ_CONTROLLER_COMMAND_BYTE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status2 = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_KEYBOARD_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status2 = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_MOUSE_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Write the i8042 controller command byte.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS PutCtrlCmd(PDEVEXT pDevExt, UCHAR Byte)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_WRITE_CONTROLLER_COMMAND_BYTE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync return (PutBytePoll(i8042Dat, FALSE /*=wait*/, NoDevice, pDevExt, Byte));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Read the i8042 controller command byte.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID TransCtrlCmd(PDEVEXT pDevExt, PI8042TRANSMITCCBCTX pCtx)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCtx->Status = GetCtrlCmd(pCtx->HwDisEnMask, pDevExt, &bCtrlCmd);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCtx->Status = GetCtrlCmd(pCtx->HwDisEnMask, pDevExt, &bVrfyCmd);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Detect the number of mouse buttons.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouQueryButtons(PDEVICE_OBJECT pDevObj, PUCHAR pNumButtons)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync NTSTATUS status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, SET_MOUSE_RESOLUTION);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, 0x00);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < 3; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, SET_MOUSE_SCALING_1TO1);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, READ_MOUSE_STATUS);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = GetBytePoll(CtrlDevType, pDevExt, &buttons);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Initialize the i8042 mouse hardware.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync NTSTATUS status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, MOUSE_RESET);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < 11200; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (NT_SUCCESS(status) && byte == (UCHAR) MOUSE_COMPLETE)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ((!NT_SUCCESS(status)) || (byte != MOUSE_ID_BYTE))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, SET_MOUSE_SAMPLING_RATE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, 60);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, SET_MOUSE_RESOLUTION);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, (UCHAR)pDevExt->Cfg.MouseResolution);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Initialize the i8042 keyboard hardware.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT)pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PutBytePoll(i8042Dat, fWaitForAck, KbdDevType, pDevExt, KEYBOARD_RESET);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < 11200; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync difference.QuadPart = nextQuery.QuadPart - startOfSpin.QuadPart;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (difference.QuadPart*KeQueryTimeIncrement() >= tenSeconds.QuadPart)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Ctx.ByteMask = (UCHAR) ~((UCHAR)CCB_KEYBOARD_TRANSLATE_MODE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PKEYBOARD_ID pId = &pDevExt->Cfg.KbdAttr.KeyboardIdentifier;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt, SET_KEYBOARD_TYPEMATIC);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ConvertTypematic(pDevExt->Cfg.KeyRepeatCurrent.Rate,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* ignore errors */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt, SET_KEYBOARD_INDICATORS);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* ignore errors */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt, SELECT_SCAN_CODE_SET);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, KbdDevType, pDevExt, 1);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Initialize the i8042 controller, keyboard and mouse.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUCHAR commandAddress = pDevExt->DevRegs[i8042Cmd];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Ctx.ByteMask = (UCHAR) ~((UCHAR)CCB_ENABLE_KEYBOARD_INTERRUPT | (UCHAR)CCB_ENABLE_MOUSE_INTERRUPT);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent &= ~MOUSE_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent &= ~KEYBOARD_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync NTSTATUS status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_KEYBOARD_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent &= ~KEYBOARD_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync NTSTATUS status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_MOUSE_DEVICE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent &= ~MOUSE_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync Ctx.ByteMask = (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT) ? CCB_ENABLE_MOUSE_INTERRUPT : 0;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* ignore */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * retrieve the drivers service parameters from the registry
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic VOID HwGetRegstry(PINITEXT pInit, PUNICODE_STRING RegistryPath,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PUNICODE_STRING KeyboardDeviceName, PUNICODE_STRING PointerDeviceName)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ExAllocatePool(PagedPool, sizeof(RTL_QUERY_REGISTRY_TABLE) * (queries + 1));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(aQuery, sizeof(RTL_QUERY_REGISTRY_TABLE) * (queries + 1));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync parametersPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync parametersPath.Buffer = (PWSTR)ExAllocatePool(PagedPool, parametersPath.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlAppendUnicodeToString(¶metersPath, L"\\Parameters");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlInitUnicodeString(&defaultKeyboardName, L"KeyboardPort");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlInitUnicodeString(&defaultPointerName, L"PointerPort");
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[2].EntryContext = &pollingIterationsMaximum;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[2].DefaultData = &defaultPollingIterationsMaximum;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[3].EntryContext = &pCfg->KbdAttr.InputDataQueueLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[4].EntryContext = &pCfg->MouAttr.InputDataQueueLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[10].DefaultData = defaultKeyboardName.Buffer;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[11].DefaultData = defaultPointerName.Buffer;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[12].EntryContext = &pInit->DevExt.MouExt.SynchTickCount;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[13].DefaultData = &defaultPollStatusIterations;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync aQuery[14].DefaultData = &defaultEnableWheelDetection;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync /* driver defaults */
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollingIterations = defaultPollingIterations;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollingIterationsMaximum = defaultPollingIterationsMaximum;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollStatusIterations = defaultPollStatusIterations;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.InputDataQueueLength = defaultDataQueueSize;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouAttr.InputDataQueueLength = defaultDataQueueSize;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->EnableWheelDetection = defaultEnableWheelDetection;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pInit->DevExt.MouExt.SynchTickCount = defaultSynchPacket100ns;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlCopyUnicodeString(KeyboardDeviceName, &defaultKeyboardName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync RtlCopyUnicodeString(PointerDeviceName, &defaultPointerName);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollingIterations = (USHORT) pollingIterations;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollingIterationsMaximum = (USHORT) pollingIterationsMaximum;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->PollStatusIterations = (USHORT) pollStatusIterations;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->EnableWheelDetection = (ULONG) ((enableWheelDetection) ? 1 : 0);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.InputDataQueueLength = defaultDataQueueSize;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.InputDataQueueLength *= sizeof(KEYBOARD_INPUT_DATA);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouAttr.InputDataQueueLength = defaultDataQueueSize;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouAttr.InputDataQueueLength *= sizeof(MOUSE_INPUT_DATA);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (overrideKeyboardType <= RT_ELEMENTS(s_aKeybType))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.KeyboardIdentifier.Type = (UCHAR) overrideKeyboardType;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (overrideKeyboardSubtype != invalidKeyboardSubtype)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.KeyboardIdentifier.Subtype = (UCHAR) overrideKeyboardSubtype;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pInit->DevExt.MouExt.SynchTickCount = defaultSynchPacket100ns;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pInit->DevExt.MouExt.SynchTickCount /= KeQueryTimeIncrement();
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic void GetDevIdentifier(PKEY_VALUE_FULL_INFORMATION *ppInf, PUNICODE_STRING pStr)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pStr->Length = (USHORT)(*(ppInf + IoQueryDeviceIdentifier))->DataLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pStr->Buffer = (PWSTR) (((PUCHAR)(*(ppInf + IoQueryDeviceIdentifier)))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync + (*(ppInf + IoQueryDeviceIdentifier))->DataOffset);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic ULONG GetDevCfgData(PKEY_VALUE_FULL_INFORMATION *ppInf, PCM_PARTIAL_RESOURCE_LIST *ppData)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync ULONG DataLength = (*(ppInf + IoQueryDeviceConfigurationData))->DataLength;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync *ppData = (PCM_PARTIAL_RESOURCE_LIST)( ((PUCHAR) (*(ppInf + IoQueryDeviceConfigurationData)))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync + (*(ppInf + IoQueryDeviceConfigurationData))->DataOffset
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList));
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Callout routine. Grab keyboard controller and peripheral configuration
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * information.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS KbdCallOut(PVOID pCtx, PUNICODE_STRING PathName,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync INTERFACE_TYPE BusType, ULONG uBusNr, PKEY_VALUE_FULL_INFORMATION *pBusInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uCtrlType, ULONG uCtrlNr, PKEY_VALUE_FULL_INFORMATION *pCtrlInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uPrfType, ULONG uPrfNr, PKEY_VALUE_FULL_INFORMATION *pPrfInf)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ( (pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent |= KEYBOARD_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc = pPrfData->PartialDescriptors;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PCM_KEYBOARD_DEVICE_DATA KbdData = (PCM_KEYBOARD_DEVICE_DATA)(((PUCHAR)pResDesc)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.KeyboardIdentifier.Type = KbdData->Type;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdAttr.KeyboardIdentifier.Subtype = KbdData->Subtype;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdInd.LedFlags = (KbdData->KeyboardFlags >> 4) & 7;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc = pCtrlData->PartialDescriptors;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[pCfg->cPorts].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdInt.ShareDisposition = fDefIntShare ? CmResourceShareShared
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(pCfg->KbdInt.Type & CmResourceTypeInterrupt))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdInt.ShareDisposition = fDefIntShare ? CmResourceShareShared
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->KbdInt.Flags = (DefIntMode == Latched) ? CM_RESOURCE_INTERRUPT_LATCHED
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].Flags = CM_RESOURCE_PORT_IO;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].u.Port.Start.LowPart = 0x60;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].Flags = CM_RESOURCE_PORT_IO;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].u.Port.Start.LowPart = 0x64;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pCfg->aPorts[i8042Cmd].u.Port.Start.LowPart < pCfg->aPorts[i8042Dat].u.Port.Start.LowPart)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CM_PARTIAL_RESOURCE_DESCRIPTOR Desc = pCfg->aPorts[i8042Dat];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * Callout routine. Grab the pointer controller and the peripheral
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync * configuration information.
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouCallOut(PVOID pCtx, PUNICODE_STRING PathName,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync INTERFACE_TYPE BusType, ULONG uBusNr, PKEY_VALUE_FULL_INFORMATION *pBusInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uCtrlType, ULONG uCtrlNr, PKEY_VALUE_FULL_INFORMATION *pCtrlInf,
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CONFIGURATION_TYPE uPrfType, ULONG uPrfNr, PKEY_VALUE_FULL_INFORMATION *pPrfInf)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if ( (pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeIdentifier, TRUE);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent |= MOUSE_HARDWARE_PRESENT;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(pDevExt->HardwarePresent & MOUSE_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(pDevExt->HardwarePresent & KEYBOARD_HARDWARE_PRESENT))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc = pCtrlData->PartialDescriptors;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync BOOLEAN fPortInfoNeeded = pCfg->cPorts ? FALSE : TRUE;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[pCfg->cPorts].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouInt.ShareDisposition = fDefIntShare ? CmResourceShareShared
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (!(pCfg->MouInt.Type & CmResourceTypeInterrupt))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouInt.ShareDisposition = fDefIntShare ? CmResourceShareShared
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->MouInt.Flags = (DefIntMode == Latched) ? CM_RESOURCE_INTERRUPT_LATCHED
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].Flags = CM_RESOURCE_PORT_IO;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Dat].u.Port.Start.LowPart = 0x60;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].Flags = CM_RESOURCE_PORT_IO;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].ShareDisposition = CmResourceShareDriverExclusive;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pCfg->aPorts[i8042Cmd].u.Port.Start.LowPart = 0x64;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync if (pCfg->aPorts[i8042Cmd].u.Port.Start.LowPart < pCfg->aPorts[i8042Dat].u.Port.Start.LowPart)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync CM_PARTIAL_RESOURCE_DESCRIPTOR Desc = pCfg->aPorts[i8042Dat];
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsyncstatic NTSTATUS MouFindWheel(PDEVICE_OBJECT pDevObj)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync PDEVEXT pDevExt = (PDEVEXT) pDevObj->DeviceExtension;
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, s_ucCommands[iCmd]);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync for (unsigned i = 0; i < 5; i++)
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync && (byte == MOUSE_ID_BYTE || byte == WHEELMOUSE_ID_BYTE))
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->HardwarePresent |= (WHEELMOUSE_HARDWARE_PRESENT | MOUSE_HARDWARE_PRESENT);
808a77f9219afa33641bb74dfff3d97948bb6b62vboxsync pDevExt->Cfg.MouAttr.MouseIdentifier = WHEELMOUSE_I8042_HARDWARE;