⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cleanup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
                        //
    
                        if (!FlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE) &&
                            (Fcb->Header.ValidDataLength.LowPart < Fcb->Header.FileSize.LowPart)) {
    
                            ULONG ValidDataLength;
    
                            ValidDataLength = Fcb->Header.ValidDataLength.LowPart;
    
                            if (ValidDataLength < Fcb->ValidDataToDisk) {
                                ValidDataLength = Fcb->ValidDataToDisk;
                            }
    
                            //
                            //  Recheck, VDD can be >= FS
                            //
                            
                            if (ValidDataLength < Fcb->Header.FileSize.LowPart) {
                                
                                try {

                                    (VOID)FatZeroData( IrpContext,
                                                       Vcb,
                                                       FileObject,
                                                       ValidDataLength,
                                                       Fcb->Header.FileSize.LowPart -
                                                       ValidDataLength );

                                    //
                                    //  Since we just zeroed this, we can now bump
                                    //  up VDL in the Fcb.
                                    //

                                    Fcb->ValidDataToDisk =
                                    Fcb->Header.ValidDataLength.LowPart =
                                    Fcb->Header.FileSize.LowPart;

                                    //
                                    //  We inform Cc of the motion so that the cache map is updated.
                                    //  This prevents optimized zero-page faults in case the cache
                                    //  structures are re-used for another handle before they are torn
                                    //  down by our soon-to-occur uninitialize. If they were, a noncached
                                    //  producer could write into the region we just zeroed and Cc would
                                    //  be none the wiser, then our async cached reader comes in and takes
                                    //  the optimized path, and we get bad (zero) data.
                                    //
                                    //  If this was memory mapped, we don't have to (can't) tell Cc, it'll
                                    //  figure it out when a cached handle is opened.
                                    //

                                    if (CcIsFileCached( FileObject )) {
                                        CcSetFileSizes( FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize );
                                    }

                                } except( FsRtlIsNtstatusExpected(GetExceptionCode()) ?
                                          EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) {

                                      FatResetExceptionState( IrpContext );
                                }
                            }
                        }
                    }
    
                    //
                    //  See if we are supposed to truncate the file on the last
                    //  close.  If we cannot wait we'll ship this off to the fsp
                    //
    
                    try {
    
                        if (FlagOn(Fcb->FcbState, FCB_STATE_TRUNCATE_ON_CLOSE)) {
    
                            DebugTrace(0, Dbg, "truncate file allocation\n", 0);
    
                            if (Vcb->VcbCondition == VcbGood) {
    
                                FatTruncateFileAllocation( IrpContext,
                                                           Fcb,
                                                           Fcb->Header.FileSize.LowPart );
                            }
    
                            //
                            //  We also have to get rid of the Cache Map because
                            //  this is the only way we have of trashing the
                            //  truncated pages.
                            //
    
                            LocalTruncateSize = Fcb->Header.FileSize;
                            TruncateSize = &LocalTruncateSize;
    
                            //
                            //  Mark the Fcb as having now been truncated, just incase
                            //  we have to reship this off to the fsp.
                            //
    
                            Fcb->FcbState &= ~FCB_STATE_TRUNCATE_ON_CLOSE;
                        }
    
                        //
                        //  Now check again if we are to delete the file and if
                        //  so then we remove the file from the disk.
                        //
    
                        if (FlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE) &&
                            Fcb->Header.AllocationSize.LowPart == 0) {
    
                            DebugTrace(0, Dbg, "Delete File\n", 0);
    
                            //
                            //  Now tunnel and delete the dirent
                            //
    
                            FatTunnelFcbOrDcb( Fcb, Ccb );
    
                            FatDeleteDirent( IrpContext, Fcb, &DeleteContext, TRUE );
    
                            //
                            //  Report that we have removed an entry.
                            //
    
                            FatNotifyReportChange( IrpContext,
                                                   Vcb,
                                                   Fcb,
                                                   FILE_NOTIFY_CHANGE_FILE_NAME,
                                                   FILE_ACTION_REMOVED );
                        }
    
                    } except( FsRtlIsNtstatusExpected(GetExceptionCode()) ?
                              EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) {
    
                          FatResetExceptionState( IrpContext );
                    }
    
                    if (FlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE)) {
    
                        //
                        //  Remove the entry from the splay table. This will
                        //  ensure that we will not collide with the Fcb if the
                        //  user wants to recreate the same file over again
                        //  before we get a close irp.
                        //
                        //  Note that we remove the name even if we couldn't
                        //  truncate the allocation and remove the dirent above.
                        //
    
                        FatRemoveNames( IrpContext, Fcb );
                    }
                }
            }
            
            //
            //  We've just finished everything associated with an unclean
            //  fcb so now decrement the unclean count before releasing
            //  the resource.
            //

            ASSERT( Fcb->UncleanCount != 0 );
            Fcb->UncleanCount -= 1;
            if (!FlagOn( FileObject->Flags, FO_CACHE_SUPPORTED )) {
                ASSERT( Fcb->NonCachedUncleanCount != 0 );
                Fcb->NonCachedUncleanCount -= 1;
            }

            //
            //  If this was the last cached open, and there are open
            //  non-cached handles, attempt a flush and purge operation
            //  to avoid cache coherency overhead from these non-cached
            //  handles later.  We ignore any I/O errors from the flush.
            //

            if (FlagOn( FileObject->Flags, FO_CACHE_SUPPORTED ) &&
                (Fcb->NonCachedUncleanCount != 0) &&
                (Fcb->NonCachedUncleanCount == Fcb->UncleanCount) &&
                (Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)) {

                CcFlushCache( &Fcb->NonPaged->SectionObjectPointers, NULL, 0, NULL );
            
                //
                //  Grab and release PagingIo to serialize ourselves with the lazy writer.
                //  This will work to ensure that all IO has completed on the cached
                //  data and we will succesfully tear away the cache section.
                //
                
                ExAcquireResourceExclusiveLite( Fcb->Header.PagingIoResource, TRUE);
                ExReleaseResourceLite( Fcb->Header.PagingIoResource );

                CcPurgeCacheSection( &Fcb->NonPaged->SectionObjectPointers,
                                     NULL,
                                     0,
                                     FALSE );
            }

            //
            //  If the file is invalid, hint to the cache that we should throw everything out.
            //
            
            if ( Fcb->FcbCondition == FcbBad ) {

                TruncateSize = &FatLargeZero;
            }

            //
            //  Cleanup the cache map
            //

            CcUninitializeCacheMap( FileObject, TruncateSize, NULL );

            break;

        default:

            FatBugCheck( TypeOfOpen, 0, 0 );
        }

        //
        //  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.
        //

        if (ShareAccess != NULL) {

            DebugTrace(0, Dbg, "Cleanup the Share access\n", 0);
            IoRemoveShareAccess( FileObject, ShareAccess );
        }

        if (TypeOfOpen == UserFileOpen) {

            //
            //  Coordinate the cleanup operation with the oplock state.
            //  Cleanup operations can always cleanup immediately.
            //

            FsRtlCheckOplock( &Fcb->Specific.Fcb.Oplock,
                              Irp,
                              IrpContext,
                              NULL,
                              NULL );

            Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
        }

        //
        //  First set the FO_CLEANUP_COMPLETE flag.
        //

        SetFlag( FileObject->Flags, FO_CLEANUP_COMPLETE );

        Status = STATUS_SUCCESS;

        //
        //  Now unpin any repinned Bcbs.
        //

        FatUnpinRepinnedBcbs( IrpContext );

        //
        //  If this was deferred flush media, flush the volume.
        //  We used to do this in lieu of write through for all removable
        //  media.
        //

        if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
            !FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED))  {

            //
            //  Flush the file.
            //

            if ((TypeOfOpen == UserFileOpen) && 
                FlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {

                Status = FatFlushFile( IrpContext, Fcb, Flush );
            }

            //
            //  If that worked ok,  then see if we should flush the FAT as well.
            //

            if (NT_SUCCESS(Status) && Fcb && !FatIsFat12( Vcb) && 
                FlagOn( Fcb->FcbState, FCB_STATE_FLUSH_FAT)) {

                Status = FatFlushFat( IrpContext, Vcb);
            }

            if (!NT_SUCCESS(Status)) {

                FatNormalizeAndRaiseStatus( IrpContext, Status );
            }
        }

    } finally {

        DebugUnwind( FatCommonCleanup );

        if (AcquiredFcb) { FatReleaseFcb( IrpContext, Fcb ); }
        if (AcquiredVcb) { FatReleaseVcb( IrpContext, Vcb ); }

        if (SendUnlockNotification) {
            
            FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK );
        }

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

        if (!AbnormalTermination()) {

            FatCompleteRequest( IrpContext, Irp, Status );
        }

        DebugTrace(-1, Dbg, "FatCommonCleanup -> %08lx\n", Status);
    }

    return Status;
}

VOID
FatAutoUnlock (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb
    )
{
    KIRQL SavedIrql;

    //
    //  Unlock the volume.
    //

    IoAcquireVpbSpinLock( &SavedIrql );

    ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED );

    Vcb->VcbState &= ~VCB_STATE_FLAG_LOCKED;
    Vcb->FileObjectWithVcbLocked = NULL;

    IoReleaseVpbSpinLock( SavedIrql );
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -