16,550
社区成员
发帖
与我相关
我的任务
分享
typedef struct _DEVICE_DESCRIPTOR
{
wstring wstrRing3Interface;
wstring wstrFriendlyName;
wstring wstrDeviceDesc;
wstring wstrPhysicalDeviceObjectName;
wstring wstrService;
wstring wstrParentInstanceID;
wstring wstrParentDeviceDesc;
wstring wstrStorageManagerName;
DWORD dwStorageDeviceNumber;
DWORD dwSectors;
DWORD dwBytesPerSector;
DISK_PARAMETER DiskGeometry;
}DEVICE_DESCRIPTOR, *PDEVICE_DESCRIPTOR;
/*************************************************************************
* Function Name : GetDeviceInfo(LPGUID, vector<DEVICE_DESCRIPTOR>&)
*
* Introduction : Get storage device description
*
* Input parameter : lpGuid, DeviceVect
*
* Output parameter :None
*
* Return : None
*************************************************************************/
DWORD GetDeviceInfo(LPGUID lpGuid, vector<DEVICE_DESCRIPTOR>& DeviceVector)
{
SP_INTERFACE_DEVICE_DATA InterfaceData = {0}; //存储设备接口信息的结构体
PSP_INTERFACE_DEVICE_DETAIL_DATA_W pDetail = NULL;
SP_DEVINFO_DATA DevInfoData = {0};
HDEVINFO hDevInfoSet = NULL;
DWORD dwErrorCount = 0;
DWORD dwDevIndex = 0;
DEVINST ParentInstance = 0;
BOOL bResult = FALSE;
DEVICE_DESCRIPTOR tmpDevInfo;
DWORD dwNeededSize = 0;
//SetupDiEnumDeviceInterfaces函数取得设备属性集中某个设备接口的上下文环境
//每次调用都返回一个设备接口的相关信息.此函数可以被再三调用以获取一或多个
//设备暴露的、数个接口的信息,这里我们用来枚举符合该GUID的设备接口,调用成功
//的话,ifdata中将得到一个完成的SP_DEVICE_INTERFACE_DATA结构,该结构体将指明
//和枚举参数对应的,设备的接口信息.在调用该参数之前,必须填写ifdata的cbSize域
hDevInfoSet = SetupDiGetClassDevsW(
lpGuid, // 设备类的GUID
NULL, // 不指定关键字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT| // 只枚举目前存在的设备
DIGCF_INTERFACEDEVICE //取得接口信息
);
if(hDevInfoSet == INVALID_HANDLE_VALUE) //失败??
{
MessageBox(NULL,"Sorry,Failed to retrive information set!","Error",MB_OK|MB_ICONERROR);
return 0;
}
// 成功!填写InterfaceData的cbSize域,准备调用SetupDiEnumDeviceInterfaces
InterfaceData.cbSize = sizeof(InterfaceData);
dwDevIndex = 0;
do
{
bResult = SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 设备信息集句柄
NULL, // 不需额外的设备描述
lpGuid, // GUID
dwDevIndex, // 设备信息集里的设备序号
&InterfaceData // 设备接口信息(出口buffer)
);
if(!bResult) //失败?
{
break;
}
//成功,继续进行下列操作
dwNeededSize = 0;
//如果在调用SetupDiGetDeviceInterfaceDetail函数时,指定DeviceInterfaceDetailData,
//DeviceInterfaceDetailDataSize为NULL,并且RequiredSize变量有效的话,将得到需要的
//出口缓冲区的大小
SetupDiGetDeviceInterfaceDetailW(
hDevInfoSet,
&InterfaceData,
NULL,
0,
&dwNeededSize,
NULL
);
//上一次调用,我们在dwNeededSize中得到了PSP_DEVICE_INTERFACE_DETAIL_DATA
//结构体需要的缓冲区的大小,现在我们分配并初始化之.
pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA_W)new char[dwNeededSize];
pDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA_W);
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//OK,分配完毕,再次调用SetupDiGetDeviceInterfaceDetail得到特定接口的详细信息
bResult = SetupDiGetDeviceInterfaceDetailW
(
hDevInfoSet, // 设备信息集句柄,包含接口和下层设备信息(入口)
&InterfaceData, // 设备接口信息,表明我们要获取哪个接口的信息(入口)
pDetail, // 存储要查询的设备接口的详细细节(设备路径,出口)
dwNeededSize, // 指定输出缓冲区大小(入口)
&dwNeededSize, // 不需计算输出缓冲区大小(直接用设定值,出口)
&DevInfoData // 不需额外的设备描述(出口)
);
if(!bResult) //失败,则清场
{
dwErrorCount++;
delete []pDetail;
pDetail = NULL;
dwNeededSize = 0;
continue;
}
//取出设备路径(3环的应用程序所看到的设备路径)
tmpDevInfo.wstrRing3Interface = pDetail->DevicePath;
delete [](char*)pDetail;
pDetail = NULL;
dwNeededSize = 0;
tmpDevInfo.wstrFriendlyName = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_FRIENDLYNAME);
tmpDevInfo.wstrDeviceDesc = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_DEVICEDESC);
tmpDevInfo.wstrPhysicalDeviceObjectName = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
tmpDevInfo.wstrService = GetRegistryPropertyW(hDevInfoSet,DevInfoData,SPDRP_SERVICE);
//获取本地设备树中父节点的ID
GetParentID(
DevInfoData.DevInst,
ParentInstance,
tmpDevInfo.wstrParentInstanceID,
tmpDevInfo.wstrParentDeviceDesc
);
GetStorageInfo(
tmpDevInfo.wstrRing3Interface,
tmpDevInfo.dwStorageDeviceNumber,
tmpDevInfo.wstrStorageManagerName
);
dwDevIndex++;
DeviceVector.push_back(tmpDevInfo);
}while(bResult);
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return dwErrorCount;
}