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

📄 cleanup.c

📁 一个windows 文件系统驱动源码
💻 C
字号:
/*
 * COPYRIGHT:        See COPYRIGHT.TXT
 * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
 * FILE:             cleanup.c
 * PROGRAMMER:       Matt Wu <mattwu@163.com>
 * HOMEPAGE:         http://ext2.yeah.net
 * UPDATE HISTORY: 
 */

/* INCLUDES *****************************************************************/

#include "ntifs.h"
#include "ext2fs.h"

/* GLOBALS ***************************************************************/

extern PEXT2_GLOBAL gExt2Global;

/* DEFINITIONS *************************************************************/

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, Ext2Cleanup)
#endif


NTSTATUS
Ext2Cleanup (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_SUCCESS;
    PEXT2_VCB       Vcb;
    BOOLEAN         VcbResourceAcquired = FALSE;
    PFILE_OBJECT    FileObject;
    PEXT2_FCB       Fcb;
    BOOLEAN         FcbResourceAcquired = FALSE;
    BOOLEAN         FcbPagingIoAcquired = FALSE;
    PEXT2_CCB       Ccb;
    PIRP            Irp;

    __try
    {
        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
            (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
        
        if (DeviceObject == gExt2Global->DeviceObject)
        {
            Status = STATUS_SUCCESS;
            __leave;
        }
        
        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
            (Vcb->Identifier.Size == sizeof(EXT2_VCB)));

        if (!IsFlagOn(Vcb->Flags, VCB_INITIALIZED))
        {
            Status = STATUS_SUCCESS;
            __leave;
        }

        if (!ExAcquireResourceExclusiveLite(
                 &Vcb->MainResource,
                 IrpContext->IsSynchronous
                 ))
        {
            Status = STATUS_PENDING;
            __leave;
        }

        VcbResourceAcquired = TRUE;
        
        FileObject = IrpContext->FileObject;
        
        Fcb = (PEXT2_FCB) FileObject->FsContext;
        
        if (!Fcb)
        {
            Status = STATUS_SUCCESS;
            __leave;
        }
        
        if (Fcb->Identifier.Type == EXT2VCB)
        {
            if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
            {
                ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED);

                Ext2ClearVpbFlag(Vcb->Vpb, VPB_LOCKED);
            }

            ExAcquireResourceExclusiveLite(
                &Vcb->CountResource, TRUE );
        
            Vcb->OpenHandleCount--;
        
            ExReleaseResourceForThreadLite(
                &Vcb->CountResource,
                ExGetCurrentResourceThread() );


            if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && (!Vcb->OpenHandleCount))
                IoRemoveShareAccess(FileObject, &Vcb->ShareAccess);

            Status = STATUS_SUCCESS;
            __leave;
        }
        

/*
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread());

            VcbResourceAcquired = FALSE;
        }
*/

        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
            (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

        if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && !IsFlagOn(Fcb->Flags, FCB_PAGE_FILE))
        {
            if (!ExAcquireResourceExclusiveLite(
                     &Fcb->MainResource,
                     IrpContext->IsSynchronous
                     ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbResourceAcquired = TRUE;
        }
        
        Ccb = (PEXT2_CCB) FileObject->FsContext2;

        if (!Ccb)
        {
            Status = STATUS_SUCCESS;
            __leave;
        }
        
        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
            (Ccb->Identifier.Size == sizeof(EXT2_CCB)));        
        Irp = IrpContext->Irp;

        ExAcquireResourceExclusiveLite(&Fcb->CountResource, TRUE);
        Fcb->OpenHandleCount--;
        if (!IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED ))
        {
            Fcb->NonCachedOpenCount--;
        }
        ExReleaseResourceForThreadLite(
                &Fcb->CountResource,
                ExGetCurrentResourceThread());

        ExAcquireResourceExclusiveLite(&Vcb->CountResource, TRUE);
        Vcb->OpenFileHandleCount--;
        ExReleaseResourceForThreadLite(
                &Vcb->CountResource,
                ExGetCurrentResourceThread());

        if (IsFlagOn(Fcb->Flags, FCB_DELETE_ON_CLOSE))
        {
            SetFlag(Fcb->Flags, FCB_DELETE_PENDING);

            FsRtlNotifyFullChangeDirectory( Vcb->NotifySync,
                                                &Vcb->NotifyList,
                                                Fcb,
                                                NULL,
                                                FALSE,
                                                FALSE,
                                                0,
                                                NULL,
                                                NULL,
                                                NULL );


        }

        if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
        {
            FsRtlNotifyCleanup(
                Vcb->NotifySync,
                &Vcb->NotifyList,
                Ccb   );
        }
        else
        {
            //
            // Drop any byte range locks this process may have on the file.
            //
            FsRtlFastUnlockAll(
                &Fcb->FileLockAnchor,
                FileObject,
                IoGetRequestorProcess(Irp),
                NULL  );

            //
            // If there are no byte range locks owned by other processes on the
            // file the fast I/O read/write functions doesn't have to check for
            // locks so we set IsFastIoPossible to FastIoIsPossible again.
            //
            if (!FsRtlGetNextFileLock(&Fcb->FileLockAnchor, TRUE))
            {
                if (Fcb->CommonFCBHeader.IsFastIoPossible != FastIoIsPossible)
                {
#if DBG
                    Ext2DbgPrint(D_CLEANUP, 
                        DRIVER_NAME ": %-16.16s %-31s %s\n",
                        Ext2DbgGetCurrentProcessName(),
                        "FastIoIsPossible",
                        Fcb->AnsiFileName.Buffer
                        );
#endif
                    Fcb->CommonFCBHeader.IsFastIoPossible = FastIoIsPossible;
                }
            }
        }

        if (!IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
        {
            if (IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
                (Fcb->SectionObject.DataSectionObject != NULL))
            {
/*
                if (Fcb->NonCachedOpenCount != 0 && 
                    Fcb->NonCachedOpenCount == Fcb->OpenHandleCount)
*/
                {

                    if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) &&
                          (IsFlagOn(Fcb->Flags, FCB_FILE_MODIFIED) || IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) ))
                    {
                        CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
                        ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                    }

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

            if (FileObject->PrivateCacheMap)
            {
                CcUninitializeCacheMap(FileObject,
                (PLARGE_INTEGER)(&(Fcb->CommonFCBHeader.FileSize)),
                NULL );
            }
        }

        if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING))
        {
			if (!Fcb->OpenHandleCount && Fcb->ReferenceCount <= 1)
			{
				//
				//	Have to delete this file...
				//

                if (!ExAcquireResourceExclusiveLite(
                         &Fcb->PagingIoResource,
                         IrpContext->IsSynchronous
                         ))
                {
                    Status = STATUS_PENDING;
                    __leave;
                }

                FcbPagingIoAcquired = TRUE;

				if (Ext2DeleteFile(IrpContext, Vcb, Fcb))
                {
/*
                    UNICODE_STRING FullFileName;

                    if (Ext2GetFullFileName(Fcb->Ext2Mcb, &FullFileName))
                    {
                        FsRtlNotifyFullReportChange((PNOTIFY_SYNC)(Vcb->NotifySync),
                                                    (PLIST_ENTRY)&(Vcb->NotifyList),
                                                    (PSTRING)(&FullFileName),
                                                    (USHORT)(FullFileName.Length - Fcb->Ext2Mcb->ShortName.Length),
                                                    (PSTRING)NULL,
                                                    (PSTRING)NULL,
                                                    IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) ?
                                                    ((ULONG)FILE_NOTIFY_CHANGE_DIR_NAME) :
                                                    ((ULONG)FILE_NOTIFY_CHANGE_FILE_NAME),
                                                    (ULONG)FILE_ACTION_REMOVED,
                                                    (PVOID)0 );


                        ExFreePool(FullFileName.Buffer);
                    }
*/
                }

                if (FcbPagingIoAcquired)
                {
                    ExReleaseResourceForThreadLite(
                        &Fcb->PagingIoResource,
                        ExGetCurrentResourceThread() );

                    FcbPagingIoAcquired = FALSE;
                }
			}
        }

       if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && !Fcb->OpenHandleCount)
            IoRemoveShareAccess(FileObject, &Fcb->ShareAccess);


#if DBG
        Ext2DbgPrint(D_CLEANUP, "Ext2Cleanup: OpenCount: %u ReferCount: %-7u %s\n",
            Fcb->OpenHandleCount,
            Fcb->ReferenceCount,
            Fcb->AnsiFileName.Buffer );
#endif
        Status = STATUS_SUCCESS;
    }

    __finally
    {
        if (IrpContext->FileObject)
        {
            SetFlag(IrpContext->FileObject->Flags, FO_CLEANUP_COMPLETE);
        }
        
        if (FcbPagingIoAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->PagingIoResource,
                ExGetCurrentResourceThread() );
        }

        if (FcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread() );
        }
        
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread());
        }
        
        if (!IrpContext->ExceptionInProgress)
        {
            if (Status == STATUS_PENDING)
            {
                Ext2QueueRequest(IrpContext);
            }
            else
            {
                IrpContext->Irp->IoStatus.Status = Status;
                
                Ext2CompleteRequest(
                    IrpContext->Irp,
                    (CCHAR)
                    (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
                
                Ext2FreeIrpContext(IrpContext);
            }
        }
    }
    
    return Status;
}

⌨️ 快捷键说明

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