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

📄 strucsup.c

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

    RtlZeroMemory( NewIrpContext, sizeof( IRP_CONTEXT ));

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

    NewIrpContext->NodeTypeCode = CDFS_NTC_IRP_CONTEXT;
    NewIrpContext->NodeByteSize = sizeof( IRP_CONTEXT );

    //
    //  Set the originating Irp field
    //

    NewIrpContext->Irp = Irp;

    //
    //  Copy RealDevice for workque algorithms.  We will update this in the Mount or
    //  Verify since they have no file objects to use here.
    //

    if (IrpSp->FileObject != NULL) {

        NewIrpContext->RealDevice = IrpSp->FileObject->DeviceObject;
    }

    //
    //  Locate the volume device object and Vcb that we are trying to access.
    //  This may be our filesystem device object.  In that case don't initialize
    //  the Vcb field.
    //

    if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject) {

        NewIrpContext->Vcb =  &((PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject)->Vcb;
    
    }

    //
    //  Major/Minor Function codes
    //

    NewIrpContext->MajorFunction = IrpSp->MajorFunction;
    NewIrpContext->MinorFunction = IrpSp->MinorFunction;

    //
    //  Set the wait parameter
    //

    if (Wait) {

        SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );

    } else {

        SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST );
    }

    //
    //  return and tell the caller
    //

    return NewIrpContext;
}


VOID
CdCleanupIrpContext (
    IN PIRP_CONTEXT IrpContext,
    IN BOOLEAN Post
    )

/*++

Routine Description:

    This routine is called to cleanup and possibly deallocate the Irp Context.
    If the request is being posted or this Irp Context is possibly on the
    stack then we only cleanup any auxilary structures.

Arguments:

    Post - TRUE if we are posting this request, FALSE if we are deleting
        or retrying this in the current thread.

Return Value:

    None.

--*/

{
    PAGED_CODE();

    //
    //  If we aren't doing more processing then deallocate this as appropriate.
    //

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

        //
        //  If this context is the top level CDFS context then we need to
        //  restore the top level thread context.
        //

        if (IrpContext->ThreadContext != NULL) {

            CdRestoreThreadContext( IrpContext );
        }

        //
        //  Deallocate the Io context if allocated.
        //

        if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {

            CdFreeIoContext( IrpContext->IoContext );
        }

        //
        //  Deallocate the IrpContext if not from the stack.
        //

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

            if (CdData.IrpContextDepth < CdData.IrpContextMaxDepth) {

                CdLockCdData();

                PushEntryList( &CdData.IrpContextList, (PSINGLE_LIST_ENTRY) IrpContext );
                CdData.IrpContextDepth++;

                CdUnlockCdData();

            } else {

                //
                //  We couldn't add this to our lookaside list so free it to
                //  pool.
                //

                CdFreePool( &IrpContext );
            }
        }

    //
    //  Clear the appropriate flags.
    //

    } else if (Post) {

        //
        //  If this context is the top level CDFS context then we need to
        //  restore the top level thread context.
        //

        if (IrpContext->ThreadContext != NULL) {

            CdRestoreThreadContext( IrpContext );
        }

        ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_POST );

    } else {

        ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY );
    }

    return;
}


VOID
CdInitializeStackIrpContext (
    OUT PIRP_CONTEXT IrpContext,
    IN PIRP_CONTEXT_LITE IrpContextLite
    )

/*++

Routine Description:

    This routine is called to initialize an IrpContext for the current
    CDFS request.  The IrpContext is on the stack and we need to initialize
    it for the current request.  The request is a close operation.

Arguments:

    IrpContext - IrpContext to initialize.

    IrpContextLite - Structure containing the details of this request.

Return Value:

    None

--*/

{
    PAGED_CODE();

    //
    //  Zero and then initialize the structure.
    //

    RtlZeroMemory( IrpContext, sizeof( IRP_CONTEXT ));

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

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

    //
    //  Note that this is from the stack.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ON_STACK );

    //
    //  Copy RealDevice for workque algorithms.
    //

    IrpContext->RealDevice = IrpContextLite->RealDevice;

    //
    //  The Vcb is found in the Fcb.
    //

    IrpContext->Vcb = IrpContextLite->Fcb->Vcb;

    //
    //  Major/Minor Function codes
    //

    IrpContext->MajorFunction = IRP_MJ_CLOSE;

    //
    //  Set the wait parameter
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );

    return;
}


VOID
CdTeardownStructures (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB StartingFcb,
    OUT PBOOLEAN RemovedStartingFcb
    )

/*++

Routine Description:

    This routine is used to walk from some starting point in the Fcb tree towards
    the root.  It will remove the Fcb and continue walking up the tree until
    it finds a point where we can't remove an Fcb.

    We look at the following fields in the Fcb to determine whether we can
    remove this.

        1 - Handle count must be zero.
        2 - If directory then only the only reference can be for a stream file.
        3 - Reference count must either be zero or go to zero here.

    We return immediately if we are recursively entering this routine.

Arguments:

    StartingFcb - This is the Fcb node in the tree to begin with.  This Fcb
        must currently be acquired exclusively.

    RemovedStartingFcb - Address to store whether we removed the starting Fcb.

Return Value:

    None

--*/

{
    PVCB Vcb = StartingFcb->Vcb;
    PFCB CurrentFcb = StartingFcb;
    BOOLEAN AcquiredCurrentFcb = FALSE;
    PFCB ParentFcb;

    PAGED_CODE();

    *RemovedStartingFcb = FALSE;

    //
    //  If this is a recursive call to TearDownStructures we return immediately
    //  doing no operation.
    //

    if (FlagOn( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN )) {

        return;
    }

    SetFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN );

    //
    //  Use a try-finally to safely clear the top-level field.
    //

    try {

        //
        //  Loop until we find an Fcb we can't remove.
        //

        do {

            //
            //  See if there is an internal stream we should delete.
            //  Only do this if it is the last reference on the Fcb.
            //

            if ((SafeNodeType( CurrentFcb ) != CDFS_NTC_FCB_DATA) &&
                (CurrentFcb->FcbUserReference == 0) &&
                (CurrentFcb->FileObject != NULL)) {

                //
                //  Go ahead and delete the stream file object.
                //

                CdDeleteInternalStream( IrpContext, CurrentFcb );
            }

            //
            //  If the reference count is non-zero then break.
            //

            if (CurrentFcb->FcbReference != 0) {

                break;
            }

            //
            //  It looks like we have a candidate for removal here.  We
            //  will need to acquire the parent, if present, in order to
            //  remove this from the parent prefix table.
            //

            ParentFcb = CurrentFcb->ParentFcb;

            if (ParentFcb != NULL) {

                CdAcquireFcbExclusive( IrpContext, ParentFcb, FALSE );
            }

            //
            //  Now lock the vcb.
            //

            CdLockVcb( IrpContext, Vcb );

            //
            //  Final check to see if the reference count is still zero.
            //

            if (CurrentFcb->FcbReference != 0) {

                CdUnlockVcb( IrpContext, Vcb );

                if (ParentFcb != NULL) {

                    CdReleaseFcb( IrpContext, ParentFcb );
                }

                break;
            }

            //
            //  If there is a parent then do the necessary cleanup for the parent.
            //

            if (ParentFcb != NULL) {

                CdRemovePrefix( IrpContext, CurrentFcb );
                RemoveEntryList( &CurrentFcb->FcbLinks );

                CdDecrementReferenceCounts( IrpContext, ParentFcb, 1, 1 );
            }

            if (FlagOn( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE )) {

                CdDeleteFcbTable( IrpContext, CurrentFcb );
                ClearFlag( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE );

            }

            //
            //  Unlock the Vcb but hold the parent in order to walk up
            //  the tree.
            //

            CdUnlockVcb( IrpContext, Vcb );
            CdDeleteFcb( IrpContext, CurrentFcb );

            //
            //  Move to the parent Fcb.
            //

            CurrentFcb = ParentFcb;
            AcquiredCurrentFcb = TRUE;

        } while (CurrentFcb != NULL);

    } finally {

        //
        //  Release the current Fcb if we have acquired it.
        //

        if (AcquiredCurrentFcb && (CurrentFcb != NULL)) {

            CdReleaseFcb( IrpContext, CurrentFcb );
        }

        //
        //  Clear the teardown flag.
        //

        ClearFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN );
    }

    *RemovedStartingFcb = (CurrentFcb != StartingFcb);
    return;
}


PFCB
CdLookupFcbTable (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN FILE_ID FileId
    )

/*++

Routine Description:

    This routine will look through the Fcb table looking for a matching
    entry.

Arguments:

    Vcb - Vcb for this volume.

    FileId - This is the key value to use for the search.

Return Value:

    PFCB - A pointer to the matching entry or NULL otherwise.

--*/

{
    FCB_TABLE_ELEMENT Key;
    PFCB_TABLE_ELEMENT Hit;
    PFCB ReturnFcb = NULL;

    PAGED_CODE();

    Key.FileId = FileId;

    Hit = (PFCB_TABLE_ELEMENT) RtlLookupElementGenericTable( &Vcb->FcbTable, &Key );

    if (Hit != NULL) {

        ReturnFcb = Hit->Fcb;
    }

    return ReturnFcb;

    UNREFERENCED_PARAMETER( IrpContext );
}


PFCB
CdGetNextFcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PVOID *RestartKey
    )

/*++

Routine Description:

    This routine will enumerate through all of the Fcb's in the Fcb table.

Arguments:

    Vcb - Vcb for this volume.

    RestartKey - This value is used by the table package to maintain
        its position in the enumeration.  It is initialized to NULL
        for the first search.

Return Value:

    PFCB - A pointer to the next fcb or NULL if the enumeration is
        completed

--*/

{
    PFCB Fcb;

    PAGED_CODE();

    Fcb = (PFCB) RtlEnumerateGenericTableWithoutSplaying( &Vcb->FcbTable, RestartKey );

    if (Fcb != NULL) {

        Fcb = ((PFCB_TABLE_ELEMENT)(Fcb))->Fcb;
    }

    return Fcb;
}


NTSTATUS
CdProcessToc (
    IN PIRP_CONTEXT IrpContext,
    IN PDEVICE_OBJECT TargetDeviceObject,
    IN PCDROM_TOC_LARGE CdromToc,
    IN OUT PULONG Length,
    OUT PULONG TrackCount,
    OUT PULONG DiskFlags
    )

/*++

⌨️ 快捷键说明

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