diff --git a/drivers/hid/CMakeLists.txt b/drivers/hid/CMakeLists.txt index 166cf1871a3..6051356e048 100644 --- a/drivers/hid/CMakeLists.txt +++ b/drivers/hid/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(hidclass) add_subdirectory(hidparse) add_subdirectory(hidusb) +add_subdirectory(kbdhid) add_subdirectory(mouhid) diff --git a/drivers/hid/kbdhid/CMakeLists.txt b/drivers/hid/kbdhid/CMakeLists.txt new file mode 100644 index 00000000000..57d918b53e9 --- /dev/null +++ b/drivers/hid/kbdhid/CMakeLists.txt @@ -0,0 +1,13 @@ + +add_definitions(-DDEBUG_MODE) + +include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include) + +add_library(kbdhid SHARED kbdhid.c kbdhid.rc) + +set_module_type(kbdhid kernelmodedriver) +add_importlibs(kbdhid ntoskrnl hal hidparse) +add_cab_target(kbdhid 2) + +add_cab_target(kbdhid 2) + diff --git a/drivers/hid/kbdhid/kbdhid.c b/drivers/hid/kbdhid/kbdhid.c new file mode 100644 index 00000000000..d0ad1e56247 --- /dev/null +++ b/drivers/hid/kbdhid/kbdhid.c @@ -0,0 +1,674 @@ +/* + * PROJECT: ReactOS HID Stack + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/hid/kbdhid/kbdhid.c + * PURPOSE: Keyboard HID Driver + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + * Johannes Anderwald (johannes.anderwald@reactos.org) + */ + +#include "kbdhid.h" + +VOID +KbdHid_DispatchInputData( + IN PKBDHID_DEVICE_EXTENSION DeviceExtension, + IN PKEYBOARD_INPUT_DATA InputData, + IN ULONG InputDataLength) +{ + KIRQL OldIrql; + ULONG InputDataConsumed; + + if (!DeviceExtension->ClassService) + return; + + /* sanity check */ + ASSERT(DeviceExtension->ClassService); + ASSERT(DeviceExtension->ClassDeviceObject); + + /* raise irql */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + /* dispatch input data */ + (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassService)(DeviceExtension->ClassDeviceObject, InputData, InputData + InputDataLength + 1, &InputDataConsumed); + + /* lower irql to previous level */ + KeLowerIrql(OldIrql); +} + +NTSTATUS +NTAPI +KbdHid_ReadCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PKBDHID_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("[KBDHID] 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; + } + + UNIMPLEMENTED + ASSERT(FALSE); + + /* dispatch mouse action */ + //KbdHid_DispatchInputData(DeviceExtension, &InputData); + + /* re-init read */ + KbdHid_InitiateRead(DeviceExtension); + + /* stop completion */ + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +KbdHid_InitiateRead( + IN PKBDHID_DEVICE_EXTENSION DeviceExtension) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* re-use irp */ + IoReuseIrp(DeviceExtension->Irp, STATUS_SUCCESS); + + /* init irp */ + DeviceExtension->Irp->MdlAddress = DeviceExtension->ReportMDL; + + /* get next stack location */ + IoStack = IoGetNextIrpStackLocation(DeviceExtension->Irp); + + /* init stack location */ + IoStack->Parameters.Read.Length = DeviceExtension->ReportLength; + IoStack->Parameters.Read.Key = 0; + IoStack->Parameters.Read.ByteOffset.QuadPart = 0LL; + IoStack->MajorFunction = IRP_MJ_READ; + IoStack->FileObject = DeviceExtension->FileObject; + + /* set completion routine */ + IoSetCompletionRoutine(DeviceExtension->Irp, KbdHid_ReadCompletion, DeviceExtension, TRUE, TRUE, TRUE); + + /* read is active */ + DeviceExtension->ReadReportActive = TRUE; + + /* start the read */ + Status = IoCallDriver(DeviceExtension->NextDeviceObject, DeviceExtension->Irp); + + /* done */ + return Status; +} + +NTSTATUS +NTAPI +KbdHid_CreateCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + KeSetEvent((PKEVENT)Context, 0, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + + +NTSTATUS +NTAPI +KbdHid_Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + KEVENT Event; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + DPRINT1("[KBDHID]: IRP_MJ_CREATE\n"); + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* copy stack location to next */ + IoCopyCurrentIrpStackLocationToNext(Irp); + + /* init event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + /* prepare irp */ + IoSetCompletionRoutine(Irp, KbdHid_CreateCompletion, &Event, TRUE, TRUE, TRUE); + + /* call lower driver */ + Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); + if (Status == STATUS_PENDING) + { + /* request pending */ + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + } + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* failed */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* is the driver already in use */ + if (DeviceExtension->FileObject == NULL) + { + /* did the caller specify correct attributes */ + ASSERT(IoStack->Parameters.Create.SecurityContext); + if (IoStack->Parameters.Create.SecurityContext->DesiredAccess) + { + /* store file object */ + DeviceExtension->FileObject = IoStack->FileObject; + + /* reset event */ + KeResetEvent(&DeviceExtension->ReadCompletionEvent); + + /* initiating read */ + Status = KbdHid_InitiateRead(DeviceExtension); + DPRINT1("[KBDHID] KbdHid_InitiateRead: status %x\n", Status); + if (Status == STATUS_PENDING) + { + /* report irp is pending */ + Status = STATUS_SUCCESS; + } + } + } + + /* complete request */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + + +NTSTATUS +NTAPI +KbdHid_Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + DPRINT("[KBDHID] 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("[KBDHID] IRP_MJ_CLOSE ReadReportActive %x\n", DeviceExtension->ReadReportActive); + + /* remove file object */ + DeviceExtension->FileObject = NULL; + + /* skip location */ + IoSkipCurrentIrpStackLocation(Irp); + + /* pass irp to down the stack */ + return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); +} + +NTSTATUS +NTAPI +KbdHid_InternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("[KBDHID] InternalDeviceControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + DPRINT1("[KBDHID] Unknown DeviceControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + + ASSERT(FALSE); + /* unknown request not supported */ + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +KbdHid_DeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* skip stack location */ + IoSkipCurrentIrpStackLocation(Irp); + + /* pass and forget */ + return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); +} + +NTSTATUS +NTAPI +KbdHid_Power( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +KbdHid_SubmitRequest( + PDEVICE_OBJECT DeviceObject, + ULONG IoControlCode, + ULONG InputBufferSize, + PVOID InputBuffer, + ULONG OutputBufferSize, + PVOID OutputBuffer) +{ + KEVENT Event; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + PIRP Irp; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + + /* get device extension */ + DeviceExtension = (PKBDHID_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 +KbdHid_StartDevice( + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + ULONG Buttons; + HID_COLLECTION_INFORMATION Information; + PHIDP_PREPARSED_DATA PreparsedData; + HIDP_CAPS Capabilities; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + PUSAGE_AND_PAGE Buffer; + + /* get device extension */ + 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); + if (!NT_SUCCESS(Status)) + { + /* failed to query collection information */ + DPRINT1("[KBDHID] failed to obtain collection information with %x\n", Status); + return Status; + } + + /* lets allocate space for preparsed data */ + PreparsedData = (PHIDP_PREPARSED_DATA)ExAllocatePool(NonPagedPool, Information.DescriptorSize); + if (!PreparsedData) + { + /* no memory */ + DPRINT1("[KBDHID] no memory size %u\n", Information.DescriptorSize); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* now obtain the preparsed data */ + Status = KbdHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, 0, NULL, Information.DescriptorSize, PreparsedData); + if (!NT_SUCCESS(Status)) + { + /* failed to get preparsed data */ + DPRINT1("[KBDHID] failed to obtain collection information with %x\n", Status); + ExFreePool(PreparsedData); + return Status; + } + + /* lets get the caps */ + Status = HidP_GetCaps(PreparsedData, &Capabilities); + if (Status != HIDP_STATUS_SUCCESS) + { + /* failed to get capabilities */ + DPRINT1("[KBDHID] failed to obtain caps with %x\n", Status); + ExFreePool(PreparsedData); + return Status; + } + + DPRINT1("[KBDHID] Usage %x UsagePage %x InputReportLength %lu\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength); + + /* init input report*/ + DeviceExtension->ReportLength = Capabilities.InputReportByteLength; + ASSERT(DeviceExtension->ReportLength); + DeviceExtension->Report = (PUCHAR)ExAllocatePool(NonPagedPool, DeviceExtension->ReportLength); + ASSERT(DeviceExtension->Report); + RtlZeroMemory(DeviceExtension->Report, DeviceExtension->ReportLength); + + /* build mdl */ + 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); + DPRINT1("[KBDHID] Buttons %lu\n", Buttons); + ASSERT(Buttons > 0); + + /* now allocate an array for those buttons */ + Buffer = (PUSAGE_AND_PAGE)ExAllocatePool(NonPagedPool, sizeof(USAGE_AND_PAGE) * 4 * Buttons); + if (!Buffer) + { + /* no memory */ + ExFreePool(PreparsedData); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* init usage lists */ + RtlZeroMemory(Buffer, sizeof(USAGE_AND_PAGE) * 4 * Buttons); + DeviceExtension->CurrentUsageList = Buffer; + Buffer += Buttons; + DeviceExtension->PreviousUsageList = Buffer; + Buffer += Buttons; + DeviceExtension->MakeUsageList = Buffer; + Buffer += Buttons; + DeviceExtension->BreakUsageList = Buffer; + + // + // FIMXE: implement device hacks + // + // UsageMappings + // KeyboardTypeOverride + // KeyboardSubTypeOverride + // KeyboardNumberTotalKeysOverride + // KeyboardNumberFunctionKeysOverride + // KeyboardNumberIndicatorsOverride + + /* store number of buttons */ + DeviceExtension->UsageListLength = (USHORT)Buttons; + + /* store preparsed data */ + DeviceExtension->PreparsedData = PreparsedData; + + /* completed successfully */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +KbdHid_StartDeviceCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + KeSetEvent((PKEVENT)Context, 0, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +NTAPI +KbdHid_Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* skip current stack location */ + IoSkipCurrentIrpStackLocation(Irp); + + /* get next stack location */ + IoStack = IoGetNextIrpStackLocation(Irp); + + /* change request to hid flush queue request */ + IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_FLUSH_QUEUE; + + /* call device */ + return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); +} + +NTSTATUS +NTAPI +KbdHid_Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + KEVENT Event; + NTSTATUS Status; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + DPRINT1("[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) + { + /* 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, 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); + DPRINT1("KbdHid_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 +KbdHid_AddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject) +{ + NTSTATUS Status; + PDEVICE_OBJECT DeviceObject, NextDeviceObject; + PKBDHID_DEVICE_EXTENSION DeviceExtension; + POWER_STATE State; + + /* create device object */ + Status = IoCreateDevice(DriverObject, sizeof(KBDHID_DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 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 = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* zero extension */ + RtlZeroMemory(DeviceExtension, sizeof(KBDHID_DEVICE_EXTENSION)); + + /* init device extension */ + DeviceExtension->NextDeviceObject = NextDeviceObject; + KeInitializeEvent(&DeviceExtension->ReadCompletionEvent, NotificationEvent, FALSE); + DeviceExtension->Irp = IoAllocateIrp(NextDeviceObject->StackSize, FALSE); + + /* FIXME handle allocation error */ + ASSERT(DeviceExtension->Irp); + + /* 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 +KbdHid_Unload( + IN PDRIVER_OBJECT DriverObject) +{ + UNIMPLEMENTED +} + + +NTSTATUS +NTAPI +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegPath) +{ + /* initialize driver object */ + DriverObject->DriverUnload = KbdHid_Unload; + DriverObject->DriverExtension->AddDevice = KbdHid_AddDevice; + DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdHid_Create; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdHid_Close; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = KbdHid_Flush; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdHid_DeviceControl; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = KbdHid_InternalDeviceControl; + DriverObject->MajorFunction[IRP_MJ_POWER] = KbdHid_Power; + DriverObject->MajorFunction[IRP_MJ_PNP] = KbdHid_Pnp; + DriverObject->DriverUnload = KbdHid_Unload; + DriverObject->DriverExtension->AddDevice = KbdHid_AddDevice; + + /* done */ + return STATUS_SUCCESS; +} diff --git a/drivers/hid/kbdhid/kbdhid.h b/drivers/hid/kbdhid/kbdhid.h new file mode 100644 index 00000000000..8add1785bb1 --- /dev/null +++ b/drivers/hid/kbdhid/kbdhid.h @@ -0,0 +1,106 @@ +#pragma once + +#define _HIDPI_NO_FUNCTION_MACROS_ +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct +{ + // + // lower device object + // + PDEVICE_OBJECT NextDeviceObject; + + // + // irp which is used for reading input reports + // + PIRP Irp; + + // + // event + // + KEVENT ReadCompletionEvent; + + // + // device object for class callback + // + PDEVICE_OBJECT ClassDeviceObject; + + // + // class callback + // + PVOID ClassService; + + // + // usage list length + // + USHORT UsageListLength; + + // + // current usage list length + // + PUSAGE_AND_PAGE CurrentUsageList; + + // + // previous usage list + // + PUSAGE_AND_PAGE PreviousUsageList; + + // + // removed usage item list + // + PUSAGE_AND_PAGE BreakUsageList; + + // + // new item usage list + // + PUSAGE_AND_PAGE MakeUsageList; + + // + // preparsed data + // + PVOID PreparsedData; + + // + // mdl for reading input report + // + PMDL ReportMDL; + + // + // input report buffer + // + PUCHAR Report; + + // + // input report length + // + ULONG ReportLength; + + // + // file object the device is reading reports from + // + PFILE_OBJECT FileObject; + + // + // report read is active + // + UCHAR ReadReportActive; + + // + // stop reading flag + // + UCHAR StopReadReport; + +}KBDHID_DEVICE_EXTENSION, *PKBDHID_DEVICE_EXTENSION; + + +NTSTATUS +KbdHid_InitiateRead( + IN PKBDHID_DEVICE_EXTENSION DeviceExtension); diff --git a/drivers/hid/kbdhid/kbdhid.rc b/drivers/hid/kbdhid/kbdhid.rc new file mode 100644 index 00000000000..317d71e2932 --- /dev/null +++ b/drivers/hid/kbdhid/kbdhid.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Keyboard HID Class Driver\0" +#define REACTOS_STR_INTERNAL_NAME "kbdhid\0" +#define REACTOS_STR_ORIGINAL_FILENAME "kbdhid.sys\0" +#include diff --git a/drivers/hid/mouhid/mouhid.rc b/drivers/hid/mouhid/mouhid.rc index 3da21c341f6..ae82d18f99b 100644 --- a/drivers/hid/mouhid/mouhid.rc +++ b/drivers/hid/mouhid/mouhid.rc @@ -1,5 +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" +#define REACTOS_STR_FILE_DESCRIPTION "Mouse HID Class Driver\0" +#define REACTOS_STR_INTERNAL_NAME "mouhid\0" +#define REACTOS_STR_ORIGINAL_FILENAME "mouhid.sys\0" #include