//
// informal debug print
//
- DPRINT1("HIDUSB Request: %x\n", IoStack->MajorFunction);
+ DPRINT("HIDUSB Request: %x\n", IoStack->MajorFunction);
//
// done
PHID_USB_RESET_CONTEXT ResetContext;
PHID_DEVICE_EXTENSION DeviceExtension;
- DPRINT1("[HIDUSB] ResetWorkerRoutine\n");
+ DPRINT("[HIDUSB] ResetWorkerRoutine\n");
//
// get context
// get port status
//
Status = HidUsb_GetPortStatus(ResetContext->DeviceObject, &PortStatus);
- DPRINT1("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status, PortStatus);
+ DPRINT("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status, PortStatus);
if (NT_SUCCESS(Status))
{
if (!(PortStatus & USB_PORT_STATUS_ENABLE))
{
//
// failed to get descriptor
+ // try with old hid version
//
- DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status);
- ASSERT(FALSE);
- return Status;
+ BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength;
+ Status = Hid_GetDescriptor(DeviceObject, URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), &Report, &BufferLength, HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType, 0, 0 /* FIXME*/);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status);
+ return Status;
+ }
}
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT1("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status, HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength);
+ DPRINT("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status, HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength);
//
// get length to copy
//
// store result
//
- DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n");
+ DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n");
ASSERT(HidDeviceExtension->DeviceDescriptor);
Irp->IoStatus.Information = sizeof(HID_DESCRIPTOR);
Attributes = (PHID_DEVICE_ATTRIBUTES)Irp->UserBuffer;
// sanity check
//
ASSERT(HidDeviceExtension->HidDescriptor);
- DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+ DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
//
// store length
case IOCTL_HID_GET_REPORT_DESCRIPTOR:
{
Status = HidUsb_GetReportDescriptor(DeviceObject, Irp);
- DPRINT1("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status);
+ DPRINT("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status);
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
Status = IoStatus.Status;
}
- DPRINT1("[HIDUSB] DispatchUrb %x\n", Status);
+ DPRINT("[HIDUSB] DispatchUrb %x\n", Status);
//
USB_DEVICE_CLASS_HUMAN_INTERFACE,
-1,
-1);
+ if (!InterfaceDescriptor)
+ {
+ //
+ // bogus configuration descriptor
+ //
+ return STATUS_INVALID_PARAMETER;
+ }
//
// sanity check
return Status;
}
+NTSTATUS
+Hid_SetIdle(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+ PURB Urb;
+ NTSTATUS Status;
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ HidDeviceExtension = (PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+ //
+ // allocate urb
+ //
+ Urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // zero urb
+ //
+ RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+
+ //
+ // format urb
+ //
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ 0,
+ 0,
+ USB_SET_IDLE_REQUEST, // HID_SET_IDLE
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ NULL);
+
+ //
+ // dispatch urb
+ //
+ Status = Hid_DispatchUrb(DeviceObject, Urb);
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+
+ //
+ // print status
+ //
+ DPRINT1("Status %x\n", Status);
+ return Status;
+}
+
+
+VOID
+Hid_GetProtocol(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+ PURB Urb;
+ NTSTATUS Status;
+ UCHAR Protocol[1];
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ HidDeviceExtension = (PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+ ASSERT(HidDeviceExtension->InterfaceInfo);
+
+ if (HidDeviceExtension->InterfaceInfo->SubClass != 0x1)
+ {
+ //
+ // device does not support the boot protocol
+ //
+ return;
+ }
+
+
+ //
+ // allocate urb
+ //
+ Urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ //
+ // no memory
+ //
+ return;
+ }
+
+ //
+ // zero urb
+ //
+ RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+
+ //
+ // format urb
+ //
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_GET_PROTOCOL_REQUEST,
+ 0,
+ 0,
+ Protocol,
+ NULL,
+ 1,
+ NULL);
+ Protocol[0] = 0xFF;
+ //
+ // dispatch urb
+ //
+ Status = Hid_DispatchUrb(DeviceObject, Urb);
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+
+ //
+ // boot protocol active 0x00 disabled 0x1
+ //
+ if (Protocol[0] != 0x1)
+ {
+ if (Protocol[0] == 0x00)
+ {
+ DPRINT1("[HIDUSB] Need to disable boot protocol!\n");
+ }
+ else
+ {
+ DPRINT1("[HIDUSB] Unexpected protocol value %x\n", Protocol[0] & 0xFF);
+ }
+ }
+}
NTSTATUS
Hid_PnpStart(
//
// no interface class
//
- DPRINT1("[HIDUSB] HID Class found\n");
+ DPRINT1("[HIDUSB] HID Interface descriptor not found\n");
return STATUS_UNSUCCESSFUL;
}
// select configuration
//
Status = Hid_SelectConfiguration(DeviceObject);
- ASSERT(Status == STATUS_SUCCESS);
//
// done
//
DPRINT1("[HIDUSB] SelectConfiguration %x\n", Status);
- return Status;
- }
- //
- // FIXME parse hid descriptor
- //
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_SUCCESS;
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // now set the device idle
+ //
+ Hid_SetIdle(DeviceObject);
+
+ //
+ // get protocol
+ //
+ Hid_GetProtocol(DeviceObject);
+ return Status;
+ }
+ }
+ else
+ {
+ //
+ // FIXME parse hid descriptor
+ // select configuration
+ // set idle
+ // and get protocol
+ //
+ UNIMPLEMENTED
+ ASSERT(FALSE);
+ }
+ return Status;
}
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT1("[HIDUSB] Pnp %x\n", IoStack->MinorFunction);
+ DPRINT("[HIDUSB] Pnp %x\n", IoStack->MinorFunction);
//
// handle requests based on request type
//
// free resources
//
- if (HidDeviceExtension->HidDescriptor)
+ if (HidDeviceExtension->ConfigurationDescriptor)
{
- ExFreePool(HidDeviceExtension->HidDescriptor);
- HidDeviceExtension->HidDescriptor = NULL;
+ ExFreePool(HidDeviceExtension->ConfigurationDescriptor);
+ HidDeviceExtension->ConfigurationDescriptor = NULL;
}
//
- // done
+ // delete and detach device
//
+ IoDetachDevice(DeviceExtension->NextDeviceObject);
+ IoDeleteDevice(DeviceObject);
+
return Status;
}
case IRP_MN_QUERY_PNP_DEVICE_STATE:
//
return Status;
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ //
+ // we're fine with it
+ //
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ //
+ // pass request to next driver
+ //
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+
+ //
+ // done
+ //
+ return Status;
+ }
case IRP_MN_STOP_DEVICE:
{
//
Status = Irp->IoStatus.Status;
}
- if (NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status) && IoStack->Parameters.DeviceCapabilities.Capabilities != NULL)
{
- //
- // driver supports D1 & D2
- //
- IoStack->Parameters.DeviceCapabilities.Capabilities->DeviceD1 = TRUE;
- IoStack->Parameters.DeviceCapabilities.Capabilities->DeviceD2 = TRUE;
-
//
// don't need to safely remove
//
// complete request
//
Irp->IoStatus.Status = Status;
- DPRINT1("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status);
+ DPRINT("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
return STATUS_SUCCESS;
}
+VOID
+NTAPI
+Hid_Unload(
+ IN PDRIVER_OBJECT DriverObject)
+{
+ UNIMPLEMENTED
+}
+
+
NTSTATUS
NTAPI
DriverEntry(
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidSystemControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = HidPnp;
DriverObject->DriverExtension->AddDevice = HidAddDevice;
+ DriverObject->DriverUnload = Hid_Unload;
//
// prepare registration info
//
// informal debug
//
- DPRINT1("********* HIDUSB *********\n");
- DPRINT1("HIDUSB Registration Status %x\n", Status);
+ DPRINT("********* HIDUSB *********\n");
+ DPRINT("HIDUSB Registration Status %x\n", Status);
return Status;
}