Multiple partition/VolumeID on removable storage (SetupDiGetClassDevs)



Hello,


I'm trying to list all volumeIDs of a removable storage which has two
partitions. In the Disk Management interface, Windows limits to 1 the
number of partition that you can mount from a removable storage. I'm
trying to programmatically get the volume ID of this second partition
and mount it. I use the piece of code below which works great but list
only the first partition of the removable device.

Questions:
- Is the VolumeID of the second partition created somewhere but it's
"simply" not listed or isn't it created at all (which would be bad)?
- If it exists, how to get the VolumeID of the second partition and
then mount it?
- If it doesn't exist, how to create it? Or How to modify the storage
type from "removable" to "basic"?

Gregoire




#define BUFFER_SIZE 10240

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

int g_count = 0;

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< 26; 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;
}
}



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;

MessageBox(0,buf, pDevDetail->DevicePath, 0);
// Get Volume mount point for the device path.
if(GetVolumeNameForVolumeMountPoint(pDevDetail->DevicePath, volume,
BUFFER_SIZE))
{
MessageBox(0,volume, L"VolumeID", 0);

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)
{
WCHAR pszdrive[5];
pszdrive[0]=g_drives[nLoopIndex].letter;
pszdrive[1]='\0';
MessageBox( 0, pszdrive,L"Drive",0);
// SetupDiDestroyDeviceInfoList(hDevInfo);
// return g_drives[nLoopIndex].letter;
}
}
}
}
}

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

.



Relevant Pages

  • Re: Problem with random disks mount sequence
    ... I'll get random mount sequences. ... At the beginning the USB ... nautilus remember that 'storage3' was 1st partition, ... SCSI drives are listed by order of discovery. ...
    (Fedora)
  • Re: Problem with random disks mount sequence
    ... I'll get random mount sequences. ... At the beginning the USB ... nautilus remember that 'storage3' was 1st partition, ... SCSI drives are listed by order of discovery. ...
    (Fedora)
  • Re: Hard drive mounting problems with debian
    ... >>I've got a problem when I try to mount a couple of my hard drives. ... >>formatted them using cfdisk (which works fine, ... about "formatting" the partition with cfdisk, ...
    (comp.os.linux.misc)
  • Re: Moving to a new disk..
    ... catch-all partition you have - often mounted as /home. ... Mount up the new partitions to something meaningful. ... You have installed the new disk so it looks like /dev/ad1 ... change the drives around so the new drive ...
    (freebsd-questions)
  • Re: How to mount logical drives?
    ... but iam unable to mount the other drives. ... It doesn't matter if it's logical, as long as you can find out the partition ... Don't forget to umount first if it sucessfully mount. ... Another way is using fdisk: ...
    (RedHat)

Loading