求助:SetupDiGetDeviceInterfaceDetail 返回false问题

xxxccc9668 2011-04-02 12:55:19
由于毕设需要做PC与USB通信的程序。之前我一点没接触过,这些天查阅一些资料后大概知道先要获取设备路径,然后调用CreateFile等函数进行连接。获取设备路径我是用的SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiGetDeviceInterfaceDetail这三个函数。但是执行SetupDiGetDeviceInterfaceDetail后返回的总是false,调用GetLastError函数给出的是1784。
以下是我的程序,望各位大虾指教~

int main()
{
_GUID InterfaceClassGuid = {0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED};

HDEVINFO hdevClassInfo;

hdevClassInfo = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hdevClassInfo == INVALID_HANDLE_VALUE)
{
cout<<"SetupDiGetClassDevs 错误"<<endl;
}

DWORD nMemberIndex;
for(nMemberIndex = 0; true; nMemberIndex++)
{
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
BOOL nStatus = SetupDiEnumDeviceInterfaces(hdevClassInfo, NULL, &InterfaceClassGuid, nMemberIndex, &DeviceInterfaceData);
if (!nStatus)
{
cout<<"枚举完成 "<<nMemberIndex<<endl;
break;
}
DWORD RequiredSize;
nStatus = SetupDiGetDeviceInterfaceDetail(hdevClassInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL);
PSP_DEVICE_INTERFACE_DETAIL_DATA pBuffer;
pBuffer = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
pBuffer->cbSize = sizeof(*pBuffer);

SP_DEVINFO_DATA DeviceInfoData;
nStatus = SetupDiGetDeviceInterfaceDetail(hdevClassInfo, &DeviceInterfaceData, pBuffer, RequiredSize, &RequiredSize, &DeviceInfoData);
if(!nStatus)
{
cout<<pBuffer->DevicePath<<endl;//没有被赋值,一堆乱字
cout<<"错误1 "<<GetLastError()<<endl;//错误代码:1784
break;
}
}
SetupDiDestroyDeviceInfoList(hdevClassInfo);
return 0;
}
...全文
929 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
tubo_true 2011-10-14
  • 打赏
  • 举报
回复
SetupDiGetDeviceInterfaceDetail 之后

createfile失败??
azureflu 2011-07-18
  • 打赏
  • 举报
回复
womne
xxxccc9668 2011-04-02
  • 打赏
  • 举报
回复
感谢LS,成功执行了~
原来是这么回事,没有注意到MSDN上说这个参数必须要设置其大小
还没想好 2011-04-02
  • 打赏
  • 举报
回复
SP_DEVINFO_DATA DeviceInfoData ;

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA) ;

试试。
利用USB接口进行通信的数据源码MemberIndex = 0 Do 'The cbSize element of the MyDeviceInterfaceData structure must be set to 'the structure's size in bytes. The size is 28 bytes. MyDeviceInterfaceData.cbSize = LenB(MyDeviceInterfaceData) Result = SetupDiEnumDeviceInterfaces _ (DeviceInfoSet, _ 0, _ HidGuid, _ MemberIndex, _ MyDeviceInterfaceData) Call DisplayResultOfAPICall("SetupDiEnumDeviceInterfaces") If Result = 0 Then LastDevice = True 'If a device exists, display the information returned. If Result <> 0 Then lstResults.AddItem " DeviceInfoSet for device #" & CStr(MemberIndex) & ": " lstResults.AddItem " cbSize = " & CStr(MyDeviceInterfaceData.cbSize) lstResults.AddItem _ " InterfaceClassGuid.Data1 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data1) lstResults.AddItem _ " InterfaceClassGuid.Data2 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data2) lstResults.AddItem _ " InterfaceClassGuid.Data3 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data3) lstResults.AddItem _ " Flags = " & Hex$(MyDeviceInterfaceData.Flags) '****************************************************************************** 'SetupDiGetDeviceInterfaceDetail 'Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure 'containing information about a device. 'To retrieve the information, call this function twice. 'The first time returns the size of the structure in Needed. 'The second time returns a pointer to the data in DeviceInfoSet. 'Requires: 'A DeviceInfoSet returned by SetupDiGetClassDevs and 'an SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. '******************************************************************************* MyDeviceInfoData.cbSize = Len(MyDeviceInfoData) Result = SetupDiGetDeviceInterfaceDetail _ (DeviceInfoSet, _ MyDeviceInterfaceData, _ 0, _ 0, _ Needed, _ 0) DetailData = Needed Call DisplayResultOfAPICall("SetupDiGetDeviceInterfaceDetail") lstResults.AddItem " (OK to say too small)" lstResults.AddItem " Required buffer size for the data: " & Needed 'Store the structure's size. MyDeviceInterfaceDetailData.cbSize = _ Len(MyDeviceInterfaceDetailData) 'Use a byte array to allocate memory for 'the MyDeviceInterfaceDetailData structure ReDim DetailDataBuffer(Needed) 'Store cbSize in the first four bytes of the array. Call RtlMoveMemory _ (DetailDataBuffer(0), _ MyDeviceInterfaceDetailData, _ 4) 'Call SetupDiGetDeviceInterfaceDetail again. 'This time, pass the address of the first element of DetailDataBuffer 'and the returned required buffer size in DetailData. Result = SetupDiGetDeviceInterfaceDetail _ (DeviceInfoSet, _ MyDeviceInterfaceData, _ VarPtr(DetailDataBuffer(0)), _ DetailData, _ Needed, _ 0) Call DisplayResultOfAPICall(" Result of second call: ") lstResults.AddItem " MyDeviceInterfaceDetailData.cbSize: " & _ CStr(MyDeviceInterfaceDetailData.cbSize) 'Convert the byte array to a string. DevicePathName = CStr(DetailDataBuffer()) 'Convert to Unicode. DevicePathName = StrConv(DevicePathName, vbUnicode) 'Strip cbSize (4 bytes) from the beginning. DevicePathName = Right$(DevicePathName, Len(DevicePathName) - 4) lstResults.AddItem " Device pathname: " lstResults.AddItem " " & DevicePathName '****************************************************************************** 'CreateFile 'Returns: a handle that enables reading and writing to the device. 'Requires: 'The DevicePathName returned by SetupDiGetDeviceInterfaceDetail. '****************************************************************************** HidDevice = CreateFile _ (DevicePathName, _ GENERIC_READ Or GENERIC_WRITE, _ (FILE_SHARE_READ Or FILE_SHARE_WRITE), _ 0, _ OPEN_EXISTING, _ 0, _ 0) Call DisplayResultOfAPICall("CreateFile") lstResults.AddItem " Returned handle: " & Hex$(HidDevice) & "h" 'Now we can find out if it's the device we're looking for. '****************************************************************************** 'HidD_GetAttributes 'Requests information from the device. 'Requires: The handle returned by CreateFile. 'Returns: an HIDD_ATTRIBUTES structure containing 'the Vendor ID, Product ID, and Product Version Number. 'Use this information to determine if the detected device 'is the one we're looking for. '****************************************************************************** 'Set the Size property to the number of bytes in the structure. DeviceAttributes.Size = LenB(DeviceAttributes) Result = HidD_GetAttributes _ (HidDevice, _ DeviceAttributes) Call DisplayResultOfAPICall("HidD_GetAttributes") If Result <> 0 Then lstResults.AddItem " HIDD_ATTRIBUTES structure filled without error." Else lstResults.AddItem " Error in filling HIDD_ATTRIBUTES structure." End If lstResults.AddItem " Structure size: " & DeviceAttributes.Size lstResults.AddItem " Vendor ID: " & Hex$(DeviceAttributes.VendorID) lstResults.AddItem " Product ID: " & Hex$(DeviceAttributes.ProductID)
现在USB设备却很多,因此对USB设备的查找与读写就必不可少了。但是能找到关于USB读写的资料很少。这里使用VC++示范了一些获得USB的信息的方法。 一、枚举USB设备   通过枚举USB控制器->枚举此控制器上的USB HUB->枚举HUB的各个端口->获得设备信息。 枚举控制器: wsprintf(HCName, "\\\\.\\HCD%d", HCNum); hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);   计算机上的USB主控制器以HCD1,HCD2等命名。通过控制器名称,使用CCreateFile 打开它。使用DeviceIoControl即可得到其驱动程序名,以及与它连接的HUB的名称。用CCreateFile打开HUB,获得连接信息。再枚举HUB的各个端口即可获得连接的设备信息。 二、枚举HID设备   HID设备是微软定义的标准人机接口规范。比如USB鼠标,USB游戏手柄等。不用查找具体设备的GUID,使用API HidD_GetHidGuid(&guidHID)即可得到GUID。有了GUID通过API SetupDiEnumDeviceInterfaces可获得是否有设备连接。如果此类设备连接通过SetupDiGetDeviceInterfaceDetail获得它的设备路径信息。使用CCreateFile 打开它,通过HidD_GetAttributes获得其基本属性信息。使用DeviceIoControl可以获得更详细的属性。在本代码中如果计算机上插有USB游戏手柄,可获得其信息。但不知道为什么xp下却不能获得USB鼠标的信息。 三 枚举U盘   先用GetDriveType API获得设备的类型,若类型为REMOVABLE(当然有些大容量U盘可能报告为FIXED,那就需要其他方法来确定了),即可能是U盘。用CCreateFile 打开之后,再用IOCTL_STORAGE_QUERY_PROPERTY为参数的DeviceIoControl来获得其属性。 四、结束语   示例工程在winxp+xpDDK+VC6下编译通过。USB设备种类比较多,也比较特殊,不同厂商的硬件不同,控制软件也不尽相同(我想主要是ICTL码不同,也不容易查到)。使得访问USB口的设备不象串口并口那么方便。这个例程只是展示了访问的基本方法。其中还有些问题还没有解决,发出来希望大家解决之后能通知我或者发表出来。 参考了USBPort,USBview等代码,一并致谢。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧