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_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; }
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; }
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 XixFsdCommonDeviceControl( IN PXIFS_IRPCONTEXT pIrpContext ) { NTSTATUS RC = STATUS_SUCCESS; PIRP pIrp = NULL; PIO_STACK_LOCATION pIrpSp= NULL; PIO_STACK_LOCATION pNextIrpSp = NULL; PFILE_OBJECT PtrFileObject = NULL; PXIFS_FCB pFCB = NULL; PXIFS_CCB pCCB = NULL; PXIFS_VCB pVCB = NULL; BOOLEAN CompleteIrp = FALSE; ULONG IoControlCode = 0; void *BufferPointer = NULL; BOOLEAN Wait = FALSE; BOOLEAN PostRequest = FALSE; TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject; KEVENT WaitEvent; PVOID CompletionContext = NULL; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL, ("Enter XixFsdCommonDeviceControl .\n")); DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, ("!!!!Enter XixFsdCommonDeviceControl \n")); ASSERT(pIrpContext); ASSERT(pIrpContext->Irp); pIrp = pIrpContext->Irp; try { Wait = XifsdCheckFlagBoolean(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); if(!Wait){ PostRequest = TRUE; try_return(RC = STATUS_PENDING); } // First, get a pointer to the current I/O stack location pIrpSp = IoGetCurrentIrpStackLocation(pIrp); ASSERT(pIrpSp); PtrFileObject = pIrpSp->FileObject; ASSERT(PtrFileObject); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL, (" Decode File Object\n")); TypeOfOpen = XixFsdDecodeFileObject( PtrFileObject, &pFCB, &pCCB ); DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DEVCTL|DEBUG_TARGET_IRPCONTEXT), ("pIrpSp->Parameters.DeviceIoControl.IoControlCode(0x%02x) .\n", pIrpSp->Parameters.DeviceIoControl.IoControlCode)); if (TypeOfOpen == UserVolumeOpen) { pVCB = (PXIFS_VCB)(pFCB ->PtrVCB); ASSERT_VCB(pVCB); } else { DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("User Volume Open Not supported!!.\n")); RC = STATUS_INVALID_PARAMETER; XixFsdCompleteRequest(pIrpContext, RC, 0); try_return(RC); } switch(pIrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES: //DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES\n"); XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE); XixFsdFlusVolume(pIrpContext, pVCB); KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE ); CompletionContext = &WaitEvent; IoCopyCurrentIrpStackLocationToNext(pIrp ); IoSetCompletionRoutine(pIrp, XixFsdDevFlushAndHoldWriteCompletionRoutine, CompletionContext, TRUE, TRUE, TRUE ); break; default: IoSkipCurrentIrpStackLocation( pIrp ); /* IoCopyCurrentIrpStackLocationToNext(pIrp ); // Set a completion routine. IoSetCompletionRoutine(pIrp, XixFsdDevIoctlCompletion, NULL, TRUE, TRUE, TRUE); */ break; } // Send the request. RC = IoCallDriver(pVCB->TargetDeviceObject, pIrp); if(RC == STATUS_PENDING && CompletionContext){ //DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES2\n"); KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); RC = pIrp->IoStatus.Status; } if(CompletionContext) { /* DbgPrint("!!! IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES RC(0x%x) Status(0x%x) Information(%ld) \n", RC, pIrp->IoStatus.Status, pIrp->IoStatus.Information); */ XifsdReleaseVcb(TRUE, pVCB); XixFsdCompleteRequest(pIrpContext, RC, (uint32)pIrp->IoStatus.Information); }else{ XixFsdReleaseIrpContext(pIrpContext); } } finally { if (!(pIrpContext->IrpContextFlags & XIFSD_IRP_CONTEXT_EXCEPTION)) { ; } if(PostRequest ){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DEVCTL|DEBUG_TARGET_IRPCONTEXT), ("PostRequest pIrpCotnext(0x%x) pIrp(0x%x)\n", pIrpContext, pIrp)); RC = XixFsdPostRequest(pIrpContext, pIrp); } } DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_DEVCTL, ("Exit XixFsdCommonDeviceControl .\n")); return(RC); }