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);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_SUCCESS;
|
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:
|
default:
|
||||||
{
|
{
|
||||||
DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
|
||||||
|
|
|
@ -67,6 +67,32 @@ HidClassPDO_GetReportDescription(
|
||||||
return NULL;
|
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
|
NTSTATUS
|
||||||
HidClassPDO_HandleQueryDeviceId(
|
HidClassPDO_HandleQueryDeviceId(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
|
@ -213,4 +213,9 @@ HidClassPDO_GetReportDescription(
|
||||||
PHIDP_DEVICE_DESC DeviceDescription,
|
PHIDP_DEVICE_DESC DeviceDescription,
|
||||||
ULONG CollectionNumber);
|
ULONG CollectionNumber);
|
||||||
|
|
||||||
|
PHIDP_REPORT_IDS
|
||||||
|
HidClassPDO_GetReportDescriptionByReportID(
|
||||||
|
PHIDP_DEVICE_DESC DeviceDescription,
|
||||||
|
UCHAR ReportID);
|
||||||
|
|
||||||
#endif /* _HIDCLASS_PCH_ */
|
#endif /* _HIDCLASS_PCH_ */
|
||||||
|
|
Loading…
Reference in a new issue