您的位置:首页 > 其它

手机接入检测及驱动安装判断

2014-08-31 08:02 246 查看
#pragma once

#include <string>
#include <vector>
#include <set>

#include <windows.h>
#include <Setupapi.h>
#include <cfgmgr32.h>

#pragma comment(lib, "Setupapi.lib")

typedef std::set<std::wstring>  set_wstring;

//
// device operation definitions
//

int detect_phone_device(const std::set<std::wstring>& phone_compatible_ids,
const std::set<std::wstring>& phone_hardware_ids,
std::wstring& phone_instance_id);
bool is_device_driver_installed(const std::wstring &instance_id);

//////////////////////////////////////////////////////////////////////////
//  Implementions
//////////////////////////////////////////////////////////////////////////
int detect_phone_device(const std::set<std::wstring>& phone_compatible_ids,
const std::set<std::wstring>& phone_hardware_ids,
std::wstring& phone_instance_id)
{

DWORD rc = -1;
//获取设备信息句柄
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, L"USB" ,NULL,DIGCF_ALLCLASSES|DIGCF_PRESENT);
//获取设备信息数据
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//对USB设备集进行枚举
std::vector<std::wstring> compatible_ids;
for(int i = 0;SetupDiEnumDeviceInfo(hDevInfo,i,&deviceInfoData);i++)
{
std::wstring compatible_id;

//首先获取兼容id
DWORD dataType= 0;
DWORD buffSize = 0;
rc = SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_COMPATIBLEIDS,&dataType,NULL,buffSize,&buffSize);
if(!rc){
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
//return rc;
continue;
}
LPTSTR szCompatibleID = (LPTSTR)LocalAlloc(LPTR,buffSize+1);
rc = SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_COMPATIBLEIDS,&dataType,(PBYTE)szCompatibleID ,buffSize,&buffSize);
//szCompatibleID  即是兼容ID
compatible_id = szCompatibleID;
LocalFree(szCompatibleID);

compatible_ids.push_back(compatible_id);

//通常情况下,如果兼容ID等于"usb\\class_ff&subclass_42" ,一般就可以直接知道属于是手机设备
//(但是兼容ID的大小写不确定)
if(phone_compatible_ids.find(compatible_id) != phone_compatible_ids.end()){
//兼容id号匹配成功,直接获取instance id
std::wstring instance_id;
LPTSTR szInstanceID = NULL;
DWORD iBuffSize = 0;
SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize );	//获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoData
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
return -1;
szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR));
SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize );	//获取实例ID
instance_id = szInstanceID;
LocalFree(szInstanceID);
phone_instance_id = instance_id;//copy to phone_instance_id

rc = 0;
return rc;
//break;
}
}

//如果 兼容ID 不是 "usb\\class_ff&subclass_42" ,则可以匹配硬件ID,获取硬件ID的方法和获取兼容ID的方法类似:
//硬件ID 的样子一般的格式是: VID_1234&PID_4321  (1234,4321根据设备有差异,其中VID代表Vendor ID(厂家ID) , PID代表Product ID(产品ID)),
//VID基本一个厂商. 这个需要收集,但是网上好像有一些VID_PID大全可以满足一般使用.
//(其中VID只能判断厂商,有些手机生产商也有别的设备产品,比如索尼有手机也有相机,所以需要进一步详细判断.

std::vector<std::wstring> hardware_ids;
for(int i = 0;SetupDiEnumDeviceInfo(hDevInfo,i,&deviceInfoData);i++)
{
std::wstring  hardware_id;

DWORD dataType= 0;
DWORD buffSize = 0;
rc = SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_HARDWAREID,&dataType,NULL,buffSize,&buffSize);
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
//return rc;
continue;
LPTSTR szHardwareID = (LPTSTR)LocalAlloc(LPTR,buffSize+1);
rc = SetupDiGetDeviceRegistryProperty(hDevInfo,&deviceInfoData,SPDRP_HARDWAREID,&dataType,(PBYTE)szHardwareID ,buffSize,&buffSize);
//szHardwareID 即是硬件ID
hardware_id = szHardwareID;
LocalFree(szHardwareID);
hardware_ids.push_back(hardware_id);

if(phone_hardware_ids.find(hardware_id) != phone_hardware_ids.end()){
//如果硬件id匹配成功,获取instance id
std::wstring instance_id;
LPTSTR szInstanceID = NULL;
DWORD iBuffSize = 0;
SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize );	//获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoData
int err = GetLastError();
if(err != ERROR_INSUFFICIENT_BUFFER)
return -1;
szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR));
SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize );	//获取实例ID
instance_id = szInstanceID;
LocalFree(szInstanceID);
phone_instance_id = instance_id;//copy to phone_instance_id

rc = 0;
return rc;
}

}

//手机设备要记录下该设备的 "实例ID" ,
//std::vector<std::wstring> instance_ids;
//for(int i = 0;SetupDiEnumDeviceInfo(hDevInfo,i,&deviceInfoData);i++)
//{
//	LPTSTR szInstanceID = NULL;
//	WORD iBuffSize = 0;
//	SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize );	//获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoData
//	int err = GetLastError();
//	if(err != ERROR_INSUFFICIENT_BUFFER)
//		return -1;
//	szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR));
//	SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize );	//获取实例ID
//	instance_ids.push_back(szInstanceID);
//	LocalFree(szInstanceID);
//}

rc = 0;
return rc;
}

//检查指定实例id号的设备驱动是否安装
bool is_device_driver_installed(const std::wstring &instance_id){
bool is_installed = false;
DEVINST deviceInstance;
if (CM_Locate_DevNode(&deviceInstance, const_cast<WCHAR*>(instance_id.c_str() ),CM_LOCATE_DEVNODE_NORMAL) == CR_SUCCESS)			//获取设备ID对应的设备实例句柄
{
DWORD status;
DWORD problemNumber;
//获取设备状态和设备状态细节
if (CM_Get_DevNode_Status(&status,&problemNumber,deviceInstance,0) == CR_SUCCESS)
{
if (!(status&DN_HAS_PROBLEM))	//判断设备是否存在问题,代表驱动已安装
{
//设备无异常,就是说驱动正常
is_installed = true;
}
else
{
if (problemNumber == CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD || problemNumber == CM_PROB_DRIVER_FAILED_LOAD)
{
//设备驱动加载不成功
is_installed = false;
}
else
{
//有不明原因,可以归结为没安装驱动
is_installed = false;
}
}
}

}

return is_installed;
}

以NOKIA 925T型号手机 的信息 ,调用测试:

set_wstring compatible_ids, hardware_ids;
compatible_ids.insert(L"USB\\MS_COMP_WINUSB");
compatible_ids.insert(L"USB\\Class_ff&SubClass_ff&Prot_ff");
compatible_ids.insert(L"USB\\Class_ff&SubClass_ff");
compatible_ids.insert(L"USB\\Class_ff");
//hardware ids
hardware_ids.insert(L"USB\\VID_0421&PID_0661&MI_03");
hardware_ids.insert(L"USB\\VID_0421&PID_0661&REV_0100&MI_03");

std::wstring phone_instance_id;
int rc = detect_phone_device(compatible_ids, hardware_ids, phone_instance_id);
bool is_installed = is_device_driver_installed(phone_instance_id);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: