枚举所有设备路径
Enumerate all device paths
我正在尝试获取具有设备接口的所有设备的路径,但是当我调用SetupDiEnumDeviceInterfaces
时,我得到ERROR_NO_MORE_ITEMS
.
#include <windows.h>
#include <setupapi.h>
#include <iostream>
#include <string>
#include <vector>
int main(int argc, const char **argv)
{
HDEVINFO hdevinfo = SetupDiGetClassDevs(0, 0, 0, DIGCF_ALLCLASSES |
DIGCF_PRESENT |
DIGCF_DEVICEINTERFACE);
if (hdevinfo == INVALID_HANDLE_VALUE)
{
std::cerr << "Failed to get device information set" << std::endl;
return -1;
}
SP_DEVINFO_DATA devinfoData{sizeof(SP_DEVINFO_DATA)};
SP_DEVICE_INTERFACE_DATA deviceInterfaceData{sizeof(SP_DEVICE_INTERFACE_DATA)};
std::vector<std::string> devicePaths{};
devicePaths.reserve(512);
DWORD index = 0;
while (SetupDiEnumDeviceInfo(hdevinfo, index, &devinfoData))
{
if (!SetupDiEnumDeviceInterfaces(hdevinfo, &devinfoData, &devinfoData.ClassGuid, index, &deviceInterfaceData))
{
DWORD error = GetLastError();
std::cout << "Error: " << error << std::endl; // always get 259
++index;
continue;
}
DWORD reqSize = 0;
SetupDiGetDeviceInterfaceDetail(hdevinfo, &deviceInterfaceData, 0, 0, &reqSize, 0);
PSP_INTERFACE_DEVICE_DETAIL_DATA pDetailData = PSP_INTERFACE_DEVICE_DETAIL_DATA(new char[reqSize]);
pDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hdevinfo, &deviceInterfaceData, pDetailData, reqSize, 0, 0));
devicePaths.push_back(pDetailData->DevicePath);
delete [] pDetailData;
++index;
}
SetupDiDestroyDeviceInfoList(hdevinfo);
return 0;
}
我已经研究了这个答案,但它对我不起作用,因为它对 USB 设备使用 GUID。就我而言,所需的设备不仅可以通过USB连接,还可以通过PCI和PCI express连接。
我需要这些路径在CreateFile
中使用. 我是否采取了不适当的方法?有其他选择吗?
我们可以CM_Get_Device_ID_ListW
函数检索本地计算机的设备实例 ID列表
然后对于每个 ID 获取设备的设备实例句柄
,方法是CM_Locate_DevNodeW
然后检索带有CM_Get_DevNode_PropertyW
的设备实例属性。 例如DEVPKEY_NAME
和DEVPKEY_Device_PDOName
- 物理设备对象 (PDO( 的名称。 我们可以在内部使用这个名称NtOpenFile
volatile UCHAR guz = 0;
void ProcessList(PZZWSTR pDeviceID)
{
ULONG cb = 0, rcb = 0x80;
CONFIGRET cr;
PVOID stack = alloca(guz);
union {
PVOID buf;
PBYTE PropertyBuffer;
};
HANDLE hFile;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
do
{
DEVINST dnDevInst;
if (CM_Locate_DevNodeW(&dnDevInst, pDeviceID, CM_LOCATE_DEVNODE_NORMAL) == CR_SUCCESS)
{
DbgPrint("n%S:t", pDeviceID);
DEVPROPTYPE PropertyType;
static const DEVPROPKEY PropertyKeys[] = { DEVPKEY_Device_PDOName, DEVPKEY_NAME };
static const PCSTR Names[] = { "PDOName", "FriendlyName" };
ULONG i = _countof(PropertyKeys);
do
{
const DEVPROPKEY* PropertyKey = &PropertyKeys[--i];
PCSTR Name = Names[i];
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
cr = CM_Get_DevNode_PropertyW(dnDevInst, PropertyKey,
&PropertyType, PropertyBuffer, &(rcb = cb), 0);
if (cr == CR_SUCCESS && PropertyType == DEVPROP_TYPE_STRING)
{
DbgPrint("[%s=%S]t", Name, PropertyBuffer);
if (!i)
{
RtlInitUnicodeString(&ObjectName, (PWSTR)PropertyBuffer);
NTSTATUS status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES, &oa, &iosb, FILE_SHARE_VALID_FLAGS, 0);
if (0 <= status)
{
NtClose(hFile);
}
DbgPrint("=%x", status);
}
}
} while (cr == CR_BUFFER_SMALL);
} while (i);
}
} while (*(pDeviceID += wcslen(pDeviceID) + 1));
}
void cccm()
{
CONFIGRET cr;
PZZWSTR pDeviceID;
ULONG ulLen;
do
{
if (CM_Get_Device_ID_List_SizeW(&ulLen, 0, CM_GETIDLIST_FILTER_PRESENT) != CR_SUCCESS || ulLen <= 1)
{
break;
}
if (pDeviceID = new WCHAR[ulLen])
{
if ((cr = CM_Get_Device_ID_ListW(0, pDeviceID, ulLen, CM_GETIDLIST_FILTER_PRESENT)) == CR_SUCCESS)
{
if (*pDeviceID) ProcessList(pDeviceID);
}
delete [] pDeviceID;
}
else
{
break;
}
} while (cr == CR_BUFFER_SMALL);
}
相关文章:
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- C++:枚举:错误:应使用标识符而不是"}"
- 带有 c++ 的枚举(输入检查)
- 枚举所有设备路径
- 如何获取句柄并枚举注册表路径:"REGISTRYA"?
- 缩短C++枚举成员的路径(使用 typedef 或 typename),以用作模板参数