UNICODE_STRING VolumeLabelU;
ULONG HashTableSize;
ULONG eocMark;
+ ULONG i;
FATINFO FatInfo;
DPRINT("VfatMount(IrpContext %p)\n", IrpContext);
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)
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)
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
*/
Status = VfatDismountVolume(IrpContext);
break;
+ case FSCTL_FILESYSTEM_GET_STATISTICS:
+ Status = VfatGetStatistics(IrpContext);
+ break;
+
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
}
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;
BOOLEAN AvailableClustersValid;
ULONG Flags;
struct _VFATFCB *VolumeFcb;
+ PSTATISTICS Statistics;
/* Pointers to functions for manipulating FAT. */
PGET_NEXT_CLUSTER GetNextCluster;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
+ ULONG NumberProcessors;
ERESOURCE VolumeListLock;
LIST_ENTRY VolumeListHead;
NPAGED_LOOKASIDE_LIST FcbLookasideList;