tags:

views:

72

answers:

2

Hello, I want to know whether the disk that a given volume resides on is removable (CM_DEVCAP_REMOVABLE). Looking for pointers on win32.

Clarify: What I am really trying to find out is whether the disk that the volume resides on is connected on a port (eg. USB) that is external to the computer.

A: 

GetDriveType

Stack Overflow rejects GetDriveType because GetDriveType is only 12 characters long. However, Stack Overflow accepts the combination of GetDriveType with an accompanying complaint about Stack Overflow.

Windows programmer
Thanks, DRIVE_REMOVABLE returned by GetDriveType means removable media which is not the same as a device plugged into an external port. I am trying to find if SetupDiGetDeviceRegistryProperty() would return CM_DEVCAP_REMOVABLE for my drive. But can't make the connection between the drive letter and the inputs that SetupDiGetDeviceRegistryProperty() expects.
I also use GetDriveType, but beware that some USB sticks/drives may report a drive as being a FIXED drive. My Freecom HDD USB-powered hard-drive (which has a similar size as an IPod) is reported as being a FIXED drive. (it probably all depends on the USB driver).
Patrick
Win32 depends on the driver. The driver might depend on the device hardware and device firmware (some devices pretend to be CD drives in order to deliver the driver and only later present their real interface). The driver might depend on the BIOS, and the BIOS might or might not be telling the truth. Anyway, if you need to predict what SetupDiGetDeviceRegistryProperty() is going to return, maybe you have to call SetupDiGetDeviceRegistryProperty() to find out.
Windows programmer
+2  A: 

You can open the volume and issue IOCTL_STORAGE_QUERY_PROPERTY; this returns a STORAGE_DEVICE_DESCRIPTOR which has a RemovableMedia property. I believe this is the same as CM_DEVCAP_REMOVABLE (not 100% sure). At least it reports "fixed" USB flash drives as removable.

HANDLE hFile = CreateFile("\\\\.\\Z:", FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
    STORAGE_PROPERTY_QUERY StoragePropertyQuery;
    StoragePropertyQuery.PropertyId = StorageDeviceProperty;
    StoragePropertyQuery.QueryType = PropertyStandardQuery;
    BYTE Buffer[1024];
    if(DeviceIoControl(hFile, IOCTL_STORAGE_QUERY_PROPERTY, &SotragePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), Buffer, 1024, &BytesReturned, NULL))
    {
        PSTORAGE_DEVICE_DESCRIPTOR StorageDeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
        if(StorageDeviceDescriptor->RemovableMedia)
        {
            printf("Z: IS removable\n");
        }
        else
        {
            printf("Z: is NOT removable\n");
        }
    }
    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
}
Luke
Interesting. MSDN tells me that RemovableMedia means removable media not removable device, so just like GetDriveType it would fail to provide what the questioner needs. OK, that's what I get for reading too much.
Windows programmer
I think in this context the volume IS the media; the physical disk or drive the volume resides on is the device. I guess if a volume is removable then the device it resides on must also be removable. I'm not sure how this all is supposed to work, but this has been my observation.
Luke
A floppy disk is removable even when the floppy drive isn't. There used to be superfloppies called something like Jazz which were non-removable drives with removable media several gigabytes in size. So maybe in this context RemovableMedia means removable device, and if a device is removable then the device it is identical too must also be removable. This requires a strained reading of MSDN, so what else is new.
Windows programmer
From what I understand, CM_DEVCAP_REMOVABLE would be a property of the USB port that the device is plugged in to. That is, it tells whether the port is external, and hence any device plugged into that port is removable.Removable media on the other hand was originally for things like floppies that were removable but the floppy drive wasn't. Its confusing.Anyways, I believe Microsoft's recommendation for flash drives to not report themselves as "Removable Media".And what I am really trying to find out is "is the device connected on a port that is external to the computer?"
What do you mean by "a port that is external to the computer"? I can run a SATA cable from my motherboard to the back of my computer and hook up an external drive; the driver has no way of knowing this. What are you really trying to achieve? If you really want to know if the device is physically external to the computer then your best bet is probably to look at its BusType and make an assumption; i.e. if it is connected via USB or FireWire then it's a fairly safe bet that it is external.
Luke
Some of my notebook PCs have internal cameras that are connected via USB but not removable, and have DVD drives that are connected by SATA but are removable.
Windows programmer