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

📄 strucsup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    DebugTrace(-1, Dbg, "FatCreateCcb -> %08lx\n", Ccb);

    UNREFERENCED_PARAMETER( IrpContext );

    return Ccb;
}



VOID
FatDeallocateCcbStrings(
    IN PCCB Ccb
    )
/*++

Routine Description:

    This routine deallocates CCB query templates

Arguments:

    Ccb - Supplies the CCB

Return Value:

    None

--*/
{
    //
    //  If we allocated query template buffers, deallocate them now.
    //

    if (FlagOn(Ccb->Flags, CCB_FLAG_FREE_UNICODE)) {

        ASSERT( Ccb->UnicodeQueryTemplate.Buffer);
        ASSERT( !FlagOn( Ccb->Flags, CCB_FLAG_CLOSE_CONTEXT));
        RtlFreeUnicodeString( &Ccb->UnicodeQueryTemplate );
    }

    if (FlagOn(Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT)) {

        ASSERT( Ccb->OemQueryTemplate.Wild.Buffer );
        ASSERT( !FlagOn( Ccb->Flags, CCB_FLAG_CLOSE_CONTEXT));
        RtlFreeOemString( &Ccb->OemQueryTemplate.Wild );
    }

    ClearFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT | CCB_FLAG_FREE_UNICODE);
}



VOID
FatDeleteCcb (
    IN PIRP_CONTEXT IrpContext,
    IN PCCB *Ccb
    )

/*++

Routine Description:

    This routine deallocates and removes the specified CCB record
    from the Fat in memory data structures

Arguments:

    Ccb - Supplies the CCB to remove

Return Value:

    None

--*/

{
    DebugTrace(+1, Dbg, "FatDeleteCcb, Ccb = %08lx\n", *Ccb);

    FatDeallocateCcbStrings( *Ccb);

    //
    //  Deallocate the Ccb record
    //

    FatFreeCcb( *Ccb );
    *Ccb = NULL;
    
    //
    //  return and tell the caller
    //

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

    UNREFERENCED_PARAMETER( IrpContext );
}


PIRP_CONTEXT
FatCreateIrpContext (
    IN PIRP Irp,
    IN BOOLEAN Wait
    )

/*++

Routine Description:

    This routine creates a new IRP_CONTEXT record

Arguments:

    Irp - Supplies the originating Irp.

    Wait - Supplies the wait value to store in the context

Return Value:

    PIRP_CONTEXT - returns a pointer to the newly allocate IRP_CONTEXT Record

--*/

{
    PIRP_CONTEXT IrpContext;
    PIO_STACK_LOCATION IrpSp;

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

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  The only operations a filesystem device object should ever receive
    //  are create/teardown of fsdo handles and operations which do not
    //  occur in the context of fileobjects (i.e., mount).
    //

    if (FatDeviceIsFatFsdo( IrpSp->DeviceObject))  {

        if (IrpSp->FileObject != NULL &&
            IrpSp->MajorFunction != IRP_MJ_CREATE &&
            IrpSp->MajorFunction != IRP_MJ_CLEANUP &&
            IrpSp->MajorFunction != IRP_MJ_CLOSE) {

            ExRaiseStatus( STATUS_INVALID_DEVICE_REQUEST );
        }

        ASSERT( IrpSp->FileObject != NULL ||

                (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
                 IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST &&
                 IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) ||

                (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
                 IrpSp->MinorFunction == IRP_MN_MOUNT_VOLUME ) ||

                IrpSp->MajorFunction == IRP_MJ_SHUTDOWN );
    }

    //
    //  Attemtp to allocate from the region first and failing that allocate
    //  from pool.
    //

    DebugDoit( FatFsdEntryCount += 1);

    IrpContext = FatAllocateIrpContext();

    //
    //  Zero out the irp context.
    //

    RtlZeroMemory( IrpContext, sizeof(IRP_CONTEXT) );

    //
    //  Set the proper node type code and node byte size
    //

    IrpContext->NodeTypeCode = FAT_NTC_IRP_CONTEXT;
    IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);

    //
    //  Set the originating Irp field
    //

    IrpContext->OriginatingIrp = Irp;

    //
    //  Major/Minor Function codes
    //

    IrpContext->MajorFunction = IrpSp->MajorFunction;
    IrpContext->MinorFunction = IrpSp->MinorFunction;

    //
    //  Copy RealDevice for workque algorithms, and also set Write Through
    //  and Removable Media if there is a file object.  Only file system
    //  control Irps won't have a file object, and they should all have
    //  a Vpb as the first IrpSp location.
    //

    if (IrpSp->FileObject != NULL) {

        PVCB Vcb;
        PFILE_OBJECT FileObject = IrpSp->FileObject;

        IrpContext->RealDevice = FileObject->DeviceObject;
        Vcb = IrpContext->Vcb = &((PVOLUME_DEVICE_OBJECT)(IrpSp->DeviceObject))->Vcb;

        //
        //  See if the request is Write Through.
        //

        if (IsFileWriteThrough( FileObject, Vcb )) {

            SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
        }
    } else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {

        IrpContext->RealDevice = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
    }

    //
    //  Set the wait parameter
    //

    if (Wait) { SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); }

    //
    //  Set the recursive file system call parameter.  We set it true if
    //  the TopLevelIrp field in the thread local storage is not the current
    //  irp, otherwise we leave it as FALSE.
    //

    if ( IoGetTopLevelIrp() != Irp) {

        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
    }

    //
    //  return and tell the caller
    //

    DebugTrace(-1, Dbg, "FatCreateIrpContext -> %08lx\n", IrpContext);

    return IrpContext;
}



VOID
FatDeleteIrpContext_Real (
    IN PIRP_CONTEXT IrpContext
    )

/*++

Routine Description:

    This routine deallocates and removes the specified IRP_CONTEXT record
    from the Fat in memory data structures.  It should only be called
    by FatCompleteRequest.

Arguments:

    IrpContext - Supplies the IRP_CONTEXT to remove

Return Value:

    None

--*/

{
    DebugTrace(+1, Dbg, "FatDeleteIrpContext, IrpContext = %08lx\n", IrpContext);

    ASSERT( IrpContext->NodeTypeCode == FAT_NTC_IRP_CONTEXT );
    ASSERT( IrpContext->PinCount == 0 );

    //
    //  If there is a FatIoContext that was allocated, free it.
    //

    if (IrpContext->FatIoContext != NULL) {

        if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {

            if (IrpContext->FatIoContext->ZeroMdl) {
                IoFreeMdl( IrpContext->FatIoContext->ZeroMdl );
            }

            ExFreePool( IrpContext->FatIoContext );
        }
    }

    //
    //  Drop the IrpContext.
    //

    FatFreeIrpContext( IrpContext );

    //
    //  return and tell the caller
    //

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

    return;
}


PFCB
FatGetNextFcbBottomUp (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb OPTIONAL,
    IN PFCB TerminationFcb
    )

/*++

Routine Description:

    This routine is used to iterate through Fcbs in a tree.  In order to match
    the lockorder for getting multiple Fcbs (so this can be used for acquiring
    all Fcbs), this version does a bottom-up enumeration.

    This is different than the old one, now called TopDown. The problem with
    lockorder was very well hidden.

    The transition rule is still pretty simple:

        A) If you have an adjacent sibling, go to it
            1) Descend to its leftmost child
        B) Else go to your parent

    If this routine is called with in invalid TerminationFcb it will fail,
    badly.

    The TerminationFcb is the last Fcb returned in the enumeration.

    This method is incompatible with the possibility that ancestors may vanish
    based on operations done on the last returned node.  For instance,
    FatPurgeReferencedFileObjects cannot use BottomUp enumeration.

Arguments:

    Fcb - Supplies the current Fcb.  This is NULL if enumeration is starting.

    TerminationFcb - The root Fcb of the tree in which the enumeration starts
        and at which it inclusively stops.

Return Value:

    The next Fcb in the enumeration, or NULL if Fcb was the final one.

--*/

{
    PFCB NextFcb;

    ASSERT( FatVcbAcquiredExclusive( IrpContext, TerminationFcb->Vcb ) ||
            FlagOn( TerminationFcb->Vcb->VcbState, VCB_STATE_FLAG_LOCKED ) );

    //
    //  Do we need to begin the enumeration?
    //

    if (Fcb != NULL) {

        //
        //  Did we complete?
        //

        if (Fcb == TerminationFcb) {

            return NULL;
        }

        //
        //  Do we have a sibling to return?
        //

        NextFcb = FatGetNextSibling( Fcb );

        //
        //  If not, return our parent.  We are done with this branch.
        //

        if (NextFcb == NULL) {

            return Fcb->ParentDcb;
        }

    } else {

        NextFcb = TerminationFcb;
    }

    //
    //  Decend to its furthest child (if it exists) and return it.
    //

    for (;
         NodeType( NextFcb ) != FAT_NTC_FCB && FatGetFirstChild( NextFcb ) != NULL;
         NextFcb = FatGetFirstChild( NextFcb )) {
    }

    return NextFcb;
}

PFCB
FatGetNextFcbTopDown (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PFCB TerminationFcb
    )

/*++

Routine Description:

    This routine is used to iterate through Fcbs in a tree, from the top down.

    The rule is very simple:

        A) If you have a child, go to it, else
        B) If you have an older sibling, go to it, else
        C) Go to your parent's older sibling.

    If this routine is called with in invalid TerminationFcb it will fail,
    badly.

    The Termination Fcb is never returned.  If it is the root of the tree you
    are traversing, visit it first.

    This routine never returns direct ancestors of Fcb, and thus is useful when
    making Fcb's go away (which may tear up the tree).

Arguments:

    Fcb - Supplies the current Fcb

    TerminationFcb - The Fcb at which the enumeration should (non-inclusivly)
        stop.  Assumed to be a directory.

Return Value:

    The next Fcb in the enumeration, or NULL if Fcb was the final one.

--*/

{
    PFCB Sibling;

    ASSERT( FatVcbAcquiredExclusive( IrpContext, Fcb->Vcb ) ||
            FlagOn( Fcb->Vcb->VcbState, VCB_STATE_FLAG_LOCKED ) );

    //
    //  If this was a directory (ie. not a file), get the child.  If
    //  there aren't any children and this is our termination Fcb,
    //  return NULL.
    //

    if ( ((NodeType(Fcb) == FAT_NTC_DCB) ||
          (NodeType(Fcb) == FAT_NTC_ROOT_DCB)) &&
         !IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) ) {

        return FatGetFirstChild( Fcb );
    }

    //
    //  Were we only meant to do one iteration?
    //

    if ( Fcb == TerminationFcb ) {

        return NULL;
    }

    Sibling = FatGetNextSibling(Fcb);

    while (TRUE) {

        //
        //  Do we still have an "older" sibling in this directory who is
        //  not the termination Fcb?
        //

        if ( Sibling != NULL ) {

            return (Sibling != TerminationFcb) ? Sibling : NULL;
        }

        //
        //  OK, let's move on to out parent and see if he is the termination
        //  node or has any older siblings.
        //

        if ( Fcb->ParentDcb == TerminationFcb ) {

            return NULL;
        }

        Fcb = F

⌨️ 快捷键说明

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