2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GNU GPLv3 as published by the Free Software Foundation
4 * FILE: drivers/filesystems/fastfat/volume.c
5 * PURPOSE: Volume information
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS ****************************************************************/
18 FatiQueryFsVolumeInfo(PVCB Vcb
,
19 PFILE_FS_VOLUME_INFORMATION Buffer
,
23 NTSTATUS Status
= STATUS_SUCCESS
;
25 /* Deduct the minimum written length */
26 *Length
-= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
[0]);
29 RtlZeroMemory(Buffer
, sizeof(FILE_FS_VOLUME_INFORMATION
));
31 DPRINT("Serial number 0x%x, label length %d\n",
32 Vcb
->Vpb
->SerialNumber
, Vcb
->Vpb
->VolumeLabelLength
);
34 /* Save serial number */
35 Buffer
->VolumeSerialNumber
= Vcb
->Vpb
->SerialNumber
;
37 /* Set max byte size */
38 ByteSize
= Vcb
->Vpb
->VolumeLabelLength
;
40 /* Check buffer length and reduce byte size if needed */
41 if (*Length
< Vcb
->Vpb
->VolumeLabelLength
)
43 /* Copy only up to what buffer size was provided */
45 Status
= STATUS_BUFFER_OVERFLOW
;
48 /* Copy volume label */
49 Buffer
->VolumeLabelLength
= Vcb
->Vpb
->VolumeLabelLength
;
50 RtlCopyMemory(Buffer
->VolumeLabel
, Vcb
->Vpb
->VolumeLabel
, ByteSize
);
58 FatiQueryFsSizeInfo(PVCB Vcb
,
59 PFILE_FS_SIZE_INFORMATION Buffer
,
62 FF_PARTITION
*Partition
;
63 NTSTATUS Status
= STATUS_SUCCESS
;
65 /* Deduct the minimum written length */
66 *Length
-= sizeof(FILE_FS_SIZE_INFORMATION
);
69 RtlZeroMemory(Buffer
, sizeof(FILE_FS_SIZE_INFORMATION
));
71 /* Reference FullFAT's partition */
72 Partition
= Vcb
->Ioman
->pPartition
;
75 Buffer
->AvailableAllocationUnits
.LowPart
= Partition
->FreeClusterCount
;
76 Buffer
->TotalAllocationUnits
.LowPart
= Partition
->NumClusters
;
77 Buffer
->SectorsPerAllocationUnit
= Vcb
->Bpb
.SectorsPerCluster
;
78 Buffer
->BytesPerSector
= Vcb
->Bpb
.BytesPerSector
;
80 DPRINT1("Total %d, free %d, SPC %d, BPS %d\n", Partition
->NumClusters
,
81 Partition
->FreeClusterCount
, Vcb
->Bpb
.SectorsPerCluster
, Vcb
->Bpb
.BytesPerSector
);
88 FatiQueryFsDeviceInfo(PVCB Vcb
,
89 PFILE_FS_DEVICE_INFORMATION Buffer
,
92 /* Deduct the minimum written length */
93 *Length
-= sizeof(FILE_FS_DEVICE_INFORMATION
);
96 RtlZeroMemory(Buffer
, sizeof(FILE_FS_DEVICE_INFORMATION
));
99 Buffer
->DeviceType
= FILE_DEVICE_DISK
;
100 Buffer
->Characteristics
= Vcb
->TargetDeviceObject
->Characteristics
;
102 return STATUS_SUCCESS
;
107 FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext
, PIRP Irp
)
109 PFILE_OBJECT FileObject
;
110 PIO_STACK_LOCATION IrpSp
;
111 FILE_INFORMATION_CLASS InfoClass
;
112 TYPE_OF_OPEN FileType
;
118 BOOLEAN VcbLocked
= FALSE
;
119 NTSTATUS Status
= STATUS_SUCCESS
;
121 /* Get IRP stack location */
122 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
124 /* Get the file object */
125 FileObject
= IrpSp
->FileObject
;
127 /* Copy variables to something with shorter names */
128 InfoClass
= IrpSp
->Parameters
.QueryVolume
.FsInformationClass
;
129 Length
= IrpSp
->Parameters
.QueryVolume
.Length
;
130 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
132 DPRINT("FatiQueryVolumeInfo\n", 0);
133 DPRINT("\tIrp = %08lx\n", Irp
);
134 DPRINT("\tLength = %08lx\n", Length
);
135 DPRINT("\tFsInformationClass = %08lx\n", InfoClass
);
136 DPRINT("\tBuffer = %08lx\n", Buffer
);
138 FileType
= FatDecodeFileObject(FileObject
, &Vcb
, &Fcb
, &Ccb
);
140 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb
, Fcb
, Ccb
, FileType
);
144 case FileFsVolumeInformation
:
145 /* Acquired the shared VCB lock */
146 if (!FatAcquireSharedVcb(IrpContext
, Vcb
))
151 /* Remember we locked it */
154 /* Call FsVolumeInfo handler */
155 Status
= FatiQueryFsVolumeInfo(Vcb
, Buffer
, &Length
);
158 case FileFsSizeInformation
:
159 /* Call FsVolumeInfo handler */
160 Status
= FatiQueryFsSizeInfo(Vcb
, Buffer
, &Length
);
163 case FileFsDeviceInformation
:
164 Status
= FatiQueryFsDeviceInfo(Vcb
, Buffer
, &Length
);
167 case FileFsAttributeInformation
:
169 //Status = FatiQueryFsAttributeInfo(IrpContext, Vcb, Buffer, &Length);
172 case FileFsFullSizeInformation
:
174 //Status = FatiQueryFsFullSizeInfo(IrpContext, Vcb, Buffer, &Length);
178 Status
= STATUS_INVALID_PARAMETER
;
181 /* Set IoStatus.Information to amount of filled bytes */
182 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryVolume
.Length
- Length
;
184 /* Release VCB lock */
185 if (VcbLocked
) FatReleaseVcb(IrpContext
, Vcb
);
187 /* Complete request and return status */
188 FatCompleteRequest(IrpContext
, Irp
, Status
);
194 FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
197 BOOLEAN TopLevel
, CanWait
;
198 PFAT_IRP_CONTEXT IrpContext
;
202 Status
= STATUS_INVALID_DEVICE_REQUEST
;
204 /* Get CanWait flag */
205 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
!= NULL
)
206 CanWait
= IoIsOperationSynchronous(Irp
);
208 /* Enter FsRtl critical region */
209 FsRtlEnterFileSystem();
211 /* Set Top Level IRP if not set */
212 TopLevel
= FatIsTopLevelIrp(Irp
);
214 /* Build an irp context */
215 IrpContext
= FatBuildIrpContext(Irp
, CanWait
);
217 /* Call the request handler */
218 Status
= FatiQueryVolumeInfo(IrpContext
, Irp
);
220 /* Restore top level Irp */
222 IoSetTopLevelIrp(NULL
);
224 /* Leave FsRtl critical region */
225 FsRtlExitFileSystem();
232 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
234 DPRINT1("FatSetVolumeInfo()\n");
235 return STATUS_NOT_IMPLEMENTED
;
240 FatReadStreamFile(PVCB Vcb
,
241 ULONGLONG ByteOffset
,
246 LARGE_INTEGER Offset
;
248 Offset
.QuadPart
= ByteOffset
;
250 if (!CcMapData(Vcb
->StreamFileObject
,
253 TRUE
, // FIXME: CanWait
263 FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext
,
267 /* We never allow deletion of a volume for now */