mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[HIDCLASS] Implement IOCTL_HID_GET_FEATURE/IOCTL_HID_SET_FEATURE
This commit is contained in:
parent
afca8367ea
commit
501116b68f
3 changed files with 145 additions and 0 deletions
|
@ -934,6 +934,120 @@ HidClass_DeviceControl(
|
|||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case IOCTL_HID_GET_FEATURE:
|
||||
{
|
||||
PIRP SubIrp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HID_XFER_PACKET XferPacket;
|
||||
NTSTATUS Status;
|
||||
PHIDP_REPORT_IDS ReportDescription;
|
||||
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < 1)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
ReportDescription = HidClassPDO_GetReportDescriptionByReportID(&PDODeviceExtension->Common.DeviceDescription, ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0]);
|
||||
if (!ReportDescription || IoStack->Parameters.DeviceIoControl.OutputBufferLength < ReportDescription->FeatureLength)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&XferPacket, sizeof(XferPacket));
|
||||
XferPacket.reportBufferLen = ReportDescription->FeatureLength;
|
||||
XferPacket.reportBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
XferPacket.reportId = ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0];
|
||||
if (!XferPacket.reportBuffer)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
SubIrp = IoBuildDeviceIoControlRequest(
|
||||
IOCTL_HID_GET_FEATURE,
|
||||
CommonDeviceExtension->HidDeviceExtension.NextDeviceObject,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
TRUE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!SubIrp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
SubIrp->UserBuffer = &XferPacket;
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
Status = IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, SubIrp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
case IOCTL_HID_SET_FEATURE:
|
||||
{
|
||||
PIRP SubIrp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HID_XFER_PACKET XferPacket;
|
||||
NTSTATUS Status;
|
||||
PHIDP_REPORT_IDS ReportDescription;
|
||||
|
||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < 1)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
ReportDescription = HidClassPDO_GetReportDescriptionByReportID(&PDODeviceExtension->Common.DeviceDescription, ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0]);
|
||||
if (!ReportDescription || IoStack->Parameters.DeviceIoControl.InputBufferLength < ReportDescription->FeatureLength)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&XferPacket, sizeof(XferPacket));
|
||||
XferPacket.reportBufferLen = ReportDescription->FeatureLength;
|
||||
XferPacket.reportBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
XferPacket.reportId = XferPacket.reportBuffer[0];
|
||||
|
||||
SubIrp = IoBuildDeviceIoControlRequest(
|
||||
IOCTL_HID_SET_FEATURE,
|
||||
CommonDeviceExtension->HidDeviceExtension.NextDeviceObject,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
TRUE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!SubIrp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
SubIrp->UserBuffer = &XferPacket;
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
Status = IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, SubIrp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
||||
|
|
|
@ -67,6 +67,32 @@ HidClassPDO_GetReportDescription(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PHIDP_REPORT_IDS
|
||||
HidClassPDO_GetReportDescriptionByReportID(
|
||||
PHIDP_DEVICE_DESC DeviceDescription,
|
||||
UCHAR ReportID)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for (Index = 0; Index < DeviceDescription->ReportIDsLength; Index++)
|
||||
{
|
||||
if (DeviceDescription->ReportIDs[Index].ReportID == ReportID)
|
||||
{
|
||||
//
|
||||
// found report id
|
||||
//
|
||||
return &DeviceDescription->ReportIDs[Index];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// failed to find report id
|
||||
//
|
||||
DPRINT1("[HIDCLASS] GetReportDescriptionByReportID ReportID %x not found\n", ReportID);
|
||||
ASSERT(FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_HandleQueryDeviceId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
|
|
|
@ -213,4 +213,9 @@ HidClassPDO_GetReportDescription(
|
|||
PHIDP_DEVICE_DESC DeviceDescription,
|
||||
ULONG CollectionNumber);
|
||||
|
||||
PHIDP_REPORT_IDS
|
||||
HidClassPDO_GetReportDescriptionByReportID(
|
||||
PHIDP_DEVICE_DESC DeviceDescription,
|
||||
UCHAR ReportID);
|
||||
|
||||
#endif /* _HIDCLASS_PCH_ */
|
||||
|
|
Loading…
Reference in a new issue