2013-10-09 57 views
1

我想使用WMI獲取計算機上除活動分區以外的所有分區的系統盤符,這是我迄今爲止所提出的(我不知道如何獲得驅動器盤符&如何檢查,如果他們都HDD或系統驅動,所以我不要在這裏任何CD-ROM):在vC++中使用WMI枚舉分區驅動器盤符

std::vector<CString> GetPartitionsVector(bool bCoInit = false ) 
{ 
    std::vector<CString> partVect; 
    HRESULT hres = NULL; 
    if(bCoInit) 
    { 

     hres = CoInitializeEx(0, COINIT_MULTITHREADED); 
     if (FAILED(hres)) 
     { 
      goto end_routine; 
     } 

     hres = CoInitializeSecurity(
      NULL, 
      -1,       // COM authentication 
      NULL,      // Authentication services 
      NULL,      // Reserved 
      RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication 
      RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation 
      NULL,      // Authentication info 
      EOAC_NONE,     // Additional capabilities 
      NULL       // Reserved 
      ); 


     if (FAILED(hres)) 
     { 
      goto end_routine; 
     } 
    } 


    IWbemLocator *pLoc = NULL; 

    hres = CoCreateInstance(
     CLSID_WbemLocator,    
     0, 
     CLSCTX_INPROC_SERVER, 
     IID_IWbemLocator, (LPVOID *) &pLoc); 

    if (FAILED(hres)) 
    { 
     goto end_routine; 
    } 


    IWbemServices *pSvc = NULL; 

    hres = pLoc->ConnectServer(
     _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace 
     NULL,     // User name. NULL = current user 
     NULL,     // User password. NULL = current 
     0,      // Locale. NULL indicates current 
     NULL,     // Security flags. 
     0,      // Authority (e.g. Kerberos) 
     0,      // Context object 
     &pSvc     // pointer to IWbemServices proxy 
     ); 

    if (FAILED(hres)) 
    { 
     goto end_routine; 
    } 

    hres = CoSetProxyBlanket(
     pSvc,      // Indicates the proxy to set 
     RPC_C_AUTHN_WINNT,   // RPC_C_AUTHN_xxx 
     RPC_C_AUTHZ_NONE,   // RPC_C_AUTHZ_xxx 
     NULL,      // Server principal name 
     RPC_C_AUTHN_LEVEL_CALL,  // RPC_C_AUTHN_LEVEL_xxx 
     RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx 
     NULL,      // client identity 
     EOAC_NONE     // proxy capabilities 
     ); 

    if (FAILED(hres)) 
    { 
     goto end_routine; 
    } 

    // Step 6: -------------------------------------------------- 
    // Use the IWbemServices pointer to make requests of WMI ---- 

    // For example, get the name of the operating system 
    IEnumWbemClassObject* pEnumerator = NULL; 
    hres = pSvc->ExecQuery(
     bstr_t("WQL"), 
     bstr_t("SELECT * FROM Win32_DiskPartition"),    // Win32_DiskPartition 
     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
     NULL, 
     &pEnumerator); 

    if (FAILED(hres)) 
    { 
     pSvc->Release(); 
     pLoc->Release(); 

     goto end_routine; 
    } 

    // Step 7: ------------------------------------------------- 
    // Get the data from the query in step 6 ------------------- 

    IWbemClassObject *pclsObj; 
    ULONG uReturn = 0; 

    while (pEnumerator) 
    { 
     HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
      &pclsObj, &uReturn); 

     if(0 == uReturn) 
     { 
      break; 
     } 

     VARIANT vtProp; 

     // Get the value of the Name property 
     hr = pclsObj->Get(L"BootPartition", 0, &vtProp, 0, 0); 

     if(!vtProp.boolVal)  //if this is not boot partition, get some more 
     { 
      hr = pclsObj->Get(L"BootPartition", 0, &vtProp, 0, 0); 
      if(FAILED(hr)) 
      { 
       //log here 
      } 
      hr = pclsObj->Get(L"SystemName", 0, &vtProp, 0, 0); 
      if(!FAILED(hr)) 
       partVect.push_back(vtProp.bstrVal); 
     } 




     VariantClear(&vtProp); 
     pclsObj->Release(); 
    } 

    // Cleanup 
    // ======== 

    pSvc->Release(); 
    pLoc->Release(); 
    pEnumerator->Release(); 



end_routine: 

    if(bCoInit) 
    { 
     CoUninitialize(); 
    } 
    return partVect; 
} 
+0

你有使用WMI? [此鏈接](http://msdn.microsoft.com/en-us/library/cc542456(VS.85).aspx)使用卷管理API執行此操作。 –

+0

搜索「WMI驅動器號」的MSDN也很有用。 –

+0

這看起來不錯,但我一直在做另一種方式..不一定是你建議的和我的應用程序在測試中崩潰,因爲某些系統缺少某些DLL ......使用WMI不會導致應用程序崩潰,所以這就是爲什麼我選擇這種方式,我也會嘗試你所建議的方式。 – AlexandruC

回答

1

要關聯由Win32_DiskPartition WMI類返回的分區列表一個你必須使用的驅動器字母(一個邏輯磁盤)遵循這個順序。

  1. 首先調用Win32_DiskDrive
  2. 然後查詢使用DeviceID屬性和Win32_DiskDriveToDiskPartition協會類的Win32_DiskPartition所有實例。
  3. 現在使用Win32_DiskPartition.DeviceID屬性和Win32_LogicalDiskToPartition關聯類調用表示分區的WMI類Win32_LogicalDisk
  4. 最後,您可以從Win32_LogicalDisk.DeviceID屬性獲取驅動器號。

這裏有一套如何使用ASSOCIATORS OF WMI句子的示例。