1 /* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $
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(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo
,
68 DPRINT("FsdGetFsAttributeInformation()\n");
69 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo
);
70 DPRINT("BufferLength %lu\n", *BufferLength
);
71 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6));
73 if (*BufferLength
< sizeof (FILE_FS_ATTRIBUTE_INFORMATION
))
74 return STATUS_INFO_LENGTH_MISMATCH
;
76 if (*BufferLength
< (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6))
77 return STATUS_BUFFER_OVERFLOW
;
79 FsAttributeInfo
->FileSystemAttributes
=
80 FILE_CASE_PRESERVED_NAMES
| FILE_UNICODE_ON_DISK
;
81 FsAttributeInfo
->MaximumComponentNameLength
= 255;
82 FsAttributeInfo
->FileSystemNameLength
= 6;
83 wcscpy(FsAttributeInfo
->FileSystemName
, L
"FAT");
85 DPRINT("Finished FsdGetFsAttributeInformation()\n");
87 *BufferLength
-= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6);
88 DPRINT("BufferLength %lu\n", *BufferLength
);
90 return(STATUS_SUCCESS
);
95 FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject
,
96 PFILE_FS_SIZE_INFORMATION FsSizeInfo
,
99 PDEVICE_EXTENSION DeviceExt
;
102 DPRINT("FsdGetFsSizeInformation()\n");
103 DPRINT("FsSizeInfo = %p\n", FsSizeInfo
);
105 if (*BufferLength
< sizeof(FILE_FS_SIZE_INFORMATION
))
106 return(STATUS_BUFFER_OVERFLOW
);
108 DeviceExt
= DeviceObject
->DeviceExtension
;
110 if (DeviceExt
->FatType
== FAT32
)
112 struct _BootSector32
*BootSect
=
113 (struct _BootSector32
*) DeviceExt
->Boot
;
115 FsSizeInfo
->TotalAllocationUnits
.QuadPart
= ((BootSect
->Sectors
? BootSect
->Sectors
: BootSect
->SectorsHuge
)-DeviceExt
->dataStart
)/BootSect
->SectorsPerCluster
;
117 Status
= FAT32CountAvailableClusters(DeviceExt
,
118 &FsSizeInfo
->AvailableAllocationUnits
);
120 FsSizeInfo
->SectorsPerAllocationUnit
= BootSect
->SectorsPerCluster
;
121 FsSizeInfo
->BytesPerSector
= BootSect
->BytesPerSector
;
125 struct _BootSector
*BootSect
= (struct _BootSector
*) DeviceExt
->Boot
;
127 FsSizeInfo
->TotalAllocationUnits
.QuadPart
= ((BootSect
->Sectors
? BootSect
->Sectors
: BootSect
->SectorsHuge
)-DeviceExt
->dataStart
)/BootSect
->SectorsPerCluster
;
129 if (DeviceExt
->FatType
== FAT16
)
130 Status
= FAT16CountAvailableClusters(DeviceExt
,
131 &FsSizeInfo
->AvailableAllocationUnits
);
133 Status
= FAT12CountAvailableClusters(DeviceExt
,
134 &FsSizeInfo
->AvailableAllocationUnits
);
135 FsSizeInfo
->SectorsPerAllocationUnit
= BootSect
->SectorsPerCluster
;
136 FsSizeInfo
->BytesPerSector
= BootSect
->BytesPerSector
;
139 DPRINT("Finished FsdGetFsSizeInformation()\n");
140 if (NT_SUCCESS(Status
))
141 *BufferLength
-= sizeof(FILE_FS_SIZE_INFORMATION
);
148 FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo
,
151 DPRINT("FsdGetFsDeviceInformation()\n");
152 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo
);
153 DPRINT("BufferLength %lu\n", *BufferLength
);
154 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION
));
156 if (*BufferLength
< sizeof(FILE_FS_DEVICE_INFORMATION
))
157 return(STATUS_BUFFER_OVERFLOW
);
159 FsDeviceInfo
->DeviceType
= FILE_DEVICE_DISK
;
160 FsDeviceInfo
->Characteristics
= 0; /* FIXME: fix this !! */
162 DPRINT("FsdGetFsDeviceInformation() finished.\n");
164 *BufferLength
-= sizeof(FILE_FS_DEVICE_INFORMATION
);
165 DPRINT("BufferLength %lu\n", *BufferLength
);
167 return(STATUS_SUCCESS
);
172 FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject
,
173 PFILE_FS_LABEL_INFORMATION FsLabelInfo
)
175 DPRINT("FsdSetFsLabelInformation()\n");
177 return(STATUS_NOT_IMPLEMENTED
);
181 NTSTATUS
VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext
)
183 * FUNCTION: Retrieve the specified volume information
186 FS_INFORMATION_CLASS FsInformationClass
;
187 NTSTATUS RC
= STATUS_SUCCESS
;
194 DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext
);
196 if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
, IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
198 return VfatQueueRequest (IrpContext
);
202 FsInformationClass
= IrpContext
->Stack
->Parameters
.QueryVolume
.FsInformationClass
;
203 BufferLength
= IrpContext
->Stack
->Parameters
.QueryVolume
.Length
;
204 SystemBuffer
= IrpContext
->Irp
->AssociatedIrp
.SystemBuffer
;
207 DPRINT ("FsInformationClass %d\n", FsInformationClass
);
208 DPRINT ("SystemBuffer %x\n", SystemBuffer
);
210 switch (FsInformationClass
)
212 case FileFsVolumeInformation
:
213 RC
= FsdGetFsVolumeInformation(IrpContext
->DeviceObject
,
218 case FileFsAttributeInformation
:
219 RC
= FsdGetFsAttributeInformation(SystemBuffer
,
223 case FileFsSizeInformation
:
224 RC
= FsdGetFsSizeInformation(IrpContext
->DeviceObject
,
229 case FileFsDeviceInformation
:
230 RC
= FsdGetFsDeviceInformation(SystemBuffer
,
235 RC
= STATUS_NOT_SUPPORTED
;
238 ExReleaseResourceLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
);
239 IrpContext
->Irp
->IoStatus
.Status
= RC
;
241 IrpContext
->Irp
->IoStatus
.Information
=
242 IrpContext
->Stack
->Parameters
.QueryVolume
.Length
- BufferLength
;
244 IrpContext
->Irp
->IoStatus
.Information
= 0;
245 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
246 VfatFreeIrpContext(IrpContext
);
252 NTSTATUS
VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext
)
254 * FUNCTION: Set the specified volume information
257 FS_INFORMATION_CLASS FsInformationClass
;
258 NTSTATUS Status
= STATUS_SUCCESS
;
265 DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext
);
267 if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
, IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
269 return VfatQueueRequest (IrpContext
);
272 FsInformationClass
= IrpContext
->Stack
->Parameters
.SetVolume
.FsInformationClass
;
273 BufferLength
= IrpContext
->Stack
->Parameters
.SetVolume
.Length
;
274 SystemBuffer
= IrpContext
->Irp
->AssociatedIrp
.SystemBuffer
;
276 DPRINT1("FsInformationClass %d\n", FsInformationClass
);
277 DPRINT1("BufferLength %d\n", BufferLength
);
278 DPRINT1("SystemBuffer %x\n", SystemBuffer
);
280 switch(FsInformationClass
)
282 case FileFsLabelInformation
:
283 Status
= FsdSetFsLabelInformation(IrpContext
->DeviceObject
,
288 Status
= STATUS_NOT_SUPPORTED
;
291 ExReleaseResourceLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
);
292 IrpContext
->Irp
->IoStatus
.Status
= Status
;
293 IrpContext
->Irp
->IoStatus
.Information
= 0;
294 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
295 VfatFreeIrpContext(IrpContext
);