Obtaining GUID for a volume

Hi,

I have a volume filter driver (upper filter) which layers on all the available volumes on a system (Windows 2003/XP). As part of the driver functionality, the driver traps the Read/Write requests for some specific volumes (input by a user mode application) for processing. In this context, I was looking for a mechanism which provides me the GUID for the volume (to be verified against the application provided GUID). Can you please let me know if there is an API for the same? Would issuing IOCTL_MOUNTDEV_QUERY_UNIQUE_ID to the PDO created by the FTDisk driver return the volume GUID?

P.S. I had posted the same query in NTDEV, but was wondering if this belonged to the area of NTFSD. Hence reposting here.

Regards,
Girish.

How about IOCTL_MOUNTMGR_QUERY_POINTS ?

Thanks Kiran. Based on my understanding of WDK documentation, callers of IOCTL_MOUNTMGR_QUERY_POINTS need to provide as input either the unique ID or the non-persistent device name of the volume and the output will contain the volume GUID. If the input is empty the entire mounted device list is returned.
However, in my case, how do I get the unique ID or the non-persistent device name for the volume that I am filtering? Do I need to form an IOCTL_MOUNTDEV_QUERY_UNIQUE_ID and send it to the volume device object first and follow it up with an IOCTL_MOUNTMGR_QUERY_POINTS?

Yes. That approach certainly will work. Other approach, if you have any user mode component, is use GetVolumeNameForVolumeMountPoint to query the volumeid and then send it down to your volume filter using some private IOCTL. The pseudo code will lookas follows :

GetVolumeNameForVolumeMountPoint(“c:\”, volName, …);
volHandle = CreateFile(“\??\c:”, …);
DevIoctl(volHandle, IOCTL_MY_VFILTER_SET_VOL_NAME, volName, …);
CloseHandle(volHandle);

I have tried the approach mentioned earlier i.e.,
a) Query the volume driver for the device name (using
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) and
b) Query the Mount Manager for the volueme GUID (using
IOCTL_MOUNTMGR_QUERY_POINTS) with the input being the device name obtained
in step a.

However, I am facing some problems in obtaining the volume GUID, as in the
driver returns STATUS_BUFFER_OVERFLOW in step b above, irrespective of the
size of the buffer I use (have tried increasing the buffer size upto 4k).

I am not sure if I am filling up the input buffer in accordance with what is
expected. Could some one please help me out with the following?

  1. As per the WDK documentation, the input to IOCTL_MOUNTMGR_QUERY_POINTS is
    a MOUNTMGR_MOUNT_POINT structure containing a simple triple. The following
    snippet of code builds the IRP and issues it to the Mount Manager:

PMOUNTMGR_MOUNT_POINTS outputBuffer = NULL;
PMOUNTMGR_MOUNT_POINT inputBuffer = NULL;
ULONG outputBufferLength = 0;
ULONG inputBufferLength = 0;

// deviceExtension contains the device name as obtained through
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME

mountDevName = deviceExtension->MountDeviceName;

inputBufferLength = sizeof(MOUNTMGR_MOUNT_POINT) +
mountDevName->NameLength;
inputBuffer = (PMOUNTMGR_MOUNT_POINT)
ExAllocatePoolWithTag(PagedPool, inputBufferLength, POOL_TAG);
if (inputBuffer == NULL)
{
DebugPrint((“Unable to allocate memory for input buffer!!”));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(inputBuffer, inputBufferLength);
inputBuffer->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
inputBuffer->DeviceNameLength = mountDevName->NameLength;
RtlCopyMemory((inputBuffer + 1), mountDevName->Name,
mountDevName->NameLength);

outputBufferLength = sizeof(MOUNTMGR_MOUNT_POINTS) + 2048; // 2k
buffer size to hold the output data
outputBuffer = ExAllocatePoolWithTag(PagedPool, outputBufferLength,
POOL_TAG);
if (outputBuffer == NULL)
{
DebugPrint((“Unable to allocate memory for output buffer!!”));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(outputBuffer, outputBufferLength);

irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_POINTS,
mountDeviceObject,
// MOUNTMGR_DEVICE_NAME
inputBuffer,
inputBufferLength,
outputBuffer,
outputBufferLength,
FALSE,
&event,
&ioStatus);
//
// Issue the IRP down to the MOUNTMANAGER
//
status = IoCallDriver(mountDeviceObject, irp);

Is this is the right way? Or am I missing something here?

I have also tried using the sample code from OSR which issues the
IOCTL_MOUNTMGR_QUERY_POINTS through an user mode application. Though the
application works when input triple is set to zero (retrieving all the
available mount points), I am unable to get it to return the data when a
specific device name is provided as input. The return status from
DeviceIoControl indicates STATUS_INVALID_PARAMETER.

Any help would be much appreciated.

Regards,
Girish.

wrote in message news:xxxxx@ntfsd…
> Yes. That approach certainly will work. Other approach, if you have any
> user mode component, is use GetVolumeNameForVolumeMountPoint to query the
> volumeid and then send it down to your volume filter using some private
> IOCTL. The pseudo code will lookas follows :
>
> GetVolumeNameForVolumeMountPoint(“c:\”, volName, …);
> volHandle = CreateFile(“\??\c:”, …);
> DevIoctl(volHandle, IOCTL_MY_VFILTER_SET_VOL_NAME, volName, …);
> CloseHandle(volHandle);
>

On getting STATUS_BUFFER_OVERFLOW as status of IoCallDriver, try

if(STATUS_BUFFER_OVERFLOW == status){
get required size as (MOUNTMGR_MOUNT_POINTS)outputBuffer->Size;
allocate output buffer of required size and retry
IOCTL_MOUNTMGR_QUERY_POINTS
}

When mount manager returns STATUS_BUFFER_OVERFLOW, required size is put
into (MOUNTMGR_MOUNT_POINTS)outputBuffer->Size

Thanks Mayur. In fact I did try to obtain the expected size through the
“Size” variable, but in my case the output buffer is empty. I have tried
this on multiple Windows Server 2003 SP2 (x86) platforms with the same
result.

Girish.

“mayur thigale” wrote in message news:xxxxx@ntfsd…
On getting STATUS_BUFFER_OVERFLOW as status of IoCallDriver, try

if(STATUS_BUFFER_OVERFLOW == status){
get required size as (MOUNTMGR_MOUNT_POINTS)outputBuffer->Size;
allocate output buffer of required size and retry
IOCTL_MOUNTMGR_QUERY_POINTS
}

When mount manager returns STATUS_BUFFER_OVERFLOW, required size is put into
(MOUNTMGR_MOUNT_POINTS)outputBuffer->Size