📄 write.c
字号:
{
__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 + -