Thanks a lot!
Could anybody give me a clue?
Or it was too easy to ask here?
My question:
I have a USB mass storage device which I have known its VID&PID. It may be mounted as different drive when connected. How can I get the path of the file it contains.
I think VID&PID and its mounted drive letter are associated with different layers of the driver stack. Then how to access dirver properties across layers.
xxxxx@idiov.com wrote:
Could anybody give me a clue?
Or it was too easy to ask here?
If you asked this before, I certainly did not see it, and it’s not in my
archive.
My question:
I have a USB mass storage device which I have known its VID&PID. It may be mounted as different drive when connected. How can I get the path of the file it contains.I think VID&PID and its mounted drive letter are associated with different layers of the driver stack. Then how to access dirver properties across layers.
You can do this by registry diving, but that’s not the recommended
method. The recommended method is rather convoluted. Basically, you go
through each of the possible drive letters, and if GetDriveType(x) is
DRIVE_REMOVABLE, you call GetVolumeNameFromVolumeMountPoint to get it’s
volume name (based on a GUID).
Then, you use the SetupDi APIs to run through the list of all volumes in
GUID_DEVINTERFACE_VOLUME. That gives you the VID/PID and the device
path. You can then call GetVolumeNameFromVolumeMountPoint to get the
volume name from the device path, and look for a match in the list you
got above.
Here is code that shows how to do this, based on an old newsgroup post
from Kiran:
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <winioctl.h>
#include <atlstr.h>
#define BUFFER_SIZE 256
#define MAX_DRIVES 26
#pragma comment( lib, “setupapi.lib” )
// Print volume information for all removable disks
int GetAllRemovableDisks()
{
 TCHAR caDrive[4] = TEXT(“A:\”);
 TCHAR volume[BUFFER_SIZE];
 DWORD dwDriveMask;
int count = 0;
// Get all drives in the system.
 dwDriveMask = GetLogicalDrives();
if(dwDriveMask == 0)
 {
 printf(“Error - GetLogicalDrives failed\n”);
 return FALSE;
 }
// Loop for all drives.
for(
 int nLoopIndex = 0;
 nLoopIndex< MAX_DRIVES;
 nLoopIndex++, dwDriveMask>>=1
 )
 {
 // If a drive is present,
 if(dwDriveMask & 1)
 {
 caDrive[0] = TEXT(‘A’) + nLoopIndex;
// If a drive is removable.
 if(GetDriveType(caDrive) == DRIVE_REMOVABLE)
 {
 //Get its volume info.
 if(GetVolumeNameForVolumeMountPoint(caDrive, volume, 
BUFFER_SIZE))
 {
 printf( “%c: %s\n”, caDrive[0], volume );
 count++;
 }
 }
 }
 }
return count;
}
// Print volume GUIDs for all volumes in GUID_DEVINTERFACE_VOLUME.
TCHAR GetAllVolumes( )
{
 HDEVINFO hDevInfo;
 SP_DEVICE_INTERFACE_DATA devInterfaceData;
 SP_DEVINFO_DATA devInfoData;
CTempBuffer<sp_device_interface_detail_data> pDevDetail;
 pDevDetail.AllocateBytes( BUFFER_SIZE );
// Get device Information handle for Volume interface
 hDevInfo = SetupDiGetClassDevs(
 &GUID_DEVINTERFACE_VOLUME,
 NULL, NULL,
 DIGCF_DEVICEINTERFACE |
 DIGCF_PRESENT
 );
if(hDevInfo == INVALID_HANDLE_VALUE)
 {
 printf(“Error - SetupDiGetClassDevs failed\n”);
 return 0;
 }
// Loop until device interfaces are found.
 for( DWORD dwIndex = 0; ; dwIndex++ )
 {
 ZeroMemory(&devInterfaceData, sizeof(devInterfaceData));
 devInterfaceData.cbSize = sizeof(devInterfaceData);
// Get device Interface data.
if(
 !SetupDiEnumDeviceInterfaces(
 hDevInfo,
 NULL,
 &GUID_DEVINTERFACE_VOLUME,
 dwIndex,
 &devInterfaceData
 )
 )
 break;
ZeroMemory(&devInfoData, sizeof(devInfoData));
 devInfoData.cbSize = sizeof(devInfoData);
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
DWORD dwRequiredSize;
 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.
 DEVINST devInstParent;
 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.
 TCHAR buf[BUFFER_SIZE];
 CM_Get_Device_ID(devInstParent, buf, BUFFER_SIZE,0);
 puts( buf );
// Append \ to the DevicePath of SP_DEVICE_INTERFACE_DETAIL_DATA
 CString Path( pDevDetail->DevicePath );
 Path += TEXT(“\”);
// Get Volume mount point for the device path.
 TCHAR volume[BUFFER_SIZE];
 if( GetVolumeNameForVolumeMountPoint( Path, volume, BUFFER_SIZE ) )
 {
 printf( " %s\n", volume );
 }
 }
SetupDiDestroyDeviceInfoList(hDevInfo);
 return 0;
}
int
main()
{
 GetAllRemovableDisks( );
 GetAllVolumes( );
 return 0;
}
– 
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</sp_device_interface_detail_data></atlstr.h></winioctl.h></cfgmgr32.h></setupapi.h></stdio.h></windows.h>
Thank you so much, Tim!
It’s really not a simple work.
Now, I have another question.
Yestoday I tried the code Tim gave us to find out relations between VID&PIDs and disk drive.
There were 2 usb mass storage devices connected to my PC.
One is a 40GB USB hard drive and another is a 1GB USB removable disk.
Here is output of my application:
/**********BEGIN*************/
Volume 0
Volume name: \?\Volume{5bdfa40e-1fe1-11dd-9baa-806d6172696f}\ 
Device ID: SCSI\CDROM&VEN_GENERIC&PROD_DVD-ROM&REV_1.0\2&12B1DE20&0&000
Parent Device ID: PCI\D347PRT\0000
Grand-parent Device ID: ROOT\SYSTEM\0003
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 1
Volume name: \?\Volume{6364aa6b-4bc7-11dd-9be6-0019b91f27a5}\ 
Device ID: STORAGE\REMOVABLEMEDIA\7&34FB39B2&0&RM
Parent Device ID: USBSTOR\DISK&VEN_CREATIVE&PROD_ZEN_V_PLUS_(UMS)&REV_0001\A834CC8
Grand-parent Device ID: USB\VID_041E&PID_4133\A834CC870002FA9D
Great-grand-parent Device ID: USB\ROOT_HUB20\4&10671E48&0
Volume 2
Volume name: \?\Volume{8e6846f7-1a43-11dd-8f55-0019b91f27a5}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE77FCC3B8OFFSET7E00LENGTH950
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 3
Volume name: \?\Volume{71a2a3a4-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSET77FE11600LENGTH77FE
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 4
Volume name: \?\Volume{71a2a3a3-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSET7E00LENGTH77FE01A00
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 5
Volume name: \?\Volume{71a2a3a5-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSETEFFC1AE00LENGTH77FE
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Drive C:
Volume name: \?\Volume{71a2a3a3-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive D:
Volume name: \?\Volume{71a2a3a4-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive E:
Volume name: \?\Volume{71a2a3a5-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive F:
Volume name: \?\Volume{5bdfa40e-1fe1-11dd-9baa-806d6172696f}\ 
Type: DRIVE_CDROM
Drive G:
Volume name: \?\Volume{8e6846f7-1a43-11dd-8f55-0019b91f27a5}\ 
Type: DRIVE_FIXED
Drive H:
Volume name: \?\Volume{6364aa6b-4bc7-11dd-9be6-0019b91f27a5}\ 
Type: DRIVE_REMOVABLE
/**********END*************/
Where C: D: E: are partitions of my hard-drive, F: is a virtual DVD-ROM.
G: and H: are two USB disk.
By the above result, we can find that drive G: was corresponding to volume 2 and its parent deivce ID is not USBSTOR\XXX.
My question is:
Why there is different behavior when walking through the driver stack for the two USB disk?
Now, I have another question.
Yesterday I tried the code Tim gave me to find out relations between VID&PIDs and disk drives.
There are 2 usb mass storage devices connected to my PC.
One is a 40GB USB hard disk and another is a 1GB USB removable disk.
Here is output of my application:
/**********BEGIN*************/
Volume 0
Volume name: \?\Volume{5bdfa40e-1fe1-11dd-9baa-806d6172696f}\ 
Device ID: SCSI\CDROM&VEN_GENERIC&PROD_DVD-ROM&REV_1.0\2&12B1DE20&0&000
Parent Device ID: PCI\D347PRT\0000
Grand-parent Device ID: ROOT\SYSTEM\0003
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 1
Volume name: \?\Volume{6364aa6b-4bc7-11dd-9be6-0019b91f27a5}\ 
Device ID: STORAGE\REMOVABLEMEDIA\7&34FB39B2&0&RM
Parent Device ID: USBSTOR\DISK&VEN_CREATIVE&PROD_ZEN_V_PLUS_(UMS)&REV_0001\A834CC8
Grand-parent Device ID: USB\VID_041E&PID_4133\A834CC870002FA9D
Great-grand-parent Device ID: USB\ROOT_HUB20\4&10671E48&0
Volume 2
Volume name: \?\Volume{8e6846f7-1a43-11dd-8f55-0019b91f27a5}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE77FCC3B8OFFSET7E00LENGTH950
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 3
Volume name: \?\Volume{71a2a3a4-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSET77FE11600LENGTH77FE
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 4
Volume name: \?\Volume{71a2a3a3-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSET7E00LENGTH77FE01A00
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Volume 5
Volume name: \?\Volume{71a2a3a5-19c5-11dd-b211-806d6172696f}\ 
Device ID: STORAGE\VOLUME\1&30A96598&0&SIGNATURE80OFFSETEFFC1AE00LENGTH77FE
Parent Device ID: ROOT\FTDISK\0000
Grand-parent Device ID: HTREE\ROOT\0
Great-grand-parent Device ID: HTREE\ROOT\0
Drive C:
Volume name: \?\Volume{71a2a3a3-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive D:
Volume name: \?\Volume{71a2a3a4-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive E:
Volume name: \?\Volume{71a2a3a5-19c5-11dd-b211-806d6172696f}\ 
Type: DRIVE_FIXED
Drive F:
Volume name: \?\Volume{5bdfa40e-1fe1-11dd-9baa-806d6172696f}\ 
Type: DRIVE_CDROM
Drive G:
Volume name: \?\Volume{8e6846f7-1a43-11dd-8f55-0019b91f27a5}\ 
Type: DRIVE_FIXED
Drive H:
Volume name: \?\Volume{6364aa6b-4bc7-11dd-9be6-0019b91f27a5}\ 
Type: DRIVE_REMOVABLE
/**********END*************/
Where C: D: E: are partitions of my hard disk, F: is a virtual DVD-ROM.
G: and H: are the two USB disk.
By the above result, we can see that drive G: was corresponding to volume 2 and its parent deivce ID is not USBSTOR\XXX.
My question is:
Why there is different parent device ID for the two USB disk?
Sorry for posting previous reply twice!
The 80G USB disk’s descriptors are here:
Device Descriptor:
bcdUSB: 0x0200
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x40 (64)
idVendor: 0x05E3 (Genesys Logic Inc.)
idProduct: 0x0702
bcdDevice: 0x0002
iManufacturer: 0x00
iProduct: 0x01
0x0409: “USB TO IDE”
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Full
Device Address: 0x01
Open Pipes: 2
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Bulk
wMaxPacketSize: 0x0200 (512)
bInterval: 0x01
Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Bulk
wMaxPacketSize: 0x0200 (512)
bInterval: 0x01
Configuration Descriptor:
wTotalLength: 0x0020
bNumInterfaces: 0x01
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0xC0 (Bus Powered Self Powered )
MaxPower: 0x30 (96 Ma)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x08
bInterfaceSubClass: 0x06
bInterfaceProtocol: 0x50
iInterface: 0x00
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Bulk
wMaxPacketSize: 0x0200 (512)
bInterval: 0x01
Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Bulk
wMaxPacketSize: 0x0200 (512)
bInterval: 0x01