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

来源:互联网 发布:美股模拟炒股软件 编辑:程序博客网 时间:2024/05/01 14:03
#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;//首先获取兼容idDWORD 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  即是兼容IDcompatible_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 idstd::wstring instance_id;LPTSTR szInstanceID = NULL;DWORD iBuffSize = 0;SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize );//获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoDataint err = GetLastError();if(err != ERROR_INSUFFICIENT_BUFFER)return -1; szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR));SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize );//获取实例IDinstance_id = szInstanceID;LocalFree(szInstanceID);phone_instance_id = instance_id;//copy to phone_instance_idrc = 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 即是硬件IDhardware_id = szHardwareID;LocalFree(szHardwareID);hardware_ids.push_back(hardware_id);if(phone_hardware_ids.find(hardware_id) != phone_hardware_ids.end()){//如果硬件id匹配成功,获取instance idstd::wstring instance_id;LPTSTR szInstanceID = NULL;DWORD iBuffSize = 0;SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize,&iBuffSize );//获取实例ID的buff需要的大小, hDevInfoSet和deviceInfoDataint err = GetLastError();if(err != ERROR_INSUFFICIENT_BUFFER)return -1; szInstanceID = (LPTSTR)LocalAlloc(LPTR,buffSize*sizeof(WCHAR));SetupDiGetDeviceInstanceId(hDevInfo,&deviceInfoData,szInstanceID ,iBuffSize ,&iBuffSize );//获取实例IDinstance_id = szInstanceID;LocalFree(szInstanceID);phone_instance_id = instance_id;//copy to phone_instance_idrc = 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 idshardware_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);



0 0