1 /* $Id: volume.c,v 1.16 2002/09/07 15:12:03 chorns 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(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
;
248 PEXTENDED_IO_STACK_LOCATION IoStack
;
253 DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext
);
255 if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
, IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
257 return VfatQueueRequest (IrpContext
);
260 IoStack
= (PEXTENDED_IO_STACK_LOCATION
)IrpContext
->Stack
;
261 FsInformationClass
= IoStack
->Parameters
.SetVolume
.FsInformationClass
;
262 BufferLength
= IoStack
->Parameters
.SetVolume
.Length
;
263 SystemBuffer
= IrpContext
->Irp
->AssociatedIrp
.SystemBuffer
;
265 DPRINT1("FsInformationClass %d\n", FsInformationClass
);
266 DPRINT1("BufferLength %d\n", BufferLength
);
267 DPRINT1("SystemBuffer %x\n", SystemBuffer
);
269 switch(FsInformationClass
)
271 case FileFsLabelInformation
:
272 Status
= FsdSetFsLabelInformation(IrpContext
->DeviceObject
,
277 Status
= STATUS_NOT_SUPPORTED
;
280 ExReleaseResourceLite(&((PDEVICE_EXTENSION
)IrpContext
->DeviceObject
->DeviceExtension
)->DirResource
);
281 IrpContext
->Irp
->IoStatus
.Status
= Status
;
282 IrpContext
->Irp
->IoStatus
.Information
= 0;
283 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
284 VfatFreeIrpContext(IrpContext
);