Windows10 x64基于BOT规范虚拟U盘调试批量端点返回CSW的问题
虚拟了这么多的USB设备,突然想着U盘还没有弄,那就搞一个吧。就当是为了自己学习,没准那天突然有这样的需求。所以说干就干。
我们知道,虚拟U盘其实是两套规范的,一种是传统的BOT协议,另一种是UASP的。这里为了兼容性,也是为了学习方便,我们使用BOT规范来虚拟一个标准的U盘。
通过UsbTreeViewer或者其它USB抓包工具,可以看到,U盘的配置描述符相对其它设备如MIC,摄像头或者HID设备,不要太简单。在它的配置描述符中只需要一个接口描述符,两个批量传输的端点描述符(一个用于输入,一个用于输出)即可。所以说从USB规范上来说,这个简单是小儿科。我们完全可以基于原来的虚拟USB设备来简单即可。
U盘遵循USB存储规范,我们这里选用的是BOT规范。使用的协议命令集是UFI命令集。这里我们一般只需要以下几个命令集就可以了。
#define INQUIRY 0x12
#define READ_FORMAT_CAPACITIES 0x23
#define READ_CAPACITY 0x25
#define READ_DATA 0x28
#define WRITE_DATA 0x2a
本来想着很简单的事情,没想到还是翻车了。
CSW的长度问题
UFI的命令是通过BW结构体下发的,并且使用的是OUT批量端点。我们通过IN输入端点返回相应的信息即可。这里由于是已经长度,所以不需要设置。最后再使用IN输入端点返回CSW返回,不过这里微软给的长度是512字节,自己需要将长度设回13字节。
在Windows驱动中,URB读的实际数据长度是通过Urb->UrbBulkOrInterruptTransfer.TransferBufferLength来设置的。不可能是因为自己编程上的不好的习惯,以前遇到的都是不需要重新设置长度,导致这次因为长度的问题,没想到usbstor长度判断失败。
输入端点的数据方向问题
你竟然相信,一个输入端点在BUSHOUND抓取时显示的是OUT,而不是IN.但这确实是发生了。原因和上面的一样,在返回CSW时,需要手动置USBD_TRANSFER_DIRECTION_IN标志。
Urb->UrbBulkOrInterruptTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
在中间返回厂商信息的时候,这个标识是有的,为什么在CSW时就没有了。微软的双标,让人看不懂。这和长度的问题一样的。