mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[USB-BRINGUP]
- Halfplement mouse hid driver, WIP, untested svn path=/branches/usb-bringup/; revision=54762
This commit is contained in:
parent
69dfb12f9a
commit
3477d17d4b
6 changed files with 558 additions and 3 deletions
|
@ -1,3 +1,4 @@
|
||||||
add_subdirectory(hidclass)
|
add_subdirectory(hidclass)
|
||||||
add_subdirectory(hidparse)
|
add_subdirectory(hidparse)
|
||||||
add_subdirectory(hidusb)
|
add_subdirectory(hidusb)
|
||||||
|
add_subdirectory(mouhid)
|
||||||
|
|
|
@ -111,14 +111,13 @@ HidClassAddDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
HidClassDriverUnload(
|
HidClassDriverUnload(
|
||||||
IN PDRIVER_OBJECT DriverObject)
|
IN PDRIVER_OBJECT DriverObject)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
13
drivers/hid/mouhid/CMakeLists.txt
Normal file
13
drivers/hid/mouhid/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
add_definitions(-DDEBUG_MODE)
|
||||||
|
|
||||||
|
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||||
|
|
||||||
|
add_library(mouhid SHARED mouhid.c mouhid.rc)
|
||||||
|
|
||||||
|
set_module_type(mouhid kernelmodedriver)
|
||||||
|
add_importlibs(mouhid ntoskrnl hidparse)
|
||||||
|
add_cab_target(mouhid 2)
|
||||||
|
|
||||||
|
add_cab_target(mouhid 2)
|
||||||
|
|
514
drivers/hid/mouhid/mouhid.c
Normal file
514
drivers/hid/mouhid/mouhid.c
Normal file
|
@ -0,0 +1,514 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS HID Stack
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/hid/mouhid/mouhid.c
|
||||||
|
* PURPOSE: Mouse HID Driver
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mouhid.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_Create(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_Close(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_DeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PMOUSE_ATTRIBUTES Attributes;
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PCONNECT_DATA Data;
|
||||||
|
|
||||||
|
/* get current stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* handle requests */
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUSE_QUERY_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
/* verify output buffer length */
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
|
||||||
|
{
|
||||||
|
/* invalid request */
|
||||||
|
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get output buffer */
|
||||||
|
Attributes = (PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
|
/* type of mouse */
|
||||||
|
Attributes->MouseIdentifier = DeviceExtension->MouseIdentifier;
|
||||||
|
|
||||||
|
/* number of buttons */
|
||||||
|
Attributes->NumberOfButtons = DeviceExtension->Buttons;
|
||||||
|
|
||||||
|
/* sample rate not used for usb */
|
||||||
|
Attributes->SampleRate = 0;
|
||||||
|
|
||||||
|
/* queue length */
|
||||||
|
Attributes->InputDataQueueLength = 2;
|
||||||
|
|
||||||
|
/* 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_MOUSE_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;
|
||||||
|
}
|
||||||
|
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == 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)
|
||||||
|
{
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* not supported */
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unknown request not supported */
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_InternalDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* skip stack location */
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* pass and forget */
|
||||||
|
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_Power(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MouHid_SubmitRequest(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
ULONG IoControlCode,
|
||||||
|
ULONG InputBufferSize,
|
||||||
|
PVOID InputBuffer,
|
||||||
|
ULONG OutputBufferSize,
|
||||||
|
PVOID OutputBuffer)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIRP Irp;
|
||||||
|
NTSTATUS Status;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* init event */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
/* build request */
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(IoControlCode, DeviceExtension->NextDeviceObject, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, FALSE, &Event, &IoStatus);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send request */
|
||||||
|
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* wait for request to complete */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_StartDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG Buttons;
|
||||||
|
HID_COLLECTION_INFORMATION Information;
|
||||||
|
PVOID PreparsedData;
|
||||||
|
HIDP_CAPS Capabilities;
|
||||||
|
ULONG ValueCapsLength;
|
||||||
|
HIDP_VALUE_CAPS ValueCaps;
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
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);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed to query collection information */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lets allocate space for preparsed data */
|
||||||
|
PreparsedData = ExAllocatePool(NonPagedPool, Information.DescriptorSize);
|
||||||
|
if (PreparsedData)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now obtain the preparsed data */
|
||||||
|
Status = MouHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_DRIVER_CONFIG, 0, NULL, Information.DescriptorSize, PreparsedData);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed to get preparsed data */
|
||||||
|
ExFreePool(PreparsedData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lets get the caps */
|
||||||
|
Status = HidP_GetCaps(PreparsedData, &Capabilities);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed to get capabilities */
|
||||||
|
ExFreePool(PreparsedData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify capabilities */
|
||||||
|
if (Capabilities.Usage != HID_USAGE_GENERIC_POINTER && Capabilities.Usage != HID_USAGE_GENERIC_MOUSE || Capabilities.UsagePage != HID_USAGE_PAGE_GENERIC)
|
||||||
|
{
|
||||||
|
/* not supported */
|
||||||
|
ExFreePool(PreparsedData);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get number of buttons */
|
||||||
|
Buttons = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, PreparsedData);
|
||||||
|
ASSERT(Buttons > 0);
|
||||||
|
/* store number of buttons */
|
||||||
|
DeviceExtension->Buttons = (USHORT)Buttons;
|
||||||
|
|
||||||
|
ValueCapsLength = 1;
|
||||||
|
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &ValueCaps, &ValueCapsLength, PreparsedData);
|
||||||
|
|
||||||
|
ValueCapsLength = 1;
|
||||||
|
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &ValueCaps, &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 )
|
||||||
|
{
|
||||||
|
/* mouse has wheel support */
|
||||||
|
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
||||||
|
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 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);
|
||||||
|
if (Status == HIDP_STATUS_SUCCESS && ValueCapsLength == 1)
|
||||||
|
{
|
||||||
|
/* wheel support */
|
||||||
|
DeviceExtension->MouseIdentifier = WHEELMOUSE_HID_HARDWARE;
|
||||||
|
DeviceExtension->WheelUsagePage = ValueCaps.UsagePage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* completed successfully */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_StartDeviceCompletion(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
KeSetEvent((PKEVENT)Context, 0, FALSE);
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_Pnp(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* get current irp stack */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* indicate success */
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
/* cancel irp */
|
||||||
|
IoCancelIrp(DeviceExtension->Irp);
|
||||||
|
|
||||||
|
/* indicate success */
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* skip irp stack location */
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* dispatch to lower device */
|
||||||
|
Status = IoCallDriver(DeviceExtension->NextDeviceObject, 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);
|
||||||
|
|
||||||
|
/* copy stack location */
|
||||||
|
IoCopyCurrentIrpStackLocationToNext (Irp);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
DPRINT1("MouHid_StartDevice %x\n", Status);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MouHid_AddDevice(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT DeviceObject, NextDeviceObject;
|
||||||
|
PMOUHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
POWER_STATE State;
|
||||||
|
|
||||||
|
/* create device object */
|
||||||
|
Status = IoCreateDevice(DriverObject, sizeof(MOUHID_DEVICE_EXTENSION), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed to create device object */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now attach it */
|
||||||
|
NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
||||||
|
if (!NextDeviceObject)
|
||||||
|
{
|
||||||
|
/* failed to attach */
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
return STATUS_DEVICE_NOT_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PMOUHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* zero extension */
|
||||||
|
RtlZeroMemory(DeviceExtension, sizeof(MOUHID_DEVICE_EXTENSION));
|
||||||
|
|
||||||
|
/* init device extension */
|
||||||
|
DeviceExtension->MouseIdentifier = MOUSE_HID_HARDWARE;
|
||||||
|
DeviceExtension->Buttons = 0;
|
||||||
|
DeviceExtension->WheelUsagePage = 0;
|
||||||
|
DeviceExtension->NextDeviceObject = NextDeviceObject;
|
||||||
|
KeInitializeEvent(&DeviceExtension->Event, NotificationEvent, FALSE);
|
||||||
|
DeviceExtension->Irp = IoAllocateIrp(NextDeviceObject->StackSize, FALSE);
|
||||||
|
|
||||||
|
/* FIXME handle allocation error */
|
||||||
|
ASSERT(DeviceExtension->Irp);
|
||||||
|
|
||||||
|
/* FIXME query parameter 'FlipFlopWheel', 'WheelScalingFactor' */
|
||||||
|
|
||||||
|
/* set power state to D0 */
|
||||||
|
State.DeviceState = PowerDeviceD0;
|
||||||
|
PoSetPowerState(DeviceObject, DevicePowerState, State);
|
||||||
|
|
||||||
|
/* init device object */
|
||||||
|
DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
|
||||||
|
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
/* completed successfully */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MouHid_Unload(
|
||||||
|
IN PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegPath)
|
||||||
|
{
|
||||||
|
/* FIXME check for parameters 'UseOnlyMice', 'TreatAbsoluteAsRelative', 'TreatAbsolutePointerAsAbsolute' */
|
||||||
|
|
||||||
|
/* initialize driver object */
|
||||||
|
DriverObject->DriverUnload = MouHid_Unload;
|
||||||
|
DriverObject->DriverExtension->AddDevice = MouHid_AddDevice;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = MouHid_Create;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouHid_Close;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MouHid_DeviceControl;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MouHid_InternalDeviceControl;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_POWER] = MouHid_Power;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_PNP] = MouHid_Pnp;
|
||||||
|
DriverObject->DriverUnload = MouHid_Unload;
|
||||||
|
DriverObject->DriverExtension->AddDevice = MouHid_AddDevice;
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
23
drivers/hid/mouhid/mouhid.h
Normal file
23
drivers/hid/mouhid/mouhid.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define _HIDPI_NO_FUNCTION_MACROS_
|
||||||
|
#include <ntddk.h>
|
||||||
|
#include <hidclass.h>
|
||||||
|
#include <hidpddi.h>
|
||||||
|
#include <hidpi.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <ntddmou.h>
|
||||||
|
#include <kbdmou.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT NextDeviceObject;
|
||||||
|
PIRP Irp;
|
||||||
|
KEVENT Event;
|
||||||
|
PDEVICE_OBJECT ClassDeviceObject;
|
||||||
|
PVOID ClassService;
|
||||||
|
USHORT Buttons;
|
||||||
|
USHORT MouseIdentifier;
|
||||||
|
USHORT WheelUsagePage;
|
||||||
|
}MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
|
5
drivers/hid/mouhid/mouhid.rc
Normal file
5
drivers/hid/mouhid/mouhid.rc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#define REACTOS_VERSION_DLL
|
||||||
|
#define REACTOS_STR_FILE_DESCRIPTION "USB HID Parser\0"
|
||||||
|
#define REACTOS_STR_INTERNAL_NAME "hidparse\0"
|
||||||
|
#define REACTOS_STR_ORIGINAL_FILENAME "hidparse.sys\0"
|
||||||
|
#include <reactos/version.rc>
|
Loading…
Reference in a new issue