获取硬盘、U盘数量和名称

获取硬盘、U盘数量和名称,使用 SetupDiEnumDeviceInfo 枚举磁盘设备,再通过 SetupDiGetDeviceRegistryProperty 获取 SPDRP_REMOVAL_POLICY 属性,确认是不是可移动设备,然后再获取名字就好了。

#include "SetupAPI.h"
#pragma comment(lib,"Setupapi.lib")
INT GetHardDiskNum(BOOL bReMov = FALSE)
{
    GUID objGuid = {0};
    DWORD dwSize = 0;
    if(SetupDiClassGuidsFromName("DiskDrive",&objGuid,1,&dwSize) == FALSE)
        return 0;
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&objGuid,0,0,DIGCF_PRESENT | DIGCF_PROFILE);//'根据串口GUID获取设备句柄  
    if(INVALID_HANDLE_VALUE == hDevInfo)
        return 0;
    int count = 0;
    for(int i = 0;;++i)
    {
        SP_DEVINFO_DATA  objSpdd = {0};//'根据设备句柄检举包含的设备  
        objSpdd.cbSize = sizeof(objSpdd);
        if(!SetupDiEnumDeviceInfo(hDevInfo,i,&objSpdd))
            break;
        BYTE PropertyBuffer[MAX_PATH] = {0};//获取SPDRP_REMOVAL_POLICY属性  3是可移动设备。。
        if(!SetupDiGetDeviceRegistryProperty(hDevInfo,&objSpdd,SPDRP_REMOVAL_POLICY,0,PropertyBuffer,MAX_PATH,&dwSize))
            break;
        if(bReMov ? PropertyBuffer[0] != 3 : PropertyBuffer[0] == 3)    //用这个判断是不是可移动的,3是可移动
            continue;
        else
        {
            ZeroMemory(PropertyBuffer,MAX_PATH);
            if(!SetupDiGetDeviceRegistryProperty(hDevInfo,&objSpdd,SPDRP_FRIENDLYNAME,0,PropertyBuffer,MAX_PATH,&dwSize)) // 根据dwIndex设备句柄请求FRIENDLYNAME访问 
                break;
            ++count;
            OutputDebugString((bReMov ? CString("可移动:") : CString("不可移动:")) + CString(PropertyBuffer));
        }
    }
    return count;
}

使用:

    CString s;
    s.Format("可移动数量:%d\n不可移动数量:%d",GetHardDiskNum(TRUE),GetHardDiskNum());
    AfxMessageBox(s);

效果:
获取硬盘、U盘数量和名称_第1张图片

更新:以上代码不能分辨本地硬盘和移动硬盘,以下代码可判断是否是USB设备,结合起来就可以判断了:

    if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &objSpdd, SPDRP_ENUMERATOR_NAME, 0, PropertyBuffer, MAX_PATH, &dwSize)) // 根据dwIndex设备句柄请求FRIENDLYNAME访问 
        continue;
    if (strncmp((char *)PropertyBuffer, "USBSTOR", strlen("USBSTOR")) == 0) //屏蔽USB设备
        continue;
  • 方法二:
    使用CreateFile创建磁盘设备的句柄,然后向驱动发送控制码查询设备总线类型,当总线类型时BusTypeUsb时,可确定是USB设备,用此代码可判断是本地硬盘还是U盘。
    char physicaldriver[256] = {0};
    for(int i = 0;i < 8;i++)
    {
        sprintf_s(physicaldriver,"\\\\.\\PHYSICALDRIVE%d",i);
        HANDLE handle = CreateFile(physicaldriver,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,NULL);
        if(handle != INVALID_HANDLE_VALUE)
        {
            STORAGE_DESCRIPTOR_HEADER *pDevDescHeader;
            STORAGE_DEVICE_DESCRIPTOR *pDevDesc;
            DWORD devDescLength;
            STORAGE_PROPERTY_QUERY query;
            query.PropertyId = StorageDeviceProperty;
            query.QueryType = PropertyStandardQuery;
            pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER));
            if(!pDevDescHeader)
            {
                CloseHandle(handle);
                handle = INVALID_HANDLE_VALUE;
                continue;
            }
            DWORD dwBytes;
            if(DeviceIoControl(handle,IOCTL_STORAGE_QUERY_PROPERTY,&query,sizeof(query),pDevDescHeader,sizeof(STORAGE_DESCRIPTOR_HEADER),&dwBytes,NULL))    //剔除移动储存设备
            {
                devDescLength = pDevDescHeader->Size;
                pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(devDescLength);
                if(!pDevDesc)
                {
                    free(pDevDescHeader);
                    continue;
                }
                if(DeviceIoControl(handle,IOCTL_STORAGE_QUERY_PROPERTY,&query,sizeof query,pDevDesc,devDescLength,&dwBytes,NULL))
                {
                    CString s;
                    s.Format("%s %d",physicaldriver,pDevDesc->BusType);
                    AfxMessageBox(s);
                }
                free(pDevDescHeader);
                free(pDevDesc);
            }
            CloseHandle(handle);
            handle = INVALID_HANDLE_VALUE;
        }
    }

你可能感兴趣的:(windows,API,u盘,硬盘)