mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 04:13:33 +00:00
[LT2013]
- Merge r58989 (kbdhid/moudhid formatting so that r59044 applies cleanly) - Merge r59039 (usb: Fix race condition for status change worker routine) - Merge r59044 (mouhid: Cleanup code. Fix distinguation between relative and absolute mice) - Merge r59045 (hidclass: Remove assert) - Merge r59049 (hidclass: Fix double irp completion bug in hidclass) svn path=/branches/ros-branch-0_3_15-lt2013/; revision=59053
This commit is contained in:
+55
-10
@@ -181,9 +181,13 @@ HidClassFDO_DispatchRequestSynchronous(
|
||||
IoStack->DeviceObject = DeviceObject;
|
||||
|
||||
//
|
||||
// call driver
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction] != NULL);
|
||||
|
||||
//
|
||||
// call minidriver (hidusb)
|
||||
//
|
||||
DPRINT("IoStack MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
|
||||
Status = CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
|
||||
|
||||
//
|
||||
@@ -205,6 +209,53 @@ HidClassFDO_DispatchRequestSynchronous(
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassFDO_DispatchRequest(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
CommonDeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Irp->CurrentLocation > 0);
|
||||
|
||||
//
|
||||
// create stack location
|
||||
//
|
||||
IoSetNextIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// get next stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// store device object
|
||||
//
|
||||
IoStack->DeviceObject = DeviceObject;
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction] != NULL);
|
||||
|
||||
//
|
||||
// call driver
|
||||
//
|
||||
Status = CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassFDO_GetDescriptors(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
@@ -602,14 +653,8 @@ HidClassFDO_PnP(
|
||||
//
|
||||
// dispatch to mini driver
|
||||
//
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
Status = HidClassFDO_DispatchRequest(DeviceObject, Irp);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +565,6 @@ HidClassPDO_PnP(
|
||||
case IRP_MN_QUERY_INTERFACE:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] PDO IRP_MN_QUERY_INTERFACE not implemented\n");
|
||||
ASSERT(FALSE);
|
||||
|
||||
//
|
||||
// do nothing
|
||||
|
||||
+271
-221
@@ -50,7 +50,7 @@ KbdHid_InsertScanCodes(
|
||||
/* get device extension */
|
||||
DeviceExtension = (PKBDHID_DEVICE_EXTENSION)Context;
|
||||
|
||||
for(Index = 0; Index < Length; Index++)
|
||||
for (Index = 0; Index < Length; Index++)
|
||||
{
|
||||
DPRINT("[KBDHID] ScanCode Index %lu ScanCode %x\n", Index, NewScanCodes[Index] & 0xFF);
|
||||
|
||||
@@ -84,7 +84,7 @@ KbdHid_InsertScanCodes(
|
||||
InputData.MakeCode = NewScanCodes[Index] & 0x7F;
|
||||
|
||||
/* dispatch scan codes */
|
||||
KbdHid_DispatchInputData((PKBDHID_DEVICE_EXTENSION)Context, &InputData);
|
||||
KbdHid_DispatchInputData(Context, &InputData);
|
||||
}
|
||||
|
||||
/* done */
|
||||
@@ -136,24 +136,46 @@ KbdHid_ReadCompletion(
|
||||
|
||||
/* get current usages */
|
||||
ButtonLength = DeviceExtension->UsageListLength;
|
||||
Status = HidP_GetUsagesEx(HidP_Input, HIDP_LINK_COLLECTION_UNSPECIFIED, DeviceExtension->CurrentUsageList, &ButtonLength, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
Status = HidP_GetUsagesEx(HidP_Input,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
DeviceExtension->CurrentUsageList,
|
||||
&ButtonLength,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* FIXME check if needs mapping */
|
||||
|
||||
/* get usage difference */
|
||||
Status = HidP_UsageAndPageListDifference(DeviceExtension->PreviousUsageList, DeviceExtension->CurrentUsageList, DeviceExtension->BreakUsageList, DeviceExtension->MakeUsageList, DeviceExtension->UsageListLength);
|
||||
Status = HidP_UsageAndPageListDifference(DeviceExtension->PreviousUsageList,
|
||||
DeviceExtension->CurrentUsageList,
|
||||
DeviceExtension->BreakUsageList,
|
||||
DeviceExtension->MakeUsageList,
|
||||
DeviceExtension->UsageListLength);
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* replace previous usage list with current list */
|
||||
RtlMoveMemory(DeviceExtension->PreviousUsageList, DeviceExtension->CurrentUsageList, sizeof(USAGE_AND_PAGE) * DeviceExtension->UsageListLength);
|
||||
RtlMoveMemory(DeviceExtension->PreviousUsageList,
|
||||
DeviceExtension->CurrentUsageList,
|
||||
sizeof(USAGE_AND_PAGE) * DeviceExtension->UsageListLength);
|
||||
|
||||
/* translate break usage list */
|
||||
HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->BreakUsageList, DeviceExtension->UsageListLength, HidP_Keyboard_Break, &DeviceExtension->ModifierState, KbdHid_InsertScanCodes, DeviceExtension);
|
||||
HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->BreakUsageList,
|
||||
DeviceExtension->UsageListLength,
|
||||
HidP_Keyboard_Break,
|
||||
&DeviceExtension->ModifierState,
|
||||
KbdHid_InsertScanCodes,
|
||||
DeviceExtension);
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* translate new usage list */
|
||||
HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->MakeUsageList, DeviceExtension->UsageListLength, HidP_Keyboard_Make, &DeviceExtension->ModifierState, KbdHid_InsertScanCodes, DeviceExtension);
|
||||
HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->MakeUsageList,
|
||||
DeviceExtension->UsageListLength,
|
||||
HidP_Keyboard_Make,
|
||||
&DeviceExtension->ModifierState,
|
||||
KbdHid_InsertScanCodes,
|
||||
DeviceExtension);
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* re-init read */
|
||||
@@ -343,166 +365,168 @@ KbdHid_InternalDeviceControl(
|
||||
/* get device extension */
|
||||
DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_ATTRIBUTES)
|
||||
switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
/* verify output buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
|
||||
{
|
||||
/* invalid request */
|
||||
DPRINT1("[MOUHID] IOCTL_MOUSE_QUERY_ATTRIBUTES Buffer too small\n");
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
|
||||
/* verify output buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
|
||||
{
|
||||
/* invalid request */
|
||||
DPRINT1("[MOUHID] IOCTL_MOUSE_QUERY_ATTRIBUTES Buffer too small\n");
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* get output buffer */
|
||||
Attributes = (PKEYBOARD_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* copy attributes */
|
||||
RtlCopyMemory(Attributes,
|
||||
&DeviceExtension->Attributes,
|
||||
sizeof(KEYBOARD_ATTRIBUTES));
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case IOCTL_INTERNAL_KEYBOARD_CONNECT:
|
||||
/* verify input buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
|
||||
{
|
||||
/* invalid request */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* is it already connected */
|
||||
if (DeviceExtension->ClassService)
|
||||
{
|
||||
/* already connected */
|
||||
Irp->IoStatus.Status = STATUS_SHARING_VIOLATION;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
|
||||
/* get connect data */
|
||||
Data = (PCONNECT_DATA)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||
|
||||
/* store connect details */
|
||||
DeviceExtension->ClassDeviceObject = Data->ClassDeviceObject;
|
||||
DeviceExtension->ClassService = Data->ClassService;
|
||||
|
||||
/* completed successfully */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
|
||||
/* not implemented */
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
/* get output buffer */
|
||||
Attributes = (PKEYBOARD_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer;
|
||||
case IOCTL_INTERNAL_KEYBOARD_ENABLE:
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* copy attributes */
|
||||
RtlCopyMemory(Attributes, &DeviceExtension->Attributes, sizeof(KEYBOARD_ATTRIBUTES));
|
||||
case IOCTL_INTERNAL_KEYBOARD_DISABLE:
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_CONNECT)
|
||||
{
|
||||
/* verify input buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
|
||||
{
|
||||
/* invalid request */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
case IOCTL_KEYBOARD_QUERY_INDICATORS:
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* is it already connected */
|
||||
if (DeviceExtension->ClassService)
|
||||
{
|
||||
/* already connected */
|
||||
Irp->IoStatus.Status = STATUS_SHARING_VIOLATION;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||
&DeviceExtension->KeyboardIndicator,
|
||||
sizeof(KEYBOARD_INDICATOR_PARAMETERS));
|
||||
|
||||
/* get connect data */
|
||||
Data = (PCONNECT_DATA)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
/* store connect details */
|
||||
DeviceExtension->ClassDeviceObject = Data->ClassDeviceObject;
|
||||
DeviceExtension->ClassService = Data->ClassService;
|
||||
case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* completed successfully */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_DISCONNECT)
|
||||
{
|
||||
/* not implemented */
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_ENABLE)
|
||||
{
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_DISABLE)
|
||||
{
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_INDICATORS)
|
||||
{
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||
&DeviceExtension->KeyboardTypematic,
|
||||
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));
|
||||
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &DeviceExtension->KeyboardIndicator, sizeof(KEYBOARD_INDICATOR_PARAMETERS));
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_TYPEMATIC)
|
||||
{
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
case IOCTL_KEYBOARD_SET_INDICATORS:
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &DeviceExtension->KeyboardTypematic, sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(&DeviceExtension->KeyboardIndicator,
|
||||
Irp->AssociatedIrp.SystemBuffer,
|
||||
sizeof(KEYBOARD_INDICATOR_PARAMETERS));
|
||||
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_SET_INDICATORS)
|
||||
{
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(&DeviceExtension->KeyboardIndicator, Irp->AssociatedIrp.SystemBuffer, sizeof(KEYBOARD_INDICATOR_PARAMETERS));
|
||||
case IOCTL_KEYBOARD_SET_TYPEMATIC:
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_SET_TYPEMATIC)
|
||||
{
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS))
|
||||
{
|
||||
/* invalid parameter */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(&DeviceExtension->KeyboardTypematic,
|
||||
Irp->AssociatedIrp.SystemBuffer,
|
||||
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));
|
||||
|
||||
/* copy indicators */
|
||||
RtlCopyMemory(&DeviceExtension->KeyboardTypematic, Irp->AssociatedIrp.SystemBuffer, sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* done */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION)
|
||||
{
|
||||
/* not implemented */
|
||||
DPRINT1("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION not implemented\n");
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
|
||||
/* not implemented */
|
||||
DPRINT1("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION not implemented\n");
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* unknown control code */
|
||||
@@ -563,7 +587,15 @@ KbdHid_SubmitRequest(
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* build request */
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode, DeviceExtension->NextDeviceObject, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, FALSE, &Event, &IoStatus);
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
||||
DeviceExtension->NextDeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferSize,
|
||||
OutputBuffer,
|
||||
OutputBufferSize,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (!Irp)
|
||||
{
|
||||
/* no memory */
|
||||
@@ -600,7 +632,12 @@ KbdHid_StartDevice(
|
||||
DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* query collection information */
|
||||
Status = KbdHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION, 0, NULL, sizeof(HID_COLLECTION_INFORMATION), &Information);
|
||||
Status = KbdHid_SubmitRequest(DeviceObject,
|
||||
IOCTL_HID_GET_COLLECTION_INFORMATION,
|
||||
0,
|
||||
NULL,
|
||||
sizeof(HID_COLLECTION_INFORMATION),
|
||||
&Information);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to query collection information */
|
||||
@@ -618,7 +655,12 @@ KbdHid_StartDevice(
|
||||
}
|
||||
|
||||
/* now obtain the preparsed data */
|
||||
Status = KbdHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, 0, NULL, Information.DescriptorSize, PreparsedData);
|
||||
Status = KbdHid_SubmitRequest(DeviceObject,
|
||||
IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
|
||||
0,
|
||||
NULL,
|
||||
Information.DescriptorSize,
|
||||
PreparsedData);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to get preparsed data */
|
||||
@@ -639,7 +681,7 @@ KbdHid_StartDevice(
|
||||
|
||||
DPRINT("[KBDHID] Usage %x UsagePage %x InputReportLength %lu\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength);
|
||||
|
||||
/* init input report*/
|
||||
/* init input report */
|
||||
DeviceExtension->ReportLength = Capabilities.InputReportByteLength;
|
||||
ASSERT(DeviceExtension->ReportLength);
|
||||
DeviceExtension->Report = (PCHAR)ExAllocatePool(NonPagedPool, DeviceExtension->ReportLength);
|
||||
@@ -647,7 +689,11 @@ KbdHid_StartDevice(
|
||||
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);
|
||||
|
||||
/* init mdl */
|
||||
@@ -752,88 +798,86 @@ KbdHid_Pnp(
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DPRINT("[KBDHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
|
||||
|
||||
if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
|
||||
{
|
||||
/* FIXME synchronization */
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
|
||||
/* cancel irp */
|
||||
IoCancelIrp(DeviceExtension->Irp);
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
/* FIXME synchronization */
|
||||
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
/* cancel irp */
|
||||
IoCancelIrp(DeviceExtension->Irp);
|
||||
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
/* dispatch to lower device */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
IoFreeIrp(DeviceExtension->Irp);
|
||||
IoDetachDevice(DeviceExtension->NextDeviceObject);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return Status;
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
|
||||
{
|
||||
/* init event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
/* dispatch to lower device */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
|
||||
/* copy stack location */
|
||||
IoCopyCurrentIrpStackLocationToNext (Irp);
|
||||
IoFreeIrp(DeviceExtension->Irp);
|
||||
IoDetachDevice(DeviceExtension->NextDeviceObject);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return Status;
|
||||
|
||||
/* set completion routine */
|
||||
IoSetCompletionRoutine(Irp, KbdHid_StartDeviceCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
Irp->IoStatus.Status = 0;
|
||||
case IRP_MN_START_DEVICE:
|
||||
/* init event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* pass request */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
/* copy stack location */
|
||||
IoCopyCurrentIrpStackLocationToNext (Irp);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed */
|
||||
/* set completion routine */
|
||||
IoSetCompletionRoutine(Irp, KbdHid_StartDeviceCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
Irp->IoStatus.Status = 0;
|
||||
|
||||
/* pass request */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* lets start the device */
|
||||
Status = KbdHid_StartDevice(DeviceObject);
|
||||
DPRINT("KbdHid_StartDevice %x\n", Status);
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* lets start the device */
|
||||
Status = KbdHid_StartDevice(DeviceObject);
|
||||
DPRINT("KbdHid_StartDevice %x\n", Status);
|
||||
default:
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,7 +893,13 @@ KbdHid_AddDevice(
|
||||
POWER_STATE State;
|
||||
|
||||
/* create device object */
|
||||
Status = IoCreateDevice(DriverObject, sizeof(KBDHID_DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, FALSE, &DeviceObject);
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(KBDHID_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to create device object */
|
||||
|
||||
@@ -26,7 +26,7 @@ typedef struct
|
||||
PIRP Irp;
|
||||
|
||||
//
|
||||
// event
|
||||
// event
|
||||
//
|
||||
KEVENT ReadCompletionEvent;
|
||||
|
||||
@@ -125,12 +125,12 @@ typedef struct
|
||||
}KBDHID_DEVICE_EXTENSION, *PKBDHID_DEVICE_EXTENSION;
|
||||
|
||||
/* defaults from kbfiltr.h */
|
||||
#define KEYBOARD_TYPEMATIC_RATE_MINIMUM 2
|
||||
#define KEYBOARD_TYPEMATIC_RATE_MAXIMUM 30
|
||||
#define KEYBOARD_TYPEMATIC_RATE_DEFAULT 30
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_MINIMUM 250
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_MAXIMUM 1000
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_DEFAULT 250
|
||||
#define KEYBOARD_TYPEMATIC_RATE_MINIMUM 2
|
||||
#define KEYBOARD_TYPEMATIC_RATE_MAXIMUM 30
|
||||
#define KEYBOARD_TYPEMATIC_RATE_DEFAULT 30
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_MINIMUM 250
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_MAXIMUM 1000
|
||||
#define KEYBOARD_TYPEMATIC_DELAY_DEFAULT 250
|
||||
|
||||
/* FIXME: write kbd.h */
|
||||
#define MICROSOFT_KBD_FUNC 12
|
||||
@@ -143,4 +143,3 @@ typedef struct
|
||||
NTSTATUS
|
||||
KbdHid_InitiateRead(
|
||||
IN PKBDHID_DEVICE_EXTENSION DeviceExtension);
|
||||
|
||||
|
||||
+296
-135
@@ -10,7 +10,7 @@
|
||||
|
||||
#include "mouhid.h"
|
||||
|
||||
static USHORT MouHid_ButtonUpFlags[] =
|
||||
static USHORT MouHid_ButtonUpFlags[] =
|
||||
{
|
||||
0xFF, /* unused */
|
||||
MOUSE_LEFT_BUTTON_DOWN,
|
||||
@@ -20,7 +20,7 @@ static USHORT MouHid_ButtonUpFlags[] =
|
||||
MOUSE_BUTTON_5_DOWN
|
||||
};
|
||||
|
||||
static USHORT MouHid_ButtonDownFlags[] =
|
||||
static USHORT MouHid_ButtonDownFlags[] =
|
||||
{
|
||||
0xFF, /* unused */
|
||||
MOUSE_LEFT_BUTTON_UP,
|
||||
@@ -30,6 +30,7 @@ static USHORT MouHid_ButtonDownFlags[] =
|
||||
MOUSE_BUTTON_5_UP
|
||||
};
|
||||
|
||||
|
||||
VOID
|
||||
MouHid_GetButtonMove(
|
||||
IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
|
||||
@@ -43,50 +44,135 @@ MouHid_GetButtonMove(
|
||||
*LastX = 0;
|
||||
*LastY = 0;
|
||||
|
||||
/* get scaled usage value x */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PLONG)LastX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
if (!DeviceExtension->MouseAbsolute)
|
||||
{
|
||||
/* FIXME: handle more errors */
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
/* get scaled usage value x */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_X,
|
||||
LastX,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
/* FIXME: assume it operates in absolute mode */
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
/* FIXME: handle more errors */
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
{
|
||||
/* FIXME: assume it operates in absolute mode */
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
|
||||
/* get unscaled value */
|
||||
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PULONG)&ValueX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
/* get unscaled value */
|
||||
Status = HidP_GetUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_X,
|
||||
&ValueX,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > 0);
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > 0);
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > DeviceExtension->ValueCapsX.LogicalMin);
|
||||
|
||||
*LastX = (ValueX * 0xFFFF) / DeviceExtension->ValueCapsX.LogicalMax;
|
||||
/* convert to logical range */
|
||||
*LastX = (ValueX * VIRTUAL_SCREEN_SIZE_X) / DeviceExtension->ValueCapsX.LogicalMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get scaled usage value y */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PLONG)LastY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
else
|
||||
{
|
||||
// FIXME: handle more errors
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
/* get unscaled value */
|
||||
Status = HidP_GetUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_X,
|
||||
&ValueX,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > 0);
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > DeviceExtension->ValueCapsX.LogicalMin);
|
||||
|
||||
/* convert to logical range */
|
||||
*LastX = (ValueX * VIRTUAL_SCREEN_SIZE_X) / DeviceExtension->ValueCapsX.LogicalMax;
|
||||
}
|
||||
|
||||
if (!DeviceExtension->MouseAbsolute)
|
||||
{
|
||||
/* get scaled usage value y */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_Y,
|
||||
LastY,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
// assume it operates in absolute mode
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
// FIXME: handle more errors
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
{
|
||||
// assume it operates in absolute mode
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
|
||||
// get unscaled value
|
||||
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PULONG)&ValueY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
// get unscaled value
|
||||
Status = HidP_GetUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_Y,
|
||||
&ValueY,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax);
|
||||
*LastY = (ValueY * 0xFFFF) / DeviceExtension->ValueCapsY.LogicalMax;
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax > 0);
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax > DeviceExtension->ValueCapsY.LogicalMin);
|
||||
|
||||
/* convert to logical range */
|
||||
*LastY = (ValueY * VIRTUAL_SCREEN_SIZE_Y) / DeviceExtension->ValueCapsY.LogicalMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// get unscaled value
|
||||
Status = HidP_GetUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_Y,
|
||||
&ValueY,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax > 0);
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax > DeviceExtension->ValueCapsY.LogicalMin);
|
||||
|
||||
/* convert to logical range */
|
||||
*LastY = (ValueY * VIRTUAL_SCREEN_SIZE_Y) / DeviceExtension->ValueCapsY.LogicalMax;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
@@ -107,7 +193,14 @@ MouHid_GetButtonFlags(
|
||||
|
||||
/* get usages */
|
||||
CurrentUsageListLength = DeviceExtension->UsageListLength;
|
||||
Status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, HIDP_LINK_COLLECTION_UNSPECIFIED, DeviceExtension->CurrentUsageList, &CurrentUsageListLength, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
Status = HidP_GetUsages(HidP_Input,
|
||||
HID_USAGE_PAGE_BUTTON,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
DeviceExtension->CurrentUsageList,
|
||||
&CurrentUsageListLength,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT1("MouHid_GetButtonFlags failed to get usages with %x\n", Status);
|
||||
@@ -115,7 +208,11 @@ MouHid_GetButtonFlags(
|
||||
}
|
||||
|
||||
/* extract usage list difference */
|
||||
Status = HidP_UsageListDifference(DeviceExtension->PreviousUsageList, DeviceExtension->CurrentUsageList, DeviceExtension->BreakUsageList, DeviceExtension->MakeUsageList, DeviceExtension->UsageListLength);
|
||||
Status = HidP_UsageListDifference(DeviceExtension->PreviousUsageList,
|
||||
DeviceExtension->CurrentUsageList,
|
||||
DeviceExtension->BreakUsageList,
|
||||
DeviceExtension->MakeUsageList,
|
||||
DeviceExtension->UsageListLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT1("MouHid_GetButtonFlags failed to get usages with %x\n", Status);
|
||||
@@ -140,7 +237,7 @@ MouHid_GetButtonFlags(
|
||||
|
||||
/* move to next index*/
|
||||
Index++;
|
||||
}while(Index < DeviceExtension->UsageListLength);
|
||||
} while (Index < DeviceExtension->UsageListLength);
|
||||
}
|
||||
|
||||
if (DeviceExtension->UsageListLength)
|
||||
@@ -161,7 +258,7 @@ MouHid_GetButtonFlags(
|
||||
|
||||
/* move to next index*/
|
||||
Index++;
|
||||
}while(Index < DeviceExtension->UsageListLength);
|
||||
} while (Index < DeviceExtension->UsageListLength);
|
||||
}
|
||||
|
||||
/* now switch the previous list with current list */
|
||||
@@ -258,7 +355,14 @@ MouHid_ReadCompletion(
|
||||
{
|
||||
/* get usage */
|
||||
UsageValue = 0;
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_WHEEL, &UsageValue, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_WHEEL,
|
||||
&UsageValue,
|
||||
DeviceExtension->PreparsedData,
|
||||
DeviceExtension->Report,
|
||||
DeviceExtension->ReportLength);
|
||||
if (Status == HIDP_STATUS_SUCCESS && UsageValue != 0)
|
||||
{
|
||||
/* store wheel status */
|
||||
@@ -277,7 +381,7 @@ MouHid_ReadCompletion(
|
||||
DeviceExtension->Report[3] & 0xFF, DeviceExtension->Report[4] & 0xFF,
|
||||
DeviceExtension->Report[5] & 0xFF, DeviceExtension->Report[6] & 0xFF);
|
||||
|
||||
DPRINT("[MOUHID] LastX %ld LastY %ld Flags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
|
||||
DPRINT("[MOUHID] LastX %ld LastY %ld Flags %x ButtonFlags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.Flags, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
|
||||
|
||||
/* dispatch mouse action */
|
||||
MouHid_DispatchInputData(DeviceExtension, &MouseInputData);
|
||||
@@ -332,7 +436,7 @@ MouHid_CreateCompletion(
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
KeSetEvent((PKEVENT)Context, 0, FALSE);
|
||||
KeSetEvent(Context, 0, FALSE);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
@@ -470,8 +574,9 @@ MouHid_InternalDeviceControl(
|
||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* handle requests */
|
||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUSE_QUERY_ATTRIBUTES)
|
||||
switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_MOUSE_QUERY_ATTRIBUTES:
|
||||
/* verify output buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
|
||||
{
|
||||
@@ -507,9 +612,8 @@ MouHid_InternalDeviceControl(
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_CONNECT)
|
||||
{
|
||||
|
||||
case IOCTL_INTERNAL_MOUSE_CONNECT:
|
||||
/* verify input buffer length */
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
|
||||
{
|
||||
@@ -539,23 +643,20 @@ MouHid_InternalDeviceControl(
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT)
|
||||
{
|
||||
|
||||
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_ENABLE)
|
||||
{
|
||||
|
||||
case IOCTL_INTERNAL_MOUSE_ENABLE:
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_DISABLE)
|
||||
{
|
||||
|
||||
case IOCTL_INTERNAL_MOUSE_DISABLE:
|
||||
/* not supported */
|
||||
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
@@ -619,7 +720,15 @@ MouHid_SubmitRequest(
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* build request */
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode, DeviceExtension->NextDeviceObject, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, FALSE, &Event, &IoStatus);
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
||||
DeviceExtension->NextDeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferSize,
|
||||
OutputBuffer,
|
||||
OutputBufferSize,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (!Irp)
|
||||
{
|
||||
/* no memory */
|
||||
@@ -658,7 +767,12 @@ MouHid_StartDevice(
|
||||
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* query collection information */
|
||||
Status = MouHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION, 0, NULL, sizeof(HID_COLLECTION_INFORMATION), &Information);
|
||||
Status = MouHid_SubmitRequest(DeviceObject,
|
||||
IOCTL_HID_GET_COLLECTION_INFORMATION,
|
||||
0,
|
||||
NULL,
|
||||
sizeof(HID_COLLECTION_INFORMATION),
|
||||
&Information);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to query collection information */
|
||||
@@ -676,7 +790,12 @@ MouHid_StartDevice(
|
||||
}
|
||||
|
||||
/* now obtain the preparsed data */
|
||||
Status = MouHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, 0, NULL, Information.DescriptorSize, PreparsedData);
|
||||
Status = MouHid_SubmitRequest(DeviceObject,
|
||||
IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
|
||||
0,
|
||||
NULL,
|
||||
Information.DescriptorSize,
|
||||
PreparsedData);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to get preparsed data */
|
||||
@@ -713,14 +832,20 @@ MouHid_StartDevice(
|
||||
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);
|
||||
|
||||
/* init mdl */
|
||||
MmBuildMdlForNonPagedPool(DeviceExtension->ReportMDL);
|
||||
|
||||
/* 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);
|
||||
DPRINT("[MOUHID] Buttons %lu\n", Buttons);
|
||||
ASSERT(Buttons > 0);
|
||||
|
||||
@@ -750,15 +875,33 @@ MouHid_StartDevice(
|
||||
DeviceExtension->PreparsedData = PreparsedData;
|
||||
|
||||
ValueCapsLength = 1;
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &DeviceExtension->ValueCapsX, &ValueCapsLength, PreparsedData);
|
||||
HidP_GetSpecificValueCaps(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_X,
|
||||
&DeviceExtension->ValueCapsX,
|
||||
&ValueCapsLength,
|
||||
PreparsedData);
|
||||
|
||||
ValueCapsLength = 1;
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &DeviceExtension->ValueCapsY, &ValueCapsLength, PreparsedData);
|
||||
HidP_GetSpecificValueCaps(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_Y,
|
||||
&DeviceExtension->ValueCapsY,
|
||||
&ValueCapsLength,
|
||||
PreparsedData);
|
||||
|
||||
/* now check for wheel mouse support */
|
||||
ValueCapsLength = 1;
|
||||
Status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_WHEEL, &ValueCaps, &ValueCapsLength, PreparsedData);
|
||||
if (Status == HIDP_STATUS_SUCCESS )
|
||||
Status = HidP_GetSpecificValueCaps(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_WHEEL,
|
||||
&ValueCaps,
|
||||
&ValueCapsLength,
|
||||
PreparsedData);
|
||||
if (Status == HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
/* mouse has wheel support */
|
||||
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
||||
@@ -769,7 +912,13 @@ MouHid_StartDevice(
|
||||
{
|
||||
/* check if the mouse has z-axis */
|
||||
ValueCapsLength = 1;
|
||||
Status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Z, &ValueCaps, &ValueCapsLength, PreparsedData);
|
||||
Status = HidP_GetSpecificValueCaps(HidP_Input,
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HIDP_LINK_COLLECTION_UNSPECIFIED,
|
||||
HID_USAGE_GENERIC_Z,
|
||||
&ValueCaps,
|
||||
&ValueCapsLength,
|
||||
PreparsedData);
|
||||
if (Status == HIDP_STATUS_SUCCESS && ValueCapsLength == 1)
|
||||
{
|
||||
/* wheel support */
|
||||
@@ -779,6 +928,14 @@ MouHid_StartDevice(
|
||||
}
|
||||
}
|
||||
|
||||
/* check if mice is absolute */
|
||||
if (DeviceExtension->ValueCapsY.LogicalMax > DeviceExtension->ValueCapsY.LogicalMin ||
|
||||
DeviceExtension->ValueCapsX.LogicalMax > DeviceExtension->ValueCapsX.LogicalMin)
|
||||
{
|
||||
/* mice is absolute */
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
}
|
||||
|
||||
/* completed successfully */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -838,101 +995,99 @@ MouHid_Pnp(
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DPRINT("[MOUHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
|
||||
|
||||
if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
|
||||
IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
|
||||
{
|
||||
/* FIXME synchronization */
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
|
||||
/* request stop */
|
||||
DeviceExtension->StopReadReport = TRUE;
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
/* FIXME synchronization */
|
||||
|
||||
/* cancel irp */
|
||||
IoCancelIrp(DeviceExtension->Irp);
|
||||
/* request stop */
|
||||
DeviceExtension->StopReadReport = TRUE;
|
||||
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
/* cancel irp */
|
||||
IoCancelIrp(DeviceExtension->Irp);
|
||||
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
/* indicate success */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
/* dispatch to lower device */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* wait for completion of stop event */
|
||||
KeWaitForSingleObject(&DeviceExtension->ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
|
||||
/* dispatch to lower device */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
|
||||
/* free irp */
|
||||
IoFreeIrp(DeviceExtension->Irp);
|
||||
/* wait for completion of stop event */
|
||||
KeWaitForSingleObject(&DeviceExtension->ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
/* detach device */
|
||||
IoDetachDevice(DeviceExtension->NextDeviceObject);
|
||||
/* free irp */
|
||||
IoFreeIrp(DeviceExtension->Irp);
|
||||
|
||||
/* delete device */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
/* detach device */
|
||||
IoDetachDevice(DeviceExtension->NextDeviceObject);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
|
||||
{
|
||||
/* init event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
/* delete device */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
/* copy stack location */
|
||||
IoCopyCurrentIrpStackLocationToNext (Irp);
|
||||
/* done */
|
||||
return Status;
|
||||
|
||||
/* set completion routine */
|
||||
IoSetCompletionRoutine(Irp, MouHid_StartDeviceCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
Irp->IoStatus.Status = 0;
|
||||
case IRP_MN_START_DEVICE:
|
||||
/* init event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* pass request */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
/* copy stack location */
|
||||
IoCopyCurrentIrpStackLocationToNext (Irp);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed */
|
||||
/* set completion routine */
|
||||
IoSetCompletionRoutine(Irp, MouHid_StartDeviceCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
Irp->IoStatus.Status = 0;
|
||||
|
||||
/* pass request */
|
||||
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* lets start the device */
|
||||
Status = MouHid_StartDevice(DeviceObject);
|
||||
DPRINT("MouHid_StartDevice %x\n", Status);
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* lets start the device */
|
||||
Status = MouHid_StartDevice(DeviceObject);
|
||||
DPRINT("MouHid_StartDevice %x\n", Status);
|
||||
default:
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* complete request */
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* skip irp stack location */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
/* dispatch to lower device */
|
||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,7 +1103,13 @@ MouHid_AddDevice(
|
||||
POWER_STATE State;
|
||||
|
||||
/* create device object */
|
||||
Status = IoCreateDevice(DriverObject, sizeof(MOUHID_DEVICE_EXTENSION), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &DeviceObject);
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(MOUHID_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_MOUSE,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed to create device object */
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef struct
|
||||
PIRP Irp;
|
||||
|
||||
//
|
||||
// event
|
||||
// event
|
||||
//
|
||||
KEVENT ReadCompletionEvent;
|
||||
|
||||
@@ -128,6 +128,8 @@ typedef struct
|
||||
}MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
|
||||
|
||||
#define WHEEL_DELTA 120
|
||||
#define VIRTUAL_SCREEN_SIZE_X (65536)
|
||||
#define VIRTUAL_SCREEN_SIZE_Y (65536)
|
||||
|
||||
NTSTATUS
|
||||
MouHid_InitiateRead(
|
||||
|
||||
@@ -96,7 +96,7 @@ protected:
|
||||
PVOID m_SCEContext; // status change callback routine context
|
||||
BOOLEAN m_DoorBellRingInProgress; // door bell ring in progress
|
||||
WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
|
||||
ULONG m_WorkItemActive; // work item status
|
||||
volatile LONG m_StatusChangeWorkItemStatus; // work item status
|
||||
ULONG m_SyncFramePhysAddr; // periodic frame list physical address
|
||||
BUS_INTERFACE_STANDARD m_BusInterface; // pci bus interface
|
||||
BOOLEAN m_PortResetInProgress[0xF]; // stores reset in progress (vbox hack)
|
||||
@@ -1433,13 +1433,13 @@ EhciDefferedRoutine(
|
||||
//
|
||||
if (QueueSCEWorkItem && This->m_SCECallBack != NULL)
|
||||
{
|
||||
// work item is now active
|
||||
This->m_WorkItemActive = TRUE;
|
||||
|
||||
//
|
||||
// queue work item for processing
|
||||
//
|
||||
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
|
||||
if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0)
|
||||
{
|
||||
//
|
||||
// queue work item for processing
|
||||
//
|
||||
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -1466,8 +1466,10 @@ StatusChangeWorkItemRoutine(
|
||||
This->m_SCECallBack(This->m_SCEContext);
|
||||
}
|
||||
|
||||
// work item is completed
|
||||
This->m_WorkItemActive = FALSE;
|
||||
//
|
||||
// reset active status
|
||||
//
|
||||
InterlockedDecrement(&This->m_StatusChangeWorkItemStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
||||
@@ -101,6 +101,7 @@ protected:
|
||||
HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine
|
||||
PVOID m_SCEContext; // status change callback routine context
|
||||
WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
|
||||
volatile LONG m_StatusChangeWorkItemStatus; // work item active status
|
||||
ULONG m_SyncFramePhysAddr; // periodic frame list physical address
|
||||
ULONG m_IntervalValue; // periodic interval value
|
||||
};
|
||||
@@ -1523,10 +1524,13 @@ OhciDefferedRoutine(
|
||||
//
|
||||
if (QueueSCEWorkItem && This->m_SCECallBack != NULL)
|
||||
{
|
||||
//
|
||||
// queue work item for processing
|
||||
//
|
||||
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
|
||||
if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0)
|
||||
{
|
||||
//
|
||||
// queue work item for processing
|
||||
//
|
||||
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1552,6 +1556,10 @@ StatusChangeWorkItemRoutine(
|
||||
This->m_SCECallBack(This->m_SCEContext);
|
||||
}
|
||||
|
||||
//
|
||||
// reset active status
|
||||
//
|
||||
InterlockedDecrement(&This->m_StatusChangeWorkItemStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
||||
Reference in New Issue
Block a user