Ejemplo n.º 1
0
/*
    This routine performs Close operation for all files from
    Delayed Close queue.
 */
VOID
UDFCloseAllDelayed(
    IN PVCB Vcb
    )
{
    PLIST_ENTRY             Entry;
    PtrUDFIrpContextLite    NextIrpContextLite;
    BOOLEAN                 GlobalDataAcquired = FALSE;

    AdPrint(("  UDFCloseAllDelayed\n"));
    // Acquire DelayedCloseResource
    if (!ExIsResourceAcquiredExclusive(&UDFGlobalData.GlobalDataResource)) {
        UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
        GlobalDataAcquired = TRUE;
    }

    Entry = UDFGlobalData.DelayedCloseQueue.Flink;

    while (Entry != &UDFGlobalData.DelayedCloseQueue) {
        //  Extract the IrpContext.
        NextIrpContextLite = CONTAINING_RECORD( Entry,
                                                UDFIrpContextLite,
                                                DelayedCloseLinks );
        Entry = Entry->Flink;
        if (NextIrpContextLite->Fcb->Vcb == Vcb) {
            RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
            UDFGlobalData.DelayedCloseCount--;
            UDFDoDelayedClose(NextIrpContextLite);
        }
    }

    Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;

    while (Entry != &UDFGlobalData.DirDelayedCloseQueue) {
        //  Extract the IrpContext.
        NextIrpContextLite = CONTAINING_RECORD( Entry,
                                                UDFIrpContextLite,
                                                DelayedCloseLinks );
        Entry = Entry->Flink;
        if (NextIrpContextLite->Fcb->Vcb == Vcb) {
            RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
            UDFGlobalData.DirDelayedCloseCount--;
            UDFDoDelayedClose(NextIrpContextLite);
        }
    }

    // Release DelayedCloseResource
    if(GlobalDataAcquired)
        UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));

} // end UDFCloseAllDelayed()
Ejemplo n.º 2
0
VOID
SrvCloseEndpoint (
    IN PENDPOINT Endpoint
    )

/*++

Routine Description:

    This function closes a transport endpoint.

    *** This function must be called with SrvEndpointLock held exactly
        once.  The lock is released on exit.

Arguments:

    Endpoint - Supplies a pointer to an Endpoint Block

Return Value:

    None.

--*/

{
    CSHORT index;
    PCONNECTION connection;

    PAGED_CODE( );

    ASSERT( ExIsResourceAcquiredExclusive(&RESOURCE_OF(SrvEndpointLock)) );

    if ( GET_BLOCK_STATE(Endpoint) == BlockStateActive ) {

        IF_DEBUG(BLOCK1) SrvPrint1( "Closing endpoint at %lx\n", Endpoint );

        SET_BLOCK_STATE( Endpoint, BlockStateClosing );

        //
        // Close all active connections.
        //

        index = (CSHORT)-1;

        while ( TRUE ) {

            //
            // Get the next active connection in the table.  If no more
            // are available, WalkConnectionTable returns NULL.
            // Otherwise, it returns a referenced pointer to a
            // connection.
            //

            connection = WalkConnectionTable( Endpoint, &index );
            if ( connection == NULL ) {
                break;
            }

            //
            // We don't want to hold the endpoint lock while we close the
            // connection (this causes lock level problems).  Since we
            // already have a referenced pointer to the connection, this
            // is safe.
            //

            RELEASE_LOCK( &SrvEndpointLock );

#if SRVDBG29
            UpdateConnectionHistory( "CEND", Endpoint, connection );
#endif
            SrvCloseConnection( connection, FALSE );

            ACQUIRE_LOCK( &SrvEndpointLock );

            SrvDereferenceConnection( connection );

        }

        //
        // Close all free connections.
        //

        EmptyFreeConnectionList( Endpoint );

        //
        // We don't need to hold the endpoint lock anymore.
        //

        RELEASE_LOCK( &SrvEndpointLock );

        //
        // Close the endpoint file handle.  This causes all pending
        // requests to be aborted.  It also deregisters all event
        // handlers.
        //
        // *** Note that we have a separate reference to the file
        //     object, in addition to the handle.  We don't release that
        //     reference until all activity on the endpoint has ceased
        //     (in SrvDereferenceEndpoint).
        //

        SRVDBG_RELEASE_HANDLE( Endpoint->EndpointHandle, "END", 2, Endpoint );
        SrvNtClose( Endpoint->EndpointHandle, FALSE );
        if ( Endpoint->IsConnectionless ) {
            SRVDBG_RELEASE_HANDLE( Endpoint->NameSocketHandle, "END", 2, Endpoint );
            SrvNtClose( Endpoint->NameSocketHandle, FALSE );
        }

        //
        // Dereference the endpoint (to indicate that it's no longer
        // open).
        //

        SrvDereferenceEndpoint( Endpoint );

        INCREMENT_DEBUG_STAT( SrvDbgStatistics.EndpointInfo.Closes );

    } else {

        RELEASE_LOCK( &SrvEndpointLock );

    }

    return;

} // SrvCloseEndpoint
Ejemplo n.º 3
0
VOID
NtfsReleaseVcbCheckDelete (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN UCHAR MajorCode,
    IN PFILE_OBJECT FileObject OPTIONAL
    )

/*++

Routine Description:

    This routine will release the Vcb.  We will also test here whether we should
    teardown the Vcb at this point.  If this is the last open queued to a dismounted
    volume or the last close from a failed mount or the failed mount then we will
    want to test the Vcb for a teardown.

Arguments:

    Vcb - Supplies the Vcb to acquire

    MajorCode - Indicates what type of operation we were called from.

    FileObject - Optionally supplies the file object whose VPB pointer we need to
        zero out

Return Value:

    None.

--*/

{
    ASSERT_IRP_CONTEXT(IrpContext);
    ASSERT_VCB(Vcb);

    if (FlagOn( Vcb->VcbState, VCB_STATE_PERFORMED_DISMOUNT ) &&
        (Vcb->CloseCount == 0)) {

        ULONG ReferenceCount;
        ULONG ResidualCount;

        KIRQL SavedIrql;
        BOOLEAN DeleteVcb = FALSE;

        ASSERT_EXCLUSIVE_RESOURCE( &Vcb->Resource );

        //
        //  The volume has gone through dismount.  Now we need to decide if this
        //  release of the Vcb is the last reference for this volume.  If so we
        //  can tear the volume down.
        //
        //  We compare the reference count in the Vpb with the state of the volume
        //  and the type of operation.  We also need to check if there is a
        //  referenced log file object.
        //

        IoAcquireVpbSpinLock( &SavedIrql );

        ReferenceCount = Vcb->Vpb->ReferenceCount;

        IoReleaseVpbSpinLock( SavedIrql );

        ResidualCount = 0;

        if (Vcb->LogFileObject != NULL) {

            ResidualCount = 1;
        }

        if (MajorCode == IRP_MJ_CREATE) {

            ResidualCount += 1;
        }

        //
        //  If the residual count is the same as the count in the Vpb then we
        //  can delete the Vpb.
        //

        if (ResidualCount == ReferenceCount) {

            SetFlag( Vcb->VcbState, VCB_STATE_DELETE_UNDERWAY );

            ExReleaseResource( &Vcb->Resource );

            //
            //  Never delete the Vcb unless this is the last release of
            //  this Vcb.
            //

            if (!ExIsResourceAcquiredExclusive( &Vcb->Resource ) &&
                (ExIsResourceAcquiredShared( &Vcb->Resource ) == 0)) {

                if (ARGUMENT_PRESENT(FileObject)) { FileObject->Vpb = NULL; }

                //
                //  If this is a create then the IO system will handle the
                //  Vpb.
                //

                if (MajorCode == IRP_MJ_CREATE) {

                    ClearFlag( Vcb->VcbState, VCB_STATE_TEMP_VPB );
                }

                //
                //  Use the global resource to synchronize the DeleteVcb process.
                //

                (VOID) ExAcquireResourceExclusive( &NtfsData.Resource, TRUE );

                RemoveEntryList( &Vcb->VcbLinks );

                ExReleaseResource( &NtfsData.Resource );

                NtfsDeleteVcb( IrpContext, &Vcb );

            } else {

                ClearFlag( Vcb->VcbState, VCB_STATE_DELETE_UNDERWAY );
            }

        } else {

            ExReleaseResource( &Vcb->Resource );
        }

    } else {

        ExReleaseResource( &Vcb->Resource );
    }
}