【问题标题】:Get Physical Disk Paths获取物理磁盘路径
【发布时间】:2011-12-16 23:27:14
【问题描述】:

我想获取 Windows 下所有物理磁盘的列表,并且昨天链接到 this 问题,这确实有效,但它似乎找不到我未格式化的硬盘驱动器(虽然我不认为不同的是,磁盘是通过 USB 连接的)。

是否有其他解决方案可以为所有连接的硬盘获取“\\.\PhysicalDrive”名称?

【问题讨论】:

    标签: c++ windows visual-c++


    【解决方案1】:

    您可以使用 SetupDi API 列出“磁盘”类中的所有设备。 (它将与设备管理器中显示的列表相同)

    【讨论】:

    • 这似乎可以完美运行,但是您知道在这种情况下可以使用的任何示例吗?我正在查看this 并将“USB”更改为 NULL 以列出所有设备,它列出了我想要的所有内容,但似乎必须有一种更简单的方法,我不确定如何转换用于获取物理驱动器路径的 GUID 的 ID。我会尝试做更多的搜索,看看我是否能找到更多关于如何正确使用这个 API 的信息......
    • 弄清楚如何仅列出磁盘驱动器(GUID 类 {4D36E967-E325-11CE-BFC1-08002BE10318}),现在是获取卷的 GUID 或物理驱动器路径的问题。
    • 好的,经过一些研究,我发现第一个评论中链接的示例并没有太远,但我应该枚举设备接口以获得在 CreateFile 中使用的正确路径功能。代码更接近于 here,除了使用“GUID_DEVINTERFACE_DISK”作为接口 GUID。感谢您带领我朝着正确的方向前进!
    【解决方案2】:

    对于任何可能在以后的搜索中遇到此问题的人,这就是我最终想出的。请注意,有一些未定义的类型是外部库的一部分或由我定义,而不是 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;
    }
    

    【讨论】:

      【解决方案3】:

      或者你可以使用 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();
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-01
        • 2011-07-22
        • 2017-02-11
        • 2013-02-25
        • 1970-01-01
        • 2018-10-24
        • 1970-01-01
        • 2019-03-11
        • 2011-08-30
        相关资源
        最近更新 更多