Find current connected USB storage path in C++

前端 未结 2 1419
無奈伤痛
無奈伤痛 2021-01-16 10:14

My Env:

Qt 5.3.1
Windows 10

I need to find the path of mounted USB storage devices. Through the path, I can copy the files via Qt. I know t

2条回答
  •  生来不讨喜
    2021-01-16 10:38

    First you need to get removable drives:

    void EnumUsbDrives() {
        DWORD drv = ::GetLogicalDrives();
        if (drv == 0) return;
    
        DWORD mask = 1;
        TCHAR szDrive[] = _TEXT("?:\\");
    
        for (uint_t i = 0; i < ('Z' - 'A' + 1); i++, mask <<= 1) {
            if (drv & mask) {
                szDrive[0] = (TCHAR)(_T('A') + i);
                if (::GetDriveType(szDrive) == DRIVE_REMOVABLE) {
                    bool bUSB = IsDriveUSB(szDrive);
                    if (bUSB) {
                        // Time do to something useful
                    }
                }
            }
        }
    }
    

    Function IsDriveUSB is a bit more complicated. I have teared it from an in-house library; the function uses custom helper classes xregistry and xstring_nocase. Their purpose is pretty obvious, I believe you will have no trouble replacing it with other similar classes or API calls.

    bool IsDriveUSB (LPCTSTR szDrive) throw() {
        TCHAR szLogicalDrive[] = _TEXT("\\\\.\\x:");
        szLogicalDrive[4] = szDrive[0];
        HANDLE hDrive = ::CreateFile(szLogicalDrive, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
        if (hDrive == INVALID_HANDLE_VALUE) return false;       // Can't open drive so we have to assume the drive is fixed
    
        VOLUME_DISK_EXTENTS vde;
        DWORD dwBytesReturned = 0;
        BOOL br = ::DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &vde, sizeof(vde), &dwBytesReturned, NULL);
        ::CloseHandle(hDrive);
        if (!br) return false;      // Can't get extents info so we have to assume the drive is fixed
    
        if (vde.NumberOfDiskExtents != 1) return false;
        ULONG uPhysDrive = vde.Extents[0].DiskNumber;
        TCHAR szPhysDrive[16];
        _stprintf(szPhysDrive, _TEXT("%u"), uPhysDrive);
    
        try {
            xregistry rk(HKEY_LOCAL_MACHINE, OS.Is64bit());
            rk.open(_TEXT("SYSTEM\\CurrentControlSet\\services\\Disk\\Enum"), KEY_QUERY_VALUE);
            if (!rk.value_exists(szPhysDrive)) return false;
            xstring_nocase strInterface = rk.get_string(szPhysDrive).substring(0, 7);
            return strInterface == _TEXT("USBSTOR");
        }
        catch (...) {
            return false;
        }
    }
    

提交回复
热议问题