📄 search_usb.cpp
字号:
pArrayUSB->Add("");
// First need to get the configuration descriptor
memset(&Packet, 0, sizeof(Packet));
Packet.ConnectionIndex = PortIndex;
Packet.SetupPacket.bmRequest = 0x80;
Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
Packet.SetupPacket.wValue[1] = USB_CONFIGURATION_DESCRIPTOR_TYPE;
Packet.SetupPacket.wLength[1] = 1; // Using a 2K buffer
Success = DeviceIoControl(HubHandle,
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
&Packet,
sizeof(Packet),
&Packet,
sizeof(Packet),
&BytesReturned,
NULL);
if (!Success)
{
sBuf.Format(" *** ERROR *** Configuration Descriptor not returned. ErrorCode = %d\n", GetLastError());
pArrayUSB->Add(sBuf);
}
PUCHAR BufferPtr = &Packet.Data[0];
UCHAR Length = *BufferPtr;
while (Length != 0) {
UCHAR Type = *++BufferPtr;
switch (Type) {
case 2:
//配置描述符
sBuf.Format(" 配置描述:");
pArrayUSB->Add(sBuf);
sBuf.Format(" bLength %2.2x", Length);
pArrayUSB->Add(sBuf);
//1 常量= 2 配置描述表类型
sBuf.Format(" bDescriptorType %2.2x = Configuration Header", Type);
pArrayUSB->Add(sBuf);
//2 数字 此配置信息的总长(包括配置,接口,端点和设备类及厂商定义的描述表)
LowByte = *++BufferPtr;
sBuf.Format(" wTotalLength %4.4x", LowByte + (*++BufferPtr << 8));
pArrayUSB->Add(sBuf);
//1 数字 此配置所支持的接口个数
sBuf.Format(" bNumInterfaces %2.2x", *++BufferPtr);
b= *BufferPtr;
sBuf1.Format(" = 支持的接口个数 = %d 个", (int)b);
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 数字 在SetConfiguration()请求中用作参数来选定此配置。
sBuf.Format(" bConfigValue %2.2x", *++BufferPtr);
sBuf= sBuf + _T(" = 配置参数");
pArrayUSB->Add(sBuf);
//1 索引 描述此配置的字串描述表索引
sBuf.Format(" iConfiguration %2.2x", *++BufferPtr);//配置名称信息的字串
pArrayUSB->Add(sBuf);
if (*BufferPtr != 0) LanguageID = Get_StringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr, pArrayUSB);
//1 位图 配置特性:
//D7: 保留(设为一)
//D6: 自给电源
//D5: 远程唤醒
//D4..0:保留(设为一)
//一个既用总线电源又有自给电源的设备会在MaxPower域指出需要从总线取的电量。
//并设置D6为一。运行时期的实际电源模式可由GetStatus(DEVICE) 请求得到。
sBuf.Format(" bmAttributes %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 mA 在此配置下的总线电源耗费量。以 2mA 为一个单位。
LowByte = *++BufferPtr;
sBuf.Format(" bMaxPower %2.2x = %d mA", LowByte, (LowByte << 1));
pArrayUSB->Add(sBuf);
break;
case 4:
//接口描述符
sBuf.Format(" 接口描述:");
pArrayUSB->Add(sBuf);
sBuf.Format(" bLength %2.2x", Length);
pArrayUSB->Add(sBuf);
//1 常量=4 接口描述表类
sBuf.Format(" bDescriptorType %2.2x = Interface Descriptor", Type);
pArrayUSB->Add(sBuf);
//1 数字 接口号,当前配置支持的接口数组索引(从零开始)
sBuf.Format(" bInterfaceNum %2.2x", *++BufferPtr);
b= *BufferPtr;
sBuf1.Format(" = 接口数组索引 %d 个", (int)b);
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 数字 可选设置的索引值。
sBuf.Format(" bAlternateSetting %2.2x", *++BufferPtr);
b= *BufferPtr;
sBuf1.Format(" = 可选设置的索引值 %d 个", (int)b);
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 数字 此接口用的端点总数,如果是零则说明此接口只用缺省控制管道。
sBuf.Format(" bNumEndpoints %2.2x", *++BufferPtr);
b= *BufferPtr;
sBuf1.Format(" = 此接口用的端点总数 %d 个", (int)b);
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 类 类值 零值为将来的标准保留。如果此域的值设为FFH,则此接口类由厂商说明。
//所有其它的值由USB 说明保留。
LowByte = *++BufferPtr;
if ((LowByte > 9) & (LowByte < 255)) LowByte = 11;
if (LowByte == 255) LowByte = 10;
sBuf.Format(" bInterfaceClass %2.2x = %s", *BufferPtr, ClassName[LowByte]);
pArrayUSB->Add(sBuf);
//1 子类 子类码 这些值的定义视bInterfaceClass域而定。如果bInterfaceClass域的值
//为零则此域的值必须为零。bInterfaceClass域不为FFH则所有值由USB 所保留。
sBuf.Format(" bSubClass %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 协议 协议码:bInterfaceClass 和bInterfaceSubClass 域的值而定.如果一个接口支持
//设备类相关的请求此域的值指出了设备类说明中所定义的协议.
sBuf.Format(" bProtocol %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 索引 描述此接口的字串描述表的索引值。
sBuf.Format(" iInterface %2.2x", *++BufferPtr);//接口说明信息的字串
sBuf= sBuf + _T(" = 此接口的字串描述表的索引值");
pArrayUSB->Add(sBuf);
if (*BufferPtr != 0) LanguageID = Get_StringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr, pArrayUSB);
break;
case 5:
//端点描述符
sBuf.Format(" 端点描述:");
pArrayUSB->Add(sBuf);
sBuf.Format(" bLength %2.2x", Length);
pArrayUSB->Add(sBuf);
//1 常量 端点描述表类
sBuf.Format(" bDescriptorType %2.2x = Endpoint Descriptor", Type);
pArrayUSB->Add(sBuf);
//1 端点,此描述表所描述的端点的地址。此地址的编码如下:
//Bit 3..0 : 端点号.
//Bit 6..4 : 保留,为零
//Bit 7: 方向,如果是控制端点则略。
//主机 0:出端点,1:入端点
//设备 1:出端点,0:入端点
sBuf.Format(" bEndpointAddress %2.2x", *++BufferPtr);
b= *BufferPtr;
if(!(b & 0x80))sBuf1.Format(" = 端点 %d 主机写出", (int)(b & 0x03));
if((b & 0x80))sBuf1.Format(" = 端点 %d 主机读入", (int)(b & 0x03));
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 位图 此域的值描述的是在bConfigurationValue域所指的配置下端点的特性。
//Bit 1..0 :传送类型,00=控制传送,01=同步传送,10=批量传送,11=中断传送所有其它的位都保留。
sBuf.Format(" bmAttributes %2.2x = ", *++BufferPtr);
sBuf= sBuf + ConnectionType[(*BufferPtr) & 0x03];
pArrayUSB->Add(sBuf);
//2 数字 当前配置下此端点能够接收或发送的最大数据包的大小。
//对与同步传送此值用于为每幀的数据净负荷预留时间。而通道可能在实际运行时不需要预留的带宽。
//实际带宽可由设备通过一种非USB定义的机制汇报给主机.
//对于中断传送,批传送,控制传送.端点可能发送较小的数据包。
//并且在结束传送后既有可能间隙时间来重启,也有可能不需要这段时间。具体请参照第五章。
LowByte = *++BufferPtr;
uData= (*(USHORT*)BufferPtr);
sBuf.Format(" wMaxPacketSize %4.4x", LowByte + (*++BufferPtr << 8));
sBuf1.Format(" = 最大数据包的大小: %d Byte", uData);
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 数字 轮寻数据传送端点的时间间隔。 此域的值对于批传送的端点及控制传送的端点忽略。
//对于同步传送的端点此域必需为1。对于中断传送的端点此域值的范围为1到255。
sBuf.Format(" bInterval %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
break;
case 0x21:
sBuf.Format(" HID 描述:");
pArrayUSB->Add(sBuf);
sBuf.Format(" bLength %2.2x", Length);
pArrayUSB->Add(sBuf);
sBuf.Format(" bDescriptorType %2.2x = HID Descriptor", Type);
pArrayUSB->Add(sBuf);
LowByte = *++BufferPtr;
sBuf.Format(" wHIDversion %4.4x", LowByte + (*++BufferPtr << 8));
pArrayUSB->Add(sBuf);
sBuf.Format(" bCountryCode %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
sBuf.Format(" bHIDDescriptorCount %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
sBuf.Format(" bHIDReportType %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
LowByte = *++BufferPtr;
sBuf.Format(" wHIDReportLength %4.4x", LowByte + (*++BufferPtr << 8));
pArrayUSB->Add(sBuf);
break;
default:
sBuf.Format(" 未知的描述:");
pArrayUSB->Add(sBuf);
sBuf.Format("Unknown descriptor with Length = %2.2xH and Type = %2.2xH", Length, Type);
pArrayUSB->Add(sBuf);
BufferPtr-=2; // Back up to start of descriptor
for (i = 0; i < Length; i++) {
if ((i % 16) == 0)
{
sBuf.Format("");
pArrayUSB->Add(sBuf);
}
sBuf.Format("%2.2x ", *++BufferPtr);
pArrayUSB->Add(sBuf);
}
break;
}
Length = *++BufferPtr;
pArrayUSB->Add("");
}
return LanguageID;
}
//获取设备描述符
USHORT Search_USB::Get_DeviceDescriptor(HANDLE HubHandle, ULONG PortIndex, USHORT LanguageID, PUCHAR BufferPtr, CStringArray* pArrayUSB)
{
CString sBuf;
CString sBuf1;
USHORT uData;
UCHAR LowByte;
if (DEBUG)
{
sBuf.Format("In DisplayDeviceDescriptor with HubHandle = %x, PortIndex = %x, LanguageID = %x", HubHandle, PortIndex, LanguageID);
pArrayUSB->Add(sBuf);
}
//设备描述符
sBuf.Format(" 设备驱动描述:");
pArrayUSB->Add(sBuf);
BufferPtr--; // Backup pointer to prepare for pre-increment
sBuf.Format(" bLength %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 常量 描述表种类为设备
sBuf.Format(" bDescriptorType %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//2 BCD码 此设备与描述表兼容的USB设备说明版本号(BCD 码)
LowByte = *++BufferPtr;
uData= (*(USHORT*)BufferPtr);
sBuf.Format(" bcdUSB %4.4x", LowByte + (*++BufferPtr << 8));
if(uData == 0x0110)sBuf1.Format(" = USB1.1");
if(uData == 0x0200)sBuf1.Format(" = USB2.0");
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//1 类 设备类码如果此域的值为0则一个设置下每个接口指出它自己的类,并个接口各自独立工作。
//如果此域的值处于1~FEH之间,则设备在不同的接口上支持不同的类。并这些接口可能不能
//独立工作。此值指出了,这些接口集体的类定义。如果此域设为FFH,则此设备的类由厂商定义。
sBuf.Format(" bDeviceClass %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 子类 子类码 这些码值的具体含义根据bDeviceClass 域来看。如bDeviceClass 域为零,
//此域也须为零如bDeviceClass 域为FFH,此域的所有值保留。
sBuf.Format(" bDeviceSubClass %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 协议 协议码 这些码的值视bDeviceClass 和 bDeviceSubClass 的值而定。
//如果设备支持设备基础上的类相关的协议,此码标志了设备类说明上的值。
//如果此域的值为零,则此设备不在设备基础上支持设备类相关的协议。然而,
//它可能在接口基础上支持设备类相关的协议。如果此域的值为FFH,此设备使用厂商定义的协议。
sBuf.Format(" bDeviceProtocol %2.2x", *++BufferPtr);
pArrayUSB->Add(sBuf);
//1 数字 端点0 的最大包尺寸(仅8,16,32,64为合法值)
sBuf.Format(" bMaxEP0Size %2.2x", *++BufferPtr);
sBuf1.Format(" = 控制管道最大包尺寸: %d Byte", BYTE(*BufferPtr));
sBuf= sBuf + sBuf1;
pArrayUSB->Add(sBuf);
//2 ID 厂商标志(由USB标准付值)供应商标识
LowByte = *++BufferPtr;
sBuf.Format(" wVendorID %4.4x", LowByte + (*++BufferPtr << 8));
sBuf= sBuf + _T(" = 厂商 ID");
pArrayUSB->Add(sBuf);
//2 ID 产品标志(由厂商付值)
LowByte = *++BufferPtr;
sBuf.Format(" wProductID %4.4x", LowByte + (*++BufferPtr << 8));
sBuf= sBuf + _T(" = 产品 ID");
pArrayUSB->Add(sBuf);
//2 BCD 码 设备发行号(BCD 码)
LowByte = *++BufferPtr;
sBuf.Format(" wDeviceID %4.4x", LowByte + (*++BufferPtr << 8));
sBuf= sBuf + _T(" = 设备发行号");
pArrayUSB->Add(sBuf);
//1 索引 描述制造厂商信息的字串的索引。
sBuf.Format(" iManufacturer %2.2x", *++BufferPtr);//制造厂商信息的字串
pArrayUSB->Add(sBuf);
if (*BufferPtr != 0) LanguageID = Get_StringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr, pArrayUSB);
//1 索引 描述产品信息的字串的索引。
sBuf.Format(" iProduct %2.2x", *++BufferPtr);//产品设备种类信息的字串
pArrayUSB->Add(sBuf);
if (*BufferPtr != 0) LanguageID = Get_StringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr, pArrayUSB);
//1 索引 描述设备序列号信息的字串的索引。
sBuf.Format(" iSerialNumber %2.2x", *++BufferPtr);//设备序列号信息的字串
pArrayUSB->Add(sBuf);
if (*BufferPtr != 0) LanguageID = Get_StringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr, pArrayUSB);
//1 数字 可能的设置数,表明此设备支持的配置数。
sBuf.Format(" bNumConfigurations %2.2x", *++BufferPtr);
sBuf= sBuf + _T(" = 设备支持的配置数");
pArrayUSB->Add(sBuf);
return LanguageID;
}
/*
case 0: 语言的码字串 &StringLANGID
case 1: //制造厂商 szManufacturer= "Tsinghua University"
case 2: //设备种类 szProduct= "USB2.0 Develope Kit By XXG: xuxigang@263.net"
case 3: //序列号 szSerialNumber= ""
case 4: //配置名称 szConfiguration= "Endian Tech BY: XXG"
case 5: //接口说明信息的字串 szInterface= "Interface to the CPU Cooler system"
case 6: //用户信息 szUserInfo"The original user of this board is xuxigang@263.net"
*/
//获取字符串
USHORT Search_USB::Get_StringDescriptor(HANDLE HubHandle, ULONG PortIndex, USHORT LanguageID, UCHAR Index, CStringArray* pArrayUSB)
{
CString sBuf;
WCHAR* pszwCHAR;
if (DEBUG)
{
sBuf.Format("In DisplayStringDescriptor with HubHandle = %x, PortIndex = %x, LanguageID = %x, Index = %x",
HubHandle, PortIndex, LanguageID, Index);
pArrayUSB->Add(sBuf);
}
DESCRIPTOR_REQUEST Packet;
DWORD BytesReturned;
BOOL Success;
if (LanguageID == 0)
{ // Get the language ID
memset(&Packet, 0, sizeof(Packet));
Packet.ConnectionIndex = PortIndex;
Packet.SetupPacket.bmRequest = 0x80;
Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
Packet.SetupPacket.wValue[1] = USB_STRING_DESCRIPTOR_TYPE;
// Packet.SetupPacket.wValue[0] = 0;//字串的索引,指示出是字符串 语言 ID
Packet.SetupPacket.wLength[0] = 4;
Success = DeviceIoControl(HubHandle,
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
&Packet,
sizeof(Packet),
&Packet,
sizeof(Packet),
&BytesReturned,
NULL);
if (!Success)
{
sBuf.Format(" *** ERROR *** String Descriptor 0 not returned, ErrorCode = %d", GetLastError());
pArrayUSB->Add(sBuf);
}
LanguageID = Packet.Data[2] + (Packet.Data[3] << 8);
}
memset(&Packet, 0, sizeof(Packet));
Packet.ConnectionIndex = PortIndex;
Packet.SetupPacket.bmRequest = 0x80;
Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
Packet.SetupPacket.wValue[1] = USB_STRING_DESCRIPTOR_TYPE;
Packet.SetupPacket.wValue[0] = Index;//字串的索引,指示出是那个字符串
Packet.SetupPacket.wIndex[0] = LanguageID & 0xFF;
Packet.SetupPacket.wIndex[1] = (LanguageID >> 8) & 0xFF;
Packet.SetupPacket.wLength[0] = 255;
Success = DeviceIoControl(HubHandle,
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
&Packet,
sizeof(Packet),
&Packet, sizeof(Packet),
&BytesReturned,
NULL);
if (!Success)
{
sBuf.Format(" *** ERROR *** String Descriptor %d not returned. ErrorCode = %d", Index, GetLastError());
pArrayUSB->Add(sBuf);
}
pszwCHAR= (WCHAR*)&Packet.Data[2];
sBuf= _T(pszwCHAR);
sBuf= " = " + sBuf;
sBuf= pArrayUSB->GetAt(pArrayUSB->GetSize()- 1)+ sBuf;
pArrayUSB->SetAt(pArrayUSB->GetSize()- 1, sBuf);
return LanguageID;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -