📄 fileinfo.c
字号:
/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
FileInfo.c
Abstract:
This module implements the File Information routines for Cdfs called by
the Fsd/Fsp dispatch drivers.
--*/
#include "CdProcs.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (CDFS_BUG_CHECK_FILEINFO)
//
// Local support routines
//
VOID
CdQueryBasicInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_BASIC_INFORMATION Buffer,
IN OUT PULONG Length
);
VOID
CdQueryStandardInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
IN OUT PULONG Length
);
VOID
CdQueryInternalInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PULONG Length
);
VOID
CdQueryEaInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_EA_INFORMATION Buffer,
IN OUT PULONG Length
);
VOID
CdQueryPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_POSITION_INFORMATION Buffer,
IN OUT PULONG Length
);
NTSTATUS
CdQueryNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
);
NTSTATUS
CdQueryAlternateNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCCB Ccb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PULONG Length
);
VOID
CdQueryNetworkInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
IN OUT PULONG Length
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdCommonQueryInfo)
#pragma alloc_text(PAGE, CdCommonSetInfo)
#pragma alloc_text(PAGE, CdFastQueryBasicInfo)
#pragma alloc_text(PAGE, CdFastQueryStdInfo)
#pragma alloc_text(PAGE, CdFastQueryNetworkInfo)
#pragma alloc_text(PAGE, CdQueryAlternateNameInfo)
#pragma alloc_text(PAGE, CdQueryBasicInfo)
#pragma alloc_text(PAGE, CdQueryEaInfo)
#pragma alloc_text(PAGE, CdQueryInternalInfo)
#pragma alloc_text(PAGE, CdQueryNameInfo)
#pragma alloc_text(PAGE, CdQueryNetworkInfo)
#pragma alloc_text(PAGE, CdQueryPositionInfo)
#pragma alloc_text(PAGE, CdQueryStandardInfo)
#endif
NTSTATUS
CdCommonQueryInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for query file information called by both the
fsd and fsp threads.
Arguments:
Irp - Supplies the Irp to process.
Return Value:
NTSTATUS - The return status for this operation.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
ULONG Length;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_ALL_INFORMATION Buffer;
TYPE_OF_OPEN TypeOfOpen;
PFCB Fcb;
PCCB Ccb;
BOOLEAN ReleaseFcb = FALSE;
PAGED_CODE();
//
// Reference our input parameters to make things easier
//
Length = IrpSp->Parameters.QueryFile.Length;
FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
Buffer = Irp->AssociatedIrp.SystemBuffer;
//
// Decode the file object
//
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
//
// Use a try-finally to facilitate cleanup.
//
try {
//
// We only support query on file and directory handles.
//
switch (TypeOfOpen) {
case UserDirectoryOpen :
case UserFileOpen :
//
// Acquire shared access to this file. NOTE that this could be
// a recursive acquire, if we already preacquired in
// CdAcquireForCreateSection().
//
CdAcquireFileShared( IrpContext, Fcb );
ReleaseFcb = TRUE;
//
// Make sure we have the correct sizes for a directory.
//
if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) {
ASSERT( TypeOfOpen == UserDirectoryOpen );
CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
}
//
// Make sure the Fcb is in a usable condition. This will raise
// an error condition if the volume is unusable
//
CdVerifyFcbOperation( 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.
//
switch (FileInformationClass) {
case FileAllInformation:
//
// We don't allow this operation on a file opened by file Id.
//
if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
Status = STATUS_INVALID_PARAMETER;
break;
}
//
// In this case go ahead and call the individual routines to
// fill in the buffer. Only the name routine will
// pointer to the output buffer and then call the
// individual routines to fill in the buffer.
//
Length -= (sizeof( FILE_ACCESS_INFORMATION ) +
sizeof( FILE_MODE_INFORMATION ) +
sizeof( FILE_ALIGNMENT_INFORMATION ));
CdQueryBasicInfo( IrpContext, Fcb, &Buffer->BasicInformation, &Length );
CdQueryStandardInfo( IrpContext, Fcb, &Buffer->StandardInformation, &Length );
CdQueryInternalInfo( IrpContext, Fcb, &Buffer->InternalInformation, &Length );
CdQueryEaInfo( IrpContext, Fcb, &Buffer->EaInformation, &Length );
CdQueryPositionInfo( IrpContext, IrpSp->FileObject, &Buffer->PositionInformation, &Length );
Status = CdQueryNameInfo( IrpContext, IrpSp->FileObject, &Buffer->NameInformation, &Length );
break;
case FileBasicInformation:
CdQueryBasicInfo( IrpContext, Fcb, (PFILE_BASIC_INFORMATION) Buffer, &Length );
break;
case FileStandardInformation:
CdQueryStandardInfo( IrpContext, Fcb, (PFILE_STANDARD_INFORMATION) Buffer, &Length );
break;
case FileInternalInformation:
CdQueryInternalInfo( IrpContext, Fcb, (PFILE_INTERNAL_INFORMATION) Buffer, &Length );
break;
case FileEaInformation:
CdQueryEaInfo( IrpContext, Fcb, (PFILE_EA_INFORMATION) Buffer, &Length );
break;
case FilePositionInformation:
CdQueryPositionInfo( IrpContext, IrpSp->FileObject, (PFILE_POSITION_INFORMATION) Buffer, &Length );
break;
case FileNameInformation:
//
// We don't allow this operation on a file opened by file Id.
//
if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
Status = CdQueryNameInfo( IrpContext, IrpSp->FileObject, (PFILE_NAME_INFORMATION) Buffer, &Length );
} else {
Status = STATUS_INVALID_PARAMETER;
}
break;
case FileAlternateNameInformation:
if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
Status = CdQueryAlternateNameInfo( IrpContext, Fcb, Ccb, (PFILE_NAME_INFORMATION) Buffer, &Length );
} else {
Status = STATUS_INVALID_PARAMETER;
}
break;
case FileNetworkOpenInformation:
CdQueryNetworkInfo( IrpContext, Fcb, (PFILE_NETWORK_OPEN_INFORMATION) Buffer, &Length );
break;
default :
Status = STATUS_INVALID_PARAMETER;
}
break;
default :
Status = STATUS_INVALID_PARAMETER;
}
//
// 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;
} finally {
//
// Release the file.
//
if (ReleaseFcb) {
CdReleaseFile( IrpContext, Fcb );
}
}
//
// Complete the request if we didn't raise.
//
CdCompleteRequest( IrpContext, Irp, Status );
return Status;
}
NTSTATUS
CdCommonSetInfo (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for set file information called by both the
fsd and fsp threads. We only support operations which set the file position.
Arguments:
Irp - Supplies the Irp to process.
Return Value:
NTSTATUS - The return status for this operation.
--*/
{
NTSTATUS Status = STATUS_INVALID_PARAMETER;
TYPE_OF_OPEN TypeOfOpen;
PFCB Fcb;
PCCB Ccb;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
PFILE_POSITION_INFORMATION Buffer;
PAGED_CODE();
//
// Decode the file object
//
TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
//
// We only support a SetPositionInformation on a user file.
//
if ((TypeOfOpen != UserFileOpen) ||
(IrpSp->Parameters.QueryFile.FileInformationClass != FilePositionInformation)) {
CdCompleteRequest( IrpContext, Irp, Status );
return Status;
}
//
// Acquire shared access to this file.
//
CdAcquireFileShared( IrpContext, Fcb );
try {
//
// Make sure the Fcb is in a usable condition. This
// will raise an error condition if the fcb is unusable
//
CdVerifyFcbOperation( IrpContext, Fcb );
Buffer = Irp->AssociatedIrp.SystemBuffer;
//
// Check if the file does not use intermediate buffering. If it
// does not use intermediate buffering then the new position we're
// supplied must be aligned properly for the device
//
if (FlagOn( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ) &&
((Buffer->CurrentByteOffset.LowPart & Fcb->Vcb->BlockMask) != 0)) {
try_return( NOTHING );
}
//
// The input parameter is fine so set the current byte offset and
// complete the request
//
//
// Lock the Fcb to provide synchronization.
//
CdLockFcb( IrpContext, Fcb );
IrpSp->FileObject->CurrentByteOffset = Buffer->CurrentByteOffset;
CdUnlockFcb( IrpContext, Fcb );
Status = STATUS_SUCCESS;
try_exit: NOTHING;
} finally {
CdReleaseFile( IrpContext, Fcb );
}
//
// Complete the request if there was no raise.
//
CdCompleteRequest( IrpContext, Irp, Status );
return Status;
}
BOOLEAN
CdFastQueryBasicInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine is for the fast query call for basic file information.
Arguments:
FileObject - Supplies the file object used in this operation
Wait - Indicates if we are allowed to wait for the information
Buffer - Supplies the output buffer to receive the basic information
IoStatus - Receives the final status of the operation
Return Value:
BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
needs to take the long route.
--*/
{
BOOLEAN Result = FALSE;
TYPE_OF_OPEN TypeOfOpen;
PFCB Fcb;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -