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
->FreeClusterCount
,
81 Partition
->NumClusters
, Vcb
->Bpb
.SectorsPerCluster
, Vcb
->Bpb
.BytesPerSector
);
88 FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext
, PIRP Irp
)
90 PFILE_OBJECT FileObject
;
91 PIO_STACK_LOCATION IrpSp
;
92 FILE_INFORMATION_CLASS InfoClass
;
93 TYPE_OF_OPEN FileType
;
99 BOOLEAN VcbLocked
= FALSE
;
100 NTSTATUS Status
= STATUS_SUCCESS
;
102 /* Get IRP stack location */
103 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
105 /* Get the file object */
106 FileObject
= IrpSp
->FileObject
;
108 /* Copy variables to something with shorter names */
109 InfoClass
= IrpSp
->Parameters
.QueryVolume
.FsInformationClass
;
110 Length
= IrpSp
->Parameters
.QueryVolume
.Length
;
111 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
113 DPRINT("FatiQueryVolumeInfo\n", 0);
114 DPRINT("\tIrp = %08lx\n", Irp
);
115 DPRINT("\tLength = %08lx\n", Length
);
116 DPRINT("\tFsInformationClass = %08lx\n", InfoClass
);
117 DPRINT("\tBuffer = %08lx\n", Buffer
);
119 FileType
= FatDecodeFileObject(FileObject
, &Vcb
, &Fcb
, &Ccb
);
121 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb
, Fcb
, Ccb
, FileType
);
125 case FileFsVolumeInformation
:
126 /* Acquired the shared VCB lock */
127 if (!FatAcquireSharedVcb(IrpContext
, Vcb
))
132 /* Remember we locked it */
135 /* Call FsVolumeInfo handler */
136 Status
= FatiQueryFsVolumeInfo(Vcb
, Buffer
, &Length
);
138 case FileFsSizeInformation
:
139 /* Call FsVolumeInfo handler */
140 Status
= FatiQueryFsSizeInfo(Vcb
, Buffer
, &Length
);
143 DPRINT1("Volume information class %d is not supported!\n", InfoClass
);
147 /* Set IoStatus.Information to amount of filled bytes */
148 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryVolume
.Length
- Length
;
150 /* Release VCB lock */
151 if (VcbLocked
) FatReleaseVcb(IrpContext
, Vcb
);
153 /* Complete request and return status */
154 FatCompleteRequest(IrpContext
, Irp
, Status
);
160 FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
163 BOOLEAN TopLevel
, CanWait
;
164 PFAT_IRP_CONTEXT IrpContext
;
168 Status
= STATUS_INVALID_DEVICE_REQUEST
;
170 /* Get CanWait flag */
171 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
!= NULL
)
172 CanWait
= IoIsOperationSynchronous(Irp
);
174 /* Enter FsRtl critical region */
175 FsRtlEnterFileSystem();
177 /* Set Top Level IRP if not set */
178 if (IoGetTopLevelIrp() == NULL
)
180 IoSetTopLevelIrp(Irp
);
184 /* Build an irp context */
185 IrpContext
= FatBuildIrpContext(Irp
, CanWait
);
187 /* Call the request handler */
188 Status
= FatiQueryVolumeInfo(IrpContext
, Irp
);
190 /* Restore top level Irp */
192 IoSetTopLevelIrp(NULL
);
194 /* Leave FsRtl critical region */
195 FsRtlExitFileSystem();
202 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
204 DPRINT1("FatSetVolumeInfo()\n");
205 return STATUS_NOT_IMPLEMENTED
;
210 FatReadStreamFile(PVCB Vcb
,
211 ULONGLONG ByteOffset
,
216 LARGE_INTEGER Offset
;
218 Offset
.QuadPart
= ByteOffset
;
220 if (!CcMapData(Vcb
->StreamFileObject
,
223 TRUE
, // FIXME: CanWait