mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 06:25:49 +00:00
[USB-BRINGUP]
- Fix a few bugs & race condition in the read report routine - mouhid initializes and is able to read input reports - button press / wheel state change is detected - mouse move detection not yet working svn path=/branches/usb-bringup/; revision=54774
This commit is contained in:
parent
012eac6d8f
commit
b27438e17d
2 changed files with 91 additions and 37 deletions
|
@ -30,16 +30,12 @@ static USHORT MouHid_ButtonUpFlags[] =
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MouHid_GetButtonMove(
|
MouHid_GetButtonMove(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
|
||||||
OUT PLONG LastX,
|
OUT PLONG LastX,
|
||||||
OUT PLONG LastY)
|
OUT PLONG LastY)
|
||||||
{
|
{
|
||||||
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* get device extension */
|
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
/* init result */
|
/* init result */
|
||||||
*LastX = 0;
|
*LastX = 0;
|
||||||
*LastY = 0;
|
*LastY = 0;
|
||||||
|
@ -59,19 +55,15 @@ MouHid_GetButtonMove(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MouHid_GetButtonFlags(
|
MouHid_GetButtonFlags(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
|
||||||
OUT PUSHORT ButtonFlags)
|
OUT PUSHORT ButtonFlags)
|
||||||
{
|
{
|
||||||
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
USAGE Usage;
|
USAGE Usage;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
PUSAGE TempList;
|
PUSAGE TempList;
|
||||||
ULONG CurrentUsageListLength;
|
ULONG CurrentUsageListLength;
|
||||||
|
|
||||||
/* get device extension */
|
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
/* init flags */
|
/* init flags */
|
||||||
*ButtonFlags = 0;
|
*ButtonFlags = 0;
|
||||||
|
|
||||||
|
@ -142,15 +134,14 @@ MouHid_GetButtonFlags(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MouHid_DispatchInputData(
|
MouHid_DispatchInputData(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN PMOUSE_INPUT_DATA InputData)
|
IN PMOUSE_INPUT_DATA InputData)
|
||||||
{
|
{
|
||||||
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ULONG InputDataConsumed;
|
ULONG InputDataConsumed;
|
||||||
|
|
||||||
/* get device extension */
|
if (!DeviceExtension->ClassService)
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
return;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
ASSERT(DeviceExtension->ClassService);
|
ASSERT(DeviceExtension->ClassService);
|
||||||
|
@ -181,13 +172,32 @@ MouHid_ReadCompletion(
|
||||||
MOUSE_INPUT_DATA MouseInputData;
|
MOUSE_INPUT_DATA MouseInputData;
|
||||||
|
|
||||||
/* get device extension */
|
/* get device extension */
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)Context;
|
||||||
|
|
||||||
|
if (Irp->IoStatus.Status == STATUS_PRIVILEGE_NOT_HELD ||
|
||||||
|
Irp->IoStatus.Status == STATUS_DEVICE_NOT_CONNECTED ||
|
||||||
|
Irp->IoStatus.Status == STATUS_CANCELLED ||
|
||||||
|
DeviceExtension->StopReadReport)
|
||||||
|
{
|
||||||
|
/* failed to read or should be stopped*/
|
||||||
|
DPRINT1("[MOUHID] ReadCompletion terminating read Status %x\n", Irp->IoStatus.Status);
|
||||||
|
|
||||||
|
/* report no longer active */
|
||||||
|
DeviceExtension->ReadReportActive = FALSE;
|
||||||
|
|
||||||
|
/* request stopping of the report cycle */
|
||||||
|
DeviceExtension->StopReadReport = FALSE;
|
||||||
|
|
||||||
|
/* signal completion event */
|
||||||
|
KeSetEvent(&DeviceExtension->ReadCompletionEvent, 0, 0);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
/* get mouse change flags */
|
/* get mouse change flags */
|
||||||
MouHid_GetButtonFlags(DeviceObject, &ButtonFlags);
|
MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags);
|
||||||
|
|
||||||
/* get mouse change */
|
/* get mouse change */
|
||||||
MouHid_GetButtonMove(DeviceObject, &LastX, &LastY);
|
MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY);
|
||||||
|
|
||||||
/* init input data */
|
/* init input data */
|
||||||
RtlZeroMemory(&MouseInputData, sizeof(MOUSE_INPUT_DATA));
|
RtlZeroMemory(&MouseInputData, sizeof(MOUSE_INPUT_DATA));
|
||||||
|
@ -215,11 +225,13 @@ MouHid_ReadCompletion(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("[MOUHID] LastX %lu LastY %lu Flags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
|
||||||
|
|
||||||
/* dispatch mouse action */
|
/* dispatch mouse action */
|
||||||
MouHid_DispatchInputData(DeviceObject, &MouseInputData);
|
MouHid_DispatchInputData(DeviceExtension, &MouseInputData);
|
||||||
|
|
||||||
/* re-init read */
|
/* re-init read */
|
||||||
MouHid_InitiateRead(DeviceObject);
|
MouHid_InitiateRead(DeviceExtension);
|
||||||
|
|
||||||
/* stop completion */
|
/* stop completion */
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
@ -227,15 +239,11 @@ MouHid_ReadCompletion(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MouHid_InitiateRead(
|
MouHid_InitiateRead(
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PMOUHID_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* get device extension */
|
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
/* re-use irp */
|
/* re-use irp */
|
||||||
IoReuseIrp(DeviceExtension->Irp, STATUS_SUCCESS);
|
IoReuseIrp(DeviceExtension->Irp, STATUS_SUCCESS);
|
||||||
|
|
||||||
|
@ -255,6 +263,9 @@ MouHid_InitiateRead(
|
||||||
/* set completion routine */
|
/* set completion routine */
|
||||||
IoSetCompletionRoutine(DeviceExtension->Irp, MouHid_ReadCompletion, DeviceExtension, TRUE, TRUE, TRUE);
|
IoSetCompletionRoutine(DeviceExtension->Irp, MouHid_ReadCompletion, DeviceExtension, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
/* read is active */
|
||||||
|
DeviceExtension->ReadReportActive = TRUE;
|
||||||
|
|
||||||
/* start the read */
|
/* start the read */
|
||||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, DeviceExtension->Irp);
|
Status = IoCallDriver(DeviceExtension->NextDeviceObject, DeviceExtension->Irp);
|
||||||
|
|
||||||
|
@ -323,18 +334,23 @@ MouHid_Create(
|
||||||
if (DeviceExtension->FileObject == NULL)
|
if (DeviceExtension->FileObject == NULL)
|
||||||
{
|
{
|
||||||
/* did the caller specify correct attributes */
|
/* did the caller specify correct attributes */
|
||||||
if (IoStack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_READONLY)
|
ASSERT(IoStack->Parameters.Create.SecurityContext);
|
||||||
|
if (IoStack->Parameters.Create.SecurityContext->DesiredAccess)
|
||||||
{
|
{
|
||||||
/* store file object */
|
/* store file object */
|
||||||
DeviceExtension->FileObject = IoStack->FileObject;
|
DeviceExtension->FileObject = IoStack->FileObject;
|
||||||
|
|
||||||
|
/* reset event */
|
||||||
|
KeResetEvent(&DeviceExtension->ReadCompletionEvent);
|
||||||
|
|
||||||
/* initiating read */
|
/* initiating read */
|
||||||
Status = MouHid_InitiateRead(DeviceObject);
|
Status = MouHid_InitiateRead(DeviceExtension);
|
||||||
}
|
DPRINT1("[MOUHID] MouHid_InitiateRead: status %x\n", Status);
|
||||||
else
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
/* wrong mode */
|
/* report irp is pending */
|
||||||
DPRINT1("MOUHID: wrong attributes: %x\n", IoStack->Parameters.Create.FileAttributes);
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +372,21 @@ MouHid_Close(
|
||||||
/* get device extension */
|
/* get device extension */
|
||||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
/* FIXME: cancel irp */
|
DPRINT("[MOUHID] IRP_MJ_CLOSE ReadReportActive %x\n", DeviceExtension->ReadReportActive);
|
||||||
|
|
||||||
|
if (DeviceExtension->ReadReportActive)
|
||||||
|
{
|
||||||
|
/* request stopping of the report cycle */
|
||||||
|
DeviceExtension->StopReadReport = TRUE;
|
||||||
|
|
||||||
|
/* wait until the reports have been read */
|
||||||
|
KeWaitForSingleObject(&DeviceExtension->ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
/* cancel irp */
|
||||||
|
IoCancelIrp(DeviceExtension->Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("[MOUHID] IRP_MJ_CLOSE ReadReportActive %x\n", DeviceExtension->ReadReportActive);
|
||||||
|
|
||||||
/* remove file object */
|
/* remove file object */
|
||||||
DeviceExtension->FileObject = NULL;
|
DeviceExtension->FileObject = NULL;
|
||||||
|
@ -572,22 +602,25 @@ MouHid_StartDevice(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* failed to query collection information */
|
/* failed to query collection information */
|
||||||
|
DPRINT1("[MOUHID] failed to obtain collection information with %x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lets allocate space for preparsed data */
|
/* lets allocate space for preparsed data */
|
||||||
PreparsedData = ExAllocatePool(NonPagedPool, Information.DescriptorSize);
|
PreparsedData = ExAllocatePool(NonPagedPool, Information.DescriptorSize);
|
||||||
if (PreparsedData)
|
if (!PreparsedData)
|
||||||
{
|
{
|
||||||
/* no memory */
|
/* no memory */
|
||||||
|
DPRINT1("[MOUHID] no memory size %u\n", Information.DescriptorSize);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now obtain the preparsed data */
|
/* now obtain the preparsed data */
|
||||||
Status = MouHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_DRIVER_CONFIG, 0, NULL, Information.DescriptorSize, PreparsedData);
|
Status = MouHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, 0, NULL, Information.DescriptorSize, PreparsedData);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* failed to get preparsed data */
|
/* failed to get preparsed data */
|
||||||
|
DPRINT1("[MOUHID] failed to obtain collection information with %x\n", Status);
|
||||||
ExFreePool(PreparsedData);
|
ExFreePool(PreparsedData);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -597,10 +630,13 @@ MouHid_StartDevice(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* failed to get capabilities */
|
/* failed to get capabilities */
|
||||||
|
DPRINT1("[MOUHID] failed to obtain caps with %x\n", Status);
|
||||||
ExFreePool(PreparsedData);
|
ExFreePool(PreparsedData);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("[MOUHID] Usage %x UsagePage %x\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength);
|
||||||
|
|
||||||
/* verify capabilities */
|
/* verify capabilities */
|
||||||
if (Capabilities.Usage != HID_USAGE_GENERIC_POINTER && Capabilities.Usage != HID_USAGE_GENERIC_MOUSE || Capabilities.UsagePage != HID_USAGE_PAGE_GENERIC)
|
if (Capabilities.Usage != HID_USAGE_GENERIC_POINTER && Capabilities.Usage != HID_USAGE_GENERIC_MOUSE || Capabilities.UsagePage != HID_USAGE_PAGE_GENERIC)
|
||||||
{
|
{
|
||||||
|
@ -615,12 +651,17 @@ MouHid_StartDevice(
|
||||||
DeviceExtension->Report = (PUCHAR)ExAllocatePool(NonPagedPool, DeviceExtension->ReportLength);
|
DeviceExtension->Report = (PUCHAR)ExAllocatePool(NonPagedPool, DeviceExtension->ReportLength);
|
||||||
ASSERT(DeviceExtension->Report);
|
ASSERT(DeviceExtension->Report);
|
||||||
RtlZeroMemory(DeviceExtension->Report, DeviceExtension->ReportLength);
|
RtlZeroMemory(DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||||
|
|
||||||
|
/* build mdl */
|
||||||
DeviceExtension->ReportMDL = IoAllocateMdl(DeviceExtension->Report, DeviceExtension->ReportLength, FALSE, FALSE, NULL);
|
DeviceExtension->ReportMDL = IoAllocateMdl(DeviceExtension->Report, DeviceExtension->ReportLength, FALSE, FALSE, NULL);
|
||||||
ASSERT(DeviceExtension->ReportMDL);
|
ASSERT(DeviceExtension->ReportMDL);
|
||||||
|
|
||||||
|
/* init mdl */
|
||||||
|
MmBuildMdlForNonPagedPool(DeviceExtension->ReportMDL);
|
||||||
|
|
||||||
/* get max number of buttons */
|
/* get max number of buttons */
|
||||||
Buttons = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, PreparsedData);
|
Buttons = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, PreparsedData);
|
||||||
|
DPRINT1("[MOUHID] Buttons %lu\n", Buttons);
|
||||||
ASSERT(Buttons > 0);
|
ASSERT(Buttons > 0);
|
||||||
|
|
||||||
/* now allocate an array for those buttons */
|
/* now allocate an array for those buttons */
|
||||||
|
@ -662,6 +703,7 @@ MouHid_StartDevice(
|
||||||
/* mouse has wheel support */
|
/* mouse has wheel support */
|
||||||
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
||||||
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
||||||
|
DPRINT1("[MOUHID] mouse wheel support detected\n", Status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -673,6 +715,7 @@ MouHid_StartDevice(
|
||||||
/* wheel support */
|
/* wheel support */
|
||||||
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
||||||
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
||||||
|
DPRINT1("[MOUHID] mouse wheel support detected with z-axis\n", Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +870,7 @@ MouHid_AddDevice(
|
||||||
DeviceExtension->MouseIdentifier = MOUSE_HID_HARDWARE;
|
DeviceExtension->MouseIdentifier = MOUSE_HID_HARDWARE;
|
||||||
DeviceExtension->WheelUsagePage = 0;
|
DeviceExtension->WheelUsagePage = 0;
|
||||||
DeviceExtension->NextDeviceObject = NextDeviceObject;
|
DeviceExtension->NextDeviceObject = NextDeviceObject;
|
||||||
KeInitializeEvent(&DeviceExtension->Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&DeviceExtension->ReadCompletionEvent, NotificationEvent, FALSE);
|
||||||
DeviceExtension->Irp = IoAllocateIrp(NextDeviceObject->StackSize, FALSE);
|
DeviceExtension->Irp = IoAllocateIrp(NextDeviceObject->StackSize, FALSE);
|
||||||
|
|
||||||
/* FIXME handle allocation error */
|
/* FIXME handle allocation error */
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <ntddmou.h>
|
#include <ntddmou.h>
|
||||||
#include <kbdmou.h>
|
#include <kbdmou.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -25,7 +26,7 @@ typedef struct
|
||||||
//
|
//
|
||||||
// event
|
// event
|
||||||
//
|
//
|
||||||
KEVENT Event;
|
KEVENT ReadCompletionEvent;
|
||||||
|
|
||||||
//
|
//
|
||||||
// device object for class callback
|
// device object for class callback
|
||||||
|
@ -97,9 +98,19 @@ typedef struct
|
||||||
//
|
//
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
|
||||||
|
//
|
||||||
|
// report read is active
|
||||||
|
//
|
||||||
|
UCHAR ReadReportActive;
|
||||||
|
|
||||||
|
//
|
||||||
|
// stop reading flag
|
||||||
|
//
|
||||||
|
UCHAR StopReadReport;
|
||||||
|
|
||||||
}MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
|
}MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MouHid_InitiateRead(
|
MouHid_InitiateRead(
|
||||||
IN PDEVICE_OBJECT DeviceObject);
|
IN PMOUHID_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue