/*++ Copyright (c) 2000-2001 Microsoft Corporation Module Name: volinfo.c Abstract: This module implements routines related to handling IRP_MJ_QUERY_VOLUME_INFORMATION. --*/ #include "gdfx.h" NTSTATUS GdfxFsdQueryVolumeInformation( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine is called by the I/O manager to handle IRP_MJ_QUERY_VOLUME_INFORMATION requests. Arguments: DeviceObject - Specifies the device object that the I/O request is for. Irp - Specifies the packet that describes the I/O request. Return Value: Status of operation. --*/ { NTSTATUS status; PGDF_VOLUME_EXTENSION VolumeExtension; PIO_STACK_LOCATION IrpSp; ULONG BytesWritten; PFILE_FS_SIZE_INFORMATION SizeInformation; PFILE_FS_DEVICE_INFORMATION DeviceInformation; PFILE_FS_ATTRIBUTE_INFORMATION AttributeInformation; VolumeExtension = (PGDF_VOLUME_EXTENSION)DeviceObject->DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp); // // Clear the output buffer. // RtlZeroMemory(Irp->UserBuffer, IrpSp->Parameters.QueryVolume.Length); // // Dispatch the information class function. // status = STATUS_SUCCESS; switch (IrpSp->Parameters.QueryVolume.FsInformationClass) { case FileFsVolumeInformation: NOTHING; BytesWritten = FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel); break; case FileFsSizeInformation: SizeInformation = (PFILE_FS_SIZE_INFORMATION)Irp->UserBuffer; SizeInformation->TotalAllocationUnits.QuadPart = (ULONGLONG)VolumeExtension->PartitionSectorCount; SizeInformation->SectorsPerAllocationUnit = 1; SizeInformation->BytesPerSector = GDF_CD_SECTOR_SIZE; BytesWritten = sizeof(FILE_FS_SIZE_INFORMATION); break; case FileFsDeviceInformation: DeviceInformation = (PFILE_FS_DEVICE_INFORMATION)Irp->UserBuffer; DeviceInformation->DeviceType = VolumeExtension->TargetDeviceObject->DeviceType; DeviceInformation->Characteristics = 0; BytesWritten = sizeof(FILE_FS_DEVICE_INFORMATION); break; case FileFsAttributeInformation: AttributeInformation = (PFILE_FS_ATTRIBUTE_INFORMATION)Irp->UserBuffer; AttributeInformation->FileSystemAttributes = 0; AttributeInformation->MaximumComponentNameLength = 255; AttributeInformation->FileSystemNameLength = sizeof(OCHAR) * 4; if (IrpSp->Parameters.QueryVolume.Length < FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName) + sizeof(OCHAR) * 4) { BytesWritten = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName); status = STATUS_BUFFER_OVERFLOW; } else { RtlCopyMemory(AttributeInformation->FileSystemName, OTEXT("GDFX"), sizeof(OCHAR) * 4); BytesWritten = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName) + sizeof(OCHAR) * 4; } break; default: BytesWritten = 0; status = STATUS_INVALID_PARAMETER; break; } // // Fill in the number of bytes that we wrote to the user's buffer. // Irp->IoStatus.Information = BytesWritten; // // Check that we didn't overflow the user's buffer. The I/O manager does // the initial check to make sure there's enough space for the static // structure for a given information class, but we might overflow the buffer // when copying in the variable length file name. // ASSERT(Irp->IoStatus.Information <= IrpSp->Parameters.QueryVolume.Length); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }