diff --git a/reactos/drivers/filesystems/fastfat/fsctl.c b/reactos/drivers/filesystems/fastfat/fsctl.c index ef0a137148e..a406276ee64 100644 --- a/reactos/drivers/filesystems/fastfat/fsctl.c +++ b/reactos/drivers/filesystems/fastfat/fsctl.c @@ -532,6 +532,7 @@ VfatMount( UNICODE_STRING VolumeLabelU; ULONG HashTableSize; ULONG eocMark; + ULONG i; FATINFO FatInfo; DPRINT("VfatMount(IrpContext %p)\n", IrpContext); @@ -669,6 +670,23 @@ VfatMount( goto ByeBye; } + DeviceExt->Statistics = ExAllocatePoolWithTag(NonPagedPool, + sizeof(STATISTICS) * VfatGlobalData->NumberProcessors, + TAG_VFAT); + if (DeviceExt->Statistics == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; + } + + RtlZeroMemory(DeviceExt->Statistics, sizeof(STATISTICS) * VfatGlobalData->NumberProcessors); + for (i = 0; i < VfatGlobalData->NumberProcessors; ++i) + { + DeviceExt->Statistics[i].Base.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT; + DeviceExt->Statistics[i].Base.Version = 1; + DeviceExt->Statistics[i].Base.SizeOfCompleteStructure = sizeof(STATISTICS); + } + DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice); Fcb = vfatNewFCB(DeviceExt, &NameU); if (Fcb == NULL) @@ -776,6 +794,8 @@ ByeBye: ObDereferenceObject (DeviceExt->FATFileObject); if (DeviceExt && DeviceExt->SpareVPB) ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VFAT); + if (DeviceExt && DeviceExt->Statistics) + ExFreePoolWithTag(DeviceExt->Statistics, TAG_VFAT); if (Fcb) vfatDestroyFCB(Fcb); if (Ccb) @@ -1188,6 +1208,46 @@ VfatDismountVolume( return STATUS_SUCCESS; } +static +NTSTATUS +VfatGetStatistics( + PVFAT_IRP_CONTEXT IrpContext) +{ + PVOID Buffer; + ULONG Length; + NTSTATUS Status; + PDEVICE_EXTENSION DeviceExt; + + DeviceExt = IrpContext->DeviceExt; + Length = IrpContext->Stack->Parameters.FileSystemControl.OutputBufferLength; + Buffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; + + if (Length < sizeof(FILESYSTEM_STATISTICS)) + { + return STATUS_BUFFER_TOO_SMALL; + } + + if (Buffer == NULL) + { + return STATUS_INVALID_USER_BUFFER; + } + + if (Length >= sizeof(STATISTICS) * VfatGlobalData->NumberProcessors) + { + Length = sizeof(STATISTICS) * VfatGlobalData->NumberProcessors; + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_BUFFER_OVERFLOW; + } + + RtlCopyMemory(Buffer, DeviceExt->Statistics, Length); + IrpContext->Irp->IoStatus.Information = Length; + + return Status; +} + /* * FUNCTION: File system control */ @@ -1243,6 +1303,10 @@ VfatFileSystemControl( Status = VfatDismountVolume(IrpContext); break; + case FSCTL_FILESYSTEM_GET_STATISTICS: + Status = VfatGetStatistics(IrpContext); + break; + default: Status = STATUS_INVALID_DEVICE_REQUEST; } diff --git a/reactos/drivers/filesystems/fastfat/iface.c b/reactos/drivers/filesystems/fastfat/iface.c index 8d564489efa..c334a95aed4 100644 --- a/reactos/drivers/filesystems/fastfat/iface.c +++ b/reactos/drivers/filesystems/fastfat/iface.c @@ -91,6 +91,7 @@ DriverEntry( RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA)); VfatGlobalData->DriverObject = DriverObject; VfatGlobalData->DeviceObject = DeviceObject; + VfatGlobalData->NumberProcessors = KeNumberProcessors; /* Enable this to enter the debugger when file system corruption * has been detected: VfatGlobalData->Flags = VFAT_BREAK_ON_CORRUPTION; */ diff --git a/reactos/drivers/filesystems/fastfat/vfat.h b/reactos/drivers/filesystems/fastfat/vfat.h index 55ac7dc94d8..97dd9249351 100644 --- a/reactos/drivers/filesystems/fastfat/vfat.h +++ b/reactos/drivers/filesystems/fastfat/vfat.h @@ -289,6 +289,13 @@ typedef struct _VFAT_DISPATCH PGET_NEXT_DIR_ENTRY GetNextDirEntry; } VFAT_DISPATCH, *PVFAT_DISPATCH; +#define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS)) +typedef struct _STATISTICS { + FILESYSTEM_STATISTICS Base; + FAT_STATISTICS Fat; + UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD]; +} STATISTICS, *PSTATISTICS; + typedef struct DEVICE_EXTENSION { ERESOURCE DirResource; @@ -308,6 +315,7 @@ typedef struct DEVICE_EXTENSION BOOLEAN AvailableClustersValid; ULONG Flags; struct _VFATFCB *VolumeFcb; + PSTATISTICS Statistics; /* Pointers to functions for manipulating FAT. */ PGET_NEXT_CLUSTER GetNextCluster; @@ -383,6 +391,7 @@ typedef struct PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; ULONG Flags; + ULONG NumberProcessors; ERESOURCE VolumeListLock; LIST_ENTRY VolumeListHead; NPAGED_LOOKASIDE_LIST FcbLookasideList;