[CDFS_NEW] -> [CDFS] No old driver, thus no new driver
[reactos.git] / drivers / filesystems / cdfs / volinfo.c
diff --git a/drivers/filesystems/cdfs/volinfo.c b/drivers/filesystems/cdfs/volinfo.c
new file mode 100644 (file)
index 0000000..7448dd5
--- /dev/null
@@ -0,0 +1,605 @@
+/*++
+
+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
+
+\f
+_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;
+}
+
+\f
+//
+//  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;
+}
+
+\f
+//
+//  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;
+}
+
+\f
+//
+//  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;
+}
+
+\f
+//
+//  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
+