1 /* $Id: volume.c,v 1.11 2001/07/20 08:00:21 ekohl 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(PFILE_OBJECT FileObject
,
25 PDEVICE_OBJECT DeviceObject
,
26 PFILE_FS_VOLUME_INFORMATION FsVolumeInfo
,
31 DPRINT("FsdGetFsVolumeInformation()\n");
32 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo
);
33 DPRINT("BufferLength %lu\n", *BufferLength
);
34 DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION
) + LabelLength
));
36 LabelLength
= DeviceObject
->Vpb
->VolumeLabelLength
;
37 DPRINT("LabelLength %lu\n", LabelLength
);
39 /* FIXME: This does not work correctly! Why?? */
40 // if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength));
41 // return(STATUS_BUFFER_OVERFLOW);
44 FsVolumeInfo
->VolumeSerialNumber
= DeviceObject
->Vpb
->SerialNumber
;
45 FsVolumeInfo
->VolumeLabelLength
= LabelLength
;
46 wcscpy(FsVolumeInfo
->VolumeLabel
, DeviceObject
->Vpb
->VolumeLabel
);
49 FsVolumeInfo
->VolumeCreationTime
.QuadPart
= 0;
50 FsVolumeInfo
->SupportsObjects
= FALSE
;
52 DPRINT("Finished FsdGetFsVolumeInformation()\n");
54 *BufferLength
-= (sizeof(FILE_FS_VOLUME_INFORMATION
) + LabelLength
);
56 DPRINT("BufferLength %lu\n", *BufferLength
);
58 return(STATUS_SUCCESS
);
63 FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo
,
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
) + 6));
71 /* FIXME: This does not work correctly! Why?? */
72 // if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
73 // return(STATUS_BUFFER_OVERFLOW);
75 FsAttributeInfo
->FileSystemAttributes
=
76 FILE_CASE_PRESERVED_NAMES
| FILE_UNICODE_ON_DISK
;
77 FsAttributeInfo
->MaximumComponentNameLength
= 255;
78 FsAttributeInfo
->FileSystemNameLength
= 6;
79 wcscpy(FsAttributeInfo
->FileSystemName
, L
"FAT");
81 DPRINT("Finished FsdGetFsAttributeInformation()\n");
83 *BufferLength
-= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6);
84 DPRINT("BufferLength %lu\n", *BufferLength
);
86 return(STATUS_SUCCESS
);
91 FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject
,
92 PFILE_FS_SIZE_INFORMATION FsSizeInfo
,
95 PDEVICE_EXTENSION DeviceExt
;
98 DPRINT("FsdGetFsSizeInformation()\n");
99 DPRINT("FsSizeInfo = %p\n", FsSizeInfo
);
101 /* FIXME: This does not work correctly! Why?? */
102 // if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION));
103 // return(STATUS_BUFFER_OVERFLOW);
105 DeviceExt
= DeviceObject
->DeviceExtension
;
107 if (DeviceExt
->FatType
== FAT32
)
109 struct _BootSector32
*BootSect
=
110 (struct _BootSector32
*) DeviceExt
->Boot
;
112 FsSizeInfo
->TotalAllocationUnits
.QuadPart
= ((BootSect
->Sectors
? BootSect
->Sectors
: BootSect
->SectorsHuge
)-DeviceExt
->dataStart
)/BootSect
->SectorsPerCluster
;
114 Status
= FAT32CountAvailableClusters(DeviceExt
,
115 &FsSizeInfo
->AvailableAllocationUnits
);
117 FsSizeInfo
->SectorsPerAllocationUnit
= BootSect
->SectorsPerCluster
;
118 FsSizeInfo
->BytesPerSector
= BootSect
->BytesPerSector
;
122 struct _BootSector
*BootSect
= (struct _BootSector
*) DeviceExt
->Boot
;
124 FsSizeInfo
->TotalAllocationUnits
.QuadPart
= ((BootSect
->Sectors
? BootSect
->Sectors
: BootSect
->SectorsHuge
)-DeviceExt
->dataStart
)/BootSect
->SectorsPerCluster
;
126 if (DeviceExt
->FatType
== FAT16
)
127 Status
= FAT16CountAvailableClusters(DeviceExt
,
128 &FsSizeInfo
->AvailableAllocationUnits
);
130 Status
= FAT12CountAvailableClusters(DeviceExt
,
131 &FsSizeInfo
->AvailableAllocationUnits
);
132 FsSizeInfo
->SectorsPerAllocationUnit
= BootSect
->SectorsPerCluster
;
133 FsSizeInfo
->BytesPerSector
= BootSect
->BytesPerSector
;
136 DPRINT("Finished FsdGetFsSizeInformation()\n");
137 if (NT_SUCCESS(Status
))
138 *BufferLength
-= sizeof(FILE_FS_SIZE_INFORMATION
);
145 FsdGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo
,
148 DPRINT("FsdGetFsDeviceInformation()\n");
149 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo
);
150 DPRINT("BufferLength %lu\n", *BufferLength
);
151 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION
));
153 /* FIXME: This does not work correctly! Why?? */
154 // if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION));
155 // return(STATUS_BUFFER_OVERFLOW);
157 FsDeviceInfo
->DeviceType
= FILE_DEVICE_DISK
;
158 FsDeviceInfo
->Characteristics
= 0; /* FIXME: fix this !! */
160 DPRINT("FsdGetFsDeviceInformation() finished.\n");
162 *BufferLength
-= sizeof(FILE_FS_DEVICE_INFORMATION
);
163 DPRINT("BufferLength %lu\n", *BufferLength
);
165 return(STATUS_SUCCESS
);
170 FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject
,
171 PFILE_FS_LABEL_INFORMATION FsLabelInfo
)
173 DPRINT("FsdSetFsLabelInformation()\n");
175 return(STATUS_NOT_IMPLEMENTED
);
180 VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject
,
183 * FUNCTION: Retrieve the specified volume information
186 PIO_STACK_LOCATION Stack
;
187 FS_INFORMATION_CLASS FsInformationClass
;
188 PFILE_OBJECT FileObject
= NULL
;
190 NTSTATUS RC
= STATUS_SUCCESS
;
195 assert(DeviceObject
!= NULL
);
198 DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
202 Stack
= IoGetCurrentIrpStackLocation (Irp
);
203 FsInformationClass
= Stack
->Parameters
.QueryVolume
.FsInformationClass
;
204 BufferLength
= Stack
->Parameters
.QueryVolume
.Length
;
205 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
206 FileObject
= Stack
->FileObject
;
207 // CCB = (PVfatCCB)(FileObject->FsContext2);
208 // FCB = CCB->Buffer; // Should be CCB->FCB???
209 FCB
= ((PVFATCCB
) (FileObject
->FsContext2
))->pFcb
;
211 DPRINT ("FsInformationClass %d\n", FsInformationClass
);
212 DPRINT ("SystemBuffer %x\n", SystemBuffer
);
214 switch (FsInformationClass
)
216 case FileFsVolumeInformation
:
217 RC
= FsdGetFsVolumeInformation(FileObject
,
224 case FileFsAttributeInformation
:
225 RC
= FsdGetFsAttributeInformation(SystemBuffer
,
229 case FileFsSizeInformation
:
230 RC
= FsdGetFsSizeInformation(DeviceObject
,
235 case FileFsDeviceInformation
:
236 RC
= FsdGetFsDeviceInformation(SystemBuffer
,
241 RC
= STATUS_NOT_SUPPORTED
;
244 Irp
->IoStatus
.Status
= RC
;
246 Irp
->IoStatus
.Information
=
247 Stack
->Parameters
.QueryVolume
.Length
- BufferLength
;
249 Irp
->IoStatus
.Information
= 0;
250 IoCompleteRequest(Irp
,
258 VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject
,
261 * FUNCTION: Set the specified volume information
264 PIO_STACK_LOCATION Stack
;
265 FS_INFORMATION_CLASS FsInformationClass
;
266 // PFILE_OBJECT FileObject = NULL;
267 // PVFATFCB FCB = NULL;
268 NTSTATUS Status
= STATUS_SUCCESS
;
273 assert(DeviceObject
!= NULL
);
276 DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n",
280 Stack
= IoGetCurrentIrpStackLocation(Irp
);
281 FsInformationClass
= Stack
->Parameters
.SetVolume
.FsInformationClass
;
282 BufferLength
= Stack
->Parameters
.SetVolume
.Length
;
283 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
284 // FileObject = Stack->FileObject;
285 // FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
287 DPRINT("FsInformationClass %d\n", FsInformationClass
);
288 DPRINT("BufferLength %d\n", BufferLength
);
289 DPRINT("SystemBuffer %x\n", SystemBuffer
);
291 switch(FsInformationClass
)
293 case FileFsLabelInformation
:
294 Status
= FsdSetFsLabelInformation(DeviceObject
,
299 Status
= STATUS_NOT_SUPPORTED
;
302 Irp
->IoStatus
.Status
= Status
;
303 Irp
->IoStatus
.Information
= 0;
304 IoCompleteRequest(Irp
,