Windows下USB驱动获取USB设备各种描述符代码函数封装
2021-08-30
669
0
USB设备的一个种要的概念就是各种描述符,如设备描述符,配置描述符,字符串描述符等等。
在设备驱动驱动开发中,通过读取这些描述符可以知道该USB设备的相关信息。
这里我们对在Windows驱动开发过程的获取USB设备的描述符进行代码封装成函数GetDescriptor。
NTSTATUS GetDescriptor(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR DescriptorType,
IN ULONG DescriptorLength,
IN UCHAR DescriptorIndex,
IN LANGID LanguageId,
OUT PVOID* OutDescriptor)
{
PURB Urb;
NTSTATUS Status;
PVOID Descriptor;
ASSERT(DeviceObject != NULL);
ASSERT(OutDescriptor != NULL);
ASSERT(DescriptorLength != 0);
Descriptor = ExAllocatePool(NonPagedPool, DescriptorLength);
if (!Descriptor)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Descriptor, DescriptorLength);
Urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(URB));
if (Urb == NULL)
{
ExFreePool(Descriptor);
return STATUS_INSUFFICIENT_RESOURCES;
}
UsbBuildGetDescriptorRequest(Urb,
sizeof(Urb->UrbControlDescriptorRequest),
DescriptorType,
DescriptorIndex,
LanguageId,
Descriptor,
NULL,
DescriptorLength,
NULL);
Status = SyncUrbRequest(DeviceObject, Urb);
ExFreePool(Urb);
if (NT_SUCCESS(Status))
{
#pragma warning(disable:6011)
*OutDescriptor = (PVOID)Descriptor;
#pragma warning(default:6011)
}
return Status;
}
可以看到,该函数使用了我们前面封装的通用URB转IRP请求函数SyncUrbRequest,其相关代码见:http://www.usbzh.com/fun/detail-31.html
GetDescriptor函数的参数不多,第一个为下层设备对象,其次为设备的描述符类型,长度,后面的DescriptorIndex和LanguageId仅对字符串有效,最后输出的是该描述符的指针。
测试代码
这里我们通过GetAllDescriptor获取USB设备的设备描述符和配置描述符。
设备描述符是通过2次获取的。
NTSTATUS GetAllDescriptor(
IN PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS Status;
PFDO_DEVICE_EXTENSION DeviceExtension;
USHORT DescriptorLength;
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// 1.0 first get device descriptor
//
Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to get device descriptor
//
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
//
// 2.0 now get basic configuration descriptor
//
Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
ExFreePool(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
//
// release basic descriptor
//
ExFreePool(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL;
/* 2.1 allocate full descriptor */
Status = GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
ExFreePool(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
return Status;
}
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936