// EnumDevices.cpp : 定义控制台应用程序的入口点。
//
#include<windows.h>
#include<stdio.h>
#include <SetupAPI.h>
#pragma comment(lib, "setupapi.lib")
// SPDRP_DEVICEDESC
// SPDRP_CLASS
// SPDRP_FRIENDLYNAME
typedef BOOL(*TfEnumDevicesCallback)(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID lpContext);
VOID EnumDevices(WCHAR *DeviceClassName, TfEnumDevicesCallback Callback, PVOID CallbackContext)
{
GUID Guid;
DWORD cbOpt;
//SetupDiClassGuidsFromName函数检索与指定类名关联的GUID。此列表是基于当前安装在系统上的类生成的
//参数1: IN 检索类guid的类的名称 例如:网卡 就是"Net"
//参数2: OUT 指向数组的指针,用于接收与指定类名关联的GUID列表。
//参数3: IN ClassGuidList数组中的GUID数。 多个网卡是不是这个数值要增加?
//参数4: OUT 提供指向接收与类名关联的GUID数量的变量的指针。如果这个数字大于ClassGuidList缓冲区的大小,
// 则该数字指示数组必须有多大才能存储所有GUID。
if (SetupDiClassGuidsFromName(DeviceClassName, &Guid, 1, &cbOpt))
{
HDEVINFO hDev;
//SetupDiGetClassDevs函数返回包含本地计算机请求的设备信息元素的设备信息集的句柄。
//参数1: 调用SetupDiClassGuidsFromName获得的GUID值
//参数2: 1)即插即用(PNP)枚举器的标识符(ID)。这个ID可以是值的全局唯一标识符(GUID),也可以是符号名。
// 例如,可以使用“PCI”来指定PCI PNP值。PNP值的其他符号名称包括“USB”、“PCMCIA”和“SCSI”
// 2)PNP设备实例ID
// 3)此指针是可选的,可以为空。如果枚举值不用于选择设备,则将枚举数设置为空。
//参数3: 用于与在设备信息集中安装设备实例相关联的用户界面的顶层窗口的句柄。这个句柄是可选的,可以是空的。
//参数4: DIGCF_PRESENT 只返回系统中当前存在的设备。
//返回值:成功后返回设备信息集的句柄,相当于申请了一个结构体内存给你,后面需要自己释放.
hDev = SetupDiGetClassDevs(&Guid, NULL, HWND_DESKTOP, DIGCF_PRESENT);
if (hDev != INVALID_HANDLE_VALUE)
{
DWORD MemberIndex;
SP_DEVINFO_DATA sdd;
MemberIndex = 0;
sdd.cbSize = sizeof(sdd);
//SetupDiEnumDeviceInfo函数返回一个SP_DEVINFO_Data结构,该结构指定设备信息集中的设备信息元素 (从返回的数据信息集数组中取一条数据)
while (SetupDiEnumDeviceInfo(hDev, MemberIndex, &sdd))
{
if (!Callback(hDev, &sdd, CallbackContext))
{
break;
}
MemberIndex++;
}
SetupDiDestroyDeviceInfoList(hDev);
}
}
return;
}
BOOL GetDevicePropertyValue(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PVOID *lppResult, DWORD *lpbResult)
{
PBYTE lpBuffer;
DWORD length;
DWORD ret=0;
lpBuffer = NULL;
length = 0;
//SetupDiGetDeviceRegistryProperty 检索特定的即插即用设备属性
//参数1: 设备信息集的句柄
//参数2: 指向指定DeviceInfoSet中设备信息元素的SP_DEVINFO_Data结构的指针。
//参数3: SPDRP_BUSNUMBER 检索设备的总线号
//参数4: 指向接收正在检索的属性的数据类型的变量的指针。这是标准的注册表数据类型之一。此参数是可选的,可以为空。
//参数5: 指向接收正在检索的属性的缓冲区的指针。如果此参数设置为NULL,而且PropertyBufferSize也设置为零,则函数将返回RequiredSize中缓冲区所需的大小。
//参数6: PropertyBuffer缓冲区的大小(以字节为单位)。
//参数7: 指向类型为DWORD的变量的指针,该变量接收用于保存所请求属性的数据所需的PropertyBuffer缓冲区的所需大小(以字节为单位)。此参数是可选的,可以为空。
if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, Property, NULL, NULL, 0, &ret))
{
if (ret==0)
{
return FALSE;
}
if (lpBuffer = (PBYTE)GlobalAlloc(GPTR, ret))
{
ZeroMemory(lpBuffer,ret);
if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, Property, NULL, lpBuffer, ret, NULL))
{
*lppResult = lpBuffer;
*lpbResult = ret;
return TRUE;
}
GlobalFree(lpBuffer);
}
}
return FALSE;
}
VOID FreeGetDevicePropertyValue(PVOID lpBuffer)
{
GlobalFree(lpBuffer);
}
//参数1: 设备信息集的句柄
//参数2: 从信息集中获取的一条数据
//参数3: NULL
BOOL EnumNetCallback(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID CallbackContext)
{
PVOID lpBusNumber;
DWORD cbBusNumber;
if (GetDevicePropertyValue(DeviceInfoSet, DeviceInfoData, SPDRP_BUSNUMBER, &lpBusNumber, &cbBusNumber))
{
if (cbBusNumber)
{
PVOID lpFriendlyName;
DWORD cbFriendlyName;
if (GetDevicePropertyValue(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, &lpFriendlyName, &cbFriendlyName))
{
printf("%S\n", lpFriendlyName);
FreeGetDevicePropertyValue(lpFriendlyName);
}
}
FreeGetDevicePropertyValue(lpBusNumber);
}
return TRUE;
}
BOOL EnumCpuCallback(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID CallbackContext)
{
PVOID lpFriendlyName;
DWORD cbFriendlyName;
if (GetDevicePropertyValue(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, &lpFriendlyName, &cbFriendlyName))
{
printf("%S\n", lpFriendlyName);
FreeGetDevicePropertyValue(lpFriendlyName);
}
return TRUE;
}
BOOL EnumDiskCallback(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID CallbackContext)
{
PVOID lpFriendlyName;
DWORD cbFriendlyName;
if (GetDevicePropertyValue(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, &lpFriendlyName, &cbFriendlyName))
{
printf("%S\n", lpFriendlyName);
FreeGetDevicePropertyValue(lpFriendlyName);
}
return TRUE;
}
BOOL EnumDisplayCallback(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID CallbackContext)
{
PVOID lpFriendlyName;
DWORD cbFriendlyName;
if (GetDevicePropertyValue(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC, &lpFriendlyName, &cbFriendlyName))
{
printf("%S\n", lpFriendlyName);
FreeGetDevicePropertyValue(lpFriendlyName);
}
return TRUE;
}
int main(int argc, CHAR* argv[])
{
UCHAR Mac[8];
printf("%s\n", "Net");
WCHAR net[] = L"Net";
EnumDevices(net, EnumNetCallback, NULL);
printf("\n");
printf("%s\n", "Processor");
WCHAR Processor[] = L"Processor";
EnumDevices(Processor, EnumCpuCallback, NULL);
printf("\n");
printf("%s\n", "Display");
WCHAR Display[] = L"Display";
EnumDevices(Display, EnumDisplayCallback, NULL);
return getchar();
}
枚举设备
最新推荐文章于 2023-12-01 17:18:15 发布