예제 #1
0
NTSTATUS
XixFsdPnpQueryRemove (
    PXIFS_IRPCONTEXT	pIrpContext,
    PIRP				pIrp,
    PXIFS_VCB			pVCB
)
{
	NTSTATUS	RC = STATUS_SUCCESS;
	KEVENT		Event;
	BOOLEAN		IsPresentVCB = FALSE;
	
	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Enter XixFsdPnpQueryRemove  \n"));
	
	
	ASSERT_IRPCONTEXT(pIrpContext);
	ASSERT(pIrp);
	ASSERT_VCB(pVCB);

	

	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("1 VCB->PtrVPB->ReferenceCount %d \n", 
						 pVCB->PtrVPB->ReferenceCount));



	XifsdAcquireGData(pIrpContext);
	XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);

	XifsdLockVcb(pIrpContext, pVCB);
	XifsdSetFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
	XifsdUnlockVcb(pIrpContext, pVCB);


	IsPresentVCB = TRUE;
	RC = XixFsdLockVolumeInternal(pIrpContext, pVCB, NULL);
	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("2 VCB->PtrVPB->ReferenceCount %d \n", 
						 pVCB->PtrVPB->ReferenceCount));
	


	if(NT_SUCCESS(RC)){
		
		//
		//	Release System Resource
		//

		XixFsdCleanupFlushVCB(pIrpContext, pVCB, TRUE);

		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("XixFsdPnpQueryRemove Forward IRP to low stack  .\n"));

		IoCopyCurrentIrpStackLocationToNext( pIrp );
		
		KeInitializeEvent( &Event, NotificationEvent, FALSE );
		IoSetCompletionRoutine( pIrp,
								XixFsdPnpCompletionRoutine,
								&Event,
								TRUE,
								TRUE,
								TRUE );

		//
		//  Send the request and wait.
		//

		RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);

		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("XixFsdPnpQueryRemove Forward IRP's result(0x%x)  .\n", RC));

		if (RC == STATUS_PENDING) {

			KeWaitForSingleObject( &Event,
								   Executive,
								   KernelMode,
								   FALSE,
								   NULL );

			RC = pIrp->IoStatus.Status;
		}

		if(NT_SUCCESS(RC)){

			IsPresentVCB = XixFsdCheckForDismount(pIrpContext, pVCB, TRUE);
			ASSERT(!IsPresentVCB || (pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_DISMOUNT_PROGRESS));
		}
	}

	
	ASSERT( !(NT_SUCCESS(RC) && IsPresentVCB && pVCB->VCBReference != 0) );

	if(IsPresentVCB){
		XifsdLockVcb(pIrpContext, pVCB);
		XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
		XifsdUnlockVcb(pIrpContext, pVCB);

		XifsdReleaseVcb(TRUE, pVCB);
	}

	XifsdReleaseGData(pIrpContext);
	XixFsdCompleteRequest(pIrpContext, RC, 0);

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Exit XifsdPnpQueryRemove  \n"));

	return RC;
}
예제 #2
0
NTSTATUS
xixfs_CommonClose(
    IN PXIXFS_IRPCONTEXT pIrpContext
)
{
    NTSTATUS				RC = STATUS_SUCCESS;
    PXIXFS_FCB				pFCB = NULL;
    PXIXFS_CCB				pCCB = NULL;
    PXIXFS_VCB				pVCB = NULL;
    PFILE_OBJECT			pFileObject = NULL;
    PIRP					pIrp = NULL;
    PIO_STACK_LOCATION		pIrpSp = NULL;
    BOOLEAN					OpenVCB = FALSE;
    BOOLEAN					PotentialVCBUnmount = FALSE;
    BOOLEAN					CanWait = FALSE;
    BOOLEAN					ForceDismount = FALSE;
    BOOLEAN					bUserReference = FALSE;
    TYPE_OF_OPEN			TypeOfOpen = UnopenedFileObject;
    BOOLEAN					bVcbAcq = FALSE;

    PAGED_CODE();
    DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
               ("Enter xixfs_CommonClose IrpContext(%p)\n", pIrpContext));



    ASSERT_IRPCONTEXT(pIrpContext);
    pIrp = pIrpContext->Irp;
    ASSERT(pIrp);


    // check if open request is releated to file system CDO
    {
        PDEVICE_OBJECT	DeviceObject = pIrpContext->TargetDeviceObject;
        ASSERT(DeviceObject);

        if (DeviceObject == XiGlobalData.XifsControlDeviceObject) {
            RC = STATUS_SUCCESS;
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                       ("CDO Device Close DevObj(%p).\n", DeviceObject));
            xixfs_CompleteRequest(pIrpContext,RC,0);
            return(RC);
        }

    }

    if(pIrpContext->VCB == NULL) {

        DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_CLOSE,
                   ("pIrpContext->VCB == NULL.\n"));
        RC = STATUS_SUCCESS;
        xixfs_CompleteRequest(pIrpContext, RC, 0);
        return RC;
    }


    CanWait = XIXCORE_TEST_FLAGS(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);

    pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
    ASSERT(pIrpSp);

    pFileObject = pIrpSp->FileObject;
    ASSERT(pFileObject);

    TypeOfOpen = xixfs_DecodeFileObject(pFileObject, &pFCB, &pCCB);





    if(TypeOfOpen == UnopenedFileObject) {
        DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                   ("TypeOfOpen <= StreamFileOpen.\n"));
        xixfs_CompleteRequest(pIrpContext, STATUS_SUCCESS, 0);
        return STATUS_SUCCESS;
    }


    if(TypeOfOpen == UserVolumeOpen) {
        ForceDismount = XIXCORE_TEST_FLAGS( pCCB->CCBFlags, XIXFSD_CCB_DISMOUNT_ON_CLOSE);
        if(ForceDismount) {
            if(!CanWait) {
                DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                           ("Force Dismount with Non Waitable Context.\n"));

                RC = xixfs_PostRequest(pIrpContext, pIrp);
                return RC;
            }
        }
    }


    DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL,
               ("!!!!Close  pCCB(%p) FileObject(%p)\n", pCCB, pFileObject));


    ASSERT_FCB(pFCB);
    pVCB = pFCB->PtrVCB;
    ASSERT_VCB(pVCB);

    if( (pVCB->VCBCleanup == 0)
            && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED) )
    {
        if(!CanWait) {
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
                       ("Force Dismount with Non Waitable Context.\n"));

            RC = xixfs_PostRequest(pIrpContext, pIrp);
            return RC;
        }
    }




    //
    //  Clean up any CCB associated with this open.
    //

    try {




        if( ((TypeOfOpen == UserDirectoryOpen) || (TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserVolumeOpen))
                && (pCCB != NULL)
          ) {
            bUserReference = TRUE;
            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_CCB),
                       ("XifsdCommonClose Delete CCB (%x)\n", pCCB));

            // Test
            //XifsdLockFcb(NULL, pFCB);
            //RemoveEntryList(&pCCB->LinkToFCB);
            //XifsdUnlockFcb(NULL, pFCB);

            xixfs_FreeCCB( pCCB );
        }




        DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB),
                   ("XifsdCommonClose GenINFO Fcb LotNumber(%I64d)  TypeOfOpen (%ld) Fcb %d/%d  Vcb %d/%d \n",
                    pFCB->XixcoreFcb.LotNumber,
                    TypeOfOpen,
                    pFCB->FCBReference,
                    pFCB->FCBUserReference,
                    pVCB->VCBReference,
                    pVCB->VCBUserReference));




        /*
        if(CanWait){
        	if(TypeOfOpen == UserFileOpen){

        		if(pFCB->FCBCleanup == 0){
        			if(pFCB->SectionObject.DataSectionObject != NULL)
        			{
        				CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

        				CcPurgeCacheSection( &(pFCB->SectionObject),
        													NULL,
        													0,
        													FALSE
        													);
        			}


        			if(XIXCORE_TEST_FLAGS(pFCB->FCBFlags,XIXCORE_FCB_MODIFIED_FILE)){
        				xixfs_LastUpdateFileFromFCB(pFCB);

        			}
        		}
        	}
        }
        */


        if((pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_MOUNTED)
                && ((TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserDirectoryOpen))
                && (pFCB != pVCB->RootDirFCB))
        {

            DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                       ("XifsdCommonClose Destroy FCB (%x)\n", pFCB));

            DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB),
                       ("XifsdCommonClose, Fcb %08x  Vcb %d/%d Fcb %d/%d\n", pFCB,
                        pVCB->VCBReference,
                        pVCB->VCBUserReference,
                        pFCB->FCBReference,
                        pFCB->FCBUserReference ));

            xixfs_TryClose(CanWait, bUserReference, pFCB);

            RC = STATUS_SUCCESS;
            try_return(RC);


        } else {

            if( ((pVCB->VCBCleanup == 0) || ForceDismount)
                    && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED))
            {


                if(ForceDismount) {
                    FsRtlNotifyVolumeEvent(pFileObject, FSRTL_VOLUME_DISMOUNT);

                }

                if( ((pVCB->VCBCleanup == 0) || ForceDismount)
                        && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED))
                {

                    PotentialVCBUnmount = TRUE;
                    if(bVcbAcq)XifsdReleaseVcb(TRUE,pVCB);
                    XifsdAcquireGData(pIrpContext);

                    DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_RESOURCE),
                               ("XifsdCommonClose Acquire exclusive GData(%p)\n", &XiGlobalData.DataResource));

                    bVcbAcq = XifsdAcquireVcbExclusive(TRUE,pVCB, FALSE);

                    DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_VCB|DEBUG_TARGET_RESOURCE),
                               ("XifsdCommonClose Acquire exclusive VCBResource(%p)\n", pVCB->VCBResource));
                }

            }



            if(PotentialVCBUnmount && bVcbAcq) {
                if(!xixfs_CheckForDismount(pIrpContext, pVCB, TRUE)) {
                    bVcbAcq = FALSE;
                    RC = STATUS_SUCCESS;
                    try_return(RC);

                }
            }

            RC = xixfs_TryClose(CanWait, bUserReference, pFCB);

            if(NT_SUCCESS(RC)) {
                if(PotentialVCBUnmount && bVcbAcq) {
                    if(!xixfs_CheckForDismount(pIrpContext, pVCB, FALSE)) {
                        bVcbAcq = FALSE;
                        RC = STATUS_SUCCESS;
                        try_return(RC);

                    }
                }
            }

            RC = STATUS_SUCCESS;

        }


        ;
    }
    finally{
        if(bVcbAcq) {
            XifsdReleaseVcb(TRUE, pVCB);
        }

        if(PotentialVCBUnmount) {
            XifsdReleaseGData(pIrpContext);
            PotentialVCBUnmount = FALSE;
        }

    }

    xixfs_CompleteRequest(pIrpContext, RC, 0);

    DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT),
               ("Exit xixfs_CommonClose \n"));
    return RC;
}
예제 #3
0
NTSTATUS
XixFsdPnpSurpriseRemove (
    PXIFS_IRPCONTEXT	pIrpContext,
    PIRP				pIrp,
    PXIFS_VCB			pVCB
)
{
	NTSTATUS	RC = STATUS_SUCCESS;
	KEVENT		Event;
	BOOLEAN		IsPresentVCB = FALSE;
	
	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Enter XixFsdPnpSurpriseRemove  \n"));
	
	ASSERT(pIrpContext);
	ASSERT(pIrp);
	ASSERT(pVCB);

	XifsdAcquireGData(pIrpContext);
	XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);
	


	XifsdLockVcb(pIrpContext, pVCB);

	XifsdSetFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
	
	if(pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_DISMOUNT_PROGRESS){
		pVCB->VCBState = XIFSD_VCB_STATE_VOLUME_INVALID;
	}
	XifsdUnlockVcb(pIrpContext, pVCB);
	
	//
	//	Release System Resource
	//

	XixFsdCleanupFlushVCB(pIrpContext, pVCB, TRUE);


	IoCopyCurrentIrpStackLocationToNext( pIrp );
	
	KeInitializeEvent( &Event, NotificationEvent, FALSE );
	IoSetCompletionRoutine( pIrp,
							XixFsdPnpCompletionRoutine,
							&Event,
							TRUE,
							TRUE,
							TRUE );

	//
	//  Send the request and wait.
	//

	RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);

	if (RC == STATUS_PENDING) {

		KeWaitForSingleObject( &Event,
							   Executive,
							   KernelMode,
							   FALSE,
							   NULL );

		RC = pIrp->IoStatus.Status;
	}


	IsPresentVCB = XixFsdCheckForDismount(pIrpContext, pVCB, TRUE);
	
	if(IsPresentVCB){
		XifsdLockVcb(pIrpContext, pVCB);
		XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
		XifsdUnlockVcb(pIrpContext, pVCB);

		XifsdReleaseVcb(TRUE, pVCB);
	}

	XifsdReleaseGData(pIrpContext);
	XixFsdCompleteRequest(pIrpContext, RC, 0);

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Exit XixFsdPnpSurpriseRemove  \n"));
	return RC;

}