手机接入检测及驱动安装判断
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);
相关文章推荐
- 浏览器判断检测手机中是否安装了ios/android客户端程序
- 仿91助手的PC与android手机通讯(3) --- 检测是否已经安装驱动
- 仿91助手的PC与android手机通讯(3) --- 检测是否已经安装驱动
- android手机安装驱动后,adb device无法识别设备
- Linux 安装android手机驱动
- 判断android手机当前是否接入网络
- 检测Android手机是否被安装了Carrier IQ监控的应用
- 判断android手机当前是否接入网络
- ubuntu下android手机驱动安装
- 检测手机中是否安装对应的应用
- 检测.net framework版本,判断是否安装了service pack
- 获取手机上apk文件信息类,主要是判断是否安装再手机上了,安装的版本比较现有apk版本信息
- 简单安装l7驱动与手机伴侣MPT(Mobile Phone Tools)使用步骤
- Android中让应用程序自动安装到手机内存及判断应用程序是否安装在SDCard中
- android检测手机是否有某个应用以及启动安装另一个应用的问题
- 教你怎么判断手机是否已安装某程序,然后调用该程序
- 检测客户端是否安装 Silverlight 插件和判断IE是否安装或支持Silverlight(限IE)
- 检测客户端是否安装 Silverlight 插件和判断IE是否安装或支持Silverlight(限IE)
- 教你怎么判断手机是否已安装某程序,然后调用该程序
- Android如何判断应用程序是安装在手机内存中还是SD卡