1 /* $Id: volume.c,v 1.13 2001/11/01 10:41:53 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(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
);
35 LabelLength
= DeviceObject
->Vpb
->VolumeLabelLength
;
37 DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION
) + LabelLength
*sizeof(WCHAR
)));
38 DPRINT("LabelLength %lu\n", LabelLength
);
39 DPRINT("Label %S\n", DeviceObject
->Vpb
->VolumeLabel
);
41 if (*BufferLength
< (sizeof(FILE_FS_VOLUME_INFORMATION
) + LabelLength
*sizeof(WCHAR
)))
42 return(STATUS_BUFFER_OVERFLOW
);
45 FsVolumeInfo
->VolumeSerialNumber
= DeviceObject
->Vpb
->SerialNumber
;
46 FsVolumeInfo
->VolumeLabelLength
= LabelLength
;
47 wcscpy(FsVolumeInfo
->VolumeLabel
, DeviceObject
->Vpb
->VolumeLabel
);
50 FsVolumeInfo
->VolumeCreationTime
.QuadPart
= 0;
51 FsVolumeInfo
->SupportsObjects
= FALSE
;
53 DPRINT("Finished FsdGetFsVolumeInformation()\n");
55 *BufferLength
-= (sizeof(FILE_FS_VOLUME_INFORMATION
) + LabelLength
* sizeof(WCHAR
));
57 DPRINT("BufferLength %lu\n", *BufferLength
);
59 return(STATUS_SUCCESS
);
64 FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo
,
67 DPRINT("FsdGetFsAttributeInformation()\n");
68 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo
);
69 DPRINT("BufferLength %lu\n", *BufferLength
);
70 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6));
72 /* FIXME: This does not work correctly! Why?? */
73 // if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
74 // return(STATUS_BUFFER_OVERFLOW);
76 FsAttributeInfo
->FileSystemAttributes
=
77 FILE_CASE_PRESERVED_NAMES
| FILE_UNICODE_ON_DISK
;
78 FsAttributeInfo
->MaximumComponentNameLength
= 255;
79 FsAttributeInfo
->FileSystemNameLength
= 6;
80 wcscpy(FsAttributeInfo
->FileSystemName
, L
"FAT");
82 DPRINT("Finished FsdGetFsAttributeInformation()\n");
84 *BufferLength
-= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + 6);
85 DPRINT("BufferLength %lu\n", *BufferLength
);
87 return(STATUS_SUCCESS
);
92 FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject
,
93 PFILE_FS_SIZE_INFORMATION FsSizeInfo
,
96 PDEVICE_EXTENSION DeviceExt
;
99 DPRINT("FsdGetFsSizeInformation()\n");
100 DPRINT("FsSizeInfo = %p\n", FsSizeInfo
);
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 if (*BufferLength
< sizeof(FILE_FS_DEVICE_INFORMATION
))
154 return(STATUS_BUFFER_OVERFLOW
);
156 FsDeviceInfo
->DeviceType
= FILE_DEVICE_DISK
;
157 FsDeviceInfo
->Characteristics
= 0; /* FIXME: fix this !! */
159 DPRINT("FsdGetFsDeviceInformation() finished.\n");
161 *BufferLength
-= sizeof(FILE_FS_DEVICE_INFORMATION
);
162 DPRINT("BufferLength %lu\n", *BufferLength
);
164 return(STATUS_SUCCESS
);
169 FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject
,
170 PFILE_FS_LABEL_INFORMATION FsLabelInfo
)
172 DPRINT("FsdSetFsLabelInformation()\n");
174 return(STATUS_NOT_IMPLEMENTED
);
179 VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject
,
182 * FUNCTION: Retrieve the specified volume information
185 PIO_STACK_LOCATION Stack
;
186 FS_INFORMATION_CLASS FsInformationClass
;
187 PFILE_OBJECT FileObject
= NULL
;
189 NTSTATUS RC
= STATUS_SUCCESS
;
194 assert(DeviceObject
!= NULL
);
197 DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
201 Stack
= IoGetCurrentIrpStackLocation (Irp
);
202 FsInformationClass
= Stack
->Parameters
.QueryVolume
.FsInformationClass
;
203 BufferLength
= Stack
->Parameters
.QueryVolume
.Length
;
204 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
205 FileObject
= Stack
->FileObject
;
206 // CCB = (PVfatCCB)(FileObject->FsContext2);
207 // FCB = CCB->Buffer; // Should be CCB->FCB???
208 FCB
= ((PVFATCCB
) (FileObject
->FsContext2
))->pFcb
;
210 DPRINT ("FsInformationClass %d\n", FsInformationClass
);
211 DPRINT ("SystemBuffer %x\n", SystemBuffer
);
213 switch (FsInformationClass
)
215 case FileFsVolumeInformation
:
216 RC
= FsdGetFsVolumeInformation(FileObject
,
223 case FileFsAttributeInformation
:
224 RC
= FsdGetFsAttributeInformation(SystemBuffer
,
228 case FileFsSizeInformation
:
229 RC
= FsdGetFsSizeInformation(DeviceObject
,
234 case FileFsDeviceInformation
:
235 RC
= FsdGetFsDeviceInformation(SystemBuffer
,
240 RC
= STATUS_NOT_SUPPORTED
;
243 Irp
->IoStatus
.Status
= RC
;
245 Irp
->IoStatus
.Information
=
246 Stack
->Parameters
.QueryVolume
.Length
- BufferLength
;
248 Irp
->IoStatus
.Information
= 0;
249 IoCompleteRequest(Irp
,
257 VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject
,
260 * FUNCTION: Set the specified volume information
263 PIO_STACK_LOCATION Stack
;
264 FS_INFORMATION_CLASS FsInformationClass
;
265 // PFILE_OBJECT FileObject = NULL;
266 // PVFATFCB FCB = NULL;
267 NTSTATUS Status
= STATUS_SUCCESS
;
272 assert(DeviceObject
!= NULL
);
275 DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n",
279 Stack
= IoGetCurrentIrpStackLocation(Irp
);
280 FsInformationClass
= Stack
->Parameters
.SetVolume
.FsInformationClass
;
281 BufferLength
= Stack
->Parameters
.SetVolume
.Length
;
282 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
283 // FileObject = Stack->FileObject;
284 // FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
286 DPRINT("FsInformationClass %d\n", FsInformationClass
);
287 DPRINT("BufferLength %d\n", BufferLength
);
288 DPRINT("SystemBuffer %x\n", SystemBuffer
);
290 switch(FsInformationClass
)
292 case FileFsLabelInformation
:
293 Status
= FsdSetFsLabelInformation(DeviceObject
,
298 Status
= STATUS_NOT_SUPPORTED
;
301 Irp
->IoStatus
.Status
= Status
;
302 Irp
->IoStatus
.Information
= 0;
303 IoCompleteRequest(Irp
,