📄 usb2com.utils.cpp
字号:
//********************************************************************
// created: 12:7:2008 1:51
// file: usb2com.utils.cpp
// author: tiamo
// purpose: utils
//********************************************************************
#include "stdafx.h"
//
// config usb device
//
NTSTATUS Usb2ComConfigUsbDevice(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
PURB Urb = 0;
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc = 0;
ULONG DescLength = 0x109;
NTSTATUS Status = STATUS_SUCCESS;
__try
{
//
// allocate urb buffer
//
Urb = static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),'URB '));
if(!Urb)
try_leave(Status = STATUS_INSUFFICIENT_RESOURCES);
//
// allocate config desc buffer
//
ConfigDesc = static_cast<PUSB_CONFIGURATION_DESCRIPTOR>(ExAllocatePoolWithTag(NonPagedPool,DescLength,'cDes'));
if(!ConfigDesc)
try_leave(Status = STATUS_INSUFFICIENT_RESOURCES);
UsbBuildGetDescriptorRequest(Urb,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),USB_CONFIGURATION_DESCRIPTOR_TYPE,0,0,ConfigDesc,0,DescLength,0);
//
// send it
//
Status = Usb2ComSendUrbSync(DevExt,Urb);
if(!NT_SUCCESS(Status))
{
//
// get config descriptor failed,then reset port and try again
//
Usb2ComResetUsbPort(DevExt);
//
// clear endpoint feature
//
Usb2ComClearEndpointFeature(DevExt,0,0);
//
// resent the usb
//
UsbBuildGetDescriptorRequest(Urb,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),USB_CONFIGURATION_DESCRIPTOR_TYPE,0,0,ConfigDesc,0,DescLength,0);
Status = Usb2ComSendUrbSync(DevExt,Urb);
if(!NT_SUCCESS(Status))
try_leave(NOTHING);
}
//
// select configuration
//
Status = Usb2ComSelectConfiguration(DevExt,ConfigDesc);
}
__finally
{
if(Urb)
ExFreePool(Urb);
if(ConfigDesc)
ExFreePool(ConfigDesc);
}
return Status;
}
//
// disable usb device
//
NTSTATUS Usb2ComDisableUsbDevice(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
PURB Urb = static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_SELECT_CONFIGURATION),'URB '));
if(!Urb)
return STATUS_INSUFFICIENT_RESOURCES;
UsbBuildSelectConfigurationRequest(Urb,sizeof(_URB_SELECT_CONFIGURATION),0);
NTSTATUS Status = Usb2ComSendUrbSync(DevExt,Urb);
ExFreePool(Urb);
return Status;
}
//
// select configuration
//
NTSTATUS Usb2ComSelectConfiguration(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc)
{
//
// find the first interface descriptor from the configuration descriptor
//
PUSB_INTERFACE_DESCRIPTOR InterfaceDesc = USBD_ParseConfigurationDescriptorEx(ConfigDesc,ConfigDesc,-1,-1,-1,-1,-1);
if(!InterfaceDesc)
return STATUS_INTERNAL_ERROR;
USBD_INTERFACE_LIST_ENTRY InterfaceList[2];
InterfaceList[0].Interface = 0;
InterfaceList[0].InterfaceDescriptor = InterfaceDesc;
InterfaceList[1].Interface = 0;
InterfaceList[1].InterfaceDescriptor = 0;
//
// create a urb to select a configuration
//
PURB Urb = USBD_CreateConfigurationRequestEx(ConfigDesc,InterfaceList);
if(!Urb)
return STATUS_INSUFFICIENT_RESOURCES;
PUSBD_INTERFACE_INFORMATION UsbInterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
ASSERT(UsbInterfaceInfo->NumberOfPipes == 3);
for(ULONG i = 0; i < UsbInterfaceInfo->NumberOfPipes; i ++)
UsbInterfaceInfo->Pipes[i].MaximumTransferSize = 0x40;
NTSTATUS Status = Usb2ComSendUrbSync(DevExt,Urb);
if(NT_SUCCESS(Status))
{
//
// make a copy and save it into device extension
//
DevExt->UsbInterfaceInfo = static_cast<PUSBD_INTERFACE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool,UsbInterfaceInfo->Length,'UsbI'));
if(DevExt->UsbInterfaceInfo)
RtlCopyMemory(DevExt->UsbInterfaceInfo,UsbInterfaceInfo,UsbInterfaceInfo->Length);
else
Status = STATUS_INSUFFICIENT_RESOURCES;
}
ExFreePool(Urb);
return Status;
}
//
// send usb sync
//
NTSTATUS Usb2ComSendUrbSync(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in PURB Urb)
{
KEVENT Event;
KeInitializeEvent(&Event,NotificationEvent,FALSE);
IO_STATUS_BLOCK IoStatusBlock;
PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,DevExt->LowerDeviceObject,
0,0,0,0,TRUE,&Event,&IoStatusBlock);
PIO_STACK_LOCATION NextIrpSp = IoGetNextIrpStackLocation(Irp);
NextIrpSp->Parameters.Others.Argument1 = Urb;
NTSTATUS Status = IoCallDriver(DevExt->LowerDeviceObject,Irp);
if(Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,0);
Status = IoStatusBlock.Status;
}
return Status;
}
//
// reset port
//
NTSTATUS Usb2ComResetUsbPort(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
KEVENT Event;
KeInitializeEvent(&Event,NotificationEvent,FALSE);
IO_STATUS_BLOCK IoStatusBlock;
PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT,DevExt->LowerDeviceObject,
0,0,0,0,TRUE,&Event,&IoStatusBlock);
NTSTATUS Status = IoCallDriver(DevExt->LowerDeviceObject,Irp);
if(Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,0);
Status = IoStatusBlock.Status;
}
return Status;
}
//
// clear feature
//
NTSTATUS Usb2ComClearEndpointFeature(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in USHORT Selector,__in USHORT Index)
{
PURB Urb = static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_FEATURE_REQUEST),'URB '));
if(!Urb)
return STATUS_INSUFFICIENT_RESOURCES;
UsbBuildFeatureRequest(Urb,URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,Selector,Index,0);
NTSTATUS Status = Usb2ComSendUrbSync(DevExt,Urb);
ExFreePool(Urb);
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -