http://blog.csdn.net/danxuezx/article/details/5085483
用SetupDi系列函数可以获得系统中一些设备的信息。
1 SetupDiGetClassDevs函数
MSDN中这样描述:
The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information elements for a local machine.
我的理解也就是这个函数能返回一个包含某个设备集合信息的一个指针。这里的handle暂且这么理解。
用SetupDiGetClassDevs得到的这个handle,最后记得要调用SetupDiDestroyDeviceInfoList来删除。
2 SetupDiEnumDeviceInfo函数
MSDN中的描述:
The SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set.
我的理解:用第一个函数得到了一个设备集合的handle,然后根据此handle用SetupDiEnumDeviceInfo可以枚举出来该设备集合中某一个设备的信息。而这些信息保存在SP_DEVINFO_DATA这样一个结构体中。实际上这里得到的还不是某一个设备的具体信息,这里得到的只是一个指针,这个指针指向了一个包含该设备所有信息的集合。一个设备可能有很多信息,比如设备描述,设备名称,设备占有资源等等。要得到该设备具体的某一项信息需要用到下面要说的第3个函数:
3 SetupDiGetDeviceRegistryProperty
MSDN中这样描述:
The SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
我的理解:用这个函数可以在前面得到的指向某一个具体设备信息集合的指针中取出某一项信息。
其实上面三个函数是从不同的层面上来一步一步的得到某一个设备的具体的信息的。
就拿网卡来说吧,这个三个层次如下:
一台机器上的网卡GUID->具体到某一个网卡的信息集合->一个集合中的一个具体的信息。
[cpp] view plain copy
BOOL CollectNetCardInfo::GetAllPhysicsNetCardName()
{
BOOL bRet = TRUE;
GUID NetCardClassGuid =
{0X4D36E972, 0XE325, 0X11CE, {0XBF, 0XC1, 0X08, 0X00, 0X2B, 0XE1, 0X03, 0X18}};
//得到一个Class下信息集句柄
m_NewDeviceInfoSet = SetupDiGetClassDevs(&NetCardClassGuid, NULL, NULL, DIGCF_PRESENT);
if(m_NewDeviceInfoSet == INVALID_HANDLE_VALUE)
{
wprintf(_T("NewDeviceInfoSet == INVALID_HANDLE_VALUE"));
bRet = FALSE;
return bRet;
}
//对得到的此class信息集进行枚举
for(int Device_Index=0; ; Device_Index++)
{
memset((void*)&(m_NetCardDevInfoData), 0, sizeof(SP_DEVINFO_DATA));
m_NetCardDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
BOOL bResult = SetupDiEnumDeviceInfo(m_NewDeviceInfoSet, Device_Index, &m_NetCardDevInfoData);
if(bResult == 0)
{
if(GetLastError() == ERROR_NO_MORE_ITEMS)
{
break;
}
}
DWORD dwBufSize = 0;
BYTE *pbReuslt = MySetupDiGetDeviceRegistryProperty(
SPDRP_ENUMERATOR_NAME ,
NULL,&dwBufSize);
if(pbReuslt)
{
TCHAR *tcName = (TCHAR*)pbReuslt;
_wcsupr_s(tcName,dwBufSize);
if(wcscmp(tcName,_T("ROOT")) != 0)
{
m_NetCardNum++;
GetNetCardDes();
}
free(pbReuslt);
}
}
//销毁一个Class的device information set
SetupDiDestroyDeviceInfoList(m_NewDeviceInfoSet);
return bRet;
}
void CollectNetCardInfo::GetNetCardDes()
{
DWORD dwBufSize = 0;
BYTE *pbTemp = MySetupDiGetDeviceRegistryProperty(
SPDRP_DEVICEDESC,
NULL,&dwBufSize);
if(pbTemp)
{
BYTE *pbNetDes = new BYTE[dwBufSize];
memset(pbNetDes,0x00,dwBufSize);
memcpy(pbNetDes,pbTemp,dwBufSize);
m_NetCardDesMap.insert(make_pair(m_NetCardNum,pbNetDes));
free(pbTemp);
}
}
BYTE* CollectNetCardInfo::MySetupDiGetDeviceRegistryProperty(
IN DWORD Property,
OUT PDWORD PropertyRegDataType ,
OUT PDWORD pdwBufSize)
{
DWORD Required_Size = 0;
BOOL bResult = SetupDiGetDeviceRegistryProperty(
m_NewDeviceInfoSet,
&m_NetCardDevInfoData,
Property ,
PropertyRegDataType,
NULL, 0,
&Required_Size);
if(!bResult)
{
if(ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
*pdwBufSize = Required_Size;
BYTE *PropertyBuffer = (BYTE*)malloc(Required_Size);
bResult = SetupDiGetDeviceRegistryProperty(
m_NewDeviceInfoSet,
&m_NetCardDevInfoData,
Property ,
PropertyRegDataType,
PropertyBuffer,
Required_Size, NULL);
if(bResult)
return PropertyBuffer;
else
{
free(PropertyBuffer);
return NULL;
}
}
else
return NULL;
}
else
return NULL;
}