Revert r39517, as there is no reason for such a change: files are consistently formatted, don't belong to ntoskrnl, use tabs only for indenting and not for formatting, and formatting revisions complicate svn blame feature usage.

svn path=/trunk/; revision=39553
This commit is contained in:
Hervé Poussineau 2009-02-11 17:21:10 +00:00
parent b4f50046ff
commit 0560eef6ec
11 changed files with 3380 additions and 3295 deletions

View file

@ -13,37 +13,40 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS NTAPI NTSTATUS NTAPI
i8042Create(IN PDEVICE_OBJECT DeviceObject, i8042Create(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
TRACE_(I8042PRT, "IRP_MJ_CREATE\n"); TRACE_(I8042PRT, "IRP_MJ_CREATE\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTAPI NTSTATUS NTAPI
i8042Cleanup(IN PDEVICE_OBJECT DeviceObject, i8042Cleanup(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
TRACE_(I8042PRT, "IRP_MJ_CLEANUP\n"); TRACE_(I8042PRT, "IRP_MJ_CLEANUP\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTAPI NTSTATUS NTAPI
i8042Close(IN PDEVICE_OBJECT DeviceObject, i8042Close(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
TRACE_(I8042PRT, "IRP_MJ_CLOSE\n"); TRACE_(I8042PRT, "IRP_MJ_CLOSE\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -23,506 +23,516 @@ static DRIVER_DISPATCH i8042InternalDeviceControl;
DRIVER_INITIALIZE DriverEntry; DRIVER_INITIALIZE DriverEntry;
NTSTATUS NTAPI NTSTATUS NTAPI
i8042AddDevice(IN PDRIVER_OBJECT DriverObject, i8042AddDevice(
IN PDEVICE_OBJECT Pdo) IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo)
{ {
PI8042_DRIVER_EXTENSION DriverExtension; PI8042_DRIVER_EXTENSION DriverExtension;
PFDO_DEVICE_EXTENSION DeviceExtension = NULL; PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
PDEVICE_OBJECT Fdo = NULL; PDEVICE_OBJECT Fdo = NULL;
ULONG DeviceExtensionSize; ULONG DeviceExtensionSize;
NTSTATUS Status; NTSTATUS Status;
TRACE_(I8042PRT, "i8042AddDevice(%p %p)\n", DriverObject, Pdo); TRACE_(I8042PRT, "i8042AddDevice(%p %p)\n", DriverObject, Pdo);
DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject); DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject);
if (Pdo == NULL) if (Pdo == NULL)
{ {
/* We're getting a NULL Pdo at the first call as /* We're getting a NULL Pdo at the first call as
* we are a legacy driver. Ignore it */ * we are a legacy driver. Ignore it */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* Create new device object. As we don't know if the device would be a keyboard /* Create new device object. As we don't know if the device would be a keyboard
* or a mouse, we have to allocate the biggest device extension. */ * or a mouse, we have to allocate the biggest device extension. */
DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION)); DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION));
Status = IoCreateDevice( Status = IoCreateDevice(
DriverObject, DriverObject,
DeviceExtensionSize, DeviceExtensionSize,
NULL, NULL,
Pdo->DeviceType, Pdo->DeviceType,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
TRUE, TRUE,
&Fdo); &Fdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, DeviceExtensionSize); RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
DeviceExtension->Type = Unknown; DeviceExtension->Type = Unknown;
DeviceExtension->Fdo = Fdo; DeviceExtension->Fdo = Fdo;
DeviceExtension->Pdo = Pdo; DeviceExtension->Pdo = Pdo;
DeviceExtension->PortDeviceExtension = &DriverExtension->Port; DeviceExtension->PortDeviceExtension = &DriverExtension->Port;
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
ExInterlockedInsertTailList( ExInterlockedInsertTailList(
&DriverExtension->DeviceListHead, &DriverExtension->DeviceListHead,
&DeviceExtension->ListEntry, &DeviceExtension->ListEntry,
&DriverExtension->DeviceListLock); &DriverExtension->DeviceListLock);
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; return STATUS_SUCCESS;
cleanup: cleanup:
if (DeviceExtension && DeviceExtension->LowerDevice) if (DeviceExtension && DeviceExtension->LowerDevice)
IoDetachDevice(DeviceExtension->LowerDevice); IoDetachDevice(DeviceExtension->LowerDevice);
if (Fdo) if (Fdo)
IoDeleteDevice(Fdo); IoDeleteDevice(Fdo);
return Status; return Status;
} }
VOID NTAPI VOID NTAPI
i8042SendHookWorkItem(IN PDEVICE_OBJECT DeviceObject, i8042SendHookWorkItem(
IN PVOID Context) IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{ {
PI8042_HOOK_WORKITEM WorkItemData; PI8042_HOOK_WORKITEM WorkItemData;
PFDO_DEVICE_EXTENSION FdoDeviceExtension; PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPORT_DEVICE_EXTENSION PortDeviceExtension; PPORT_DEVICE_EXTENSION PortDeviceExtension;
PDEVICE_OBJECT TopOfStack = NULL; PDEVICE_OBJECT TopOfStack = NULL;
ULONG IoControlCode; ULONG IoControlCode;
PVOID InputBuffer; PVOID InputBuffer;
ULONG InputBufferLength; ULONG InputBufferLength;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KEVENT Event; KEVENT Event;
PIRP NewIrp; PIRP NewIrp;
NTSTATUS Status; NTSTATUS Status;
TRACE_(I8042PRT, "i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context); TRACE_(I8042PRT, "i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context);
WorkItemData = (PI8042_HOOK_WORKITEM)Context; WorkItemData = (PI8042_HOOK_WORKITEM)Context;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension; PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension;
switch (FdoDeviceExtension->Type) switch (FdoDeviceExtension->Type)
{ {
case Keyboard: case Keyboard:
{ {
PI8042_KEYBOARD_EXTENSION DeviceExtension; PI8042_KEYBOARD_EXTENSION DeviceExtension;
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD;
InputBuffer = &DeviceExtension->KeyboardHook; InputBuffer = &DeviceExtension->KeyboardHook;
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD);
break; break;
} }
case Mouse: case Mouse:
{ {
PI8042_MOUSE_EXTENSION DeviceExtension; PI8042_MOUSE_EXTENSION DeviceExtension;
DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension; DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension;
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE;
InputBuffer = &DeviceExtension->MouseHook; InputBuffer = &DeviceExtension->MouseHook;
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE);
break; break;
} }
default: default:
{ {
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type); ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
ASSERT(FALSE); ASSERT(FALSE);
WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
goto cleanup; goto cleanup;
} }
} }
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
TopOfStack = IoGetAttachedDeviceReference(DeviceObject); TopOfStack = IoGetAttachedDeviceReference(DeviceObject);
NewIrp = IoBuildDeviceIoControlRequest( NewIrp = IoBuildDeviceIoControlRequest(
IoControlCode, IoControlCode,
TopOfStack, TopOfStack,
InputBuffer, InputBuffer,
InputBufferLength, InputBufferLength,
NULL, NULL,
0, 0,
TRUE, TRUE,
&Event, &Event,
&IoStatus); &IoStatus);
if (!NewIrp) if (!NewIrp)
{ {
WARN_(I8042PRT, "IoBuildDeviceIoControlRequest() failed\n"); WARN_(I8042PRT, "IoBuildDeviceIoControlRequest() failed\n");
WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup; goto cleanup;
} }
Status = IoCallDriver(TopOfStack, NewIrp); Status = IoCallDriver(TopOfStack, NewIrp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject( KeWaitForSingleObject(
&Event, &Event,
Executive, Executive,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
Status = IoStatus.Status; Status = IoStatus.Status;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
if (FdoDeviceExtension->Type == Keyboard) if (FdoDeviceExtension->Type == Keyboard)
{ {
PI8042_KEYBOARD_EXTENSION DeviceExtension; PI8042_KEYBOARD_EXTENSION DeviceExtension;
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
/* Call the hooked initialization if it exists */ /* Call the hooked initialization if it exists */
if (DeviceExtension->KeyboardHook.InitializationRoutine) if (DeviceExtension->KeyboardHook.InitializationRoutine)
{ {
Status = DeviceExtension->KeyboardHook.InitializationRoutine( Status = DeviceExtension->KeyboardHook.InitializationRoutine(
DeviceExtension->KeyboardHook.Context, DeviceExtension->KeyboardHook.Context,
PortDeviceExtension, PortDeviceExtension,
i8042SynchReadPort, i8042SynchReadPort,
i8042SynchWritePortKbd, i8042SynchWritePortKbd,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status);
WorkItemData->Irp->IoStatus.Status = Status; WorkItemData->Irp->IoStatus.Status = Status;
goto cleanup; goto cleanup;
} }
} }
} }
WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS;
cleanup: cleanup:
if (TopOfStack != NULL) if (TopOfStack != NULL)
ObDereferenceObject(TopOfStack); ObDereferenceObject(TopOfStack);
WorkItemData->Irp->IoStatus.Information = 0; WorkItemData->Irp->IoStatus.Information = 0;
IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT);
IoFreeWorkItem(WorkItemData->WorkItem); IoFreeWorkItem(WorkItemData->WorkItem);
ExFreePoolWithTag(WorkItemData, I8042PRT_TAG); ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
} }
static VOID NTAPI static VOID NTAPI
i8042StartIo(IN PDEVICE_OBJECT DeviceObject, i8042StartIo(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
switch (DeviceExtension->Type) switch (DeviceExtension->Type)
{ {
case Keyboard: case Keyboard:
i8042KbdStartIo(DeviceObject, Irp); i8042KbdStartIo(DeviceObject, Irp);
break; break;
default: default:
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type); ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
ASSERT(FALSE); ASSERT(FALSE);
break; break;
} }
} }
/* Write the current byte of the packet. Returns FALSE in case /* Write the current byte of the packet. Returns FALSE in case
* of problems. * of problems.
*/ */
static BOOLEAN static BOOLEAN
i8042PacketWrite(IN PPORT_DEVICE_EXTENSION DeviceExtension) i8042PacketWrite(
IN PPORT_DEVICE_EXTENSION DeviceExtension)
{ {
UCHAR Port = DeviceExtension->PacketPort; UCHAR Port = DeviceExtension->PacketPort;
if (Port) if (Port)
{ {
if (!i8042Write(DeviceExtension, if (!i8042Write(DeviceExtension,
DeviceExtension->ControlPort, DeviceExtension->ControlPort,
Port)) Port))
{ {
/* something is really wrong! */ /* something is really wrong! */
WARN_(I8042PRT, "Failed to send packet byte!\n"); WARN_(I8042PRT, "Failed to send packet byte!\n");
return FALSE; return FALSE;
} }
} }
return i8042Write(DeviceExtension, return i8042Write(DeviceExtension,
DeviceExtension->DataPort, DeviceExtension->DataPort,
DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]); DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]);
} }
BOOLEAN BOOLEAN
i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042PacketIsr(
IN UCHAR Output) IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR Output)
{ {
if (DeviceExtension->Packet.State == Idle) if (DeviceExtension->Packet.State == Idle)
return FALSE; return FALSE;
switch (Output) switch (Output)
{ {
case KBD_RESEND: case KBD_RESEND:
DeviceExtension->PacketResends++; DeviceExtension->PacketResends++;
if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations) if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations)
{ {
DeviceExtension->Packet.State = Idle; DeviceExtension->Packet.State = Idle;
DeviceExtension->PacketComplete = TRUE; DeviceExtension->PacketComplete = TRUE;
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
DeviceExtension->PacketResends = 0; DeviceExtension->PacketResends = 0;
return TRUE; return TRUE;
} }
DeviceExtension->Packet.CurrentByte--; DeviceExtension->Packet.CurrentByte--;
break; break;
case KBD_NACK: case KBD_NACK:
DeviceExtension->Packet.State = Idle; DeviceExtension->Packet.State = Idle;
DeviceExtension->PacketComplete = TRUE; DeviceExtension->PacketComplete = TRUE;
DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR; DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR;
DeviceExtension->PacketResends = 0; DeviceExtension->PacketResends = 0;
return TRUE; return TRUE;
default: default:
DeviceExtension->PacketResends = 0; DeviceExtension->PacketResends = 0;
} }
if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount) if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount)
{ {
DeviceExtension->Packet.State = Idle; DeviceExtension->Packet.State = Idle;
DeviceExtension->PacketComplete = TRUE; DeviceExtension->PacketComplete = TRUE;
DeviceExtension->PacketResult = STATUS_SUCCESS; DeviceExtension->PacketResult = STATUS_SUCCESS;
return TRUE; return TRUE;
} }
if (!i8042PacketWrite(DeviceExtension)) if (!i8042PacketWrite(DeviceExtension))
{ {
DeviceExtension->Packet.State = Idle; DeviceExtension->Packet.State = Idle;
DeviceExtension->PacketComplete = TRUE; DeviceExtension->PacketComplete = TRUE;
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
return TRUE; return TRUE;
} }
DeviceExtension->Packet.CurrentByte++; DeviceExtension->Packet.CurrentByte++;
return TRUE; return TRUE;
} }
/* /*
* This function starts a packet. It must be called with the * This function starts a packet. It must be called with the
* correct DIRQL. * correct DIRQL.
*/ */
NTSTATUS NTSTATUS
i8042StartPacket(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042StartPacket(
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN PUCHAR Bytes, IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
IN ULONG ByteCount, IN PUCHAR Bytes,
IN PIRP Irp) IN ULONG ByteCount,
IN PIRP Irp)
{ {
KIRQL Irql; KIRQL Irql;
NTSTATUS Status; NTSTATUS Status;
Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
if (DeviceExtension->Packet.State != Idle) if (DeviceExtension->Packet.State != Idle)
{ {
Status = STATUS_DEVICE_BUSY; Status = STATUS_DEVICE_BUSY;
goto done; goto done;
} }
switch (FdoDeviceExtension->Type) switch (FdoDeviceExtension->Type)
{ {
case Keyboard: DeviceExtension->PacketPort = 0; break; case Keyboard: DeviceExtension->PacketPort = 0; break;
case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break; case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break;
default: default:
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type); ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
ASSERT(FALSE); ASSERT(FALSE);
Status = STATUS_INTERNAL_ERROR; Status = STATUS_INTERNAL_ERROR;
goto done; goto done;
} }
DeviceExtension->Packet.Bytes = Bytes; DeviceExtension->Packet.Bytes = Bytes;
DeviceExtension->Packet.CurrentByte = 0; DeviceExtension->Packet.CurrentByte = 0;
DeviceExtension->Packet.ByteCount = ByteCount; DeviceExtension->Packet.ByteCount = ByteCount;
DeviceExtension->Packet.State = SendingBytes; DeviceExtension->Packet.State = SendingBytes;
DeviceExtension->PacketResult = Status = STATUS_PENDING; DeviceExtension->PacketResult = Status = STATUS_PENDING;
DeviceExtension->CurrentIrp = Irp; DeviceExtension->CurrentIrp = Irp;
DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo; DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo;
if (!i8042PacketWrite(DeviceExtension)) if (!i8042PacketWrite(DeviceExtension))
{ {
Status = STATUS_IO_TIMEOUT; Status = STATUS_IO_TIMEOUT;
DeviceExtension->Packet.State = Idle; DeviceExtension->Packet.State = Idle;
DeviceExtension->PacketResult = STATUS_ABANDONED; DeviceExtension->PacketResult = STATUS_ABANDONED;
goto done; goto done;
} }
DeviceExtension->Packet.CurrentByte++; DeviceExtension->Packet.CurrentByte++;
done: done:
KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
DeviceExtension->CurrentIrp = NULL; DeviceExtension->CurrentIrp = NULL;
DeviceExtension->CurrentIrpDevice = NULL; DeviceExtension->CurrentIrpDevice = NULL;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
} }
return Status; return Status;
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
IrpStub(IN PDEVICE_OBJECT DeviceObject, IrpStub(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
NTSTATUS Status = Irp->IoStatus.Status; NTSTATUS Status = Irp->IoStatus.Status;
/* Do nothing */ /* Do nothing */
ASSERT(FALSE); ASSERT(FALSE);
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
i8042DeviceControl(IN PDEVICE_OBJECT DeviceObject, i8042DeviceControl(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
TRACE_(I8042PRT, "i8042DeviceControl(%p %p)\n", DeviceObject, Irp); TRACE_(I8042PRT, "i8042DeviceControl(%p %p)\n", DeviceObject, Irp);
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
switch (DeviceExtension->Type) switch (DeviceExtension->Type)
{ {
case Keyboard: case Keyboard:
return i8042KbdDeviceControl(DeviceObject, Irp); return i8042KbdDeviceControl(DeviceObject, Irp);
break; break;
default: default:
return IrpStub(DeviceObject, Irp); return IrpStub(DeviceObject, Irp);
} }
return Status; return Status;
} }
static NTSTATUS NTAPI static NTSTATUS NTAPI
i8042InternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, i8042InternalDeviceControl(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
ULONG ControlCode; ULONG ControlCode;
NTSTATUS Status; NTSTATUS Status;
TRACE_(I8042PRT, "i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp); TRACE_(I8042PRT, "i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp);
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
switch (DeviceExtension->Type) switch (DeviceExtension->Type)
{ {
case Unknown: case Unknown:
{ {
ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode; ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode;
switch (ControlCode) switch (ControlCode)
{ {
case IOCTL_INTERNAL_KEYBOARD_CONNECT: case IOCTL_INTERNAL_KEYBOARD_CONNECT:
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
break; break;
case IOCTL_INTERNAL_MOUSE_CONNECT: case IOCTL_INTERNAL_MOUSE_CONNECT:
Status = i8042MouInternalDeviceControl(DeviceObject, Irp); Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
break; break;
default: default:
ERR_(I8042PRT, "Unknown IO control code 0x%lx\n", ControlCode); ERR_(I8042PRT, "Unknown IO control code 0x%lx\n", ControlCode);
ASSERT(FALSE); ASSERT(FALSE);
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
break; break;
} }
break; break;
} }
case Keyboard: case Keyboard:
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
break; break;
case Mouse: case Mouse:
Status = i8042MouInternalDeviceControl(DeviceObject, Irp); Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
break; break;
default: default:
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type); ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
ASSERT(FALSE); ASSERT(FALSE);
Status = STATUS_INTERNAL_ERROR; Status = STATUS_INTERNAL_ERROR;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; break;
} }
return Status; return Status;
} }
NTSTATUS NTAPI NTSTATUS NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject, DriverEntry(
IN PUNICODE_STRING RegistryPath) IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ {
PI8042_DRIVER_EXTENSION DriverExtension; PI8042_DRIVER_EXTENSION DriverExtension;
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
/* ROS Hack: ideally, we shouldn't have to initialize debug level this way, /* ROS Hack: ideally, we shouldn't have to initialize debug level this way,
but since the only way is to change it via KDBG, it's better to leave but since the only way is to change it via KDBG, it's better to leave
it here too. */ it here too. */
#if 0 #if 0
DbgSetDebugFilterState( DbgSetDebugFilterState(
DPFLTR_I8042PRT_ID, DPFLTR_I8042PRT_ID,
(1 << DPFLTR_ERROR_LEVEL) | (1 << DPFLTR_WARNING_LEVEL) | (1 << DPFLTR_ERROR_LEVEL) | (1 << DPFLTR_WARNING_LEVEL) |
(1 << DPFLTR_TRACE_LEVEL) /*| (1 << DPFLTR_INFO_LEVEL)*/ | DPFLTR_MASK, (1 << DPFLTR_TRACE_LEVEL) /*| (1 << DPFLTR_INFO_LEVEL)*/ | DPFLTR_MASK,
TRUE); TRUE);
#endif #endif
Status = IoAllocateDriverObjectExtension( Status = IoAllocateDriverObjectExtension(
DriverObject, DriverObject,
DriverObject, DriverObject,
sizeof(I8042_DRIVER_EXTENSION), sizeof(I8042_DRIVER_EXTENSION),
(PVOID*)&DriverExtension); (PVOID*)&DriverExtension);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
return Status; return Status;
} }
RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION)); RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION));
KeInitializeSpinLock(&DriverExtension->Port.SpinLock); KeInitializeSpinLock(&DriverExtension->Port.SpinLock);
InitializeListHead(&DriverExtension->DeviceListHead); InitializeListHead(&DriverExtension->DeviceListHead);
KeInitializeSpinLock(&DriverExtension->DeviceListLock); KeInitializeSpinLock(&DriverExtension->DeviceListLock);
Status = DuplicateUnicodeString( Status = DuplicateUnicodeString(
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
RegistryPath, RegistryPath,
&DriverExtension->RegistryPath); &DriverExtension->RegistryPath);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
return Status; return Status;
} }
Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings); Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "ReadRegistryEntries() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
return Status; return Status;
} }
DriverObject->DriverExtension->AddDevice = i8042AddDevice; DriverObject->DriverExtension->AddDevice = i8042AddDevice;
DriverObject->DriverStartIo = i8042StartIo; DriverObject->DriverStartIo = i8042StartIo;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = IrpStub; DriverObject->MajorFunction[i] = IrpStub;
DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create; DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close; DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp; DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
if (IsFirstStageSetup()) if (IsFirstStageSetup())
return i8042AddLegacyKeyboard(DriverObject, RegistryPath); return i8042AddLegacyKeyboard(DriverObject, RegistryPath);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -11,56 +11,56 @@
#include <debug.h> #include <debug.h>
/*----------------------------------------------------- /*-----------------------------------------------------
* Structures * Structures
* --------------------------------------------------*/ * --------------------------------------------------*/
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
#define I8042PRT_TAG TAG('8', '0', '4', '2') #define I8042PRT_TAG TAG('8', '0', '4', '2')
typedef enum typedef enum
{ {
dsStopped, dsStopped,
dsStarted, dsStarted,
dsPaused, dsPaused,
dsRemoved, dsRemoved,
dsSurpriseRemoved dsSurpriseRemoved
} DEVICE_STATE; } DEVICE_STATE;
typedef struct _I8042_SETTINGS typedef struct _I8042_SETTINGS
{ {
/* Registry settings */ /* Registry settings */
ULONG KeyboardDataQueueSize; /* done */ ULONG KeyboardDataQueueSize; /* done */
UNICODE_STRING KeyboardDeviceBaseName; UNICODE_STRING KeyboardDeviceBaseName;
ULONG MouseDataQueueSize; /* done */ ULONG MouseDataQueueSize; /* done */
ULONG MouseResolution; ULONG MouseResolution;
ULONG MouseSynchIn100ns; ULONG MouseSynchIn100ns;
ULONG NumberOfButtons; ULONG NumberOfButtons;
UNICODE_STRING PointerDeviceBaseName; UNICODE_STRING PointerDeviceBaseName;
ULONG PollStatusIterations; /* done */ ULONG PollStatusIterations; /* done */
ULONG OverrideKeyboardType; ULONG OverrideKeyboardType;
ULONG OverrideKeyboardSubtype; ULONG OverrideKeyboardSubtype;
ULONG PollingIterations; /* done */ ULONG PollingIterations; /* done */
ULONG PollingIterationsMaximum; ULONG PollingIterationsMaximum;
ULONG ResendIterations; /* done */ ULONG ResendIterations; /* done */
ULONG SampleRate; ULONG SampleRate;
ULONG CrashOnCtrlScroll; /* done */ ULONG CrashOnCtrlScroll; /* done */
} I8042_SETTINGS, *PI8042_SETTINGS; } I8042_SETTINGS, *PI8042_SETTINGS;
typedef enum _MOUSE_TIMEOUT_STATE typedef enum _MOUSE_TIMEOUT_STATE
{ {
NoChange, NoChange,
TimeoutStart, TimeoutStart,
TimeoutCancel TimeoutCancel
} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; } MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE;
typedef struct _INTERRUPT_DATA typedef struct _INTERRUPT_DATA
{ {
PKINTERRUPT Object; PKINTERRUPT Object;
ULONG Vector; ULONG Vector;
KIRQL Dirql; KIRQL Dirql;
KINTERRUPT_MODE InterruptMode; KINTERRUPT_MODE InterruptMode;
BOOLEAN ShareInterrupt; BOOLEAN ShareInterrupt;
KAFFINITY Affinity; KAFFINITY Affinity;
} INTERRUPT_DATA, *PINTERRUPT_DATA; } INTERRUPT_DATA, *PINTERRUPT_DATA;
#define WHEEL_DELTA 120 #define WHEEL_DELTA 120
@ -82,135 +82,135 @@ typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION;
typedef struct _PORT_DEVICE_EXTENSION typedef struct _PORT_DEVICE_EXTENSION
{ {
PUCHAR DataPort; /* Usually 0x60 */ PUCHAR DataPort; /* Usually 0x60 */
PUCHAR ControlPort; /* Usually 0x64 */ PUCHAR ControlPort; /* Usually 0x64 */
I8042_SETTINGS Settings; I8042_SETTINGS Settings;
ULONG Flags; ULONG Flags;
PI8042_KEYBOARD_EXTENSION KeyboardExtension; PI8042_KEYBOARD_EXTENSION KeyboardExtension;
INTERRUPT_DATA KeyboardInterrupt; INTERRUPT_DATA KeyboardInterrupt;
PI8042_MOUSE_EXTENSION MouseExtension; PI8042_MOUSE_EXTENSION MouseExtension;
INTERRUPT_DATA MouseInterrupt; INTERRUPT_DATA MouseInterrupt;
PKINTERRUPT HighestDIRQLInterrupt; PKINTERRUPT HighestDIRQLInterrupt;
KSPIN_LOCK SpinLock; KSPIN_LOCK SpinLock;
KIRQL HighestDirql; KIRQL HighestDirql;
OUTPUT_PACKET Packet; OUTPUT_PACKET Packet;
ULONG PacketResends; ULONG PacketResends;
BOOLEAN PacketComplete; BOOLEAN PacketComplete;
NTSTATUS PacketResult; NTSTATUS PacketResult;
UCHAR PacketBuffer[16]; UCHAR PacketBuffer[16];
UCHAR PacketPort; UCHAR PacketPort;
PIRP CurrentIrp; PIRP CurrentIrp;
PDEVICE_OBJECT CurrentIrpDevice; PDEVICE_OBJECT CurrentIrpDevice;
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
typedef struct _I8042_DRIVER_EXTENSION typedef struct _I8042_DRIVER_EXTENSION
{ {
UNICODE_STRING RegistryPath; UNICODE_STRING RegistryPath;
PORT_DEVICE_EXTENSION Port; PORT_DEVICE_EXTENSION Port;
LIST_ENTRY DeviceListHead; LIST_ENTRY DeviceListHead;
KSPIN_LOCK DeviceListLock; KSPIN_LOCK DeviceListLock;
} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION; } I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION;
typedef enum _I8042_DEVICE_TYPE typedef enum _I8042_DEVICE_TYPE
{ {
Unknown, Unknown,
Keyboard, Keyboard,
Mouse, Mouse,
PhysicalDeviceObject PhysicalDeviceObject
} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; } I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE;
typedef struct _FDO_DEVICE_EXTENSION typedef struct _FDO_DEVICE_EXTENSION
{ {
I8042_DEVICE_TYPE Type; I8042_DEVICE_TYPE Type;
// Linkage in I8042_DRIVER_EXTENSION.DeviceListHead // Linkage in I8042_DRIVER_EXTENSION.DeviceListHead
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
// Associated device object (FDO) // Associated device object (FDO)
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo;
// Associated device object (PDO) // Associated device object (PDO)
PDEVICE_OBJECT Pdo; PDEVICE_OBJECT Pdo;
// Lower device object // Lower device object
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
// Current state of the driver // Current state of the driver
DEVICE_STATE PnpState; DEVICE_STATE PnpState;
PPORT_DEVICE_EXTENSION PortDeviceExtension; PPORT_DEVICE_EXTENSION PortDeviceExtension;
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
typedef struct _I8042_KEYBOARD_EXTENSION typedef struct _I8042_KEYBOARD_EXTENSION
{ {
FDO_DEVICE_EXTENSION Common; FDO_DEVICE_EXTENSION Common;
CONNECT_DATA KeyboardData; CONNECT_DATA KeyboardData;
INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */ INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */
KDPC DpcKeyboard; KDPC DpcKeyboard;
KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators;
KEYBOARD_SCAN_STATE KeyboardScanState; KEYBOARD_SCAN_STATE KeyboardScanState;
BOOLEAN KeyComplete; BOOLEAN KeyComplete;
PKEYBOARD_INPUT_DATA KeyboardBuffer; PKEYBOARD_INPUT_DATA KeyboardBuffer;
ULONG KeysInBuffer; ULONG KeysInBuffer;
/* Power keys items */ /* Power keys items */
ULONG ReportedCaps; ULONG ReportedCaps;
ULONG NewCaps; ULONG NewCaps;
ULONG LastPowerKey; ULONG LastPowerKey;
UNICODE_STRING PowerInterfaceName; UNICODE_STRING PowerInterfaceName;
PIO_WORKITEM PowerWorkItem; PIO_WORKITEM PowerWorkItem;
PIRP PowerIrp; PIRP PowerIrp;
/* Debug items */ /* Debug items */
ULONG ComboPosition; ULONG ComboPosition;
PIO_WORKITEM DebugWorkItem; PIO_WORKITEM DebugWorkItem;
BOOLEAN TabPressed; BOOLEAN TabPressed;
} I8042_KEYBOARD_EXTENSION; } I8042_KEYBOARD_EXTENSION;
typedef enum _I8042_MOUSE_TYPE typedef enum _I8042_MOUSE_TYPE
{ {
GenericPS2, GenericPS2,
Intellimouse, Intellimouse,
IntellimouseExplorer, IntellimouseExplorer,
Ps2pp Ps2pp
} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; } I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE;
typedef struct _I8042_MOUSE_EXTENSION typedef struct _I8042_MOUSE_EXTENSION
{ {
FDO_DEVICE_EXTENSION Common; FDO_DEVICE_EXTENSION Common;
CONNECT_DATA MouseData; CONNECT_DATA MouseData;
INTERNAL_I8042_HOOK_MOUSE MouseHook; INTERNAL_I8042_HOOK_MOUSE MouseHook;
KDPC DpcMouse; KDPC DpcMouse;
MOUSE_ATTRIBUTES MouseAttributes; MOUSE_ATTRIBUTES MouseAttributes;
MOUSE_STATE MouseState; MOUSE_STATE MouseState;
BOOLEAN MouseComplete; BOOLEAN MouseComplete;
MOUSE_RESET_SUBSTATE MouseResetState; MOUSE_RESET_SUBSTATE MouseResetState;
PMOUSE_INPUT_DATA MouseBuffer; PMOUSE_INPUT_DATA MouseBuffer;
ULONG MouseInBuffer; ULONG MouseInBuffer;
USHORT MouseButtonState; USHORT MouseButtonState;
ULARGE_INTEGER MousePacketStartTime; ULARGE_INTEGER MousePacketStartTime;
KTIMER TimerMouseTimeout; KTIMER TimerMouseTimeout;
KDPC DpcMouseTimeout; KDPC DpcMouseTimeout;
MOUSE_TIMEOUT_STATE MouseTimeoutState; MOUSE_TIMEOUT_STATE MouseTimeoutState;
BOOLEAN MouseTimeoutActive; BOOLEAN MouseTimeoutActive;
UCHAR MouseLogiBuffer[3]; UCHAR MouseLogiBuffer[3];
I8042_MOUSE_TYPE MouseType; I8042_MOUSE_TYPE MouseType;
} I8042_MOUSE_EXTENSION; } I8042_MOUSE_EXTENSION;
typedef struct _I8042_HOOK_WORKITEM typedef struct _I8042_HOOK_WORKITEM
{ {
PIO_WORKITEM WorkItem; PIO_WORKITEM WorkItem;
PIRP Irp; PIRP Irp;
} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; } I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM;
/*----------------------------------------------------- /*-----------------------------------------------------
* Some defines * Some defines
* --------------------------------------------------*/ * --------------------------------------------------*/
#define MAX(a, b) ((a) >= (b) ? (a) : (b)) #define MAX(a, b) ((a) >= (b) ? (a) : (b))
@ -219,8 +219,8 @@ typedef struct _I8042_HOOK_WORKITEM
#define KEYBOARD_WAKE_CODE 0x63 #define KEYBOARD_WAKE_CODE 0x63
/*----------------------------------------------------- /*-----------------------------------------------------
* Controller commands * Controller commands
* --------------------------------------------------*/ * --------------------------------------------------*/
#define KBD_READ_MODE 0x20 #define KBD_READ_MODE 0x20
#define KBD_WRITE_MODE 0x60 #define KBD_WRITE_MODE 0x60
@ -230,15 +230,15 @@ typedef struct _I8042_HOOK_WORKITEM
#define CTRL_WRITE_MOUSE 0xD4 #define CTRL_WRITE_MOUSE 0xD4
/*----------------------------------------------------- /*-----------------------------------------------------
* Keyboard commands * Keyboard commands
* --------------------------------------------------*/ * --------------------------------------------------*/
#define KBD_CMD_SET_LEDS 0xED #define KBD_CMD_SET_LEDS 0xED
#define KBD_CMD_GET_ID 0xF2 #define KBD_CMD_GET_ID 0xF2
/*----------------------------------------------------- /*-----------------------------------------------------
* Keyboard responses * Keyboard responses
* --------------------------------------------------*/ * --------------------------------------------------*/
#define KBD_SELF_TEST_OK 0x55 #define KBD_SELF_TEST_OK 0x55
#define KBD_ACK 0xFA #define KBD_ACK 0xFA
@ -246,8 +246,8 @@ typedef struct _I8042_HOOK_WORKITEM
#define KBD_RESEND 0xFE #define KBD_RESEND 0xFE
/*----------------------------------------------------- /*-----------------------------------------------------
* Controller status register bits * Controller status register bits
* --------------------------------------------------*/ * --------------------------------------------------*/
#define KBD_OBF 0x01 #define KBD_OBF 0x01
#define KBD_IBF 0x02 #define KBD_IBF 0x02
@ -255,8 +255,8 @@ typedef struct _I8042_HOOK_WORKITEM
#define KBD_PERR 0x80 #define KBD_PERR 0x80
/*----------------------------------------------------- /*-----------------------------------------------------
* Controller command byte bits * Controller command byte bits
* --------------------------------------------------*/ * --------------------------------------------------*/
#define CCB_KBD_INT_ENAB 0x01 #define CCB_KBD_INT_ENAB 0x01
#define CCB_MOUSE_INT_ENAB 0x02 #define CCB_MOUSE_INT_ENAB 0x02
@ -266,31 +266,31 @@ typedef struct _I8042_HOOK_WORKITEM
#define CCB_TRANSLATE 0x40 #define CCB_TRANSLATE 0x40
/*----------------------------------------------------- /*-----------------------------------------------------
* LED bits * LED bits
* --------------------------------------------------*/ * --------------------------------------------------*/
#define KBD_LED_SCROLL 0x01 #define KBD_LED_SCROLL 0x01
#define KBD_LED_NUM 0x02 #define KBD_LED_NUM 0x02
#define KBD_LED_CAPS 0x04 #define KBD_LED_CAPS 0x04
/*----------------------------------------------------- /*-----------------------------------------------------
* Mouse commands * Mouse commands
* --------------------------------------------------*/ * --------------------------------------------------*/
#define MOU_ENAB 0xF4 #define MOU_ENAB 0xF4
#define MOU_CMD_RESET 0xFF #define MOU_CMD_RESET 0xFF
/*----------------------------------------------------- /*-----------------------------------------------------
* Mouse responses * Mouse responses
* --------------------------------------------------*/ * --------------------------------------------------*/
#define MOUSE_ACK 0xFA #define MOUSE_ACK 0xFA
#define MOUSE_ERROR 0xFC #define MOUSE_ERROR 0xFC
#define MOUSE_NACK 0xFE #define MOUSE_NACK 0xFE
/*----------------------------------------------------- /*-----------------------------------------------------
* Prototypes * Prototypes
* --------------------------------------------------*/ * --------------------------------------------------*/
/* createclose.c */ /* createclose.c */
@ -305,9 +305,10 @@ DRIVER_DISPATCH i8042Close;
/* keyboard.c */ /* keyboard.c */
NTSTATUS NTAPI NTSTATUS NTAPI
i8042SynchWritePortKbd(IN PVOID Context, i8042SynchWritePortKbd(
IN UCHAR Value, IN PVOID Context,
IN BOOLEAN WaitForAck); IN UCHAR Value,
IN BOOLEAN WaitForAck);
DRIVER_STARTIO i8042KbdStartIo; DRIVER_STARTIO i8042KbdStartIo;
@ -322,15 +323,17 @@ KSERVICE_ROUTINE i8042KbdInterruptService;
DRIVER_ADD_DEVICE i8042AddDevice; DRIVER_ADD_DEVICE i8042AddDevice;
BOOLEAN BOOLEAN
i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042PacketIsr(
IN UCHAR Output); IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR Output);
NTSTATUS NTSTATUS
i8042StartPacket(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042StartPacket(
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN PUCHAR Bytes, IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
IN ULONG ByteCount, IN PUCHAR Bytes,
IN PIRP Irp); IN ULONG ByteCount,
IN PIRP Irp);
/* misc.c */ /* misc.c */
@ -339,22 +342,26 @@ DRIVER_DISPATCH ForwardIrpAndForget;
DRIVER_DISPATCH ForwardIrpAndWait; DRIVER_DISPATCH ForwardIrpAndWait;
NTSTATUS NTSTATUS
DuplicateUnicodeString(IN ULONG Flags, DuplicateUnicodeString(
IN PCUNICODE_STRING SourceString, IN ULONG Flags,
OUT PUNICODE_STRING DestinationString); IN PCUNICODE_STRING SourceString,
OUT PUNICODE_STRING DestinationString);
/* mouse.c */ /* mouse.c */
VOID VOID
i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension, i8042MouHandle(
IN UCHAR Output); IN PI8042_MOUSE_EXTENSION DeviceExtension,
IN UCHAR Output);
VOID VOID
i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, i8042MouHandleButtons(
IN USHORT Mask); IN PI8042_MOUSE_EXTENSION DeviceExtension,
IN USHORT Mask);
NTSTATUS NTSTATUS
i8042MouInitialize(IN PI8042_MOUSE_EXTENSION DeviceExtension); i8042MouInitialize(
IN PI8042_MOUSE_EXTENSION DeviceExtension);
DRIVER_DISPATCH i8042MouInternalDeviceControl; DRIVER_DISPATCH i8042MouInternalDeviceControl;
@ -363,73 +370,86 @@ KSERVICE_ROUTINE i8042MouInterruptService;
/* pnp.c */ /* pnp.c */
BOOLEAN BOOLEAN
i8042ChangeMode(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ChangeMode(
IN UCHAR FlagsToDisable, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR FlagsToEnable); IN UCHAR FlagsToDisable,
IN UCHAR FlagsToEnable);
DRIVER_DISPATCH i8042Pnp; DRIVER_DISPATCH i8042Pnp;
/* ps2pp.c */ /* ps2pp.c */
VOID VOID
i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, i8042MouHandlePs2pp(
IN UCHAR Input); IN PI8042_MOUSE_EXTENSION DeviceExtension,
IN UCHAR Input);
/* readwrite.c */ /* readwrite.c */
VOID VOID
i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension); i8042Flush(
IN PPORT_DEVICE_EXTENSION DeviceExtension);
BOOLEAN BOOLEAN
i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042IsrWritePort(
IN UCHAR Value, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR SelectCmd OPTIONAL); IN UCHAR Value,
IN UCHAR SelectCmd OPTIONAL);
NTSTATUS NTSTATUS
i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadData(
IN UCHAR StatusFlags, IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Data); IN UCHAR StatusFlags,
OUT PUCHAR Data);
#define i8042ReadKeyboardData(DeviceExtension, Data) \ #define i8042ReadKeyboardData(DeviceExtension, Data) \
i8042ReadData(DeviceExtension, KBD_OBF, Data) i8042ReadData(DeviceExtension, KBD_OBF, Data)
#define i8042ReadMouseData(DeviceExtension, Data) \ #define i8042ReadMouseData(DeviceExtension, Data) \
i8042ReadData(DeviceExtension, MOU_OBF, Data) i8042ReadData(DeviceExtension, MOU_OBF, Data)
NTSTATUS NTSTATUS
i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadDataWait(
OUT PUCHAR Data); IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Data);
NTSTATUS NTSTATUS
i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadStatus(
OUT PUCHAR Status); IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Status);
NTSTATUS NTAPI NTSTATUS NTAPI
i8042SynchReadPort(IN PVOID Context, i8042SynchReadPort(
OUT PUCHAR Value, IN PVOID Context,
IN BOOLEAN WaitForAck); OUT PUCHAR Value,
IN BOOLEAN WaitForAck);
NTSTATUS NTAPI NTSTATUS NTAPI
i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042SynchWritePort(
IN UCHAR Port, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR Value, IN UCHAR Port,
IN BOOLEAN WaitForAck); IN UCHAR Value,
IN BOOLEAN WaitForAck);
BOOLEAN BOOLEAN
i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042Write(
IN PUCHAR addr, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR data); IN PUCHAR addr,
IN UCHAR data);
/* registry.c */ /* registry.c */
NTSTATUS NTSTATUS
ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, ReadRegistryEntries(
OUT PI8042_SETTINGS Settings); IN PUNICODE_STRING RegistryPath,
OUT PI8042_SETTINGS Settings);
/* setup.c */ /* setup.c */
BOOLEAN BOOLEAN
IsFirstStageSetup(VOID); IsFirstStageSetup(
VOID);
NTSTATUS NTSTATUS
i8042AddLegacyKeyboard(IN PDRIVER_OBJECT DriverObject, i8042AddLegacyKeyboard(
IN PUNICODE_STRING RegistryPath); IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath);
#endif // _I8042PRT_H_ #endif // _I8042PRT_H_

File diff suppressed because it is too large Load diff

View file

@ -13,71 +13,74 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS NTAPI NTSTATUS NTAPI
ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject, ForwardIrpAndWait(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
ASSERT(LowerDevice); ASSERT(LowerDevice);
if (!IoForwardIrpSynchronously(LowerDevice, Irp)) if (!IoForwardIrpSynchronously(LowerDevice, Irp))
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
return Irp->IoStatus.Status; return Irp->IoStatus.Status;
} }
NTSTATUS NTAPI NTSTATUS NTAPI
ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject, ForwardIrpAndForget(
IN PIRP Irp) IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
ASSERT(LowerDevice); ASSERT(LowerDevice);
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(LowerDevice, Irp); return IoCallDriver(LowerDevice, Irp);
} }
NTSTATUS NTSTATUS
DuplicateUnicodeString(IN ULONG Flags, DuplicateUnicodeString(
IN PCUNICODE_STRING SourceString, IN ULONG Flags,
OUT PUNICODE_STRING DestinationString) IN PCUNICODE_STRING SourceString,
OUT PUNICODE_STRING DestinationString)
{ {
if (SourceString == NULL || DestinationString == NULL if (SourceString == NULL || DestinationString == NULL
|| SourceString->Length > SourceString->MaximumLength || SourceString->Length > SourceString->MaximumLength
|| (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
|| Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4) || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if ((SourceString->Length == 0) if ((SourceString->Length == 0)
&& (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE | && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING))) RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
{ {
DestinationString->Length = 0; DestinationString->Length = 0;
DestinationString->MaximumLength = 0; DestinationString->MaximumLength = 0;
DestinationString->Buffer = NULL; DestinationString->Buffer = NULL;
} }
else else
{ {
USHORT DestMaxLength = SourceString->Length; USHORT DestMaxLength = SourceString->Length;
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
DestMaxLength += sizeof(UNICODE_NULL); DestMaxLength += sizeof(UNICODE_NULL);
DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, I8042PRT_TAG); DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, I8042PRT_TAG);
if (DestinationString->Buffer == NULL) if (DestinationString->Buffer == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length); RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
DestinationString->Length = SourceString->Length; DestinationString->Length = SourceString->Length;
DestinationString->MaximumLength = DestMaxLength; DestinationString->MaximumLength = DestMaxLength;
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0; DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,124 +14,125 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID VOID
i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, i8042MouHandlePs2pp(
IN UCHAR Input) IN PI8042_MOUSE_EXTENSION DeviceExtension,
IN UCHAR Input)
{ {
UCHAR PktType; UCHAR PktType;
PMOUSE_INPUT_DATA MouseInput; PMOUSE_INPUT_DATA MouseInput;
MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
/* First, collect 3 bytes for a packet /* First, collect 3 bytes for a packet
* We can detect out-of-sync only by checking * We can detect out-of-sync only by checking
* the whole packet anyway. * the whole packet anyway.
* *
* If bit 7 and 8 of the first byte are 0, its * If bit 7 and 8 of the first byte are 0, its
* a normal packet. * a normal packet.
* *
* Otherwise, the packet is different, like this: * Otherwise, the packet is different, like this:
* 1: E 1 b3 b2 x x x x * 1: E 1 b3 b2 x x x x
* 2: x x b1 b0 x1 x0 1 0 * 2: x x b1 b0 x1 x0 1 0
* 3: x x x x x x x1 x0 * 3: x x x x x x x1 x0
* *
* b3-0 form a code that specifies the packet type: * b3-0 form a code that specifies the packet type:
* *
* 0 Device Type * 0 Device Type
* 1 Rollers and buttons * 1 Rollers and buttons
* 2 Reserved * 2 Reserved
* 3 Reserved * 3 Reserved
* 4 Device ID * 4 Device ID
* 5 Channel & Battery * 5 Channel & Battery
* 6 Wireless notifications * 6 Wireless notifications
* 7 Reserved * 7 Reserved
* 8 ShortID LSB (ShortID is a number that is supposed to differentiate * 8 ShortID LSB (ShortID is a number that is supposed to differentiate
* 9 ShortID MSB between your mouse and your neighbours') * 9 ShortID MSB between your mouse and your neighbours')
* 10 Reserved * 10 Reserved
* 11 Mouse capabilities * 11 Mouse capabilities
* 12 Remote control LSB * 12 Remote control LSB
* 13 Remote control MSB * 13 Remote control MSB
* 14 Reserved * 14 Reserved
* 15 Extended packet * 15 Extended packet
*/ */
switch (DeviceExtension->MouseState) switch (DeviceExtension->MouseState)
{ {
case MouseIdle: case MouseIdle:
case XMovement: case XMovement:
DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input; DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
DeviceExtension->MouseState++; DeviceExtension->MouseState++;
break; break;
case YMovement: case YMovement:
DeviceExtension->MouseLogiBuffer[2] = Input; DeviceExtension->MouseLogiBuffer[2] = Input;
DeviceExtension->MouseState = MouseIdle; DeviceExtension->MouseState = MouseIdle;
/* first check if it's a normal packet */ /* first check if it's a normal packet */
if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0)) if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
{ {
DeviceExtension->MouseState = MouseIdle; DeviceExtension->MouseState = MouseIdle;
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]); i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]); i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]); i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
/* We could care about wether MouseState really /* We could care about wether MouseState really
* advances, but we don't need to because we're * advances, but we don't need to because we're
* only doing three bytes anyway, so the packet * only doing three bytes anyway, so the packet
* will never complete if it's broken. * will never complete if it's broken.
*/ */
return; return;
} }
/* sanity check */ /* sanity check */
if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) || if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
(((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) != (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
(DeviceExtension->MouseLogiBuffer[2] & 0x03))) (DeviceExtension->MouseLogiBuffer[2] & 0x03)))
{ {
WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n"); WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
return; return;
} }
/* Now get the packet type */ /* Now get the packet type */
PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) & PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) &
((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6); ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6);
switch (PktType) switch (PktType)
{ {
case 0: case 0:
/* The packet contains the device ID, but we /* The packet contains the device ID, but we
* already read that in the initialization * already read that in the initialization
* sequence. Ignore it. * sequence. Ignore it.
*/ */
return; return;
case 1: case 1:
RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
if (DeviceExtension->MouseLogiBuffer[2] & 0x10) if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
if (DeviceExtension->MouseLogiBuffer[2] & 0x20) if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
if (DeviceExtension->MouseLogiBuffer[2] & 0x0F) if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
{ {
MouseInput->ButtonFlags |= MOUSE_WHEEL; MouseInput->ButtonFlags |= MOUSE_WHEEL;
if (DeviceExtension->MouseLogiBuffer[2] & 0x08) if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8; MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
else else
MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07; MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
} }
i8042MouHandleButtons( i8042MouHandleButtons(
DeviceExtension, DeviceExtension,
MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN); MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext); DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
return; return;
default: default:
/* These are for things that would probably /* These are for things that would probably
* be handled by logitechs own driver. * be handled by logitechs own driver.
*/ */
return; return;
} }
default: default:
WARN_(I8042PRT, "Unexpected input state for ps2pp!\n"); WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
} }
} }

View file

@ -16,197 +16,205 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID VOID
i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension) i8042Flush(
IN PPORT_DEVICE_EXTENSION DeviceExtension)
{ {
UCHAR Ignore; UCHAR Ignore;
/* Flush output buffer */ /* Flush output buffer */
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) { while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) {
KeStallExecutionProcessor(50); KeStallExecutionProcessor(50);
TRACE_(I8042PRT, "Output data flushed\n"); TRACE_(I8042PRT, "Output data flushed\n");
} }
/* Flush input buffer */ /* Flush input buffer */
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) { while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) {
KeStallExecutionProcessor(50); KeStallExecutionProcessor(50);
TRACE_(I8042PRT, "Input data flushed\n"); TRACE_(I8042PRT, "Input data flushed\n");
} }
} }
BOOLEAN BOOLEAN
i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042IsrWritePort(
IN UCHAR Value, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR SelectCmd OPTIONAL) IN UCHAR Value,
IN UCHAR SelectCmd OPTIONAL)
{ {
if (SelectCmd) if (SelectCmd)
if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd)) if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd))
return FALSE; return FALSE;
return i8042Write(DeviceExtension, DeviceExtension->DataPort, Value); return i8042Write(DeviceExtension, DeviceExtension->DataPort, Value);
} }
/* /*
* FUNCTION: Read data from port 0x60 * FUNCTION: Read data from port 0x60
*/ */
NTSTATUS NTSTATUS
i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadData(
IN UCHAR StatusFlags, IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Data) IN UCHAR StatusFlags,
OUT PUCHAR Data)
{ {
UCHAR PortStatus; UCHAR PortStatus;
NTSTATUS Status; NTSTATUS Status;
Status = i8042ReadStatus(DeviceExtension, &PortStatus); Status = i8042ReadStatus(DeviceExtension, &PortStatus);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
// If data is available // If data is available
if (PortStatus & StatusFlags) if (PortStatus & StatusFlags)
{ {
*Data = READ_PORT_UCHAR(DeviceExtension->DataPort); *Data = READ_PORT_UCHAR(DeviceExtension->DataPort);
INFO_(I8042PRT, "Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus); INFO_(I8042PRT, "Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus);
// If the data is valid (not timeout, not parity error) // If the data is valid (not timeout, not parity error)
if ((PortStatus & KBD_PERR) == 0) if ((PortStatus & KBD_PERR) == 0)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
NTSTATUS NTSTATUS
i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadStatus(
OUT PUCHAR Status) IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Status)
{ {
ASSERT(DeviceExtension->ControlPort != NULL); ASSERT(DeviceExtension->ControlPort != NULL);
*Status = READ_PORT_UCHAR(DeviceExtension->ControlPort); *Status = READ_PORT_UCHAR(DeviceExtension->ControlPort);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* /*
* FUNCTION: Read data from data port * FUNCTION: Read data from data port
*/ */
NTSTATUS NTSTATUS
i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042ReadDataWait(
OUT PUCHAR Data) IN PPORT_DEVICE_EXTENSION DeviceExtension,
OUT PUCHAR Data)
{ {
ULONG Counter; ULONG Counter;
NTSTATUS Status; NTSTATUS Status;
Counter = DeviceExtension->Settings.PollingIterations; Counter = DeviceExtension->Settings.PollingIterations;
while (Counter--) while (Counter--)
{ {
Status = i8042ReadKeyboardData(DeviceExtension, Data); Status = i8042ReadKeyboardData(DeviceExtension, Data);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
return Status; return Status;
KeStallExecutionProcessor(50); KeStallExecutionProcessor(50);
} }
/* Timed out */ /* Timed out */
return STATUS_IO_TIMEOUT; return STATUS_IO_TIMEOUT;
} }
/* /*
* This one reads a value from the port; You don't have to specify * This one reads a value from the port; You don't have to specify
* which one, it'll always be from the one you talked to, so one function * which one, it'll always be from the one you talked to, so one function
* is enough this time. Note how MSDN specifies the * is enough this time. Note how MSDN specifies the
* WaitForAck parameter to be ignored. * WaitForAck parameter to be ignored.
*/ */
NTSTATUS NTAPI NTSTATUS NTAPI
i8042SynchReadPort(IN PVOID Context, i8042SynchReadPort(
OUT PUCHAR Value, IN PVOID Context,
IN BOOLEAN WaitForAck) OUT PUCHAR Value,
IN BOOLEAN WaitForAck)
{ {
PPORT_DEVICE_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION DeviceExtension;
DeviceExtension = (PPORT_DEVICE_EXTENSION)Context; DeviceExtension = (PPORT_DEVICE_EXTENSION)Context;
return i8042ReadDataWait(DeviceExtension, Value); return i8042ReadDataWait(DeviceExtension, Value);
} }
/* /*
* These functions are callbacks for filter driver custom * These functions are callbacks for filter driver custom
* initialization routines. * initialization routines.
*/ */
NTSTATUS NTAPI NTSTATUS NTAPI
i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042SynchWritePort(
IN UCHAR Port, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR Value, IN UCHAR Port,
IN BOOLEAN WaitForAck) IN UCHAR Value,
IN BOOLEAN WaitForAck)
{ {
NTSTATUS Status; NTSTATUS Status;
UCHAR Ack; UCHAR Ack;
ULONG ResendIterations; ULONG ResendIterations;
ResendIterations = DeviceExtension->Settings.ResendIterations + 1; ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
do do
{ {
if (Port) if (Port)
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port)) if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port))
{ {
WARN_(I8042PRT, "Failed to write Port\n"); WARN_(I8042PRT, "Failed to write Port\n");
return STATUS_IO_TIMEOUT; return STATUS_IO_TIMEOUT;
} }
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value))
{ {
WARN_(I8042PRT, "Failed to write Value\n"); WARN_(I8042PRT, "Failed to write Value\n");
return STATUS_IO_TIMEOUT; return STATUS_IO_TIMEOUT;
} }
if (WaitForAck) if (WaitForAck)
{ {
Status = i8042ReadDataWait(DeviceExtension, &Ack); Status = i8042ReadDataWait(DeviceExtension, &Ack);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "Failed to read Ack\n"); WARN_(I8042PRT, "Failed to read Ack\n");
return Status; return Status;
} }
if (Ack == KBD_ACK) if (Ack == KBD_ACK)
return STATUS_SUCCESS; return STATUS_SUCCESS;
else if (Ack == KBD_RESEND) else if (Ack == KBD_RESEND)
INFO_(I8042PRT, "i8042 asks for a data resend\n"); INFO_(I8042PRT, "i8042 asks for a data resend\n");
} }
else else
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
TRACE_(I8042PRT, "Reiterating\n"); TRACE_(I8042PRT, "Reiterating\n");
ResendIterations--; ResendIterations--;
} while (ResendIterations); } while (ResendIterations);
return STATUS_IO_TIMEOUT; return STATUS_IO_TIMEOUT;
} }
/* /*
* FUNCTION: Write data to a port, waiting first for it to become ready * FUNCTION: Write data to a port, waiting first for it to become ready
*/ */
BOOLEAN BOOLEAN
i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, i8042Write(
IN PUCHAR addr, IN PPORT_DEVICE_EXTENSION DeviceExtension,
IN UCHAR data) IN PUCHAR addr,
IN UCHAR data)
{ {
ULONG Counter; ULONG Counter;
ASSERT(addr); ASSERT(addr);
ASSERT(DeviceExtension->ControlPort != NULL); ASSERT(DeviceExtension->ControlPort != NULL);
Counter = DeviceExtension->Settings.PollingIterations; Counter = DeviceExtension->Settings.PollingIterations;
while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) && while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) &&
(Counter--)) (Counter--))
{ {
KeStallExecutionProcessor(50); KeStallExecutionProcessor(50);
} }
if (Counter) if (Counter)
{ {
WRITE_PORT_UCHAR(addr, data); WRITE_PORT_UCHAR(addr, data);
INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr); INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }

View file

@ -16,215 +16,216 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS NTSTATUS
ReadRegistryEntries(IN PUNICODE_STRING RegistryPath, ReadRegistryEntries(
OUT PI8042_SETTINGS Settings) IN PUNICODE_STRING RegistryPath,
OUT PI8042_SETTINGS Settings)
{ {
RTL_QUERY_REGISTRY_TABLE Parameters[17]; RTL_QUERY_REGISTRY_TABLE Parameters[17];
NTSTATUS Status; NTSTATUS Status;
ULONG DefaultKeyboardDataQueueSize = 0x64; ULONG DefaultKeyboardDataQueueSize = 0x64;
PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort"; PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort";
ULONG DefaultMouseDataQueueSize = 0x64; ULONG DefaultMouseDataQueueSize = 0x64;
ULONG DefaultMouseResolution = 3; ULONG DefaultMouseResolution = 3;
ULONG DefaultMouseSynchIn100ns = 20000000; ULONG DefaultMouseSynchIn100ns = 20000000;
ULONG DefaultNumberOfButtons = 2; ULONG DefaultNumberOfButtons = 2;
PCWSTR DefaultPointerDeviceBaseName = L"PointerPort"; PCWSTR DefaultPointerDeviceBaseName = L"PointerPort";
ULONG DefaultPollStatusIterations = 1; ULONG DefaultPollStatusIterations = 1;
ULONG DefaultOverrideKeyboardType = 4; ULONG DefaultOverrideKeyboardType = 4;
ULONG DefaultOverrideKeyboardSubtype = 0; ULONG DefaultOverrideKeyboardSubtype = 0;
ULONG DefaultPollingIterations = 12000; ULONG DefaultPollingIterations = 12000;
ULONG DefaultPollingIterationsMaximum = 12000; ULONG DefaultPollingIterationsMaximum = 12000;
ULONG DefaultResendIterations = 0x3; ULONG DefaultResendIterations = 0x3;
ULONG DefaultSampleRate = 60; ULONG DefaultSampleRate = 60;
ULONG DefaultCrashOnCtrlScroll; ULONG DefaultCrashOnCtrlScroll;
/* Default value for CrashOnCtrlScroll depends if we're /* Default value for CrashOnCtrlScroll depends if we're
* running a debug build or a normal build. * running a debug build or a normal build.
*/ */
#ifdef DBG #ifdef DBG
DefaultCrashOnCtrlScroll = 1; DefaultCrashOnCtrlScroll = 1;
#else #else
DefaultCrashOnCtrlScroll = 0; DefaultCrashOnCtrlScroll = 0;
#endif #endif
RtlZeroMemory(Parameters, sizeof(Parameters)); RtlZeroMemory(Parameters, sizeof(Parameters));
Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
Parameters[0].Name = L"Parameters"; Parameters[0].Name = L"Parameters";
Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[1].Name = L"KeyboardDataQueueSize"; Parameters[1].Name = L"KeyboardDataQueueSize";
Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize; Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize;
Parameters[1].DefaultType = REG_DWORD; Parameters[1].DefaultType = REG_DWORD;
Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize; Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize;
Parameters[1].DefaultLength = sizeof(ULONG); Parameters[1].DefaultLength = sizeof(ULONG);
Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[2].Name = L"KeyboardDeviceBaseName"; Parameters[2].Name = L"KeyboardDeviceBaseName";
Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName; Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName;
Parameters[2].DefaultType = REG_SZ; Parameters[2].DefaultType = REG_SZ;
Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName; Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName;
Parameters[2].DefaultLength = 0; Parameters[2].DefaultLength = 0;
Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[3].Name = L"MouseDataQueueSize"; Parameters[3].Name = L"MouseDataQueueSize";
Parameters[3].EntryContext = &Settings->MouseDataQueueSize; Parameters[3].EntryContext = &Settings->MouseDataQueueSize;
Parameters[3].DefaultType = REG_DWORD; Parameters[3].DefaultType = REG_DWORD;
Parameters[3].DefaultData = &DefaultMouseDataQueueSize; Parameters[3].DefaultData = &DefaultMouseDataQueueSize;
Parameters[3].DefaultLength = sizeof(ULONG); Parameters[3].DefaultLength = sizeof(ULONG);
Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[4].Name = L"MouseResolution"; Parameters[4].Name = L"MouseResolution";
Parameters[4].EntryContext = &Settings->MouseResolution; Parameters[4].EntryContext = &Settings->MouseResolution;
Parameters[4].DefaultType = REG_DWORD; Parameters[4].DefaultType = REG_DWORD;
Parameters[4].DefaultData = &DefaultMouseResolution; Parameters[4].DefaultData = &DefaultMouseResolution;
Parameters[4].DefaultLength = sizeof(ULONG); Parameters[4].DefaultLength = sizeof(ULONG);
Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[5].Name = L"MouseSynchIn100ns"; Parameters[5].Name = L"MouseSynchIn100ns";
Parameters[5].EntryContext = &Settings->MouseSynchIn100ns; Parameters[5].EntryContext = &Settings->MouseSynchIn100ns;
Parameters[5].DefaultType = REG_DWORD; Parameters[5].DefaultType = REG_DWORD;
Parameters[5].DefaultData = &DefaultMouseSynchIn100ns; Parameters[5].DefaultData = &DefaultMouseSynchIn100ns;
Parameters[5].DefaultLength = sizeof(ULONG); Parameters[5].DefaultLength = sizeof(ULONG);
Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[6].Name = L"NumberOfButtons"; Parameters[6].Name = L"NumberOfButtons";
Parameters[6].EntryContext = &Settings->NumberOfButtons; Parameters[6].EntryContext = &Settings->NumberOfButtons;
Parameters[6].DefaultType = REG_DWORD; Parameters[6].DefaultType = REG_DWORD;
Parameters[6].DefaultData = &DefaultNumberOfButtons; Parameters[6].DefaultData = &DefaultNumberOfButtons;
Parameters[6].DefaultLength = sizeof(ULONG); Parameters[6].DefaultLength = sizeof(ULONG);
Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[7].Name = L"PointerDeviceBaseName"; Parameters[7].Name = L"PointerDeviceBaseName";
Parameters[7].EntryContext = &Settings->PointerDeviceBaseName; Parameters[7].EntryContext = &Settings->PointerDeviceBaseName;
Parameters[7].DefaultType = REG_SZ; Parameters[7].DefaultType = REG_SZ;
Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName; Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName;
Parameters[7].DefaultLength = 0; Parameters[7].DefaultLength = 0;
Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[8].Name = L"PollStatusIterations"; Parameters[8].Name = L"PollStatusIterations";
Parameters[8].EntryContext = &Settings->PollStatusIterations; Parameters[8].EntryContext = &Settings->PollStatusIterations;
Parameters[8].DefaultType = REG_DWORD; Parameters[8].DefaultType = REG_DWORD;
Parameters[8].DefaultData = &DefaultPollStatusIterations; Parameters[8].DefaultData = &DefaultPollStatusIterations;
Parameters[8].DefaultLength = sizeof(ULONG); Parameters[8].DefaultLength = sizeof(ULONG);
Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[9].Name = L"OverrideKeyboardType"; Parameters[9].Name = L"OverrideKeyboardType";
Parameters[9].EntryContext = &Settings->OverrideKeyboardType; Parameters[9].EntryContext = &Settings->OverrideKeyboardType;
Parameters[9].DefaultType = REG_DWORD; Parameters[9].DefaultType = REG_DWORD;
Parameters[9].DefaultData = &DefaultOverrideKeyboardType; Parameters[9].DefaultData = &DefaultOverrideKeyboardType;
Parameters[9].DefaultLength = sizeof(ULONG); Parameters[9].DefaultLength = sizeof(ULONG);
Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[10].Name = L"OverrideKeyboardSubtype"; Parameters[10].Name = L"OverrideKeyboardSubtype";
Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype; Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype;
Parameters[10].DefaultType = REG_DWORD; Parameters[10].DefaultType = REG_DWORD;
Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype;
Parameters[10].DefaultLength = sizeof(ULONG); Parameters[10].DefaultLength = sizeof(ULONG);
Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[11].Name = L"PollingIterations"; Parameters[11].Name = L"PollingIterations";
Parameters[11].EntryContext = &Settings->PollingIterations; Parameters[11].EntryContext = &Settings->PollingIterations;
Parameters[11].DefaultType = REG_DWORD; Parameters[11].DefaultType = REG_DWORD;
Parameters[11].DefaultData = &DefaultPollingIterations; Parameters[11].DefaultData = &DefaultPollingIterations;
Parameters[11].DefaultLength = sizeof(ULONG); Parameters[11].DefaultLength = sizeof(ULONG);
Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[12].Name = L"PollingIterationsMaximum"; Parameters[12].Name = L"PollingIterationsMaximum";
Parameters[12].EntryContext = &Settings->PollingIterationsMaximum; Parameters[12].EntryContext = &Settings->PollingIterationsMaximum;
Parameters[12].DefaultType = REG_DWORD; Parameters[12].DefaultType = REG_DWORD;
Parameters[12].DefaultData = &DefaultPollingIterationsMaximum; Parameters[12].DefaultData = &DefaultPollingIterationsMaximum;
Parameters[12].DefaultLength = sizeof(ULONG); Parameters[12].DefaultLength = sizeof(ULONG);
Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[13].Name = L"ResendIterations"; Parameters[13].Name = L"ResendIterations";
Parameters[13].EntryContext = &Settings->ResendIterations; Parameters[13].EntryContext = &Settings->ResendIterations;
Parameters[13].DefaultType = REG_DWORD; Parameters[13].DefaultType = REG_DWORD;
Parameters[13].DefaultData = &DefaultResendIterations; Parameters[13].DefaultData = &DefaultResendIterations;
Parameters[13].DefaultLength = sizeof(ULONG); Parameters[13].DefaultLength = sizeof(ULONG);
Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[14].Name = L"SampleRate"; Parameters[14].Name = L"SampleRate";
Parameters[14].EntryContext = &Settings->SampleRate; Parameters[14].EntryContext = &Settings->SampleRate;
Parameters[14].DefaultType = REG_DWORD; Parameters[14].DefaultType = REG_DWORD;
Parameters[14].DefaultData = &DefaultSampleRate; Parameters[14].DefaultData = &DefaultSampleRate;
Parameters[14].DefaultLength = sizeof(ULONG); Parameters[14].DefaultLength = sizeof(ULONG);
Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
Parameters[15].Name = L"CrashOnCtrlScroll"; Parameters[15].Name = L"CrashOnCtrlScroll";
Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll; Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll;
Parameters[15].DefaultType = REG_DWORD; Parameters[15].DefaultType = REG_DWORD;
Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll; Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll;
Parameters[15].DefaultLength = sizeof(ULONG); Parameters[15].DefaultLength = sizeof(ULONG);
Status = RtlQueryRegistryValues( Status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE, RTL_REGISTRY_ABSOLUTE,
RegistryPath->Buffer, RegistryPath->Buffer,
Parameters, Parameters,
NULL, NULL,
NULL); NULL);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* Check values */ /* Check values */
if (Settings->KeyboardDataQueueSize < 1) if (Settings->KeyboardDataQueueSize < 1)
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
if (Settings->MouseDataQueueSize < 1) if (Settings->MouseDataQueueSize < 1)
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
if (Settings->NumberOfButtons < 1) if (Settings->NumberOfButtons < 1)
Settings->NumberOfButtons = DefaultNumberOfButtons; Settings->NumberOfButtons = DefaultNumberOfButtons;
if (Settings->PollingIterations < 0x400) if (Settings->PollingIterations < 0x400)
Settings->PollingIterations = DefaultPollingIterations; Settings->PollingIterations = DefaultPollingIterations;
if (Settings->PollingIterationsMaximum < 0x400) if (Settings->PollingIterationsMaximum < 0x400)
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
if (Settings->ResendIterations < 1) if (Settings->ResendIterations < 1)
Settings->ResendIterations = DefaultResendIterations; Settings->ResendIterations = DefaultResendIterations;
} }
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{ {
/* Registry path doesn't exist. Set defaults */ /* Registry path doesn't exist. Set defaults */
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
Settings->MouseResolution = DefaultMouseResolution; Settings->MouseResolution = DefaultMouseResolution;
Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns;
Settings->NumberOfButtons = DefaultNumberOfButtons; Settings->NumberOfButtons = DefaultNumberOfButtons;
Settings->PollStatusIterations = DefaultPollStatusIterations; Settings->PollStatusIterations = DefaultPollStatusIterations;
Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; Settings->OverrideKeyboardType = DefaultOverrideKeyboardType;
Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype;
Settings->PollingIterations = DefaultPollingIterations; Settings->PollingIterations = DefaultPollingIterations;
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
Settings->ResendIterations = DefaultResendIterations; Settings->ResendIterations = DefaultResendIterations;
Settings->SampleRate = DefaultSampleRate; Settings->SampleRate = DefaultSampleRate;
Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll;
if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName) if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName)
|| !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName)) || !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName))
{ {
WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n"); WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n");
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
} }
else else
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
} }
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize);
INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName);
INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize);
INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution); INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution);
INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns);
INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons);
INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName);
INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations);
INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType);
INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype);
INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations); INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations);
INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum);
INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations); INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations);
INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate); INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate);
} }
return Status; return Status;
} }

View file

@ -7,8 +7,8 @@
*/ */
/* NOTE: /* NOTE:
* All this file is a big hack and should be removed one day... * All this file is a big hack and should be removed one day...
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -23,247 +23,251 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOLEAN BOOLEAN
IsFirstStageSetup(VOID) IsFirstStageSetup(
VOID)
{ {
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup"); UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hSetupKey = (HANDLE)NULL; HANDLE hSetupKey = (HANDLE)NULL;
NTSTATUS Status; NTSTATUS Status;
BOOLEAN ret = TRUE; BOOLEAN ret = TRUE;
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes); Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND) if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
ret = TRUE; ret = TRUE;
else else
ret = FALSE; ret = FALSE;
if (hSetupKey != (HANDLE)NULL) if (hSetupKey != (HANDLE)NULL)
ZwClose(hSetupKey); ZwClose(hSetupKey);
INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO");
return ret; return ret;
} }
static VOID NTAPI static VOID NTAPI
SendStartDevice(IN PDRIVER_OBJECT DriverObject, SendStartDevice(
IN PVOID Context, IN PDRIVER_OBJECT DriverObject,
IN ULONG Count) IN PVOID Context,
IN ULONG Count)
{ {
PDEVICE_OBJECT Pdo; PDEVICE_OBJECT Pdo;
PCM_RESOURCE_LIST AllocatedResources = NULL; PCM_RESOURCE_LIST AllocatedResources = NULL;
PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL; PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL;
PDEVICE_OBJECT TopDeviceObject = NULL; PDEVICE_OBJECT TopDeviceObject = NULL;
KEVENT Event; KEVENT Event;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
ULONG ResourceListSize; ULONG ResourceListSize;
NTSTATUS Status; NTSTATUS Status;
Pdo = (PDEVICE_OBJECT)Context; Pdo = (PDEVICE_OBJECT)Context;
TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo); TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo);
/* Create default resource list */ /* Create default resource list */
ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
if (!AllocatedResources) if (!AllocatedResources)
{ {
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
goto cleanup; goto cleanup;
} }
AllocatedResources->Count = 1; AllocatedResources->Count = 1;
AllocatedResources->List[0].PartialResourceList.Version = 1; AllocatedResources->List[0].PartialResourceList.Version = 1;
AllocatedResources->List[0].PartialResourceList.Revision = 1; AllocatedResources->List[0].PartialResourceList.Revision = 1;
AllocatedResources->List[0].PartialResourceList.Count = 3; AllocatedResources->List[0].PartialResourceList.Count = 3;
/* Data port */ /* Data port */
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */ AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1;
/* Control port */ /* Control port */
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */ AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1;
/* Interrupt */ /* Interrupt */
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0;
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1; AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1;
/* Create default resource list translated */ /* Create default resource list translated */
AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
if (!AllocatedResourcesTranslated) if (!AllocatedResourcesTranslated)
{ {
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
goto cleanup; goto cleanup;
} }
RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize); RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize);
AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector( AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector(
Internal, 0, Internal, 0,
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector, AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector,
(PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, (PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity); &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity);
/* Send IRP_MN_START_DEVICE */ /* Send IRP_MN_START_DEVICE */
TopDeviceObject = IoGetAttachedDeviceReference(Pdo); TopDeviceObject = IoGetAttachedDeviceReference(Pdo);
KeInitializeEvent( KeInitializeEvent(
&Event, &Event,
NotificationEvent, NotificationEvent,
FALSE); FALSE);
Irp = IoBuildSynchronousFsdRequest( Irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP, IRP_MJ_PNP,
TopDeviceObject, TopDeviceObject,
NULL, NULL,
0, 0,
NULL, NULL,
&Event, &Event,
&IoStatusBlock); &IoStatusBlock);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Stack = IoGetNextIrpStackLocation(Irp); Stack = IoGetNextIrpStackLocation(Irp);
Stack->MinorFunction = IRP_MN_START_DEVICE; Stack->MinorFunction = IRP_MN_START_DEVICE;
Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources; Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources;
Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated; Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated;
Status = IoCallDriver(TopDeviceObject, Irp); Status = IoCallDriver(TopDeviceObject, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject( KeWaitForSingleObject(
&Event, &Event,
Executive, Executive,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
Status = IoStatusBlock.Status; Status = IoStatusBlock.Status;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
cleanup: cleanup:
if (TopDeviceObject) if (TopDeviceObject)
ObDereferenceObject(TopDeviceObject); ObDereferenceObject(TopDeviceObject);
if (AllocatedResources) if (AllocatedResources)
ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG); ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG);
if (AllocatedResourcesTranslated) if (AllocatedResourcesTranslated)
ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG); ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG);
} }
static NTSTATUS static NTSTATUS
AddRegistryEntry(IN PCWSTR PortTypeName, AddRegistryEntry(
IN PUNICODE_STRING DeviceName, IN PCWSTR PortTypeName,
IN PCWSTR RegistryPath) IN PUNICODE_STRING DeviceName,
IN PCWSTR RegistryPath)
{ {
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP"); UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDeviceMapKey = (HANDLE)-1; HANDLE hDeviceMapKey = (HANDLE)-1;
HANDLE hPortKey = (HANDLE)-1; HANDLE hPortKey = (HANDLE)-1;
UNICODE_STRING PortTypeNameU; UNICODE_STRING PortTypeNameU;
NTSTATUS Status; NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
RtlInitUnicodeString(&PortTypeNameU, PortTypeName); RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
cleanup: cleanup:
if (hDeviceMapKey != (HANDLE)-1) if (hDeviceMapKey != (HANDLE)-1)
ZwClose(hDeviceMapKey); ZwClose(hDeviceMapKey);
if (hPortKey != (HANDLE)-1) if (hPortKey != (HANDLE)-1)
ZwClose(hPortKey); ZwClose(hPortKey);
return Status; return Status;
} }
NTSTATUS NTSTATUS
i8042AddLegacyKeyboard(IN PDRIVER_OBJECT DriverObject, i8042AddLegacyKeyboard(
IN PUNICODE_STRING RegistryPath) IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ {
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
PI8042_DEVICE_TYPE DeviceExtension = NULL; PI8042_DEVICE_TYPE DeviceExtension = NULL;
PDEVICE_OBJECT Pdo = NULL; PDEVICE_OBJECT Pdo = NULL;
NTSTATUS Status; NTSTATUS Status;
TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n"); TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n");
/* Create a named PDO */ /* Create a named PDO */
Status = IoCreateDevice( Status = IoCreateDevice(
DriverObject, DriverObject,
sizeof(I8042_DEVICE_TYPE), sizeof(I8042_DEVICE_TYPE),
&KeyboardName, &KeyboardName,
FILE_DEVICE_8042_PORT, FILE_DEVICE_8042_PORT,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
TRUE, TRUE,
&Pdo); &Pdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
/* Initialize device extension */ /* Initialize device extension */
DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension; DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE)); RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE));
*DeviceExtension = PhysicalDeviceObject; *DeviceExtension = PhysicalDeviceObject;
Pdo->Flags &= ~DO_DEVICE_INITIALIZING; Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
/* Add FDO at the top of the PDO */ /* Add FDO at the top of the PDO */
Status = i8042AddDevice(DriverObject, Pdo); Status = i8042AddDevice(DriverObject, Pdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status); WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status);
goto cleanup; goto cleanup;
} }
/* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */ /* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */
AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer); AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer);
IoRegisterBootDriverReinitialization( IoRegisterBootDriverReinitialization(
DriverObject, DriverObject,
SendStartDevice, SendStartDevice,
Pdo); Pdo);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
/* Yes, completly forget the Pdo pointer, as we will never /* Yes, completly forget the Pdo pointer, as we will never
* have to unload this driver during first stage setup. * have to unload this driver during first stage setup.
*/ */
cleanup: cleanup:
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (Pdo) if (Pdo)
IoDeleteDevice(Pdo); IoDeleteDevice(Pdo);
} }
return Status; return Status;
} }