mirror of
https://github.com/reactos/reactos.git
synced 2025-06-11 04:47:22 +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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042Create(IN PDEVICE_OBJECT DeviceObject,
|
i8042Create(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
TRACE_(I8042PRT, "IRP_MJ_CREATE\n");
|
TRACE_(I8042PRT, "IRP_MJ_CREATE\n");
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042Cleanup(IN PDEVICE_OBJECT DeviceObject,
|
i8042Cleanup(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
TRACE_(I8042PRT, "IRP_MJ_CLEANUP\n");
|
TRACE_(I8042PRT, "IRP_MJ_CLEANUP\n");
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042Close(IN PDEVICE_OBJECT DeviceObject,
|
i8042Close(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
TRACE_(I8042PRT, "IRP_MJ_CLOSE\n");
|
TRACE_(I8042PRT, "IRP_MJ_CLOSE\n");
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,506 +23,516 @@ static DRIVER_DISPATCH i8042InternalDeviceControl;
|
||||||
DRIVER_INITIALIZE DriverEntry;
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042AddDevice(IN PDRIVER_OBJECT DriverObject,
|
i8042AddDevice(
|
||||||
IN PDEVICE_OBJECT Pdo)
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT Pdo)
|
||||||
{
|
{
|
||||||
PI8042_DRIVER_EXTENSION DriverExtension;
|
PI8042_DRIVER_EXTENSION DriverExtension;
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
||||||
PDEVICE_OBJECT Fdo = NULL;
|
PDEVICE_OBJECT Fdo = NULL;
|
||||||
ULONG DeviceExtensionSize;
|
ULONG DeviceExtensionSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE_(I8042PRT, "i8042AddDevice(%p %p)\n", DriverObject, Pdo);
|
TRACE_(I8042PRT, "i8042AddDevice(%p %p)\n", DriverObject, Pdo);
|
||||||
|
|
||||||
DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject);
|
DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||||
|
|
||||||
if (Pdo == NULL)
|
if (Pdo == NULL)
|
||||||
{
|
{
|
||||||
/* We're getting a NULL Pdo at the first call as
|
/* We're getting a NULL Pdo at the first call as
|
||||||
* we are a legacy driver. Ignore it */
|
* we are a legacy driver. Ignore it */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create new device object. As we don't know if the device would be a keyboard
|
/* Create new device object. As we don't know if the device would be a keyboard
|
||||||
* or a mouse, we have to allocate the biggest device extension. */
|
* or a mouse, we have to allocate the biggest device extension. */
|
||||||
DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION));
|
DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION));
|
||||||
Status = IoCreateDevice(
|
Status = IoCreateDevice(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
DeviceExtensionSize,
|
DeviceExtensionSize,
|
||||||
NULL,
|
NULL,
|
||||||
Pdo->DeviceType,
|
Pdo->DeviceType,
|
||||||
FILE_DEVICE_SECURE_OPEN,
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
TRUE,
|
TRUE,
|
||||||
&Fdo);
|
&Fdo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||||
RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
|
RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
|
||||||
DeviceExtension->Type = Unknown;
|
DeviceExtension->Type = Unknown;
|
||||||
DeviceExtension->Fdo = Fdo;
|
DeviceExtension->Fdo = Fdo;
|
||||||
DeviceExtension->Pdo = Pdo;
|
DeviceExtension->Pdo = Pdo;
|
||||||
DeviceExtension->PortDeviceExtension = &DriverExtension->Port;
|
DeviceExtension->PortDeviceExtension = &DriverExtension->Port;
|
||||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExInterlockedInsertTailList(
|
ExInterlockedInsertTailList(
|
||||||
&DriverExtension->DeviceListHead,
|
&DriverExtension->DeviceListHead,
|
||||||
&DeviceExtension->ListEntry,
|
&DeviceExtension->ListEntry,
|
||||||
&DriverExtension->DeviceListLock);
|
&DriverExtension->DeviceListLock);
|
||||||
|
|
||||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (DeviceExtension && DeviceExtension->LowerDevice)
|
if (DeviceExtension && DeviceExtension->LowerDevice)
|
||||||
IoDetachDevice(DeviceExtension->LowerDevice);
|
IoDetachDevice(DeviceExtension->LowerDevice);
|
||||||
if (Fdo)
|
if (Fdo)
|
||||||
IoDeleteDevice(Fdo);
|
IoDeleteDevice(Fdo);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
i8042SendHookWorkItem(IN PDEVICE_OBJECT DeviceObject,
|
i8042SendHookWorkItem(
|
||||||
IN PVOID Context)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
PI8042_HOOK_WORKITEM WorkItemData;
|
PI8042_HOOK_WORKITEM WorkItemData;
|
||||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||||
PPORT_DEVICE_EXTENSION PortDeviceExtension;
|
PPORT_DEVICE_EXTENSION PortDeviceExtension;
|
||||||
PDEVICE_OBJECT TopOfStack = NULL;
|
PDEVICE_OBJECT TopOfStack = NULL;
|
||||||
ULONG IoControlCode;
|
ULONG IoControlCode;
|
||||||
PVOID InputBuffer;
|
PVOID InputBuffer;
|
||||||
ULONG InputBufferLength;
|
ULONG InputBufferLength;
|
||||||
IO_STATUS_BLOCK IoStatus;
|
IO_STATUS_BLOCK IoStatus;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIRP NewIrp;
|
PIRP NewIrp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE_(I8042PRT, "i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context);
|
TRACE_(I8042PRT, "i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context);
|
||||||
|
|
||||||
WorkItemData = (PI8042_HOOK_WORKITEM)Context;
|
WorkItemData = (PI8042_HOOK_WORKITEM)Context;
|
||||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension;
|
PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension;
|
||||||
|
|
||||||
switch (FdoDeviceExtension->Type)
|
switch (FdoDeviceExtension->Type)
|
||||||
{
|
{
|
||||||
case Keyboard:
|
case Keyboard:
|
||||||
{
|
{
|
||||||
PI8042_KEYBOARD_EXTENSION DeviceExtension;
|
PI8042_KEYBOARD_EXTENSION DeviceExtension;
|
||||||
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
|
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
|
||||||
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD;
|
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD;
|
||||||
InputBuffer = &DeviceExtension->KeyboardHook;
|
InputBuffer = &DeviceExtension->KeyboardHook;
|
||||||
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD);
|
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mouse:
|
case Mouse:
|
||||||
{
|
{
|
||||||
PI8042_MOUSE_EXTENSION DeviceExtension;
|
PI8042_MOUSE_EXTENSION DeviceExtension;
|
||||||
DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension;
|
DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension;
|
||||||
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE;
|
IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE;
|
||||||
InputBuffer = &DeviceExtension->MouseHook;
|
InputBuffer = &DeviceExtension->MouseHook;
|
||||||
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE);
|
InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
|
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
|
WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
TopOfStack = IoGetAttachedDeviceReference(DeviceObject);
|
TopOfStack = IoGetAttachedDeviceReference(DeviceObject);
|
||||||
|
|
||||||
NewIrp = IoBuildDeviceIoControlRequest(
|
NewIrp = IoBuildDeviceIoControlRequest(
|
||||||
IoControlCode,
|
IoControlCode,
|
||||||
TopOfStack,
|
TopOfStack,
|
||||||
InputBuffer,
|
InputBuffer,
|
||||||
InputBufferLength,
|
InputBufferLength,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
TRUE,
|
TRUE,
|
||||||
&Event,
|
&Event,
|
||||||
&IoStatus);
|
&IoStatus);
|
||||||
|
|
||||||
if (!NewIrp)
|
if (!NewIrp)
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoBuildDeviceIoControlRequest() failed\n");
|
WARN_(I8042PRT, "IoBuildDeviceIoControlRequest() failed\n");
|
||||||
WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IoCallDriver(TopOfStack, NewIrp);
|
Status = IoCallDriver(TopOfStack, NewIrp);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(
|
KeWaitForSingleObject(
|
||||||
&Event,
|
&Event,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
Status = IoStatus.Status;
|
Status = IoStatus.Status;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FdoDeviceExtension->Type == Keyboard)
|
if (FdoDeviceExtension->Type == Keyboard)
|
||||||
{
|
{
|
||||||
PI8042_KEYBOARD_EXTENSION DeviceExtension;
|
PI8042_KEYBOARD_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
|
DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension;
|
||||||
/* Call the hooked initialization if it exists */
|
/* Call the hooked initialization if it exists */
|
||||||
if (DeviceExtension->KeyboardHook.InitializationRoutine)
|
if (DeviceExtension->KeyboardHook.InitializationRoutine)
|
||||||
{
|
{
|
||||||
Status = DeviceExtension->KeyboardHook.InitializationRoutine(
|
Status = DeviceExtension->KeyboardHook.InitializationRoutine(
|
||||||
DeviceExtension->KeyboardHook.Context,
|
DeviceExtension->KeyboardHook.Context,
|
||||||
PortDeviceExtension,
|
PortDeviceExtension,
|
||||||
i8042SynchReadPort,
|
i8042SynchReadPort,
|
||||||
i8042SynchWritePortKbd,
|
i8042SynchWritePortKbd,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status);
|
||||||
WorkItemData->Irp->IoStatus.Status = Status;
|
WorkItemData->Irp->IoStatus.Status = Status;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS;
|
WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (TopOfStack != NULL)
|
if (TopOfStack != NULL)
|
||||||
ObDereferenceObject(TopOfStack);
|
ObDereferenceObject(TopOfStack);
|
||||||
WorkItemData->Irp->IoStatus.Information = 0;
|
WorkItemData->Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
IoFreeWorkItem(WorkItemData->WorkItem);
|
IoFreeWorkItem(WorkItemData->WorkItem);
|
||||||
ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
|
ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
i8042StartIo(IN PDEVICE_OBJECT DeviceObject,
|
i8042StartIo(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
switch (DeviceExtension->Type)
|
switch (DeviceExtension->Type)
|
||||||
{
|
{
|
||||||
case Keyboard:
|
case Keyboard:
|
||||||
i8042KbdStartIo(DeviceObject, Irp);
|
i8042KbdStartIo(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
|
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the current byte of the packet. Returns FALSE in case
|
/* Write the current byte of the packet. Returns FALSE in case
|
||||||
* of problems.
|
* of problems.
|
||||||
*/
|
*/
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
i8042PacketWrite(IN PPORT_DEVICE_EXTENSION DeviceExtension)
|
i8042PacketWrite(
|
||||||
|
IN PPORT_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
UCHAR Port = DeviceExtension->PacketPort;
|
UCHAR Port = DeviceExtension->PacketPort;
|
||||||
|
|
||||||
if (Port)
|
if (Port)
|
||||||
{
|
{
|
||||||
if (!i8042Write(DeviceExtension,
|
if (!i8042Write(DeviceExtension,
|
||||||
DeviceExtension->ControlPort,
|
DeviceExtension->ControlPort,
|
||||||
Port))
|
Port))
|
||||||
{
|
{
|
||||||
/* something is really wrong! */
|
/* something is really wrong! */
|
||||||
WARN_(I8042PRT, "Failed to send packet byte!\n");
|
WARN_(I8042PRT, "Failed to send packet byte!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i8042Write(DeviceExtension,
|
return i8042Write(DeviceExtension,
|
||||||
DeviceExtension->DataPort,
|
DeviceExtension->DataPort,
|
||||||
DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]);
|
DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042PacketIsr(
|
||||||
IN UCHAR Output)
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
IN UCHAR Output)
|
||||||
{
|
{
|
||||||
if (DeviceExtension->Packet.State == Idle)
|
if (DeviceExtension->Packet.State == Idle)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (Output)
|
switch (Output)
|
||||||
{
|
{
|
||||||
case KBD_RESEND:
|
case KBD_RESEND:
|
||||||
DeviceExtension->PacketResends++;
|
DeviceExtension->PacketResends++;
|
||||||
if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations)
|
if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations)
|
||||||
{
|
{
|
||||||
DeviceExtension->Packet.State = Idle;
|
DeviceExtension->Packet.State = Idle;
|
||||||
DeviceExtension->PacketComplete = TRUE;
|
DeviceExtension->PacketComplete = TRUE;
|
||||||
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
|
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
|
||||||
DeviceExtension->PacketResends = 0;
|
DeviceExtension->PacketResends = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
DeviceExtension->Packet.CurrentByte--;
|
DeviceExtension->Packet.CurrentByte--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KBD_NACK:
|
case KBD_NACK:
|
||||||
DeviceExtension->Packet.State = Idle;
|
DeviceExtension->Packet.State = Idle;
|
||||||
DeviceExtension->PacketComplete = TRUE;
|
DeviceExtension->PacketComplete = TRUE;
|
||||||
DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR;
|
DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR;
|
||||||
DeviceExtension->PacketResends = 0;
|
DeviceExtension->PacketResends = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DeviceExtension->PacketResends = 0;
|
DeviceExtension->PacketResends = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount)
|
if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount)
|
||||||
{
|
{
|
||||||
DeviceExtension->Packet.State = Idle;
|
DeviceExtension->Packet.State = Idle;
|
||||||
DeviceExtension->PacketComplete = TRUE;
|
DeviceExtension->PacketComplete = TRUE;
|
||||||
DeviceExtension->PacketResult = STATUS_SUCCESS;
|
DeviceExtension->PacketResult = STATUS_SUCCESS;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i8042PacketWrite(DeviceExtension))
|
if (!i8042PacketWrite(DeviceExtension))
|
||||||
{
|
{
|
||||||
DeviceExtension->Packet.State = Idle;
|
DeviceExtension->Packet.State = Idle;
|
||||||
DeviceExtension->PacketComplete = TRUE;
|
DeviceExtension->PacketComplete = TRUE;
|
||||||
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
|
DeviceExtension->PacketResult = STATUS_IO_TIMEOUT;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
DeviceExtension->Packet.CurrentByte++;
|
DeviceExtension->Packet.CurrentByte++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function starts a packet. It must be called with the
|
* This function starts a packet. It must be called with the
|
||||||
* correct DIRQL.
|
* correct DIRQL.
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042StartPacket(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042StartPacket(
|
||||||
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN PUCHAR Bytes,
|
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
|
||||||
IN ULONG ByteCount,
|
IN PUCHAR Bytes,
|
||||||
IN PIRP Irp)
|
IN ULONG ByteCount,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
|
Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
|
||||||
|
|
||||||
if (DeviceExtension->Packet.State != Idle)
|
if (DeviceExtension->Packet.State != Idle)
|
||||||
{
|
{
|
||||||
Status = STATUS_DEVICE_BUSY;
|
Status = STATUS_DEVICE_BUSY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (FdoDeviceExtension->Type)
|
switch (FdoDeviceExtension->Type)
|
||||||
{
|
{
|
||||||
case Keyboard: DeviceExtension->PacketPort = 0; break;
|
case Keyboard: DeviceExtension->PacketPort = 0; break;
|
||||||
case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break;
|
case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break;
|
||||||
default:
|
default:
|
||||||
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
|
ERR_(I8042PRT, "Unknown FDO type %u\n", FdoDeviceExtension->Type);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
Status = STATUS_INTERNAL_ERROR;
|
Status = STATUS_INTERNAL_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceExtension->Packet.Bytes = Bytes;
|
DeviceExtension->Packet.Bytes = Bytes;
|
||||||
DeviceExtension->Packet.CurrentByte = 0;
|
DeviceExtension->Packet.CurrentByte = 0;
|
||||||
DeviceExtension->Packet.ByteCount = ByteCount;
|
DeviceExtension->Packet.ByteCount = ByteCount;
|
||||||
DeviceExtension->Packet.State = SendingBytes;
|
DeviceExtension->Packet.State = SendingBytes;
|
||||||
DeviceExtension->PacketResult = Status = STATUS_PENDING;
|
DeviceExtension->PacketResult = Status = STATUS_PENDING;
|
||||||
DeviceExtension->CurrentIrp = Irp;
|
DeviceExtension->CurrentIrp = Irp;
|
||||||
DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo;
|
DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo;
|
||||||
|
|
||||||
if (!i8042PacketWrite(DeviceExtension))
|
if (!i8042PacketWrite(DeviceExtension))
|
||||||
{
|
{
|
||||||
Status = STATUS_IO_TIMEOUT;
|
Status = STATUS_IO_TIMEOUT;
|
||||||
DeviceExtension->Packet.State = Idle;
|
DeviceExtension->Packet.State = Idle;
|
||||||
DeviceExtension->PacketResult = STATUS_ABANDONED;
|
DeviceExtension->PacketResult = STATUS_ABANDONED;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceExtension->Packet.CurrentByte++;
|
DeviceExtension->Packet.CurrentByte++;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
|
KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
|
||||||
|
|
||||||
if (Status != STATUS_PENDING)
|
if (Status != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
DeviceExtension->CurrentIrp = NULL;
|
DeviceExtension->CurrentIrp = NULL;
|
||||||
DeviceExtension->CurrentIrpDevice = NULL;
|
DeviceExtension->CurrentIrpDevice = NULL;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static NTSTATUS NTAPI
|
||||||
IrpStub(IN PDEVICE_OBJECT DeviceObject,
|
IrpStub(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = Irp->IoStatus.Status;
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static NTSTATUS NTAPI
|
||||||
i8042DeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
i8042DeviceControl(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE_(I8042PRT, "i8042DeviceControl(%p %p)\n", DeviceObject, Irp);
|
TRACE_(I8042PRT, "i8042DeviceControl(%p %p)\n", DeviceObject, Irp);
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
switch (DeviceExtension->Type)
|
switch (DeviceExtension->Type)
|
||||||
{
|
{
|
||||||
case Keyboard:
|
case Keyboard:
|
||||||
return i8042KbdDeviceControl(DeviceObject, Irp);
|
return i8042KbdDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return IrpStub(DeviceObject, Irp);
|
return IrpStub(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static NTSTATUS NTAPI
|
||||||
i8042InternalDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
i8042InternalDeviceControl(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
ULONG ControlCode;
|
ULONG ControlCode;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE_(I8042PRT, "i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp);
|
TRACE_(I8042PRT, "i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp);
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
switch (DeviceExtension->Type)
|
switch (DeviceExtension->Type)
|
||||||
{
|
{
|
||||||
case Unknown:
|
case Unknown:
|
||||||
{
|
{
|
||||||
ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode;
|
ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode;
|
||||||
switch (ControlCode)
|
switch (ControlCode)
|
||||||
{
|
{
|
||||||
case IOCTL_INTERNAL_KEYBOARD_CONNECT:
|
case IOCTL_INTERNAL_KEYBOARD_CONNECT:
|
||||||
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
|
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
case IOCTL_INTERNAL_MOUSE_CONNECT:
|
case IOCTL_INTERNAL_MOUSE_CONNECT:
|
||||||
Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
|
Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_(I8042PRT, "Unknown IO control code 0x%lx\n", ControlCode);
|
ERR_(I8042PRT, "Unknown IO control code 0x%lx\n", ControlCode);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Keyboard:
|
case Keyboard:
|
||||||
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
|
Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
case Mouse:
|
case Mouse:
|
||||||
Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
|
Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
|
ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
Status = STATUS_INTERNAL_ERROR;
|
Status = STATUS_INTERNAL_ERROR;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
DriverEntry(
|
||||||
IN PUNICODE_STRING RegistryPath)
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
PI8042_DRIVER_EXTENSION DriverExtension;
|
PI8042_DRIVER_EXTENSION DriverExtension;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* ROS Hack: ideally, we shouldn't have to initialize debug level this way,
|
/* ROS Hack: ideally, we shouldn't have to initialize debug level this way,
|
||||||
but since the only way is to change it via KDBG, it's better to leave
|
but since the only way is to change it via KDBG, it's better to leave
|
||||||
it here too. */
|
it here too. */
|
||||||
#if 0
|
#if 0
|
||||||
DbgSetDebugFilterState(
|
DbgSetDebugFilterState(
|
||||||
DPFLTR_I8042PRT_ID,
|
DPFLTR_I8042PRT_ID,
|
||||||
(1 << DPFLTR_ERROR_LEVEL) | (1 << DPFLTR_WARNING_LEVEL) |
|
(1 << DPFLTR_ERROR_LEVEL) | (1 << DPFLTR_WARNING_LEVEL) |
|
||||||
(1 << DPFLTR_TRACE_LEVEL) /*| (1 << DPFLTR_INFO_LEVEL)*/ | DPFLTR_MASK,
|
(1 << DPFLTR_TRACE_LEVEL) /*| (1 << DPFLTR_INFO_LEVEL)*/ | DPFLTR_MASK,
|
||||||
TRUE);
|
TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Status = IoAllocateDriverObjectExtension(
|
Status = IoAllocateDriverObjectExtension(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
DriverObject,
|
DriverObject,
|
||||||
sizeof(I8042_DRIVER_EXTENSION),
|
sizeof(I8042_DRIVER_EXTENSION),
|
||||||
(PVOID*)&DriverExtension);
|
(PVOID*)&DriverExtension);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION));
|
RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION));
|
||||||
KeInitializeSpinLock(&DriverExtension->Port.SpinLock);
|
KeInitializeSpinLock(&DriverExtension->Port.SpinLock);
|
||||||
InitializeListHead(&DriverExtension->DeviceListHead);
|
InitializeListHead(&DriverExtension->DeviceListHead);
|
||||||
KeInitializeSpinLock(&DriverExtension->DeviceListLock);
|
KeInitializeSpinLock(&DriverExtension->DeviceListLock);
|
||||||
|
|
||||||
Status = DuplicateUnicodeString(
|
Status = DuplicateUnicodeString(
|
||||||
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
||||||
RegistryPath,
|
RegistryPath,
|
||||||
&DriverExtension->RegistryPath);
|
&DriverExtension->RegistryPath);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "DuplicateUnicodeString() failed with status 0x%08lx\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings);
|
Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "ReadRegistryEntries() failed with status 0x%08lx\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverObject->DriverExtension->AddDevice = i8042AddDevice;
|
DriverObject->DriverExtension->AddDevice = i8042AddDevice;
|
||||||
DriverObject->DriverStartIo = i8042StartIo;
|
DriverObject->DriverStartIo = i8042StartIo;
|
||||||
|
|
||||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||||
DriverObject->MajorFunction[i] = IrpStub;
|
DriverObject->MajorFunction[i] = IrpStub;
|
||||||
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create;
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup;
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl;
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl;
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
|
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
|
||||||
|
|
||||||
if (IsFirstStageSetup())
|
if (IsFirstStageSetup())
|
||||||
return i8042AddLegacyKeyboard(DriverObject, RegistryPath);
|
return i8042AddLegacyKeyboard(DriverObject, RegistryPath);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,56 +11,56 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Structures
|
* Structures
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||||
#define I8042PRT_TAG TAG('8', '0', '4', '2')
|
#define I8042PRT_TAG TAG('8', '0', '4', '2')
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
dsStopped,
|
dsStopped,
|
||||||
dsStarted,
|
dsStarted,
|
||||||
dsPaused,
|
dsPaused,
|
||||||
dsRemoved,
|
dsRemoved,
|
||||||
dsSurpriseRemoved
|
dsSurpriseRemoved
|
||||||
} DEVICE_STATE;
|
} DEVICE_STATE;
|
||||||
|
|
||||||
typedef struct _I8042_SETTINGS
|
typedef struct _I8042_SETTINGS
|
||||||
{
|
{
|
||||||
/* Registry settings */
|
/* Registry settings */
|
||||||
ULONG KeyboardDataQueueSize; /* done */
|
ULONG KeyboardDataQueueSize; /* done */
|
||||||
UNICODE_STRING KeyboardDeviceBaseName;
|
UNICODE_STRING KeyboardDeviceBaseName;
|
||||||
ULONG MouseDataQueueSize; /* done */
|
ULONG MouseDataQueueSize; /* done */
|
||||||
ULONG MouseResolution;
|
ULONG MouseResolution;
|
||||||
ULONG MouseSynchIn100ns;
|
ULONG MouseSynchIn100ns;
|
||||||
ULONG NumberOfButtons;
|
ULONG NumberOfButtons;
|
||||||
UNICODE_STRING PointerDeviceBaseName;
|
UNICODE_STRING PointerDeviceBaseName;
|
||||||
ULONG PollStatusIterations; /* done */
|
ULONG PollStatusIterations; /* done */
|
||||||
ULONG OverrideKeyboardType;
|
ULONG OverrideKeyboardType;
|
||||||
ULONG OverrideKeyboardSubtype;
|
ULONG OverrideKeyboardSubtype;
|
||||||
ULONG PollingIterations; /* done */
|
ULONG PollingIterations; /* done */
|
||||||
ULONG PollingIterationsMaximum;
|
ULONG PollingIterationsMaximum;
|
||||||
ULONG ResendIterations; /* done */
|
ULONG ResendIterations; /* done */
|
||||||
ULONG SampleRate;
|
ULONG SampleRate;
|
||||||
ULONG CrashOnCtrlScroll; /* done */
|
ULONG CrashOnCtrlScroll; /* done */
|
||||||
} I8042_SETTINGS, *PI8042_SETTINGS;
|
} I8042_SETTINGS, *PI8042_SETTINGS;
|
||||||
|
|
||||||
typedef enum _MOUSE_TIMEOUT_STATE
|
typedef enum _MOUSE_TIMEOUT_STATE
|
||||||
{
|
{
|
||||||
NoChange,
|
NoChange,
|
||||||
TimeoutStart,
|
TimeoutStart,
|
||||||
TimeoutCancel
|
TimeoutCancel
|
||||||
} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE;
|
} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE;
|
||||||
|
|
||||||
typedef struct _INTERRUPT_DATA
|
typedef struct _INTERRUPT_DATA
|
||||||
{
|
{
|
||||||
PKINTERRUPT Object;
|
PKINTERRUPT Object;
|
||||||
ULONG Vector;
|
ULONG Vector;
|
||||||
KIRQL Dirql;
|
KIRQL Dirql;
|
||||||
KINTERRUPT_MODE InterruptMode;
|
KINTERRUPT_MODE InterruptMode;
|
||||||
BOOLEAN ShareInterrupt;
|
BOOLEAN ShareInterrupt;
|
||||||
KAFFINITY Affinity;
|
KAFFINITY Affinity;
|
||||||
} INTERRUPT_DATA, *PINTERRUPT_DATA;
|
} INTERRUPT_DATA, *PINTERRUPT_DATA;
|
||||||
|
|
||||||
#define WHEEL_DELTA 120
|
#define WHEEL_DELTA 120
|
||||||
|
@ -82,135 +82,135 @@ typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _PORT_DEVICE_EXTENSION
|
typedef struct _PORT_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
PUCHAR DataPort; /* Usually 0x60 */
|
PUCHAR DataPort; /* Usually 0x60 */
|
||||||
PUCHAR ControlPort; /* Usually 0x64 */
|
PUCHAR ControlPort; /* Usually 0x64 */
|
||||||
I8042_SETTINGS Settings;
|
I8042_SETTINGS Settings;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
|
|
||||||
PI8042_KEYBOARD_EXTENSION KeyboardExtension;
|
PI8042_KEYBOARD_EXTENSION KeyboardExtension;
|
||||||
INTERRUPT_DATA KeyboardInterrupt;
|
INTERRUPT_DATA KeyboardInterrupt;
|
||||||
PI8042_MOUSE_EXTENSION MouseExtension;
|
PI8042_MOUSE_EXTENSION MouseExtension;
|
||||||
INTERRUPT_DATA MouseInterrupt;
|
INTERRUPT_DATA MouseInterrupt;
|
||||||
PKINTERRUPT HighestDIRQLInterrupt;
|
PKINTERRUPT HighestDIRQLInterrupt;
|
||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock;
|
||||||
KIRQL HighestDirql;
|
KIRQL HighestDirql;
|
||||||
|
|
||||||
OUTPUT_PACKET Packet;
|
OUTPUT_PACKET Packet;
|
||||||
ULONG PacketResends;
|
ULONG PacketResends;
|
||||||
BOOLEAN PacketComplete;
|
BOOLEAN PacketComplete;
|
||||||
NTSTATUS PacketResult;
|
NTSTATUS PacketResult;
|
||||||
UCHAR PacketBuffer[16];
|
UCHAR PacketBuffer[16];
|
||||||
UCHAR PacketPort;
|
UCHAR PacketPort;
|
||||||
|
|
||||||
PIRP CurrentIrp;
|
PIRP CurrentIrp;
|
||||||
PDEVICE_OBJECT CurrentIrpDevice;
|
PDEVICE_OBJECT CurrentIrpDevice;
|
||||||
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
|
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _I8042_DRIVER_EXTENSION
|
typedef struct _I8042_DRIVER_EXTENSION
|
||||||
{
|
{
|
||||||
UNICODE_STRING RegistryPath;
|
UNICODE_STRING RegistryPath;
|
||||||
|
|
||||||
PORT_DEVICE_EXTENSION Port;
|
PORT_DEVICE_EXTENSION Port;
|
||||||
LIST_ENTRY DeviceListHead;
|
LIST_ENTRY DeviceListHead;
|
||||||
KSPIN_LOCK DeviceListLock;
|
KSPIN_LOCK DeviceListLock;
|
||||||
} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION;
|
} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION;
|
||||||
|
|
||||||
typedef enum _I8042_DEVICE_TYPE
|
typedef enum _I8042_DEVICE_TYPE
|
||||||
{
|
{
|
||||||
Unknown,
|
Unknown,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
Mouse,
|
Mouse,
|
||||||
PhysicalDeviceObject
|
PhysicalDeviceObject
|
||||||
} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE;
|
} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE;
|
||||||
|
|
||||||
typedef struct _FDO_DEVICE_EXTENSION
|
typedef struct _FDO_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
I8042_DEVICE_TYPE Type;
|
I8042_DEVICE_TYPE Type;
|
||||||
// Linkage in I8042_DRIVER_EXTENSION.DeviceListHead
|
// Linkage in I8042_DRIVER_EXTENSION.DeviceListHead
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
// Associated device object (FDO)
|
// Associated device object (FDO)
|
||||||
PDEVICE_OBJECT Fdo;
|
PDEVICE_OBJECT Fdo;
|
||||||
// Associated device object (PDO)
|
// Associated device object (PDO)
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
// Lower device object
|
// Lower device object
|
||||||
PDEVICE_OBJECT LowerDevice;
|
PDEVICE_OBJECT LowerDevice;
|
||||||
// Current state of the driver
|
// Current state of the driver
|
||||||
DEVICE_STATE PnpState;
|
DEVICE_STATE PnpState;
|
||||||
|
|
||||||
PPORT_DEVICE_EXTENSION PortDeviceExtension;
|
PPORT_DEVICE_EXTENSION PortDeviceExtension;
|
||||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _I8042_KEYBOARD_EXTENSION
|
typedef struct _I8042_KEYBOARD_EXTENSION
|
||||||
{
|
{
|
||||||
FDO_DEVICE_EXTENSION Common;
|
FDO_DEVICE_EXTENSION Common;
|
||||||
CONNECT_DATA KeyboardData;
|
CONNECT_DATA KeyboardData;
|
||||||
INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */
|
INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; /* FIXME: IsrWritePort ignored */
|
||||||
KDPC DpcKeyboard;
|
KDPC DpcKeyboard;
|
||||||
|
|
||||||
KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators;
|
KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators;
|
||||||
|
|
||||||
KEYBOARD_SCAN_STATE KeyboardScanState;
|
KEYBOARD_SCAN_STATE KeyboardScanState;
|
||||||
BOOLEAN KeyComplete;
|
BOOLEAN KeyComplete;
|
||||||
PKEYBOARD_INPUT_DATA KeyboardBuffer;
|
PKEYBOARD_INPUT_DATA KeyboardBuffer;
|
||||||
ULONG KeysInBuffer;
|
ULONG KeysInBuffer;
|
||||||
|
|
||||||
/* Power keys items */
|
/* Power keys items */
|
||||||
ULONG ReportedCaps;
|
ULONG ReportedCaps;
|
||||||
ULONG NewCaps;
|
ULONG NewCaps;
|
||||||
ULONG LastPowerKey;
|
ULONG LastPowerKey;
|
||||||
UNICODE_STRING PowerInterfaceName;
|
UNICODE_STRING PowerInterfaceName;
|
||||||
PIO_WORKITEM PowerWorkItem;
|
PIO_WORKITEM PowerWorkItem;
|
||||||
PIRP PowerIrp;
|
PIRP PowerIrp;
|
||||||
|
|
||||||
/* Debug items */
|
/* Debug items */
|
||||||
ULONG ComboPosition;
|
ULONG ComboPosition;
|
||||||
PIO_WORKITEM DebugWorkItem;
|
PIO_WORKITEM DebugWorkItem;
|
||||||
BOOLEAN TabPressed;
|
BOOLEAN TabPressed;
|
||||||
} I8042_KEYBOARD_EXTENSION;
|
} I8042_KEYBOARD_EXTENSION;
|
||||||
|
|
||||||
typedef enum _I8042_MOUSE_TYPE
|
typedef enum _I8042_MOUSE_TYPE
|
||||||
{
|
{
|
||||||
GenericPS2,
|
GenericPS2,
|
||||||
Intellimouse,
|
Intellimouse,
|
||||||
IntellimouseExplorer,
|
IntellimouseExplorer,
|
||||||
Ps2pp
|
Ps2pp
|
||||||
} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE;
|
} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE;
|
||||||
|
|
||||||
typedef struct _I8042_MOUSE_EXTENSION
|
typedef struct _I8042_MOUSE_EXTENSION
|
||||||
{
|
{
|
||||||
FDO_DEVICE_EXTENSION Common;
|
FDO_DEVICE_EXTENSION Common;
|
||||||
CONNECT_DATA MouseData;
|
CONNECT_DATA MouseData;
|
||||||
INTERNAL_I8042_HOOK_MOUSE MouseHook;
|
INTERNAL_I8042_HOOK_MOUSE MouseHook;
|
||||||
KDPC DpcMouse;
|
KDPC DpcMouse;
|
||||||
|
|
||||||
MOUSE_ATTRIBUTES MouseAttributes;
|
MOUSE_ATTRIBUTES MouseAttributes;
|
||||||
|
|
||||||
MOUSE_STATE MouseState;
|
MOUSE_STATE MouseState;
|
||||||
BOOLEAN MouseComplete;
|
BOOLEAN MouseComplete;
|
||||||
MOUSE_RESET_SUBSTATE MouseResetState;
|
MOUSE_RESET_SUBSTATE MouseResetState;
|
||||||
PMOUSE_INPUT_DATA MouseBuffer;
|
PMOUSE_INPUT_DATA MouseBuffer;
|
||||||
ULONG MouseInBuffer;
|
ULONG MouseInBuffer;
|
||||||
USHORT MouseButtonState;
|
USHORT MouseButtonState;
|
||||||
ULARGE_INTEGER MousePacketStartTime;
|
ULARGE_INTEGER MousePacketStartTime;
|
||||||
|
|
||||||
KTIMER TimerMouseTimeout;
|
KTIMER TimerMouseTimeout;
|
||||||
KDPC DpcMouseTimeout;
|
KDPC DpcMouseTimeout;
|
||||||
MOUSE_TIMEOUT_STATE MouseTimeoutState;
|
MOUSE_TIMEOUT_STATE MouseTimeoutState;
|
||||||
BOOLEAN MouseTimeoutActive;
|
BOOLEAN MouseTimeoutActive;
|
||||||
|
|
||||||
UCHAR MouseLogiBuffer[3];
|
UCHAR MouseLogiBuffer[3];
|
||||||
I8042_MOUSE_TYPE MouseType;
|
I8042_MOUSE_TYPE MouseType;
|
||||||
} I8042_MOUSE_EXTENSION;
|
} I8042_MOUSE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _I8042_HOOK_WORKITEM
|
typedef struct _I8042_HOOK_WORKITEM
|
||||||
{
|
{
|
||||||
PIO_WORKITEM WorkItem;
|
PIO_WORKITEM WorkItem;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM;
|
} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM;
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Some defines
|
* Some defines
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
||||||
|
|
||||||
|
@ -219,8 +219,8 @@ typedef struct _I8042_HOOK_WORKITEM
|
||||||
#define KEYBOARD_WAKE_CODE 0x63
|
#define KEYBOARD_WAKE_CODE 0x63
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Controller commands
|
* Controller commands
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define KBD_READ_MODE 0x20
|
#define KBD_READ_MODE 0x20
|
||||||
#define KBD_WRITE_MODE 0x60
|
#define KBD_WRITE_MODE 0x60
|
||||||
|
@ -230,15 +230,15 @@ typedef struct _I8042_HOOK_WORKITEM
|
||||||
#define CTRL_WRITE_MOUSE 0xD4
|
#define CTRL_WRITE_MOUSE 0xD4
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Keyboard commands
|
* Keyboard commands
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define KBD_CMD_SET_LEDS 0xED
|
#define KBD_CMD_SET_LEDS 0xED
|
||||||
#define KBD_CMD_GET_ID 0xF2
|
#define KBD_CMD_GET_ID 0xF2
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Keyboard responses
|
* Keyboard responses
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define KBD_SELF_TEST_OK 0x55
|
#define KBD_SELF_TEST_OK 0x55
|
||||||
#define KBD_ACK 0xFA
|
#define KBD_ACK 0xFA
|
||||||
|
@ -246,8 +246,8 @@ typedef struct _I8042_HOOK_WORKITEM
|
||||||
#define KBD_RESEND 0xFE
|
#define KBD_RESEND 0xFE
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Controller status register bits
|
* Controller status register bits
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define KBD_OBF 0x01
|
#define KBD_OBF 0x01
|
||||||
#define KBD_IBF 0x02
|
#define KBD_IBF 0x02
|
||||||
|
@ -255,8 +255,8 @@ typedef struct _I8042_HOOK_WORKITEM
|
||||||
#define KBD_PERR 0x80
|
#define KBD_PERR 0x80
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Controller command byte bits
|
* Controller command byte bits
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define CCB_KBD_INT_ENAB 0x01
|
#define CCB_KBD_INT_ENAB 0x01
|
||||||
#define CCB_MOUSE_INT_ENAB 0x02
|
#define CCB_MOUSE_INT_ENAB 0x02
|
||||||
|
@ -266,31 +266,31 @@ typedef struct _I8042_HOOK_WORKITEM
|
||||||
#define CCB_TRANSLATE 0x40
|
#define CCB_TRANSLATE 0x40
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* LED bits
|
* LED bits
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define KBD_LED_SCROLL 0x01
|
#define KBD_LED_SCROLL 0x01
|
||||||
#define KBD_LED_NUM 0x02
|
#define KBD_LED_NUM 0x02
|
||||||
#define KBD_LED_CAPS 0x04
|
#define KBD_LED_CAPS 0x04
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Mouse commands
|
* Mouse commands
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define MOU_ENAB 0xF4
|
#define MOU_ENAB 0xF4
|
||||||
#define MOU_CMD_RESET 0xFF
|
#define MOU_CMD_RESET 0xFF
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Mouse responses
|
* Mouse responses
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
#define MOUSE_ACK 0xFA
|
#define MOUSE_ACK 0xFA
|
||||||
#define MOUSE_ERROR 0xFC
|
#define MOUSE_ERROR 0xFC
|
||||||
#define MOUSE_NACK 0xFE
|
#define MOUSE_NACK 0xFE
|
||||||
|
|
||||||
/*-----------------------------------------------------
|
/*-----------------------------------------------------
|
||||||
* Prototypes
|
* Prototypes
|
||||||
* --------------------------------------------------*/
|
* --------------------------------------------------*/
|
||||||
|
|
||||||
/* createclose.c */
|
/* createclose.c */
|
||||||
|
|
||||||
|
@ -305,9 +305,10 @@ DRIVER_DISPATCH i8042Close;
|
||||||
/* keyboard.c */
|
/* keyboard.c */
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042SynchWritePortKbd(IN PVOID Context,
|
i8042SynchWritePortKbd(
|
||||||
IN UCHAR Value,
|
IN PVOID Context,
|
||||||
IN BOOLEAN WaitForAck);
|
IN UCHAR Value,
|
||||||
|
IN BOOLEAN WaitForAck);
|
||||||
|
|
||||||
DRIVER_STARTIO i8042KbdStartIo;
|
DRIVER_STARTIO i8042KbdStartIo;
|
||||||
|
|
||||||
|
@ -322,15 +323,17 @@ KSERVICE_ROUTINE i8042KbdInterruptService;
|
||||||
DRIVER_ADD_DEVICE i8042AddDevice;
|
DRIVER_ADD_DEVICE i8042AddDevice;
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042PacketIsr(
|
||||||
IN UCHAR Output);
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
IN UCHAR Output);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042StartPacket(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042StartPacket(
|
||||||
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN PUCHAR Bytes,
|
IN PFDO_DEVICE_EXTENSION FdoDeviceExtension,
|
||||||
IN ULONG ByteCount,
|
IN PUCHAR Bytes,
|
||||||
IN PIRP Irp);
|
IN ULONG ByteCount,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
|
|
||||||
|
@ -339,22 +342,26 @@ DRIVER_DISPATCH ForwardIrpAndForget;
|
||||||
DRIVER_DISPATCH ForwardIrpAndWait;
|
DRIVER_DISPATCH ForwardIrpAndWait;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
DuplicateUnicodeString(IN ULONG Flags,
|
DuplicateUnicodeString(
|
||||||
IN PCUNICODE_STRING SourceString,
|
IN ULONG Flags,
|
||||||
OUT PUNICODE_STRING DestinationString);
|
IN PCUNICODE_STRING SourceString,
|
||||||
|
OUT PUNICODE_STRING DestinationString);
|
||||||
|
|
||||||
/* mouse.c */
|
/* mouse.c */
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
i8042MouHandle(
|
||||||
IN UCHAR Output);
|
IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
||||||
|
IN UCHAR Output);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
i8042MouHandleButtons(
|
||||||
IN USHORT Mask);
|
IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
||||||
|
IN USHORT Mask);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042MouInitialize(IN PI8042_MOUSE_EXTENSION DeviceExtension);
|
i8042MouInitialize(
|
||||||
|
IN PI8042_MOUSE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
DRIVER_DISPATCH i8042MouInternalDeviceControl;
|
DRIVER_DISPATCH i8042MouInternalDeviceControl;
|
||||||
|
|
||||||
|
@ -363,73 +370,86 @@ KSERVICE_ROUTINE i8042MouInterruptService;
|
||||||
/* pnp.c */
|
/* pnp.c */
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042ChangeMode(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ChangeMode(
|
||||||
IN UCHAR FlagsToDisable,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR FlagsToEnable);
|
IN UCHAR FlagsToDisable,
|
||||||
|
IN UCHAR FlagsToEnable);
|
||||||
|
|
||||||
DRIVER_DISPATCH i8042Pnp;
|
DRIVER_DISPATCH i8042Pnp;
|
||||||
|
|
||||||
/* ps2pp.c */
|
/* ps2pp.c */
|
||||||
VOID
|
VOID
|
||||||
i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
i8042MouHandlePs2pp(
|
||||||
IN UCHAR Input);
|
IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
||||||
|
IN UCHAR Input);
|
||||||
|
|
||||||
/* readwrite.c */
|
/* readwrite.c */
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension);
|
i8042Flush(
|
||||||
|
IN PPORT_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042IsrWritePort(
|
||||||
IN UCHAR Value,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR SelectCmd OPTIONAL);
|
IN UCHAR Value,
|
||||||
|
IN UCHAR SelectCmd OPTIONAL);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadData(
|
||||||
IN UCHAR StatusFlags,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
OUT PUCHAR Data);
|
IN UCHAR StatusFlags,
|
||||||
|
OUT PUCHAR Data);
|
||||||
#define i8042ReadKeyboardData(DeviceExtension, Data) \
|
#define i8042ReadKeyboardData(DeviceExtension, Data) \
|
||||||
i8042ReadData(DeviceExtension, KBD_OBF, Data)
|
i8042ReadData(DeviceExtension, KBD_OBF, Data)
|
||||||
#define i8042ReadMouseData(DeviceExtension, Data) \
|
#define i8042ReadMouseData(DeviceExtension, Data) \
|
||||||
i8042ReadData(DeviceExtension, MOU_OBF, Data)
|
i8042ReadData(DeviceExtension, MOU_OBF, Data)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadDataWait(
|
||||||
OUT PUCHAR Data);
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
OUT PUCHAR Data);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadStatus(
|
||||||
OUT PUCHAR Status);
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
OUT PUCHAR Status);
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042SynchReadPort(IN PVOID Context,
|
i8042SynchReadPort(
|
||||||
OUT PUCHAR Value,
|
IN PVOID Context,
|
||||||
IN BOOLEAN WaitForAck);
|
OUT PUCHAR Value,
|
||||||
|
IN BOOLEAN WaitForAck);
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042SynchWritePort(
|
||||||
IN UCHAR Port,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR Value,
|
IN UCHAR Port,
|
||||||
IN BOOLEAN WaitForAck);
|
IN UCHAR Value,
|
||||||
|
IN BOOLEAN WaitForAck);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042Write(
|
||||||
IN PUCHAR addr,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR data);
|
IN PUCHAR addr,
|
||||||
|
IN UCHAR data);
|
||||||
|
|
||||||
/* registry.c */
|
/* registry.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ReadRegistryEntries(IN PUNICODE_STRING RegistryPath,
|
ReadRegistryEntries(
|
||||||
OUT PI8042_SETTINGS Settings);
|
IN PUNICODE_STRING RegistryPath,
|
||||||
|
OUT PI8042_SETTINGS Settings);
|
||||||
|
|
||||||
/* setup.c */
|
/* setup.c */
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsFirstStageSetup(VOID);
|
IsFirstStageSetup(
|
||||||
|
VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042AddLegacyKeyboard(IN PDRIVER_OBJECT DriverObject,
|
i8042AddLegacyKeyboard(
|
||||||
IN PUNICODE_STRING RegistryPath);
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath);
|
||||||
|
|
||||||
#endif // _I8042PRT_H_
|
#endif // _I8042PRT_H_
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,71 +13,74 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject,
|
ForwardIrpAndWait(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||||
|
|
||||||
ASSERT(LowerDevice);
|
ASSERT(LowerDevice);
|
||||||
|
|
||||||
if (!IoForwardIrpSynchronously(LowerDevice, Irp))
|
if (!IoForwardIrpSynchronously(LowerDevice, Irp))
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
return Irp->IoStatus.Status;
|
return Irp->IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject,
|
ForwardIrpAndForget(
|
||||||
IN PIRP Irp)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||||
|
|
||||||
ASSERT(LowerDevice);
|
ASSERT(LowerDevice);
|
||||||
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
return IoCallDriver(LowerDevice, Irp);
|
return IoCallDriver(LowerDevice, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
DuplicateUnicodeString(IN ULONG Flags,
|
DuplicateUnicodeString(
|
||||||
IN PCUNICODE_STRING SourceString,
|
IN ULONG Flags,
|
||||||
OUT PUNICODE_STRING DestinationString)
|
IN PCUNICODE_STRING SourceString,
|
||||||
|
OUT PUNICODE_STRING DestinationString)
|
||||||
{
|
{
|
||||||
if (SourceString == NULL || DestinationString == NULL
|
if (SourceString == NULL || DestinationString == NULL
|
||||||
|| SourceString->Length > SourceString->MaximumLength
|
|| SourceString->Length > SourceString->MaximumLength
|
||||||
|| (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
|
|| (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
|
||||||
|| Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
|
|| Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((SourceString->Length == 0)
|
if ((SourceString->Length == 0)
|
||||||
&& (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
|
&& (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
|
||||||
RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
|
RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
|
||||||
{
|
{
|
||||||
DestinationString->Length = 0;
|
DestinationString->Length = 0;
|
||||||
DestinationString->MaximumLength = 0;
|
DestinationString->MaximumLength = 0;
|
||||||
DestinationString->Buffer = NULL;
|
DestinationString->Buffer = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
USHORT DestMaxLength = SourceString->Length;
|
USHORT DestMaxLength = SourceString->Length;
|
||||||
|
|
||||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||||
DestMaxLength += sizeof(UNICODE_NULL);
|
DestMaxLength += sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, I8042PRT_TAG);
|
DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, I8042PRT_TAG);
|
||||||
if (DestinationString->Buffer == NULL)
|
if (DestinationString->Buffer == NULL)
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
|
RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
|
||||||
DestinationString->Length = SourceString->Length;
|
DestinationString->Length = SourceString->Length;
|
||||||
DestinationString->MaximumLength = DestMaxLength;
|
DestinationString->MaximumLength = DestMaxLength;
|
||||||
|
|
||||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||||
DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
|
DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -14,124 +14,125 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
i8042MouHandlePs2pp(
|
||||||
IN UCHAR Input)
|
IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
||||||
|
IN UCHAR Input)
|
||||||
{
|
{
|
||||||
UCHAR PktType;
|
UCHAR PktType;
|
||||||
PMOUSE_INPUT_DATA MouseInput;
|
PMOUSE_INPUT_DATA MouseInput;
|
||||||
|
|
||||||
MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
|
MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
|
||||||
|
|
||||||
/* First, collect 3 bytes for a packet
|
/* First, collect 3 bytes for a packet
|
||||||
* We can detect out-of-sync only by checking
|
* We can detect out-of-sync only by checking
|
||||||
* the whole packet anyway.
|
* the whole packet anyway.
|
||||||
*
|
*
|
||||||
* If bit 7 and 8 of the first byte are 0, its
|
* If bit 7 and 8 of the first byte are 0, its
|
||||||
* a normal packet.
|
* a normal packet.
|
||||||
*
|
*
|
||||||
* Otherwise, the packet is different, like this:
|
* Otherwise, the packet is different, like this:
|
||||||
* 1: E 1 b3 b2 x x x x
|
* 1: E 1 b3 b2 x x x x
|
||||||
* 2: x x b1 b0 x1 x0 1 0
|
* 2: x x b1 b0 x1 x0 1 0
|
||||||
* 3: x x x x x x x1 x0
|
* 3: x x x x x x x1 x0
|
||||||
*
|
*
|
||||||
* b3-0 form a code that specifies the packet type:
|
* b3-0 form a code that specifies the packet type:
|
||||||
*
|
*
|
||||||
* 0 Device Type
|
* 0 Device Type
|
||||||
* 1 Rollers and buttons
|
* 1 Rollers and buttons
|
||||||
* 2 Reserved
|
* 2 Reserved
|
||||||
* 3 Reserved
|
* 3 Reserved
|
||||||
* 4 Device ID
|
* 4 Device ID
|
||||||
* 5 Channel & Battery
|
* 5 Channel & Battery
|
||||||
* 6 Wireless notifications
|
* 6 Wireless notifications
|
||||||
* 7 Reserved
|
* 7 Reserved
|
||||||
* 8 ShortID LSB (ShortID is a number that is supposed to differentiate
|
* 8 ShortID LSB (ShortID is a number that is supposed to differentiate
|
||||||
* 9 ShortID MSB between your mouse and your neighbours')
|
* 9 ShortID MSB between your mouse and your neighbours')
|
||||||
* 10 Reserved
|
* 10 Reserved
|
||||||
* 11 Mouse capabilities
|
* 11 Mouse capabilities
|
||||||
* 12 Remote control LSB
|
* 12 Remote control LSB
|
||||||
* 13 Remote control MSB
|
* 13 Remote control MSB
|
||||||
* 14 Reserved
|
* 14 Reserved
|
||||||
* 15 Extended packet
|
* 15 Extended packet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (DeviceExtension->MouseState)
|
switch (DeviceExtension->MouseState)
|
||||||
{
|
{
|
||||||
case MouseIdle:
|
case MouseIdle:
|
||||||
case XMovement:
|
case XMovement:
|
||||||
DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
|
DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
|
||||||
DeviceExtension->MouseState++;
|
DeviceExtension->MouseState++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case YMovement:
|
case YMovement:
|
||||||
DeviceExtension->MouseLogiBuffer[2] = Input;
|
DeviceExtension->MouseLogiBuffer[2] = Input;
|
||||||
DeviceExtension->MouseState = MouseIdle;
|
DeviceExtension->MouseState = MouseIdle;
|
||||||
|
|
||||||
/* first check if it's a normal packet */
|
/* first check if it's a normal packet */
|
||||||
|
|
||||||
if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
|
if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
|
||||||
{
|
{
|
||||||
DeviceExtension->MouseState = MouseIdle;
|
DeviceExtension->MouseState = MouseIdle;
|
||||||
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
|
||||||
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
|
||||||
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
|
||||||
/* We could care about wether MouseState really
|
/* We could care about wether MouseState really
|
||||||
* advances, but we don't need to because we're
|
* advances, but we don't need to because we're
|
||||||
* only doing three bytes anyway, so the packet
|
* only doing three bytes anyway, so the packet
|
||||||
* will never complete if it's broken.
|
* will never complete if it's broken.
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
|
if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
|
||||||
(((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
|
(((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
|
||||||
(DeviceExtension->MouseLogiBuffer[2] & 0x03)))
|
(DeviceExtension->MouseLogiBuffer[2] & 0x03)))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
|
WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now get the packet type */
|
/* Now get the packet type */
|
||||||
PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) &
|
PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) &
|
||||||
((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6);
|
((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6);
|
||||||
|
|
||||||
switch (PktType)
|
switch (PktType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
/* The packet contains the device ID, but we
|
/* The packet contains the device ID, but we
|
||||||
* already read that in the initialization
|
* already read that in the initialization
|
||||||
* sequence. Ignore it.
|
* sequence. Ignore it.
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
|
RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
|
||||||
if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
|
||||||
MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
|
MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
|
||||||
|
|
||||||
if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
|
||||||
MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
|
MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
|
||||||
|
|
||||||
if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
|
||||||
{
|
{
|
||||||
MouseInput->ButtonFlags |= MOUSE_WHEEL;
|
MouseInput->ButtonFlags |= MOUSE_WHEEL;
|
||||||
if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
|
||||||
MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
|
MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
|
||||||
else
|
else
|
||||||
MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
|
MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
|
||||||
}
|
}
|
||||||
i8042MouHandleButtons(
|
i8042MouHandleButtons(
|
||||||
DeviceExtension,
|
DeviceExtension,
|
||||||
MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
|
MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
|
||||||
DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
|
DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
/* These are for things that would probably
|
/* These are for things that would probably
|
||||||
* be handled by logitechs own driver.
|
* be handled by logitechs own driver.
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
|
WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,197 +16,205 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
|
i8042Flush(
|
||||||
|
IN PPORT_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
UCHAR Ignore;
|
UCHAR Ignore;
|
||||||
|
|
||||||
/* Flush output buffer */
|
/* Flush output buffer */
|
||||||
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) {
|
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) {
|
||||||
KeStallExecutionProcessor(50);
|
KeStallExecutionProcessor(50);
|
||||||
TRACE_(I8042PRT, "Output data flushed\n");
|
TRACE_(I8042PRT, "Output data flushed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush input buffer */
|
/* Flush input buffer */
|
||||||
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) {
|
while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) {
|
||||||
KeStallExecutionProcessor(50);
|
KeStallExecutionProcessor(50);
|
||||||
TRACE_(I8042PRT, "Input data flushed\n");
|
TRACE_(I8042PRT, "Input data flushed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042IsrWritePort(
|
||||||
IN UCHAR Value,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR SelectCmd OPTIONAL)
|
IN UCHAR Value,
|
||||||
|
IN UCHAR SelectCmd OPTIONAL)
|
||||||
{
|
{
|
||||||
if (SelectCmd)
|
if (SelectCmd)
|
||||||
if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd))
|
if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return i8042Write(DeviceExtension, DeviceExtension->DataPort, Value);
|
return i8042Write(DeviceExtension, DeviceExtension->DataPort, Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Read data from port 0x60
|
* FUNCTION: Read data from port 0x60
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadData(
|
||||||
IN UCHAR StatusFlags,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
OUT PUCHAR Data)
|
IN UCHAR StatusFlags,
|
||||||
|
OUT PUCHAR Data)
|
||||||
{
|
{
|
||||||
UCHAR PortStatus;
|
UCHAR PortStatus;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = i8042ReadStatus(DeviceExtension, &PortStatus);
|
Status = i8042ReadStatus(DeviceExtension, &PortStatus);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
// If data is available
|
// If data is available
|
||||||
if (PortStatus & StatusFlags)
|
if (PortStatus & StatusFlags)
|
||||||
{
|
{
|
||||||
*Data = READ_PORT_UCHAR(DeviceExtension->DataPort);
|
*Data = READ_PORT_UCHAR(DeviceExtension->DataPort);
|
||||||
INFO_(I8042PRT, "Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus);
|
INFO_(I8042PRT, "Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus);
|
||||||
|
|
||||||
// If the data is valid (not timeout, not parity error)
|
// If the data is valid (not timeout, not parity error)
|
||||||
if ((PortStatus & KBD_PERR) == 0)
|
if ((PortStatus & KBD_PERR) == 0)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadStatus(
|
||||||
OUT PUCHAR Status)
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
OUT PUCHAR Status)
|
||||||
{
|
{
|
||||||
ASSERT(DeviceExtension->ControlPort != NULL);
|
ASSERT(DeviceExtension->ControlPort != NULL);
|
||||||
*Status = READ_PORT_UCHAR(DeviceExtension->ControlPort);
|
*Status = READ_PORT_UCHAR(DeviceExtension->ControlPort);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Read data from data port
|
* FUNCTION: Read data from data port
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042ReadDataWait(
|
||||||
OUT PUCHAR Data)
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
OUT PUCHAR Data)
|
||||||
{
|
{
|
||||||
ULONG Counter;
|
ULONG Counter;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Counter = DeviceExtension->Settings.PollingIterations;
|
Counter = DeviceExtension->Settings.PollingIterations;
|
||||||
|
|
||||||
while (Counter--)
|
while (Counter--)
|
||||||
{
|
{
|
||||||
Status = i8042ReadKeyboardData(DeviceExtension, Data);
|
Status = i8042ReadKeyboardData(DeviceExtension, Data);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
KeStallExecutionProcessor(50);
|
KeStallExecutionProcessor(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Timed out */
|
/* Timed out */
|
||||||
return STATUS_IO_TIMEOUT;
|
return STATUS_IO_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This one reads a value from the port; You don't have to specify
|
* This one reads a value from the port; You don't have to specify
|
||||||
* which one, it'll always be from the one you talked to, so one function
|
* which one, it'll always be from the one you talked to, so one function
|
||||||
* is enough this time. Note how MSDN specifies the
|
* is enough this time. Note how MSDN specifies the
|
||||||
* WaitForAck parameter to be ignored.
|
* WaitForAck parameter to be ignored.
|
||||||
*/
|
*/
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042SynchReadPort(IN PVOID Context,
|
i8042SynchReadPort(
|
||||||
OUT PUCHAR Value,
|
IN PVOID Context,
|
||||||
IN BOOLEAN WaitForAck)
|
OUT PUCHAR Value,
|
||||||
|
IN BOOLEAN WaitForAck)
|
||||||
{
|
{
|
||||||
PPORT_DEVICE_EXTENSION DeviceExtension;
|
PPORT_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PPORT_DEVICE_EXTENSION)Context;
|
DeviceExtension = (PPORT_DEVICE_EXTENSION)Context;
|
||||||
|
|
||||||
return i8042ReadDataWait(DeviceExtension, Value);
|
return i8042ReadDataWait(DeviceExtension, Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions are callbacks for filter driver custom
|
* These functions are callbacks for filter driver custom
|
||||||
* initialization routines.
|
* initialization routines.
|
||||||
*/
|
*/
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042SynchWritePort(
|
||||||
IN UCHAR Port,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR Value,
|
IN UCHAR Port,
|
||||||
IN BOOLEAN WaitForAck)
|
IN UCHAR Value,
|
||||||
|
IN BOOLEAN WaitForAck)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UCHAR Ack;
|
UCHAR Ack;
|
||||||
ULONG ResendIterations;
|
ULONG ResendIterations;
|
||||||
|
|
||||||
ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
|
ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (Port)
|
if (Port)
|
||||||
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port))
|
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "Failed to write Port\n");
|
WARN_(I8042PRT, "Failed to write Port\n");
|
||||||
return STATUS_IO_TIMEOUT;
|
return STATUS_IO_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value))
|
if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "Failed to write Value\n");
|
WARN_(I8042PRT, "Failed to write Value\n");
|
||||||
return STATUS_IO_TIMEOUT;
|
return STATUS_IO_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WaitForAck)
|
if (WaitForAck)
|
||||||
{
|
{
|
||||||
Status = i8042ReadDataWait(DeviceExtension, &Ack);
|
Status = i8042ReadDataWait(DeviceExtension, &Ack);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "Failed to read Ack\n");
|
WARN_(I8042PRT, "Failed to read Ack\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
if (Ack == KBD_ACK)
|
if (Ack == KBD_ACK)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
else if (Ack == KBD_RESEND)
|
else if (Ack == KBD_RESEND)
|
||||||
INFO_(I8042PRT, "i8042 asks for a data resend\n");
|
INFO_(I8042PRT, "i8042 asks for a data resend\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
TRACE_(I8042PRT, "Reiterating\n");
|
TRACE_(I8042PRT, "Reiterating\n");
|
||||||
ResendIterations--;
|
ResendIterations--;
|
||||||
} while (ResendIterations);
|
} while (ResendIterations);
|
||||||
|
|
||||||
return STATUS_IO_TIMEOUT;
|
return STATUS_IO_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Write data to a port, waiting first for it to become ready
|
* FUNCTION: Write data to a port, waiting first for it to become ready
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
i8042Write(
|
||||||
IN PUCHAR addr,
|
IN PPORT_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN UCHAR data)
|
IN PUCHAR addr,
|
||||||
|
IN UCHAR data)
|
||||||
{
|
{
|
||||||
ULONG Counter;
|
ULONG Counter;
|
||||||
|
|
||||||
ASSERT(addr);
|
ASSERT(addr);
|
||||||
ASSERT(DeviceExtension->ControlPort != NULL);
|
ASSERT(DeviceExtension->ControlPort != NULL);
|
||||||
|
|
||||||
Counter = DeviceExtension->Settings.PollingIterations;
|
Counter = DeviceExtension->Settings.PollingIterations;
|
||||||
|
|
||||||
while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) &&
|
while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) &&
|
||||||
(Counter--))
|
(Counter--))
|
||||||
{
|
{
|
||||||
KeStallExecutionProcessor(50);
|
KeStallExecutionProcessor(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Counter)
|
if (Counter)
|
||||||
{
|
{
|
||||||
WRITE_PORT_UCHAR(addr, data);
|
WRITE_PORT_UCHAR(addr, data);
|
||||||
INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr);
|
INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,215 +16,216 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ReadRegistryEntries(IN PUNICODE_STRING RegistryPath,
|
ReadRegistryEntries(
|
||||||
OUT PI8042_SETTINGS Settings)
|
IN PUNICODE_STRING RegistryPath,
|
||||||
|
OUT PI8042_SETTINGS Settings)
|
||||||
{
|
{
|
||||||
RTL_QUERY_REGISTRY_TABLE Parameters[17];
|
RTL_QUERY_REGISTRY_TABLE Parameters[17];
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ULONG DefaultKeyboardDataQueueSize = 0x64;
|
ULONG DefaultKeyboardDataQueueSize = 0x64;
|
||||||
PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort";
|
PCWSTR DefaultKeyboardDeviceBaseName = L"KeyboardPort";
|
||||||
ULONG DefaultMouseDataQueueSize = 0x64;
|
ULONG DefaultMouseDataQueueSize = 0x64;
|
||||||
ULONG DefaultMouseResolution = 3;
|
ULONG DefaultMouseResolution = 3;
|
||||||
ULONG DefaultMouseSynchIn100ns = 20000000;
|
ULONG DefaultMouseSynchIn100ns = 20000000;
|
||||||
ULONG DefaultNumberOfButtons = 2;
|
ULONG DefaultNumberOfButtons = 2;
|
||||||
PCWSTR DefaultPointerDeviceBaseName = L"PointerPort";
|
PCWSTR DefaultPointerDeviceBaseName = L"PointerPort";
|
||||||
ULONG DefaultPollStatusIterations = 1;
|
ULONG DefaultPollStatusIterations = 1;
|
||||||
ULONG DefaultOverrideKeyboardType = 4;
|
ULONG DefaultOverrideKeyboardType = 4;
|
||||||
ULONG DefaultOverrideKeyboardSubtype = 0;
|
ULONG DefaultOverrideKeyboardSubtype = 0;
|
||||||
ULONG DefaultPollingIterations = 12000;
|
ULONG DefaultPollingIterations = 12000;
|
||||||
ULONG DefaultPollingIterationsMaximum = 12000;
|
ULONG DefaultPollingIterationsMaximum = 12000;
|
||||||
ULONG DefaultResendIterations = 0x3;
|
ULONG DefaultResendIterations = 0x3;
|
||||||
ULONG DefaultSampleRate = 60;
|
ULONG DefaultSampleRate = 60;
|
||||||
ULONG DefaultCrashOnCtrlScroll;
|
ULONG DefaultCrashOnCtrlScroll;
|
||||||
|
|
||||||
/* Default value for CrashOnCtrlScroll depends if we're
|
/* Default value for CrashOnCtrlScroll depends if we're
|
||||||
* running a debug build or a normal build.
|
* running a debug build or a normal build.
|
||||||
*/
|
*/
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
DefaultCrashOnCtrlScroll = 1;
|
DefaultCrashOnCtrlScroll = 1;
|
||||||
#else
|
#else
|
||||||
DefaultCrashOnCtrlScroll = 0;
|
DefaultCrashOnCtrlScroll = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RtlZeroMemory(Parameters, sizeof(Parameters));
|
RtlZeroMemory(Parameters, sizeof(Parameters));
|
||||||
|
|
||||||
Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
|
Parameters[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
|
||||||
Parameters[0].Name = L"Parameters";
|
Parameters[0].Name = L"Parameters";
|
||||||
|
|
||||||
Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[1].Name = L"KeyboardDataQueueSize";
|
Parameters[1].Name = L"KeyboardDataQueueSize";
|
||||||
Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize;
|
Parameters[1].EntryContext = &Settings->KeyboardDataQueueSize;
|
||||||
Parameters[1].DefaultType = REG_DWORD;
|
Parameters[1].DefaultType = REG_DWORD;
|
||||||
Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize;
|
Parameters[1].DefaultData = &DefaultKeyboardDataQueueSize;
|
||||||
Parameters[1].DefaultLength = sizeof(ULONG);
|
Parameters[1].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[2].Name = L"KeyboardDeviceBaseName";
|
Parameters[2].Name = L"KeyboardDeviceBaseName";
|
||||||
Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName;
|
Parameters[2].EntryContext = &Settings->KeyboardDeviceBaseName;
|
||||||
Parameters[2].DefaultType = REG_SZ;
|
Parameters[2].DefaultType = REG_SZ;
|
||||||
Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName;
|
Parameters[2].DefaultData = (PVOID)DefaultKeyboardDeviceBaseName;
|
||||||
Parameters[2].DefaultLength = 0;
|
Parameters[2].DefaultLength = 0;
|
||||||
|
|
||||||
Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[3].Name = L"MouseDataQueueSize";
|
Parameters[3].Name = L"MouseDataQueueSize";
|
||||||
Parameters[3].EntryContext = &Settings->MouseDataQueueSize;
|
Parameters[3].EntryContext = &Settings->MouseDataQueueSize;
|
||||||
Parameters[3].DefaultType = REG_DWORD;
|
Parameters[3].DefaultType = REG_DWORD;
|
||||||
Parameters[3].DefaultData = &DefaultMouseDataQueueSize;
|
Parameters[3].DefaultData = &DefaultMouseDataQueueSize;
|
||||||
Parameters[3].DefaultLength = sizeof(ULONG);
|
Parameters[3].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[4].Name = L"MouseResolution";
|
Parameters[4].Name = L"MouseResolution";
|
||||||
Parameters[4].EntryContext = &Settings->MouseResolution;
|
Parameters[4].EntryContext = &Settings->MouseResolution;
|
||||||
Parameters[4].DefaultType = REG_DWORD;
|
Parameters[4].DefaultType = REG_DWORD;
|
||||||
Parameters[4].DefaultData = &DefaultMouseResolution;
|
Parameters[4].DefaultData = &DefaultMouseResolution;
|
||||||
Parameters[4].DefaultLength = sizeof(ULONG);
|
Parameters[4].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[5].Name = L"MouseSynchIn100ns";
|
Parameters[5].Name = L"MouseSynchIn100ns";
|
||||||
Parameters[5].EntryContext = &Settings->MouseSynchIn100ns;
|
Parameters[5].EntryContext = &Settings->MouseSynchIn100ns;
|
||||||
Parameters[5].DefaultType = REG_DWORD;
|
Parameters[5].DefaultType = REG_DWORD;
|
||||||
Parameters[5].DefaultData = &DefaultMouseSynchIn100ns;
|
Parameters[5].DefaultData = &DefaultMouseSynchIn100ns;
|
||||||
Parameters[5].DefaultLength = sizeof(ULONG);
|
Parameters[5].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[6].Name = L"NumberOfButtons";
|
Parameters[6].Name = L"NumberOfButtons";
|
||||||
Parameters[6].EntryContext = &Settings->NumberOfButtons;
|
Parameters[6].EntryContext = &Settings->NumberOfButtons;
|
||||||
Parameters[6].DefaultType = REG_DWORD;
|
Parameters[6].DefaultType = REG_DWORD;
|
||||||
Parameters[6].DefaultData = &DefaultNumberOfButtons;
|
Parameters[6].DefaultData = &DefaultNumberOfButtons;
|
||||||
Parameters[6].DefaultLength = sizeof(ULONG);
|
Parameters[6].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[7].Name = L"PointerDeviceBaseName";
|
Parameters[7].Name = L"PointerDeviceBaseName";
|
||||||
Parameters[7].EntryContext = &Settings->PointerDeviceBaseName;
|
Parameters[7].EntryContext = &Settings->PointerDeviceBaseName;
|
||||||
Parameters[7].DefaultType = REG_SZ;
|
Parameters[7].DefaultType = REG_SZ;
|
||||||
Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName;
|
Parameters[7].DefaultData = (PVOID)DefaultPointerDeviceBaseName;
|
||||||
Parameters[7].DefaultLength = 0;
|
Parameters[7].DefaultLength = 0;
|
||||||
|
|
||||||
Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[8].Name = L"PollStatusIterations";
|
Parameters[8].Name = L"PollStatusIterations";
|
||||||
Parameters[8].EntryContext = &Settings->PollStatusIterations;
|
Parameters[8].EntryContext = &Settings->PollStatusIterations;
|
||||||
Parameters[8].DefaultType = REG_DWORD;
|
Parameters[8].DefaultType = REG_DWORD;
|
||||||
Parameters[8].DefaultData = &DefaultPollStatusIterations;
|
Parameters[8].DefaultData = &DefaultPollStatusIterations;
|
||||||
Parameters[8].DefaultLength = sizeof(ULONG);
|
Parameters[8].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[9].Name = L"OverrideKeyboardType";
|
Parameters[9].Name = L"OverrideKeyboardType";
|
||||||
Parameters[9].EntryContext = &Settings->OverrideKeyboardType;
|
Parameters[9].EntryContext = &Settings->OverrideKeyboardType;
|
||||||
Parameters[9].DefaultType = REG_DWORD;
|
Parameters[9].DefaultType = REG_DWORD;
|
||||||
Parameters[9].DefaultData = &DefaultOverrideKeyboardType;
|
Parameters[9].DefaultData = &DefaultOverrideKeyboardType;
|
||||||
Parameters[9].DefaultLength = sizeof(ULONG);
|
Parameters[9].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[10].Name = L"OverrideKeyboardSubtype";
|
Parameters[10].Name = L"OverrideKeyboardSubtype";
|
||||||
Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype;
|
Parameters[10].EntryContext = &Settings->OverrideKeyboardSubtype;
|
||||||
Parameters[10].DefaultType = REG_DWORD;
|
Parameters[10].DefaultType = REG_DWORD;
|
||||||
Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype;
|
Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype;
|
||||||
Parameters[10].DefaultLength = sizeof(ULONG);
|
Parameters[10].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[11].Name = L"PollingIterations";
|
Parameters[11].Name = L"PollingIterations";
|
||||||
Parameters[11].EntryContext = &Settings->PollingIterations;
|
Parameters[11].EntryContext = &Settings->PollingIterations;
|
||||||
Parameters[11].DefaultType = REG_DWORD;
|
Parameters[11].DefaultType = REG_DWORD;
|
||||||
Parameters[11].DefaultData = &DefaultPollingIterations;
|
Parameters[11].DefaultData = &DefaultPollingIterations;
|
||||||
Parameters[11].DefaultLength = sizeof(ULONG);
|
Parameters[11].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[12].Name = L"PollingIterationsMaximum";
|
Parameters[12].Name = L"PollingIterationsMaximum";
|
||||||
Parameters[12].EntryContext = &Settings->PollingIterationsMaximum;
|
Parameters[12].EntryContext = &Settings->PollingIterationsMaximum;
|
||||||
Parameters[12].DefaultType = REG_DWORD;
|
Parameters[12].DefaultType = REG_DWORD;
|
||||||
Parameters[12].DefaultData = &DefaultPollingIterationsMaximum;
|
Parameters[12].DefaultData = &DefaultPollingIterationsMaximum;
|
||||||
Parameters[12].DefaultLength = sizeof(ULONG);
|
Parameters[12].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[13].Name = L"ResendIterations";
|
Parameters[13].Name = L"ResendIterations";
|
||||||
Parameters[13].EntryContext = &Settings->ResendIterations;
|
Parameters[13].EntryContext = &Settings->ResendIterations;
|
||||||
Parameters[13].DefaultType = REG_DWORD;
|
Parameters[13].DefaultType = REG_DWORD;
|
||||||
Parameters[13].DefaultData = &DefaultResendIterations;
|
Parameters[13].DefaultData = &DefaultResendIterations;
|
||||||
Parameters[13].DefaultLength = sizeof(ULONG);
|
Parameters[13].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[14].Name = L"SampleRate";
|
Parameters[14].Name = L"SampleRate";
|
||||||
Parameters[14].EntryContext = &Settings->SampleRate;
|
Parameters[14].EntryContext = &Settings->SampleRate;
|
||||||
Parameters[14].DefaultType = REG_DWORD;
|
Parameters[14].DefaultType = REG_DWORD;
|
||||||
Parameters[14].DefaultData = &DefaultSampleRate;
|
Parameters[14].DefaultData = &DefaultSampleRate;
|
||||||
Parameters[14].DefaultLength = sizeof(ULONG);
|
Parameters[14].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL;
|
||||||
Parameters[15].Name = L"CrashOnCtrlScroll";
|
Parameters[15].Name = L"CrashOnCtrlScroll";
|
||||||
Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll;
|
Parameters[15].EntryContext = &Settings->CrashOnCtrlScroll;
|
||||||
Parameters[15].DefaultType = REG_DWORD;
|
Parameters[15].DefaultType = REG_DWORD;
|
||||||
Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll;
|
Parameters[15].DefaultData = &DefaultCrashOnCtrlScroll;
|
||||||
Parameters[15].DefaultLength = sizeof(ULONG);
|
Parameters[15].DefaultLength = sizeof(ULONG);
|
||||||
|
|
||||||
Status = RtlQueryRegistryValues(
|
Status = RtlQueryRegistryValues(
|
||||||
RTL_REGISTRY_ABSOLUTE,
|
RTL_REGISTRY_ABSOLUTE,
|
||||||
RegistryPath->Buffer,
|
RegistryPath->Buffer,
|
||||||
Parameters,
|
Parameters,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Check values */
|
/* Check values */
|
||||||
if (Settings->KeyboardDataQueueSize < 1)
|
if (Settings->KeyboardDataQueueSize < 1)
|
||||||
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
|
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
|
||||||
if (Settings->MouseDataQueueSize < 1)
|
if (Settings->MouseDataQueueSize < 1)
|
||||||
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
|
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
|
||||||
if (Settings->NumberOfButtons < 1)
|
if (Settings->NumberOfButtons < 1)
|
||||||
Settings->NumberOfButtons = DefaultNumberOfButtons;
|
Settings->NumberOfButtons = DefaultNumberOfButtons;
|
||||||
if (Settings->PollingIterations < 0x400)
|
if (Settings->PollingIterations < 0x400)
|
||||||
Settings->PollingIterations = DefaultPollingIterations;
|
Settings->PollingIterations = DefaultPollingIterations;
|
||||||
if (Settings->PollingIterationsMaximum < 0x400)
|
if (Settings->PollingIterationsMaximum < 0x400)
|
||||||
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
|
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
|
||||||
if (Settings->ResendIterations < 1)
|
if (Settings->ResendIterations < 1)
|
||||||
Settings->ResendIterations = DefaultResendIterations;
|
Settings->ResendIterations = DefaultResendIterations;
|
||||||
}
|
}
|
||||||
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
{
|
{
|
||||||
/* Registry path doesn't exist. Set defaults */
|
/* Registry path doesn't exist. Set defaults */
|
||||||
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
|
Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize;
|
||||||
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
|
Settings->MouseDataQueueSize = DefaultMouseDataQueueSize;
|
||||||
Settings->MouseResolution = DefaultMouseResolution;
|
Settings->MouseResolution = DefaultMouseResolution;
|
||||||
Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns;
|
Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns;
|
||||||
Settings->NumberOfButtons = DefaultNumberOfButtons;
|
Settings->NumberOfButtons = DefaultNumberOfButtons;
|
||||||
Settings->PollStatusIterations = DefaultPollStatusIterations;
|
Settings->PollStatusIterations = DefaultPollStatusIterations;
|
||||||
Settings->OverrideKeyboardType = DefaultOverrideKeyboardType;
|
Settings->OverrideKeyboardType = DefaultOverrideKeyboardType;
|
||||||
Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype;
|
Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype;
|
||||||
Settings->PollingIterations = DefaultPollingIterations;
|
Settings->PollingIterations = DefaultPollingIterations;
|
||||||
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
|
Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum;
|
||||||
Settings->ResendIterations = DefaultResendIterations;
|
Settings->ResendIterations = DefaultResendIterations;
|
||||||
Settings->SampleRate = DefaultSampleRate;
|
Settings->SampleRate = DefaultSampleRate;
|
||||||
Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll;
|
Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll;
|
||||||
if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName)
|
if (!RtlCreateUnicodeString(&Settings->KeyboardDeviceBaseName, DefaultKeyboardDeviceBaseName)
|
||||||
|| !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName))
|
|| !RtlCreateUnicodeString(&Settings->PointerDeviceBaseName, DefaultPointerDeviceBaseName))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n");
|
WARN_(I8042PRT, "RtlCreateUnicodeString() failed\n");
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize);
|
INFO_(I8042PRT, "KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize);
|
||||||
INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName);
|
INFO_(I8042PRT, "KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName);
|
||||||
INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize);
|
INFO_(I8042PRT, "MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize);
|
||||||
INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution);
|
INFO_(I8042PRT, "MouseResolution : 0x%lx\n", Settings->MouseResolution);
|
||||||
INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns);
|
INFO_(I8042PRT, "MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns);
|
||||||
INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons);
|
INFO_(I8042PRT, "NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons);
|
||||||
INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName);
|
INFO_(I8042PRT, "PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName);
|
||||||
INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations);
|
INFO_(I8042PRT, "PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations);
|
||||||
INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType);
|
INFO_(I8042PRT, "OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType);
|
||||||
INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype);
|
INFO_(I8042PRT, "OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype);
|
||||||
INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations);
|
INFO_(I8042PRT, "PollingIterations : 0x%lx\n", Settings->PollingIterations);
|
||||||
INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum);
|
INFO_(I8042PRT, "PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum);
|
||||||
INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations);
|
INFO_(I8042PRT, "ResendIterations : 0x%lx\n", Settings->ResendIterations);
|
||||||
INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate);
|
INFO_(I8042PRT, "SampleRate : %lu\n", Settings->SampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* All this file is a big hack and should be removed one day...
|
* All this file is a big hack and should be removed one day...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
@ -23,247 +23,251 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsFirstStageSetup(VOID)
|
IsFirstStageSetup(
|
||||||
|
VOID)
|
||||||
{
|
{
|
||||||
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
|
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE hSetupKey = (HANDLE)NULL;
|
HANDLE hSetupKey = (HANDLE)NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOLEAN ret = TRUE;
|
BOOLEAN ret = TRUE;
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes);
|
Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
|
||||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
else
|
else
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
|
||||||
if (hSetupKey != (HANDLE)NULL)
|
if (hSetupKey != (HANDLE)NULL)
|
||||||
ZwClose(hSetupKey);
|
ZwClose(hSetupKey);
|
||||||
INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO");
|
INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
SendStartDevice(IN PDRIVER_OBJECT DriverObject,
|
SendStartDevice(
|
||||||
IN PVOID Context,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN ULONG Count)
|
IN PVOID Context,
|
||||||
|
IN ULONG Count)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
PCM_RESOURCE_LIST AllocatedResources = NULL;
|
PCM_RESOURCE_LIST AllocatedResources = NULL;
|
||||||
PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL;
|
PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL;
|
||||||
PDEVICE_OBJECT TopDeviceObject = NULL;
|
PDEVICE_OBJECT TopDeviceObject = NULL;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
ULONG ResourceListSize;
|
ULONG ResourceListSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Pdo = (PDEVICE_OBJECT)Context;
|
Pdo = (PDEVICE_OBJECT)Context;
|
||||||
TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo);
|
TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo);
|
||||||
|
|
||||||
/* Create default resource list */
|
/* Create default resource list */
|
||||||
ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||||||
AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
|
AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
|
||||||
if (!AllocatedResources)
|
if (!AllocatedResources)
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
|
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
AllocatedResources->Count = 1;
|
AllocatedResources->Count = 1;
|
||||||
AllocatedResources->List[0].PartialResourceList.Version = 1;
|
AllocatedResources->List[0].PartialResourceList.Version = 1;
|
||||||
AllocatedResources->List[0].PartialResourceList.Revision = 1;
|
AllocatedResources->List[0].PartialResourceList.Revision = 1;
|
||||||
AllocatedResources->List[0].PartialResourceList.Count = 3;
|
AllocatedResources->List[0].PartialResourceList.Count = 3;
|
||||||
/* Data port */
|
/* Data port */
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1;
|
||||||
/* Control port */
|
/* Control port */
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1;
|
||||||
/* Interrupt */
|
/* Interrupt */
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0;
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1;
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1;
|
||||||
|
|
||||||
/* Create default resource list translated */
|
/* Create default resource list translated */
|
||||||
AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
|
AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG);
|
||||||
if (!AllocatedResourcesTranslated)
|
if (!AllocatedResourcesTranslated)
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
|
WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize);
|
RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize);
|
||||||
AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector(
|
AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector(
|
||||||
Internal, 0,
|
Internal, 0,
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
|
||||||
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector,
|
AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector,
|
||||||
(PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
|
(PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
|
||||||
&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity);
|
&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity);
|
||||||
|
|
||||||
/* Send IRP_MN_START_DEVICE */
|
/* Send IRP_MN_START_DEVICE */
|
||||||
TopDeviceObject = IoGetAttachedDeviceReference(Pdo);
|
TopDeviceObject = IoGetAttachedDeviceReference(Pdo);
|
||||||
KeInitializeEvent(
|
KeInitializeEvent(
|
||||||
&Event,
|
&Event,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
FALSE);
|
||||||
Irp = IoBuildSynchronousFsdRequest(
|
Irp = IoBuildSynchronousFsdRequest(
|
||||||
IRP_MJ_PNP,
|
IRP_MJ_PNP,
|
||||||
TopDeviceObject,
|
TopDeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&Event,
|
&Event,
|
||||||
&IoStatusBlock);
|
&IoStatusBlock);
|
||||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
Stack = IoGetNextIrpStackLocation(Irp);
|
||||||
Stack->MinorFunction = IRP_MN_START_DEVICE;
|
Stack->MinorFunction = IRP_MN_START_DEVICE;
|
||||||
Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources;
|
Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources;
|
||||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated;
|
Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated;
|
||||||
Status = IoCallDriver(TopDeviceObject, Irp);
|
Status = IoCallDriver(TopDeviceObject, Irp);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(
|
KeWaitForSingleObject(
|
||||||
&Event,
|
&Event,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
Status = IoStatusBlock.Status;
|
Status = IoStatusBlock.Status;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (TopDeviceObject)
|
if (TopDeviceObject)
|
||||||
ObDereferenceObject(TopDeviceObject);
|
ObDereferenceObject(TopDeviceObject);
|
||||||
if (AllocatedResources)
|
if (AllocatedResources)
|
||||||
ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG);
|
ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG);
|
||||||
if (AllocatedResourcesTranslated)
|
if (AllocatedResourcesTranslated)
|
||||||
ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG);
|
ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
AddRegistryEntry(IN PCWSTR PortTypeName,
|
AddRegistryEntry(
|
||||||
IN PUNICODE_STRING DeviceName,
|
IN PCWSTR PortTypeName,
|
||||||
IN PCWSTR RegistryPath)
|
IN PUNICODE_STRING DeviceName,
|
||||||
|
IN PCWSTR RegistryPath)
|
||||||
{
|
{
|
||||||
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE hDeviceMapKey = (HANDLE)-1;
|
HANDLE hDeviceMapKey = (HANDLE)-1;
|
||||||
HANDLE hPortKey = (HANDLE)-1;
|
HANDLE hPortKey = (HANDLE)-1;
|
||||||
UNICODE_STRING PortTypeNameU;
|
UNICODE_STRING PortTypeNameU;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
|
RtlInitUnicodeString(&PortTypeNameU, PortTypeName);
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
|
InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL);
|
||||||
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
|
Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (hDeviceMapKey != (HANDLE)-1)
|
if (hDeviceMapKey != (HANDLE)-1)
|
||||||
ZwClose(hDeviceMapKey);
|
ZwClose(hDeviceMapKey);
|
||||||
if (hPortKey != (HANDLE)-1)
|
if (hPortKey != (HANDLE)-1)
|
||||||
ZwClose(hPortKey);
|
ZwClose(hPortKey);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
i8042AddLegacyKeyboard(IN PDRIVER_OBJECT DriverObject,
|
i8042AddLegacyKeyboard(
|
||||||
IN PUNICODE_STRING RegistryPath)
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
|
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042");
|
||||||
PI8042_DEVICE_TYPE DeviceExtension = NULL;
|
PI8042_DEVICE_TYPE DeviceExtension = NULL;
|
||||||
PDEVICE_OBJECT Pdo = NULL;
|
PDEVICE_OBJECT Pdo = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n");
|
TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n");
|
||||||
|
|
||||||
/* Create a named PDO */
|
/* Create a named PDO */
|
||||||
Status = IoCreateDevice(
|
Status = IoCreateDevice(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
sizeof(I8042_DEVICE_TYPE),
|
sizeof(I8042_DEVICE_TYPE),
|
||||||
&KeyboardName,
|
&KeyboardName,
|
||||||
FILE_DEVICE_8042_PORT,
|
FILE_DEVICE_8042_PORT,
|
||||||
FILE_DEVICE_SECURE_OPEN,
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
TRUE,
|
TRUE,
|
||||||
&Pdo);
|
&Pdo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize device extension */
|
/* Initialize device extension */
|
||||||
DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension;
|
DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension;
|
||||||
RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE));
|
RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE));
|
||||||
*DeviceExtension = PhysicalDeviceObject;
|
*DeviceExtension = PhysicalDeviceObject;
|
||||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
/* Add FDO at the top of the PDO */
|
/* Add FDO at the top of the PDO */
|
||||||
Status = i8042AddDevice(DriverObject, Pdo);
|
Status = i8042AddDevice(DriverObject, Pdo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status);
|
WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */
|
/* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */
|
||||||
AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer);
|
AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer);
|
||||||
IoRegisterBootDriverReinitialization(
|
IoRegisterBootDriverReinitialization(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
SendStartDevice,
|
SendStartDevice,
|
||||||
Pdo);
|
Pdo);
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
/* Yes, completly forget the Pdo pointer, as we will never
|
/* Yes, completly forget the Pdo pointer, as we will never
|
||||||
* have to unload this driver during first stage setup.
|
* have to unload this driver during first stage setup.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (Pdo)
|
if (Pdo)
|
||||||
IoDeleteDevice(Pdo);
|
IoDeleteDevice(Pdo);
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue