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

📄 fileinfo.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:

    None

--*/

{
    PAGED_CODE();

    //
    //  Index number is the file Id number in the Fcb.
    //

    Buffer->IndexNumber = Fcb->FileId;
    *Length -= sizeof( FILE_INTERNAL_INFORMATION );

    return;
}


//
//  Local support routine
//

VOID
CdQueryEaInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_EA_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine performs the query Ea information function for cdfs.

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

--*/

{
    PAGED_CODE();

    //
    //  No Ea's on Cdfs volumes.
    //

    Buffer->EaSize = 0;
    *Length -= sizeof( FILE_EA_INFORMATION );

    return;
}


//
//  Local support routine
//

VOID
CdQueryPositionInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_POSITION_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine performs the query position information function for cdfs.

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

--*/

{
    PAGED_CODE();

    //
    //  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 );

    return;
}


//
//  Local support routine
//

NTSTATUS
CdQueryNameInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_NAME_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine performs the query name information function for cdfs.

Arguments:

    FileObject - Supplies the file object containing the name.

    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:

    NTSTATUS - STATUS_BUFFER_OVERFLOW if the entire name can't be copied.

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG LengthToCopy;

    PAGED_CODE();

    ASSERT(*Length >= sizeof(ULONG));
    
    //
    //  Simply copy the name in the file object to the user's buffer.
    //

    //
    //  Place the size of the filename in the user's buffer and reduce the remaining
    //  size to match.
    //

    Buffer->FileNameLength = LengthToCopy = FileObject->FileName.Length;
    *Length -= sizeof(ULONG);

    if (LengthToCopy > *Length) {

        LengthToCopy = *Length;
        Status = STATUS_BUFFER_OVERFLOW;
    }

    RtlCopyMemory( Buffer->FileName, FileObject->FileName.Buffer, LengthToCopy );

    //
    //  Reduce the available bytes by the amount stored into this buffer.  In the overflow
    //  case, this simply drops to zero.  The returned filenamelength will indicate to the
    //  caller how much space is required.
    //

    *Length -= LengthToCopy;

    return Status;
}


//
//  Local support routine
//

NTSTATUS
CdQueryAlternateNameInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PCCB Ccb,
    IN OUT PFILE_NAME_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

Routine Description:

    This routine performs the query alternate name information function.
    We lookup the dirent for this file and then check if there is a
    short name.

Arguments:

    Fcb - Supplies the Fcb being queried, it has been verified.

    Ccb - Ccb for this open handle.

    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:

    NTSTATUS - STATUS_SUCCESS if the whole name would fit into the user buffer,
               STATUS_OBJECT_NAME_NOT_FOUND if we can't return the name,
               STATUS_BUFFER_OVERFLOW otherwise.

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;

    DIRENT_ENUM_CONTEXT DirContext;
    DIRENT Dirent;

    PUNICODE_STRING NameToUse;
    ULONG DirentOffset;

    COMPOUND_PATH_ENTRY CompoundPathEntry;
    FILE_ENUM_CONTEXT FileContext;

    PFCB ParentFcb;
    BOOLEAN ReleaseParentFcb = FALSE;

    BOOLEAN CleanupFileLookup = FALSE;
    BOOLEAN CleanupDirectoryLookup = FALSE;

    WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / 2 ];
    USHORT ShortNameLength;

    PAGED_CODE();

    //
    //  Initialize the buffer length to zero.
    //

    Buffer->FileNameLength = 0;

    //
    //  If this is the root or this file was opened using a version number then
    //  there is no short name.
    //

    if ((Fcb == Fcb->Vcb->RootIndexFcb) ||
        FlagOn( Ccb->Flags, CCB_FLAG_OPEN_WITH_VERSION)) {

        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    //
    //  Use a try-finally to cleanup the structures.
    //

    try {

        ParentFcb = Fcb->ParentFcb;
        CdAcquireFileShared( IrpContext, ParentFcb );
        ReleaseParentFcb = TRUE;
    
        CdVerifyOrCreateDirStreamFile( IrpContext, ParentFcb);

        if (CdFidIsDirectory( Fcb->FileId)) {

            //
            //  Fcb is for a directory, so we need to dig the dirent from the parent.  In
            //  order to do this we need to get the name of the directory from its pathtable
            //  entry and then search in the parent for a matching dirent.
            //
            //  This could be optimized somewhat.
            //

            CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry );
            CdInitializeFileContext( IrpContext, &FileContext );

            CleanupDirectoryLookup = TRUE;

            CdLookupPathEntry( IrpContext,
                               CdQueryFidPathTableOffset( Fcb->FileId ),
                               Fcb->Ordinal,
                               FALSE,
                               &CompoundPathEntry );

            CdUpdatePathEntryName( IrpContext, &CompoundPathEntry.PathEntry, TRUE );

            if (!CdFindDirectory( IrpContext,
                                  ParentFcb,
                                  &CompoundPathEntry.PathEntry.CdCaseDirName,
                                  TRUE,
                                  &FileContext )) {

                //
                //  If we failed to find the child directory by name in the parent
                //  something is quite wrong with this disc.
                //

                CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
            }

            NameToUse = &FileContext.InitialDirent->Dirent.CdCaseFileName.FileName;
            DirentOffset = FileContext.InitialDirent->Dirent.DirentOffset;
        
        } else {

            //
            //  Initialize the search dirent structures.
            //
        
            CdInitializeDirContext( IrpContext, &DirContext );
            CdInitializeDirent( IrpContext, &Dirent );
    
            CleanupFileLookup = TRUE;
        
            CdLookupDirent( IrpContext,
                            ParentFcb,
                            CdQueryFidDirentOffset( Fcb->FileId ),
                            &DirContext );
    
            CdUpdateDirentFromRawDirent( IrpContext,
                                         ParentFcb,
                                         &DirContext,
                                         &Dirent );

            //
            //  Now update the dirent name.
            //
    
            CdUpdateDirentName( IrpContext, &Dirent, TRUE );
    
            NameToUse = &Dirent.CdCaseFileName.FileName;
            DirentOffset = Dirent.DirentOffset;
        }

        //
        //  If the name is 8.3 then fail this request.
        //

        if (CdIs8dot3Name( IrpContext,
                           *NameToUse )) {


            try_return( Status = STATUS_OBJECT_NAME_NOT_FOUND );
        }

        CdGenerate8dot3Name( IrpContext,
                             NameToUse,
                             DirentOffset,
                             ShortNameBuffer,
                             &ShortNameLength );

        //
        //  We now have the short name.  We have left it in Unicode form so copy it directly.
        //

        Buffer->FileNameLength = ShortNameLength;

        if (Buffer->FileNameLength + sizeof( ULONG ) > *Length) {

            Buffer->FileNameLength = *Length - sizeof( ULONG );
            Status = STATUS_BUFFER_OVERFLOW;
        }

        RtlCopyMemory( Buffer->FileName, ShortNameBuffer, Buffer->FileNameLength );

    try_exit:  NOTHING;
    } finally {

        if (CleanupFileLookup) {

            CdCleanupDirContext( IrpContext, &DirContext );
            CdCleanupDirent( IrpContext, &Dirent );

        } else if (CleanupDirectoryLookup) {

            CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
            CdCleanupFileContext( IrpContext, &FileContext );
        }

        if (ReleaseParentFcb) {

            CdReleaseFile( IrpContext, ParentFcb );
        }
    }

    //
    //  Reduce the available bytes by the amount stored into this buffer.
    //

    if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {

        *Length -= sizeof( ULONG ) + Buffer->FileNameLength;
    }

    return Status;
}


//
//  Local support routine
//

VOID
CdQueryNetworkInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
    IN OUT PULONG Length
    )

/*++

 Description:

    This routine performs the query network open information function for Cdfs

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

--*/

{
    PAGED_CODE();

    //
    //  We only support creation, last modify and last write times on Cdfs.
    //

    Buffer->LastWriteTime.QuadPart =
    Buffer->CreationTime.QuadPart =
    Buffer->ChangeTime.QuadPart = Fcb->CreationTime;

    Buffer->LastAccessTime.QuadPart = 0;

    Buffer->FileAttributes = Fcb->FileAttributes;

    //
    //  We get the sizes from the header.  Return a size of zero
    //  for all directories.
    //

    if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {

        Buffer->AllocationSize.QuadPart =
        Buffer->EndOfFile.QuadPart = 0;

    } else {

        Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
        Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
    }

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

    *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION );

    return;
}

⌨️ 快捷键说明

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