C++ 获取物理磁盘路径

C++ 获取物理磁盘路径,c++,windows,visual-c++,C++,Windows,Visual C++,我想得到一份Windows下所有物理磁盘的列表,昨天被链接到了问题“哪个可用”,但它似乎找不到我的未格式化硬盘(尽管我不认为这有什么区别,但磁盘是通过USB连接的) 是否有其他解决方案可以为所有连接的硬盘获取“\\.\PhysicalDrive”名称?您可以使用SetupDi API列出“磁盘”类中的所有设备。(它将与设备管理器中显示的列表相同)或者您可以使用WMI #include <comutil.h> #pragma comment(lib, "comsuppd.lib") #

我想得到一份Windows下所有物理磁盘的列表,昨天被链接到了问题“哪个可用”,但它似乎找不到我的未格式化硬盘(尽管我不认为这有什么区别,但磁盘是通过USB连接的)


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

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

或者您可以使用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();
}
#包括
#pragma注释(lib,“comsuppd.lib”)
#pragma注释(lib,“comsupwd.lib”)
#定义\u WIN32\u DCOM
#包括
#pragma注释(lib,“wbemuid.lib”)
#包括
#包括
使用名称空间std;
IWbemLocator*pWbemLoc;
IWbemServices*pWbemSvc;
bool ReleaseWMI()
{
如果(pWbemSvc!=NULL)
pWbemSvc->Release();
pWbemSvc=NULL;
如果(pWbemLoc!=NULL)
pWbemLoc->Release();
pWbemLoc=NULL;
coninitialize();
返回true;
}
bool InitWMI()
{
HRESULT-hr;
hr=coinitializex(0,COINIT\u多线程);
如果(失败(小时))
返回false;
hr=共同初始化安全性(
无效的
-1,
无效的
无效的
RPC_C_AUTHN_LEVEL_默认值,
RPC_C_IMP_LEVEL_模拟,
无效的
无,
无效);
如果(失败(小时))
返回false;
HRESULT hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_服务器,IID_IWbemLocator,(LPVOID*)和pWbemLoc);
如果(失败(hres))
{
releasewimi();
返回false;
}
hres=pWbemLoc->ConnectServer(\u bstr\u t(L“ROOT\\CIMV2”)、NULL、NULL、NULL、WBEM\u标志\u CONNECT\u USE\u MAX\u WAIT、NULL、NULL和pWbemSvc);
如果(失败(hres))
{
releasewimi();
返回false;
}
hres=CoSetProxyBlanket(pWbemSvc、RPC_C_AUTHN_WINNT、RPC_C_AUTHZ_NONE、NULL、RPC_C_AUTHN_LEVEL_CALL、RPC_IMP_LEVEL_IMPERSONATE、NULL、EOAC_NONE);
如果(失败(hres))
{
releasewimi();
返回false;
}
返回true;
}
结构磁盘信息
{
wstring设备id;
wstring自由空间;
};
wstring GetProperty(IWbemClassObject*pclsObj,常量wstring&property)
{
wstring retVal(L“);
变异vtProp;
VariantInit(&vtProp);
HRESULT-hr;
hr=pclsObj->Get(property.c_str(),0,&vtProp,0,0);
如果(!失败(hr))
{
变异vtbstrop;
VariantInit(&vtbstrop);
hr=变量更改类型(&vtbstrop,&vtProp,0,VT_BSTR);
如果(!失败(hr))
{
retVal=vtbstrop.bstrVal;
}
VariantClear(&vtbstrop);
}
VariantClear(&vtProp);
返回返回;
}
bool QueryWMI(\u bstr\t查询、向量和磁盘)
{
布尔-布雷特=假;
HRESULT hres;
IEnumWbemClassObject*pEnumerator=NULL;
IWbemClassObject*pclsObj=NULL;
if(pWbemSvc)
{
hres=pWbemSvc->ExecQuery(bstr_t(“WQL”)、query、WBEM_标志、仅转发、WBEM_标志、立即返回、NULL和pEnumerator);
如果(!失败(hres))
{
ULONG uReturn=0;
while(pEnumerator)
{
HRESULT hr=pEnumerator->Next(WBEM_INFINITE,1,&pclsObj,&uReturn);
如果(uReturn==0)
打破
diskd;
d、 deviceId=GetProperty(pclsObj,L“deviceId”);
d、 freeSpace=GetProperty(pclsObj,L“freeSpace”);
磁盘。推回(d);
bRet=真;
}
如果(pclsObj!=NULL)
pclsObj->Release();
if(pEnumerator!=NULL)
pEnumerator->Release();
}
}
返回布雷特;
}
void main()
{
InitWMI();
载体d;
bool ret=QueryWMI(bstr_t(“从Win32_LogicalDisk中选择*,其中DriveType=3”),d);
releasewimi();
}

对于任何在未来的搜索中可能遇到这种情况的人,以下是我最终得出的结论。请注意,有一些未定义的类型是外部库的一部分或由我定义的,而不是Windows的一部分。e、 g.
nowide
qDebug

至少可以说,注释很差,但是交叉引用函数调用的MSDN文档应该会让您走上正轨。目标是列出每个磁盘的每个列表,并获得所需的信息,以使我能够获得设备的
句柄
,并填充即插即用信息(设备描述/名称)


这似乎可以很好地工作,但您知道在这种情况下有任何样本可以工作吗?我正在查看并将“USB”更改为NULL以列出所有设备,它列出了我希望列出的所有设备,但似乎必须有一种更简单的方法,而且我不确定如何将ID转换为GUID以获得物理驱动器路径。我将尝试进行更多搜索,看看是否可以找到有关如何正确使用此API的更多信息…了解了如何仅列出磁盘驱动器(GUID类{4D36E967-E325-11CE-BFC1-08002BE10318}),现在是获取卷的GUID或物理驱动器路径的问题。好的,经过一些研究,我发现第一条评论中链接的示例并不遥远,但我应该枚举设备接口,以获得在CreateFile函数中使用的正确路径。代码更接近实际情况,除了使用“GUID\u deviceinterface\u DISK”作为接口GUID。谢谢你给我指引了正确的方向!
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;
}