mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
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:
parent
b4f50046ff
commit
0560eef6ec
11 changed files with 3380 additions and 3295 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue