void DrivesEnumerator::setDriveInfoEx(std::vector<DriveInfo>& rez,bool hasUSB){ if(rez.empty()){ return; } HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); //COINIT_APARTMENTTHREADED bool uninit = (S_OK==hres); IWbemLocator *pLoc = NULL; IWbemServices *pSvc = NULL; IEnumWbemClassObject* pEnumerator = NULL; IWbemClassObject *pclsObj = NULL; std::map<unicodeString,int> mm; //PnP-SN,index do{ if(uninit){ hres = CoInitializeSecurity(NULL,-1,NULL,NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL,EOAC_NONE,NULL); if(FAILED(hres)){ break; } } hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID*)&pLoc); if(FAILED(hres)){ break; } hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc); if(FAILED(hres)){ break; } hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if(FAILED(hres)){ break; } VARIANT v; HRESULT hr; //retrieving Drive's name hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_DiskDrive"), //Win32_DiskDrive, PhysicalMedia , Win32_DiskDrivePhysicalMedia WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,&pEnumerator); if(FAILED(hres)){ break; } while(pEnumerator){ ULONG uReturn = 0; hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if(0 == uReturn){ break; } if(S_OK == (hr = pclsObj->Get(L"Index", 0, &v, 0, 0))){ for(unsigned i=0;i<rez.size();++i){ adf::gui::DriveInfo& r = rez[i]; if(r.driveNumber() == (int)v.uintVal){ if(S_OK == (hr = pclsObj->Get(L"Model", 0, &v, 0, 0))){ r._name = v.bstrVal; VariantClear(&v); } if(!hasUSB){ break; } if(S_OK != (hr = pclsObj->Get(L"InterfaceType", 0, &v, 0, 0))){ break; } //SCSI,HDC,IDE,USB,1394 bool ok = (unicodeString(v.bstrVal)==STRING_CONST("USB")); VariantClear(&v); if(!ok){ break; } if(S_OK != (hr = pclsObj->Get(L"PNPDeviceID", 0, &v, 0, 0))){ break; } unicodeString s = (v.bstrVal); VariantClear(&v); unicodeString::size_type ps, pos = s.rfind(UNICHR('\\')); if(unicodeString::npos!=pos){ ps = s.find(UNICHR('&'),++pos); if(unicodeString::npos!=ps){ mm[unicodeString(s.substr(pos,ps-pos))] = i; } } break; } } VariantClear(&v); } } if(!hasUSB){ break; } if(pEnumerator){ pEnumerator->Release(); } //retrieving USB VendorID,ProductID hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_USBControllerDevice"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,&pEnumerator); if(FAILED(hres)){ break; } while(pEnumerator){ ULONG uReturn = 0; hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if(0 == uReturn){ break; } if(S_OK == (hr = pclsObj->Get(L"Dependent", 0, &v, 0, 0))){ unicodeString s = v.bstrVal; VariantClear(&v); //"USB\\VID_058F&PID_6387\\GXP25EUB" unicodeString str( STRING_CONST("=\"USB\\\\VID_") ); unicodeString::size_type ps, pos = s.find(str); if(pos==unicodeString::npos){ //extract VendorID, ProductID, SerialNumber(for searching) continue; } pos += str.size(); str = STRING_CONST("&PID_"); ps = s.find(str,pos); if(unicodeString::npos==ps){ continue; } unicodeString VID( s.substr(pos,ps-pos) ); ps += str.size(); //extract PID str = STRING_CONST("\\\\"); pos = s.find(str,ps); if(unicodeString::npos==ps){ continue; } unicodeString PID( s.substr(ps,pos-ps) ); pos += str.size(); if(unicodeString::npos != s.find(STRING_CONST("&"),pos)){ continue; } //extract SerialNumber ps = s.find(STRING_CONST("\""),pos); if(unicodeString::npos==ps){ continue; } unicodeString SN( s.substr(pos,ps-pos) ); //set founded information std::map<unicodeString,int>::iterator it = mm.find(SN); if(it!=mm.end()){ DriveInfo& r = rez[it->second]; r._vendorID = VID; r._productID = PID; r._serial = SN; } } } }while(0); if(pSvc){ pSvc->Release(); } if(pLoc){ pLoc->Release(); } if(pEnumerator){ pEnumerator->Release(); } if(pclsObj){ pclsObj->Release(); } if(uninit){ CoUninitialize(); }}