[CDFS_NEW] Re-apply many of the reactos-specific changes and fix build.
[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 _Requires_lock_held_(_Global_critical_region_)
30 NTSTATUS
31 CdQueryFsVolumeInfo (
32 _In_ PIRP_CONTEXT IrpContext,
33 _In_ PVCB Vcb,
34 _Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
35 _Inout_ PULONG Length
36 );
37
38 NTSTATUS
39 CdQueryFsSizeInfo (
40 _In_ PIRP_CONTEXT IrpContext,
41 _In_ PVCB Vcb,
42 _Out_ PFILE_FS_SIZE_INFORMATION Buffer,
43 _Inout_ PULONG Length
44 );
45
46 NTSTATUS
47 CdQueryFsDeviceInfo (
48 _In_ PIRP_CONTEXT IrpContext,
49 _In_ PVCB Vcb,
50 _Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
51 _Inout_ PULONG Length
52 );
53
54 NTSTATUS
55 CdQueryFsAttributeInfo (
56 _In_ PIRP_CONTEXT IrpContext,
57 _In_ PVCB Vcb,
58 _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
59 _Inout_ PULONG Length
60 );
61
62 #ifdef __REACTOS__
63 #define PFILE_FS_SECTOR_SIZE_INFORMATION PVOID
64 #endif
65
66 NTSTATUS
67 CdQueryFsSectorSizeInfo (
68 _In_ PIRP_CONTEXT IrpContext,
69 _In_ PVCB Vcb,
70 _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
71 _Inout_ PULONG Length
72 );
73
74 #ifdef ALLOC_PRAGMA
75 #pragma alloc_text(PAGE, CdCommonQueryVolInfo)
76 #pragma alloc_text(PAGE, CdQueryFsAttributeInfo)
77 #pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
78 #pragma alloc_text(PAGE, CdQueryFsSizeInfo)
79 #pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
80 #pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
81 #endif
82
83 \f
84 _Requires_lock_held_(_Global_critical_region_)
85 NTSTATUS
86 CdCommonQueryVolInfo (
87 _Inout_ PIRP_CONTEXT IrpContext,
88 _Inout_ PIRP Irp
89 )
90
91 /*++
92
93 Routine Description:
94
95 This is the common routine for querying volume information called by both
96 the fsd and fsp threads.
97
98 Arguments:
99
100 Irp - Supplies the Irp being processed
101
102 Return Value:
103
104 NTSTATUS - The return status for the operation
105
106 --*/
107
108 {
109 NTSTATUS Status = STATUS_INVALID_PARAMETER;
110 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
111
112 ULONG Length;
113
114 TYPE_OF_OPEN TypeOfOpen;
115 PFCB Fcb;
116 PCCB Ccb;
117
118 PAGED_CODE();
119
120 //
121 // Reference our input parameters to make things easier
122 //
123
124 Length = IrpSp->Parameters.QueryVolume.Length;
125
126 //
127 // Decode the file object and fail if this an unopened file object.
128 //
129
130 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
131
132 if (TypeOfOpen == UnopenedFileObject) {
133
134 CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
135 return STATUS_INVALID_PARAMETER;
136 }
137
138 //
139 // Acquire the Vcb for this volume.
140 //
141
142 CdAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
143
144 //
145 // Use a try-finally to facilitate cleanup.
146 //
147
148 _SEH2_TRY {
149
150 //
151 // Verify the Vcb.
152 //
153
154 CdVerifyVcb( IrpContext, Fcb->Vcb );
155
156 //
157 // Based on the information class we'll do different actions. Each
158 // of the procedures that we're calling fills up the output buffer
159 // if possible and returns true if it successfully filled the buffer
160 // and false if it couldn't wait for any I/O to complete.
161 //
162
163 switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
164
165 case FileFsSizeInformation:
166
167 Status = CdQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
168 break;
169
170 case FileFsVolumeInformation:
171
172 Status = CdQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
173 break;
174
175 case FileFsDeviceInformation:
176
177 Status = CdQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
178 break;
179
180 case FileFsAttributeInformation:
181
182 Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
183 break;
184
185 #if (NTDDI_VERSION >= NTDDI_WIN8)
186 case FileFsSectorSizeInformation:
187
188 Status = CdQueryFsSectorSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
189 break;
190 #endif
191
192 /* ReactOS Change: GCC "enumeration value not handled in switch" */
193 default: break;
194 }
195
196 //
197 // Set the information field to the number of bytes actually filled in
198 //
199
200 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
201
202 } _SEH2_FINALLY {
203
204 //
205 // Release the Vcb.
206 //
207
208 CdReleaseVcb( IrpContext, Fcb->Vcb );
209 } _SEH2_END;
210
211 //
212 // Complete the request if we didn't raise.
213 //
214
215 CdCompleteRequest( IrpContext, Irp, Status );
216
217 return Status;
218 }
219
220 \f
221 //
222 // Local support routine
223 //
224
225 _Requires_lock_held_(_Global_critical_region_)
226 NTSTATUS
227 CdQueryFsVolumeInfo (
228 _In_ PIRP_CONTEXT IrpContext,
229 _In_ PVCB Vcb,
230 _Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
231 _Inout_ PULONG Length
232 )
233
234 /*++
235
236 Routine Description:
237
238 This routine implements the query volume info call
239
240 Arguments:
241
242 Vcb - Vcb for this volume.
243
244 Buffer - Supplies a pointer to the output buffer where the information
245 is to be returned
246
247 Length - Supplies the length of the buffer in byte. This variable
248 upon return recieves the remaining bytes free in the buffer
249
250 Return Value:
251
252 NTSTATUS - Returns the status for the query
253
254 --*/
255
256 {
257 ULONG BytesToCopy;
258
259 NTSTATUS Status = STATUS_SUCCESS;
260
261 PAGED_CODE();
262
263 UNREFERENCED_PARAMETER( IrpContext );
264
265 //
266 // Fill in the data from the Vcb.
267 //
268
269 Buffer->VolumeCreationTime = *((PLARGE_INTEGER) &Vcb->VolumeDasdFcb->CreationTime);
270 Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
271
272 Buffer->SupportsObjects = FALSE;
273
274 *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
275
276 //
277 // Check if the buffer we're given is long enough
278 //
279
280 if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) {
281
282 BytesToCopy = Vcb->Vpb->VolumeLabelLength;
283
284 } else {
285
286 BytesToCopy = *Length;
287
288 Status = STATUS_BUFFER_OVERFLOW;
289 }
290
291 //
292 // Copy over what we can of the volume label, and adjust *Length
293 //
294
295 Buffer->VolumeLabelLength = BytesToCopy;
296
297 if (BytesToCopy) {
298
299 RtlCopyMemory( &Buffer->VolumeLabel[0],
300 &Vcb->Vpb->VolumeLabel[0],
301 BytesToCopy );
302 }
303
304 *Length -= BytesToCopy;
305
306 //
307 // Set our status and return to our caller
308 //
309
310 return Status;
311 }
312
313 \f
314 //
315 // Local support routine
316 //
317
318 NTSTATUS
319 CdQueryFsSizeInfo (
320 _In_ PIRP_CONTEXT IrpContext,
321 _In_ PVCB Vcb,
322 _Out_ PFILE_FS_SIZE_INFORMATION Buffer,
323 _Inout_ PULONG Length
324 )
325
326 /*++
327
328 Routine Description:
329
330 This routine implements the query volume size call.
331
332 Arguments:
333
334 Vcb - Vcb for this volume.
335
336 Buffer - Supplies a pointer to the output buffer where the information
337 is to be returned
338
339 Length - Supplies the length of the buffer in byte. This variable
340 upon return recieves the remaining bytes free in the buffer
341
342 Return Value:
343
344 NTSTATUS - Returns the status for the query
345
346 --*/
347
348 {
349 PAGED_CODE();
350
351 UNREFERENCED_PARAMETER( IrpContext );
352
353 //
354 // Fill in the output buffer.
355 //
356
357 Buffer->TotalAllocationUnits.QuadPart = LlSectorsFromBytes( Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
358
359 Buffer->AvailableAllocationUnits.QuadPart = 0;
360 Buffer->SectorsPerAllocationUnit = 1;
361 Buffer->BytesPerSector = SECTOR_SIZE;
362
363 //
364 // Adjust the length variable
365 //
366
367 *Length -= sizeof( FILE_FS_SIZE_INFORMATION );
368
369 //
370 // And return success to our caller
371 //
372
373 return STATUS_SUCCESS;
374 }
375
376 \f
377 //
378 // Local support routine
379 //
380
381 NTSTATUS
382 CdQueryFsDeviceInfo (
383 _In_ PIRP_CONTEXT IrpContext,
384 _In_ PVCB Vcb,
385 _Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
386 _Inout_ PULONG Length
387 )
388
389 /*++
390
391 Routine Description:
392
393 This routine implements the query volume device call.
394
395 Arguments:
396
397 Vcb - Vcb for this volume.
398
399 Buffer - Supplies a pointer to the output buffer where the information
400 is to be returned
401
402 Length - Supplies the length of the buffer in byte. This variable
403 upon return recieves the remaining bytes free in the buffer
404
405 Return Value:
406
407 NTSTATUS - Returns the status for the query
408
409 --*/
410
411 {
412 PAGED_CODE();
413
414 UNREFERENCED_PARAMETER( IrpContext );
415
416 //
417 // Update the output buffer.
418 //
419
420 Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
421 Buffer->DeviceType = FILE_DEVICE_CD_ROM;
422
423 //
424 // Adjust the length variable
425 //
426
427 *Length -= sizeof( FILE_FS_DEVICE_INFORMATION );
428
429 //
430 // And return success to our caller
431 //
432
433 return STATUS_SUCCESS;
434 }
435
436 \f
437 //
438 // Local support routine
439 //
440
441 NTSTATUS
442 CdQueryFsAttributeInfo (
443 _In_ PIRP_CONTEXT IrpContext,
444 _In_ PVCB Vcb,
445 _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
446 _Inout_ PULONG Length
447 )
448
449 /*++
450
451 Routine Description:
452
453 This routine implements the query volume attribute call.
454
455 Arguments:
456
457 Vcb - Vcb for this volume.
458
459 Buffer - Supplies a pointer to the output buffer where the information
460 is to be returned
461
462 Length - Supplies the length of the buffer in byte. This variable
463 upon return recieves the remaining bytes free in the buffer
464
465 Return Value:
466
467 NTSTATUS - Returns the status for the query
468
469 --*/
470
471 {
472 ULONG BytesToCopy;
473
474 NTSTATUS Status = STATUS_SUCCESS;
475
476 PAGED_CODE();
477
478 UNREFERENCED_PARAMETER( Vcb );
479
480 //
481 // Fill out the fixed portion of the buffer.
482 //
483
484 Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
485 FILE_READ_ONLY_VOLUME |
486 FILE_SUPPORTS_OPEN_BY_FILE_ID;
487
488 if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
489
490 SetFlag( Buffer->FileSystemAttributes, FILE_UNICODE_ON_DISK );
491
492 Buffer->MaximumComponentNameLength = 110;
493
494 } else {
495
496 Buffer->MaximumComponentNameLength = 221;
497 }
498
499 *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName );
500
501 //
502 // Make sure we can copy full unicode characters.
503 //
504
505 ClearFlag( *Length, 1 );
506
507 //
508 // Determine how much of the file system name will fit.
509 //
510
511 if (*Length >= 8) {
512
513 BytesToCopy = 8;
514
515 } else {
516
517 BytesToCopy = *Length;
518 Status = STATUS_BUFFER_OVERFLOW;
519 }
520
521 *Length -= BytesToCopy;
522
523 //
524 // Do the file system name.
525 //
526
527 Buffer->FileSystemNameLength = BytesToCopy;
528
529 RtlCopyMemory( &Buffer->FileSystemName[0], L"CDFS", BytesToCopy );
530
531 //
532 // And return to our caller
533 //
534
535 return Status;
536 }
537
538 #if (NTDDI_VERSION >= NTDDI_WIN8)
539
540 NTSTATUS
541 CdQueryFsSectorSizeInfo (
542 _In_ PIRP_CONTEXT IrpContext,
543 _In_ PVCB Vcb,
544 _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
545 _Inout_ PULONG Length
546 )
547
548 /*++
549
550 Routine Description:
551
552 This routine implements the query sector size information call
553 This operation will work on any handle and requires no privilege.
554
555 Arguments:
556
557 Vcb - Supplies the Vcb being queried
558
559 Buffer - Supplies a pointer to the output buffer where the information
560 is to be returned
561
562 Length - Supplies the length of the buffer in byte. This variable
563 upon return receives the remaining bytes free in the buffer
564
565 Return Value:
566
567 NTSTATUS - Returns the status for the query
568
569 --*/
570
571 {
572 NTSTATUS Status;
573
574 PAGED_CODE();
575 UNREFERENCED_PARAMETER( IrpContext );
576
577 //
578 // Sufficient buffer size is guaranteed by the I/O manager or the
579 // originating kernel mode driver.
580 //
581
582 ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
583 _Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
584
585 //
586 // Retrieve the sector size information
587 //
588
589 Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
590 Buffer );
591
592 //
593 // Adjust the length variable
594 //
595
596 if (NT_SUCCESS( Status )) {
597
598 *Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
599 }
600
601 return Status;
602 }
603
604 #endif
605