VBoxPS2NT.cpp revision 7519a1c4323fa86fbb19a36a91cd25abfd7af714
/* $Id$ */
/** @file
* VBox NT4 Mouse Driver
*/
/*
* Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#define LOG_GROUP LOG_GROUP_DRV_MOUSE
#include <VBox/VBoxGuestLib.h>
#include <stdarg.h>
#include <string.h>
#include <ntddk.h>
#include <ntddkbd.h>
#include <ntddmou.h>
/* not available on NT4 */
/* i8042 mouse status bits */
#define LEFT_BUTTON_DOWN 0x01
#define RIGHT_BUTTON_DOWN 0x02
#define MIDDLE_BUTTON_DOWN 0x04
#define X_DATA_SIGN 0x10
#define Y_DATA_SIGN 0x20
#define X_OVERFLOW 0x40
#define Y_OVERFLOW 0x80
#define MOUSE_MAXIMUM_POSITIVE_DELTA 0x000000FF
#define MOUSE_MAXIMUM_NEGATIVE_DELTA 0xFFFFFF00
#define KEYBOARD_HARDWARE_PRESENT 0x01
#define MOUSE_HARDWARE_PRESENT 0x02
#define BALLPOINT_HARDWARE_PRESENT 0x04
#define WHEELMOUSE_HARDWARE_PRESENT 0x08
/* commands to the i8042 controller */
#define I8042_READ_CONTROLLER_COMMAND_BYTE 0x20
#define I8042_WRITE_CONTROLLER_COMMAND_BYTE 0x60
#define I8042_DISABLE_MOUSE_DEVICE 0xA7
#define I8042_ENABLE_MOUSE_DEVICE 0xA8
#define I8042_AUXILIARY_DEVICE_TEST 0xA9
#define I8042_KEYBOARD_DEVICE_TEST 0xAB
#define I8042_DISABLE_KEYBOARD_DEVICE 0xAD
#define I8042_ENABLE_KEYBOARD_DEVICE 0xAE
#define I8042_WRITE_TO_AUXILIARY_DEVICE 0xD4
/* i8042 Controller Command Byte */
#define CCB_ENABLE_KEYBOARD_INTERRUPT 0x01
#define CCB_ENABLE_MOUSE_INTERRUPT 0x02
#define CCB_DISABLE_KEYBOARD_DEVICE 0x10
#define CCB_DISABLE_MOUSE_DEVICE 0x20
#define CCB_KEYBOARD_TRANSLATE_MODE 0x40
/* i8042 Controller Status Register bits */
#define OUTPUT_BUFFER_FULL 0x01
#define INPUT_BUFFER_FULL 0x02
#define MOUSE_OUTPUT_BUFFER_FULL 0x20
/* i8042 responses */
#define ACKNOWLEDGE 0xFA
#define RESEND 0xFE
/* commands to the keyboard (through the 8042 data port) */
#define SET_KEYBOARD_INDICATORS 0xED
#define SELECT_SCAN_CODE_SET 0xF0
#define READ_KEYBOARD_ID 0xF2
#define SET_KEYBOARD_TYPEMATIC 0xF3
#define SET_ALL_TYPEMATIC_MAKE_BREAK 0xFA
#define KEYBOARD_RESET 0xFF
/* commands to the mouse (through the 8042 data port) */
#define SET_MOUSE_SCALING_1TO1 0xE6
#define SET_MOUSE_RESOLUTION 0xE8
#define READ_MOUSE_STATUS 0xE9
#define GET_DEVICE_ID 0xF2
#define SET_MOUSE_SAMPLING_RATE 0xF3
#define ENABLE_MOUSE_TRANSMISSION 0xF4
#define MOUSE_RESET 0xFF
/* mouse responses */
#define MOUSE_COMPLETE 0xAA
#define MOUSE_ID_BYTE 0x00
#define WHEELMOUSE_ID_BYTE 0x03
#define POINTER_PORTS_MAXIMUM 8
#define KEYBOARD_PORTS_MAXIMUM 8
/* NtDeviceIoControlFile internal IoControlCode values for keyboard device */
#define IOCTL_INTERNAL_KEYBOARD_CONNECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_KEYBOARD_ENABLE CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_KEYBOARD_DISABLE CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS)
/* NtDeviceIoControlFile internal IoControlCode values for mouse device */
#define IOCTL_INTERNAL_MOUSE_CONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MOUSE_DISCONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MOUSE_ENABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MOUSE_DISABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS)
typedef enum _I8042IOPORTTYPE
{
i8042Dat = 0,
/* device types attached to the i8042 controller */
typedef enum _I8042DEVTYPE
{
} I8042DEVTYPE;
/* keyboard output states */
typedef enum _KBDSTATE
{
Idle,
} KBDSTATE;
/* keyboard scan code input states */
typedef enum _KBDSCANSTATE
{
} KBDSCANSTATE;
/* mouse states */
typedef enum _MOUSTATE
{
} MOUSTATE;
typedef struct _CONNECT_DATA
{
typedef struct _KBDSETPACKET
{
typedef struct _I8042CFGINF
{
} I8042CFGINF, *PI8042CFGINF;
typedef struct _PORTKBDEXT
{
} PORTKBDEXT, *PPORTKBDEXT;
typedef struct _PORTMOUEXT
{
} PORTMOUEXT, *PPORTMOUEXT;
typedef struct _DEVEXT
{
volatile uint32_t KeyboardEnableCount;
volatile uint32_t MouseEnableCount;
typedef struct _INITEXT
{
typedef struct _I8042INITDATACTX
{
int DevType;
typedef struct _I8042TRANSMITCCBCTX
{
typedef struct _GETDATAPTRCTX
{
int DevType;
typedef struct _SETDATAPTRCTX
{
int DevType;
typedef struct _TIMERCTX
{
typedef struct _KBDINITIATECTX
{
typedef enum _OPTYPE
{
} OPTYPE;
typedef struct _VAROPCTX
{
typedef struct _KBDTYPEINFO
{
} KBDTYPEINFO;
{
{0x3A, KEYBOARD_CAPS_LOCK_ON},
{0x45, KEYBOARD_NUM_LOCK_ON},
{0x46, KEYBOARD_SCROLL_LOCK_ON}
};
{
{12, 3, 102}, /* Olivetti M24 102-key keyboard (and compatibles) */
{10, 3, 84}, /* All AT type keyboards (84-86 keys) */
{12, 3, 101} /* Enhanced 101- or 102-key keyboards (and compatibles) */
};
#ifdef ALLOC_PRAGMA
#endif
{
return FALSE;
return TRUE;
}
{
{
else
previousDataIn->Flags = 0;
return FALSE;
}
return TRUE;
}
/**
* Queues the current input data to be processed by a DPC outside the ISR
*/
{
if (pDevExt->MouseEnableCount)
{
{
}
else if (pDevExt->DpcInterlockMouse >= 0)
else
}
}
/**
* Drain the i8042 controller buffer.
*/
{
for (unsigned i = 0; i < 2000; i++)
{
break;
}
}
/**
* Read a data byte from the controller, keyboard or mouse in polling mode.
*/
{
ULONG i = 0;
: (UCHAR) OUTPUT_BUFFER_FULL;
{
if (byte & OUTPUT_BUFFER_FULL)
else
{
i++;
}
}
return STATUS_IO_TIMEOUT;
return STATUS_SUCCESS;
}
/**
* Send a command or data byte to the controller, keyboard or mouse.
*/
static NTSTATUS PutBytePoll(CCHAR PortType, BOOLEAN fWaitForAck, int AckDevType, PDEVEXT pDevExt, UCHAR Byte)
{
if (AckDevType == MouDevType)
{
/* switch to AUX device */
}
{
unsigned i = 0;
return STATUS_IO_TIMEOUT;
else
if (!fWaitForAck)
return STATUS_SUCCESS;
{
if (byte == ACKNOWLEDGE)
break;
{
if (AckDevType == MouDevType)
fKeepTrying = TRUE;
break;
}
}
if (!fKeepTrying)
return status;
}
return STATUS_IO_TIMEOUT;
}
/**
* Read a byte from controller, keyboard or mouse
*/
{
ULONG i = 0;
: (UCHAR) OUTPUT_BUFFER_FULL;
{
if (byte & OUTPUT_BUFFER_FULL)
else
i++;
}
return;
}
/**
* Send a command or data byte to the controller, keyboard or mouse
* asynchronously.
*/
{
unsigned i = 0;
return;
else
}
/**
* Initiaze an I/O operation for the keyboard device.
*/
{
else
}
{
return TRUE;
}
{
(*(pTmCtx->TimerCounter))--;
if (*(pTmCtx->TimerCounter) == 0)
{
}
return TRUE;
}
/**
* Perform an operation on the InterlockedDpcVariable.
*/
{
{
case IncrementOperation:
(*pOpCtx->VariableAddress)++;
break;
case DecrementOperation:
(*pOpCtx->VariableAddress)--;
break;
case WriteOperation:
break;
default:
break;
}
return TRUE;
}
{
if (DevType == KbdDevType)
{
}
else if (DevType == MouDevType)
{
}
else
return TRUE;
}
{
if (DevType == KbdDevType)
{
}
else if (DevType == MouDevType)
{
}
else
return TRUE;
}
{
if (DevType == KbdDevType)
{
}
else if (DevType == MouDevType)
{
}
else
return TRUE;
}
/**
* DISPATCH_LEVEL IRQL: Complete requests.
*/
{
{
break;
break;
default:
break;
}
}
{
return STATUS_NOT_IMPLEMENTED;
}
/**
* Dispatch internal device control requests.
*/
{
{
{
break;
}
{
break;
}
{
break;
}
pDevExt->KbdExt.ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
break;
{
break;
}
{
break;
}
{
break;
}
pDevExt->MouExt.ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
break;
break;
break;
else
{
}
break;
cbTrans = sizeof(KEYBOARD_INDICATOR_TRANSLATION)
else
{
}
break;
else
{
}
break;
else
break;
else
{
}
break;
else
break;
else
{
}
break;
default:
break;
}
if (status == STATUS_PENDING)
{
}
else
return status;
}
/**
*/
{
return STATUS_SUCCESS;
}
/**
* DISPATCH_LEVEL IRQL: Complete requests that have exceeded the maximum
* number of retries.
*/
{
}
static UCHAR TypematicPeriod[] =
{
31, 31, 28, 26, 23, 20, 18, 17, 15, 13, 12, 11, 10, 9,
9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1
};
/**
* - bit 7 is zero
* - bits 5...6 indicate the delay
* - bits 0...4 indicate the rate
*/
{
value <<= 5;
if (Rate <= 27)
return value;
}
/**
* Start an I/O operation for the device.
*/
{
{
break;
if (pDevExt->KeyboardEnableCount == 0)
else
{
}
break;
break;
if (pDevExt->MouseEnableCount == 0)
else
{
}
break;
break;
break;
default:
break;
}
}
/**
* Driver's command timeout routine.
*/
static VOID CtrlTimeoutDpc(PKDPC Dpc, PDEVICE_OBJECT pDevObj, PVOID SystemContext1, PVOID SystemContext2)
{
if (!irp)
{
return;
}
if (timerContext.NewTimerCount == 0)
{
}
else
{
}
}
/**
* DISPATCH_LEVEL IRQL: Finish processing for keyboard interrupts.
*/
{
while (fContinue)
{
ULONG cbNotConsumed = 0;
ULONG inputDataConsumed = 0;
{
{
/ sizeof(KEYBOARD_INPUT_DATA)) - inputDataConsumed;
if (cbNotConsumed)
{
+ (inputDataConsumed * sizeof(KEYBOARD_INPUT_DATA));
}
else
{
}
}
if ( cbNotConsumed == 0
{
/ sizeof(KEYBOARD_INPUT_DATA)) - inputDataConsumed;
(inputDataConsumed * sizeof(KEYBOARD_INPUT_DATA));
}
}
if (cbNotConsumed)
{
interlockedResult = -1;
}
else
{
if (interlockedResult != -1)
{
interlockedResult = 0;
}
else
}
}
}
/**
* DISPATCH_LEVEL IRQL: Finish processing of mouse interrupts
*/
{
while (fContinue)
{
ULONG cbNotConsumed = 0;
ULONG inputDataConsumed = 0;
{
{
/ sizeof(MOUSE_INPUT_DATA)) - inputDataConsumed;
if (cbNotConsumed)
{
}
else
{
}
}
if ( cbNotConsumed == 0
{
/ sizeof(MOUSE_INPUT_DATA)) - inputDataConsumed;
}
}
if (cbNotConsumed)
{
interlockedResult = -1;
}
else
{
if (interlockedResult != -1)
{
interlockedResult = 0;
}
else
}
}
}
/**
* Interrupt service routine for the mouse device.
*/
{
if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
{
if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
return FALSE;
}
&& byte == 0x00)
{
}
{
case MouseIdle:
{
break;
}
case XMovement:
{
{
if (uPrevSignAndOverflow & X_OVERFLOW)
{
}
else
}
else
{
}
break;
}
case YMovement:
{
{
if (uPrevSignAndOverflow & Y_OVERFLOW)
{
}
else
}
else
{
}
else
{
{
if (pReq)
{
if (RT_SUCCESS(rc))
{
{
/* make it an absolute move */
}
}
else
}
}
}
break;
}
case ZMovement:
{
#if 0
#else
if (byte)
#endif
{
if (byte & 0x80)
else
}
{
if (pReq)
{
if (RT_SUCCESS(rc))
{
{
/* make it an absolute move */
}
}
else
}
}
break;
}
case MouseExpectingACK:
{
if (byte == ACKNOWLEDGE)
{
}
break;
}
default:
{
break;
}
}
return TRUE;
}
/**
* Interrupt service routine.
*/
{
if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
{
{
if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
== (OUTPUT_BUFFER_FULL))
break;
}
if ((I8X_GET_STATUS_BYTE(pDevExt->DevRegs[i8042Cmd]) & (OUTPUT_BUFFER_FULL|MOUSE_OUTPUT_BUFFER_FULL))
!= (OUTPUT_BUFFER_FULL))
{
if (pDevExt->KeyboardEnableCount == 0)
return FALSE;
}
}
switch (scanCode)
{
case RESEND:
if (pDevExt->TimerCount == 0)
break;
|| !pDevObj->CurrentIrp)
goto ScanCodeCase;
{
}
else
{
}
break;
case ACKNOWLEDGE:
if (pDevExt->TimerCount == 0)
break;
{
}
{
}
break;
default:
{
{
*pScanState = Normal;
}
else
{
switch (*pScanState)
{
case Normal:
{
*pScanState = GotE0;
break;
}
{
*pScanState = GotE1;
break;
}
/* fall through */
case GotE0:
case GotE1:
if (scanCode > 0x7F)
{
}
else
*pScanState = Normal;
break;
default:
break;
}
}
if (*pScanState == Normal)
{
if (pDevExt->KeyboardEnableCount)
{
{
}
else if (pDevExt->DpcInterlockKeyboard >= 0)
else
}
}
break;
}
}
return TRUE;
}
{
return status;
}
/**
* Configuration information for the keyboard.
*/
{
for (unsigned i = 0; i < MaximumInterfaceType; i++)
{
KbdCallOut, pInit);
{
if (!ENHANCED_KEYBOARD(*keyboardId))
break;
}
}
}
/**
* Retrieve the configuration information for the mouse.
*/
{
for (unsigned i = 0; i < MaximumInterfaceType; i++)
{
interfaceType = (INTERFACE_TYPE)i;
MouCallOut, pInit);
{
break;
}
}
}
/**
* Initialize the driver.
*/
{
#define NAME_MAX 256
LogFlow(("VBoxMouseNT::DriverEntry: enter\n"));
if (!pInit)
{
goto fail;
}
KbdNameFull.MaximumLength = 0;
KbdNameFull.Length = 0;
MouNameFull.MaximumLength = 0;
MouNameFull.Length = 0;
DevNameSuff.MaximumLength = 0;
DevNameSuff.Length = 0;
KbdNameBase.Length = 0;
MouNameBase.Length = 0;
registryPath.Buffer = (PWSTR)ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(UNICODE_NULL));
if (!registryPath.Buffer)
{
goto fail;
}
else
{
}
{
goto fail;
}
? KEYBOARD_PORTS_MAXIMUM * sizeof(WCHAR)
: POINTER_PORTS_MAXIMUM * sizeof(WCHAR);
if (!DevNameSuff.Buffer)
{
goto fail;
}
if (!KbdNameFull.Buffer)
{
goto fail;
}
for (unsigned i = 0; i < KEYBOARD_PORTS_MAXIMUM; i++)
{
if (!NT_SUCCESS(status))
break;
if (NT_SUCCESS(status))
break;
else
}
if (!NT_SUCCESS(status))
goto fail;
ULONG resourceListSize = 0;
if (!resourceDeviceClass.Buffer)
{
goto fail;
}
if (fConflict)
{
goto fail;
}
{
&addressSpace, &Phys))
{
addressSpace = 1;
}
if (!addressSpace)
{
}
else
{
}
{
goto fail;
}
}
{
{
goto fail;
}
(PKEYBOARD_INPUT_DATA)((PCHAR) (pDevExt->KbdExt.InputData) + pDevExt->Cfg.KbdAttr.InputDataQueueLength);
}
{
if (!MouNameFull.Buffer)
{
goto fail;
}
DevNameSuff.Length = 0;
for (unsigned i = 0; i < POINTER_PORTS_MAXIMUM; i++)
{
if (!NT_SUCCESS(status))
break;
LogFlow(("VBoxMouseNT::DriverEntry: pointer port name (symbolic link) = %S\n", MouNameFull.Buffer));
if (NT_SUCCESS(status))
break;
else
}
if (!NT_SUCCESS(status))
goto fail;
{
goto fail;
}
pDevExt->MouExt.DataEnd = (PMOUSE_INPUT_DATA)((PCHAR) (pDevExt->MouExt.InputData) + pDevExt->Cfg.MouAttr.InputDataQueueLength);
}
KeInitializeDpc(&pDevExt->RetriesExceededDpc, (PKDEFERRED_ROUTINE)CtrlRetriesExceededDpc, pPortDevObj);
{
? Latched : LevelSensitive,
if (!NT_SUCCESS(status))
goto fail;
if (!NT_SUCCESS(status))
}
{
? Latched : LevelSensitive,
if (!NT_SUCCESS(status))
goto fail;
}
{
if (!NT_SUCCESS(status))
goto fail;
}
{
if (!NT_SUCCESS(status))
goto fail;
}
if (RT_FAILURE(rcVBox))
{
/* Continue working in non-VBox mode. */
}
else
{
rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&pReq, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
if (RT_SUCCESS(rcVBox))
{
/* Inform host that we support absolute */
pReq->pointerXPos = 0;
pReq->pointerYPos = 0;
if (RT_FAILURE(rcVBox))
Log(("VBoxMouseNT::DriverEntry: ERROR communicating new mouse capabilities to VMMDev. rc = %Rrc\n", rcVBox));
else
{
/* We will use the allocated request buffer in the ServiceCallback to GET mouse status. */
}
}
else
{
/* Continue working in non-VBox mode. */
}
}
fail:
if (!NT_SUCCESS(status))
{
if (resources)
{
}
if (pDevExt)
{
if (pDevExt->fUnmapRegs)
{
}
}
if (pPortDevObj)
{
if (MouNameFull.Length > 0)
}
}
if (resources)
if (pInit)
if (DevNameSuff.MaximumLength)
if (KbdNameFull.MaximumLength)
if (MouNameFull.MaximumLength)
return status;
}
{
}
/**
* Build a resource list.
*/
{
cPorts++;
cPorts++;
if (!*pResList)
{
*pResListSize = 0;
return;
}
ULONG i = 0;
}
/**
* Read the i8042 controller command byte
*/
{
{
if (!NT_SUCCESS(status))
return status;
}
{
if (!NT_SUCCESS(status))
{
return status;
}
}
status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_READ_CONTROLLER_COMMAND_BYTE);
if (NT_SUCCESS(status))
{
{
if (NT_SUCCESS(status))
break;
if (status == STATUS_IO_TIMEOUT)
else
break;
}
}
{
if (!NT_SUCCESS(status2))
{
if (NT_SUCCESS(status))
}
else if (status == STATUS_SUCCESS)
}
{
if (!NT_SUCCESS(status2))
{
if (NT_SUCCESS(status))
}
else if (NT_SUCCESS(status))
}
return status;
}
/**
* Write the i8042 controller command byte.
*/
{
status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_WRITE_CONTROLLER_COMMAND_BYTE);
if (!NT_SUCCESS(status))
return status;
}
/**
* Read the i8042 controller command byte.
*/
{
return;
else
}
/**
* Detect the number of mouse buttons.
*/
{
if (!NT_SUCCESS(status))
return status;
if (!NT_SUCCESS(status))
return status;
for (unsigned i = 0; i < 3; i++)
{
if (!NT_SUCCESS(status))
return status;
}
if (!NT_SUCCESS(status))
return status;
if (!NT_SUCCESS(status))
return status;
if (!NT_SUCCESS(status))
return status;
if (!NT_SUCCESS(status))
return status;
*pNumButtons = buttons;
else
*pNumButtons = 0;
return status;
}
/**
* Initialize the i8042 mouse hardware.
*/
{
if (!NT_SUCCESS(status))
goto fail;
for (unsigned i = 0; i < 11200; i++)
{
break;
if (status != STATUS_IO_TIMEOUT)
break;
}
if (!NT_SUCCESS(status))
goto fail;
goto fail;
if (!NT_SUCCESS(status))
goto fail;
else if (numButtons)
if (!NT_SUCCESS(status))
goto fail;
if (!NT_SUCCESS(status))
goto fail;
if (!NT_SUCCESS(status))
goto fail;
status = PutBytePoll(i8042Dat, TRUE /*=wait*/, MouDevType, pDevExt, (UCHAR)pDevExt->Cfg.MouseResolution);
fail:
return status;
}
/**
* Initialize the i8042 keyboard hardware.
*/
{
for (unsigned i = 0; i < 11200; i++)
{
if (NT_SUCCESS(status))
break;
else
{
if (status == STATUS_IO_TIMEOUT)
{
break;
}
else
break;
}
}
if (!NT_SUCCESS(status))
{
if (fWaitForAck)
{
fWaitForAck = FALSE;
goto retry;
}
goto fail;
}
Ctx.HwDisEnMask = 0;
{
goto fail;
}
if (status == STATUS_SUCCESS)
{
/* ignore errors */
}
if (status == STATUS_SUCCESS)
{
/* ignore errors */
}
{
Ctx.HwDisEnMask = 0;
{
{
if (ENHANCED_KEYBOARD(*pId))
{
if (!NT_SUCCESS(status))
else
{
if (!NT_SUCCESS(status))
}
}
}
else
{
goto fail;
}
}
}
fail:
return status;
}
/**
* Initialize the i8042 controller, keyboard and mouse.
*/
{
Ctx.HwDisEnMask = 0;
return;
{
if (!NT_SUCCESS(status))
}
{
if (!NT_SUCCESS(status))
}
{
NTSTATUS status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_KEYBOARD_DEVICE);
if (!NT_SUCCESS(status))
}
{
NTSTATUS status = PutBytePoll(i8042Cmd, FALSE /*=wait*/, NoDevice, pDevExt, I8042_ENABLE_MOUSE_DEVICE);
if (!NT_SUCCESS(status))
}
if (pDevExt->HardwarePresent)
{
{
/* ignore */
}
}
}
/**
* retrieve the drivers service parameters from the registry
*/
{
ULONG pollingIterations = 0;
ULONG invalidKeyboardType = 0;
if (NT_SUCCESS(status))
{
if (!aQuery)
else
{
if (!parametersPath.Buffer)
}
}
if (NT_SUCCESS(status))
{
}
if (!NT_SUCCESS(status))
{
/* driver defaults */
}
else
{
}
{
}
if (parametersPath.Buffer)
if (aQuery)
}
{
return;
}
{
if (DataLength)
return DataLength;
}
/**
* Callout routine. Grab keyboard controller and peripheral configuration
* information.
*/
{
|| !unicodeIdentifier.Length)
return STATUS_SUCCESS;
{
{
{
{
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
break;
}
default:
break;
}
}
}
{
}
if (BusType == MicroChannel)
{
fDefIntShare = TRUE;
}
else
{
}
{
{
{
case CmResourceTypePort:
break;
case CmResourceTypeInterrupt:
break;
break;
default:
break;
}
}
}
{
}
{
}
{
}
else
{
{
}
}
return STATUS_SUCCESS;
}
/**
* Callout routine. Grab the pointer controller and the peripheral
* configuration information.
*/
{
|| unicodeIdentifier.Length == 0)
return status;
if (!NT_SUCCESS(status))
return status;
return status;
{
}
{
fDefIntShare = TRUE;
}
else
{
}
{
{
{
case CmResourceTypePort:
if (fPortInfoNeeded)
{
}
break;
case CmResourceTypeInterrupt:
break;
default:
break;
}
}
}
{
}
{
}
{
}
else
{
{
}
}
return status;
}
static const UCHAR s_ucCommands[] =
{
SET_MOUSE_SAMPLING_RATE, 200,
SET_MOUSE_SAMPLING_RATE, 100,
};
{
return STATUS_NO_SUCH_DEVICE;
{
if (!NT_SUCCESS(status))
goto fail;
iCmd++;
}
for (unsigned i = 0; i < 5; i++)
{
if (status != STATUS_IO_TIMEOUT)
break;
}
if ( NT_SUCCESS(status)
{
if (byte == WHEELMOUSE_ID_BYTE)
{
}
else
}
fail:
return status;
}