📄 fileinfo.c
字号:
// Extract the data and fill in the non zero fields of the output
// buffer
//
if (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB) {
//
// We have to munge a lie on the fly. Every time we have to
// use 1/1/80 we need to convert to GMT since the TZ may have
// changed on us.
//
ExLocalTimeToSystemTime( &FatJanOne1980,
&Buffer->LastWriteTime );
Buffer->CreationTime = Buffer->LastAccessTime = Buffer->LastWriteTime;
} else {
Buffer->LastWriteTime = Fcb->LastWriteTime;
Buffer->CreationTime = Fcb->CreationTime;
Buffer->LastAccessTime = Fcb->LastAccessTime;
}
Buffer->FileAttributes = Fcb->DirentFatFlags;
//
// If the temporary flag is set, then set it in the buffer.
//
if (FlagOn( Fcb->FcbState, FCB_STATE_TEMPORARY )) {
SetFlag( Buffer->FileAttributes, FILE_ATTRIBUTE_TEMPORARY );
}
//
// If no attributes were set, set the normal bit.
//
if (Buffer->FileAttributes == 0) {
Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
}
//
// Update the length and status output variables
//
*Length -= sizeof( FILE_BASIC_INFORMATION );
DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
DebugTrace(-1, Dbg, "FatQueryBasicInfo -> VOID\n", 0);
return;
}
//
// Internal Support Routine
//
VOID
FatQueryStandardInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Routine Description:
This routine performs the query standard information function for fat.
Arguments:
Fcb - Supplies the Fcb being queried, it has been verified
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, "FatQueryStandardInfo...\n", 0);
//
// Zero out the output buffer, and fill in the number of links
// and the delete pending flag.
//
RtlZeroMemory( Buffer, sizeof(FILE_STANDARD_INFORMATION) );
Buffer->NumberOfLinks = 1;
Buffer->DeletePending = BooleanFlagOn( Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE );
//
// Case on whether this is a file or a directory, and extract
// the information and fill in the fcb/dcb specific parts
// of the output buffer
//
if (NodeType(Fcb) == FAT_NTC_FCB) {
if (Fcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {
FatLookupFileAllocationSize( IrpContext, Fcb );
}
Buffer->AllocationSize = Fcb->Header.AllocationSize;
Buffer->EndOfFile = Fcb->Header.FileSize;
Buffer->Directory = FALSE;
} else {
Buffer->Directory = TRUE;
}
//
// Update the length and status output variables
//
*Length -= sizeof( FILE_STANDARD_INFORMATION );
DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
DebugTrace(-1, Dbg, "FatQueryStandardInfo -> VOID\n", 0);
return;
}
//
// Internal Support Routine
//
VOID
FatQueryInternalInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Routine Description:
This routine performs the query internal information function for fat.
Arguments:
Fcb - Supplies the Fcb being queried, it has been verified
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, "FatQueryInternalInfo...\n", 0);
try {
Buffer->IndexNumber.QuadPart = FatGenerateFileIdFromFcb( Fcb );
//
// Update the length and status output variables
//
*Length -= sizeof( FILE_INTERNAL_INFORMATION );
} finally {
DebugUnwind( FatQueryInternalInfo );
DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
DebugTrace(-1, Dbg, "FatQueryInternalInfo -> VOID\n", 0);
}
return;
}
//
// Internal Support Routine
//
VOID
FatQueryEaInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_EA_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Routine Description:
This routine performs the query Ea information function for fat.
Arguments:
Fcb - Supplies the Fcb being queried, it has been verified
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
--*/
{
PBCB Bcb;
DebugTrace(+1, Dbg, "FatQueryEaInfo...\n", 0);
Bcb = NULL;
try {
//
// Zero out the output buffer
//
RtlZeroMemory( Buffer, sizeof(FILE_EA_INFORMATION) );
#if 0
//
// The Root dcb does not have any EAs so don't look for any. Fat32
// doesn't have any, either.
//
if ( NodeType( Fcb ) != FAT_NTC_ROOT_DCB &&
!FatIsFat32( Fcb->Vcb )) {
PDIRENT Dirent;
//
// Try to get the dirent for this file.
//
FatGetDirentFromFcbOrDcb( IrpContext,
Fcb,
&Dirent,
&Bcb );
if (Dirent != NULL) {
//
// Get a the size needed to store the full eas for the file.
//
FatGetEaLength( IrpContext,
Fcb->Vcb,
Dirent,
&Buffer->EaSize );
}
}
#endif
//
// Update the length and status output variables
//
*Length -= sizeof( FILE_EA_INFORMATION );
} finally {
DebugUnwind( FatQueryEaInfo );
//
// Unpin the dirent if pinned.
//
FatUnpinBcb( IrpContext, Bcb );
DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
DebugTrace(-1, Dbg, "FatQueryEaInfo -> VOID\n", 0);
}
}
//
// Internal Support Routine
//
VOID
FatQueryPositionInfo (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_POSITION_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Routine Description:
This routine performs the query position information function for fat.
Arguments:
FileObject - Supplies the File object being queried
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, "FatQueryPositionInfo...\n", 0);
//
// Get the current position found in the file object.
//
Buffer->CurrentByteOffset = FileObject->CurrentByteOffset;
//
// Update the length and status output variables
//
*Length -= sizeof( FILE_POSITION_INFORMATION );
DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
DebugTrace(-1, Dbg, "FatQueryPositionInfo -> VOID\n", 0);
UNREFERENCED_PARAMETER( IrpContext );
return;
}
//
// Internal Support Routine
//
VOID
FatQueryNameInfo (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCCB Ccb,
IN OUT PFILE_NAME_INFORMATION Buffer,
IN OUT PLONG Length
)
/*++
Routine Description:
This routine performs the query name information function for fat.
Arguments:
Fcb - Supplies the Fcb being queried, it has been verified
Ccb - Supplies the Ccb for the context of the user open
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
--*/
{
ULONG BytesToCopy;
LONG TrimLength;
BOOLEAN Overflow = FALSE;
DebugTrace(+1, Dbg, "FatQueryNameInfo...\n", 0);
//
// Convert the name to UNICODE
//
*Length -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]);
//
// Use the full filename to build the path up. If we wanted to be
// slick in the future, we'd just build the path directly into the
// return buffer and avoid constructing the full filename, but since
// the full filename winds up being required so often lets not
// over optimize this case yet.
//
if (Fcb->FullFileName.Buffer == NULL) {
FatSetFullFileNameInFcb( IrpContext, Fcb );
}
//
// Here is where it gets a smidge tricky. FinalNameLength is the length
// of the LFN element if it exists, and since the long name is always used
// to build FullFileName, we have two cases:
//
// 1) short name: use FinalNameLength to tear off the path from FullFileName
// and append the UNICODE converted short name.
// 2) long name: just use FullFileName
//
// We bias to the name the user thinks they opened by. This winds
// up fixing some oddball tunneling cases where intermediate filters
// translate operations like delete into renames - this lets them
// do the operation in the context of the name the user was using.
//
// It also matches what NTFS does, and so we have the definition of
// correct behavior.
//
//
//
// Assume there is no long name and we are just going to use
// FullFileName.
//
TrimLength = 0;
//
// If a LongName exists and the original open was by the short name
// then set TrimLength to point to the place where the short name goes.
//
//
// Note: The Ccb can be NULL. The lazy writer calls to get the name of
// a DirectoryOpen FILE_OBJECT that it wants to display in the lost
// delayed write popup. Handle this case by just using the FileFullName.
//
if (Fcb->LongName.Unicode.Name.Unicode.Buffer != NULL) {
if ((Ccb != NULL) && FlagOn(Ccb->Flags, CCB_FLAG_OPENED_BY_SHORTNAME)) {
TrimLength = Fcb->FinalNameLength;
}
}
if (*Length < Fcb->FullFileName.Length - TrimLength) {
BytesToCopy = *Length;
Overflow = TRUE;
} else {
BytesToCopy = Fcb->FullFileName.Length - TrimLength;
*Length -= BytesToCopy;
}
RtlCopyMemory( &Buffer->FileName[0],
Fcb->FullFileName.Buffer,
BytesToCopy );
//
// Note that this is just the amount of name we've copied so far. It'll
// either be all of it (long) or the path element including the \ (short).
//
Buffer->FileNameLength = Fcb->FullFileName.Length - TrimLength;
//
// If we trimmed off the name element, this is the short name case. Pick
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -