mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:05:43 +00:00
[USB-BRINGUP]
- Implement retrieving device / configuration descriptor - Partly implement hid descriptor parsing - Select configuration when initialization is complete - Implement starting up device svn path=/branches/usb-bringup/; revision=54765
This commit is contained in:
parent
c626190319
commit
bf1f779fff
2 changed files with 460 additions and 17 deletions
|
@ -86,13 +86,13 @@ HidInternalDeviceControl(
|
||||||
//
|
//
|
||||||
// store result
|
// store result
|
||||||
//
|
//
|
||||||
ASSERT(HidDeviceExtension->HidDescriptor);
|
ASSERT(HidDeviceExtension->DeviceDescriptor);
|
||||||
Irp->IoStatus.Information = sizeof(HID_DESCRIPTOR);
|
Irp->IoStatus.Information = sizeof(HID_DESCRIPTOR);
|
||||||
Attributes = (PHID_DEVICE_ATTRIBUTES)Irp->UserBuffer;
|
Attributes = (PHID_DEVICE_ATTRIBUTES)Irp->UserBuffer;
|
||||||
Attributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
|
Attributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
|
||||||
Attributes->VendorID = HidDeviceExtension->VendorID;
|
Attributes->VendorID = HidDeviceExtension->DeviceDescriptor->idVendor;
|
||||||
Attributes->ProductID = HidDeviceExtension->ProductID;
|
Attributes->ProductID = HidDeviceExtension->DeviceDescriptor->idProduct;
|
||||||
Attributes->VersionNumber = HidDeviceExtension->VersionNumber;
|
Attributes->VersionNumber = HidDeviceExtension->DeviceDescriptor->bcdDevice;
|
||||||
|
|
||||||
//
|
//
|
||||||
// complete request
|
// complete request
|
||||||
|
@ -186,14 +186,6 @@ HidSystemControl(
|
||||||
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
Hid_PnpStart(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
Hid_PnpCompletion(
|
Hid_PnpCompletion(
|
||||||
|
@ -212,6 +204,437 @@ Hid_PnpCompletion(
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Hid_DispatchUrb(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PURB Urb)
|
||||||
|
{
|
||||||
|
PIRP Irp;
|
||||||
|
KEVENT Event;
|
||||||
|
PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
|
||||||
|
PHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// init event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
HidDeviceExtension = (PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// build irp
|
||||||
|
//
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, DeviceExtension->NextDeviceObject, NULL, 0, NULL, 0, TRUE, &Event, &IoStatus);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// store urb
|
||||||
|
//
|
||||||
|
IoStack->Parameters.Others.Argument1 = (PVOID)Urb;
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// call driver
|
||||||
|
//
|
||||||
|
Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// wait for the request to finish
|
||||||
|
//
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Hid_GetDescriptor(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN USHORT UrbLength,
|
||||||
|
IN OUT PVOID *UrbBuffer,
|
||||||
|
IN OUT PULONG UrbBufferLength,
|
||||||
|
IN UCHAR DescriptorType,
|
||||||
|
IN UCHAR Index,
|
||||||
|
IN USHORT LanguageIndex)
|
||||||
|
{
|
||||||
|
PURB Urb;
|
||||||
|
NTSTATUS Status;
|
||||||
|
UCHAR Allocated = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate urb
|
||||||
|
//
|
||||||
|
Urb = (PURB)ExAllocatePool(NonPagedPool, UrbLength);
|
||||||
|
if (!Urb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// is there an urb buffer
|
||||||
|
//
|
||||||
|
if (!*UrbBuffer)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// allocate buffer
|
||||||
|
//
|
||||||
|
*UrbBuffer = ExAllocatePool(NonPagedPool, *UrbBufferLength);
|
||||||
|
if (!*UrbBuffer)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// zero buffer
|
||||||
|
//
|
||||||
|
RtlZeroMemory(*UrbBuffer, *UrbBufferLength);
|
||||||
|
Allocated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// zero urb
|
||||||
|
//
|
||||||
|
RtlZeroMemory(Urb, UrbLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// build descriptor request
|
||||||
|
//
|
||||||
|
UsbBuildGetDescriptorRequest(Urb, UrbLength, DescriptorType, Index, LanguageIndex, *UrbBuffer, NULL, *UrbBufferLength, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// dispatch urb
|
||||||
|
//
|
||||||
|
Status = Hid_DispatchUrb(DeviceObject, Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// did the request fail
|
||||||
|
//
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Allocated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// free allocated buffer
|
||||||
|
//
|
||||||
|
ExFreePool(*UrbBuffer);
|
||||||
|
*UrbBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
*UrbBufferLength = 0;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// did urb request fail
|
||||||
|
//
|
||||||
|
if (!NT_SUCCESS(Urb->UrbHeader.Status))
|
||||||
|
{
|
||||||
|
if (Allocated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// free allocated buffer
|
||||||
|
//
|
||||||
|
ExFreePool(*UrbBuffer);
|
||||||
|
*UrbBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
*UrbBufferLength = 0;
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store result length
|
||||||
|
//
|
||||||
|
*UrbBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// completed successfully
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Hid_SelectConfiguration(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||||
|
NTSTATUS Status;
|
||||||
|
USBD_INTERFACE_LIST_ENTRY InterfaceList[2];
|
||||||
|
PURB Urb;
|
||||||
|
PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
|
||||||
|
PHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
HidDeviceExtension = (PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// now parse the descriptors
|
||||||
|
//
|
||||||
|
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
|
||||||
|
HidDeviceExtension->ConfigurationDescriptor,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
USB_DEVICE_CLASS_HUMAN_INTERFACE,
|
||||||
|
-1,
|
||||||
|
-1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(InterfaceDescriptor);
|
||||||
|
ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE);
|
||||||
|
ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
|
||||||
|
ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup interface list
|
||||||
|
//
|
||||||
|
RtlZeroMemory(InterfaceList, sizeof(InterfaceList));
|
||||||
|
InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// build urb
|
||||||
|
//
|
||||||
|
Urb = USBD_CreateConfigurationRequestEx(HidDeviceExtension->ConfigurationDescriptor, InterfaceList);
|
||||||
|
if (!Urb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// dispatch request
|
||||||
|
//
|
||||||
|
Status = Hid_DispatchUrb(DeviceObject, Urb);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store configuration handle
|
||||||
|
//
|
||||||
|
HidDeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy interface info
|
||||||
|
//
|
||||||
|
HidDeviceExtension->InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)ExAllocatePool(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length);
|
||||||
|
if (HidDeviceExtension->InterfaceInfo)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// copy interface info
|
||||||
|
//
|
||||||
|
RtlCopyMemory(HidDeviceExtension->InterfaceInfo, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb request
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
Hid_PnpStart(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
|
||||||
|
PHID_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG DescriptorLength;
|
||||||
|
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||||
|
PHID_DESCRIPTOR HidDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
HidDeviceExtension = (PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device descriptor
|
||||||
|
//
|
||||||
|
DescriptorLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||||
|
Status = Hid_GetDescriptor(DeviceObject, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), (PVOID*)&HidDeviceExtension->DeviceDescriptor, &DescriptorLength, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to obtain device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now get the configuration descriptor
|
||||||
|
//
|
||||||
|
DescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
||||||
|
Status = Hid_GetDescriptor(DeviceObject, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), (PVOID*)&HidDeviceExtension->ConfigurationDescriptor, &DescriptorLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to obtain device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(DescriptorLength);
|
||||||
|
ASSERT(HidDeviceExtension->ConfigurationDescriptor);
|
||||||
|
ASSERT(HidDeviceExtension->ConfigurationDescriptor->bLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// store full length
|
||||||
|
//
|
||||||
|
DescriptorLength = HidDeviceExtension->ConfigurationDescriptor->wTotalLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// delete partial configuration descriptor
|
||||||
|
//
|
||||||
|
ExFreePool(HidDeviceExtension->ConfigurationDescriptor);
|
||||||
|
HidDeviceExtension->ConfigurationDescriptor = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get full configuration descriptor
|
||||||
|
//
|
||||||
|
Status = Hid_GetDescriptor(DeviceObject, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), (PVOID*)&HidDeviceExtension->ConfigurationDescriptor, &DescriptorLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to obtain device descriptor
|
||||||
|
//
|
||||||
|
DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now parse the descriptors
|
||||||
|
//
|
||||||
|
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
|
||||||
|
HidDeviceExtension->ConfigurationDescriptor,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
USB_DEVICE_CLASS_HUMAN_INTERFACE,
|
||||||
|
-1,
|
||||||
|
-1);
|
||||||
|
if (!InterfaceDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no interface class
|
||||||
|
//
|
||||||
|
DPRINT1("NO HID Class found\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE);
|
||||||
|
ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
|
||||||
|
ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next descriptor
|
||||||
|
//
|
||||||
|
HidDescriptor = (PHID_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
|
||||||
|
ASSERT(HidDescriptor->bLength >= 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if this is the hid descriptor
|
||||||
|
//
|
||||||
|
if (HidDescriptor->bLength == sizeof(HID_DESCRIPTOR) && HidDescriptor->bDescriptorType == HID_HID_DESCRIPTOR_TYPE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found
|
||||||
|
//
|
||||||
|
HidDeviceExtension->HidDescriptor = HidDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// select configuration
|
||||||
|
//
|
||||||
|
Status = Hid_SelectConfiguration(DeviceObject);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME parse hid descriptor
|
||||||
|
//
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
HidPnp(
|
HidPnp(
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <hidport.h>
|
#include <hidport.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <hubbusif.h>
|
||||||
|
#include <usbbusif.h>
|
||||||
|
#include <usbioctl.h>
|
||||||
|
#include <usb.h>
|
||||||
|
#include <usbdlib.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -18,14 +23,29 @@ typedef struct
|
||||||
//
|
//
|
||||||
LIST_ENTRY PendingRequests;
|
LIST_ENTRY PendingRequests;
|
||||||
|
|
||||||
|
//
|
||||||
|
// device descriptor
|
||||||
|
//
|
||||||
|
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// configuration descriptor
|
||||||
|
//
|
||||||
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// interface information
|
||||||
|
//
|
||||||
|
PUSBD_INTERFACE_INFORMATION InterfaceInfo;
|
||||||
|
|
||||||
|
//
|
||||||
|
// configuration handle
|
||||||
|
//
|
||||||
|
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
||||||
|
|
||||||
//
|
//
|
||||||
// hid descriptor
|
// hid descriptor
|
||||||
//
|
//
|
||||||
PHID_DESCRIPTOR HidDescriptor;
|
PHID_DESCRIPTOR HidDescriptor;
|
||||||
|
|
||||||
USHORT VendorID;
|
|
||||||
USHORT ProductID;
|
|
||||||
USHORT VersionNumber;
|
|
||||||
|
|
||||||
}HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
|
}HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue