2011-12-16 142 views
1

我想獲取Windows下的所有物理磁盤的列表,並且鏈接到this昨天的問題確實起作用,但它似乎沒有找到我未格式化的硬盤驅動器(雖然我不'不認爲它有所作爲,磁盤通過USB連接)。獲取物理磁盤路徑

是否有另一種解決方案來獲取所有連接硬盤的「\\。\ PhysicalDrive」名稱?

回答

0

對於任何人誰可能會遇到這個在未來的搜索,這是我最終來到了。請注意,有一些未定義的類型是外部庫的一部分或由我定義的,而不是Windows的一部分。例如nowideqDebug

的評論是至少可以這樣說,但對於函數調用交叉參考MSDN文檔應該讓你對你的方式。我們的目標是列出每個磁盤的每個列表,並獲取所需的信息,以便讓我獲得設備的HANDLE,並填充即插即用信息(設備描述/名稱)。

typedef struct _DISK_DRIVE_INFORMATION 
{ 
    std::string Path; 
    std::string FriendlyName; 
} DISK_DRIVE_INFORMATION; 

unsigned i; 
DWORD dwSize, dwPropertyRegDataType = SPDRP_PHYSICAL_DEVICE_OBJECT_NAME; 
CONFIGRET r; 
HDEVINFO hDevInfo; 
SP_DEVINFO_DATA DeviceInfoData; 
SP_DEVICE_INTERFACE_DATA interfaceData; 

TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN]; 
TCHAR szDesc[1024]; 

GUID HddClass; 
HddClass = GUID_DEVINTERFACE_DISK;//GUID_DEVCLASS_DISKDRIVE; 

// List all connected disk drives 
hDevInfo = SetupDiGetClassDevs (&HddClass, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 
if (hDevInfo == INVALID_HANDLE_VALUE) 
    return; 

// Find the ones that are driverless 
for (i = 0; ; i++) 
{ 
    DeviceInfoData.cbSize = sizeof (DeviceInfoData); 
    // Get the next device info 
    if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) 
     break; 
    interfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); 
    // Get the next device interface 
    if (!SetupDiEnumInterfaceDevice(hDevInfo, NULL, &HddClass, i, &interfaceData)) 
    { 
     break; 
    } 

    // Get the device ID 
    r = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0); 
    if (r != CR_SUCCESS) 
     continue; 

    // To add to the vector 
    DISK_DRIVE_INFORMATION AddToVector; 

    DWORD requiredSize = 0; 

    // Get the path 
    SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, NULL, NULL, &requiredSize, NULL); 
    SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize); 

    data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); 


    if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &interfaceData, data, requiredSize, NULL, NULL)) 
    { 
     continue; 
    } 

    AddToVector.Path = nowide::convert(std::wstring(data->DevicePath)); 
    qDebug("Disk path: %s", AddToVector.Path.c_str()); 

    // Friendly name (e.g. SanDisk Cruzer USB...) 
    SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, 
             &dwPropertyRegDataType, (BYTE*)szDesc, 
             sizeof(szDesc), // The size, in bytes 
             &dwSize); 
    AddToVector.FriendlyName = nowide::convert(std::wstring((TCHAR*)szDesc)); 
    qDebug("Friendly name: %s", AddToVector.FriendlyName.c_str()); 

    OutVector.push_back(AddToVector); 
    delete data; 
} 
2

您可以使用SetupDi API列出「DISK」類中的所有設備。 (這將是在設備管理器中顯示相同的列表)

+0

這似乎是完美的工作,但你知道任何樣品在這種情況下可以工作嗎?我正在看[這個](http://stackoverflow.com/questions/3438366/setupdigetdeviceproperty),並將「USB」更改爲NULL以列出所有設備,並列出了我想要的所有內容,但似乎已有是一種更簡單的方法,並且我不確定如何將ID轉換爲要使用的GUID以獲取物理驅動器路徑。我會嘗試做更多的狩獵,以查看我是否可以找到有關如何正確使用此API的更多信息... – Lander 2011-12-17 00:54:24

0

或者你可以使用WMI ...

#include <comutil.h> 
#pragma comment(lib, "comsuppd.lib") 
#pragma comment(lib, "comsuppwd.lib") 
#define _WIN32_DCOM 
#include <wbemcli.h> 
#pragma comment(lib, "wbemuuid.lib") 

#include <string> 
#include <vector> 

using namespace std; 

IWbemLocator* pWbemLoc; 
IWbemServices* pWbemSvc; 

bool ReleaseWMI() 
{ 
    if (pWbemSvc != NULL) 
     pWbemSvc->Release(); 
    pWbemSvc = NULL; 
    if (pWbemLoc != NULL) 
     pWbemLoc->Release(); 
    pWbemLoc = NULL; 

    CoUninitialize(); 

    return true; 
} 

bool InitWMI() 
{ 
    HRESULT hr; 
    hr = CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hr)) 
     return false; 

    hr = CoInitializeSecurity(
     NULL, 
     -1, 
     NULL, 
     NULL, 
     RPC_C_AUTHN_LEVEL_DEFAULT, 
     RPC_C_IMP_LEVEL_IMPERSONATE, 
     NULL, 
     EOAC_NONE, 
     NULL); 
    if (FAILED(hr)) 
     return false; 

    HRESULT hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*) &pWbemLoc); 
    if(FAILED(hres)) 
    { 
     ReleaseWMI(); 
     return false; 
    } 

    hres = pWbemLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pWbemSvc); 
    if(FAILED(hres)) 
    { 
     ReleaseWMI(); 
     return false; 
    } 

    hres = CoSetProxyBlanket(pWbemSvc, 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)) 
    { 
     ReleaseWMI(); 
     return false; 
    } 

    return true; 
} 

struct diskInfo 
{ 
    wstring deviceId; 
    wstring freeSpace; 
}; 

wstring GetProperty(IWbemClassObject* pclsObj, const wstring &property) 
{ 
    wstring retVal(L""); 
    VARIANT vtProp; 
    VariantInit(&vtProp); 
    HRESULT hr; 
    hr = pclsObj->Get(property.c_str(),0,&vtProp,0,0); 
    if (!FAILED(hr)) 
    { 
     VARIANT vtBstrProp; 
     VariantInit(&vtBstrProp); 
     hr = VariantChangeType(&vtBstrProp, &vtProp, 0, VT_BSTR); 
     if (!FAILED(hr)) 
     { 
      retVal = vtBstrProp.bstrVal; 
     } 
     VariantClear(&vtBstrProp); 
    } 
    VariantClear(&vtProp); 

    return retVal; 
} 

bool QueryWMI(_bstr_t query, vector<diskInfo> &disks) 
{ 
    bool bRet = false; 

    HRESULT hres; 
    IEnumWbemClassObject* pEnumerator = NULL; 
    IWbemClassObject* pclsObj = NULL; 

    if(pWbemSvc) 
    { 
     hres = pWbemSvc->ExecQuery(bstr_t("WQL"), query, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); 
     if(!FAILED(hres)) 
     { 
      ULONG uReturn = 0; 
      while(pEnumerator) 
      { 
       HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 
       if(uReturn == 0) 
        break; 
       diskInfo d; 
       d.deviceId = GetProperty(pclsObj, L"DeviceID"); 
       d.freeSpace = GetProperty(pclsObj, L"FreeSpace"); 
       disks.push_back(d); 
       bRet = true; 
      } 
      if(pclsObj != NULL) 
       pclsObj->Release(); 
      if(pEnumerator != NULL) 
       pEnumerator->Release(); 
     } 
    } 

    return bRet; 
} 

void main() 
{ 
    InitWMI(); 
    vector<diskInfo> d; 
    bool ret = QueryWMI(bstr_t("SELECT * FROM Win32_LogicalDisk WHERE DriveType=3"), d); 
    ReleaseWMI(); 
}