📄 fileinfo.c
字号:
Status = STATUS_USER_MAPPED_FILE;
__leave;
}
if (NT_SUCCESS(Status))
{
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->CommonFCBHeader.AllocationSize)));
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
}
}
}
break;
case FileDispositionInformation:
{
PFILE_DISPOSITION_INFORMATION FDI = (PFILE_DISPOSITION_INFORMATION)Buffer;
Status = Ext2SetDispositionInfo(IrpContext, Vcb, Fcb, FDI->DeleteFile);
}
break;
case FileRenameInformation:
{
Status = Ext2SetRenameInfo(IrpContext, Vcb, Fcb);
}
break;
//
// This is the only set file information request supported on read
// only file systems
//
case FilePositionInformation:
{
PFILE_POSITION_INFORMATION FilePositionInformation;
if (Length < sizeof(FILE_POSITION_INFORMATION))
{
Status = STATUS_INVALID_PARAMETER;
__leave;
}
FilePositionInformation = (PFILE_POSITION_INFORMATION) Buffer;
if ((FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) &&
(FilePositionInformation->CurrentByteOffset.LowPart &
DeviceObject->AlignmentRequirement) )
{
Status = STATUS_INVALID_PARAMETER;
__leave;
}
FileObject->CurrentByteOffset =
FilePositionInformation->CurrentByteOffset;
Status = STATUS_SUCCESS;
__leave;
}
break;
default:
Status = STATUS_INVALID_INFO_CLASS;
}
}
__finally
{
if (FcbPagingIoResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->PagingIoResource,
ExGetCurrentResourceThread() );
}
if (FcbMainResourceAcquired)
{
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;
}
BOOLEAN
Ext2ExpandFileAllocation(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_FCB Fcb, PLARGE_INTEGER AllocationSize)
{
ULONG dwRet = 0;
BOOLEAN bRet = TRUE;
if (AllocationSize->QuadPart <= Fcb->CommonFCBHeader.AllocationSize.QuadPart)
return TRUE;
if (((LONGLONG)Vcb->ext2_super_block->s_free_blocks_count) * Vcb->ext2_block <= (AllocationSize->QuadPart - Fcb->CommonFCBHeader.AllocationSize.QuadPart))
{
Ext2DbgPrint(D_FILEINFO, "Ext2ExpandFileAllocation: There is no enough disk space available.\n");
return FALSE;
}
while (bRet && (AllocationSize->QuadPart > Fcb->CommonFCBHeader.AllocationSize.QuadPart))
{
bRet = Ext2ExpandInode(IrpContext, Vcb, Fcb, &dwRet);
}
return bRet;
}
BOOLEAN
Ext2TruncateFileAllocation(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_FCB Fcb, PLARGE_INTEGER AllocationSize)
{
BOOLEAN bRet = TRUE;
while (bRet && (AllocationSize->QuadPart < Fcb->CommonFCBHeader.AllocationSize.QuadPart))
{
bRet = Ext2TruncateInode(IrpContext, Vcb, Fcb);
}
return bRet;
}
NTSTATUS
Ext2SetDispositionInfo(
PEXT2_IRP_CONTEXT IrpContext,
PEXT2_VCB Vcb,
PEXT2_FCB Fcb,
BOOLEAN bDelete)
{
PIRP Irp = IrpContext->Irp;
PIO_STACK_LOCATION IrpSp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Ext2DbgPrint(D_FILEINFO, "Ext2SetDispositionInfo: bDelete=%x\n", bDelete);
if (bDelete)
{
if (!MmFlushImageSection( &Fcb->SectionObject,
MmFlushForDelete ))
{
return STATUS_CANNOT_DELETE;
}
if (Fcb->Ext2Mcb->Inode == EXT2_ROOT_INO)
{
return STATUS_CANNOT_DELETE;
}
if (IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
if (!Ext2IsDirectoryEmpty(Vcb, Fcb))
{
return STATUS_DIRECTORY_NOT_EMPTY;
}
}
SetFlag(Fcb->Flags, FCB_DELETE_PENDING);
IrpSp->FileObject->DeletePending = TRUE;
if (IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
FsRtlNotifyFullChangeDirectory( Vcb->NotifySync,
&Vcb->NotifyList,
Fcb,
NULL,
FALSE,
FALSE,
0,
NULL,
NULL,
NULL );
}
}
else
{
ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
IrpSp->FileObject->DeletePending = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS
Ext2SetRenameInfo(
PEXT2_IRP_CONTEXT IrpContext,
PEXT2_VCB Vcb,
PEXT2_FCB Fcb)
{
PEXT2_FCB TargetDcb;
PEXT2_MCB Mcb;
PEXT2_MCB TargetMcb;
EXT2_INODE TargetIno;
UNICODE_STRING FileName;
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
PFILE_OBJECT FileObject;
PFILE_OBJECT TargetObject;
BOOLEAN ReplaceIfExists;
PFILE_RENAME_INFORMATION FRI;
if (Fcb->Ext2Mcb->Inode == EXT2_ROOT_INO)
{
Status = STATUS_INVALID_PARAMETER;
goto errorout;
}
Irp = IrpContext->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FileObject = IrpSp->FileObject;
TargetObject = IrpSp->Parameters.SetFile.FileObject;
ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
FRI = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
if (TargetObject == NULL)
{
UNICODE_STRING NewName;
NewName.Buffer = FRI->FileName;
NewName.MaximumLength = NewName.Length = (USHORT)FRI->FileNameLength;
while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] == L'\\')
{
NewName.Buffer[NewName.Length/2 - 1] = 0;
NewName.Length -= 2;
}
while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] != L'\\')
{
NewName.Length -= 2;
}
NewName.Buffer = (USHORT *)((UCHAR *)NewName.Buffer + NewName.Length);
NewName.Length = (USHORT)(FRI->FileNameLength - NewName.Length);
FileName = NewName;
TargetDcb = NULL;
Mcb = Fcb->Ext2Mcb->Parent;
if (FileName.Length >= EXT2_NAME_LEN*sizeof(USHORT))
{
Status = STATUS_OBJECT_NAME_INVALID;
goto errorout;
}
}
else
{
TargetDcb = (PEXT2_FCB)(TargetObject->FsContext);
if (!TargetDcb || TargetDcb->Vcb != Vcb)
{
Status = STATUS_INVALID_PARAMETER;
goto errorout;
}
Mcb = TargetDcb->Ext2Mcb;
FileName = TargetObject->FileName;
}
if (Mcb->Inode == Fcb->Ext2Mcb->Parent->Inode)
{
if (FsRtlAreNamesEqual( &FileName,
&(Fcb->Ext2Mcb->ShortName),
FALSE,
NULL ))
{
Status = STATUS_SUCCESS;
goto errorout;
}
}
TargetDcb = Mcb->Ext2Fcb;
if (!TargetDcb)
TargetDcb = Ext2CreateFcbFromMcb(Vcb, Mcb);
if (Mcb->Inode != Fcb->Ext2Mcb->Parent->Inode)
Ext2CreateFcbFromMcb(Vcb, Fcb->Ext2Mcb->Parent);
if (!TargetDcb || !(Fcb->Ext2Mcb->Parent->Ext2Fcb))
{
Status = STATUS_UNSUCCESSFUL;
goto errorout;
}
TargetMcb = NULL;
Status = Ext2LookupFileName(
Vcb,
&FileName,
TargetDcb,
&TargetMcb,
&TargetIno );
if (NT_SUCCESS(Status))
{
if ( (!ReplaceIfExists) ||
(IsFlagOn(TargetMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) ||
(IsFlagOn(TargetMcb->FileAttr, FILE_ATTRIBUTE_READONLY)))
{
Status = STATUS_OBJECT_NAME_COLLISION;
goto errorout;
}
if (ReplaceIfExists)
{
Status = STATUS_NOT_IMPLEMENTED;
goto errorout;
}
}
Status = Ext2RemoveEntry(IrpContext, Vcb, Fcb->Ext2Mcb->Parent->Ext2Fcb, Fcb->Ext2Mcb->Inode);
if (IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
Status = Ext2AddEntry(IrpContext, Vcb, TargetDcb, EXT2_FT_DIR, Fcb->Ext2Mcb->Inode, &FileName);
else
Status = Ext2AddEntry(IrpContext, Vcb, TargetDcb, EXT2_FT_REG_FILE, Fcb->Ext2Mcb->Inode, &FileName);
if (NT_SUCCESS(Status))
{
if (Fcb->Ext2Mcb->ShortName.MaximumLength < (FileName.Length + 2))
{
ExFreePool(Fcb->Ext2Mcb->ShortName.Buffer);
Fcb->Ext2Mcb->ShortName.Buffer =
ExAllocatePool(PagedPool, FileName.Length + 2);
if (!Fcb->Ext2Mcb->ShortName.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
Fcb->Ext2Mcb->ShortName.MaximumLength = FileName.Length + 2;
}
{
RtlCopyMemory(Fcb->Ext2Mcb->ShortName.Buffer, FileName.Buffer, FileName.Length);
Fcb->Ext2Mcb->ShortName.Length = FileName.Length;
}
#if DBG
if (Fcb->AnsiFileName.Length < (FileName.Length / 2 + 1))
{
ExFreePool(Fcb->AnsiFileName.Buffer);
Fcb->AnsiFileName.Buffer =
ExAllocatePool(PagedPool, FileName.Length / 2 + 1);
if (!Fcb->AnsiFileName.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
Fcb->AnsiFileName.MaximumLength = FileName.Length / 2 + 1;
}
Fcb->AnsiFileName.Length = FileName.Length / 2;
Ext2WcharToChar(
Fcb->AnsiFileName.Buffer,
FileName.Buffer,
FileName.Length / 2 );
Fcb->AnsiFileName.Buffer[FileName.Length / sizeof(WCHAR)] = 0;
#endif
Ext2DeleteMcbNode(Fcb->Ext2Mcb->Parent, Fcb->Ext2Mcb);
Ext2AddMcbNode(Mcb, Fcb->Ext2Mcb);
}
errorout:
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -