📄 fileinfo.c
字号:
/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
FileInfo.c
Abstract:
This module implements the File Information routines for Fat called by
the dispatch driver.
--*/
#include "FatProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (FAT_BUG_CHECK_FILEINFO)
//
// The local debug trace level
//
#define Dbg (DEBUG_TRACE_FILEINFO)
VOID
FatQueryBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_BASIC_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryStandardInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryInternalInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryEaInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_EA_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_POSITION_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCCB Ccb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryShortNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PLONG Length
);
VOID
FatQueryNetworkInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
IN OUT PLONG Length
);
NTSTATUS
FatSetBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFCB Fcb,
IN PCCB Ccb
);
NTSTATUS
FatSetDispositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFILE_OBJECT FileObject,
IN PFCB Fcb
);
NTSTATUS
FatSetRenameInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PVCB Vcb,
IN PFCB Fcb,
IN PCCB Ccb
);
NTSTATUS
FatSetPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFILE_OBJECT FileObject
);
NTSTATUS
FatSetAllocationInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFCB Fcb,
IN PFILE_OBJECT FileObject
);
NTSTATUS
FatSetEndOfFileInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFILE_OBJECT FileObject,
IN PVCB Vcb,
IN PFCB Fcb
);
VOID
FatDeleteFile (
IN PIRP_CONTEXT IrpContext,
IN PDCB TargetDcb,
IN ULONG LfnOffset,
IN ULONG DirentOffset,
IN PDIRENT Dirent,
IN PUNICODE_STRING Lfn
);
VOID
FatRenameEAs (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN USHORT ExtendedAttributes,
IN POEM_STRING OldOemName
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FatCommonQueryInformation)
#pragma alloc_text(PAGE, FatCommonSetInformation)
#pragma alloc_text(PAGE, FatFsdQueryInformation)
#pragma alloc_text(PAGE, FatFsdSetInformation)
#pragma alloc_text(PAGE, FatQueryBasicInfo)
#pragma alloc_text(PAGE, FatQueryEaInfo)
#pragma alloc_text(PAGE, FatQueryInternalInfo)
#pragma alloc_text(PAGE, FatQueryNameInfo)
#pragma alloc_text(PAGE, FatQueryNetworkInfo)
#pragma alloc_text(PAGE, FatQueryShortNameInfo)
#pragma alloc_text(PAGE, FatQueryPositionInfo)
#pragma alloc_text(PAGE, FatQueryStandardInfo)
#pragma alloc_text(PAGE, FatSetAllocationInfo)
#pragma alloc_text(PAGE, FatSetBasicInfo)
#pragma alloc_text(PAGE, FatSetDispositionInfo)
#pragma alloc_text(PAGE, FatSetEndOfFileInfo)
#pragma alloc_text(PAGE, FatSetPositionInfo)
#pragma alloc_text(PAGE, FatSetRenameInfo)
#pragma alloc_text(PAGE, FatDeleteFile)
#pragma alloc_text(PAGE, FatRenameEAs)
#endif
NTSTATUS
FatFsdQueryInformation (
IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the Fsd part of the NtQueryInformationFile API
call.
Arguments:
VolumeDeviceObject - Supplies the volume device object where the file
being queried exists.
Irp - Supplies the Irp being processed.
Return Value:
NTSTATUS - The FSD status for the Irp.
--*/
{
NTSTATUS Status;
PIRP_CONTEXT IrpContext = NULL;
BOOLEAN TopLevel;
DebugTrace(+1, Dbg, "FatFsdQueryInformation\n", 0);
//
// Call the common query routine, with blocking allowed if synchronous
//
FsRtlEnterFileSystem();
TopLevel = FatIsIrpTopLevel( Irp );
try {
IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
Status = FatCommonQueryInformation( IrpContext, Irp );
} except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {
//
// We had some trouble trying to perform the requested
// operation, so we'll abort the I/O request with
// the error status that we get back from the
// execption code
//
Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
}
if (TopLevel) { IoSetTopLevelIrp( NULL ); }
FsRtlExitFileSystem();
//
// And return to our caller
//
DebugTrace(-1, Dbg, "FatFsdQueryInformation -> %08lx\n", Status);
UNREFERENCED_PARAMETER( VolumeDeviceObject );
return Status;
}
NTSTATUS
FatFsdSetInformation (
IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the FSD part of the NtSetInformationFile API
call.
Arguments:
VolumeDeviceObject - Supplies the volume device object where the file
being set exists.
Irp - Supplies the Irp being processed.
Return Value:
NTSTATUS - The FSD status for the Irp.
--*/
{
NTSTATUS Status;
PIRP_CONTEXT IrpContext = NULL;
BOOLEAN TopLevel;
DebugTrace(+1, Dbg, "FatFsdSetInformation\n", 0);
//
// Call the common set routine, with blocking allowed if synchronous
//
FsRtlEnterFileSystem();
TopLevel = FatIsIrpTopLevel( Irp );
try {
IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
Status = FatCommonSetInformation( IrpContext, Irp );
} except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {
//
// We had some trouble trying to perform the requested
// operation, so we'll abort the I/O request with
// the error status that we get back from the
// execption code
//
Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
}
if (TopLevel) { IoSetTopLevelIrp( NULL ); }
FsRtlExitFileSystem();
//
// And return to our caller
//
DebugTrace(-1, Dbg, "FatFsdSetInformation -> %08lx\n", Status);
UNREFERENCED_PARAMETER( VolumeDeviceObject );
return Status;
}
NTSTATUS
FatCommonQueryInformation (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for querying file 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;
PIO_STACK_LOCATION IrpSp;
PFILE_OBJECT FileObject;
LONG Length;
FILE_INFORMATION_CLASS FileInformationClass;
PVOID Buffer;
TYPE_OF_OPEN TypeOfOpen;
PVCB Vcb;
PFCB Fcb;
PCCB Ccb;
BOOLEAN FcbAcquired = FALSE;
BOOLEAN VcbAcquired = FALSE;
PFILE_ALL_INFORMATION AllInfo;
//
// Get the current stack location
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
FileObject = IrpSp->FileObject;
DebugTrace(+1, Dbg, "FatCommonQueryInformation...\n", 0);
DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp);
DebugTrace( 0, Dbg, "->Length = %08lx\n", IrpSp->Parameters.QueryFile.Length);
DebugTrace( 0, Dbg, "->FileInformationClass = %08lx\n", IrpSp->Parameters.QueryFile.FileInformationClass);
DebugTrace( 0, Dbg, "->Buffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer);
//
// Reference our input parameters to make things easier
//
Length = (LONG)IrpSp->Parameters.QueryFile.Length;
FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
Buffer = Irp->AssociatedIrp.SystemBuffer;
//
// Decode the file object
//
TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );
Status = STATUS_SUCCESS;
try {
//
// Case on the type of open we're dealing with
//
switch (TypeOfOpen) {
case UserVolumeOpen:
//
// We cannot query the user volume open.
//
Status = STATUS_INVALID_PARAMETER;
break;
case UserFileOpen:
case UserDirectoryOpen:
case DirectoryFile:
//
// NameInfo requires synchronization with deletion in order to perform
// the full filename query. A lighter-weight way to do this would be per
// directory as the full name is built up and since the multiple Fcb
// lockorder is bottom up, this is conceivable. At this time, though,
// this change is safer.
//
if (FileInformationClass == FileNameInformation ||
FileInformationClass == FileAllInformation) {
if (!FatAcquireExclusiveVcb( IrpContext, Vcb )) {
DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);
Status = FatFsdPostRequest( IrpContext, Irp );
IrpContext = NULL;
Irp = NULL;
try_return( Status );
}
VcbAcquired = TRUE;
}
//
// Acquire shared access to the fcb, except for a paging file
// in order to avoid deadlocks with Mm.
//
if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE )) {
if (!FatAcquireSharedFcb( IrpContext, Fcb )) {
DebugTrace(0, Dbg, "Cannot acquire Fcb\n", 0);
Status = FatFsdPostRequest( IrpContext, Irp );
IrpContext = NULL;
Irp = NULL;
try_return( Status );
}
FcbAcquired = TRUE;
}
//
// Make sure the Fcb is in a usable condition. This
// will raise an error condition if the fcb is unusable
//
FatVerifyFcb( IrpContext, Fcb );
//
// Based on the information class we'll do different
// actions. Each of hte procedures that we're calling fills
// up the output buffer, if possible. They will raise the
// status STATUS_BUFFER_OVERFLOW for an insufficient buffer.
// This is considered a somewhat unusual case and is handled
// more cleanly with the exception mechanism rather than
// testing a return status value for each call.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -