3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/vfat/volume.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
10 /* INCLUDES *****************************************************************/
12 #include <ddk/ntddk.h>
20 /* FUNCTIONS ****************************************************************/
23 FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
24 PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
29 DPRINT("FsdGetFsVolumeInformation()\n");
30 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
31 DPRINT("BufferLength %lu\n", *BufferLength);
33 LabelLength = DeviceObject->Vpb->VolumeLabelLength;
35 DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)));
36 DPRINT("LabelLength %lu\n", LabelLength);
37 DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
39 if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
40 return STATUS_INFO_LENGTH_MISMATCH;
42 if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
43 return STATUS_BUFFER_OVERFLOW;
46 FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
47 FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
48 wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
51 FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
52 FsVolumeInfo->SupportsObjects = FALSE;
54 DPRINT("Finished FsdGetFsVolumeInformation()\n");
56 *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR));
58 DPRINT("BufferLength %lu\n", *BufferLength);
60 return(STATUS_SUCCESS);
65 FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
66 PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
69 ULONG Length = DeviceExt->FatInfo.FatType == FAT32 ? 10 : 6;
71 DPRINT("FsdGetFsAttributeInformation()\n");
72 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
73 DPRINT("BufferLength %lu\n", *BufferLength);
74 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length));
76 if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
77 return STATUS_INFO_LENGTH_MISMATCH;
79 if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length))
80 return STATUS_BUFFER_OVERFLOW;
82 FsAttributeInfo->FileSystemAttributes =
83 FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
84 FsAttributeInfo->MaximumComponentNameLength = 255;
85 FsAttributeInfo->FileSystemNameLength = Length;
86 if (DeviceExt->FatInfo.FatType == FAT32)
88 memcpy(FsAttributeInfo->FileSystemName, L"FAT32", 10);
92 memcpy(FsAttributeInfo->FileSystemName, L"FAT", 6);
95 DPRINT("Finished FsdGetFsAttributeInformation()\n");
97 *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length);
98 DPRINT("BufferLength %lu\n", *BufferLength);
100 return(STATUS_SUCCESS);
105 FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
106 PFILE_FS_SIZE_INFORMATION FsSizeInfo,
109 PDEVICE_EXTENSION DeviceExt;
112 DPRINT("FsdGetFsSizeInformation()\n");
113 DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
115 if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
116 return(STATUS_BUFFER_OVERFLOW);
118 DeviceExt = DeviceObject->DeviceExtension;
119 Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits);
121 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->FatInfo.NumberOfClusters;
122 FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->FatInfo.SectorsPerCluster;
123 FsSizeInfo->BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
125 DPRINT("Finished FsdGetFsSizeInformation()\n");
126 if (NT_SUCCESS(Status))
127 *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
134 FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
137 DPRINT("FsdGetFsDeviceInformation()\n");
138 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
139 DPRINT("BufferLength %lu\n", *BufferLength);
140 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
142 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
143 return(STATUS_BUFFER_OVERFLOW);
145 FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
146 FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
148 DPRINT("FsdGetFsDeviceInformation() finished.\n");
150 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
151 DPRINT("BufferLength %lu\n", *BufferLength);
153 return(STATUS_SUCCESS);
158 FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
159 PFILE_FS_LABEL_INFORMATION FsLabelInfo)
161 DPRINT("FsdSetFsLabelInformation()\n");
163 return(STATUS_NOT_IMPLEMENTED);
167 NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
169 * FUNCTION: Retrieve the specified volume information
172 FS_INFORMATION_CLASS FsInformationClass;
173 NTSTATUS RC = STATUS_SUCCESS;
180 DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext);
182 if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
184 return VfatQueueRequest (IrpContext);
188 FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass;
189 BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length;
190 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
193 DPRINT ("FsInformationClass %d\n", FsInformationClass);
194 DPRINT ("SystemBuffer %x\n", SystemBuffer);
196 switch (FsInformationClass)
198 case FileFsVolumeInformation:
199 RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject,
204 case FileFsAttributeInformation:
205 RC = FsdGetFsAttributeInformation(IrpContext->DeviceObject->DeviceExtension,
210 case FileFsSizeInformation:
211 RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
216 case FileFsDeviceInformation:
217 RC = FsdGetFsDeviceInformation(SystemBuffer,
222 RC = STATUS_NOT_SUPPORTED;
225 ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
226 IrpContext->Irp->IoStatus.Status = RC;
228 IrpContext->Irp->IoStatus.Information =
229 IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
231 IrpContext->Irp->IoStatus.Information = 0;
232 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
233 VfatFreeIrpContext(IrpContext);
239 NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
241 * FUNCTION: Set the specified volume information
244 FS_INFORMATION_CLASS FsInformationClass;
245 NTSTATUS Status = STATUS_SUCCESS;
252 DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
254 if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
256 return VfatQueueRequest (IrpContext);
259 FsInformationClass = IrpContext->Stack->Parameters.SetVolume.FsInformationClass;
260 BufferLength = IrpContext->Stack->Parameters.SetVolume.Length;
261 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
263 DPRINT1("FsInformationClass %d\n", FsInformationClass);
264 DPRINT1("BufferLength %d\n", BufferLength);
265 DPRINT1("SystemBuffer %x\n", SystemBuffer);
267 switch(FsInformationClass)
269 case FileFsLabelInformation:
270 Status = FsdSetFsLabelInformation(IrpContext->DeviceObject,
275 Status = STATUS_NOT_SUPPORTED;
278 ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
279 IrpContext->Irp->IoStatus.Status = Status;
280 IrpContext->Irp->IoStatus.Information = 0;
281 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
282 VfatFreeIrpContext(IrpContext);