3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the volume information routines for Cdfs called by
20 // The Bug check file id for this module
23 #define BugCheckFileId (CDFS_BUG_CHECK_VOLINFO)
26 // Local support routines
29 _Requires_lock_held_(_Global_critical_region_
)
32 _In_ PIRP_CONTEXT IrpContext
,
34 _Out_ PFILE_FS_VOLUME_INFORMATION Buffer
,
40 _In_ PIRP_CONTEXT IrpContext
,
42 _Out_ PFILE_FS_SIZE_INFORMATION Buffer
,
48 _In_ PIRP_CONTEXT IrpContext
,
50 _Out_ PFILE_FS_DEVICE_INFORMATION Buffer
,
55 CdQueryFsAttributeInfo (
56 _In_ PIRP_CONTEXT IrpContext
,
58 _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer
,
63 #define PFILE_FS_SECTOR_SIZE_INFORMATION PVOID
67 CdQueryFsSectorSizeInfo (
68 _In_ PIRP_CONTEXT IrpContext
,
70 _Out_writes_bytes_(*Length
) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer
,
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)
84 _Requires_lock_held_(_Global_critical_region_
)
86 CdCommonQueryVolInfo (
87 _Inout_ PIRP_CONTEXT IrpContext
,
95 This is the common routine for querying volume information called by both
96 the fsd and fsp threads.
100 Irp - Supplies the Irp being processed
104 NTSTATUS - The return status for the operation
109 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
110 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
114 TYPE_OF_OPEN TypeOfOpen
;
121 // Reference our input parameters to make things easier
124 Length
= IrpSp
->Parameters
.QueryVolume
.Length
;
127 // Decode the file object and fail if this an unopened file object.
130 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
132 if (TypeOfOpen
== UnopenedFileObject
) {
134 CdCompleteRequest( IrpContext
, Irp
, STATUS_INVALID_PARAMETER
);
135 return STATUS_INVALID_PARAMETER
;
139 // Acquire the Vcb for this volume.
142 CdAcquireVcbShared( IrpContext
, Fcb
->Vcb
, FALSE
);
145 // Use a try-finally to facilitate cleanup.
154 CdVerifyVcb( IrpContext
, Fcb
->Vcb
);
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.
163 switch (IrpSp
->Parameters
.QueryVolume
.FsInformationClass
) {
165 case FileFsSizeInformation
:
167 Status
= CdQueryFsSizeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
170 case FileFsVolumeInformation
:
172 Status
= CdQueryFsVolumeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
175 case FileFsDeviceInformation
:
177 Status
= CdQueryFsDeviceInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
180 case FileFsAttributeInformation
:
182 Status
= CdQueryFsAttributeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
185 #if (NTDDI_VERSION >= NTDDI_WIN8)
186 case FileFsSectorSizeInformation
:
188 Status
= CdQueryFsSectorSizeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
192 /* ReactOS Change: GCC "enumeration value not handled in switch" */
197 // Set the information field to the number of bytes actually filled in
200 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryVolume
.Length
- Length
;
208 CdReleaseVcb( IrpContext
, Fcb
->Vcb
);
212 // Complete the request if we didn't raise.
215 CdCompleteRequest( IrpContext
, Irp
, Status
);
222 // Local support routine
225 _Requires_lock_held_(_Global_critical_region_
)
227 CdQueryFsVolumeInfo (
228 _In_ PIRP_CONTEXT IrpContext
,
230 _Out_ PFILE_FS_VOLUME_INFORMATION Buffer
,
231 _Inout_ PULONG Length
238 This routine implements the query volume info call
242 Vcb - Vcb for this volume.
244 Buffer - Supplies a pointer to the output buffer where the information
247 Length - Supplies the length of the buffer in byte. This variable
248 upon return recieves the remaining bytes free in the buffer
252 NTSTATUS - Returns the status for the query
259 NTSTATUS Status
= STATUS_SUCCESS
;
263 UNREFERENCED_PARAMETER( IrpContext
);
266 // Fill in the data from the Vcb.
269 Buffer
->VolumeCreationTime
= *((PLARGE_INTEGER
) &Vcb
->VolumeDasdFcb
->CreationTime
);
270 Buffer
->VolumeSerialNumber
= Vcb
->Vpb
->SerialNumber
;
272 Buffer
->SupportsObjects
= FALSE
;
274 *Length
-= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION
, VolumeLabel
[0] );
277 // Check if the buffer we're given is long enough
280 if (*Length
>= (ULONG
) Vcb
->Vpb
->VolumeLabelLength
) {
282 BytesToCopy
= Vcb
->Vpb
->VolumeLabelLength
;
286 BytesToCopy
= *Length
;
288 Status
= STATUS_BUFFER_OVERFLOW
;
292 // Copy over what we can of the volume label, and adjust *Length
295 Buffer
->VolumeLabelLength
= BytesToCopy
;
299 RtlCopyMemory( &Buffer
->VolumeLabel
[0],
300 &Vcb
->Vpb
->VolumeLabel
[0],
304 *Length
-= BytesToCopy
;
307 // Set our status and return to our caller
315 // Local support routine
320 _In_ PIRP_CONTEXT IrpContext
,
322 _Out_ PFILE_FS_SIZE_INFORMATION Buffer
,
323 _Inout_ PULONG Length
330 This routine implements the query volume size call.
334 Vcb - Vcb for this volume.
336 Buffer - Supplies a pointer to the output buffer where the information
339 Length - Supplies the length of the buffer in byte. This variable
340 upon return recieves the remaining bytes free in the buffer
344 NTSTATUS - Returns the status for the query
351 UNREFERENCED_PARAMETER( IrpContext
);
354 // Fill in the output buffer.
357 Buffer
->TotalAllocationUnits
.QuadPart
= LlSectorsFromBytes( Vcb
->VolumeDasdFcb
->AllocationSize
.QuadPart
);
359 Buffer
->AvailableAllocationUnits
.QuadPart
= 0;
360 Buffer
->SectorsPerAllocationUnit
= 1;
361 Buffer
->BytesPerSector
= SECTOR_SIZE
;
364 // Adjust the length variable
367 *Length
-= sizeof( FILE_FS_SIZE_INFORMATION
);
370 // And return success to our caller
373 return STATUS_SUCCESS
;
378 // Local support routine
382 CdQueryFsDeviceInfo (
383 _In_ PIRP_CONTEXT IrpContext
,
385 _Out_ PFILE_FS_DEVICE_INFORMATION Buffer
,
386 _Inout_ PULONG Length
393 This routine implements the query volume device call.
397 Vcb - Vcb for this volume.
399 Buffer - Supplies a pointer to the output buffer where the information
402 Length - Supplies the length of the buffer in byte. This variable
403 upon return recieves the remaining bytes free in the buffer
407 NTSTATUS - Returns the status for the query
414 UNREFERENCED_PARAMETER( IrpContext
);
417 // Update the output buffer.
420 Buffer
->Characteristics
= Vcb
->TargetDeviceObject
->Characteristics
;
421 Buffer
->DeviceType
= FILE_DEVICE_CD_ROM
;
424 // Adjust the length variable
427 *Length
-= sizeof( FILE_FS_DEVICE_INFORMATION
);
430 // And return success to our caller
433 return STATUS_SUCCESS
;
438 // Local support routine
442 CdQueryFsAttributeInfo (
443 _In_ PIRP_CONTEXT IrpContext
,
445 _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer
,
446 _Inout_ PULONG Length
453 This routine implements the query volume attribute call.
457 Vcb - Vcb for this volume.
459 Buffer - Supplies a pointer to the output buffer where the information
462 Length - Supplies the length of the buffer in byte. This variable
463 upon return recieves the remaining bytes free in the buffer
467 NTSTATUS - Returns the status for the query
474 NTSTATUS Status
= STATUS_SUCCESS
;
478 UNREFERENCED_PARAMETER( Vcb
);
481 // Fill out the fixed portion of the buffer.
484 Buffer
->FileSystemAttributes
= FILE_CASE_SENSITIVE_SEARCH
|
485 FILE_READ_ONLY_VOLUME
|
486 FILE_SUPPORTS_OPEN_BY_FILE_ID
;
488 if (FlagOn( IrpContext
->Vcb
->VcbState
, VCB_STATE_JOLIET
)) {
490 SetFlag( Buffer
->FileSystemAttributes
, FILE_UNICODE_ON_DISK
);
492 Buffer
->MaximumComponentNameLength
= 110;
496 Buffer
->MaximumComponentNameLength
= 221;
499 *Length
-= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION
, FileSystemName
);
502 // Make sure we can copy full unicode characters.
505 ClearFlag( *Length
, 1 );
508 // Determine how much of the file system name will fit.
517 BytesToCopy
= *Length
;
518 Status
= STATUS_BUFFER_OVERFLOW
;
521 *Length
-= BytesToCopy
;
524 // Do the file system name.
527 Buffer
->FileSystemNameLength
= BytesToCopy
;
529 RtlCopyMemory( &Buffer
->FileSystemName
[0], L
"CDFS", BytesToCopy
);
532 // And return to our caller
538 #if (NTDDI_VERSION >= NTDDI_WIN8)
541 CdQueryFsSectorSizeInfo (
542 _In_ PIRP_CONTEXT IrpContext
,
544 _Out_writes_bytes_(*Length
) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer
,
545 _Inout_ PULONG Length
552 This routine implements the query sector size information call
553 This operation will work on any handle and requires no privilege.
557 Vcb - Supplies the Vcb being queried
559 Buffer - Supplies a pointer to the output buffer where the information
562 Length - Supplies the length of the buffer in byte. This variable
563 upon return receives the remaining bytes free in the buffer
567 NTSTATUS - Returns the status for the query
575 UNREFERENCED_PARAMETER( IrpContext
);
578 // Sufficient buffer size is guaranteed by the I/O manager or the
579 // originating kernel mode driver.
582 ASSERT( *Length
>= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
));
583 _Analysis_assume_( *Length
>= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
));
586 // Retrieve the sector size information
589 Status
= FsRtlGetSectorSizeInformation( Vcb
->Vpb
->RealDevice
,
593 // Adjust the length variable
596 if (NT_SUCCESS( Status
)) {
598 *Length
-= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
);