因为项目需要,需要遍历设备管理器,找了很多资料,结果发现还是使用SetupAPI来实现比较靠谱,其本质是读取注册表的内容,当然也可以通过遍历注册表来实现,当然这样会比较麻烦。
/*********************************
* 枚举所有设备信息
* @int index[in] 枚举设备时的序号
* @LPTSTR lpDeviceClassName[out] 设备的Class,对应注册表中的Class的值
* @LPTSTR lpDeviceClassDesc[out] 设备描述,对应注册表的默认值
* @BOOL* bDevicePresent 设备是否存在
*********************************/
BOOL CGetComputerInfo::EnumDeviceClasses(int index,LPTSTR lpDeviceClassName,
LPTSTR lpDeviceClassDesc,BOOL* bDevicePresent)
{
BOOL bRet = FALSE;
GUID ClassGuid;
HDEVINFO hNewDeviceInfoSet = INVALID_HANDLE_VALUE;//设备信息集
int result;
BOOL bResNam = FALSE;
LPTSTR lpClassName = NULL;
HKEY hKeyClass = NULL;
ULONG RequiredSize = MAX_PATH;
WCHAR* name = NULL;
__try
{
ZeroMemory(&ClassGuid, sizeof(GUID));
//按index顺序枚举设备列表,获取设备UID
//对应注册表路径:"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\"
result = CM_Enumerate_Classes(index, &ClassGuid, 0);
if(result != CR_SUCCESS)
{
return FALSE;
}
//根据GUID获得设备名
name = new WCHAR[MAX_PATH];
bResNam = SetupDiClassNameFromGuid(&ClassGuid, name, RequiredSize, &RequiredSize);
if(RequiredSize > 0)
{
delete [] name;
name = NULL;
name = new WCHAR[RequiredSize];
bResNam = SetupDiClassNameFromGuid(&ClassGuid, name, RequiredSize, &RequiredSize);
}
//根据GUID返回device information Handle(HDEVINFO)
hNewDeviceInfoSet = SetupDiGetClassDevs(&ClassGuid, 0, NULL, DIGCF_PRESENT);
if (hNewDeviceInfoSet == INVALID_HANDLE_VALUE)
{
*bDevicePresent = FALSE;
StringCchCopy(lpDeviceClassName,MAX_PATH,name);
return FALSE;
}
//打开device setup class registry key
hKeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED,DIOCR_INSTALLER,NULL, 0);
if (hKeyClass == INVALID_HANDLE_VALUE)
{
*bDevicePresent = FALSE;
StringCchCopy(lpDeviceClassName,MAX_PATH,name);
return FALSE;
}
else
{
LONG dwSize = MAX_PATH;
//读取注册表默认值
LONG res = RegQueryValue(hKeyClass, NULL, lpDeviceClassDesc, &dwSize);
if (res != ERROR_SUCCESS)
{
StringCchCopy(lpDeviceClassDesc,MAX_PATH,_T(""));
return FALSE;
}
}
StringCchCopy(lpDeviceClassName,MAX_PATH,name);
*bDevicePresent =TRUE;
bRet = TRUE;
}
__finally
{
if(name)
{
delete [] name;
name = NULL;
}
if(hKeyClass)
{
RegCloseKey(hKeyClass);
hKeyClass = NULL;
}
if(hNewDeviceInfoSet)
{
SetupDiDestroyDeviceInfoList(hNewDeviceInfoSet);
hNewDeviceInfoSet = NULL;
}
}
return bRet;
}
/*********************************
* 获取设备具体名,若具有多个名,通过index进行枚举
* @int index[in] 枚举设备名时的序号
* @LPTSTR DeviceClassName[out] 设备的Class,对应注册表中的Class的值
* @LPTSTR DeviceName[out] 设备具体名字,详见设备管理器
*********************************/
DWORD CGetComputerInfo::EnumDevices(int index, LPTSTR DeviceClassName, LPTSTR DeviceName)
{
ULONG RequiredSize = 0;
//GUID guid;
//ZeroMemory(&guid, sizeof(GUID));
GUID* guids = new GUID[1];
HDEVINFO hNewDeviceInfoSet = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
//获取GUIDS大小
BOOL res=SetupDiClassGuidsFromName(DeviceClassName, &guids[0], RequiredSize, &RequiredSize);
if (RequiredSize==0)
{
StringCchCopy(DeviceName,MAX_PATH, _T(""));
delete [] guids;
guids = NULL;
return CSIERROR_GUIDSFAILED;
}
if (!res)
{
delete [] guids;
guids=new GUID[RequiredSize];
//获取GUID的名字
res=SetupDiClassGuidsFromName(DeviceClassName, &guids[0], RequiredSize, &RequiredSize);
if (!res || RequiredSize==0)
{
StringCchCopy(DeviceName,MAX_PATH, _T(""));
delete [] guids;
guids = NULL;
return CSIERROR_GUIDSFAILED;
}
}
//返回设备信息句柄
hNewDeviceInfoSet=SetupDiGetClassDevs(&guids[0], 0, NULL, DIGCF_PRESENT );
if(hNewDeviceInfoSet == INVALID_HANDLE_VALUE)
{
delete [] guids;
guids = NULL;
return CSIERROR_INVALID_HANDLE;
}
//初始化SP_DEVINFO_DATA结构
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DeviceInfoData.DevInst=0;
ZeroMemory(&DeviceInfoData.ClassGuid, sizeof(GUID));
DeviceInfoData.Reserved=0;
//根据HDEVINFO返回要枚举设备的信息
res=SetupDiEnumDeviceInfo(hNewDeviceInfoSet, index, &DeviceInfoData);
if (!res)
{
//设备不存在,销毁枚举设备信息的句柄
SetupDiDestroyDeviceInfoList(hNewDeviceInfoSet);
hNewDeviceInfoSet = INVALID_HANDLE_VALUE;
StringCchCopy(DeviceName,MAX_PATH, _T(""));
delete [] guids;
guids = NULL;
return CSIERROR_NO_DEVICE;
}
// 返回设备具体名
if (!SetupDiGetDeviceRegistryProperty(hNewDeviceInfoSet, &DeviceInfoData,
SPDRP_FRIENDLYNAME, 0, (BYTE*) DeviceName,
MAX_PATH, NULL))
{
res = SetupDiGetDeviceRegistryProperty(hNewDeviceInfoSet, &DeviceInfoData,
SPDRP_DEVICEDESC, 0, (BYTE*) DeviceName,
MAX_PATH, NULL);
if (!res)
{
//设备名获取失败
SetupDiDestroyDeviceInfoList(hNewDeviceInfoSet);
hNewDeviceInfoSet = INVALID_HANDLE_VALUE;
StringCchCopy(DeviceName,MAX_PATH, _T(""));
delete [] guids;
guids = NULL;
return CSIERROR_GETDEVICENAME;
}
}
delete [] guids;
guids = NULL;
SetupDiDestroyDeviceInfoList(hNewDeviceInfoSet);
hNewDeviceInfoSet = INVALID_HANDLE_VALUE;
return CSIERROR_OK;
}