Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to match between physical usb device and its drive letter?

838 views
Skip to first unread message

RB

unread,
Oct 18, 2004, 11:41:18 AM10/18/04
to
Hello, all!

I make enumeration of all usb devices using functions SetupDixxx,
starting from SetupDiGetClassDevs with GUID_CLASS_USB_DEVICE.
I can obtain symbolic path name of each usb device from
SetupDiGetDeviceInterfaceDetail() and its physical name from
SetupDiGetDeviceRegistryProperty() with
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME.
Now, how can I find drive letter for each device?

* QueryDosDevice() gets path different from the physical name.

Thanks in advance,
Rita

Kiran

unread,
Oct 21, 2004, 1:01:02 AM10/21/04
to
Hi,

There is no simple/direct way of obtaining the drive letter.

The following code can be used to get the drive letter
But you have to modify them here and there to meet you need.

Kiran


struct tagDrives
{
WCHAR letter;
WCHAR volume[BUFFER_SIZE];
} g_drives[26];

//
WCHAR GetUSBDrive()
{
LPTSTR lpDevID;
WCHAR cDrive;
DWORD dwSize = BUFFER_SIZE;

// Get all removable disks on user laptop.
if(!GetAllRemovableDisks())
{
WRITELOG("Error - GetAllRemovableDisks failed\n");
return 0;
}

// Alocate memory to device ID
lpDevID = (LPTSTR)AllocMem(BUFFER_SIZE);

// Get device ID corresponding to USBFM from registry.
if(!GetRegValue(lpDevID, DEVICE_ID, dwSize))
{
WRITELOG("Error - Registry - USBFMDevID failed\n");
FreeMem(lpDevID);
return 0;
}

// Get drive corresponding to the registry entry.
cDrive = GetSpecificDrive(lpDevID);

FreeMem(lpDevID);

// return the drive letter.
return cDrive;
}

/******************************************************************************
* GetAllRemovableDisks - This function retrieves volume information for all
removable disks
*
* In: None
*
* Out: TRUE - Success
* FALSE - Failure
*
*******************************************************************************/

BOOL GetAllRemovableDisks()
{
WCHAR caDrive[4];
WCHAR volume[BUFFER_SIZE];
int nLoopIndex;
DWORD dwDriveMask;

caDrive[0] = 'A';
caDrive[1] = ':';
caDrive[2] = '\\';
caDrive[3] = 0;

g_count = 0;

// Get all drives in the system.
dwDriveMask = GetLogicalDrives();

if(dwDriveMask == 0)
{
WRITELOG("Error - GetLogicalDrives failed\n");
return FALSE;
}

// Loop for all drives (MAX_DRIVES = 26)

for(nLoopIndex = 0; nLoopIndex< MAX_DRIVES; nLoopIndex++)
{
// if a drive is present,
if(dwDriveMask & 1)
{
caDrive[0] = 'A' + nLoopIndex;

// If a drive is removable
if(GetDriveType(caDrive) == DRIVE_REMOVABLE)
{
//Get its volume info and store it in the global variable.
if(GetVolumeNameForVolumeMountPoint(caDrive, volume, BUFFER_SIZE))
{
g_drives[g_count].letter = caDrive[0];
wcscpy(g_drives[g_count].volume, volume);
g_count ++;
}

}
}
dwDriveMask >>= 1;
}

// success if atleast one removable drive is found.
if(g_count == 0)
{
return FALSE;
}
else
{
return TRUE;
}
}

/******************************************************************************
* GetSpecificDrive - This function returns the drive corresponding to the
given device ID
*
* In : lpDevID - Device ID
*
* Return: Drive letter corresponding to the given device ID.
*
*******************************************************************************/

WCHAR GetSpecificDrive(
LPTSTR lpDevID)
{
HDEVINFO hDevInfo;
GUID guid;
BYTE buffer[BUFFER_SIZE];
DWORD dwRequiredSize ;
WCHAR buf[BUFFER_SIZE];
DEVINST devInstParent;
DWORD dwIndex;
WCHAR volume[BUFFER_SIZE];
int nLength,nLoopIndex;

SP_DEVICE_INTERFACE_DATA devInterfaceData;
SP_DEVINFO_DATA devInfoData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;

if(!lpDevID)
{
return 0;
}

// GUID_DEVINTERFACE_VOLUME is interface Guid for Volume class devices.
guid = GUID_DEVINTERFACE_VOLUME;


// Get device Information handle for Volume interface
hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL,
DIGCF_DEVICEINTERFACE |
DIGCF_PRESENT);

if(hDevInfo == INVALID_HANDLE_VALUE)
{
WRITELOG("Error - SetupDiGetClassDevs failed\n");
return 0;
}

// Loop until device interfaces are found.
for(dwIndex = 0; ;dwIndex ++)
{
ZeroMemory(&devInterfaceData, sizeof(devInterfaceData));
devInterfaceData.cbSize = sizeof(devInterfaceData);

// Get device Interface data.

if(!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid,
dwIndex,&devInterfaceData))
{
break;
}

ZeroMemory(&devInfoData, sizeof(devInfoData));
devInfoData.cbSize = sizeof(devInfoData);

pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
pDevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

// Get device interface detail data to get
// Device Instance from SP_DEVINFO_DATA and
// Device Path from SP_DEVICE_INTERFACE_DETAIL_DATA

SetupDiGetDeviceInterfaceDetail(hDevInfo,
&devInterfaceData,
pDevDetail, // SP_DEVICE_INTERFACE_DETAIL_DATA
BUFFER_SIZE,
&dwRequiredSize,
&devInfoData); // SP_DEVINFO_DATA

// Get the device instance of parent. This points to USBSTOR.
CM_Get_Parent(&devInstParent,devInfoData.DevInst, 0);

// Get the device instance of grand parent. This points to USB root.
CM_Get_Parent(&devInstParent,devInstParent, 0);

// Get the device ID of the USB root.
CM_Get_Device_ID(devInstParent, buf, BUFFER_SIZE,0);

// If USB root device matches with the input device ID, it is the target
device.

if( buf != NULL && wcscmp(lpDevID,buf) == 0)
{
// Append \ to the DevicePath of SP_DEVICE_INTERFACE_DETAIL_DATA

nLength = wcslen(pDevDetail->DevicePath);
pDevDetail->DevicePath[nLength] = '\\';
pDevDetail->DevicePath[nLength+1] = 0;

// Get Volume mount point for the device path.
if(GetVolumeNameForVolumeMountPoint(pDevDetail->DevicePath, volume,
BUFFER_SIZE))
{
for(nLoopIndex=0; nLoopIndex< g_count; nLoopIndex++)
{
// Compare volume mount point with the one stored earlier.
// If both match, return the corresponding drive letter.

if(wcscmp(g_drives[nLoopIndex].volume, volume)==0)
{
SetupDiDestroyDeviceInfoList(hDevInfo);
return g_drives[nLoopIndex].letter;
}
}
}
}
}

SetupDiDestroyDeviceInfoList(hDevInfo);
WRITELOG("Error - No drives found in GetSpecificDrives\n");
return 0;
}

Bryan

unread,
Feb 7, 2005, 5:01:01 PM2/7/05
to
Hi Kiran,

Thanks for your posting. Which registry key are you reading when you
call:

> // Get device ID corresponding to USBFM from registry.
> if(!GetRegValue(lpDevID, DEVICE_ID, dwSize))

Is it the same data as returned by IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
which returns something like
"\??\Volume{GUID}\", where GUID is a globally unique identifier that
identifies the volume. This is found in the registry at
HKLM\SYSTEM\MountedDevice. Is it this or something else?

Thanks,

Bryan

0 new messages