mirror of
https://github.com/reactos/reactos.git
synced 2024-07-29 23:58:44 +00:00
[USB-BRINGUP]
- Rename device extension - Implement FDO Initialization (IRP_MN_START_DEVICE) svn path=/branches/usb-bringup/; revision=54787
This commit is contained in:
parent
ceb3f5ee43
commit
c671800d55
|
@ -2,6 +2,7 @@
|
||||||
spec2def(hidclass.sys hidclass.spec)
|
spec2def(hidclass.sys hidclass.spec)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
|
fdo.c
|
||||||
hidclass.c
|
hidclass.c
|
||||||
hidclass.rc
|
hidclass.rc
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/hidclass.def)
|
${CMAKE_CURRENT_BINARY_DIR}/hidclass.def)
|
||||||
|
|
472
drivers/hid/hidclass/fdo.c
Normal file
472
drivers/hid/hidclass/fdo.c
Normal file
|
@ -0,0 +1,472 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Human Interface Device Driver
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/hid/hidclass/fdo.c
|
||||||
|
* PURPOSE: HID Class Driver
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
*/
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClassFDO_QueryCapabilitiesCompletionRoutine(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// set event
|
||||||
|
//
|
||||||
|
KeSetEvent((PRKEVENT)Context, 0, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// completion is done in the HidClassFDO_QueryCapabilities routine
|
||||||
|
//
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_QueryCapabilities(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PDEVICE_CAPABILITIES Capabilities)
|
||||||
|
{
|
||||||
|
PIRP Irp;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now allocte the irp
|
||||||
|
//
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init stack location
|
||||||
|
//
|
||||||
|
IoStack->MajorFunction = IRP_MJ_PNP;
|
||||||
|
IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
|
||||||
|
IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, HidClassFDO_QueryCapabilitiesCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init capabilities
|
||||||
|
//
|
||||||
|
RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||||
|
Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
|
||||||
|
Capabilities->Version = 1; // FIXME hardcoded constant
|
||||||
|
Capabilities->Address = MAXULONG;
|
||||||
|
Capabilities->UINumber = MAXULONG;
|
||||||
|
|
||||||
|
//
|
||||||
|
// pnp irps have default completion code
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// call lower device
|
||||||
|
//
|
||||||
|
Status = IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for completion
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get status
|
||||||
|
//
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClassFDO_DispatchRequestSynchronousCompletion(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// signal event
|
||||||
|
//
|
||||||
|
KeSetEvent((PRKEVENT)Context, 0, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_DispatchRequestSynchronous(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
//
|
||||||
|
// init event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, HidClassFDO_DispatchRequestSynchronousCompletion, &Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
ASSERT(Irp->CurrentLocation > 0);
|
||||||
|
//
|
||||||
|
// create stack location
|
||||||
|
//
|
||||||
|
IoSetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// store device object
|
||||||
|
//
|
||||||
|
IoStack->DeviceObject = DeviceObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
DPRINT1("IoStack MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
|
||||||
|
Status = FDODeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// wait for the request to finish
|
||||||
|
//
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// update status
|
||||||
|
//
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_GetDescriptors(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// lets allocate irp
|
||||||
|
//
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init stack location
|
||||||
|
//
|
||||||
|
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_DESCRIPTOR;
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DESCRIPTOR);
|
||||||
|
IoStack->Parameters.DeviceIoControl.InputBufferLength = 0;
|
||||||
|
IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
|
||||||
|
Irp->UserBuffer = &FDODeviceExtension->HidDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// send request
|
||||||
|
//
|
||||||
|
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_DESCRIPTOR failed with %x\n", Status);
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// lets get device attributes
|
||||||
|
//
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_ATTRIBUTES;
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DEVICE_ATTRIBUTES);
|
||||||
|
Irp->UserBuffer = &FDODeviceExtension->Attributes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// send request
|
||||||
|
//
|
||||||
|
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_ATTRIBUTES failed with %x\n", Status);
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
ASSERT(FDODeviceExtension->HidDescriptor.bLength == sizeof(HID_DESCRIPTOR));
|
||||||
|
ASSERT(FDODeviceExtension->HidDescriptor.bNumDescriptors > 0);
|
||||||
|
ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength > 0);
|
||||||
|
ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].bReportType == HID_REPORT_DESCRIPTOR_TYPE);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// now allocate space for the report descriptor
|
||||||
|
//
|
||||||
|
FDODeviceExtension->ReportDescriptor = (PUCHAR)ExAllocatePool(NonPagedPool, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength);
|
||||||
|
if (!FDODeviceExtension->ReportDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// not enough memory
|
||||||
|
//
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// init stack location
|
||||||
|
//
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_REPORT_DESCRIPTOR;
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength = FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength;
|
||||||
|
Irp->UserBuffer = FDODeviceExtension->ReportDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// send request
|
||||||
|
//
|
||||||
|
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("[HIDCLASS] IOCTL_HID_GET_REPORT_DESCRIPTOR failed with %x\n", Status);
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// completed successfully
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_StartDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// query capabilities
|
||||||
|
//
|
||||||
|
Status = HidClassFDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// lets start the lower device too
|
||||||
|
//
|
||||||
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||||
|
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// lets get the descriptors
|
||||||
|
//
|
||||||
|
Status = HidClassFDO_GetDescriptors(DeviceObject);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now get the the collection description
|
||||||
|
//
|
||||||
|
Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->DeviceDescription);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_RemoveDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_DeviceRelations(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_PnP(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get current irp stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
switch(IoStack->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
{
|
||||||
|
return HidClassFDO_StartDevice(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
case IRP_MN_REMOVE_DEVICE:
|
||||||
|
{
|
||||||
|
return HidClassFDO_RemoveDevice(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_STOP_DEVICE:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// set status to succes
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// forward to lower device
|
||||||
|
//
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// set status to succes
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// forward to lower device
|
||||||
|
//
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
{
|
||||||
|
return HidClassFDO_DeviceRelations(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// dispatch to lower device
|
||||||
|
//
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ HidClassAddDevice(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
PDEVICE_OBJECT NewDeviceObject;
|
PDEVICE_OBJECT NewDeviceObject;
|
||||||
PHIDCLASS_DEVICE_EXTENSION DeviceExtension;
|
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||||
ULONG DeviceExtensionSize;
|
ULONG DeviceExtensionSize;
|
||||||
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ HidClassAddDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate device extension size */
|
/* calculate device extension size */
|
||||||
DeviceExtensionSize = sizeof(HIDCLASS_DEVICE_EXTENSION) + DriverExtension->DeviceExtensionSize;
|
DeviceExtensionSize = sizeof(HIDCLASS_FDO_EXTENSION) + DriverExtension->DeviceExtensionSize;
|
||||||
|
|
||||||
/* now create the device */
|
/* now create the device */
|
||||||
Status = IoCreateDevice(DriverObject, DeviceExtensionSize, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &NewDeviceObject);
|
Status = IoCreateDevice(DriverObject, DeviceExtensionSize, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &NewDeviceObject);
|
||||||
|
@ -73,20 +73,20 @@ HidClassAddDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get device extension */
|
/* get device extension */
|
||||||
DeviceExtension = (PHIDCLASS_DEVICE_EXTENSION)NewDeviceObject->DeviceExtension;
|
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)NewDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
/* zero device extension */
|
/* zero device extension */
|
||||||
RtlZeroMemory(DeviceExtension, sizeof(HIDCLASS_DEVICE_EXTENSION));
|
RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION));
|
||||||
|
|
||||||
/* initialize device extension */
|
/* initialize device extension */
|
||||||
DeviceExtension->HidDeviceExtension.PhysicalDeviceObject = PhysicalDeviceObject;
|
FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = PhysicalDeviceObject;
|
||||||
DeviceExtension->HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)DeviceExtension + sizeof(HIDCLASS_DEVICE_EXTENSION));
|
FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)FDODeviceExtension + sizeof(HIDCLASS_FDO_EXTENSION));
|
||||||
DeviceExtension->HidDeviceExtension.NextDeviceObject = IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject);
|
FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject);
|
||||||
DeviceExtension->IsFDO = TRUE;
|
FDODeviceExtension->Common.IsFDO = TRUE;
|
||||||
DeviceExtension->DriverExtension = DriverExtension;
|
FDODeviceExtension->DriverExtension = DriverExtension;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
ASSERT(DeviceExtension->HidDeviceExtension.NextDeviceObject);
|
ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
|
||||||
|
|
||||||
/* increment stack size */
|
/* increment stack size */
|
||||||
NewDeviceObject->StackSize++;
|
NewDeviceObject->StackSize++;
|
||||||
|
@ -102,7 +102,7 @@ HidClassAddDevice(
|
||||||
{
|
{
|
||||||
/* failed */
|
/* failed */
|
||||||
DPRINT1("HIDCLASS: AddDevice failed with %x\n", Status);
|
DPRINT1("HIDCLASS: AddDevice failed with %x\n", Status);
|
||||||
IoDetachDevice(DeviceExtension->HidDeviceExtension.NextDeviceObject);
|
IoDetachDevice(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
|
||||||
IoDeleteDevice(NewDeviceObject);
|
IoDeleteDevice(NewDeviceObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ HidClassDriverUnload(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
HidClassDispatch(
|
HidClass_Create(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,167 @@ HidClassDispatch(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_Close(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_Read(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_Write(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_DeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_InternalDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_Power(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_PnP(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get common device extension
|
||||||
|
//
|
||||||
|
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: support PDO
|
||||||
|
//
|
||||||
|
ASSERT(CommonDeviceExtension->IsFDO == TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle request
|
||||||
|
//
|
||||||
|
return HidClassFDO_PnP(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClass_DispatchDefault(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get common device extension
|
||||||
|
//
|
||||||
|
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: support PDO
|
||||||
|
//
|
||||||
|
ASSERT(CommonDeviceExtension->IsFDO == TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// skip current irp stack location
|
||||||
|
//
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// dispatch to lower device object
|
||||||
|
//
|
||||||
|
return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HidClassDispatch(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get current stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
DPRINT1("[HIDCLASS] Dispatch Major %x Minor %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
|
||||||
|
|
||||||
|
//
|
||||||
|
// dispatch request based on major function
|
||||||
|
//
|
||||||
|
switch(IoStack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
return HidClass_Create(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
return HidClass_Close(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
return HidClass_Read(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
return HidClass_Write(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
return HidClass_DeviceControl(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
|
||||||
|
return HidClass_InternalDeviceControl(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_POWER:
|
||||||
|
return HidClass_Power(DeviceObject, Irp);
|
||||||
|
case IRP_MJ_PNP:
|
||||||
|
return HidClass_PnP(DeviceObject, Irp);
|
||||||
|
default:
|
||||||
|
return HidClass_DispatchDefault(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
HidRegisterMinidriver(
|
HidRegisterMinidriver(
|
||||||
|
@ -167,7 +328,7 @@ HidRegisterMinidriver(
|
||||||
DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload;
|
DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload;
|
||||||
|
|
||||||
/* copy driver dispatch routines */
|
/* copy driver dispatch routines */
|
||||||
RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * IRP_MJ_MAXIMUM_FUNCTION);
|
RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION+1));
|
||||||
|
|
||||||
/* initialize lock */
|
/* initialize lock */
|
||||||
KeInitializeSpinLock(&DriverExtension->Lock);
|
KeInitializeSpinLock(&DriverExtension->Lock);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#define _HIDPI_NO_FUNCTION_MACROS_
|
#define _HIDPI_NO_FUNCTION_MACROS_
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <hidport.h>
|
#include <hidport.h>
|
||||||
|
#include <hidpddi.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ typedef struct
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
ULONG DeviceExtensionSize;
|
ULONG DeviceExtensionSize;
|
||||||
BOOLEAN DevicesArePolled;
|
BOOLEAN DevicesArePolled;
|
||||||
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION];
|
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
|
||||||
PDRIVER_ADD_DEVICE AddDevice;
|
PDRIVER_ADD_DEVICE AddDevice;
|
||||||
PDRIVER_UNLOAD DriverUnload;
|
PDRIVER_UNLOAD DriverUnload;
|
||||||
KSPIN_LOCK Lock;
|
KSPIN_LOCK Lock;
|
||||||
|
@ -22,6 +23,53 @@ typedef struct
|
||||||
{
|
{
|
||||||
HID_DEVICE_EXTENSION HidDeviceExtension;
|
HID_DEVICE_EXTENSION HidDeviceExtension;
|
||||||
BOOLEAN IsFDO;
|
BOOLEAN IsFDO;
|
||||||
|
}HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// parts shared by fdo and pdo
|
||||||
|
//
|
||||||
|
HIDCLASS_COMMON_DEVICE_EXTENSION Common;
|
||||||
|
|
||||||
|
//
|
||||||
|
// driver extension
|
||||||
|
//
|
||||||
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
|
||||||
}HIDCLASS_DEVICE_EXTENSION, *PHIDCLASS_DEVICE_EXTENSION;
|
//
|
||||||
|
// device capabilities
|
||||||
|
//
|
||||||
|
DEVICE_CAPABILITIES Capabilities;
|
||||||
|
|
||||||
|
//
|
||||||
|
// hid descriptor
|
||||||
|
//
|
||||||
|
HID_DESCRIPTOR HidDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// hid attributes
|
||||||
|
//
|
||||||
|
HID_DEVICE_ATTRIBUTES Attributes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// report descriptor
|
||||||
|
//
|
||||||
|
PUCHAR ReportDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// device description
|
||||||
|
//
|
||||||
|
HIDP_DEVICE_DESC DeviceDescription;
|
||||||
|
|
||||||
|
}HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
/* fdo.c */
|
||||||
|
NTSTATUS
|
||||||
|
HidClassFDO_PnP(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue