枚举所有设备路径

Enumerate all device paths

本文关键字:路径 枚举      更新时间:2023-10-16

我正在尝试获取具有设备接口的所有设备的路径,但是当我调用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_NAMEDEVPKEY_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);
}