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

📄 write.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            {
                __leave;
            }

            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = Length;
            
            Status = 
                Ext2WriteInode(
                IrpContext,
                Vcb,
                Fcb->ext2_inode,
                (ULONG)(ByteOffset.QuadPart),
                NULL,
                Length,
                TRUE,
                &ReturnedLength);

            Irp = IrpContext->Irp;

        }
    }

    __finally
    {
        if (PagingIoResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->PagingIoResource,
                ExGetCurrentResourceThread());
        }
        
        if (MainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread());
        }
        
        if (!IrpContext->ExceptionInProgress)
        {
            if (Irp)
            {
                if (Status == STATUS_PENDING)
                {
                    Status = Ext2LockUserBuffer(
                        IrpContext->Irp,
                        Length,
                        IoReadAccess );
                    
                    if (NT_SUCCESS(Status))
                    {
                        Status = Ext2QueueRequest(IrpContext);
                    }
                    else
                    {
                        IrpContext->Irp->IoStatus.Status = Status;
                        Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
                        Ext2FreeIrpContext(IrpContext);
                    }
                }
                else
                {
                    IrpContext->Irp->IoStatus.Status = Status;
                    
                    if (SynchronousIo && !PagingIo && NT_SUCCESS(Status))
                    {
                        FileObject->CurrentByteOffset.QuadPart =
                            ByteOffset.QuadPart + Irp->IoStatus.Information;
                    }
                    
                    if (!PagingIo && NT_SUCCESS(Status))
                    {
                        SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
                        SetFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                    }
                    
                    Ext2CompleteRequest(
                            IrpContext->Irp,
                            (CCHAR)
                            (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
                    
                    Ext2FreeIrpContext(IrpContext);
                }
            }
            else
            {
                Ext2FreeIrpContext(IrpContext);
            }
        }
    }
    
    return Status;

}

NTSTATUS
Ext2WriteComplete (IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PFILE_OBJECT    FileObject;
    PIRP            Irp;
    PIO_STACK_LOCATION IrpSp;
    
    __try
    {
        ASSERT(IrpContext);
        
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
            (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
        
        FileObject = IrpContext->FileObject;
        
        Irp = IrpContext->Irp;
        IrpSp = IoGetCurrentIrpStackLocation(Irp);
        
        CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
        
        Irp->MdlAddress = NULL;
        
        Status = STATUS_SUCCESS;
    }

    __finally
    {
        if (!IrpContext->ExceptionInProgress)
        {
            IrpContext->Irp->IoStatus.Status = Status;
            
            Ext2CompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );
            
            Ext2FreeIrpContext(IrpContext);
        }
    }
    
    return Status;
}


NTSTATUS
Ext2Write (IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status;
    PEXT2_FCBVCB        FcbOrVcb;
    PDEVICE_OBJECT      DeviceObject;
    PFILE_OBJECT        FileObject;
    PEXT2_VCB           Vcb;
    
    ASSERT(IrpContext);
    
    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
        (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

    __try
    {
        if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE))
        {
            Status =  Ext2WriteComplete(IrpContext);
        }
        else
        {
            DeviceObject = IrpContext->DeviceObject;

            if (DeviceObject == gExt2Global->DeviceObject)
            {
                Status = Ext2CompleteIrpContext(IrpContext, STATUS_INVALID_DEVICE_REQUEST);
                __leave;
            }

            Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;

            if (Vcb->Identifier.Type != EXT2VCB ||
                Vcb->Identifier.Size != sizeof(EXT2_VCB) )
            {
                 Status = Ext2CompleteIrpContext(IrpContext, STATUS_INVALID_PARAMETER);
                __leave;
            }

            if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
            {
                Status = STATUS_MEDIA_WRITE_PROTECTED;
                __leave;
            }

            FileObject = IrpContext->FileObject;
            
            FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;

            if (FcbOrVcb->Identifier.Type == EXT2VCB)
            {
                Status = Ext2WriteVolume(IrpContext);
            }
            else if (FcbOrVcb->Identifier.Type == EXT2FCB)
            {
                Status = Ext2WriteFile(IrpContext);
            }
            else
            {
                Status = Ext2CompleteIrpContext(IrpContext, STATUS_INVALID_PARAMETER);
            }
        }
    }

    __finally
    {

    }
    
    return Status;
}


BOOLEAN
Ext2SupersedeOrOverWriteFile(
        PEXT2_IRP_CONTEXT IrpContext,
        PEXT2_VCB Vcb,
        PEXT2_FCB Fcb,
        ULONG     Disposition)
{
	LARGE_INTEGER   CurrentTime;
    LARGE_INTEGER   AllocationSize;
    
    BOOLEAN         bRet = FALSE;

	KeQuerySystemTime(&CurrentTime);

    AllocationSize.QuadPart = (LONGLONG)0;

    bRet = Ext2TruncateFileAllocation(IrpContext, Vcb, Fcb, &AllocationSize);

    if (bRet)
    {
        Fcb->CommonFCBHeader.AllocationSize.QuadPart = 
        Fcb->CommonFCBHeader.FileSize.QuadPart =  (LONGLONG) 0;

        Fcb->ext2_inode->i_size = 0;

        if (Disposition == FILE_SUPERSEDE)
            Fcb->ext2_inode->i_ctime = Ext2InodeTime(CurrentTime);

        Fcb->ext2_inode->i_atime =
        Fcb->ext2_inode->i_mtime = Ext2InodeTime(CurrentTime);
    }
    else
    {
        if (Fcb->ext2_inode->i_size > (Fcb->ext2_inode->i_blocks * SECTOR_SIZE))
            Fcb->ext2_inode->i_size = (Fcb->ext2_inode->i_blocks * SECTOR_SIZE);
    
        Fcb->CommonFCBHeader.AllocationSize.QuadPart = (LONGLONG)(Fcb->ext2_inode->i_blocks * SECTOR_SIZE);
        Fcb->CommonFCBHeader.FileSize.QuadPart =  (LONGLONG) Fcb->ext2_inode->i_size;

    }

    Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode);

    return bRet;
}

BOOLEAN Ext2IsDirectoryEmpty (
        PEXT2_VCB Vcb,
        PEXT2_FCB Dcb )
{
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;

    PEXT2_DIR_ENTRY2        pTarget = NULL;

    ULONG                   dwBytes = 0;
    ULONG                   dwRet;

    BOOLEAN                 bRet = TRUE;

    if (!IsFlagOn(Dcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
        return TRUE;

    __try
    {
        pTarget = (PEXT2_DIR_ENTRY2) ExAllocatePool(PagedPool,
                                     EXT2_DIR_REC_LEN(EXT2_NAME_LEN));
        if (!pTarget)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }
        
        dwBytes = 0;


        while ((LONGLONG)dwBytes < Dcb->CommonFCBHeader.AllocationSize.QuadPart)
        {
            RtlZeroMemory(pTarget, EXT2_DIR_REC_LEN(EXT2_NAME_LEN));

            Status = Ext2ReadInode(
                        NULL,
                        Vcb,
                        Dcb->ext2_inode,
                        dwBytes,
                        (PVOID)pTarget,
                        EXT2_DIR_REC_LEN(EXT2_NAME_LEN),
                        &dwRet);

            if (!NT_SUCCESS(Status))
            {
                Ext2DbgPrint(D_WRITE, "Ext2RemoveEntry: Reading Directory Content error.\n");
                __leave;
            }

            if (pTarget->inode)
            {
                if (pTarget->name_len == 1 && pTarget->name[0] == '.')
                {
                }
                else if (pTarget->name_len == 2 && pTarget->name[0] == '.' && 
                         pTarget->name[1] == '.')
                {
                }
                else
                {
                    bRet = FALSE;
                    break;
                }
            }
            else
            {
                break;
            }

            dwBytes += pTarget->rec_len;
        }
    }

    __finally
    {
        if (pTarget != NULL)
        {
            ExFreePool(pTarget);
        }
    }
    
    return bRet;
}


BOOLEAN
Ext2DeleteFile(
        PEXT2_IRP_CONTEXT IrpContext,
        PEXT2_VCB Vcb,
        PEXT2_FCB Fcb )
{
    BOOLEAN         bRet = FALSE;
    LARGE_INTEGER   AllocationSize;
    PEXT2_FCB       Dcb = NULL;

    NTSTATUS        Status;

    Ext2DbgPrint(D_WRITE, "Ext2DeleteFile: File %S (%xh) will be deleted!\n", Fcb->Ext2Mcb->ShortName.Buffer, Fcb->Ext2Mcb->Inode);

    if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
        return TRUE;

    if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
    {
        if (!Ext2IsDirectoryEmpty(Vcb, Fcb))
        {
            ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
            
            return FALSE;
        }
    }

    Ext2DbgPrint(D_WRITE, "Ext2DeleteFile: EXT2SB->S_FREE_BLOCKS = %xh .\n", Vcb->ext2_super_block->s_free_blocks_count);

    Status = STATUS_UNSUCCESSFUL;

    {
        if (Fcb->Ext2Mcb->Parent->Ext2Fcb)
        {
            Status = Ext2RemoveEntry(IrpContext, Vcb, Fcb->Ext2Mcb->Parent->Ext2Fcb, Fcb->Ext2Mcb->Inode);
        }
        else
        {
            Dcb = Ext2CreateFcbFromMcb(Vcb, Fcb->Ext2Mcb->Parent);
            if (Dcb)
            {
                Status = Ext2RemoveEntry(IrpContext, Vcb, Dcb, Fcb->Ext2Mcb->Inode);
            }
        }
    }

    if (NT_SUCCESS(Status))
    {
        Fcb->ext2_inode->i_links_count--;

        if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
        {
            if (Fcb->ext2_inode->i_links_count <= 1)
            {
                bRet = TRUE;
            }
        }
        else
        {
            if (Fcb->ext2_inode->i_links_count == 0)
            {
                bRet = TRUE;
            }
        }
    }

    if (bRet)
    {
        AllocationSize.QuadPart = (LONGLONG)0;
        bRet = Ext2TruncateFileAllocation(IrpContext, Vcb, Fcb, &AllocationSize);
        
        if (bRet)
        {
            if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
                bRet = Ext2FreeInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, EXT2_FT_DIR);
            else
                bRet = Ext2FreeInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, EXT2_FT_REG_FILE);

            SetFlag(Fcb->Flags, FCB_FILE_DELETED);
            Ext2DeleteMcbNode(Fcb->Ext2Mcb->Parent, Fcb->Ext2Mcb);

            {
                LARGE_INTEGER   SysTime;
                KeQuerySystemTime(&SysTime);

                Fcb->ext2_inode->i_dtime = Ext2InodeTime(SysTime);

                Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode);
            }
        }
    }

    Ext2DbgPrint(D_WRITE, "Ext2DeleteFile: Succeed... EXT2SB->S_FREE_BLOCKS = %xh .\n", Vcb->ext2_super_block->s_free_blocks_count);

    return bRet;
}

⌨️ 快捷键说明

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