WinAPI calls to access USB storage which has no drive letter?

后端 未结 3 1638
走了就别回头了
走了就别回头了 2021-02-15 15:18

I\'ve noticed, that some USB storage devices don\'t register in Windows as regular drives, in that they don\'t even get assigned a drive letter. Therefore, I can\'t apparently a

相关标签:
3条回答
  • 2021-02-15 15:50

    Yes. There are few cases a USB drive doesn't have a drive letter.

    1. Bluetooth device, USB camera doesnt have drive letter. but this is not your case, since you mentioned storage device.
    2. A USB storage device which is registered in PC not as a storage device. eg. USB MP3 player (MTP device) will be detected as Music Player and doesn't have a drive letter.

    I believe yours is case #2.

    In order to access files in a storage device, you need to force mount it as a storage device with drive letter. Unless you have a mount point, you cannot access the files i believe. This depends on the devices. Some devices (MTP) have internal settings to decide whether to detect as storage or not. You can explore the settings in the MTP device.

    Otherwise you need to force all the storage device to mount through code.

    0 讨论(0)
  • 2021-02-15 16:03

    If you're talking about a USB mass storage device without any assigned drive letter then it's just a volume without a mount point. You'll need to mount the volume before reading/writing it.

    You can use the Volume Management Functions :

    • FindFirstVolume and FindNextVolume to get the volumes GUID
    • GetVolumePathNamesForVolumeName to know if the volume is mounted (and get the mount point)
    • SetVolumeMountPoint to mount a volume

    Here is a quickly-written example in C that list all the existing volumes, mount the unmounted ones and show some information about each volume :

    char volumeID[256], volumePathName[256], volumeName[256], volumeFS[256];
    char newMountPoint[4] = " :\\";
    unsigned long volumeSerialNumber;
    unsigned long size;
    HANDLE handle = FindFirstVolume(volumeID, 256);
    do {
        printf("Volume GUID = %s\n", volumeID);
        GetVolumePathNamesForVolumeName(volumeID, volumePathName, 256, &size);
        if(strlen(volumePathName) == 0) {
            printf("Not mounted\n");
            newMountPoint[0] = firstFreeLetter();
            if(SetVolumeMountPoint(newMountPoint, volumeID)) {
                GetVolumePathNamesForVolumeName(volumeID, volumePathName, 256, &size);
                printf("Now mounted on %s\n", volumePathName);
            }
        }
        else {
            printf("Mounted on %s\n", volumePathName);
        }
        GetVolumeInformation(volumePathName, volumeName, 256, &volumeSerialNumber,
                             NULL, NULL, volumeFS, 256);
        printf("Volume name = %s, FS = %s, serial = %lu\n\n",
               volumeName, volumeFS, volumeSerialNumber);
    
    }while(FindNextVolume(handle, volumeID, 256));
    
    FindVolumeClose(handle);
    

    I deliberetely simplify this example, but a volume can have multiple mount points (volumePathName is actually a multi-string). It uses this function to get the first available letter (after 'C') to mount a drive :

    char firstFreeLetter() {
        unsigned long freeLetters = GetLogicalDrives();
        if(freeLetters < 4) return 0;
        char letter = 'C';
        for(unsigned long i=4; (freeLetters & i) != 0; ++letter, i <<= 1);
        return letter;
    }
    
    0 讨论(0)
  • 2021-02-15 16:05

    If you're talking about mobile devices that appears like mounted volumes but without any mounted points, well they are called Windows Portable Devices and they are not mounted volumes.

    Windows doesn't access the file system directly, it only communicates with them through the Media Transfer Protocol (MTP) or Picture Transfert Protocol (PTP) and creates a shell namespace extension to present a virtual folder to the user.

    If you want to communicate with these kind of devices, then you most probably want to use the WPD API.

    0 讨论(0)
提交回复
热议问题