windows-nt/Source/XPSP1/NT/base/fs/mailslot/volinfo.c

623 lines
12 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
fileinfo.c
Abstract:
This module implements the get / set volume information routines for
MSFS called by the dispatch driver.
Setting volume information is currently unimplemented in MSFS.
Author:
Manny Weiser (mannyw) 31-Jan-1991
Revision History:
--*/
#include "mailslot.h"
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_FILEINFO)
//
// Local procedure prototypes.
//
NTSTATUS
MsCommonQueryVolumeInformation (
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
IN PIRP Irp
);
NTSTATUS
MsQueryAttributeInfo (
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
);
NTSTATUS
MsQueryFsVolumeInfo (
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
);
NTSTATUS
MsQueryFsSizeInfo (
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
);
NTSTATUS
MsQueryFsFullSizeInfo (
IN PVCB Vcb,
IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
);
NTSTATUS
MsQueryFsDeviceInfo (
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, MsCommonQueryVolumeInformation )
#pragma alloc_text( PAGE, MsFsdQueryVolumeInformation )
#pragma alloc_text( PAGE, MsQueryAttributeInfo )
#pragma alloc_text( PAGE, MsQueryFsVolumeInfo )
#pragma alloc_text( PAGE, MsQueryFsSizeInfo )
#pragma alloc_text( PAGE, MsQueryFsDeviceInfo )
#pragma alloc_text( PAGE, MsQueryFsFullSizeInfo )
#endif
NTSTATUS
MsFsdQueryVolumeInformation (
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the FSD part of the NtQueryVolumeInformationFile
API calls.
Arguments:
MsfsDeviceObject - Supplies a pointer to the device object to use.
Irp - Supplies a pointer to the Irp to process.
Return Value:
NTSTATUS - The Fsd status for the Irp
--*/
{
NTSTATUS status;
PAGED_CODE();
DebugTrace(+1, Dbg, "MsFsdQueryVolumeInformation\n", 0);
//
// Call the common query volume information routine.
//
FsRtlEnterFileSystem();
status = MsCommonQueryVolumeInformation( MsfsDeviceObject, Irp );
FsRtlExitFileSystem();
//
// Return to the caller.
//
DebugTrace(-1, Dbg, "MsFsdQueryVolumeInformation -> %08lx\n", status );
return status;
}
NTSTATUS
MsCommonQueryVolumeInformation (
IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for querying volume information.
Arguments:
MsfsDeviceObject - The device object to use.
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - the return status for the operation.
--*/
{
PIO_STACK_LOCATION irpSp;
NTSTATUS status;
ULONG length;
ULONG bytesWritten = 0;
FS_INFORMATION_CLASS fsInformationClass;
PVOID buffer;
NODE_TYPE_CODE nodeTypeCode;
PVCB vcb;
PVOID fsContext, fsContext2;
PAGED_CODE();
//
// Get the current stack location.
//
irpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace(+1, Dbg, "MsCommonQueryInformation...\n", 0);
DebugTrace( 0, Dbg, " Irp = %08lx\n", (ULONG)Irp);
DebugTrace( 0, Dbg, " ->Length = %08lx\n", irpSp->Parameters.QueryFile.Length);
DebugTrace( 0, Dbg, " ->FsInformationClass = %08lx\n", irpSp->Parameters.QueryVolume.FsInformationClass);
DebugTrace( 0, Dbg, " ->Buffer = %08lx\n", (ULONG)Irp->AssociatedIrp.SystemBuffer);
//
// Find out who are.
//
if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject,
&fsContext,
&fsContext2 )) == NTC_UNDEFINED) {
DebugTrace(0, Dbg, "Mailslot is disconnected from us\n", 0);
MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED );
status = STATUS_FILE_FORCED_CLOSED;
DebugTrace(-1, Dbg, "MsCommonQueryInformation -> %08lx\n", status );
return status;
}
//
// Decide how to handle this request. A user can query information
// on a VCB only.
//
switch (nodeTypeCode) {
case MSFS_NTC_VCB:
vcb = (PVCB)fsContext;
break;
case MSFS_NTC_ROOT_DCB :
//
// Explorer calls us like this. Ship from the root dir to the volume.
//
vcb = (PVCB) ((PROOT_DCB_CCB)fsContext2)->Vcb;
MsReferenceVcb (vcb);
MsDereferenceRootDcb ((PROOT_DCB) fsContext);
break;
default: // This is not a volume control block.
DebugTrace(0, Dbg, "Node type code is not incorrect\n", 0);
MsDereferenceNode( (PNODE_HEADER)fsContext );
MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
DebugTrace(-1,
Dbg,
"MsCommonQueryVolumeInformation -> STATUS_INVALID_PARAMETER\n",
0);
return STATUS_INVALID_PARAMETER;
}
//
// Make local copies of the input parameters.
//
length = irpSp->Parameters.QueryVolume.Length;
fsInformationClass = irpSp->Parameters.QueryVolume.FsInformationClass;
buffer = Irp->AssociatedIrp.SystemBuffer;
//
// Now acquire shared access to the VCB
//
MsAcquireSharedVcb( vcb );
try {
//
// Decide how to handle the request.
//
switch (fsInformationClass) {
case FileFsAttributeInformation:
status = MsQueryAttributeInfo( vcb, buffer, length, &bytesWritten );
break;
case FileFsVolumeInformation:
status = MsQueryFsVolumeInfo( vcb, buffer, length, &bytesWritten );
break;
case FileFsSizeInformation:
status = MsQueryFsSizeInfo( vcb, buffer, length, &bytesWritten );
break;
case FileFsFullSizeInformation:
status = MsQueryFsFullSizeInfo( vcb, buffer, length, &bytesWritten );
break;
case FileFsDeviceInformation:
status = MsQueryFsDeviceInfo( vcb, buffer, length, &bytesWritten );
break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
} finally {
MsReleaseVcb( vcb );
MsDereferenceVcb( vcb );
//
// Set the information field to the number of bytes actually
// filled in and then complete the request.
//
Irp->IoStatus.Information = bytesWritten;
MsCompleteRequest( Irp, status );
DebugTrace(-1, Dbg, "MsCommonQueryVolumeInformation -> %08lx\n", status );
}
return status;
}
NTSTATUS
MsQueryAttributeInfo (
IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
)
/*++
Routine Description:
This routine performs the query fs attribute information operation.
Arguments:
Vcb - Supplies the VCB to query.
Buffer - Supplies a pointer to the buffer where the information is
to be returned.
Length - Supplies the length of the buffer in bytes.
BytesWritten - Returns the number of bytes written to the buffer.
Return Value:
NTSTATUS - The result of this query.
--*/
{
NTSTATUS status;
PAGED_CODE();
DebugTrace(0, Dbg, "QueryFsAttributeInfo...\n", 0);
//
// See how many bytes of the file system name we can copy.
//
Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0] );
if ( Length >= Vcb->FileSystemName.Length ) {
status = STATUS_SUCCESS;
*BytesWritten = Vcb->FileSystemName.Length;
} else {
status = STATUS_BUFFER_OVERFLOW;
*BytesWritten = Length;
}
//
// Fill in the attribute information.
//
Buffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
Buffer->MaximumComponentNameLength = MAXIMUM_FILENAME_LENGTH;
//
// And copy over the file name and its length.
//
RtlCopyMemory (&Buffer->FileSystemName[0],
&Vcb->FileSystemName.Buffer[0],
*BytesWritten);
Buffer->FileSystemNameLength = *BytesWritten;
//
// Now account for the fixed part of the structure
//
*BytesWritten += FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0] );
return status;
}
NTSTATUS
MsQueryFsVolumeInfo (
IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
)
/*++
Routine Description:
This routine implements the query volume info call
Arguments:
Vcb - Supplies the VCB to query.
Buffer - Supplies a pointer to the buffer where the information is
to be returned.
Length - Supplies the length of the buffer in bytes.
BytesWritten - Returns the number of bytes written to the buffer.
Return Value:
NTSTATUS - The result of this query.
--*/
{
ULONG BytesToCopy;
NTSTATUS Status;
Status = STATUS_SUCCESS;
Buffer->VolumeCreationTime = Vcb->CreationTime;
Buffer->VolumeSerialNumber = 0;
Buffer->SupportsObjects = FALSE;
Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] );
//
// Check if the buffer we're given is long enough
//
BytesToCopy = sizeof (MSFS_VOLUME_LABEL) - sizeof (WCHAR);
if (Length < BytesToCopy) {
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],
MSFS_VOLUME_LABEL,
BytesToCopy );
}
*BytesWritten = FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] ) + BytesToCopy;
//
// Set our status and return to our caller
//
return Status;
}
NTSTATUS
MsQueryFsSizeInfo (
IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
)
/*++
Routine Description:
This routine implements the query size info call
Arguments:
Vcb - Supplies the VCB to query.
Buffer - Supplies a pointer to the buffer where the information is
to be returned.
Length - Supplies the length of the buffer in bytes.
BytesWritten - Returns the number of bytes written to the buffer.
Return Value:
NTSTATUS - The result of this query.
--*/
{
Buffer->TotalAllocationUnits.QuadPart = 0;
Buffer->AvailableAllocationUnits.QuadPart = 0;
Buffer->SectorsPerAllocationUnit = 0;
Buffer->BytesPerSector = 0;
*BytesWritten = sizeof( FILE_FS_SIZE_INFORMATION );
//
// Set our status and return to our caller
//
return STATUS_SUCCESS;
}
NTSTATUS
MsQueryFsFullSizeInfo (
IN PVCB Vcb,
IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
)
/*++
Routine Description:
This routine implements the query full size info call
Arguments:
Vcb - Supplies the VCB to query.
Buffer - Supplies a pointer to the buffer where the information is
to be returned.
Length - Supplies the length of the buffer in bytes.
BytesWritten - Returns the number of bytes written to the buffer.
Return Value:
NTSTATUS - The result of this query.
--*/
{
RtlZeroMemory( Buffer, sizeof(FILE_FS_FULL_SIZE_INFORMATION) );
*BytesWritten = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
//
// Set our status and return to our caller
//
return STATUS_SUCCESS;
}
NTSTATUS
MsQueryFsDeviceInfo (
IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN ULONG Length,
OUT PULONG BytesWritten
)
/*++
Routine Description:
This routine implements the query size info call
Arguments:
Vcb - Supplies the VCB to query.
Buffer - Supplies a pointer to the buffer where the information is
to be returned.
Length - Supplies the length of the buffer in bytes.
BytesWritten - Returns the number of bytes written to the buffer.
Return Value:
NTSTATUS - The result of this query.
--*/
{
Buffer->Characteristics = 0;
Buffer->DeviceType = FILE_DEVICE_MAILSLOT;
//
// Adjust the length variable
//
*BytesWritten = sizeof( FILE_FS_DEVICE_INFORMATION );
//
// And return success to our caller
//
return STATUS_SUCCESS;
}