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 CdQueryFsSectorSizeInfo (
64 _In_ PIRP_CONTEXT IrpContext
,
66 _Out_writes_bytes_(*Length
) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer
,
71 #pragma alloc_text(PAGE, CdCommonQueryVolInfo)
72 #pragma alloc_text(PAGE, CdQueryFsAttributeInfo)
73 #pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
74 #pragma alloc_text(PAGE, CdQueryFsSizeInfo)
75 #pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
76 #pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
80 _Requires_lock_held_(_Global_critical_region_
)
82 CdCommonQueryVolInfo (
83 _Inout_ PIRP_CONTEXT IrpContext
,
91 This is the common routine for querying volume information called by both
92 the fsd and fsp threads.
96 Irp - Supplies the Irp being processed
100 NTSTATUS - The return status for the operation
105 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
106 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
110 TYPE_OF_OPEN TypeOfOpen
;
117 // Reference our input parameters to make things easier
120 Length
= IrpSp
->Parameters
.QueryVolume
.Length
;
123 // Decode the file object and fail if this an unopened file object.
126 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
128 if (TypeOfOpen
== UnopenedFileObject
) {
130 CdCompleteRequest( IrpContext
, Irp
, STATUS_INVALID_PARAMETER
);
131 return STATUS_INVALID_PARAMETER
;
135 // Acquire the Vcb for this volume.
138 CdAcquireVcbShared( IrpContext
, Fcb
->Vcb
, FALSE
);
141 // Use a try-finally to facilitate cleanup.
150 CdVerifyVcb( IrpContext
, Fcb
->Vcb
);
153 // Based on the information class we'll do different actions. Each
154 // of the procedures that we're calling fills up the output buffer
155 // if possible and returns true if it successfully filled the buffer
156 // and false if it couldn't wait for any I/O to complete.
159 switch (IrpSp
->Parameters
.QueryVolume
.FsInformationClass
) {
161 case FileFsSizeInformation
:
163 Status
= CdQueryFsSizeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
166 case FileFsVolumeInformation
:
168 Status
= CdQueryFsVolumeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
171 case FileFsDeviceInformation
:
173 Status
= CdQueryFsDeviceInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
176 case FileFsAttributeInformation
:
178 Status
= CdQueryFsAttributeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
181 #if (NTDDI_VERSION >= NTDDI_WIN8)
182 case FileFsSectorSizeInformation
:
184 Status
= CdQueryFsSectorSizeInfo( IrpContext
, Fcb
->Vcb
, Irp
->AssociatedIrp
.SystemBuffer
, &Length
);
190 // Set the information field to the number of bytes actually filled in
193 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryVolume
.Length
- Length
;
201 CdReleaseVcb( IrpContext
, Fcb
->Vcb
);
205 // Complete the request if we didn't raise.
208 CdCompleteRequest( IrpContext
, Irp
, Status
);
215 // Local support routine
218 _Requires_lock_held_(_Global_critical_region_
)
220 CdQueryFsVolumeInfo (
221 _In_ PIRP_CONTEXT IrpContext
,
223 _Out_ PFILE_FS_VOLUME_INFORMATION Buffer
,
224 _Inout_ PULONG Length
231 This routine implements the query volume info call
235 Vcb - Vcb for this volume.
237 Buffer - Supplies a pointer to the output buffer where the information
240 Length - Supplies the length of the buffer in byte. This variable
241 upon return recieves the remaining bytes free in the buffer
245 NTSTATUS - Returns the status for the query
252 NTSTATUS Status
= STATUS_SUCCESS
;
256 UNREFERENCED_PARAMETER( IrpContext
);
259 // Fill in the data from the Vcb.
262 Buffer
->VolumeCreationTime
= *((PLARGE_INTEGER
) &Vcb
->VolumeDasdFcb
->CreationTime
);
263 Buffer
->VolumeSerialNumber
= Vcb
->Vpb
->SerialNumber
;
265 Buffer
->SupportsObjects
= FALSE
;
267 *Length
-= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION
, VolumeLabel
[0] );
270 // Check if the buffer we're given is long enough
273 if (*Length
>= (ULONG
) Vcb
->Vpb
->VolumeLabelLength
) {
275 BytesToCopy
= Vcb
->Vpb
->VolumeLabelLength
;
279 BytesToCopy
= *Length
;
281 Status
= STATUS_BUFFER_OVERFLOW
;
285 // Copy over what we can of the volume label, and adjust *Length
288 Buffer
->VolumeLabelLength
= BytesToCopy
;
292 RtlCopyMemory( &Buffer
->VolumeLabel
[0],
293 &Vcb
->Vpb
->VolumeLabel
[0],
297 *Length
-= BytesToCopy
;
300 // Set our status and return to our caller
308 // Local support routine
313 _In_ PIRP_CONTEXT IrpContext
,
315 _Out_ PFILE_FS_SIZE_INFORMATION Buffer
,
316 _Inout_ PULONG Length
323 This routine implements the query volume size call.
327 Vcb - Vcb for this volume.
329 Buffer - Supplies a pointer to the output buffer where the information
332 Length - Supplies the length of the buffer in byte. This variable
333 upon return recieves the remaining bytes free in the buffer
337 NTSTATUS - Returns the status for the query
344 UNREFERENCED_PARAMETER( IrpContext
);
347 // Fill in the output buffer.
350 Buffer
->TotalAllocationUnits
.QuadPart
= LlSectorsFromBytes( Vcb
->VolumeDasdFcb
->AllocationSize
.QuadPart
);
352 Buffer
->AvailableAllocationUnits
.QuadPart
= 0;
353 Buffer
->SectorsPerAllocationUnit
= 1;
354 Buffer
->BytesPerSector
= SECTOR_SIZE
;
357 // Adjust the length variable
360 *Length
-= sizeof( FILE_FS_SIZE_INFORMATION
);
363 // And return success to our caller
366 return STATUS_SUCCESS
;
371 // Local support routine
375 CdQueryFsDeviceInfo (
376 _In_ PIRP_CONTEXT IrpContext
,
378 _Out_ PFILE_FS_DEVICE_INFORMATION Buffer
,
379 _Inout_ PULONG Length
386 This routine implements the query volume device call.
390 Vcb - Vcb for this volume.
392 Buffer - Supplies a pointer to the output buffer where the information
395 Length - Supplies the length of the buffer in byte. This variable
396 upon return recieves the remaining bytes free in the buffer
400 NTSTATUS - Returns the status for the query
407 UNREFERENCED_PARAMETER( IrpContext
);
410 // Update the output buffer.
413 Buffer
->Characteristics
= Vcb
->TargetDeviceObject
->Characteristics
;
414 Buffer
->DeviceType
= FILE_DEVICE_CD_ROM
;
417 // Adjust the length variable
420 *Length
-= sizeof( FILE_FS_DEVICE_INFORMATION
);
423 // And return success to our caller
426 return STATUS_SUCCESS
;
431 // Local support routine
435 CdQueryFsAttributeInfo (
436 _In_ PIRP_CONTEXT IrpContext
,
438 _Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer
,
439 _Inout_ PULONG Length
446 This routine implements the query volume attribute call.
450 Vcb - Vcb for this volume.
452 Buffer - Supplies a pointer to the output buffer where the information
455 Length - Supplies the length of the buffer in byte. This variable
456 upon return recieves the remaining bytes free in the buffer
460 NTSTATUS - Returns the status for the query
467 NTSTATUS Status
= STATUS_SUCCESS
;
471 UNREFERENCED_PARAMETER( Vcb
);
474 // Fill out the fixed portion of the buffer.
477 Buffer
->FileSystemAttributes
= FILE_CASE_SENSITIVE_SEARCH
|
478 FILE_READ_ONLY_VOLUME
|
479 FILE_SUPPORTS_OPEN_BY_FILE_ID
;
481 if (FlagOn( IrpContext
->Vcb
->VcbState
, VCB_STATE_JOLIET
)) {
483 SetFlag( Buffer
->FileSystemAttributes
, FILE_UNICODE_ON_DISK
);
485 Buffer
->MaximumComponentNameLength
= 110;
489 Buffer
->MaximumComponentNameLength
= 221;
492 *Length
-= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION
, FileSystemName
);
495 // Make sure we can copy full unicode characters.
498 ClearFlag( *Length
, 1 );
501 // Determine how much of the file system name will fit.
510 BytesToCopy
= *Length
;
511 Status
= STATUS_BUFFER_OVERFLOW
;
514 *Length
-= BytesToCopy
;
517 // Do the file system name.
520 Buffer
->FileSystemNameLength
= BytesToCopy
;
522 RtlCopyMemory( &Buffer
->FileSystemName
[0], L
"CDFS", BytesToCopy
);
525 // And return to our caller
531 #if (NTDDI_VERSION >= NTDDI_WIN8)
534 CdQueryFsSectorSizeInfo (
535 _In_ PIRP_CONTEXT IrpContext
,
537 _Out_writes_bytes_(*Length
) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer
,
538 _Inout_ PULONG Length
545 This routine implements the query sector size information call
546 This operation will work on any handle and requires no privilege.
550 Vcb - Supplies the Vcb being queried
552 Buffer - Supplies a pointer to the output buffer where the information
555 Length - Supplies the length of the buffer in byte. This variable
556 upon return receives the remaining bytes free in the buffer
560 NTSTATUS - Returns the status for the query
568 UNREFERENCED_PARAMETER( IrpContext
);
571 // Sufficient buffer size is guaranteed by the I/O manager or the
572 // originating kernel mode driver.
575 ASSERT( *Length
>= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
));
576 _Analysis_assume_( *Length
>= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
));
579 // Retrieve the sector size information
582 Status
= FsRtlGetSectorSizeInformation( Vcb
->Vpb
->RealDevice
,
586 // Adjust the length variable
589 if (NT_SUCCESS( Status
)) {
591 *Length
-= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION
);