📄 fileinfo.c
字号:
switch (FileInformationClass) {
case FileAllInformation:
//
// For the all information class we'll typecast a local
// pointer to the output buffer and then call the
// individual routines to fill in the buffer.
//
AllInfo = Buffer;
Length -= (sizeof(FILE_ACCESS_INFORMATION)
+ sizeof(FILE_MODE_INFORMATION)
+ sizeof(FILE_ALIGNMENT_INFORMATION));
FatQueryBasicInfo( IrpContext, Fcb, FileObject, &AllInfo->BasicInformation, &Length );
FatQueryStandardInfo( IrpContext, Fcb, &AllInfo->StandardInformation, &Length );
FatQueryInternalInfo( IrpContext, Fcb, &AllInfo->InternalInformation, &Length );
FatQueryEaInfo( IrpContext, Fcb, &AllInfo->EaInformation, &Length );
FatQueryPositionInfo( IrpContext, FileObject, &AllInfo->PositionInformation, &Length );
FatQueryNameInfo( IrpContext, Fcb, Ccb, &AllInfo->NameInformation, &Length );
break;
case FileBasicInformation:
FatQueryBasicInfo( IrpContext, Fcb, FileObject, Buffer, &Length );
break;
case FileStandardInformation:
FatQueryStandardInfo( IrpContext, Fcb, Buffer, &Length );
break;
case FileInternalInformation:
FatQueryInternalInfo( IrpContext, Fcb, Buffer, &Length );
break;
case FileEaInformation:
FatQueryEaInfo( IrpContext, Fcb, Buffer, &Length );
break;
case FilePositionInformation:
FatQueryPositionInfo( IrpContext, FileObject, Buffer, &Length );
break;
case FileNameInformation:
FatQueryNameInfo( IrpContext, Fcb, Ccb, Buffer, &Length );
break;
case FileAlternateNameInformation:
FatQueryShortNameInfo( IrpContext, Fcb, Buffer, &Length );
break;
case FileNetworkOpenInformation:
FatQueryNetworkInfo( IrpContext, Fcb, FileObject, Buffer, &Length );
break;
default:
Status = STATUS_INVALID_PARAMETER;
break;
}
break;
default:
KdPrintEx((DPFLTR_FASTFAT_ID,
DPFLTR_INFO_LEVEL,
"FATQueryFile, Illegal TypeOfOpen = %08lx\n",
TypeOfOpen));
Status = STATUS_INVALID_PARAMETER;
break;
}
//
// If we overflowed the buffer, set the length to 0 and change the
// status to STATUS_BUFFER_OVERFLOW.
//
if ( Length < 0 ) {
Status = STATUS_BUFFER_OVERFLOW;
Length = 0;
}
//
// Set the information field to the number of bytes actually filled in
// and then complete the request
//
Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
try_exit: NOTHING;
} finally {
DebugUnwind( FatCommonQueryInformation );
if (FcbAcquired) { FatReleaseFcb( IrpContext, Fcb ); }
if (VcbAcquired) { FatReleaseVcb( IrpContext, Vcb ); }
if (!AbnormalTermination()) {
FatCompleteRequest( IrpContext, Irp, Status );
}
DebugTrace(-1, Dbg, "FatCommonQueryInformation -> %08lx\n", Status);
}
return Status;
}
NTSTATUS
FatCommonSetInformation (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for setting 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;
FILE_INFORMATION_CLASS FileInformationClass;
TYPE_OF_OPEN TypeOfOpen;
PVCB Vcb;
PFCB Fcb;
PCCB Ccb;
BOOLEAN VcbAcquired = FALSE;
BOOLEAN FcbAcquired = FALSE;
//
// Get the current stack location
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace(+1, Dbg, "FatCommonSetInformation...\n", 0);
DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp);
DebugTrace( 0, Dbg, "->Length = %08lx\n", IrpSp->Parameters.SetFile.Length);
DebugTrace( 0, Dbg, "->FileInformationClass = %08lx\n", IrpSp->Parameters.SetFile.FileInformationClass);
DebugTrace( 0, Dbg, "->FileObject = %08lx\n", IrpSp->Parameters.SetFile.FileObject);
DebugTrace( 0, Dbg, "->ReplaceIfExists = %08lx\n", IrpSp->Parameters.SetFile.ReplaceIfExists);
DebugTrace( 0, Dbg, "->Buffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer);
//
// Reference our input parameters to make things easier
//
FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
FileObject = IrpSp->FileObject;
//
// Decode the file object
//
TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );
try {
//
// Case on the type of open we're dealing with
//
switch (TypeOfOpen) {
case UserVolumeOpen:
//
// We cannot query the user volume open.
//
try_return( Status = STATUS_INVALID_PARAMETER );
break;
case UserFileOpen:
if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE ) &&
((FileInformationClass == FileEndOfFileInformation) ||
(FileInformationClass == FileAllocationInformation))) {
//
// We check whether we can proceed
// based on the state of the file oplocks.
//
Status = FsRtlCheckOplock( &Fcb->Specific.Fcb.Oplock,
Irp,
IrpContext,
NULL,
NULL );
if (Status != STATUS_SUCCESS) {
try_return( Status );
}
//
// Set the flag indicating if Fast I/O is possible
//
Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
}
break;
case UserDirectoryOpen:
break;
default:
try_return( Status = STATUS_INVALID_PARAMETER );
}
//
// We can only do a set on a nonroot dcb, so we do the test
// and then fall through to the user file open code.
//
if (NodeType(Fcb) == FAT_NTC_ROOT_DCB) {
if (FileInformationClass == FileDispositionInformation) {
try_return( Status = STATUS_CANNOT_DELETE );
}
try_return( Status = STATUS_INVALID_PARAMETER );
}
//
// In the following two cases, we cannot have creates occuring
// while we are here, so acquire the volume exclusive.
//
if ((FileInformationClass == FileDispositionInformation) ||
(FileInformationClass == FileRenameInformation)) {
if (!FatAcquireExclusiveVcb( IrpContext, Vcb )) {
DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);
Status = FatFsdPostRequest( IrpContext, Irp );
Irp = NULL;
IrpContext = NULL;
try_return( Status );
}
VcbAcquired = TRUE;
//
// Make sure we haven't been called recursively by a filter inside an existing
// create request.
//
if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_CREATE_IN_PROGRESS)) {
FatBugCheck( 0, 0, 0);
}
}
//
// We need to look here to check whether the oplock state
// will allow us to continue. We may have to loop to prevent
// an oplock being granted between the time we check the oplock
// and obtain the Fcb.
//
//
// Acquire exclusive access to the Fcb, We use exclusive
// because it is probable that one of the subroutines
// that we call will need to monkey with file allocation,
// create/delete extra fcbs. So we're willing to pay the
// cost of exclusive Fcb access.
//
// Note that we do not acquire the resource for paging file
// operations in order to avoid deadlock with Mm.
//
if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE )) {
if (!FatAcquireExclusiveFcb( IrpContext, Fcb )) {
DebugTrace(0, Dbg, "Cannot acquire Fcb\n", 0);
Status = FatFsdPostRequest( IrpContext, Irp );
Irp = NULL;
IrpContext = NULL;
try_return( Status );
}
FcbAcquired = TRUE;
}
Status = STATUS_SUCCESS;
//
// 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 the procedures that we're calling will either
// complete the request of send the request off to the fsp
// to do the work.
//
switch (FileInformationClass) {
case FileBasicInformation:
Status = FatSetBasicInfo( IrpContext, Irp, Fcb, Ccb );
break;
case FileDispositionInformation:
//
// If this is on deferred flush media, we have to be able to wait.
//
if ( FlagOn(Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ) {
Status = FatFsdPostRequest( IrpContext, Irp );
Irp = NULL;
IrpContext = NULL;
} else {
Status = FatSetDispositionInfo( IrpContext, Irp, FileObject, Fcb );
}
break;
case FileRenameInformation:
//
// We proceed with this operation only if we can wait
//
if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
Status = FatFsdPostRequest( IrpContext, Irp );
Irp = NULL;
IrpContext = NULL;
} else {
Status = FatSetRenameInfo( IrpContext, Irp, Vcb, Fcb, Ccb );
//
// If STATUS_PENDING is returned it means the oplock
// package has the Irp. Don't complete the request here.
//
if (Status == STATUS_PENDING) {
Irp = NULL;
IrpContext = NULL;
}
}
break;
case FilePositionInformation:
Status = FatSetPositionInfo( IrpContext, Irp, FileObject );
break;
case FileLinkInformation:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case FileAllocationInformation:
Status = FatSetAllocationInfo( IrpContext, Irp, Fcb, FileObject );
break;
case FileEndOfFileInformation:
Status = FatSetEndOfFileInfo( IrpContext, Irp, FileObject, Vcb, Fcb );
break;
default:
Status = STATUS_INVALID_PARAMETER;
break;
}
if ( IrpContext != NULL ) {
FatUnpinRepinnedBcbs( IrpContext );
}
try_exit: NOTHING;
} finally {
DebugUnwind( FatCommonSetInformation );
if (FcbAcquired) { FatReleaseFcb( IrpContext, Fcb ); }
if (VcbAcquired) { FatReleaseVcb( IrpContext, Vcb ); }
if (!AbnormalTermination()) {
FatCompleteRequest( IrpContext, Irp, Status );
}
DebugTrace(-1, Dbg, "FatCommonSetInformation -> %08lx\n", Status);
}
return Status;
}
//
// Internal Support Routine
//
VOID
FatQueryBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_BASIC_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Description:
This routine performs the query basic information function for fat.
Arguments:
Fcb - Supplies the Fcb being queried, it has been verified
FileObject - Supplies the flag bit that indicates the file was modified.
Buffer - Supplies a pointer to the buffer where the information is to
be returned
Length - Supplies the length of the buffer in bytes, and receives the
remaining bytes free in the buffer upon return.
Return Value:
None
--*/
{
DebugTrace(+1, Dbg, "FatQueryBasicInfo...\n", 0);
//
// Zero out the output buffer, and set it to indicate that
// the query is a normal file. Later we might overwrite the
// attribute.
//
RtlZeroMemory( Buffer, sizeof(FILE_BASIC_INFORMATION) );
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -