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; }
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; }
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; }
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; }
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; }