Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684/* * 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"
#define NDEBUG#include <debug.h>
NTSTATUSNTAPIHidClassFDO_QueryCapabilitiesCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){ // // set event // KeSetEvent(Context, 0, FALSE);
// // completion is done in the HidClassFDO_QueryCapabilities routine // return STATUS_MORE_PROCESSING_REQUIRED;}
NTSTATUSHidClassFDO_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 = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
// // init event // KeInitializeEvent(&Event, NotificationEvent, FALSE);
// // now allocate 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, &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;}
NTSTATUSNTAPIHidClassFDO_DispatchRequestSynchronousCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){ // // signal event // KeSetEvent(Context, 0, FALSE);
// // done // return STATUS_MORE_PROCESSING_REQUIRED;}
NTSTATUSHidClassFDO_DispatchRequestSynchronous( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ KEVENT Event; PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; NTSTATUS Status; PIO_STACK_LOCATION IoStack;
// // init event // KeInitializeEvent(&Event, NotificationEvent, FALSE);
// // get device extension // CommonDeviceExtension = DeviceObject->DeviceExtension;
// // 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;
// // sanity check // ASSERT(CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction] != NULL);
// // call minidriver (hidusb) // Status = CommonDeviceExtension->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;}
NTSTATUSHidClassFDO_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;}
NTSTATUSHidClassFDO_GetDescriptors( IN PDEVICE_OBJECT DeviceObject){ PHIDCLASS_FDO_EXTENSION FDODeviceExtension; PIRP Irp; PIO_STACK_LOCATION IoStack; NTSTATUS Status;
// // get device extension // FDODeviceExtension = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
// // let's 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; }
// // let's get device attributes // IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_ATTRIBUTES; IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DEVICE_ATTRIBUTES); Irp->UserBuffer = &FDODeviceExtension->Common.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 = ExAllocatePoolWithTag(NonPagedPool, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, HIDCLASS_TAG); 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 // IoFreeIrp(Irp); return STATUS_SUCCESS;}
NTSTATUSHidClassFDO_StartDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ NTSTATUS Status; PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
// // get device extension // FDODeviceExtension = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
// // query capabilities // Status = HidClassFDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities); if (!NT_SUCCESS(Status)) { DPRINT1("[HIDCLASS] Failed to retrieve capabilities %x\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
// // let's start the lower device too // IoSkipCurrentIrpStackLocation(Irp); Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); if (!NT_SUCCESS(Status)) { DPRINT1("[HIDCLASS] Failed to start lower device with %x\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
// // let's get the descriptors // Status = HidClassFDO_GetDescriptors(DeviceObject); if (!NT_SUCCESS(Status)) { DPRINT1("[HIDCLASS] Failed to retrieve the descriptors %x\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
// // now get the the collection description // Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->Common.DeviceDescription); if (!NT_SUCCESS(Status)) { DPRINT1("[HIDCLASS] Failed to retrieve the collection description %x\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
// // complete request // Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;}
NTSTATUSHidClassFDO_RemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ NTSTATUS Status; PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
// // get device extension // FDODeviceExtension = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
/* FIXME cleanup */
// // dispatch to minidriver // IoSkipCurrentIrpStackLocation(Irp); Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
// // complete request // Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT);
// // detach and delete device // IoDetachDevice(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject); IoDeleteDevice(DeviceObject);
return Status;}
NTSTATUSHidClassFDO_CopyDeviceRelations( IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_RELATIONS *OutRelations){ PDEVICE_RELATIONS DeviceRelations; PHIDCLASS_FDO_EXTENSION FDODeviceExtension; ULONG Index;
// // get device extension // FDODeviceExtension = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
// // allocate result // DeviceRelations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations->Count - 1) * sizeof(PDEVICE_OBJECT), HIDCLASS_TAG); if (!DeviceRelations) { // // no memory // *OutRelations = NULL; return STATUS_INSUFFICIENT_RESOURCES; }
// // copy device objects // for (Index = 0; Index < FDODeviceExtension->DeviceRelations->Count; Index++) { // // reference pdo // ObReferenceObject(FDODeviceExtension->DeviceRelations->Objects[Index]);
// // store object // DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations->Objects[Index]; }
// // set object count // DeviceRelations->Count = FDODeviceExtension->DeviceRelations->Count;
// // store result // *OutRelations = DeviceRelations; return STATUS_SUCCESS;}
NTSTATUSHidClassFDO_DeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PHIDCLASS_FDO_EXTENSION FDODeviceExtension; PIO_STACK_LOCATION IoStack; NTSTATUS Status; PDEVICE_RELATIONS DeviceRelations;
// // get device extension // FDODeviceExtension = DeviceObject->DeviceExtension; ASSERT(FDODeviceExtension->Common.IsFDO);
// // get current irp stack location // IoStack = IoGetCurrentIrpStackLocation(Irp);
// // check relations type // if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) { // // only bus relations are handled // IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); }
if (FDODeviceExtension->DeviceRelations == NULL) { // // time to create the pdos // Status = HidClassPDO_CreatePDO(DeviceObject, &FDODeviceExtension->DeviceRelations); if (!NT_SUCCESS(Status)) { // // failed // DPRINT1("[HIDCLASS] HidClassPDO_CreatePDO failed with %x\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // // sanity check // ASSERT(FDODeviceExtension->DeviceRelations->Count > 0); }
// // now copy device relations // Status = HidClassFDO_CopyDeviceRelations(DeviceObject, &DeviceRelations); // // store result // Irp->IoStatus.Status = Status; Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
// // complete request // IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;}
NTSTATUSHidClassFDO_PnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; PHIDCLASS_FDO_EXTENSION FDODeviceExtension; NTSTATUS Status;
// // get device extension // FDODeviceExtension = 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_DEVICE_RELATIONS: { return HidClassFDO_DeviceRelations(DeviceObject, Irp); } case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: { // // set status to success and fall through // Irp->IoStatus.Status = STATUS_SUCCESS; } default: { // // dispatch to mini driver // IoCopyCurrentIrpStackLocationToNext(Irp); Status = HidClassFDO_DispatchRequest(DeviceObject, Irp); return Status; } }}