DeviceIoControl()可以利用Io Control (aka IOCTL) code操作USB设备驱动,这些IOCTL码由谁定义由谁解释呢?(CyAPI.lib? CyUSB.dll? CyUSB.sys?)
答案:cyioctl.h
例如:
#define IOCTL_ADAPT_GET_DRIVER_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS)
..
#define IOCTL_ADAPT_GET_ALT_INTERFACE_SETTING CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+2, METHOD_BUFFERED, FILE_ANY_ACCESS)
至于“FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS”这些东西的定义,应该是在Windows相关头文件or库里面吧。
这是IOCTL Interface的IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER的使用范例:
Description
This command sends a control request to the default Control endpoint, endpoint zero.
DeviceIoControl( ) is passed a pointer to a two-part structure as both the lpInBuffer and lpOutBuffer parameters. This two-part structure contains a SINGLE_TRANSFER structure followed by a data buffer.
The SINGLE_TRANSFER structure contains all the parameters for the control request.
The buffer contains the transfer data.
pXmitBuf
SINGLE_TRANFER
bmRequest
Request
.
.
buff
union { struct { UCHAR Recipient:5; //接收方: Device,Interface,Endpoint,Other UCHAR Type:2; //Type: Standard,Class,Vendor UCHAR Direction:1; //数据传输方向: Host2Device,Device2Host } bmRequest; UCHAR bmReq; //请求类型 }; bmRequest.Recipient = 0; // Device bmRequest.Type = 2; // Vendor bmRequest.Direction = 1; // IN command (from Device to Host) int iXmitBufSize = sizeof(SINGLE_TRANSFER) + bufLen; // The size of the two-part structure. XmitBuf is the two-part structure. UCHAR *pXmitBuf = new UCHAR[iXmitBufSize]; // Allocate the memory 创建iXmitBufSize大小的UCHAR变量 ZeroMemory(pXmitBuf, iXmitBufSize); // 指定存储空(UCHAR)间清零 PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER)pXmitBuf; // The SINGLE_TRANSFER comes first 下面首先定义SINGLE_TRANSFER Structure的值 pTransfer->SetupPacket.bmRequest = bmReq; //Birmap Characteristics of request pTransfer->SetupPacket.bRequest = ReqCode; //Specific request pTransfer->SetupPacket.wValue = Value; pTransfer->SetupPacket.wIndex = Index; pTransfer->SetupPacket.wLength = bufLen; //Number of bytes to transfer if there is a Data stage pTransfer->SetupPacket.ulTimeOut = TimeOut / 1000; pTransfer->Reserved = 0; pTransfer->ucEndpointAddress = 0x00; // Control pipe pTransfer->IsoPacketLength = 0; pTransfer->BufferOffset = sizeof (SINGLE_TRANSFER); pTransfer->BufferLength = bufLen; DWORD dwReturnBytes; DeviceIoControl (hDevice, IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, pXmitBuf, iXmitBufSize, pXmitBuf, iXmitBufSize, &dwReturnBytes, NULL); // Copy data into buf UCHAR *ptr = pXmitBuf + sizeof (SINGLE_TRANSFER); memcpy(buf, ptr, dwReturnBytes);