Y always fail to get volume capacity?

Hi!

I am writing a File System Filter program. And I want to get the volume capaciy as soon as the new volume is being mounted. I’ll describe how I try to do that below:

I do not build IRP to query the volume capacity info of the newly mounted volume. Instead, I use ZwDeviceIoControlFile with IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX I/O command. And I call this routine in the dispatch routine which deals with IRP_MJ_FILE_SYSTEM_CONTROL request. If I call this routine, my computer crashes or the exeplorer process dies. I also try to get the volume capacity in the completion routine of IRP_MJ_FILE_SYSTEM_CONTROL. But I still fail to get the volume info. Why?

Can someone tell how I can get the volume info as the new volume is being mounted? Thanks very very very … very much!

What does this have to do with file systems? This is a question about
storage.

wrote in message news:xxxxx@ntfsd…
> Hi!
>
> I am writing a File System Filter program. And I want to get the volume
> capaciy as soon as the new volume is being mounted. I’ll describe how I
> try to do that below:
>
> I do not build IRP to query the volume capacity info of the newly mounted
> volume. Instead, I use ZwDeviceIoControlFile with
> IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX I/O
> command. And I call this routine in the dispatch routine which deals with
> IRP_MJ_FILE_SYSTEM_CONTROL request. If I call this routine, my computer
> crashes or the exeplorer process dies. I also try to get the volume
> capacity in the completion routine of IRP_MJ_FILE_SYSTEM_CONTROL. But I
> still fail to get the volume info. Why?
>
> Can someone tell how I can get the volume info as the new volume is being
> mounted? Thanks very very very … very much!
>

Is that to say I can get the volume info before the volume is mounted? In fact, what I want to get is the formatted volume storage of the newly mounted volume, then it must have something to do with the file system.

You listed a couple of IoCtls that are specific to the storage stack and not
the file system stack. Start with the Win32 and Native apis for getting the
information you want from the file systems and see what type of request you
need to make. FatQueryFsSizeInfo is a function in fastfat you can search
for.

wrote in message news:xxxxx@ntfsd…
> Is that to say I can get the volume info before the volume is mounted? In
> fact, what I want to get is the formatted volume storage of the newly
> mounted volume, then it must have something to do with the file system.
>

In fact, I write like this to get volume capacity.

NTSTATUS
HDGetVolumeInfoEx(
IN HD_DEVICE_TYPE DeviceType,
IN PUNICODE_STRING DeviceName,
OUT LONGLONG *Capacity
)
/***
***Routine Description:
***Get the volume capacity of the volume with the name of “DeveciName”. And the capacity is
***stored in the Capacity.
***/
{
HANDLE handle;
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES objectAttributes;
PDISK_GEOMETRY_EX diskGeom;

ASSERT(DeviceName != NULL);

//Allocate buffer to store the geometry info of the volume.
diskGeom = (PDISK_GEOMETRY_EX)ExAllocatePoolWithTag(NonPagedPool, 512, SFLT_POOL_TAG);
if( diskGeom == NULL )
return STATUS_UNSUCCESSFUL;

//
// Open the device file according to the device name.
//
DbgPrint(“SFilter(HDGetVolumeInfoEx): %wZ\n”, DeviceName );
InitializeObjectAttributes( &objectAttributes,
DeviceName,
OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = ZwCreateFile( &handle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&objectAttributes,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
0,
NULL,
0
);
if( !NT_SUCCESS(status) ){
ExFreePool( diskGeom );
DbgPrint( “Sfilter(HDGetVolumeInfo): Fail to open device\n” );
return status;
}

//
// Send IOCTL according to the specific type of device object.
//
switch( DeviceType ){
case HD_HDO_DISK:
status = ZwDeviceIoControlFile( handle,
NULL,
NULL,
NULL,
&ioStatus,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
diskGeom,
512
);
break;

case HD_HDO_CDROM:
case HD_HDO_DVDROM:
status = ZwDeviceIoControlFile( handle,
NULL,
NULL,
NULL,
&ioStatus,
IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
diskGeom,
512
);

break;
}

if( !NT_SUCCESS(ioStatus.Status) ){
*Capacity = 0x00;
ExFreePool( diskGeom );
return ioStatus.Status;
}
else{
*Capacity = diskGeom->DiskSize.HighPart;
*Capacity = *Capacity<< 32;
*Capacity += diskGeom->DiskSize.LowPart;
}

DbgPrint( “SFilter(HDGetVolumeInfoEx): Capacity is %X\n”, (*Capacity)>>20 ); //Output the capacity(MB)

ZwClose( handle );
ExFreePool( diskGeom );
return STATUS_SUCCESS;
}

Is there anything wrong? By the way, FatQueryFsSizeInfo can be called in filter driver?

That is a storage call and not file system. Regardless if you access it
with a symbolic link you are talking to the storage drivers. Look at the
source code for disk.sys, cdfs.sys, and classpnp.sys. Look for those IOCTLs
in fastfat.sys and you won’t find them. I have spent a long time in the
storage stack, so I am certain. The numbers you get from those do not take
into account the file system overhead such as fats, boot sectors, maybe root
directory (not FAT32), and minimal MFT. Why do you think those IOCTLs have
the words CDROM or DISK in them? This is still not the correct group for
these questions. I will not respond here to more posts.

wrote in message news:xxxxx@ntfsd…
> In fact, I write like this to get volume capacity.
>
> NTSTATUS
> HDGetVolumeInfoEx(
> IN HD_DEVICE_TYPE DeviceType,
> IN PUNICODE_STRING DeviceName,
> OUT LONGLONG *Capacity
> )
> /
>
Routine Description:
> Get the volume capacity of the volume with the name of “DeveciName”.
> And the capacity is
>
stored in the Capacity.
> ***/
> {
> HANDLE handle;
> NTSTATUS status;
> IO_STATUS_BLOCK ioStatus;
> OBJECT_ATTRIBUTES objectAttributes;
> PDISK_GEOMETRY_EX diskGeom;
>
> ASSERT(DeviceName != NULL);
>
> //Allocate buffer to store the geometry info of the volume.
> diskGeom = (PDISK_GEOMETRY_EX)ExAllocatePoolWithTag(NonPagedPool, 512,
> SFLT_POOL_TAG);
> if( diskGeom == NULL )
> return STATUS_UNSUCCESSFUL;
>
> //
> // Open the device file according to the device name.
> //
> DbgPrint(“SFilter(HDGetVolumeInfoEx): %wZ\n”, DeviceName );
> InitializeObjectAttributes( &objectAttributes,
> DeviceName,
> OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
> NULL,
> NULL
> );
> status = ZwCreateFile( &handle,
> GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
> &objectAttributes,
> &ioStatus,
> NULL,
> FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> 0,
> 0,
> NULL,
> 0
> );
> if( !NT_SUCCESS(status) ){
> ExFreePool( diskGeom );
> DbgPrint( “Sfilter(HDGetVolumeInfo): Fail to open device\n” );
> return status;
> }
>
> //
> // Send IOCTL according to the specific type of device object.
> //
> switch( DeviceType ){
> case HD_HDO_DISK:
> status = ZwDeviceIoControlFile( handle,
> NULL,
> NULL,
> NULL,
> &ioStatus,
> IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
> NULL,
> 0,
> diskGeom,
> 512
> );
> break;
>
> case HD_HDO_CDROM:
> case HD_HDO_DVDROM:
> status = ZwDeviceIoControlFile( handle,
> NULL,
> NULL,
> NULL,
> &ioStatus,
> IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,
> NULL,
> 0,
> diskGeom,
> 512
> );
>
> break;
> }
>
> if( !NT_SUCCESS(ioStatus.Status) ){
> *Capacity = 0x00;
> ExFreePool( diskGeom );
> return ioStatus.Status;
> }
> else{
> *Capacity = diskGeom->DiskSize.HighPart;
> *Capacity = *Capacity<< 32;
> *Capacity += diskGeom->DiskSize.LowPart;
> }
>
> DbgPrint( “SFilter(HDGetVolumeInfoEx): Capacity is %X\n”,
> (*Capacity)>>20 ); //Output the capacity(MB)
>
> ZwClose( handle );
> ExFreePool( diskGeom );
> return STATUS_SUCCESS;
> }
>
> Is there anything wrong? By the way, FatQueryFsSizeInfo can be called in
> filter driver?
>