📄 fileinfo.c
字号:
FileNetworkOpenInformation->CreationTime = Ext2SysTime(Fcb->ext2_inode->i_ctime);
FileNetworkOpenInformation->LastAccessTime = Ext2SysTime(Fcb->ext2_inode->i_atime);
FileNetworkOpenInformation->LastWriteTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
FileNetworkOpenInformation->ChangeTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
FileNetworkOpenInformation->AllocationSize.QuadPart =
(LONGLONG)(Fcb->ext2_inode->i_size);
FileNetworkOpenInformation->EndOfFile.QuadPart =
(LONGLONG)(Fcb->ext2_inode->i_size);
FileNetworkOpenInformation->FileAttributes =
Fcb->Ext2Mcb->FileAttr;
Irp->IoStatus.Information =
sizeof(FILE_NETWORK_OPEN_INFORMATION);
Status = STATUS_SUCCESS;
__leave;
}
default:
Status = STATUS_INVALID_INFO_CLASS;
}
}
__finally
{
if (FcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->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;
}
NTSTATUS
Ext2SetInformation (IN PEXT2_IRP_CONTEXT IrpContext)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb;
PFILE_OBJECT FileObject;
PEXT2_FCB Fcb;
PEXT2_CCB Ccb;
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
FILE_INFORMATION_CLASS FileInformationClass;
ULONG Length;
PVOID Buffer;
BOOLEAN FcbMainResourceAcquired = FALSE;
BOOLEAN VcbResourceAcquired = FALSE;
BOOLEAN FcbPagingIoResourceAcquired = FALSE;
__try
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
//
// This request is not allowed on the main device object
//
if (DeviceObject == gExt2Global->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
FileObject = IrpContext->FileObject;
Fcb = (PEXT2_FCB) FileObject->FsContext;
ASSERT(Fcb != NULL);
//
// This request is not allowed on volumes
//
if (Fcb->Identifier.Type == EXT2VCB)
{
Status = STATUS_INVALID_PARAMETER;
__leave;
}
ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
{
Status = STATUS_FILE_DELETED;
__leave;
}
Ccb = (PEXT2_CCB) FileObject->FsContext2;
ASSERT(Ccb != NULL);
ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
(Ccb->Identifier.Size == sizeof(EXT2_CCB)));
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass =
IoStackLocation->Parameters.SetFile.FileInformationClass;
Length = IoStackLocation->Parameters.SetFile.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
if (FileInformationClass == FileDispositionInformation ||
FileInformationClass == FileRenameInformation ||
FileInformationClass == FileLinkInformation)
{
if (!ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
IrpContext->IsSynchronous ))
{
Status = STATUS_PENDING;
__leave;
}
VcbResourceAcquired = TRUE;
}
}
if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) && !FlagOn(Fcb->Flags, FCB_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(
&Fcb->MainResource,
IrpContext->IsSynchronous ))
{
Status = STATUS_PENDING;
__leave;
}
FcbMainResourceAcquired = TRUE;
}
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
if (FileInformationClass != FilePositionInformation)
{
Status = STATUS_MEDIA_WRITE_PROTECTED;
__leave;
}
}
if (FileInformationClass == FileDispositionInformation ||
FileInformationClass == FileRenameInformation ||
FileInformationClass == FileLinkInformation ||
FileInformationClass == FileAllocationInformation ||
FileInformationClass == FileEndOfFileInformation)
{
if (!ExAcquireResourceExclusiveLite(
&Fcb->PagingIoResource,
IrpContext->IsSynchronous ))
{
Status = STATUS_PENDING;
__leave;
}
FcbPagingIoResourceAcquired = TRUE;
}
/*
if (FileInformationClass != FileDispositionInformation
&& FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
{
Status = STATUS_DELETE_PENDING;
__leave;
}
*/
switch (FileInformationClass)
{
case FileBasicInformation:
{
PFILE_BASIC_INFORMATION FBI = (PFILE_BASIC_INFORMATION) Buffer;
PEXT2_INODE Ext2Inode = Fcb->ext2_inode;
if( FBI->CreationTime.QuadPart )
{
Ext2Inode->i_ctime = (ULONG)(Ext2InodeTime(FBI->CreationTime));
}
if( FBI->LastAccessTime.QuadPart )
{
Ext2Inode->i_atime = (ULONG)(Ext2InodeTime(FBI->LastAccessTime));
}
if( FBI->LastWriteTime.QuadPart )
{
Ext2Inode->i_mtime = (ULONG)(Ext2InodeTime(FBI->LastWriteTime));
}
if (IsFlagOn(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY))
{
Ext2SetReadOnly(Fcb->ext2_inode->i_mode);
SetFlag(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
else
{
Ext2SetWritable(Fcb->ext2_inode->i_mode);
ClearFlag(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_READONLY);
}
if(Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Ext2Inode))
Status = STATUS_SUCCESS;
if (FBI->FileAttributes & FILE_ATTRIBUTE_TEMPORARY)
{
SetFlag(FileObject->Flags, FO_TEMPORARY_FILE);
}
else
{
ClearFlag(FileObject->Flags, FO_TEMPORARY_FILE);
}
Status = STATUS_SUCCESS;
}
break;
case FileAllocationInformation:
{
PFILE_ALLOCATION_INFORMATION FAI = (PFILE_ALLOCATION_INFORMATION)Buffer;
if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
if (FAI->AllocationSize.QuadPart == Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
Status = STATUS_SUCCESS;
}
else if (FAI->AllocationSize.QuadPart > Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
if(Ext2ExpandFileAllocation(IrpContext, Vcb, Fcb, &(FAI->AllocationSize)))
{
if (Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode))
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
if (MmCanFileBeTruncated(&(Fcb->SectionObject), &(FAI->AllocationSize)))
{
LARGE_INTEGER EndOfFile;
EndOfFile.QuadPart = FAI->AllocationSize.QuadPart + (LONGLONG)(Vcb->ext2_block - 1);
if(Ext2TruncateFileAllocation(IrpContext, Vcb, Fcb, &(EndOfFile)))
{
if (FAI->AllocationSize.QuadPart < Fcb->CommonFCBHeader.FileSize.QuadPart)
Fcb->CommonFCBHeader.FileSize.QuadPart = FAI->AllocationSize.QuadPart;
Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode);
Status = STATUS_SUCCESS;
}
}
else
{
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 FileEndOfFileInformation:
{
PFILE_END_OF_FILE_INFORMATION FEOFI = (PFILE_END_OF_FILE_INFORMATION) Buffer;
BOOLEAN CacheInitialized = FALSE;
if (IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
Status = STATUS_INVALID_DEVICE_REQUEST;
__leave;
}
if (FEOFI->EndOfFile.HighPart != 0)
{
Status = STATUS_INVALID_PARAMETER;
__leave;
}
if (IoStackLocation->Parameters.SetFile.AdvanceOnly)
{
Status = STATUS_SUCCESS;
__leave;
}
if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
(FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
ASSERT( !FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE ) );
CcInitializeCacheMap( FileObject,
(PCC_FILE_SIZES)&(Fcb->CommonFCBHeader.AllocationSize),
FALSE,
&(gExt2Global->CacheManagerNoOpCallbacks),
Fcb );
CacheInitialized = TRUE;
}
if (FEOFI->EndOfFile.QuadPart == Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
Status = STATUS_SUCCESS;
}
else if (FEOFI->EndOfFile.QuadPart > Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
LARGE_INTEGER FileSize = Fcb->CommonFCBHeader.FileSize;
if(Ext2ExpandFileAllocation(IrpContext, Vcb, Fcb, &(FEOFI->EndOfFile)))
{
{
Fcb->CommonFCBHeader.FileSize.QuadPart = FEOFI->EndOfFile.QuadPart;
Fcb->ext2_inode->i_size = (ULONG)FEOFI->EndOfFile.QuadPart;
Fcb->CommonFCBHeader.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
}
if (Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode))
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(Status))
{
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->CommonFCBHeader.AllocationSize)));
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
Ext2ZeroHoles(IrpContext, Vcb, FileObject, FileSize.QuadPart, Fcb->CommonFCBHeader.AllocationSize.QuadPart - FileSize.QuadPart);
}
}
else
{
if (MmCanFileBeTruncated(&(Fcb->SectionObject), &(FEOFI->EndOfFile)))
{
LARGE_INTEGER EndOfFile = FEOFI->EndOfFile;
EndOfFile.QuadPart = EndOfFile.QuadPart + (LONGLONG)(Vcb->ext2_block - 1);
if(Ext2TruncateFileAllocation(IrpContext, Vcb, Fcb, &(EndOfFile)))
{
Fcb->CommonFCBHeader.FileSize.QuadPart = FEOFI->EndOfFile.QuadPart;
Fcb->ext2_inode->i_size = (ULONG)FEOFI->EndOfFile.QuadPart;
Ext2SaveInode(IrpContext, Vcb, Fcb->Ext2Mcb->Inode, Fcb->ext2_inode);
Status = STATUS_SUCCESS;
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -