Sync with trunk (r48545)
[reactos.git] / drivers / filesystems / fastfat_new / volume.c
1 /*
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)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define NDEBUG
12 #include "fastfat.h"
13
14 /* FUNCTIONS ****************************************************************/
15
16 NTSTATUS
17 NTAPI
18 FatiQueryFsVolumeInfo(PVCB Vcb,
19 PFILE_FS_VOLUME_INFORMATION Buffer,
20 PLONG Length)
21 {
22 ULONG ByteSize;
23 NTSTATUS Status = STATUS_SUCCESS;
24
25 /* Deduct the minimum written length */
26 *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
27
28 /* Zero it */
29 RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION));
30
31 DPRINT("Serial number 0x%x, label length %d\n",
32 Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength);
33
34 /* Save serial number */
35 Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
36
37 /* Set max byte size */
38 ByteSize = Vcb->Vpb->VolumeLabelLength;
39
40 /* Check buffer length and reduce byte size if needed */
41 if (*Length < Vcb->Vpb->VolumeLabelLength)
42 {
43 /* Copy only up to what buffer size was provided */
44 ByteSize = *Length;
45 Status = STATUS_BUFFER_OVERFLOW;
46 }
47
48 /* Copy volume label */
49 Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
50 RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize);
51 *Length -= ByteSize;
52
53 return Status;
54 }
55
56 NTSTATUS
57 NTAPI
58 FatiQueryFsSizeInfo(PVCB Vcb,
59 PFILE_FS_SIZE_INFORMATION Buffer,
60 PLONG Length)
61 {
62 FF_PARTITION *Partition;
63 NTSTATUS Status = STATUS_SUCCESS;
64
65 /* Deduct the minimum written length */
66 *Length -= sizeof(FILE_FS_SIZE_INFORMATION);
67
68 /* Zero it */
69 RtlZeroMemory(Buffer, sizeof(FILE_FS_SIZE_INFORMATION));
70
71 /* Reference FullFAT's partition */
72 Partition = Vcb->Ioman->pPartition;
73
74 /* Set values */
75 Buffer->AvailableAllocationUnits.LowPart = Partition->FreeClusterCount;
76 Buffer->TotalAllocationUnits.LowPart = Partition->NumClusters;
77 Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster;
78 Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector;
79
80 DPRINT1("Total %d, free %d, SPC %d, BPS %d\n", Partition->NumClusters,
81 Partition->FreeClusterCount, Vcb->Bpb.SectorsPerCluster, Vcb->Bpb.BytesPerSector);
82
83 return Status;
84 }
85
86 NTSTATUS
87 NTAPI
88 FatiQueryFsDeviceInfo(PVCB Vcb,
89 PFILE_FS_DEVICE_INFORMATION Buffer,
90 PLONG Length)
91 {
92 /* Deduct the minimum written length */
93 *Length -= sizeof(FILE_FS_DEVICE_INFORMATION);
94
95 /* Zero it */
96 RtlZeroMemory(Buffer, sizeof(FILE_FS_DEVICE_INFORMATION));
97
98 /* Set values */
99 Buffer->DeviceType = FILE_DEVICE_DISK;
100 Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
101
102 return STATUS_SUCCESS;
103 }
104
105 NTSTATUS
106 NTAPI
107 FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
108 {
109 PFILE_OBJECT FileObject;
110 PIO_STACK_LOCATION IrpSp;
111 FILE_INFORMATION_CLASS InfoClass;
112 TYPE_OF_OPEN FileType;
113 PVCB Vcb;
114 PFCB Fcb;
115 PCCB Ccb;
116 LONG Length;
117 PVOID Buffer;
118 BOOLEAN VcbLocked = FALSE;
119 NTSTATUS Status = STATUS_SUCCESS;
120
121 /* Get IRP stack location */
122 IrpSp = IoGetCurrentIrpStackLocation(Irp);
123
124 /* Get the file object */
125 FileObject = IrpSp->FileObject;
126
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;
131
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);
137
138 FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
139
140 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
141
142 switch (InfoClass)
143 {
144 case FileFsVolumeInformation:
145 /* Acquired the shared VCB lock */
146 if (!FatAcquireSharedVcb(IrpContext, Vcb))
147 {
148 ASSERT(FALSE);
149 }
150
151 /* Remember we locked it */
152 VcbLocked = TRUE;
153
154 /* Call FsVolumeInfo handler */
155 Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
156 break;
157
158 case FileFsSizeInformation:
159 /* Call FsVolumeInfo handler */
160 Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
161 break;
162
163 case FileFsDeviceInformation:
164 Status = FatiQueryFsDeviceInfo(Vcb, Buffer, &Length);
165 break;
166
167 case FileFsAttributeInformation:
168 UNIMPLEMENTED;
169 //Status = FatiQueryFsAttributeInfo(IrpContext, Vcb, Buffer, &Length);
170 break;
171
172 case FileFsFullSizeInformation:
173 UNIMPLEMENTED;
174 //Status = FatiQueryFsFullSizeInfo(IrpContext, Vcb, Buffer, &Length);
175 break;
176
177 default:
178 Status = STATUS_INVALID_PARAMETER;
179 }
180
181 /* Set IoStatus.Information to amount of filled bytes */
182 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
183
184 /* Release VCB lock */
185 if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
186
187 /* Complete request and return status */
188 FatCompleteRequest(IrpContext, Irp, Status);
189 return Status;
190 }
191
192 NTSTATUS
193 NTAPI
194 FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
195 {
196 NTSTATUS Status;
197 BOOLEAN TopLevel, CanWait;
198 PFAT_IRP_CONTEXT IrpContext;
199
200 CanWait = TRUE;
201 TopLevel = FALSE;
202 Status = STATUS_INVALID_DEVICE_REQUEST;
203
204 /* Get CanWait flag */
205 if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
206 CanWait = IoIsOperationSynchronous(Irp);
207
208 /* Enter FsRtl critical region */
209 FsRtlEnterFileSystem();
210
211 /* Set Top Level IRP if not set */
212 TopLevel = FatIsTopLevelIrp(Irp);
213
214 /* Build an irp context */
215 IrpContext = FatBuildIrpContext(Irp, CanWait);
216
217 /* Call the request handler */
218 Status = FatiQueryVolumeInfo(IrpContext, Irp);
219
220 /* Restore top level Irp */
221 if (TopLevel)
222 IoSetTopLevelIrp(NULL);
223
224 /* Leave FsRtl critical region */
225 FsRtlExitFileSystem();
226
227 return Status;
228 }
229
230 NTSTATUS
231 NTAPI
232 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
233 {
234 DPRINT1("FatSetVolumeInfo()\n");
235 return STATUS_NOT_IMPLEMENTED;
236 }
237
238 VOID
239 NTAPI
240 FatReadStreamFile(PVCB Vcb,
241 ULONGLONG ByteOffset,
242 ULONG ByteSize,
243 PBCB *Bcb,
244 PVOID *Buffer)
245 {
246 LARGE_INTEGER Offset;
247
248 Offset.QuadPart = ByteOffset;
249
250 if (!CcMapData(Vcb->StreamFileObject,
251 &Offset,
252 ByteSize,
253 TRUE, // FIXME: CanWait
254 Bcb,
255 Buffer))
256 {
257 ASSERT(FALSE);
258 }
259 }
260
261 BOOLEAN
262 NTAPI
263 FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext,
264 PVCB Vcb,
265 IN BOOLEAN Force)
266 {
267 /* We never allow deletion of a volume for now */
268 return FALSE;
269 }
270
271 /* EOF */