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

📄 dirsup.c

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

    FatStringTo8dot3( IrpContext,
                      *FileName,
                      &LocalCcb.OemQueryTemplate.Constant );
    LocalCcb.ContainsWildCards = FALSE;
    LocalCcb.Flags = 0;

    FatLocateDirent( IrpContext,
                     ParentDirectory,
                     &LocalCcb,
                     0,
                     Dirent,
                     Bcb,
                     ByteOffset,
                     NULL,
                     NULL);

    return;
}


VOID
FatLocateVolumeLabel (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    OUT PDIRENT *Dirent,
    OUT PBCB *Bcb,
    OUT PVBO ByteOffset
    )

/*++

Routine Description:

    This routine locates on the disk a dirent representing the volume
    label.  It does this by searching the root directory for a special
    volume label dirent.

Arguments:

    Vcb - Supplies the VCB for the volume to search

    Dirent - Receives a pointer to the located dirent if one was found
        or NULL otherwise.

    Bcb - Receives the Bcb for the located dirent if one was found or
        NULL otherwise.

    ByteOffset - Receives the VBO within the Parent directory for
        the located dirent if one was found, or 0 otherwise.

Return Value:

    None.

--*/

{
    NTSTATUS Status;

    PAGED_CODE();

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

    DebugTrace( 0, Dbg, "  Vcb        = %08lx\n", Vcb);
    DebugTrace( 0, Dbg, "  Dirent     = %08lx\n", Dirent);
    DebugTrace( 0, Dbg, "  Bcb        = %08lx\n", Bcb);
    DebugTrace( 0, Dbg, "  ByteOffset = %08lx\n", ByteOffset);

    //
    //  The algorithm here is really simple.  We just walk through the
    //  root directory until we:
    //
    //      A)  Find the non-deleted volume label
    //      B)  Can't Wait
    //      C)  Hit the End of Directory
    //      D)  Hit Eof
    //
    //  In the first case we found it, in the latter three cases we did not.
    //

    *Bcb = NULL;
    *ByteOffset = 0;

    while ( TRUE ) {

        //
        //  Try to read in the dirent
        //

        FatReadDirent( IrpContext,
                       Vcb->RootDcb,
                       *ByteOffset,
                       Bcb,
                       Dirent,
                       &Status );

        //
        //  If End Directory dirent or EOF, set all out parameters to
        //  indicate volume label not found and, like, bail.
        //
        //  Note that the order of evaluation here is important since we cannot
        //  check the first character of the dirent until after we know we
        //  are not beyond EOF
        //

        if ((Status == STATUS_END_OF_FILE) ||
            ((*Dirent)->FileName[0] == FAT_DIRENT_NEVER_USED)) {

            DebugTrace( 0, Dbg, "Volume label not found.\n", 0);

            //
            //  If there is a Bcb, unpin it and set it to null
            //

            FatUnpinBcb( IrpContext, *Bcb );

            *Dirent = NULL;
            *ByteOffset = 0;
            break;
        }

        //
        //  If the entry is the non-deleted volume label break from the loop.
        //
        //  Note that all out parameters are already correctly set.
        //

        if ((((*Dirent)->Attributes & ~FAT_DIRENT_ATTR_ARCHIVE) == FAT_DIRENT_ATTR_VOLUME_ID) &&
            ((*Dirent)->FileName[0] != FAT_DIRENT_DELETED)) {

            DebugTrace( 0, Dbg, "Volume label found at VBO = %08lx\n", *ByteOffset);

            //
            //  We may set this dirty, so pin it.
            //

            FatPinMappedData( IrpContext,
                              Vcb->RootDcb,
                              *ByteOffset,
                              sizeof(DIRENT),
                              Bcb );

            break;
        }

        //
        //  Move on to the next dirent.
        //

        *ByteOffset += sizeof(DIRENT);
        *Dirent += 1;
    }


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

    return;
}


VOID
FatGetDirentFromFcbOrDcb (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB FcbOrDcb,
    IN BOOLEAN ReturnOnFailure,
    OUT PDIRENT *Dirent,
    OUT PBCB *Bcb
    )

/*++

Routine Description:

    This routine reads locates on the disk the dirent denoted by the
    specified Fcb/Dcb.

Arguments:

    FcbOrDcb - Supplies the FCB/DCB for the file/directory whose dirent
        we are trying to read in.  This must not be the root dcb.

    Dirent - Receives a pointer to the dirent

    Bcb - Receives the Bcb for the dirent

Return Value:

    None.

--*/

{
    NTSTATUS DontCare;

    PAGED_CODE();

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

    DebugTrace( 0, Dbg, "  FcbOrDcb = %08lx\n", FcbOrDcb);
    DebugTrace( 0, Dbg, "  Dirent   = %08lx\n", Dirent);
    DebugTrace( 0, Dbg, "  Bcb      = %08lx\n", Bcb);

    //
    //  Assert that we are not attempting this on the root directory.
    //

    ASSERT( NodeType(FcbOrDcb) != FAT_NTC_ROOT_DCB );

    //
    //  We know the offset of the dirent within the directory file,
    //  so we just read it (with pinning).
    //

    FatReadDirectoryFile( IrpContext,
                          FcbOrDcb->ParentDcb,
                          FcbOrDcb->DirentOffsetWithinDirectory,
                          sizeof(DIRENT),
                          TRUE,
                          Bcb,
                          (PVOID *)Dirent,
                          &DontCare );

    //
    //  Previous call can fail.  We used to assert success, but we use this
    //  as part of volume verification (DetermineAndMarkFcbCondition) after
    //  media has been removed.  Clearly the directory could shrink and we
    //  would try to read beyond filesize.
    //
    //  The caller will note this via NULL pointers for Bcb/Buffer.  Note that
    //  both asserts below are OK since this should never happen fixed media.
    //
    //  This was a Prefix catch.
    //

    ASSERT( FlagOn( FcbOrDcb->Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA) ||
            NT_SUCCESS( DontCare ));

    //
    //  Note also that the only way this could fail is if the Fcb was being
    //  verified.  This can't happen if the Fcb is in good condition.
    //
    //  Also a Prefix catch.
    //

    ASSERT( NT_SUCCESS( DontCare ) || FcbOrDcb->FcbCondition == FcbNeedsToBeVerified );

    //
    //  This should never happen except in very specific cases (during volume
    //  verify) but we'll handle and raise here to save all callers checking the
    //  pointers.
    //
    
    if ((NULL == *Dirent) && !ReturnOnFailure) {

        ASSERT( FALSE);
        FatRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR);
    }
    
    DebugTrace(-1, Dbg, "FatGetDirentFromFcbOrDcb -> (VOID)\n", 0);
}


BOOLEAN
FatIsDirectoryEmpty (
    IN PIRP_CONTEXT IrpContext,
    IN PDCB Dcb
    )

/*++

Routine Description:

    This routine indicates to the caller if the specified directory
    is empty.  (i.e., it is not the root dcb and it only contains
    the "." and ".." entries, or deleted files).

Arguments:

    Dcb - Supplies the DCB for the directory being queried.

Return Value:

    BOOLEAN - Returns TRUE if the directory is empty and
        FALSE if the directory and is not empty.

--*/

{
    PBCB Bcb;
    ULONG ByteOffset;
    PDIRENT Dirent;

    BOOLEAN IsDirectoryEmpty = FALSE;

    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

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

    DebugTrace( 0, Dbg, "  Dcb              = %08lx\n", Dcb);
    DebugTrace( 0, Dbg, "  IsDirectoryEmpty = %08lx\n", IsDirectoryEmpty);

    //
    //  Check to see if the first entry is an and of directory marker.
    //  For the root directory we check at Vbo = 0, for normal directories
    //  we check after the "." and ".." entries.
    //

    ByteOffset = (NodeType(Dcb) == FAT_NTC_ROOT_DCB) ? 0 : 2*sizeof(DIRENT);

    //
    //  We just march through the directory looking for anything other
    //  than deleted files, LFNs, an EOF, or end of directory marker.
    //

    Bcb = NULL;

    try {

        while ( TRUE ) {

            //
            //  Try to read in the dirent
            //

            FatReadDirent( IrpContext,
                           Dcb,
                           ByteOffset,
                           &Bcb,
                           &Dirent,
                           &Status );

            //
            //  If End Directory dirent or EOF, set IsDirectoryEmpty to TRUE and,
            //  like, bail.
            //
            //  Note that the order of evaluation here is important since we cannot
            //  check the first character of the dirent until after we know we
            //  are not beyond EOF
            //

            if ((Status == STATUS_END_OF_FILE) ||
                (Dirent->FileName[0] == FAT_DIRENT_NEVER_USED)) {

                DebugTrace( 0, Dbg, "Empty.  Last exempt entry at VBO = %08lx\n", ByteOffset);

                IsDirectoryEmpty = TRUE;
                break;
            }

            //
            //  If this dirent is NOT deleted or an LFN set IsDirectoryEmpty to
            //  FALSE and, like, bail.
            //

            if ((Dirent->FileName[0] != FAT_DIRENT_DELETED) &&
                (Dirent->Attributes != FAT_DIRENT_ATTR_LFN)) {

                DebugTrace( 0, Dbg, "Not Empty.  First entry at VBO = %08lx\n", ByteOffset);

                IsDirectoryEmpty = FALSE;
                break;
            }

            //
            //  Move on to the next dirent.
            //

            ByteOffset += sizeof(DIRENT);
            Dirent += 1;
        }

    } finally {

        FatUnpinBcb( IrpContext, Bcb );
    }

    DebugTrace(-1, Dbg, "FatIsDirectoryEmpty -> %ld\n", IsDirectoryEmpty);

    return IsDirectoryEmpty;
}


VOID
FatConstructDirent (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PDIRENT Dirent,
    IN POEM_STRING FileName,
    IN BOOLEAN ComponentReallyLowercase,
    IN BOOLEAN ExtensionReallyLowercase,
    IN PUNICODE_STRING Lfn OPTIONAL,
    IN UCHAR Attributes,
    IN BOOLEAN ZeroAndSetTimeFields,
    IN PLARGE_INTEGER SetCreationTime OPTIONAL
    )

/*++

Routine Description:

    This routine modifies the fields of a dirent.

Arguments:

    Dirent - Supplies the dirent being modified.

    FileName - Supplies the name to store in the Dirent.  This
        name must not contain wildcards.

    ComponentReallyLowercase - This boolean indicates that the User Specified
        compoent name was really all a-z and < 0x80 characters.  We set the
        magic bit in this case.

    ExtensionReallyLowercase - Same as above, but for the extension.

    Lfn - May supply a long file name.

    Attributes - Supplies the attributes to store in the dirent

    ZeroAndSetTimeFields - Tells whether or not to initially zero the dirent
        and update the time fields.

    SetCreationTime - If specified, contains a timestamp to us

⌨️ 快捷键说明

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