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; }
BOOLEAN xixfs_NLInsertNameLinkIgnoreCase ( IN PXIXFS_IRPCONTEXT IrpContext, IN PRTL_SPLAY_LINKS *RootNode, IN PXIXFS_LCB NameLink ) { FSRTL_COMPARISON_RESULT Comparison; PXIXFS_LCB Node; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Enter xixfs_NLInsertNameLink \n")); // // Check inputs. // ASSERT_IRPCONTEXT( IrpContext ); RtlInitializeSplayLinks( &NameLink->IgnoreCaseLinks ); // // If we are the first entry in the tree, just become the root. // if (*RootNode == NULL) { *RootNode = &NameLink->IgnoreCaseLinks; return TRUE; } Node = CONTAINING_RECORD( *RootNode, XIXFS_LCB, IgnoreCaseLinks ); while (TRUE) { // // Compare the prefix in the tree with the prefix we want // to insert. // Comparison = xixfs_FCBTLBFullCompareNames( IrpContext, &Node->IgnoreCaseFileName, &NameLink->IgnoreCaseFileName ); // // If we found the entry, return immediately. // if (Comparison == EqualTo) { return FALSE; } // // If the tree prefix is greater than the new prefix then // we go down the left subtree // if (Comparison == GreaterThan) { // // We want to go down the left subtree, first check to see // if we have a left subtree // if (RtlLeftChild( &Node->IgnoreCaseLinks ) == NULL) { // // there isn't a left child so we insert ourselves as the // new left child // RtlInsertAsLeftChild( &Node->IgnoreCaseLinks, &NameLink->IgnoreCaseLinks ); // // and exit the while loop // break; } else { // // there is a left child so simply go down that path, and // go back to the top of the loop // Node = CONTAINING_RECORD( RtlLeftChild( &Node->IgnoreCaseLinks ), XIXFS_LCB, IgnoreCaseLinks ); } } else { // // The tree prefix is either less than or a proper prefix // of the new string. We treat both cases as less than when // we do insert. So we want to go down the right subtree, // first check to see if we have a right subtree // if (RtlRightChild( &Node->IgnoreCaseLinks ) == NULL) { // // These isn't a right child so we insert ourselves as the // new right child // RtlInsertAsRightChild( &Node->IgnoreCaseLinks, &NameLink->IgnoreCaseLinks ); // // and exit the while loop // break; } else { // // there is a right child so simply go down that path, and // go back to the top of the loop // Node = CONTAINING_RECORD( RtlRightChild( &Node->IgnoreCaseLinks ), XIXFS_LCB, IgnoreCaseLinks ); } } } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Exit xixfs_NLInsertNameLink \n")); return TRUE; }
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; }
FSRTL_COMPARISON_RESULT xixfs_FCBTLBFullCompareNames ( IN PXIXFS_IRPCONTEXT IrpContext, IN PUNICODE_STRING NameA, IN PUNICODE_STRING NameB ) { ULONG i; ULONG MinLength = NameA->Length; FSRTL_COMPARISON_RESULT Result = LessThan; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Enter xixfs_FCBTLBFullCompareNames\n")); // // Check inputs. // ASSERT_IRPCONTEXT( IrpContext ); // // Figure out the minimum of the two lengths // if (NameA->Length > NameB->Length) { MinLength = NameB->Length; Result = GreaterThan; } else if (NameA->Length == NameB->Length) { Result = EqualTo; } // // Loop through looking at all of the characters in both strings // testing for equalilty, less than, and greater than // i = (ULONG) RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength ); if (i < MinLength) { // // We know the offset of the first character which is different. // return ((NameA->Buffer[ i / 2 ] < NameB->Buffer[ i / 2 ]) ? LessThan : GreaterThan); } // // The names match up to the length of the shorter string. // The shorter string lexically appears first. // DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Exit xixfs_FCBTLBFullCompareNames\n")); return Result; }
PXIXFS_LCB xixfs_FCBTLBInsertPrefix ( IN PXIXFS_IRPCONTEXT IrpContext, IN PXIXFS_FCB Fcb, IN PUNICODE_STRING Name, IN PXIXFS_FCB ParentFcb ) { PXIXFS_LCB Lcb; PRTL_SPLAY_LINKS *TreeRoot; PLIST_ENTRY ListLinks; PWCHAR NameBuffer; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Enter xixfs_FCBTLBInsertPrefix \n" )); // // Check inputs. // ASSERT_IRPCONTEXT( IrpContext ); ASSERT_FCB( Fcb ); ASSERT_EXCLUSIVE_FCB( Fcb ); ASSERT_EXCLUSIVE_FCB( ParentFcb ); ASSERT( ParentFcb->XixcoreFcb.FCBType == FCB_TYPE_DIR); // // It must be the case that an index Fcb is only referenced by a single index. Now // we walk the child's Lcb queue to insure that if any prefixes have already been // inserted, they all refer to the index Fcb we are linking to. This is the only way // we can detect directory cross-linkage. // if (Fcb->XixcoreFcb.FCBType == FCB_TYPE_DIR) { for (ListLinks = Fcb->ParentLcbQueue.Flink; ListLinks != &Fcb->ParentLcbQueue; ListLinks = ListLinks->Flink) { Lcb = CONTAINING_RECORD( ListLinks, XIXFS_LCB, ChildFcbLinks ); if (Lcb->ParentFcb != ParentFcb) { XifsdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); } } } // // Allocate space for the Lcb. // Lcb = xixfs_AllocateLCB(Name->Length); // // Initialize the name-based file attributes. // Lcb->FileAttributes = 0; // // Set up the filename in the Lcb. // RtlCopyMemory( Lcb->FileName.Buffer, Name->Buffer, Name->Length ); // // Capture the separate cases. // TreeRoot = &ParentFcb->Root; // // Insert the Lcb into the prefix tree. // if (!xixfs_NLInsertNameLink( IrpContext, TreeRoot, Lcb )) { // // This will very rarely occur. // xixfs_FreeLCB( Lcb ); Lcb = xixfs_NLFindNameLink( IrpContext, TreeRoot, Name ); if (Lcb == NULL) { // // Even worse. // XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } if(!XIXCORE_TEST_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET)){ XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } return Lcb; } // // Capture the separate cases. // TreeRoot = &ParentFcb->IgnoreCaseRoot; // // Set up the filename in the Lcb. // RtlDowncaseUnicodeString(&(Lcb->IgnoreCaseFileName), Name, FALSE); if(!xixfs_NLInsertNameLinkIgnoreCase( IrpContext, TreeRoot, Lcb )){ XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } XIXCORE_SET_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET); // // Link the Fcbs together through the Lcb. // Lcb->ParentFcb = ParentFcb; Lcb->ChildFcb = Fcb; InsertHeadList( &ParentFcb->ChildLcbQueue, &Lcb->ParentFcbLinks ); InsertHeadList( &Fcb->ParentLcbQueue, &Lcb->ChildFcbLinks ); // // Initialize the reference count. // Lcb->Reference = 0; //DbgPrint(" !!!Insert LCB FileName(%wZ) IgnoreFileName(%wZ) .\n", &Lcb->FileName, &Lcb->IgnoreCaseFileName); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Exit xixfs_FCBTLBInsertPrefix \n" )); return Lcb; }
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; }
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; }