U盘自定义驱动开发过程遇到问题记
BUS HOUND 使用指南
(5)在"PHASE TO CAPTURE"里面的几个和USB相关的选项如下: CDB:命令描述符块; CTL:USB控制传输; DI/D数据输入/输出; LEN:数据长度; INSOC:同步传输; RSET:总线复位; URB:USB请求块; USTS:USB状态 查看USB数据传输就把它们都打勾就行了; (6)在"Coloumn to display"里面,把里面的全部打勾,(为什么我就不说了).注意,这样要把窗体最大化才可以看见全部数据. (7)在"CAPTURE"选项卡里面可以看捕捉的数据了,在文本框输入文字,再点旁边的箭头,可以查询.按STOP,再按START可以清屏. (8)举个例子,接上设备,在文本框输入GET DESCRIPTOR(大小写无所谓),点箭头,可以找到你的DESCRIPTOR,但是值得注意的是这个DESCRIPTOR主要是CONFIG,如果 是设备描述符会有专门的说明GET DEVICE DESCRIPTOR;这个软件好像不会捕捉STRING DESCRIPTOR. 设备返回的信息在DI里面
不明白: “URB:USB请求块”是指什么东西?是由主机发给Device的么?所有的USB通信包都是通过URB的形式发送出去的,而在bus hound里出现的URB的含义是什么?
有如下数据:
在USB传输过程中,所有的包都是URB,而此处的URB的含义是什么?
8.0 CTL 00 09 01 00 00 00 00 00 SET CONFIG 8.1.0 18.0 URB 50 00 00 00 00 00 00 00 58 1e f1 86 00 00 00 00 58 21 89 85 58 19 86 85 38 00 00 00 08 06 50 00 SELECT CONFIG 8.2.0 60 43 8c 85 02 00 00 00 00 02 81 ff 02 00 00 00 7c 43 8c 85 00 10 00 00 00 00 00 00 00 02 02 ff 8.2.32 02 00 00 00 9c 43 8c 85 00 10 00 00 00 00 00 00 8.2.64 18.0 CTL 01 0b 00 00 00 00 00 00 SET INTERFACE 9.1.0 18.0 URB 4c 00 01 00 00 00 00 00 58 1e f1 86 00 00 00 00 58 19 86 85 38 00 00 00 08 06 50 00 70 ce 8d 85 SELECT INTERFACE 9.2.0 02 00 00 00 00 02 81 ff 02 00 00 00 8c ce 8d 85 00 00 01 00 00 00 00 00 00 02 02 ff 02 00 00 00 9.2.32 ac ce 8d 85 00 00 01 00 00 00 00 00 9.2.64 18.0 CTL a1 fe 00 00 00 00 01 00 GET MAX LUN 10.1.0 18.0 DI 00 . 10.2.0 18.0 URB 50 00 08 00 00 00 00 00 58 1e f1 86 22 00 00 00 70 1e f1 86 0b 00 00 00 01 00 00 00 50 e2 8b 85 CONTROL TRANSFER 10.3.0 e0 f1 a0 85 00 00 00 00 ff ff ff ff 0d f0 ad de 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10.3.32 00 00 00 00 00 00 00 00 a1 fe 00 00 00 00 01 00 10.3.64 18.2 DO 55 53 42 43 08 b0 57 86 24 00 00 00 80 00 06 12 00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 USBC..W.$....... 11.1.0 18.2 URB 48 00 09 00 00 00 00 00 58 1e f1 86 22 00 00 00 ac ce 8d 85 00 00 00 00 1f 00 00 00 98 a7 9d 85 BULK/INT XFER 11.2.0 88 89 95 85 00 00 00 00 ff ff ff ff 0d f0 ad de 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11.2.32 00 00 00 00 00 00 00 00 11.2.64 18.1 DI 00 80 00 01 1f 00 00 00 47 65 6e 65 72 69 63 20 55 53 42 20 20 53 44 20 52 65 61 64 65 72 20 20 ........Generic 12.1.0 31 2e 30 30 1.00 12.1.32 18.1 URB 48 00 09 00 00 00 00 00 58 1e f1 86 20 00 00 00 8c ce 8d 85 03 00 00 00 24 00 00 00 00 00 00 00 BULK/INT XFER 12.2.0 58 11 b9 86 00 00 00 00 ff ff ff ff 0d f0 ad de 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12.2.32 00 00 00 00 00 00 00 00 12.2.64 18.1 DI 55 53 42 53 08 b0 57 86 00 00 00 00 00
疑问2:
在DriverStudio 的帮助文件中:driver Works help中函数BuildClassRequest有参数:RequestTypeReservedBits不解,
RequestTypeReservedBits
Bit mask to be inserted into the RequestType field of the data payload during setup transaction. Bits 0-3 are specific to the request type and are ignored by this call. The remaining bits (4 - 31) are OR'ed in. This parameter is normally zero. Do not specify a value other than zero unless you understand the consequences.
下面的方法中,对这个函数就不屑与说的详细些了,害的我没看明白。KUsbPipe::BuildClassRequest
FORM 1:
PURB BuildClassRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL, PURB pUrb=NULL ); RequestTypeReservedBits
Specifies a value, from 4 to 31 inclusive, that becomes part of the request type code in the USB-defined setup packet. This value is defined by USB for a class request or the vendor for a vendor request.
3 疑问
不知道如何通过DriverStudio 的驱动去
设置SET INTERFACE,GET MAX LUN
后来只好转到DDK中去做。把代码贴出来了,借鉴的ezusb的
NTSTATUS SetInterface( IN PDEVICE_OBJECT fdo, IN UCHAR InterfaceNumber, IN UCHAR AlternateSetting ) { PUSBD_INTERFACE_INFORMATION interfaceInformation = NULL; PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL; PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL; PDEVICE_EXTENSION pdx = fdo->DeviceExtension; PURB urb = NULL; USHORT urbSize; ULONG numberOfPipes; ULONG i,j; NTSTATUS ntStatus; DbgPrint("masc 1111 SetInterface masc\n");
//
// Get the configuration Descriptor
//
configurationDescriptor = GetConfigDescriptor(fdo); if (!configurationDescriptor) { Ezusb_KdPrint (("Get Configuration Descriptor Failed\n")); ntStatus = STATUS_UNSUCCESSFUL; goto CleanupSetInterface; }
//
// Get the interface Descriptor for the interface we want
//
interfaceDescriptor = USBD_ParseConfigurationDescriptorEx( configurationDescriptor, configurationDescriptor, InterfaceNumber, AlternateSetting, -1, -1, -1);
if (!interfaceDescriptor) { Ezusb_KdPrint (("USBD_ParseConfigurationDescriptorEx failed\n")); ntStatus = STATUS_UNSUCCESSFUL; goto CleanupSetInterface; }
numberOfPipes = interfaceDescriptor->bNumEndpoints; Ezusb_KdPrint (("numberOfPipes = %d\n", numberOfPipes));
urbSize =(USHORT) GET_SELECT_INTERFACE_REQUEST_SIZE(numberOfPipes); Ezusb_KdPrint (("urbSize = %d\n", urbSize)); urb = ExAllocatePool(NonPagedPool,urbSize);
if (!urb) { DbgPrint("masc no urb memory\n");
ntStatus = STATUS_NO_MEMORY; goto CleanupSetInterface; } RtlZeroMemory(urb,urbSize);
UsbBuildSelectInterfaceRequest(urb, urbSize, pdx->ConfigurationHandle, InterfaceNumber, AlternateSetting);
interfaceInformation = &(urb->UrbSelectInterface.Interface); interfaceInformation->Length = (USHORT)GET_USBD_INTERFACE_SIZE(numberOfPipes);
for (i = 0 ;i < numberOfPipes ;i++ ) { interfaceInformation->Pipes[i].MaximumTransferSize = (64*1024) -1; }
ntStatus = Ezusb_CallUSBD(fdo, urb);
//
// If that succeeded, then update the Interface structure
// in the device extension.
//
if (NT_SUCCESS(ntStatus)) { for (j=0; j<interfaceInformation->NumberOfPipes; j++) { PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &interfaceInformation->Pipes[j];
Ezusb_KdPrint (("---------\n")); Ezusb_KdPrint (("PipeType 0x%x\n", pipeInformation->PipeType)); Ezusb_KdPrint (("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress)); Ezusb_KdPrint (("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize)); Ezusb_KdPrint (("Interval 0x%x\n", pipeInformation->Interval)); Ezusb_KdPrint (("Handle 0x%x\n", pipeInformation->PipeHandle)); Ezusb_KdPrint (("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize)); }
if (pdx->Interface) { ExFreePool(pdx->Interface); }
pdx->Interface = NULL; pdx->Interface = ExAllocatePool(NonPagedPool,interfaceInformation->Length); if (!pdx->Interface) { ntStatus = STATUS_NO_MEMORY; goto CleanupSetInterface; } RtlCopyMemory(pdx->Interface, interfaceInformation, interfaceInformation->Length); }
CleanupSetInterface:
// Clean up and exit this routine
if (urb != NULL) { ExFreePool(urb); }
if (configurationDescriptor != NULL) { ExFreePool(configurationDescriptor); }
return(ntStatus); }
|
4 疑问
CDB:命令描述符块; 是SCSI命令,并没有出现在USB总线上?
因此不要考虑如何发这个命令。
bus hound 注意字段:Device 17 /16.1 16.2 16.0
.前面的数据是Device视图的设备编号
.后面的数字是EP号,
5 clear feature
对于USB,Stand feature Select有:
Device_remote_wakeup
ENDPOINT_HALT
TEST_MODE
比如有的U盘在枚举使用过程中,使用clear feature清楚因获取lun导致的USB disk stall
Devices that do not support multiple LUNs may STALL this command.
6用自己做的驱动去读写U盘数据
一定要注意的:
setInterface
先用test Unit测试U盘响应,直到U盘test Unit返回的CSW状态末字节为0
7: U盘一般都是bulk only,但输入,输出端点号有的是0x81,2;有的是0x01,0x82
如果端点号不正确,那么对U盘的读写将导致XP蓝屏,重启等;
|