Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

509 lines
9.8 KiB

/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
VolInfo.c
Abstract:
This module implements the volume information routines for Udfs called by
the dispatch driver.
// @@BEGIN_DDKSPLIT
Author:
Dan Lovinger [DanLo] 20-Jan-1997
Revision History:
// @@END_DDKSPLIT
--*/
#include "UdfProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (UDFS_BUG_CHECK_VOLINFO)
//
// The local debug trace level
//
#define Dbg (UDFS_DEBUG_LEVEL_VOLINFO)
//
// Local support routines
//
NTSTATUS
UdfQueryFsVolumeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN OUT PULONG Length
);
NTSTATUS
UdfQueryFsSizeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN OUT PULONG Length
);
NTSTATUS
UdfQueryFsDeviceInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN OUT PULONG Length
);
NTSTATUS
UdfQueryFsAttributeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN OUT PULONG Length
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCommonQueryVolInfo)
#pragma alloc_text(PAGE, UdfQueryFsAttributeInfo)
#pragma alloc_text(PAGE, UdfQueryFsDeviceInfo)
#pragma alloc_text(PAGE, UdfQueryFsSizeInfo)
#pragma alloc_text(PAGE, UdfQueryFsVolumeInfo)
#endif
NTSTATUS
UdfCommonQueryVolInfo (
IN PIRP_CONTEXT IrpContext,
IN 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 = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb );
if (TypeOfOpen == UnopenedFileObject) {
UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
return STATUS_INVALID_PARAMETER;
}
//
// Acquire the Vcb for this volume.
//
UdfAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE );
//
// Use a try-finally to facilitate cleanup.
//
try {
//
// Verify the Vcb.
//
UdfVerifyVcb( 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 = UdfQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsVolumeInformation:
Status = UdfQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsDeviceInformation:
Status = UdfQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
case FileFsAttributeInformation:
Status = UdfQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length );
break;
}
//
// Set the information field to the number of bytes actually filled in
//
Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
} finally {
//
// Release the Vcb.
//
UdfReleaseVcb( IrpContext, Fcb->Vcb );
}
//
// Complete the request if we didn't raise.
//
UdfCompleteRequest( IrpContext, Irp, Status );
return Status;
}
//
// Local support routine
//
NTSTATUS
UdfQueryFsVolumeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN OUT 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();
//
// Fill in the data from the Vcb.
//
Buffer->VolumeCreationTime = Vcb->VolumeDasdFcb->Timestamps.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
UdfQueryFsSizeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN OUT 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();
//
// Fill in the output buffer.
//
Buffer->TotalAllocationUnits.QuadPart = LlBlocksFromBytes( Vcb, Vcb->VolumeDasdFcb->AllocationSize.QuadPart );
Buffer->AvailableAllocationUnits.QuadPart = 0;
Buffer->SectorsPerAllocationUnit = SectorsFromBytes( Vcb, BlockSize( Vcb ));
Buffer->BytesPerSector = SectorSize( Vcb );
//
// Adjust the length variable
//
*Length -= sizeof( FILE_FS_SIZE_INFORMATION );
//
// And return success to our caller
//
return STATUS_SUCCESS;
}
//
// Local support routine
//
NTSTATUS
UdfQueryFsDeviceInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN OUT 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();
//
// 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
UdfQueryFsAttributeInfo (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN OUT 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();
//
// Fill out the fixed portion of the buffer.
//
Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH |
FILE_UNICODE_ON_DISK |
FILE_READ_ONLY_VOLUME;
Buffer->MaximumComponentNameLength = 255;
*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 >= 6) {
BytesToCopy = 6;
} else {
BytesToCopy = *Length;
Status = STATUS_BUFFER_OVERFLOW;
}
*Length -= BytesToCopy;
//
// Do the file system name. We explicitly share this designation with all
// Microsoft implementations of the UDF filesystem - DO NOT CHANGE!
//
Buffer->FileSystemNameLength = BytesToCopy;
RtlCopyMemory( &Buffer->FileSystemName[0], L"UDF", BytesToCopy );
//
// And return to our caller
//
return Status;
}