⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileinfo.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    //  up the UNICODE conversion and append it.
    //

    if (TrimLength != 0) {

        UNICODE_STRING ShortName;
        WCHAR ShortNameBuffer[12];
        NTSTATUS Status;

        //
        //  Convert the short name to UNICODE and figure out how much
        //  of it can fit.  Again, we always bump the returned length
        //  to indicate how much is available even if we can't return it.
        //

        ShortName.Length = 0;
        ShortName.MaximumLength = sizeof(ShortNameBuffer);
        ShortName.Buffer = ShortNameBuffer;

        Status = RtlOemStringToCountedUnicodeString( &ShortName,
                                                     &Fcb->ShortName.Name.Oem,
                                                     FALSE );

        ASSERT( Status == STATUS_SUCCESS );

        if (!Overflow) {

            if (*Length < ShortName.Length) {

                BytesToCopy = *Length;
                Overflow = TRUE;

            } else {

                BytesToCopy = ShortName.Length;
                *Length -= BytesToCopy;
            }

            RtlCopyMemory( (PUCHAR)&Buffer->FileName[0] + Buffer->FileNameLength,
                           ShortName.Buffer,
                           BytesToCopy );
        }

        Buffer->FileNameLength += ShortName.Length;
    }

    if (Overflow) {

        *Length = -1;
    }

    //
    //  Return to caller
    //

    DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);

    DebugTrace(-1, Dbg, "FatQueryNameInfo -> VOID\n", 0);

    UNREFERENCED_PARAMETER( IrpContext );

    return;
}


//
//  Internal Support Routine
//

VOID
FatQueryShortNameInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_NAME_INFORMATION Buffer,
    IN OUT PLONG Length
    )

/*++

Routine Description:

    This routine queries the short name of the file.

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

--*/

{
    NTSTATUS Status;

    ULONG BytesToCopy;
    WCHAR ShortNameBuffer[12];
    UNICODE_STRING ShortName;

    DebugTrace(+1, Dbg, "FatQueryNameInfo...\n", 0);

    //
    //  Convert the name to UNICODE
    //

    ShortName.Length = 0;
    ShortName.MaximumLength = sizeof(ShortNameBuffer);
    ShortName.Buffer = ShortNameBuffer;

    *Length -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]);

    Status = RtlOemStringToCountedUnicodeString( &ShortName,
                                                 &Fcb->ShortName.Name.Oem,
                                                 FALSE );

    ASSERT( Status == STATUS_SUCCESS );

    //
    //  If we overflow, set *Length to -1 as a flag.
    //

    if (*Length < ShortName.Length) {

        BytesToCopy = *Length;
        *Length = -1;

    } else {

        BytesToCopy = ShortName.Length;
        *Length -= ShortName.Length;
    }

    RtlCopyMemory( &Buffer->FileName[0],
                   &ShortName.Buffer[0],
                   BytesToCopy );

    Buffer->FileNameLength = ShortName.Length;

    //
    //  Return to caller
    //

    DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);

    DebugTrace(-1, Dbg, "FatQueryNameInfo -> VOID\n", 0);

    UNREFERENCED_PARAMETER( IrpContext );

    return;
}


//
//  Internal Support Routine
//

VOID
FatQueryNetworkInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
    IN OUT PLONG Length
    )

/*++
 Description:

    This routine performs the query network open 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, "FatQueryNetworkInfo...\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_NETWORK_OPEN_INFORMATION) );

    //
    //  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.QuadPart = Fcb->LastWriteTime.QuadPart;
        Buffer->CreationTime.QuadPart = Fcb->CreationTime.QuadPart;
        Buffer->LastAccessTime.QuadPart = Fcb->LastAccessTime.QuadPart;
    }

    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;
    }
    //
    //  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.QuadPart = Fcb->Header.AllocationSize.QuadPart;
        Buffer->EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
    }

    //
    //  Update the length and status output variables
    //

    *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION );

    DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);

    DebugTrace(-1, Dbg, "FatQueryNetworkInfo -> VOID\n", 0);

    return;
}


//
//  Internal Support routine
//

NTSTATUS
FatSetBasicInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp,
    IN PFCB Fcb,
    IN PCCB Ccb
    )

/*++

Routine Description:

    This routine performs the set basic information for fat.  It either
    completes the request or enqueues it off to the fsp.

Arguments:

    Irp - Supplies the irp being processed

    Fcb - Supplies the Fcb or Dcb being processed, already known not to
        be the root dcb

    Ccb - Supplies the flag bit that control updating the last modify
        time on cleanup.

Return Value:

    NTSTATUS - The result of this operation if it completes without
               an exception.

--*/

{
    NTSTATUS Status;

    PFILE_BASIC_INFORMATION Buffer;

    PDIRENT Dirent;
    PBCB DirentBcb;

    FAT_TIME_STAMP CreationTime;
    UCHAR CreationMSec;
    FAT_TIME_STAMP LastWriteTime;
    FAT_TIME_STAMP LastAccessTime;
    FAT_DATE LastAccessDate;
    UCHAR Attributes;

    BOOLEAN ModifyCreation = FALSE;
    BOOLEAN ModifyLastWrite = FALSE;
    BOOLEAN ModifyLastAccess = FALSE;

    LARGE_INTEGER LargeCreationTime;
    LARGE_INTEGER LargeLastWriteTime;
    LARGE_INTEGER LargeLastAccessTime;


    ULONG NotifyFilter = 0;

    DebugTrace(+1, Dbg, "FatSetBasicInfo...\n", 0);

    Buffer = Irp->AssociatedIrp.SystemBuffer;

    //
    //  If the user is specifying -1 for a field, that means
    //  we should leave that field unchanged, even if we might
    //  have otherwise set it ourselves.  We'll set the Ccb flag
    //  saying that the user set the field so that we
    //  don't do our default updating.
    //
    //  We set the field to 0 then so we know not to actually
    //  set the field to the user-specified (and in this case,
    //  illegal) value.
    //

    if (Buffer->LastWriteTime.QuadPart == -1) {

        SetFlag( Ccb->Flags, CCB_FLAG_USER_SET_LAST_WRITE );
        Buffer->LastWriteTime.QuadPart = 0;
    }

    if (Buffer->LastAccessTime.QuadPart == -1) {

        SetFlag( Ccb->Flags, CCB_FLAG_USER_SET_LAST_ACCESS );
        Buffer->LastAccessTime.QuadPart = 0;
    }

    if (Buffer->CreationTime.QuadPart == -1) {

        SetFlag( Ccb->Flags, CCB_FLAG_USER_SET_CREATION );
        Buffer->CreationTime.QuadPart = 0;
    }

    DirentBcb = NULL;

    Status = STATUS_SUCCESS;

    try {

        LARGE_INTEGER FatLocalDecThirtyOne1979;
        LARGE_INTEGER FatLocalJanOne1980;

        ExLocalTimeToSystemTime( &FatDecThirtyOne1979,
                                 &FatLocalDecThirtyOne1979 );

        ExLocalTimeToSystemTime( &FatJanOne1980,
                                 &FatLocalJanOne1980 );

        //
        //  Get a pointer to the dirent
        //

        ASSERT( Fcb->FcbCondition == FcbGood );

        FatGetDirentFromFcbOrDcb( IrpContext,
                                  Fcb,
                                  FALSE,
                                  &Dirent,
                                  &DirentBcb );
        //
        //  Check if the user specified a non-zero creation time
        //

        if (FatData.ChicagoMode && (Buffer->CreationTime.QuadPart != 0)) {

            LargeCreationTime = Buffer->CreationTime;

            //
            //  Convert the Nt time to a Fat time
            //

            if ( !FatNtTimeToFatTime( IrpContext,
                                      &LargeCreationTime,
                                      FALSE,
                                      &CreationTime,
                                      &CreationMSec )) {

                //
                //  Special case the value 12/31/79 and treat this as 1/1/80.
                //  This '79 value can happen because of time zone issues.
                //

                if ((LargeCreationTime.QuadPart >= FatLocalDecThirtyOne1979.QuadPart) &&
                    (LargeCreationTime.QuadPart < FatLocalJanOne1980.QuadPart)) {

                    CreationTime = FatTimeJanOne1980;
                    LargeCreationTime = FatLocalJanOne1980;

                } else {

                    DebugTrace(0, Dbg, "Invalid CreationTime\n", 0);
                    try_return( Status = STATUS_INVALID_PARAMETER );
                }

                //
                //  Don't worry about CreationMSec
                //

                CreationMSec = 0;
            }

            ModifyCreation = TRUE;
        }

        //
        //  Check if the user specified a non-zero last access time
        //

        if (FatData.ChicagoMode && (Buffer->LastAccessTime.QuadPart != 0)) {

            LargeLastAccessTime = Buffer->LastAccessTime;

            //
            //  Convert the Nt time to a Fat time
            //

            if ( !FatNtTimeToFatTime( IrpContext,
                                      &LargeLastAccessTime,
                                      TRUE,
                                      &LastAccessTime,
                                      NULL )) {

                //
                //  Special case the value 12/31/79 and treat this as 1/1/80.
                //  This '79 value can happen because of time zone issues.
                //

                if ((LargeLastAccessTime.QuadPart >= FatLocalDecThirtyOne1979.QuadPart) &&
                    (LargeLastAccessTime.QuadPart < FatLocalJanOne1980.QuadPart)) {

                    LastAccessTime = FatTimeJanOne1980;
                    LargeLastAccessTime = FatLocalJanOne1980;

                } else {

                    DebugTrace(0, Dbg, "Invalid LastAccessTime\n", 0);
                    try_return( Status = STATUS_INVALID_PARAMETER );
                }
            }

            LastAccessDate = LastAccessTime.Date;
            ModifyLastAccess = TRUE;
        }

        //
        //  Check if the user specified a non-zero last write time
        //

        if (Buffer->LastWriteTime.QuadPart != 0) {

            //
            //  First do a quick check here if the this time is the same
            //  time as LastAccessTime.
            //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -