Example #1
0
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdOplockComplete (
    _Inout_ PIRP_CONTEXT IrpContext,
    _Inout_ PIRP Irp
    )

/*++

Routine Description:

    This routine is called by the oplock package when an oplock break has
    completed, allowing an Irp to resume execution.  If the status in
    the Irp is STATUS_SUCCESS, then we queue the Irp to the Fsp queue.
    Otherwise we complete the Irp with the status in the Irp.

    If we are completing due to an error then check if there is any
    cleanup to do.

Arguments:

    Irp - I/O Request Packet.

Return Value:

    None.

--*/

{
    BOOLEAN RemovedFcb;

    PAGED_CODE();

    //
    //  Check on the return value in the Irp.  If success then we
    //  are to post this request.
    //

    if (Irp->IoStatus.Status == STATUS_SUCCESS) {

        //
        //  Check if there is any cleanup work to do.
        //

        switch (IrpContext->MajorFunction) {

        case IRP_MJ_CREATE :

            //
            //  If called from the oplock package then there is an
            //  Fcb to possibly teardown.  We will call the teardown
            //  routine and release the Fcb if still present.  The cleanup
            //  code in create will know not to release this Fcb because
            //  we will clear the pointer.
            //

            if (IrpContext->TeardownFcb != NULL) {

                CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb );

                if (!RemovedFcb) {

                    _Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
                    CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
                }

                *(IrpContext->TeardownFcb) = NULL;
                IrpContext->TeardownFcb = NULL;
            }

            break;
        }

        //
        //  Insert the Irp context in the workqueue.
        //

        CdAddToWorkque( IrpContext, Irp );

    //
    //  Otherwise complete the request.
    //

    } else {

        CdCompleteRequest( IrpContext, Irp, Irp->IoStatus.Status );
    }

    return;
}
Example #2
0
BOOLEAN
CdCommonClosePrivate (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PFCB Fcb,
    IN ULONG UserReference,
    IN BOOLEAN FromFsd
    )

/*++

Routine Description:

    This is the worker routine for the close operation.  We can be called in
    an Fsd thread or from a worker Fsp thread.  If called from the Fsd thread
    then we acquire the resources without waiting.  Otherwise we know it is
    safe to wait.

    We check to see whether we should post this request to the delayed close
    queue.  If we are to process the close here then we acquire the Vcb and
    Fcb.  We will adjust the counts and call our teardown routine to see
    if any of the structures should go away.

Arguments:

    Vcb - Vcb for this volume.

    Fcb - Fcb for this request.

    UserReference - Number of user references for this file object.  This is
        zero for an internal stream.

    FromFsd - This request was called from an Fsd thread.  Indicates whether
        we should wait to acquire resources.

    DelayedClose - Address to store whether we should try to put this on
        the delayed close queue.  Ignored if this routine can process this
        close.

Return Value:

    BOOLEAN - TRUE if this thread processed the close, FALSE otherwise.

--*/

{
    BOOLEAN RemovedFcb;

    PAGED_CODE();

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_FCB( Fcb );

    //
    //  Try to acquire the Vcb and Fcb.  If we can't acquire them then return
    //  and let our caller know he should post the request to the async
    //  queue.
    //

    if (CdAcquireVcbShared( IrpContext, Vcb, FromFsd )) {

        if (!CdAcquireFcbExclusive( IrpContext, Fcb, FromFsd )) {

            //
            //  We couldn't get the Fcb.  Release the Vcb and let our caller
            //  know to post this request.
            //

            CdReleaseVcb( IrpContext, Vcb );
            return FALSE;
        }

    //
    //  We didn't get the Vcb.  Let our caller know to post this request.
    //

    } else {

        return FALSE;
    }

    //
    //  Lock the Vcb and decrement the reference counts.
    //

    CdLockVcb( IrpContext, Vcb );
    CdDecrementReferenceCounts( IrpContext, Fcb, 1, UserReference );
    CdUnlockVcb( IrpContext, Vcb );

    //
    //  Call our teardown routine to see if this object can go away.
    //  If we don't remove the Fcb then release it.
    //

    CdTeardownStructures( IrpContext, Fcb, &RemovedFcb );

    if (!RemovedFcb) {

        CdReleaseFcb( IrpContext, Fcb );
    }

    //
    //  Release the Vcb and return to our caller.  Let him know we completed
    //  this request.
    //

    CdReleaseVcb( IrpContext, Vcb );

    return TRUE;
}
Example #3
0
VOID
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
CdPrePostIrp (
    _Inout_ PIRP_CONTEXT IrpContext,
    _Inout_ PIRP Irp
    )

/*++

Routine Description:

    This routine performs any neccessary work before STATUS_PENDING is
    returned with the Fsd thread.  This routine is called within the
    filesystem and by the oplock package.

Arguments:

    Context - Pointer to the IrpContext to be queued to the Fsp

    Irp - I/O Request Packet.

Return Value:

    None.

--*/

{
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
    BOOLEAN RemovedFcb;

    PAGED_CODE();

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_IRP( Irp );

    //
    //  Case on the type of the operation.
    //

    switch (IrpContext->MajorFunction) {

    case IRP_MJ_CREATE :

        //
        //  If called from the oplock package then there is an
        //  Fcb to possibly teardown.  We will call the teardown
        //  routine and release the Fcb if still present.  The cleanup
        //  code in create will know not to release this Fcb because
        //  we will clear the pointer.
        //

        if ((IrpContext->TeardownFcb != NULL) &&
            *(IrpContext->TeardownFcb) != NULL) {

            CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb );

            if (!RemovedFcb) {

                _Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
                CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
            }

            *(IrpContext->TeardownFcb) = NULL;
            IrpContext->TeardownFcb = NULL;
        }

        break;

    //
    //  We need to lock the user's buffer, unless this is an MDL read/write,
    //  in which case there is no user buffer.
    //

    case IRP_MJ_READ :

        if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {

            CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoWriteAccess );
        }

        break;

    case IRP_MJ_WRITE :

        if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {

            CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoReadAccess );
        }

        break;

    //
    //  We also need to check whether this is a query file operation.
    //

    case IRP_MJ_DIRECTORY_CONTROL :

        if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {

            CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length, IoWriteAccess );
        }

        break;
    }

    //
    //  Cleanup the IrpContext for the post.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
    CdCleanupIrpContext( IrpContext, TRUE );

    //
    //  Mark the Irp to show that we've already returned pending to the user.
    //

    IoMarkIrpPending( Irp );

    return;
}