コード例 #1
0
VOID
NTAPI
NpDeleteFcb(IN PNP_FCB Fcb,
            IN PLIST_ENTRY ListEntry)
{
    PNP_DCB Dcb;
    PAGED_CODE();

    Dcb = Fcb->ParentDcb;
    if (Fcb->CurrentInstances) NpBugCheck(0, 0, 0);

    NpCancelWaiter(&NpVcb->WaitQueue,
                   &Fcb->FullName,
                   STATUS_OBJECT_NAME_NOT_FOUND,
                   ListEntry);

    RemoveEntryList(&Fcb->DcbEntry);

    if (Fcb->SecurityDescriptor)
    {
        ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1);
    }

    RtlRemoveUnicodePrefix(&NpVcb->PrefixTable, &Fcb->PrefixTableEntry);
    ExFreePool(Fcb->FullName.Buffer);
    ExFreePool(Fcb);
    NpCheckForNotify(Dcb, TRUE, ListEntry);
}
コード例 #2
0
ファイル: strucsup.c プロジェクト: BillTheBest/WinNT4
VOID
MsDeleteRootDcb (
    IN PROOT_DCB RootDcb
    )

/*++

Routine Description:

    This routine deallocates and removes the ROOT DCB record
    from our in-memory data structures.  It also will remove all
    associated underlings (i.e., Notify queues and child FCB records).

Arguments:

    RootDcb - Supplies the ROOT DCB to be removed

Return Value:

    None

--*/

{
    PLIST_ENTRY links;
    PIRP irp;

    PAGED_CODE();
    DebugTrace(+1, Dbg, "MsDeleteRootDcb, RootDcb = %08lx\n", (ULONG)RootDcb);

    //
    // We can only delete this record if the reference count is zero.
    //

    if (RootDcb->Header.ReferenceCount != 0) {
        DebugDump("Error deleting RootDcb, Still Open\n", 0, RootDcb);
        KeBugCheck( MAILSLOT_FILE_SYSTEM );
    }

    //
    // Remove every notify IRP from the two notify queues.
    //

    while (!IsListEmpty(&RootDcb->Specific.Dcb.NotifyFullQueue)) {

        links = RemoveHeadList( &RootDcb->Specific.Dcb.NotifyFullQueue );
        irp = CONTAINING_RECORD( links, IRP, Tail.Overlay.ListEntry );

        MsCompleteRequest( irp, STATUS_FILE_FORCED_CLOSED );
    }

    while (!IsListEmpty(&RootDcb->Specific.Dcb.NotifyPartialQueue)) {

        links = RemoveHeadList( &RootDcb->Specific.Dcb.NotifyPartialQueue );
        irp = CONTAINING_RECORD( links, IRP, Tail.Overlay.ListEntry );

        MsCompleteRequest( irp, STATUS_FILE_FORCED_CLOSED );
    }

    //
    // We can only be removed if the no other FCB have us referenced
    // as a their parent DCB.
    //

    if (!IsListEmpty(&RootDcb->Specific.Dcb.ParentDcbQueue)) {
        DebugDump("Error deleting RootDcb\n", 0, RootDcb);
        KeBugCheck( MAILSLOT_FILE_SYSTEM );
    }

    //
    // Remove the entry from the prefix table, and then remove the full
    // file name.
    //

    MsAcquirePrefixTableLock();
    RtlRemoveUnicodePrefix( &RootDcb->Vcb->PrefixTable, &RootDcb->PrefixTableEntry );
    MsReleasePrefixTableLock();
    ExFreePool( RootDcb->FullFileName.Buffer );

    //
    // Free up the resource variable.
    //

    ExDeleteResource( &(RootDcb->Resource) );

    //
    // Finally deallocate the DCB record.
    //

    ExFreePool( RootDcb );

    //
    // Return to the caller.
    //

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

    return;
}
コード例 #3
0
ファイル: cleanup.c プロジェクト: BillTheBest/WinNT4
NTSTATUS
MsCleanupFcb (
    IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
    IN PIRP Irp,
    IN PFCB Fcb
    )

/*++

Routine Description:

    This routine cleans up an FCB.  All outstanding i/o on the file
    object are completed with an error status.

Arguments:

    MsfsDeviceObject - A pointer the the mailslot file system device object.

    Irp - Supplies the IRP associated with the cleanup.

    Fcb - Supplies the FCB for the mailslot to clean up.

Return Value:

    NTSTATUS - An appropriate completion status

--*/
{
    NTSTATUS status;
    PDATA_QUEUE dataQueue;
    PDATA_ENTRY dataEntry;
    PLIST_ENTRY listEntry;
    PIRP oldIrp;
    PCCB ccb;
    PWORK_CONTEXT workContext;
    PKTIMER timer;

    PAGED_CODE();
    DebugTrace(+1, Dbg, "MsCleanupFcb, Fcb = %08lx\n", (ULONG)Fcb);

    //
    // Acquire exclusive access to the FCB.
    //

    MsAcquireExclusiveFcb( Fcb );

    status = STATUS_SUCCESS;

    try {

        //
        // Ensure that this FCB still belongs to an active open mailslot.
        //

        MsVerifyFcb( Fcb );

        //
        // Remove the entry from the prefix table, and then remove the full
        // file name.
        //

        MsAcquirePrefixTableLock();
        RtlRemoveUnicodePrefix( &Fcb->Vcb->PrefixTable, &Fcb->PrefixTableEntry );
        MsReleasePrefixTableLock();

        //
        // Remove ourselves from our parent DCB's queue.
        //

        RemoveEntryList( &(Fcb->ParentDcbLinks) );

        //
        // Complete all outstanding I/O on this FCB.
        //

        dataQueue = &Fcb->DataQueue;
        dataQueue->QueueState = -1;

        for (listEntry = MsGetNextDataQueueEntry( dataQueue );
             !MsIsDataQueueEmpty(dataQueue);
             listEntry = MsGetNextDataQueueEntry( dataQueue ) ) {

             //
             // This is an outstanding I/O request on this FCB.
             // Remove it from our queue and complete the request
             // if one is outstanding.
             //

             dataEntry = CONTAINING_RECORD( listEntry, DATA_ENTRY, ListEntry );

             //
             // Cancel the timer if there is a timer for the read request.
             //

             workContext = dataEntry->TimeoutWorkContext;
             if (workContext != NULL) {

                 DebugTrace( 0, Dbg, "Cancelling a timer\n", 0);

                 //
                 // There was a timer on this read operation.  Attempt
                 // to cancel the operation.  If the cancel operation
                 // is successful, then we must cleanup after the operation.
                 // If it was unsuccessful the timer DPC will run, and
                 // will eventually cleanup.
                 //

                 timer = &workContext->Timer;

                 if (KeCancelTimer( timer ) ) {

                     //
                     // Release the reference to the FCB.
                     //

                     MsDereferenceFcb( workContext->Fcb );

                     //
                     // Free the memory from the work context, the timer,
                     // and the DPC.
                     //

                     ExFreePool( workContext );

                 }

             }

             oldIrp = MsRemoveDataQueueEntry( dataQueue, dataEntry );

             if (oldIrp != NULL) {

                 DebugTrace(0, Dbg, "Completing IRP %08lx\n", (ULONG)oldIrp );
                 MsCompleteRequest( oldIrp, STATUS_FILE_FORCED_CLOSED );

             }

        }

        //
        // Now cleanup all the CCB's on this FCB, to ensure that new
        // write IRP will not be processed.
        //

        MsAcquireCcbListLock();

        listEntry = Fcb->Specific.Fcb.CcbQueue.Flink;

        while( listEntry != &Fcb->Specific.Fcb.CcbQueue ) {

            ccb = (PCCB)CONTAINING_RECORD( listEntry, CCB, CcbLinks );

            ccb->Header.NodeState = NodeStateClosing;

            //
            // Get the next CCB on this FCB.
            //

            listEntry = listEntry->Flink;
        }

        MsReleaseCcbListLock();

        //
        // Cleanup the share access.
        //

        IoRemoveShareAccess( Fcb->FileObject, &Fcb->ShareAccess);

        //
        // Mark the FCB closing.
        //

        Fcb->Header.NodeState = NodeStateClosing;

   } finally {

        ASSERT (MsIsDataQueueEmpty(dataQueue));

        MsReleaseFcb( Fcb );
        DebugTrace(-1, Dbg, "MsCloseFcb -> %08lx\n", status);
    }

    //
    // Return to the caller.
    //

    return status;

}