6fc53f23f6c06d944f6cc62858676e935e56f38c
[reactos.git] / reactos / 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 FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
89 {
90 PFILE_OBJECT FileObject;
91 PIO_STACK_LOCATION IrpSp;
92 FILE_INFORMATION_CLASS InfoClass;
93 TYPE_OF_OPEN FileType;
94 PVCB Vcb;
95 PFCB Fcb;
96 PCCB Ccb;
97 LONG Length;
98 PVOID Buffer;
99 BOOLEAN VcbLocked = FALSE;
100 NTSTATUS Status = STATUS_SUCCESS;
101
102 /* Get IRP stack location */
103 IrpSp = IoGetCurrentIrpStackLocation(Irp);
104
105 /* Get the file object */
106 FileObject = IrpSp->FileObject;
107
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;
112
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);
118
119 FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
120
121 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
122
123 switch (InfoClass)
124 {
125 case FileFsVolumeInformation:
126 /* Acquired the shared VCB lock */
127 if (!FatAcquireSharedVcb(IrpContext, Vcb))
128 {
129 ASSERT(FALSE);
130 }
131
132 /* Remember we locked it */
133 VcbLocked = TRUE;
134
135 /* Call FsVolumeInfo handler */
136 Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
137 break;
138
139 case FileFsSizeInformation:
140 /* Call FsVolumeInfo handler */
141 Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
142 break;
143
144 case FileFsDeviceInformation:
145 UNIMPLEMENTED
146 //Status = FatiQueryFsDeviceInfo(IrpContext, Vcb, Buffer, &Length);
147 break;
148
149 case FileFsAttributeInformation:
150 UNIMPLEMENTED;
151 //Status = FatiQueryFsAttributeInfo(IrpContext, Vcb, Buffer, &Length);
152 break;
153
154 case FileFsFullSizeInformation:
155 UNIMPLEMENTED;
156 //Status = FatiQueryFsFullSizeInfo(IrpContext, Vcb, Buffer, &Length);
157 break;
158
159 default:
160 Status = STATUS_INVALID_PARAMETER;
161 }
162
163 /* Set IoStatus.Information to amount of filled bytes */
164 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
165
166 /* Release VCB lock */
167 if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
168
169 /* Complete request and return status */
170 FatCompleteRequest(IrpContext, Irp, Status);
171 return Status;
172 }
173
174 NTSTATUS
175 NTAPI
176 FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
177 {
178 NTSTATUS Status;
179 BOOLEAN TopLevel, CanWait;
180 PFAT_IRP_CONTEXT IrpContext;
181
182 CanWait = TRUE;
183 TopLevel = FALSE;
184 Status = STATUS_INVALID_DEVICE_REQUEST;
185
186 /* Get CanWait flag */
187 if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
188 CanWait = IoIsOperationSynchronous(Irp);
189
190 /* Enter FsRtl critical region */
191 FsRtlEnterFileSystem();
192
193 /* Set Top Level IRP if not set */
194 TopLevel = FatIsTopLevelIrp(Irp);
195
196 /* Build an irp context */
197 IrpContext = FatBuildIrpContext(Irp, CanWait);
198
199 /* Call the request handler */
200 Status = FatiQueryVolumeInfo(IrpContext, Irp);
201
202 /* Restore top level Irp */
203 if (TopLevel)
204 IoSetTopLevelIrp(NULL);
205
206 /* Leave FsRtl critical region */
207 FsRtlExitFileSystem();
208
209 return Status;
210 }
211
212 NTSTATUS
213 NTAPI
214 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
215 {
216 DPRINT1("FatSetVolumeInfo()\n");
217 return STATUS_NOT_IMPLEMENTED;
218 }
219
220 VOID
221 NTAPI
222 FatReadStreamFile(PVCB Vcb,
223 ULONGLONG ByteOffset,
224 ULONG ByteSize,
225 PBCB *Bcb,
226 PVOID *Buffer)
227 {
228 LARGE_INTEGER Offset;
229
230 Offset.QuadPart = ByteOffset;
231
232 if (!CcMapData(Vcb->StreamFileObject,
233 &Offset,
234 ByteSize,
235 TRUE, // FIXME: CanWait
236 Bcb,
237 Buffer))
238 {
239 ASSERT(FALSE);
240 }
241 }
242
243 BOOLEAN
244 NTAPI
245 FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext,
246 PVCB Vcb,
247 IN BOOLEAN Force)
248 {
249 /* We never allow deletion of a volume for now */
250 return FALSE;
251 }
252
253 /* EOF */