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 *****************************************************************/
NTSTATUS NTAPI
i8042Create(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
i8042Create(
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.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
i8042Cleanup(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
i8042Cleanup(
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.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
i8042Close(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
i8042Close(
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.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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