Пример #1
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;
}
Пример #2
0
NTSTATUS
xixfs_CommonQueryVolumeInformation(
	IN PXIXFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS				RC = STATUS_SUCCESS;
	PIRP					pIrp = NULL;
	PIO_STACK_LOCATION		pIrpSp = NULL;
	PXIXFS_VCB				pVCB = NULL;
	PXIXFS_FCB				pFCB = NULL;
	PXIXFS_CCB				pCCB = NULL;
	PFILE_OBJECT				pFileObject = NULL;
	BOOLEAN					Wait = FALSE;
	uint32					BytesToReturn = 0;
	uint32					Length = 0;
	TYPE_OF_OPEN			TypeOfOpen = UnopenedFileObject;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
		("Enter xixfs_CommonQueryVolumeInformation \n"));

	ASSERT(pIrpContext);

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

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

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

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

    if (TypeOfOpen == UnopenedFileObject) {
		RC = STATUS_INVALID_PARAMETER;
        xixfs_CompleteRequest( pIrpContext, STATUS_INVALID_PARAMETER, 0 );
        return RC;
    }


	DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!VolumeInformation  pCCB(%p)\n", pCCB));

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


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




	if(!ExAcquireResourceSharedLite(&(pVCB->VCBResource), Wait)){
		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
					("PostRequest IrpContext(%p) Irp(%p)\n", pIrpContext, pIrp));
		RC = xixfs_PostRequest(pIrpContext, pIrp);
		return RC;
	}

	try{


		Length = pIrpSp->Parameters.QueryVolume.Length ;


		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
					 ("pIrpSp->Parameters.QueryVolume.FsInformationClass (0x%x)\n", 
					 pIrpSp->Parameters.QueryVolume.FsInformationClass));
	

		switch (pIrpSp->Parameters.QueryVolume.FsInformationClass) {

		case FileFsSizeInformation:
		{
	

			RC = xixfs_QueryFsSizeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsVolumeInformation:
		{

			RC = xixfs_QueryFsVolumeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsDeviceInformation:
		{

			RC = xixfs_QueryFsDeviceInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		case FileFsAttributeInformation:
		{

			RC = xixfs_QueryFsAttributeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn );
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}		
		case FileFsFullSizeInformation:
		{
			RC = xixfs_QueryFsFullSizeInfo(pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn);
			xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn);
			break;
		}
		default:
			DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
				("default Not supported Volume Info %ld\n",pIrpSp->Parameters.QueryVolume.FsInformationClass));
			RC = STATUS_INVALID_PARAMETER;
			xixfs_CompleteRequest(pIrpContext, RC, 0);
		break;
		 }

		

	}finally{
		ExReleaseResourceLite(&(pVCB->VCBResource));
	}
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT),
		("Exit xixfs_CommonQueryVolumeInformation \n"));
	return RC;	
}