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

后端 未结 3 1647
走了就别回头了
走了就别回头了 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 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;
    }
    

提交回复
热议问题