1.
根据设备类型获得设备类的
GUID
对
VC
来说
,
这些
GUID
定义在
DEVGUID.H
文件中
.
假设是一个端口类设备
,
则
GUID
为
DEFINE_GUID( GUID_DEVCLASS_PORTS,
0x4d36e978L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
2.
根据
GUID
得到设备类信息句柄
Windows DDK, SetupDiGetClassDevs,
返回一个
HDEVINFO
类型句柄
,
可通过它枚举该设备类下所有设备
.
3.
根据设备类信息句柄依次枚举这个设备类下的所有设备的设备信息
Windows DDK, SetupDiEnumDeviceInfo,
输出一个
SP_DEVINFO_DATA
结构体指针
,
这个结构体包含了设备的
GUID,
设备实例
(Device Instance)
等信息
.
4.
获得当前设备的属性
Windows DDK, SetupDiGetDeviceRegistryProperty, retrieves the specified Plug and Play device property.
得到一个特定的即插即用设备的属性
.
可以传入参数
,
以得到不同类型的属性
.
通常需要连续调用两次
,
每一次根据需要的属性类型
,
得到传出属性所需内存大小
,
第二次传出所需属性
.
5.
根据属性确定是否为正在枚举的设备
,
如果是返回一个值
,
我们可以根据这个值去打开这个设备
.
假设上一步得到设备名称
”XX Port(COM2)”,
可匹配
”XX Port”,
返回
”COM2”,
并通过
Windows API “OpenFile”
去打开它
.
实例
:
根据设备描述
,
找到并返回一个串口设备的串口名称
:
BOOL
BTCGetDigPort(PCHAR pPort, PCHAR pName)
{
HDEVINFO
DeviceInfoSet;
SP_DEVINFO_DATA
DeviceInfoData;
DWORD
index;
BOOL
bReult = FALSE;
if(!pPort || !pName)
{
return FALSE;
}
// Buffer must over MAX_PATH(127 Byte)
/*
** Get port info set
*/
DeviceInfoSet = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_PORTS, // All Classes
0,
0,
DIGCF_PRESENT);//DIGCF_ALLCLASSES); // All devices
if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
/*
** Enum all ports
*/
for(index=0;SetupDiEnumDeviceInfo(DeviceInfoSet,index,&DeviceInfoData);index++)
{
LPTSTR buffer
= NULL;
DWORD
buffersize = 0;
/*
** Get friendly name
*/
while (!SetupDiGetDeviceRegistryProperty(IN
DeviceInfoSet,
IN
&DeviceInfoData,
IN
SPDRP_FRIENDLYNAME,
OUT NULL,
OUT (PBYTE)buffer,
IN
buffersize,
OUT &buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
/*
** May be a Legacy Device with no HardwareID
*/
break;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
/*
** We need to change the buffer size
*/
if (buffer)
{
LocalFree(buffer);
}
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
/*
**
Unknown Failure
*/
goto cleanup_DeviceInfo;
}
}
if(!buffer)
{
/*
** Some device no friendly name, so buffer is null
** In this situation, we can’t compare device ID
*/
continue;
}
/*
** Compare device ID
*/
if(strstr(buffer, pName))
//
这里的
AT_PORT
就是设备管理器里
,AT
口的设备名称
{
/*
** Get Port number
*/
//DBG_PRINT(“Name: %s”, buffer, 0);
DWORD i
= strlen(buffer);
DWORD dwStart, dwEnd;
PCHAR pStart;
while(buffer[i] != ‘(‘)
{
if(buffer[i] == ‘)’)
{
dwEnd = i;
}
i–;
}
dwStart = i+1;
pStart = buffer+dwStart;
memcpy(pPort, pStart, dwEnd-dwStart);
pPort[dwEnd-dwStart] = ‘/0’;
//DBG_PRINT(“pPort: %s”, pPort, 0);
bReult = TRUE;
if(buffer)
{
LocalFree(buffer);
buffer = NULL;
}
goto cleanup_DeviceInfo;
}/* End find our diag port */
if(buffer)
{
LocalFree(buffer);
buffer = NULL;
}
}
cleanup_DeviceInfo:
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return bReult;
}