mirror of https://github.com/tongzx/nt5src
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.
623 lines
12 KiB
623 lines
12 KiB
/*++
|
|
|
|
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;
|
|
}
|