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,
27 DPRINT("FsdGetFsVolumeInformation()\n");
28 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
29 DPRINT("BufferLength %lu\n", *BufferLength);
31 DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength));
32 DPRINT("LabelLength %lu\n", DeviceObject->Vpb->VolumeLabelLength);
33 DPRINT("Label %*.S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel);
35 if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
36 return STATUS_INFO_LENGTH_MISMATCH;
38 if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
39 return STATUS_BUFFER_OVERFLOW;
42 FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
43 FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
44 memcpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength);
47 FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
48 FsVolumeInfo->SupportsObjects = FALSE;
50 DPRINT("Finished FsdGetFsVolumeInformation()\n");
52 *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
54 DPRINT("BufferLength %lu\n", *BufferLength);
56 return(STATUS_SUCCESS);
61 FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
62 PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
65 WCHAR* pName; ULONG Length;
66 DPRINT("FsdGetFsAttributeInformation()\n");
67 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
68 DPRINT("BufferLength %lu\n", *BufferLength);
69 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length));
71 if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
72 return STATUS_INFO_LENGTH_MISMATCH;
74 if (DeviceExt->FatInfo.FatType == FAT32)
85 if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length))
86 return STATUS_BUFFER_OVERFLOW;
88 FsAttributeInfo->FileSystemAttributes =
89 FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
91 FsAttributeInfo->MaximumComponentNameLength = 255;
93 FsAttributeInfo->FileSystemNameLength = Length;
95 memcpy(FsAttributeInfo->FileSystemName, pName, Length );
97 DPRINT("Finished FsdGetFsAttributeInformation()\n");
99 *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length);
100 DPRINT("BufferLength %lu\n", *BufferLength);
102 return(STATUS_SUCCESS);
107 FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
108 PFILE_FS_SIZE_INFORMATION FsSizeInfo,
111 PDEVICE_EXTENSION DeviceExt;
114 DPRINT("FsdGetFsSizeInformation()\n");
115 DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
117 if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
118 return(STATUS_BUFFER_OVERFLOW);
120 DeviceExt = DeviceObject->DeviceExtension;
121 Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits);
123 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->FatInfo.NumberOfClusters;
124 FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->FatInfo.SectorsPerCluster;
125 FsSizeInfo->BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
127 DPRINT("Finished FsdGetFsSizeInformation()\n");
128 if (NT_SUCCESS(Status))
129 *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
136 FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
139 DPRINT("FsdGetFsDeviceInformation()\n");
140 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
141 DPRINT("BufferLength %lu\n", *BufferLength);
142 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
144 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
145 return(STATUS_BUFFER_OVERFLOW);
147 FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
148 FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
150 DPRINT("FsdGetFsDeviceInformation() finished.\n");
152 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
153 DPRINT("BufferLength %lu\n", *BufferLength);
155 return(STATUS_SUCCESS);
160 FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
161 PFILE_FS_LABEL_INFORMATION FsLabelInfo)
163 DPRINT("FsdSetFsLabelInformation()\n");
165 return(STATUS_NOT_IMPLEMENTED);
169 NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
171 * FUNCTION: Retrieve the specified volume information
174 FS_INFORMATION_CLASS FsInformationClass;
175 NTSTATUS RC = STATUS_SUCCESS;
182 DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext);
184 if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
185 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
187 return VfatQueueRequest (IrpContext);
191 FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass;
192 BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length;
193 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
196 DPRINT ("FsInformationClass %d\n", FsInformationClass);
197 DPRINT ("SystemBuffer %x\n", SystemBuffer);
199 switch (FsInformationClass)
201 case FileFsVolumeInformation:
202 RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject,
207 case FileFsAttributeInformation:
208 RC = FsdGetFsAttributeInformation(IrpContext->DeviceObject->DeviceExtension,
213 case FileFsSizeInformation:
214 RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
219 case FileFsDeviceInformation:
220 RC = FsdGetFsDeviceInformation(SystemBuffer,
225 RC = STATUS_NOT_SUPPORTED;
228 ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
229 IrpContext->Irp->IoStatus.Status = RC;
231 IrpContext->Irp->IoStatus.Information =
232 IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
234 IrpContext->Irp->IoStatus.Information = 0;
235 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
236 VfatFreeIrpContext(IrpContext);
242 NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
244 * FUNCTION: Set the specified volume information
247 FS_INFORMATION_CLASS FsInformationClass;
248 NTSTATUS Status = STATUS_SUCCESS;
251 PEXTENDED_IO_STACK_LOCATION Stack = (PEXTENDED_IO_STACK_LOCATION) IrpContext->Stack;
256 DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
258 if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
259 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
261 return VfatQueueRequest (IrpContext);
264 FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass;
265 BufferLength = Stack->Parameters.SetVolume.Length;
266 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
268 DPRINT1("FsInformationClass %d\n", FsInformationClass);
269 DPRINT1("BufferLength %d\n", BufferLength);
270 DPRINT1("SystemBuffer %x\n", SystemBuffer);
272 switch(FsInformationClass)
274 case FileFsLabelInformation:
275 Status = FsdSetFsLabelInformation(IrpContext->DeviceObject,
280 Status = STATUS_NOT_SUPPORTED;
283 ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
284 IrpContext->Irp->IoStatus.Status = Status;
285 IrpContext->Irp->IoStatus.Information = 0;
286 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
287 VfatFreeIrpContext(IrpContext);