mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[USB-BRINGUP]
- Implement HidClassFDO_DeviceRelations - Implement IOCTL_HID_GET_COLLECTION_INFORMATION, IOCTL_HID_GET_COLLECTION_DESCRIPTOR - Implement IRP_MN_QUERY_ID, IRP_MN_QUERY_CAPABILITIES, IRP_MN_QUERY_BUS_INFORMATION, IRP_MN_QUERY_PNP_STATE, IRP_MN_QUERY_DEVICE_RELATIONS, - HIDClass PDO is now created and starts initialization, needs IRP_MN_START_DEVICE request implementation - Tested in Vbox 4.1.4 + WinXP + ReactOS hidusb,hidmou,hidclass svn path=/branches/usb-bringup/; revision=54791
This commit is contained in:
parent
ef72bc2d72
commit
a64411cfbf
5 changed files with 875 additions and 25 deletions
|
@ -5,6 +5,7 @@ list(APPEND SOURCE
|
|||
fdo.c
|
||||
hidclass.c
|
||||
hidclass.rc
|
||||
pdo.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/hidclass.def)
|
||||
|
||||
add_library(hidclass SHARED ${SOURCE})
|
||||
|
|
|
@ -145,7 +145,7 @@ HidClassFDO_DispatchRequestSynchronous(
|
|||
IN PIRP Irp)
|
||||
{
|
||||
KEVENT Event;
|
||||
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
|
@ -157,8 +157,7 @@ HidClassFDO_DispatchRequestSynchronous(
|
|||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// set completion routine
|
||||
|
@ -187,7 +186,7 @@ HidClassFDO_DispatchRequestSynchronous(
|
|||
// call driver
|
||||
//
|
||||
DPRINT1("IoStack MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
|
||||
Status = FDODeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
|
||||
Status = CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp);
|
||||
|
||||
//
|
||||
// wait for the request to finish
|
||||
|
@ -392,14 +391,133 @@ HidClassFDO_RemoveDevice(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassFDO_CopyDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS *OutRelations)
|
||||
{
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||
ULONG Index;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// allocate result
|
||||
//
|
||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations.Count-1) * sizeof(PDEVICE_OBJECT));
|
||||
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;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassFDO_DeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)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.Count == 0)
|
||||
{
|
||||
//
|
||||
// time to create the pdos
|
||||
//
|
||||
Status = HidClassPDO_CreatePDO(DeviceObject);
|
||||
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;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -83,7 +83,7 @@ HidClassAddDevice(
|
|||
FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)FDODeviceExtension + sizeof(HIDCLASS_FDO_EXTENSION));
|
||||
FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject);
|
||||
FDODeviceExtension->Common.IsFDO = TRUE;
|
||||
FDODeviceExtension->DriverExtension = DriverExtension;
|
||||
FDODeviceExtension->Common.DriverExtension = DriverExtension;
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
|
||||
|
@ -170,9 +170,105 @@ HidClass_DeviceControl(
|
|||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||
PHID_COLLECTION_INFORMATION CollectionInformation;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(CommonDeviceExtension->IsFDO == FALSE);
|
||||
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)CommonDeviceExtension;
|
||||
|
||||
//
|
||||
// get stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_HID_GET_COLLECTION_INFORMATION:
|
||||
{
|
||||
//
|
||||
// check if output buffer is big enough
|
||||
//
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_COLLECTION_INFORMATION))
|
||||
{
|
||||
//
|
||||
// invalid buffer size
|
||||
//
|
||||
Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
//
|
||||
// get output buffer
|
||||
//
|
||||
CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
|
||||
ASSERT(CollectionInformation);
|
||||
|
||||
//
|
||||
// init result buffer
|
||||
//
|
||||
CollectionInformation->DescriptorSize = PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; //FIXME which collection is to be retrieved for composite devices / multi collection devices?
|
||||
CollectionInformation->Polled = CommonDeviceExtension->DriverExtension->DevicesArePolled;
|
||||
CollectionInformation->VendorID = PDODeviceExtension->Attributes.VendorID;
|
||||
CollectionInformation->ProductID = PDODeviceExtension->Attributes.ProductID;
|
||||
CollectionInformation->VersionNumber = PDODeviceExtension->Attributes.VersionNumber;
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
Irp->IoStatus.Information = sizeof(HID_COLLECTION_INFORMATION);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case IOCTL_HID_GET_COLLECTION_DESCRIPTOR:
|
||||
{
|
||||
//
|
||||
// FIXME: which collection to use for composite / multi collection devices...
|
||||
//
|
||||
|
||||
//
|
||||
// check if output buffer is big enough
|
||||
//
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength)
|
||||
{
|
||||
//
|
||||
// invalid buffer size
|
||||
//
|
||||
Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
//
|
||||
// copy result
|
||||
//
|
||||
ASSERT(Irp->UserBuffer);
|
||||
RtlCopyMemory(Irp->UserBuffer, PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedData, PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength);
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
Irp->IoStatus.Information = PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
||||
ASSERT(FALSE);
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -212,14 +308,22 @@ HidClass_PnP(
|
|||
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// FIXME: support PDO
|
||||
// check type of device object
|
||||
//
|
||||
ASSERT(CommonDeviceExtension->IsFDO == TRUE);
|
||||
|
||||
//
|
||||
// handle request
|
||||
//
|
||||
return HidClassFDO_PnP(DeviceObject, Irp);
|
||||
if (CommonDeviceExtension->IsFDO)
|
||||
{
|
||||
//
|
||||
// handle request
|
||||
//
|
||||
return HidClassFDO_PnP(DeviceObject, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// handle request
|
||||
//
|
||||
return HidClassPDO_PnP(DeviceObject, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
566
drivers/hid/hidclass/pdo.c
Normal file
566
drivers/hid/hidclass/pdo.c
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* 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
|
||||
HidClassPDO_HandleQueryDeviceId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LPWSTR Buffer;
|
||||
LPWSTR NewBuffer, Ptr;
|
||||
ULONG Length;
|
||||
|
||||
//
|
||||
// copy current stack location
|
||||
//
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
//
|
||||
// call mini-driver
|
||||
//
|
||||
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// get buffer
|
||||
//
|
||||
Buffer = (LPWSTR)Irp->IoStatus.Information;
|
||||
Length = wcslen(Buffer);
|
||||
|
||||
//
|
||||
// allocate new buffer
|
||||
//
|
||||
NewBuffer = (LPWSTR)ExAllocatePool(NonPagedPool, (Length + 1) * sizeof(WCHAR));
|
||||
if (!NewBuffer)
|
||||
{
|
||||
//
|
||||
// failed to allocate buffer
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// replace bus
|
||||
//
|
||||
wcscpy(NewBuffer, L"HID\\");
|
||||
|
||||
//
|
||||
// get offset to first '\\'
|
||||
//
|
||||
Ptr = wcschr(Buffer, L'\\');
|
||||
if (Ptr)
|
||||
{
|
||||
//
|
||||
// append result
|
||||
//
|
||||
wcscat(NewBuffer, Ptr + 1);
|
||||
}
|
||||
|
||||
//
|
||||
// free old buffer
|
||||
//
|
||||
ExFreePool(Buffer);
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)NewBuffer;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_HandleQueryHardwareId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
WCHAR Buffer[100];
|
||||
ULONG Offset = 0;
|
||||
LPWSTR Ptr;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
|
||||
|
||||
//
|
||||
// copy current stack location
|
||||
//
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
//
|
||||
// call mini-driver
|
||||
//
|
||||
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// store hardware ids
|
||||
//
|
||||
Offset = swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Rev_%04x", PDODeviceExtension->Attributes.VendorID, PDODeviceExtension->Attributes.ProductID, PDODeviceExtension->Attributes.VersionNumber) + 1;
|
||||
Offset += swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x", PDODeviceExtension->Attributes.VendorID, PDODeviceExtension->Attributes.ProductID) + 1;
|
||||
|
||||
if (PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_GENERIC)
|
||||
{
|
||||
switch(PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage)
|
||||
{
|
||||
case HID_USAGE_GENERIC_POINTER:
|
||||
case HID_USAGE_GENERIC_MOUSE:
|
||||
//
|
||||
// Pointer / Mouse
|
||||
//
|
||||
Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_MOUSE") + 1;
|
||||
break;
|
||||
case HID_USAGE_GENERIC_GAMEPAD:
|
||||
case HID_USAGE_GENERIC_JOYSTICK:
|
||||
//
|
||||
// Joystick / Gamepad
|
||||
//
|
||||
Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_GAME") + 1;
|
||||
break;
|
||||
case HID_USAGE_GENERIC_KEYBOARD:
|
||||
case HID_USAGE_GENERIC_KEYPAD:
|
||||
//
|
||||
// Keyboard / Keypad
|
||||
//
|
||||
Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_KEYBOARD") + 1;
|
||||
break;
|
||||
case HID_USAGE_GENERIC_SYSTEM_CTL:
|
||||
//
|
||||
// System Control
|
||||
//
|
||||
Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_CONTROL") + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_CONSUMER && PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage == HID_USAGE_CONSUMERCTRL)
|
||||
{
|
||||
//
|
||||
// Consumer Audio Control
|
||||
//
|
||||
Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_CONSUMER") + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME: add 'HID_DEVICE_UP:0001_U:0002'
|
||||
//
|
||||
|
||||
//
|
||||
// add HID
|
||||
//
|
||||
Offset +=swprintf(&Buffer[Offset], L"HID_DEVICE") + 1;
|
||||
|
||||
//
|
||||
// free old buffer
|
||||
//
|
||||
ExFreePool((PVOID)Irp->IoStatus.Information);
|
||||
|
||||
//
|
||||
// allocate buffer
|
||||
//
|
||||
Ptr = (LPWSTR)ExAllocatePool(NonPagedPool, (Offset +1)* sizeof(WCHAR));
|
||||
if (!Ptr)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// copy buffer
|
||||
//
|
||||
RtlCopyMemory(Ptr, Buffer, Offset * sizeof(WCHAR));
|
||||
Ptr[Offset] = UNICODE_NULL;
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Ptr;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_HandleQueryInstanceId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// copy current stack location
|
||||
//
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
//
|
||||
// call mini-driver
|
||||
//
|
||||
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
DPRINT1("HidClassPDO_HandleQueryInstanceId Buffer %S\n", Irp->IoStatus.Information);
|
||||
//
|
||||
//TODO implement instance id
|
||||
// example:
|
||||
// HID\VID_045E&PID_0047\8&1A0700BC&0&0000
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_HandleQueryCompatibleId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// copy current stack location
|
||||
//
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
//
|
||||
// call mini-driver
|
||||
//
|
||||
Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME: implement me
|
||||
//
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_PnP(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
PPNP_BUS_INFORMATION BusInformation;
|
||||
PDEVICE_RELATIONS DeviceRelation;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
|
||||
|
||||
//
|
||||
// get current irp stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// handle request
|
||||
//
|
||||
switch(IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_ID:
|
||||
{
|
||||
if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
|
||||
{
|
||||
//
|
||||
// handle query device id
|
||||
//
|
||||
Status = HidClassPDO_HandleQueryDeviceId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
Status = HidClassPDO_HandleQueryHardwareId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
Status = HidClassPDO_HandleQueryInstanceId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
|
||||
{
|
||||
//
|
||||
// handle instance id
|
||||
//
|
||||
Status = HidClassPDO_HandleQueryCompatibleId(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT1("[HIDCLASS]: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
{
|
||||
if (IoStack->Parameters.DeviceCapabilities.Capabilities == NULL)
|
||||
{
|
||||
//
|
||||
// invalid request
|
||||
//
|
||||
Status = STATUS_DEVICE_CONFIGURATION_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// copy capabilities
|
||||
//
|
||||
RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
{
|
||||
//
|
||||
//
|
||||
//
|
||||
BusInformation = (PPNP_BUS_INFORMATION)ExAllocatePool(NonPagedPool, sizeof(PNP_BUS_INFORMATION));
|
||||
|
||||
//
|
||||
// fill in result
|
||||
//
|
||||
RtlCopyMemory(&BusInformation->BusTypeGuid, &GUID_BUS_TYPE_HID, sizeof(GUID));
|
||||
BusInformation->LegacyBusType = PNPBus;
|
||||
BusInformation->BusNumber = 0; //FIXME
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
{
|
||||
//
|
||||
// FIXME set flags when driver fails / disabled
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
//
|
||||
// only target relations are supported
|
||||
//
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
|
||||
{
|
||||
//
|
||||
// not supported
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// allocate device relations
|
||||
//
|
||||
DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS));
|
||||
if (!DeviceRelation)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// init device relation
|
||||
//
|
||||
DeviceRelation->Count = 1;
|
||||
DeviceRelation->Objects[0] = DeviceObject;
|
||||
ObReferenceObject(DeviceRelation->Objects[0]);
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] PDO PnP not implemented %x\n", IoStack->MinorFunction);
|
||||
ASSERT(FALSE);
|
||||
|
||||
//
|
||||
// do nothing
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] PDO IRP_MN_REMOVE_DEVICE not implemented\n");
|
||||
ASSERT(FALSE);
|
||||
|
||||
//
|
||||
// do nothing
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_INTERFACE:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] PDO IRP_MN_QUERY_INTERFACE not implemented\n");
|
||||
ASSERT(FALSE);
|
||||
|
||||
//
|
||||
// do nothing
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//
|
||||
// do nothing
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
||||
//
|
||||
// complete request
|
||||
//
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
//
|
||||
// done processing
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT PDODeviceObject;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// lets create the device object
|
||||
//
|
||||
Status = IoCreateDevice(FDODeviceExtension->Common.DriverExtension->DriverObject, sizeof(HIDCLASS_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &PDODeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create device
|
||||
//
|
||||
DPRINT1("[HIDCLASS] Failed to create device %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// patch stack size
|
||||
//
|
||||
PDODeviceObject->StackSize = DeviceObject->StackSize + 1;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// init device extension
|
||||
//
|
||||
PDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension;
|
||||
PDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject;
|
||||
PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = NULL;
|
||||
PDODeviceExtension->Common.IsFDO = FALSE;
|
||||
PDODeviceExtension->Common.DriverExtension = FDODeviceExtension->Common.DriverExtension;
|
||||
RtlCopyMemory(&PDODeviceExtension->Attributes, &FDODeviceExtension->Attributes, sizeof(HID_DEVICE_ATTRIBUTES));
|
||||
RtlCopyMemory(&PDODeviceExtension->DeviceDescription, &FDODeviceExtension->DeviceDescription, sizeof(HIDP_DEVICE_DESC));
|
||||
RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||
|
||||
//
|
||||
// FIXME: support composite devices
|
||||
//
|
||||
PDODeviceExtension->CollectionIndex = 0;
|
||||
ASSERT(PDODeviceExtension->DeviceDescription.CollectionDescLength == 1);
|
||||
|
||||
//
|
||||
// store in device relations struct
|
||||
//
|
||||
FDODeviceExtension->DeviceRelations.Count = 1;
|
||||
FDODeviceExtension->DeviceRelations.Objects[0] = PDODeviceObject;
|
||||
|
||||
//
|
||||
// set device flags
|
||||
//
|
||||
PDODeviceObject->Flags |= DO_MAP_IO_BUFFER;
|
||||
|
||||
//
|
||||
// device is initialized
|
||||
//
|
||||
PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
ObReferenceObject(PDODeviceObject);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -4,9 +4,13 @@
|
|||
#include <ntddk.h>
|
||||
#include <hidport.h>
|
||||
#include <hidpddi.h>
|
||||
#include <stdio.h>
|
||||
#include <initguid.h>
|
||||
#include <wdmguid.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
|
@ -21,12 +25,23 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
//
|
||||
// hid device extension
|
||||
//
|
||||
HID_DEVICE_EXTENSION HidDeviceExtension;
|
||||
|
||||
//
|
||||
// if it is a pdo
|
||||
//
|
||||
BOOLEAN IsFDO;
|
||||
|
||||
//
|
||||
// driver extension
|
||||
//
|
||||
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||
|
||||
}HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//
|
||||
|
@ -34,11 +49,6 @@ typedef struct
|
|||
//
|
||||
HIDCLASS_COMMON_DEVICE_EXTENSION Common;
|
||||
|
||||
//
|
||||
// driver extension
|
||||
//
|
||||
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
|
||||
|
||||
//
|
||||
// device capabilities
|
||||
//
|
||||
|
@ -64,8 +74,42 @@ typedef struct
|
|||
//
|
||||
HIDP_DEVICE_DESC DeviceDescription;
|
||||
|
||||
//
|
||||
// device relations
|
||||
//
|
||||
DEVICE_RELATIONS DeviceRelations;
|
||||
|
||||
}HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//
|
||||
// parts shared by fdo and pdo
|
||||
//
|
||||
HIDCLASS_COMMON_DEVICE_EXTENSION Common;
|
||||
|
||||
//
|
||||
// device descriptor
|
||||
//
|
||||
HID_DEVICE_ATTRIBUTES Attributes;
|
||||
|
||||
//
|
||||
// device capabilities
|
||||
//
|
||||
DEVICE_CAPABILITIES Capabilities;
|
||||
|
||||
//
|
||||
// device description
|
||||
//
|
||||
HIDP_DEVICE_DESC DeviceDescription;
|
||||
|
||||
//
|
||||
// collection index
|
||||
//
|
||||
ULONG CollectionIndex;
|
||||
|
||||
}HIDCLASS_PDO_DEVICE_EXTENSION, *PHIDCLASS_PDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* fdo.c */
|
||||
NTSTATUS
|
||||
|
@ -73,3 +117,20 @@ HidClassFDO_PnP(
|
|||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
HidClassFDO_DispatchRequestSynchronous(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/* pdo.c */
|
||||
NTSTATUS
|
||||
HidClassPDO_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_PnP(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
||||
/* eof */
|
||||
|
|
Loading…
Reference in a new issue