32 out of 43 rated this helpful - Rate this topic

GetDriveType function

Applies to: desktop apps only

Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

To determine whether a drive is a USB-type drive, call SetupDiGetDeviceRegistryProperty and specify the SPDRP_REMOVAL_POLICY property.

Syntax

UINT WINAPI GetDriveType(
  __in_opt  LPCTSTR lpRootPathName
);

Parameters

lpRootPathName [in, optional]

The root directory for the drive.

A trailing backslash is required. If this parameter is NULL, the function uses the root of the current directory.

Return value

The return value specifies the type of drive, which can be one of the following values.

Return code/valueDescription
DRIVE_UNKNOWN
0

The drive type cannot be determined.

DRIVE_NO_ROOT_DIR
1

The root path is invalid; for example, there is no volume mounted at the specified path.

DRIVE_REMOVABLE
2

The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.

DRIVE_FIXED
3

The drive has fixed media; for example, a hard disk drive or flash drive.

DRIVE_REMOTE
4

The drive is a remote (network) drive.

DRIVE_CDROM
5

The drive is a CD-ROM drive.

DRIVE_RAMDISK
6

The drive is a RAM disk.

 

Requirements

Minimum supported client

Windows XP

Minimum supported server

Windows Server 2003

Header

FileAPI.h (include Windows.h);
WinBase.h on Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP (include Windows.h)

Library

Kernel32.lib

DLL

Kernel32.dll

Unicode and ANSI names

GetDriveTypeW (Unicode) and GetDriveTypeA (ANSI)

See also

GetDiskFreeSpace
Volume Management Functions

 

 

Send comments about this topic to Microsoft

Build date: 4/17/2012

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Determinig USB
To add on KayS' comments "To determine whether a drive is a USB-type drive, call SetupDiGetDeviceRegistryProperty and specify the SPDRP_REMOVAL_POLICY property." However the SetupDiSetDeviceRegistryProperty MSDN documentation (http://msdn.microsoft.com/en-us/library/windows/hardware/ff552169.aspx) states: "The following values are reserved for use by the operating system and cannot be used in the Property parameter: SPDRP_REMOVAL_POLICY" Thus, if one decides to use SPDRP_REMOVAL_POLICY, they will do so against Microsoft's own recommendations. Moreover, even if you use SPDRP_REMOVAL_POLICY (which, at least on Windows 7, appears to be working) you cannot use SPDRP_BUSTYPEGUID or SPDRP_LEGACYBUSTYPE with SetupDiGetDeviceRegistryProperty to determine the bus type, as these return an error indeed. All in all, one does not appear to be able to safely determine whether a drive is a USB-type without using an IOCTL (or checking whether the device interface path starts with "...USB..." which I wouldn't recommend).
detect if drive a flopy disk or a falsh
how i can detect if drive a flopy disk or falsh
Works for non-root paths, though softlinks too.
At least in Windows 7 (only thing I've tested on), GetDrivePath allows you to give the full path to a directory (but not a file) and will correctly report the type of drive that directory resides on, even if the directory is on a different drive/type to the root (e.g. because of a softlink along the way).

For example, if C:\moo\cow is a softlink pointing to R:\test, and R a removable drive, GetDrivePath(L"C:\\moo\\cow\\") will return DRIVE_REMOVABLE even though GetDrivePath(L"C:\\") would (typically) return DRIVE_FIXED.

(It would be good to have this guaranteed as part of the API contract/documentation in case it only works by accident right now. It's very useful, e.g. for making policy decisions about where to create temp files based on the type of drive a folder is on while working with links.)
This seems to work with VolumeGuids

MSDN says

The root directory for the drive. (This would be for ex. E:\ D:\ X:\ )

MSDN doesn't mention anything about passing a volume guid ex. \\?\Volume{2b294683-62aa-11de-9520-806d6172696f}\ the function in my tests is more than capable of determine the type by volume GUID. Just to let you know this can save you some time if you don't need to convert first.



(Tested with Windows XP)

This seems to work with UNC paths and device paths too
\\P2P\to150\
\\?\UNC\P2P\to150\
  \\.\HarddiskVolume1\


allso working: complete path with GUID and mount point

\\?\Volume{cfe6df15-9df5-11de-aca4-806e6f6e6963}\Removable\SD16#1\


(Tested with Windows 7)

Determinig USB

"To determine whether a drive is a USB-type drive, call SetupDiGetDeviceRegistryProperty and specify the SPDRP_REMOVAL_POLICY property."

This is not safe. I've seen FireWire drives with CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL and USB drives with CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL (a card reader in a printer).
The better way is to check the BusType for being BusTypeUsb by means of IOCTL_STORAGE_QUERY_PROPERTY.
http://msdn.microsoft.com/en-us/library/ms803642.aspx

Sample:
// szPath without trailing backslash like
// "\\\\.\\X:"
// "\\\\\?\\Volume{433619ed-c6ea-11d9-a3b2-806d6172696f}
// "\\\\.\\PhysicalDrive0"

HANDLE hDevice = CreateFile(szPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);

if ( hDevice != INVALID_HANDLE_VALUE ) {

DWORD dwOutBytes = 0; // IOCTL output length
STORAGE_PROPERTY_QUERY Query; // input param for query

// specify the query type
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;

char OutBuf[1024] = {0}; // good enough, usually about 100 bytes
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)OutBuf;
pDevDesc->Size = sizeof(OutBuf);

// Query using IOCTL_STORAGE_QUERY_PROPERTY
BOOL res = DeviceIoControl(hDevice, // device handle
IOCTL_STORAGE_QUERY_PROPERTY, // info of device property
&Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer
pDevDesc, pDevDesc->Size, // output data buffer
&dwOutBytes, // out's length
(LPOVERLAPPED)NULL);

CloseHandle(hDevice);

if ( res ) {
// here we are
BusType = pDevDesc->BusType;
}
}


Alternative to Unmanaged Code

You could use these APIs in managed code as noted above. As an alternative to using unmanaged code, you could consider using the System.Io.DriveInfo class and its DriveType property.

For more info on this class, see http://msdn.microsoft.com/en-us/library/system.io.driveinfo_properties(VS.80).aspx