reactos/drivers/filesystems/cdfs_new/volinfo.c
Joachim Henze 688875e411 [0.4.7][CDFS_NEW/NTOSKRNL/NDK] Switch from our old CDFS to MS-PL CDFS_NEW
The main motivation to switch to that newer driver is, that our old one
simply can not read all isos. Especially complex ones made trouble and were
only shown as empty in explorer.
It is still possible to build and use the old driver when needed, only thing
that needs to be done for that is to revert 0.4.8-dev-164-g ec6b3ecbe4

Porting back the state up to 0.4.8-release-100-g8f947b5 implies:

Fixing the following JIRA-IDs (or avoid introducing them):
CORE-18029 "Mute noisy DPRINT 'SectionObject has ImageSection'"
CORE-17405 "Fix a macro-copy-paste and shrink the binary size"
CORE-15659 "Unable to build the gcc Release version in Windows using RosBE 2.1.6 (module cdfs fails)"
CORE-14315 "CDFS_NEW assertion during first stage setup due to new CcPerformReadAhead"
CORE-14128 "Avast! Free Antivirus 7.0 hangs the system when trying to detect a newly created virus"
CORE-14067 "CDFS_NEW assertions and exceptions"
CORE-14003 "Shutting down LiveCD asserts since introduction of MS PL CDFS_NEW"
CORE-13184 "Restore ability to install from disk-image"

by picking the following commits:
0.4.8-release-100-g 8f947b5322 [NTOSKRNL] Mute noisy DPRINT 'SectionObject has ImageSection' CORE-18029
0.4.8-release-80-g eb1ea19588 [CDFS_NEW] == 0.4.15-dev-1456-g 889eab7 CORE-17405
0.4.8-release-62-g 8c07aad4a8 [CDFS_NEW/XDK] == 0.4.11-dev-39-g a2f9762 + 0.4.11-dev-40-g 6d7ec8c CORE-14067
0.4.8-release-3-g 5d976d04e8 [CDFS_NEW] == 0.4.12-dev-431-g bccad87f3c + 0.4.12-dev-432-g 3463b2db9f CORE-15659
0.4.8-RC-3-g 51f9494d48 [CDFS_NEW] superseded later by the proper fix 0.4.8-release-62-g 8c07aad4a8 CORE-14067
0.4.8-dev-1069-g a5e89014dc [CDFS_NEW] CORE-14315
0.4.8-dev-475-g a59d4674de [NTOSKRNL] io/iomgr/device.c (forgotten assert) CORE-14128
0.4.8-dev-221-g 9d67a24799 [CDFS_NEW]
0.4.8-dev-220-g 67a7e45e35 [CDFS_NEW/DOC]
0.4.8-dev-219-g 6a3bbf24e0 [CDFS_NEW]
0.4.8-dev-218-g ec26cde4a1 [CDFS_NEW]
0.4.8-dev-217-g bc2378a356 [CDFS_NEW]
0.4.8-dev-216-g 5429771b99 [CDFS_NEW]
0.4.8-dev-215-g fd34548263 [CDFS_NEW] Sync with MS-PL driver
0.4.8-dev-164-g ec6b3ecbe4 [FILESYSTEMS] switch from CDFS to CDFS_NEW in CMakeLists.txt
0.4.8-dev-160-g 2b217e4ecf [NTOSKRNL] Mute spam CcSetReadAheadGranularity()
0.4.8-dev-159-g 64cb138a67 [NTOSKRNL] Mute spam CcPurgeCacheSection()
0.4.8-dev-150-g f723d230a0 [CDFS_NEW]
0.4.8-dev-133-g faee3753ea [CDFS_NEW] CORE-14003
0.4.8-dev-132-g 1d777ffab5 [NTOSKRNL] iofunc.c CORE-14003
0.4.8-dev-131-g c3d5a3f2bd [NTOSKRNL] iofunc.c CORE-14003
0.4.8-dev-130-g 3b64f7f8fb [NTOSKRNL] ob/obref.c & co CORE-14003
0.4.8-dev-129-g 7eefe70294 [NTOSKRNL] io/iomgr.c & co CORE-14003
0.4.8-dev-127-g 5f255827d3 [CDFS_NEW]
0.4.8-dev-126-g 1bef48796e [NTOSKRNL] just a comment, superseded later
0.4.8-dev-125-g cbf0430b56 [CDFS_NEW]
0.4.8-dev-123-g f88fe43abd [NTOSKRNL] io/iomgr/device.c (forbidden DPRINT)
0.4.8-dev-122-g 6c73385625 [CDFS_NEW] CORE-13184
0.4.8-dev-97-g 94298313c0 [CDFS_NEW]
0.4.8-dev-95-g e88eeb21af [CDFS_NEW/NTOSKRNL] CcWaitForCurrentLazyWriterActivity() stub return Success
0.4.8-dev-94-g 03d5be6437 [CDFS_NEW]
0.4.8-dev-93-g fa1c60db50 [CDFS_NEW]
0.4.8-dev-92-g 8b2fd60829 [CDFS_NEW]
0.4.8-dev-91-g e4da7ecc50 [CDFS_NEW]
0.4.8-dev-90-g 7b19676e2b [CDFS_NEW]
0.4.8-dev-89-g 3d4b8783fd [CDFS_NEW]
0.4.8-dev-88-g 818025ecc8 [CDFS_NEW]
0.4.8-dev-87-g 2639dd6736 [CDFS_NEW]
0.4.8-dev-86-g 755bdb5d0b [CDFS_NEW]
0.4.8-dev-85-g 3cbcb1bade [CDFS_NEW]

and mute spam in opcode INSTEAD of picking:
0.4.8-dev-165-g 2284a457a3 [NTOSKRNL] oplock.c Fixup
0.4.8-dev-163-g d3d5853956 [NTOSKRNL] oplock.c Implement oplock-support
0.4.12-dev-232-g f488102c86 [CDFS] was also left out for now

I am aware, that the backport introduces white-space-glitches within CDFS_NEW.
I decided to live with them in favor of better sync to master and newer releases.
2022-01-27 21:11:23 +01:00

606 lines
12 KiB
C
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
VolInfo.c
Abstract:
This module implements the volume information routines for Cdfs called by
the dispatch driver.
--*/
#include "cdprocs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (CDFS_BUG_CHECK_VOLINFO)
//
// Local support routines
//
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryFsVolumeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsDeviceInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
_Inout_ PULONG Length
);
NTSTATUS
CdQueryFsAttributeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
_Inout_ PULONG Length
);
#ifdef __REACTOS__
#define PFILE_FS_SECTOR_SIZE_INFORMATION PVOID
#endif
NTSTATUS
CdQueryFsSectorSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdCommonQueryVolInfo)
#pragma alloc_text(PAGE, CdQueryFsAttributeInfo)
#pragma alloc_text(PAGE, CdQueryFsDeviceInfo)
#pragma alloc_text(PAGE, CdQueryFsSizeInfo)
#pragma alloc_text(PAGE, CdQueryFsVolumeInfo)
#pragma alloc_text(PAGE, CdQueryFsSectorSizeInfo)
#endif
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdCommonQueryVolInfo (
_Inout_ PIRP_CONTEXT IrpContext,
_Inout_ PIRP Irp
)
/*++
Routine Description:
This is the common routine for querying volume information called by both
the fsd and fsp threads.
Arguments:
Irp - Supplies the Irp being processed
Return Value:
NTSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
ULONG Length;
TYPE_OF_OPEN TypeOfOpen;
PFCB Fcb;
PCCB Ccb;
PAGED_CODE();
//
// Reference our input parameters to make things easier
//
Length = IrpSp->Parameters.QueryVolume.Length;
//
// Decode the file object and fail if this an unopened file object.
//
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
if (TypeOfOpen == UnopenedFileObject) {
CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
return STATUS_INVALID_PARAMETER;
}
//
// Acquire the Vcb for this volume.
//
CdAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
//
// Use a try-finally to facilitate cleanup.
//
_SEH2_TRY {
//
// Verify the Vcb.
//
CdVerifyVcb( IrpContext, Fcb->Vcb );
//
// Based on the information class we'll do different actions. Each
// of the procedures that we're calling fills up the output buffer
// if possible and returns true if it successfully filled the buffer
// and false if it couldn't wait for any I/O to complete.
//
switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
case FileFsSizeInformation:
Status = CdQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsVolumeInformation:
Status = CdQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsDeviceInformation:
Status = CdQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsAttributeInformation:
Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
#if (NTDDI_VERSION >= NTDDI_WIN8)
case FileFsSectorSizeInformation:
Status = CdQueryFsSectorSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
#endif
/* ReactOS Change: GCC "enumeration value not handled in switch" */
default: break;
}
//
// Set the information field to the number of bytes actually filled in
//
Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
} _SEH2_FINALLY {
//
// Release the Vcb.
//
CdReleaseVcb( IrpContext, Fcb->Vcb );
} _SEH2_END;
//
// Complete the request if we didn't raise.
//
CdCompleteRequest( IrpContext, Irp, Status );
return Status;
}
//
// Local support routine
//
_Requires_lock_held_(_Global_critical_region_)
NTSTATUS
CdQueryFsVolumeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_VOLUME_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query volume info call
Arguments:
Vcb - Vcb for this volume.
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return recieves the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
ULONG BytesToCopy;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Fill in the data from the Vcb.
//
Buffer->VolumeCreationTime = *((PLARGE_INTEGER) &Vcb->VolumeDasdFcb->CreationTime);
Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
Buffer->SupportsObjects = FALSE;
*Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
//
// Check if the buffer we're given is long enough
//
if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) {
BytesToCopy = Vcb->Vpb->VolumeLabelLength;
} else {
BytesToCopy = *Length;
Status = STATUS_BUFFER_OVERFLOW;
}
//
// Copy over what we can of the volume label, and adjust *Length
//
Buffer->VolumeLabelLength = BytesToCopy;
if (BytesToCopy) {
RtlCopyMemory( &Buffer->VolumeLabel[0],
&Vcb->Vpb->VolumeLabel[0],
BytesToCopy );
}
*Length -= BytesToCopy;
//
// Set our status and return to our caller
//
return Status;
}
//
// Local support routine
//
NTSTATUS
CdQueryFsSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query volume size call.
Arguments:
Vcb - Vcb for this volume.
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return recieves the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Fill in the output buffer.
//
Buffer->TotalAllocationUnits.QuadPart = LlSectorsFromBytes( Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
Buffer->AvailableAllocationUnits.QuadPart = 0;
Buffer->SectorsPerAllocationUnit = 1;
Buffer->BytesPerSector = SECTOR_SIZE;
//
// Adjust the length variable
//
*Length -= sizeof( FILE_FS_SIZE_INFORMATION );
//
// And return success to our caller
//
return STATUS_SUCCESS;
}
//
// Local support routine
//
NTSTATUS
CdQueryFsDeviceInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_DEVICE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query volume device call.
Arguments:
Vcb - Vcb for this volume.
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return recieves the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Update the output buffer.
//
Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
Buffer->DeviceType = FILE_DEVICE_CD_ROM;
//
// Adjust the length variable
//
*Length -= sizeof( FILE_FS_DEVICE_INFORMATION );
//
// And return success to our caller
//
return STATUS_SUCCESS;
}
//
// Local support routine
//
NTSTATUS
CdQueryFsAttributeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_ PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query volume attribute call.
Arguments:
Vcb - Vcb for this volume.
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return recieves the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
ULONG BytesToCopy;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
UNREFERENCED_PARAMETER( Vcb );
//
// Fill out the fixed portion of the buffer.
//
Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
FILE_READ_ONLY_VOLUME |
FILE_SUPPORTS_OPEN_BY_FILE_ID;
if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
SetFlag( Buffer->FileSystemAttributes, FILE_UNICODE_ON_DISK );
Buffer->MaximumComponentNameLength = 110;
} else {
Buffer->MaximumComponentNameLength = 221;
}
*Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName );
//
// Make sure we can copy full unicode characters.
//
ClearFlag( *Length, 1 );
//
// Determine how much of the file system name will fit.
//
if (*Length >= 8) {
BytesToCopy = 8;
} else {
BytesToCopy = *Length;
Status = STATUS_BUFFER_OVERFLOW;
}
*Length -= BytesToCopy;
//
// Do the file system name.
//
Buffer->FileSystemNameLength = BytesToCopy;
RtlCopyMemory( &Buffer->FileSystemName[0], L"CDFS", BytesToCopy );
//
// And return to our caller
//
return Status;
}
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSTATUS
CdQueryFsSectorSizeInfo (
_In_ PIRP_CONTEXT IrpContext,
_In_ PVCB Vcb,
_Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
_Inout_ PULONG Length
)
/*++
Routine Description:
This routine implements the query sector size information call
This operation will work on any handle and requires no privilege.
Arguments:
Vcb - Supplies the Vcb being queried
Buffer - Supplies a pointer to the output buffer where the information
is to be returned
Length - Supplies the length of the buffer in byte. This variable
upon return receives the remaining bytes free in the buffer
Return Value:
NTSTATUS - Returns the status for the query
--*/
{
NTSTATUS Status;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Sufficient buffer size is guaranteed by the I/O manager or the
// originating kernel mode driver.
//
ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
_Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
//
// Retrieve the sector size information
//
Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
Buffer );
//
// Adjust the length variable
//
if (NT_SUCCESS( Status )) {
*Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
}
return Status;
}
#endif