[CDFS_NEW] You know... RBuild has been gone for ages!
[reactos.git] / drivers / filesystems / cdfs_new / volinfo.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 VolInfo.c
8
9 Abstract:
10
11 This module implements the volume information routines for Cdfs called by
12 the dispatch driver.
13
14
15 --*/
16
17 #include "cdprocs.h"
18
19 //
20 // The Bug check file id for this module
21 //
22
23 #define BugCheckFileId (CDFS_BUG_CHECK_VOLINFO)
24
25 //
26 // Local support routines
27 //
28
29 NTSTATUS
30 CdQueryFsVolumeInfo (
31 IN PIRP_CONTEXT IrpContext,
32 IN PVCB Vcb,
33 IN PFILE_FS_VOLUME_INFORMATION Buffer,
34 IN OUT PULONG Length
35 );
36
37 NTSTATUS
38 CdQueryFsSizeInfo (
39 IN PIRP_CONTEXT IrpContext,
40 IN PVCB Vcb,
41 IN PFILE_FS_SIZE_INFORMATION Buffer,
42 IN OUT PULONG Length
43 );
44
45 NTSTATUS
46 CdQueryFsDeviceInfo (
47 IN PIRP_CONTEXT IrpContext,
48 IN PVCB Vcb,
49 IN PFILE_FS_DEVICE_INFORMATION Buffer,
50 IN OUT PULONG Length
51 );
52
53 NTSTATUS
54 CdQueryFsAttributeInfo (
55 IN PIRP_CONTEXT IrpContext,
56 IN PVCB Vcb,
57 IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
58 IN OUT PULONG Length
59 );
60
61 #ifdef ALLOC_PRAGMA
62 #pragma alloc_text(PAGE, CdCommonQueryVolInfo)
63 #pragma alloc_text(PAGE, CdQueryFsAttributeInfo)
64 #pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
65 #pragma alloc_text(PAGE, CdQueryFsSizeInfo)
66 #pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
67 #endif
68
69 \f
70 NTSTATUS
71 CdCommonQueryVolInfo (
72 IN PIRP_CONTEXT IrpContext,
73 IN PIRP Irp
74 )
75
76 /*++
77
78 Routine Description:
79
80 This is the common routine for querying volume information called by both
81 the fsd and fsp threads.
82
83 Arguments:
84
85 Irp - Supplies the Irp being processed
86
87 Return Value:
88
89 NTSTATUS - The return status for the operation
90
91 --*/
92
93 {
94 NTSTATUS Status = STATUS_INVALID_PARAMETER;
95 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
96
97 ULONG Length;
98
99 TYPE_OF_OPEN TypeOfOpen;
100 PFCB Fcb;
101 PCCB Ccb;
102
103 PAGED_CODE();
104
105 //
106 // Reference our input parameters to make things easier
107 //
108
109 Length = IrpSp->Parameters.QueryVolume.Length;
110
111 //
112 // Decode the file object and fail if this an unopened file object.
113 //
114
115 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
116
117 if (TypeOfOpen == UnopenedFileObject) {
118
119 CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
120 return STATUS_INVALID_PARAMETER;
121 }
122
123 //
124 // Acquire the Vcb for this volume.
125 //
126
127 CdAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
128
129 //
130 // Use a try-finally to facilitate cleanup.
131 //
132
133 try {
134
135 //
136 // Verify the Vcb.
137 //
138
139 CdVerifyVcb( IrpContext, Fcb->Vcb );
140
141 //
142 // Based on the information class we'll do different actions. Each
143 // of the procedures that we're calling fills up the output buffer
144 // if possible and returns true if it successfully filled the buffer
145 // and false if it couldn't wait for any I/O to complete.
146 //
147
148 switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
149
150 case FileFsSizeInformation:
151
152 Status = CdQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
153 break;
154
155 case FileFsVolumeInformation:
156
157 Status = CdQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
158 break;
159
160 case FileFsDeviceInformation:
161
162 Status = CdQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
163 break;
164
165 case FileFsAttributeInformation:
166
167 Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
168 break;
169
170 /* ReactOS Change: GCC "enumeration value not handled in switch" */
171 default: break;
172 }
173
174 //
175 // Set the information field to the number of bytes actually filled in
176 //
177
178 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
179
180 } finally {
181
182 //
183 // Release the Vcb.
184 //
185
186 CdReleaseVcb( IrpContext, Fcb->Vcb );
187 }
188
189 //
190 // Complete the request if we didn't raise.
191 //
192
193 CdCompleteRequest( IrpContext, Irp, Status );
194
195 return Status;
196 }
197
198 \f
199 //
200 // Local support routine
201 //
202
203 NTSTATUS
204 CdQueryFsVolumeInfo (
205 IN PIRP_CONTEXT IrpContext,
206 IN PVCB Vcb,
207 IN PFILE_FS_VOLUME_INFORMATION Buffer,
208 IN OUT PULONG Length
209 )
210
211 /*++
212
213 Routine Description:
214
215 This routine implements the query volume info call
216
217 Arguments:
218
219 Vcb - Vcb for this volume.
220
221 Buffer - Supplies a pointer to the output buffer where the information
222 is to be returned
223
224 Length - Supplies the length of the buffer in byte. This variable
225 upon return receives the remaining bytes free in the buffer
226
227 Return Value:
228
229 NTSTATUS - Returns the status for the query
230
231 --*/
232
233 {
234 ULONG BytesToCopy;
235
236 NTSTATUS Status = STATUS_SUCCESS;
237
238 PAGED_CODE();
239
240 //
241 // Fill in the data from the Vcb.
242 //
243
244 Buffer->VolumeCreationTime = *((PLARGE_INTEGER) &Vcb->VolumeDasdFcb->CreationTime);
245 Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
246
247 Buffer->SupportsObjects = FALSE;
248
249 *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
250
251 //
252 // Check if the buffer we're given is long enough
253 //
254
255 if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) {
256
257 BytesToCopy = Vcb->Vpb->VolumeLabelLength;
258
259 } else {
260
261 BytesToCopy = *Length;
262
263 Status = STATUS_BUFFER_OVERFLOW;
264 }
265
266 //
267 // Copy over what we can of the volume label, and adjust *Length
268 //
269
270 Buffer->VolumeLabelLength = BytesToCopy;
271
272 if (BytesToCopy) {
273
274 RtlCopyMemory( &Buffer->VolumeLabel[0],
275 &Vcb->Vpb->VolumeLabel[0],
276 BytesToCopy );
277 }
278
279 *Length -= BytesToCopy;
280
281 //
282 // Set our status and return to our caller
283 //
284
285 return Status;
286 }
287
288 \f
289 //
290 // Local support routine
291 //
292
293 NTSTATUS
294 CdQueryFsSizeInfo (
295 IN PIRP_CONTEXT IrpContext,
296 IN PVCB Vcb,
297 IN PFILE_FS_SIZE_INFORMATION Buffer,
298 IN OUT PULONG Length
299 )
300
301 /*++
302
303 Routine Description:
304
305 This routine implements the query volume size call.
306
307 Arguments:
308
309 Vcb - Vcb for this volume.
310
311 Buffer - Supplies a pointer to the output buffer where the information
312 is to be returned
313
314 Length - Supplies the length of the buffer in byte. This variable
315 upon return receives the remaining bytes free in the buffer
316
317 Return Value:
318
319 NTSTATUS - Returns the status for the query
320
321 --*/
322
323 {
324 PAGED_CODE();
325
326 //
327 // Fill in the output buffer.
328 //
329
330 Buffer->TotalAllocationUnits.QuadPart = LlSectorsFromBytes( Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
331
332 Buffer->AvailableAllocationUnits.QuadPart = 0;
333 Buffer->SectorsPerAllocationUnit = 1;
334 Buffer->BytesPerSector = SECTOR_SIZE;
335
336 //
337 // Adjust the length variable
338 //
339
340 *Length -= sizeof( FILE_FS_SIZE_INFORMATION );
341
342 //
343 // And return success to our caller
344 //
345
346 return STATUS_SUCCESS;
347 }
348
349 \f
350 //
351 // Local support routine
352 //
353
354 NTSTATUS
355 CdQueryFsDeviceInfo (
356 IN PIRP_CONTEXT IrpContext,
357 IN PVCB Vcb,
358 IN PFILE_FS_DEVICE_INFORMATION Buffer,
359 IN OUT PULONG Length
360 )
361
362 /*++
363
364 Routine Description:
365
366 This routine implements the query volume device call.
367
368 Arguments:
369
370 Vcb - Vcb for this volume.
371
372 Buffer - Supplies a pointer to the output buffer where the information
373 is to be returned
374
375 Length - Supplies the length of the buffer in byte. This variable
376 upon return receives the remaining bytes free in the buffer
377
378 Return Value:
379
380 NTSTATUS - Returns the status for the query
381
382 --*/
383
384 {
385 PAGED_CODE();
386
387 //
388 // Update the output buffer.
389 //
390
391 Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
392 Buffer->DeviceType = FILE_DEVICE_CD_ROM;
393
394 //
395 // Adjust the length variable
396 //
397
398 *Length -= sizeof( FILE_FS_DEVICE_INFORMATION );
399
400 //
401 // And return success to our caller
402 //
403
404 return STATUS_SUCCESS;
405 }
406
407 \f
408 //
409 // Local support routine
410 //
411
412 NTSTATUS
413 CdQueryFsAttributeInfo (
414 IN PIRP_CONTEXT IrpContext,
415 IN PVCB Vcb,
416 IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
417 IN OUT PULONG Length
418 )
419
420 /*++
421
422 Routine Description:
423
424 This routine implements the query volume attribute call.
425
426 Arguments:
427
428 Vcb - Vcb for this volume.
429
430 Buffer - Supplies a pointer to the output buffer where the information
431 is to be returned
432
433 Length - Supplies the length of the buffer in byte. This variable
434 upon return receives the remaining bytes free in the buffer
435
436 Return Value:
437
438 NTSTATUS - Returns the status for the query
439
440 --*/
441
442 {
443 ULONG BytesToCopy;
444
445 NTSTATUS Status = STATUS_SUCCESS;
446
447 PAGED_CODE();
448
449 //
450 // Fill out the fixed portion of the buffer.
451 //
452
453 Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
454 FILE_READ_ONLY_VOLUME;
455
456 if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
457
458 SetFlag( Buffer->FileSystemAttributes, FILE_UNICODE_ON_DISK );
459
460 Buffer->MaximumComponentNameLength = 110;
461
462 } else {
463
464 Buffer->MaximumComponentNameLength = 221;
465 }
466
467 *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName );
468
469 //
470 // Make sure we can copy full unicode characters.
471 //
472
473 ClearFlag( *Length, 1 );
474
475 //
476 // Determine how much of the file system name will fit.
477 //
478
479 if (*Length >= 8) {
480
481 BytesToCopy = 8;
482
483 } else {
484
485 BytesToCopy = *Length;
486 Status = STATUS_BUFFER_OVERFLOW;
487 }
488
489 *Length -= BytesToCopy;
490
491 //
492 // Do the file system name.
493 //
494
495 Buffer->FileSystemNameLength = BytesToCopy;
496
497 RtlCopyMemory( &Buffer->FileSystemName[0], L"CDFS", BytesToCopy );
498
499 //
500 // And return to our caller
501 //
502
503 return Status;
504 }
505