Beispiel #1
0
NTSTATUS
XixFsdPnpCancelRemove(
    PXIFS_IRPCONTEXT	pIrpContext,
    PIRP				pIrp,
    PXIFS_VCB			pVCB
)
{
	NTSTATUS	RC = STATUS_SUCCESS;
	
	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Enter XixFsdPnpCancelRemove  \n"));



	ASSERT(pIrpContext);
	ASSERT(pIrp);
	ASSERT(pVCB);

	if(!XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE)){
		DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
				 ("XifsdPostRequest  IrpContext(%p) Irp(%p)\n", pIrpContext, pIrp ));
		RC = XixFsdPostRequest(pIrpContext, pIrp);
		return RC;
	}
	
	XifsdLockVcb(pIrpContext, pVCB);
	XifsdSetFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
	XifsdUnlockVcb(pIrpContext, pVCB);

	RC = XixFsdUnlockVolumeInternal(pIrpContext, pVCB, NULL);

	XifsdLockVcb(pIrpContext, pVCB);
	XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_PROCESSING_PNP);
	XifsdUnlockVcb(pIrpContext, pVCB);
	
	XifsdReleaseVcb(TRUE, pVCB);

	IoSkipCurrentIrpStackLocation( pIrp );

    RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp);
	
	pIrpContext->Irp = NULL;
	XixFsdCompleteRequest(pIrpContext, STATUS_SUCCESS, 0);
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
		("Exit XixFsdPnpCancelRemove  \n"));
	

	return RC;
}
Beispiel #2
0
NTSTATUS
xixfs_TryClose(
    IN BOOLEAN	CanWait,
    IN BOOLEAN	bUserReference,
    IN PXIXFS_FCB	pFCB
)
{
    PXIXFS_VCB		pVCB = NULL;
    NTSTATUS		RC = STATUS_SUCCESS;
    uint32			UserReference = 0;


    PAGED_CODE();

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

    if(bUserReference) {
        UserReference = 1;
    } else {
        UserReference = 0;
    }



    XifsdDecCloseCount(pFCB);



    if(!CanWait) {
        if(bUserReference) {
            XifsdLockVcb(TRUE, pVCB);

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


            XifsdDecRefCount(pFCB, 0, 1);
            /*
            DbgPrint("dec CCB user ref Count CCB with  VCB (%d/%d)  (%d/%d)\n",
            		 pVCB->VCBReference,
            		 pVCB->VCBUserReference,
            		 pFCB->FCBReference,
            		 pFCB->FCBUserReference);
            */

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

            XifsdUnlockVcb(TRUE, pVCB);
        }

        DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                   ("XifsdCloseFCB Fail Insert delete queue FCB Lotnumber(%I64d)\n", pFCB->XixcoreFcb.LotNumber));

        xixfs_InsertCloseQueue(pFCB);

        RC =  STATUS_UNSUCCESSFUL;
    } else {
        if(!xixfs_CloseFCB(CanWait, pVCB, pFCB, UserReference)) {
            if(bUserReference) {
                XifsdLockVcb(TRUE, pVCB);

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


                XifsdDecRefCount(pFCB, 0, 1);
                /*
                DbgPrint("dec CCB user ref Count CCB with  VCB (%d/%d)  (%d/%d)\n",
                		 pVCB->VCBReference,
                		 pVCB->VCBUserReference,
                		 pFCB->FCBReference,
                		 pFCB->FCBUserReference);
                */

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

                XifsdUnlockVcb(TRUE, pVCB);
            }

            DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB),
                       ("XifsdCloseFCB Fail Insert delete queue FCB Lotnumber(%I64d)\n", pFCB->XixcoreFcb.LotNumber));

            xixfs_InsertCloseQueue(pFCB);
            RC =  STATUS_UNSUCCESSFUL;
        }

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

    }

    return RC;
}
Beispiel #3
0
NTSTATUS
XixFsdCommonCleanUp(
	IN PXIFS_IRPCONTEXT pIrpContext
	)
{
	NTSTATUS		RC = STATUS_SUCCESS;
	PXIFS_FCB		pFCB = NULL;
	PXIFS_CCB		pCCB = NULL;
	PXIFS_VCB		pVCB = NULL;
	PFILE_OBJECT	pFileObject = NULL;	
	TYPE_OF_OPEN	TypeOfOpen = UnopenedFileObject;

	PIRP					pIrp = NULL;
	PIO_STACK_LOCATION		pIrpSp = NULL;
	KIRQL					SavedIrql;

	PXIFS_LCB	pLCB = NULL;
	PXIFS_FCB	pParentFCB = NULL;

	BOOLEAN					Wait = FALSE;
	BOOLEAN					VCBAcquired = FALSE;
	BOOLEAN					ParentFCBAcquired = FALSE;
	BOOLEAN					CanWait = FALSE;
	BOOLEAN					AttemptTeardown = FALSE;
	BOOLEAN					SendUnlockNotification = FALSE;

	PAGED_CODE();

	DebugTrace((DEBUG_LEVEL_TRACE), (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT), 
		("Enter XifsdCommonCleanUp pIrpContext(%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_TRACE, (DEBUG_TARGET_CLEANUP), 
					("CDO Device TargetDevide(%p).\n", DeviceObject));
			XixFsdCompleteRequest(pIrpContext,RC,0);
			return(RC);
		}

	}	



	if(pIrpContext->VCB == NULL){

		DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CLEANUP, 
					("pIrpContext->VCB == NULL.\n"));
		RC = STATUS_SUCCESS;
		XixFsdCompleteRequest(pIrpContext, RC, 0);
		return RC;
	}


	

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

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

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

	if(TypeOfOpen <= StreamFileOpen){
		DebugTrace((DEBUG_LEVEL_TRACE|DEBUG_LEVEL_INFO), DEBUG_TARGET_CLEANUP, 
					("TypeOfOpen <= StreamFileOpen.\n"));
		XixFsdCompleteRequest(pIrpContext, STATUS_SUCCESS, 0);
		return STATUS_SUCCESS;
	}


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

	
	if(CanWait == FALSE){
		DebugTrace((DEBUG_LEVEL_TRACE|DEBUG_LEVEL_INFO), (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_IRPCONTEXT), 
					("PostRequest IrpCxt(%p) Irp(%p)\n", pIrpContext, pIrp));
		RC = XixFsdPostRequest(pIrpContext, pIrp);
		return RC;
	}

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




	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE|DEBUG_TARGET_VCB), 
				("Acquire exclusive pVCB(%p) VCBResource(%p).\n", pVCB, &pVCB->VCBResource));	

	if((TypeOfOpen == UserVolumeOpen)
		&& XifsdCheckFlagBoolean(pFileObject->Flags, FO_FILE_MODIFIED))
	{
		XifsdAcquireVcbExclusive(CanWait, pVCB, FALSE);
		VCBAcquired = TRUE;		
	}


	XifsdAcquireFcbExclusive(CanWait, pFCB, FALSE);		


	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB), 
					("Acquire exclusive FCB(%p) FCBResource(%p).\n", pFCB, pFCB->FCBResource));

	
	XifsdSetFlag(pFileObject->Flags, FO_CLEANUP_COMPLETE);
	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLEANUP| DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB), 
					("Set File Object Flags(0x%x)\n", pFileObject->Flags));	



	//IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );

	try{
		switch(TypeOfOpen){
		case UserDirectoryOpen:
			
			if(XifsdCheckFlagBoolean(pCCB->CCBFlags, XIFSD_CCB_FLAG_NOFITY_SET))
			{
				DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("CompletionFilter Notify CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB));

				FsRtlNotifyCleanup(pVCB->NotifyIRPSync, &pVCB->NextNotifyIRP, pCCB);

				//DbgPrint("Notify CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB);

			}


			//DbgPrint("CleanUp (%wZ) pCCB(%p) pCCB->CCBFlags(%x)\n", &pFCB->FCBName, pCCB, pCCB->CCBFlags);


			DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, 
					("!!!!CleanUp (%wZ) pCCB(%p)\n", &pFCB->FCBName, pCCB));


			IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );
			break;
			
		case UserFileOpen:
			//
			//  Coordinate the cleanup operation with the oplock state.
			//  Oplock cleanup operations can always cleanup immediately so no
			//  need to check for STATUS_PENDING.
			//

			FsRtlCheckOplock( &pFCB->FCBOplock,
							  pIrp,
							  pIrpContext,
							  NULL,
							  NULL );

			//
			//  Unlock all outstanding file locks.
			//

			if (pFCB->FCBFileLock != NULL) {

				FsRtlFastUnlockAll( pFCB->FCBFileLock,
									pFileObject,
									IoGetRequestorProcess( pIrp ),
									NULL );
			}



			//
			//  Check the fast io state.
			//

			XifsdLockFcb( pIrpContext, pFCB );
			pFCB->IsFastIoPossible = XixFsdCheckFastIoPossible( pFCB );
			XifsdUnlockFcb( pIrpContext, pFCB );


			/*
			if((pFCB->HasLock != FCB_FILE_LOCK_HAS)
				&& (!XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_OPEN_WRITE))
				&& XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED) 
				&& (pFCB->FCBCleanup == 1)
			){
					if(pFCB->SectionObject.DataSectionObject != NULL) 
					{
						
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

						ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
						ExReleaseResourceLite( pFCB->PagingIoResource );
						
						
						CcPurgeCacheSection( &(pFCB->SectionObject),
														NULL,
														0,
														FALSE 
														);	
														
					}			
			
			}
			*/


			
			if(
				XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED) &&
				(pFCB->FcbNonCachedOpenCount > 1)	&&
				((pFCB->FcbNonCachedOpenCount + 1) ==  pFCB->FCBCleanup)
			)
			{
				if(pFCB->SectionObject.DataSectionObject != NULL) 
				{

					// changed by ILGU HONG for readonly 09052006
					if(!pFCB->PtrVCB->IsVolumeWriteProctected)
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);
					// changed by ILGU HONG for readonly end
					
					//DbgPrint("CcFlush  1 File(%wZ)\n", &pFCB->FCBFullPath);
					ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
					ExReleaseResourceLite( pFCB->PagingIoResource );


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

				}	
			}
			
			/*
			else if(pFCB->FCBCleanup == 1 ){
		
				if(XifsdCheckFlagBoolean(pFileObject->Flags, FO_CACHE_SUPPORTED)){
					if(pFCB->SectionObject.DataSectionObject != NULL) 
					{
						CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL);

						ExAcquireResourceSharedLite(pFCB->PagingIoResource, TRUE);
						ExReleaseResourceLite( pFCB->PagingIoResource );

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

					}
				}

				if(XifsdCheckFlagBoolean(pFCB->FCBFlags,XIFSD_FCB_MODIFIED_FILE)){
					XixFsdUpdateFCB(pFCB);
				}

			}
			*/

			IoRemoveShareAccess( pFileObject, &pFCB->FCBShareAccess );
			//
			//  Cleanup the cache map.
			//
			
			CcUninitializeCacheMap( pFileObject, NULL, NULL );
					
			

			break;
		case UserVolumeOpen:
			break;
		default:
			break;
		}

		


		if((TypeOfOpen == UserDirectoryOpen) || (TypeOfOpen == UserFileOpen)){

			if(pFCB->FCBCleanup == 1 ){
				if(XifsdCheckFlagBoolean(pFCB->FCBFlags,XIFSD_FCB_MODIFIED_FILE)){
					
					// changed by ILGU HONG for readonly 09052006
					if(!pFCB->PtrVCB->IsVolumeWriteProctected){

						XixFsdUpdateFCB(pFCB);

						if(pFCB->WriteStartOffset != -1){

							//DbgPrint("Set Update Information!!!\n");
							XixFsdSendFileChangeRC(
									TRUE,
									pVCB->HostMac, 
									pFCB->LotNumber, 
									pVCB->DiskId, 
									pVCB->PartitionId, 
									pFCB->FileSize.QuadPart, 
									pFCB->RealAllocationSize,
									pFCB->WriteStartOffset
							);
							
							pFCB->WriteStartOffset = -1;
						}
					}
					// changed by ILGU HONG for readonly end

				}


	


			}




			if(XifsdCheckFlagBoolean(pCCB->CCBFlags, XIFSD_CCB_FLAGS_DELETE_ON_CLOSE)){
				
				if(pFCB == pFCB->PtrVCB->RootDirFCB){
					XifsdClearFlag(pCCB->CCBFlags, XIFSD_CCB_FLAGS_DELETE_ON_CLOSE);
					XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
				}else{
					XifsdSetFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
				}
			}

	


			// changed by ILGU HONG for readonly 09082006
			if(XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE) && (!pFCB->PtrVCB->IsVolumeWriteProctected) ){
			// changed by ILGU HONG for readonly end
				if(pFCB->FCBCleanup == 1){
					
					//DbgPrint(" !!!Delete Entry From table (%wZ)  .\n", &pFCB->FCBFullPath);

					ASSERT_CCB(pCCB);
					pLCB = pCCB->PtrLCB;

					ASSERT_LCB(pLCB);

					pParentFCB = pLCB->ParentFcb;
					ASSERT_FCB(pParentFCB);					



  					pFCB->FileSize.QuadPart = 0;
					pFCB->ValidDataLength.QuadPart = 0;

					if(pFCB->FCBType == FCB_TYPE_FILE){
						
						XifsdReleaseFcb(TRUE, pFCB);
						XifsdAcquireFcbExclusive(TRUE, pParentFCB, FALSE);
						ParentFCBAcquired = TRUE;
						XifsdAcquireFcbExclusive(TRUE, pFCB, FALSE);
						RC = DeleteParentChild(pIrpContext, pParentFCB, &pLCB->FileName);
						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							//XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						XifsdClearFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_DELETE_ON_CLOSE);
						XifsdSetFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_LINK_IS_GONE);
						
						XixFsdRemovePrefix(TRUE, pLCB);

						//
						//  Now Decrement the reference counts for the parent and drop the Vcb.
						//
						XifsdLockVcb(pIrpContext,pVCB);
						DebugTrace( DEBUG_LEVEL_INFO, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdDecRefCount( pParentFCB, 1, 1 );

						DebugTrace( DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdUnlockVcb( pIrpContext, pVCB );
						


						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						

					}else {
						
						RC = XixFsReLoadFileFromFcb(pFCB);
						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail XixFsReLoadFileFromFcb (%wZ)\n", &pFCB->FCBName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						
						if(pFCB->ChildCount != 0){
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}

						XifsdReleaseFcb(TRUE, pFCB);
						XifsdAcquireFcbExclusive(TRUE, pParentFCB, FALSE);
						ParentFCBAcquired = TRUE;
						
						XifsdAcquireFcbExclusive(TRUE, pFCB, FALSE);

						RC = DeleteParentChild(pIrpContext, pParentFCB, &pLCB->FileName);

						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							//ifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						

						XifsdClearFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_DELETE_ON_CLOSE);
						XifsdSetFlag(pLCB->LCBFlags, XIFSD_LCB_STATE_LINK_IS_GONE);
						
						
						XixFsdRemovePrefix(TRUE, pLCB);

						//
						//  Now Decrement the reference counts for the parent and drop the Vcb.
						//
						XifsdLockVcb(pIrpContext,pVCB);
						DebugTrace( DEBUG_LEVEL_INFO, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdDecRefCount( pParentFCB, 1, 1 );

						DebugTrace( DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_FILEINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_REFCOUNT),
									("XifsdSetRenameInformation, PFcb (%I64d) Vcb %d/%d Fcb %d/%d\n", 
									pParentFCB->LotNumber,
									 pVCB->VCBReference,
									 pVCB->VCBUserReference,
									 pParentFCB->FCBReference,
									 pParentFCB->FCBUserReference ));

						XifsdUnlockVcb( pIrpContext, pVCB );

						
						if(!NT_SUCCESS(RC)){
							DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL,
								("Fail DeleteParentChild (%wZ)\n", &pLCB->FileName));
							
							XifsdClearFlag(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE);
							RC = STATUS_SUCCESS;
							goto pass_through;
						}
						

						
					}


			
					//XixFsdDeleteUpdateFCB(pFCB);

					XixFsdSendRenameLinkBC(
						TRUE,
						XIFS_SUBTYPE_FILE_DEL,
						pVCB->HostMac,
						pFCB->LotNumber,
						pVCB->DiskId,
						pVCB->PartitionId,
						pFCB->ParentLotNumber,
						0
					);

				}
			}
			

		}


pass_through:

		XifsdLockVcb(pIrpContext, pVCB);
		
		if(XifsdCheckFlagBoolean(pFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
		{
			ASSERT(pFCB->FcbNonCachedOpenCount > 0);
			pFCB->FcbNonCachedOpenCount --;
		}

		XifsdDecrementClenupCount(pFCB);


		DebugTrace(DEBUG_LEVEL_ALL, DEBUG_TARGET_ALL,
			("Cleanup  Name(%wZ) FCBLotNumber(%I64d) FCBCleanUp(%ld) VCBCleanup(%ld) pCCB(%p) FileObject(%p)\n", 
			&pFCB->FCBName,
			pFCB->LotNumber, 
			pFCB->FCBCleanup, 
			pVCB->VCBCleanup,
			pCCB,
			pFileObject
			));
			
		XifsdUnlockVcb( pIrpContext, pVCB );

		AttemptTeardown = (pVCB->VCBCleanup == 0 && pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_DISMOUNTED );
		
		if(pFileObject == pVCB->LockVolumeFileObject){
			ASSERT(XifsdCheckFlagBoolean(pVCB->VCBFlags, XIFSD_VCB_FLAGS_VOLUME_LOCKED));
			
			IoAcquireVpbSpinLock(&SavedIrql);
			XifsdClearFlag(pVCB->PtrVPB->Flags, VPB_LOCKED);
			IoReleaseVpbSpinLock( SavedIrql );
			
			XifsdClearFlag(pVCB->VCBFlags, XIFSD_VCB_FLAGS_VOLUME_LOCKED);
			pVCB->LockVolumeFileObject = NULL;
			SendUnlockNotification = TRUE;
			
		}

		

		/*
		if( (pFCB->FCBCleanup == 0) 
				&& (!XifsdCheckFlagBoolean(pFCB->FCBFlags, XIFSD_FCB_DELETE_ON_CLOSE)) ){

			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT| DEBUG_TARGET_ALL), 
				("CleanUp Release Lot Lock LotNumber(%ld)\n", pFCB->LotNumber));

			XifsdLotUnLock(pVCB, pVCB->TargetDeviceObject, pFCB->LotNumber);
			pFCB->HasLock = FCB_FILE_LOCK_INVALID;
		}
		*/

		//
		//  We must clean up the share access at this time, since we may not
		//  get a Close call for awhile if the file was mapped through this
		//  File Object.
		//

		


	}finally{

		XifsdReleaseFcb(pIrpContext, pFCB);

		if(ParentFCBAcquired) {
			XifsdReleaseFcb(TRUE,pParentFCB);
		}
		

        if (SendUnlockNotification) {

            FsRtlNotifyVolumeEvent( pFileObject, FSRTL_VOLUME_UNLOCK );
        }

  		if (VCBAcquired)  {

			XifsdReleaseVcb( pIrpContext, pVCB);
		}


	}



    if (AttemptTeardown) {
        XifsdAcquireVcbExclusive( CanWait, pVCB, FALSE );

        try {
            
            XixFsdPurgeVolume( pIrpContext, pVCB, FALSE );

        } finally {

            XifsdReleaseVcb( pIrpContext, pVCB );
        }
    }


    //
    //  If this is a normal termination then complete the request
    //

	DebugTrace((DEBUG_LEVEL_TRACE), (DEBUG_TARGET_CLEANUP|DEBUG_TARGET_IRPCONTEXT), 
		("Exit XifsdCommonCleanUp pIrpContext(%p)\n", pIrpContext));

    XixFsdCompleteRequest( pIrpContext, STATUS_SUCCESS, 0 );

    return STATUS_SUCCESS;
}
PXIXFS_LCB
xixfs_FCBTLBFindPrefix (
    IN PXIXFS_IRPCONTEXT IrpContext,
    IN OUT PXIXFS_FCB *CurrentFcb,
    IN OUT PUNICODE_STRING RemainingName,
	IN BOOLEAN	bIgnoreCase
    )
{
	UNICODE_STRING LocalRemainingName;
	UNICODE_STRING FinalName;
	
	PXIXFS_LCB	NameLink;
	PXIXFS_LCB	CurrentLcb = NULL;
	BOOLEAN		Waitable = FALSE;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB),
		("Enter xixfs_FCBTLBFindPrefix \n" ));   
	//
	//  Check inputs.
	//

	ASSERT_IRPCONTEXT( IrpContext );
	ASSERT_FCB( *CurrentFcb );
	ASSERT_EXCLUSIVE_FCB( *CurrentFcb );


	

	Waitable =  XIXCORE_TEST_FLAGS(IrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT);

	try{
		//
		//  Make a local copy of the input strings.
		//

		LocalRemainingName = *RemainingName;

		//
		//  Loop until we find the longest matching prefix.
		//

		while (TRUE) {

			//
			//  If there are no characters left or we are not at an IndexFcb then
			//  return immediately.
			//

			if ((LocalRemainingName.Length == 0) ||
				(XifsSafeNodeType( *CurrentFcb ) != XIFS_NODE_FCB)) {

				try_return(TRUE); 
				// return CurrentLcb;
			}

			if((*CurrentFcb)->XixcoreFcb.FCBType != FCB_TYPE_DIR){
				try_return(TRUE); 
				//return CurrentLcb;

			}

			//
			//  Split off the next component from the name.
			//

			FsRtlDissectName( LocalRemainingName,
								&FinalName,
								&LocalRemainingName);

			//
			//  Check if this name is in the splay tree for this Fcb.
			//


			if(bIgnoreCase){
				NameLink = xixfs_NLFindNameLinkIgnoreCase( IrpContext,
											&(*CurrentFcb)->IgnoreCaseRoot,
											&FinalName );
			}else{
				NameLink = xixfs_NLFindNameLink( IrpContext,
											&(*CurrentFcb)->Root,
											&FinalName );
			}



			//
			//  If we didn't find a match then exit.
			//

			if (NameLink == NULL) { 

				break;
			}



			//
			//
			//
			//if ( XIXCORE_TEST_FLAGS(NameLink->LCBFlags, 
			//	(XIFSD_LCB_STATE_LINK_IS_GONE)) )
			//{
			//	break;
			//}


			CurrentLcb = NameLink;

			//
			//  Update the caller's remaining name string to reflect the fact that we found
			//  a match.
			//

			*RemainingName = LocalRemainingName;

			//
			//  Move down to the next component in the tree.  Acquire without waiting.
			//  If this fails then lock the Fcb to reference this Fcb and then drop
			//  the parent and acquire the child.
			//

			ASSERT( NameLink->ParentFcb == *CurrentFcb );

			if (!XifsdAcquireFcbExclusive( Waitable, NameLink->ChildFcb, FALSE ))  
			{

				//
				//  If we can't wait then raise CANT_WAIT.
				//

				if ( Waitable) {

					XifsdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
				}

				XifsdLockVcb( IrpContext, IrpContext->VCB );
				NameLink->ChildFcb->FCBReference += 1;
				NameLink->Reference += 1;
				XifsdUnlockVcb( IrpContext, IrpContext->VCB );

				XifsdReleaseFcb( IrpContext, *CurrentFcb );
				XifsdAcquireFcbExclusive(  Waitable, NameLink->ChildFcb, FALSE );

				XifsdLockVcb( IrpContext, IrpContext->VCB );
				NameLink->ChildFcb->FCBReference -= 1;
				NameLink->Reference -= 1;
				XifsdUnlockVcb( IrpContext, IrpContext->VCB );

			} else {

				XifsdReleaseFcb( IrpContext, *CurrentFcb );
			}

			*CurrentFcb = NameLink->ChildFcb;
		}
	}finally{
		if(AbnormalTermination()){
			ExRaiseStatus(STATUS_CANT_WAIT);
		}
	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB),
		("Exit xixfs_FCBTLBFindPrefix \n" ));   
	return CurrentLcb;
}
Beispiel #5
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;
}
Beispiel #6
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;

}
VOID
xixfs_CleanupFlushVCB(
	IN PXIXFS_IRPCONTEXT pIrpContext,
	IN PXIXFS_VCB		pVCB,
	IN BOOLEAN			DisMountVCB
)
{

	

	//PAGED_CODE();

	ASSERT_IRPCONTEXT( pIrpContext );
	ASSERT_VCB( pVCB );

	ASSERT_EXCLUSIVE_XIFS_GDATA;
	ASSERT_EXCLUSIVE_VCB(pVCB);

	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("xixfs_CleanupFlushVCB Status(%ld).\n", pVCB->VCBState));




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


	XifsdLockVcb( pIrpContext, pVCB );

	XIXCORE_SET_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);

	if(DisMountVCB){
		if(pVCB->VolumeDasdFCB != NULL){
			pVCB->VolumeDasdFCB->FCBReference -= 1;
			pVCB->VolumeDasdFCB->FCBUserReference -= 1;
		}

		
		if(pVCB->MetaFCB != NULL){
			pVCB->MetaFCB->FCBReference -=1;
			pVCB->MetaFCB->FCBUserReference -= 1;
		}


		if(pVCB->RootDirFCB != NULL){
			pVCB->RootDirFCB->FCBReference -=1;
			pVCB->RootDirFCB->FCBUserReference -= 1;
		}
	}

	XifsdUnlockVcb(pIrpContext, pVCB);

	xixfs_PurgeVolume(pIrpContext, pVCB, DisMountVCB);

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


	if(DisMountVCB){
		// Added by ILGU HONG
		XifsdReleaseVcb(TRUE, pVCB);
		
		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ),
					 ("VCB %d/%d \n", pVCB->VCBReference, pVCB->VCBUserReference));		


		CcWaitForCurrentLazyWriterActivity();

		XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);
			
		xixfs_RealCloseFCB((PVOID)pVCB);
	}

	XifsdLockVcb( pIrpContext, pVCB );
	XIXCORE_CLEAR_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);
	XifsdUnlockVcb(pIrpContext, pVCB);


	// Added by ILGU HONG END
	if(DisMountVCB){

		// changed by ILGU HONG for readonly 09052006
		if(!pVCB->XixcoreVcb.IsVolumeWriteProtected){

			LARGE_INTEGER	TimeOut;
			
			//
			//	Stop Meta Update process
			//

			KeSetEvent(&pVCB->VCBUmountEvent, 0, FALSE);

			TimeOut.QuadPart = - DEFAULT_XIFS_UMOUNTWAIT;
			KeWaitForSingleObject(&pVCB->VCBStopOkEvent, Executive, KernelMode, FALSE, &TimeOut);		
			


			xixcore_DeregisterHost(&pVCB->XixcoreVcb);
			
			//	Added by ILGU HONG for 08312006
			if(pVCB->NdasVolBacl_Id){
				xixfs_RemoveUserBacl(pVCB->TargetDeviceObject, pVCB->NdasVolBacl_Id);
			}
			
			//	Added by ILGU HONG End	
		}
		// changed by ILGU HONG for readonly end
	}

	return;
}
NTSTATUS
xixfs_FlusVolume(
	IN PXIXFS_IRPCONTEXT IrpContext,
	IN PXIXFS_VCB		pVCB
)
{
	PVOID RestartKey = NULL;
	PXIXFS_FCB ThisFcb = NULL;
	PXIXFS_FCB NextFcb = NULL;
	
	BOOLEAN RemovedFcb = FALSE;
	BOOLEAN	CanWait = FALSE;
	uint32	lockedVcbValue = 0;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter  xixfs_FlusVolume\n"));

	ASSERT_EXCLUSIVE_VCB(pVCB);

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

	xixfs_RealCloseFCB(pVCB);

	while (TRUE) {
		
		XifsdLockVcb( IrpContext, pVCB );
		NextFcb = xixfs_FCBTLBGetNextEntry(pVCB, &RestartKey );

		//
		//  Reference the NextFcb if present.
		//

		if (NextFcb != NULL) {

			NextFcb->FCBReference += 1;
		}

		//
		//  If the last Fcb is present then decrement reference count and call teardown
		//  to see if it should be removed.
		//

		if (ThisFcb != NULL) {

			ThisFcb->FCBReference -= 1;

			XifsdUnlockVcb( IrpContext, pVCB );

		} else {

			XifsdUnlockVcb( IrpContext, pVCB );
		}

		//
		//  Break out of the loop if no more Fcb's.
		//

		if (NextFcb == NULL) {

			break;
		}

		//
		//  Move to the next Fcb.
		//

		ThisFcb = NextFcb;

		//
		//  If there is a image section then see if that can be closed.
		//

		if(ThisFcb->XixcoreFcb.FCBType == FCB_TYPE_FILE){
			
			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("XifsdPurgeVolume FCB(%I64d) \n", 
						 ThisFcb->XixcoreFcb.LotNumber));
			
			XifsdAcquireFcbExclusive(TRUE, ThisFcb, FALSE);
			//ExAcquireResourceShared(ThisFcb->PagingIoResource, TRUE);


			if(XIXCORE_TEST_FLAGS(ThisFcb->XixcoreFcb.FCBFlags, XIXCORE_FCB_CACHED_FILE)){

				// Added by ILGU HONG for readonly 09052006
				if(!ThisFcb->PtrVCB->XixcoreVcb.IsVolumeWriteProtected){
					CcFlushCache(&ThisFcb->SectionObject, NULL, 0, NULL);
				}
				// Added by ILGU HONG for readonly end
				
			}
			//ExReleaseResource(ThisFcb->PagingIoResource);
			XifsdReleaseFcb(TRUE, ThisFcb);
		}

	}

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit  xixfs_FlusVolume\n"));

	return STATUS_SUCCESS;
}
NTSTATUS
xixfs_PurgeVolume(
	IN PXIXFS_IRPCONTEXT IrpContext,
	IN PXIXFS_VCB		pVCB,
	IN BOOLEAN			DismountForce
)
{
	NTSTATUS Status = STATUS_SUCCESS;

	PVOID RestartKey = NULL;
	PXIXFS_FCB ThisFcb = NULL;
	PXIXFS_FCB NextFcb = NULL;
	
	BOOLEAN RemovedFcb = FALSE;
	BOOLEAN	CanWait = FALSE;
	uint32	lockedVcbValue = 0;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Enter  xixfs_PurgeVolume\n"));

	ASSERT_EXCLUSIVE_VCB(pVCB);

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



	
	
	//
	//  Force any remaining Fcb's in the delayed close queue to be closed.
	//
	
	xixfs_RealCloseFCB(pVCB);

	//
	//  Acquire the global file resource.
	//

	//XifsdAcquireAllFiles( CanWait, pVCB );

	//
	//  Loop through each Fcb in the Fcb Table and perform the flush.
	//

	while (TRUE) {

		//
		//  Lock the Vcb to lookup the next Fcb.
		//

		XifsdLockVcb( IrpContext, pVCB );
		NextFcb = xixfs_FCBTLBGetNextEntry(pVCB, &RestartKey );

		//
		//  Reference the NextFcb if present.
		//

		if (NextFcb != NULL) {

			NextFcb->FCBReference += 1;
		}

		//
		//  If the last Fcb is present then decrement reference count and call teardown
		//  to see if it should be removed.
		//

		if (ThisFcb != NULL) {

			ThisFcb->FCBReference -= 1;

			XifsdUnlockVcb( IrpContext, pVCB );


			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_PNP|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO|DEBUG_TARGET_REFCOUNT),
					 ("XifsdPurgeVolume FCB(%I64d) VCB %d/%d FCB %d/%d\n",
					 ThisFcb->XixcoreFcb.LotNumber,
					 pVCB->VCBReference,
					 pVCB->VCBUserReference,
					 ThisFcb->FCBReference,
					 ThisFcb->FCBUserReference ));


			DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_PNP|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT,
				("XifsdPurgeVolume FCBLotNumber(%I64d) FCBCleanUp(%ld) VCBCleanup(%ld)\n", 
				ThisFcb->XixcoreFcb.LotNumber, 
				ThisFcb->FCBCleanup, 
				pVCB->VCBCleanup));
			

			xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb );

		} else {

			XifsdUnlockVcb( IrpContext, pVCB );
		}

		//
		//  Break out of the loop if no more Fcb's.
		//

		if (NextFcb == NULL) {

			break;
		}

		//
		//  Move to the next Fcb.
		//

		ThisFcb = NextFcb;

		//
		//  If there is a image section then see if that can be closed.
		//

		if(ThisFcb->XixcoreFcb.FCBType == FCB_TYPE_FILE){
			
			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("XifsdPurgeVolume FCB(%I64d) \n", 
						 ThisFcb->XixcoreFcb.LotNumber));
			
			XifsdAcquireFcbExclusive(TRUE, ThisFcb, FALSE);

			
			//	Added by ILGU HONG for readonly 09052006
			if(!ThisFcb->PtrVCB->XixcoreVcb.IsVolumeWriteProtected){
				if (ThisFcb->SectionObject.ImageSectionObject != NULL) {

					MmFlushImageSection( &ThisFcb->SectionObject, MmFlushForWrite );
				}

				//
				//  If there is a data section then purge this.  If there is an image
				//  section then we won't be able to.  Remember this if it is our first
				//  error.
				//

				
				CcFlushCache(&ThisFcb->SectionObject, NULL, 0, NULL);
				//DbgPrint("CcFlush  3 File(%wZ)\n", &ThisFcb->FCBFullPath);
			}
			//	Added by ILGU HONG for readonly end


			
			ExAcquireResourceSharedLite(ThisFcb->PagingIoResource, TRUE);
			ExReleaseResourceLite( ThisFcb->PagingIoResource );

			
			if ((ThisFcb->SectionObject.DataSectionObject != NULL) &&
				!CcPurgeCacheSection( &ThisFcb->SectionObject,
									   NULL,
									   0,
									   FALSE ) &&
				(Status == STATUS_SUCCESS)) {

				Status = STATUS_UNABLE_TO_DELETE_SECTION;
			}
			
			

			XifsdReleaseFcb(TRUE, ThisFcb);
		}
		//
		//  Dereference the internal stream if dismounting.
		//

		if (DismountForce &&
			(ThisFcb->XixcoreFcb.FCBType  != FCB_TYPE_FILE) &&
			(ThisFcb->XixcoreFcb.FCBType != FCB_TYPE_DIR)	&&
			(ThisFcb->FileObject != NULL)) {

			xixfs_DeleteInternalStream( CanWait, ThisFcb );
		}
	}

	//
	//  Now look at the Root Index, Metadata, Volume Dasd and VAT Fcbs.
	//  Note that we usually hit the Root Index in the loop above, but
	//  it is possible miss it if it didn't get into the Fcb table in the
	//  first place!
	//


	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("xixfs_PurgeVolume DismountFore (%s)\n", ((DismountForce)?"TRUE":"FALSE")));


	if (DismountForce) {




		if (pVCB->RootDirFCB != NULL) {
			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
				("Deal with RootFCB \n"));


			ThisFcb = pVCB->RootDirFCB;
			InterlockedIncrement( &ThisFcb->FCBReference );

			if ((ThisFcb->SectionObject.DataSectionObject != NULL) &&
				!CcPurgeCacheSection( &ThisFcb->SectionObject,
									   NULL,
									   0,
									   FALSE ) &&
				(Status == STATUS_SUCCESS)) {

				Status = STATUS_UNABLE_TO_DELETE_SECTION;
			}


			InterlockedDecrement( &ThisFcb->FCBReference );
/*
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
						 ("pVCB->RootDirFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n",
						 ThisFcb->LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));
			
			XifsdLockVcb(IrpContext, pVCB);
			XifsdDecRefCount(ThisFcb, 1, 1);
			XifsdUnlockVcb(IrpContext, pVCB);
*/	
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("pVCB->RootDirFCB FCB(%I64d)  VCB %d/%d FCB %d/%d\n",
						 ThisFcb->XixcoreFcb.LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));

			xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb );
			
		}
    
		if (pVCB->MetaFCB != NULL) {

			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
				("Deal with pVCB->MetaFCB \n"));

			ThisFcb = pVCB->MetaFCB;
			InterlockedIncrement( &ThisFcb->FCBReference );

			if ((ThisFcb->SectionObject.DataSectionObject != NULL) &&
				!CcPurgeCacheSection( &ThisFcb->SectionObject,
									   NULL,
									   0,
									   FALSE ) &&
				(Status == STATUS_SUCCESS)) {

				Status = STATUS_UNABLE_TO_DELETE_SECTION;
			}

			
			xixfs_DeleteInternalStream( CanWait, ThisFcb );

			InterlockedDecrement( &ThisFcb->FCBReference );

/*			
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("pVCB->MetaFCB FCB(%I64d)  VCB %d/%d FCB %d/%d\n",
						 ThisFcb->LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));

			XifsdLockVcb(IrpContext, pVCB);
			XifsdDecRefCount(ThisFcb, 1, 1);
			XifsdUnlockVcb(IrpContext, pVCB);
*/
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("pVCB->MetaFCB FCB(%I64d)  VCB %d/%d FCB %d/%d\n",
						 ThisFcb->XixcoreFcb.LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));



			xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb );
			
			
			
		}

		if (pVCB->VolumeDasdFCB != NULL) {
			DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
				("Deal with pVCB->VolumeDasdFCB \n"));

			ThisFcb = pVCB->VolumeDasdFCB;
			InterlockedIncrement( &ThisFcb->FCBReference );

			if ((ThisFcb->SectionObject.DataSectionObject != NULL) &&
				!CcPurgeCacheSection( &ThisFcb->SectionObject,
									   NULL,
									   0,
									   FALSE ) &&
				(Status == STATUS_SUCCESS)) {

				Status = STATUS_UNABLE_TO_DELETE_SECTION;
			}
			
			xixfs_DeleteInternalStream( CanWait, ThisFcb );

			InterlockedDecrement( &ThisFcb->FCBReference );
/*
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("pVCB->VolumeDasdFCB FCB(%I64d)  VCB %d/%d FCB %d/%d\n",
						 ThisFcb->LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));

			
			XifsdLockVcb(IrpContext, pVCB);
			XifsdDecRefCount(ThisFcb, 1, 1);
			XifsdUnlockVcb(IrpContext, pVCB);
*/			
			DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), 
						 ("pVCB->VolumeDasdFCB FCB(%I64d)  VCB %d/%d FCB %d/%d\n",
						 ThisFcb->XixcoreFcb.LotNumber,
						 pVCB->VCBReference,
						 pVCB->VCBUserReference,
						 ThisFcb->FCBReference,
						 ThisFcb->FCBUserReference ));	
			

			
			xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb );
			
		}
	}

	//
	//  Release all of the files.
	//

	//XifsdReleaseAllFiles( CanWait, pVCB );
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO),
		("Exit  xixfs_PurgeVolume\n"));
	return Status;
}