📄 ext2fs.c
字号:
Index -= 12;
for (i = 0; i < 3; i++)
{
if (i > 0)
{
dwSizes[i] = vcb->ext2_block/4 * dwSizes[i-1];
}
if (Index < dwSizes[i])
{
return Ext2GetBlock(vcb, ext2_inode->i_block[i + 12], Index , i + 1);
}
Index -= dwSizes[i];
}
return 0;
}
ULONG
Ext2ReadInode (IN PEXT2_VCB vcb,
IN struct ext2_inode* ext2_inode,
IN ULONG offset,
IN PVOID Buffer,
IN ULONG size )
{
ULONG dwBytes = 0;
ULONG nBeg, nEnd;
ULONG dwBlk;
ULONG lba, off, dwSize;
ULONG i;
nBeg = offset / vcb->ext2_block;
nEnd = (size + offset + vcb->ext2_block - 1) / vcb->ext2_block;
for (i = nBeg; i < nEnd; i++)
{
dwBlk = Ext2BlockMap(vcb, ext2_inode, i);
lba = dwBlk * vcb->ext2_block / SECTOR_SIZE;
off = 0;
dwSize = vcb->ext2_block;
if (i == nBeg)
{
lba += (offset % vcb->ext2_block) / SECTOR_SIZE;
off = offset % SECTOR_SIZE;
dwSize = vcb->ext2_block - (offset % vcb->ext2_block);
}
else if (i == nEnd)
{
dwSize = size - dwBytes;
}
Ext2ReadDisk(vcb->TargetDeviceObject,
lba, off, dwSize, &((PUCHAR)Buffer)[dwBytes]);
dwBytes += dwSize;
}
return dwBytes;
}
ULONG
Ext2WriteInode (IN PEXT2_VCB vcb,
IN struct ext2_inode* ext2_inode,
IN ULONG offset,
IN PVOID Buffer,
IN ULONG size )
{
ULONG dwBytes = 0;
ULONG nBeg, nEnd;
ULONG dwBlk;
ULONG lba, off, dwSize;
ULONG i;
nBeg = offset / vcb->ext2_block;
nEnd = (size + offset + vcb->ext2_block - 1) / vcb->ext2_block;
for (i = nBeg; i < nEnd; i++)
{
dwBlk = Ext2BlockMap(vcb, ext2_inode, nBeg);
lba = dwBlk * vcb->ext2_block / SECTOR_SIZE;
off = 0;
dwSize = vcb->ext2_block;
if (i == nBeg)
{
off = offset;
dwSize = vcb->ext2_block - off;
}
else if (i == nEnd)
{
dwSize = size - dwBytes;
}
Ext2WriteDisk(vcb->TargetDeviceObject,
lba, off, dwSize, &((PUCHAR)Buffer)[dwBytes]);
dwBytes += dwSize;
}
return dwBytes;
}
PEXT2_IRP_CONTEXT
Ext2AllocateIrpContext (IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
PIO_STACK_LOCATION IoStackLocation;
PEXT2_IRP_CONTEXT IrpContext;
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
IrpContext = (PEXT2_IRP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(EXT2_IRP_CONTEXT));
if (!IrpContext)
{
return NULL;
}
IrpContext->Identifier.Type = ICX;
IrpContext->Identifier.Size = sizeof(EXT2_IRP_CONTEXT);
IrpContext->Irp = Irp;
IrpContext->MajorFunction = IoStackLocation->MajorFunction;
IrpContext->MinorFunction = IoStackLocation->MinorFunction;
IrpContext->DeviceObject = DeviceObject;
IrpContext->FileObject = IoStackLocation->FileObject;
if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
IrpContext->MajorFunction == IRP_MJ_SHUTDOWN)
{
IrpContext->IsSynchronous = TRUE;
}
else if (IrpContext->MajorFunction == IRP_MJ_CLEANUP ||
IrpContext->MajorFunction == IRP_MJ_CLOSE)
{
IrpContext->IsSynchronous = FALSE;
}
else
{
IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
}
//
// Temporary workaround for a bug in close that makes it reference a
// fileobject when it is no longer valid.
//
if (IrpContext->MajorFunction == IRP_MJ_CLOSE)
{
IrpContext->IsSynchronous = TRUE;
}
IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
IrpContext->ExceptionInProgress = FALSE;
return IrpContext;
}
VOID
Ext2FreeIrpContext (IN PEXT2_IRP_CONTEXT IrpContext)
{
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
ExFreePool(IrpContext);
}
PEXT2_FCB
Ext2AllocateFcb (IN PEXT2_VCB Vcb,
IN PUNICODE_STRING FileName,
IN ULONG IndexNumber,
IN ULONG inode,
IN ULONG dir_inode,
IN struct ext2_inode* ext2_inode )
{
PEXT2_FCB Fcb;
Fcb = (PEXT2_FCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
if (!Fcb)
{
return NULL;
}
Fcb->Identifier.Type = FCB;
Fcb->Identifier.Size = sizeof(EXT2_FCB);
#ifndef EXT2_RO
RtlZeroMemory(&Fcb->ShareAccess, sizeof(SHARE_ACCESS));
#endif
FsRtlInitializeFileLock (
&Fcb->FileLockAnchor,
NULL,
NULL );
Fcb->OpenHandleCount = 0;
Fcb->ReferenceCount = 0;
#ifndef EXT2_RO
Fcb->IsPageFile = FALSE;
Fcb->DeletePending = FALSE;
#endif
Fcb->FileName.Length = 0;
Fcb->FileName.MaximumLength = FileName->MaximumLength;
Fcb->FileName.Buffer = (PWSTR) ExAllocatePool(
NonPagedPool,
Fcb->FileName.MaximumLength
);
if (!Fcb->FileName.Buffer)
{
ExFreePool(Fcb);
return NULL;
}
RtlCopyUnicodeString(
&Fcb->FileName,
FileName );
#if DBG
Fcb->DbgFileName = (PUCHAR) ExAllocatePool(
NonPagedPool,
Fcb->FileName.MaximumLength / sizeof(WCHAR) + 1
);
if (!Fcb->DbgFileName)
{
ExFreePool(Fcb->FileName.Buffer);
ExFreePool(Fcb);
return NULL;
}
Ext2WcharToChar (
Fcb->DbgFileName,
Fcb->FileName.Buffer,
Fcb->FileName.Length / sizeof(WCHAR)
);
Fcb->DbgFileName[Fcb->FileName.Length / sizeof(WCHAR)] = 0;
#endif // DBG
Fcb->FileAttributes = FILE_ATTRIBUTE_NORMAL;
if (S_ISDIR(ext2_inode->i_mode))
{
Fcb->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
}
Fcb->IndexNumber.QuadPart = IndexNumber;
Fcb->ext2_inode = ext2_inode;
Fcb->inode = inode;
Fcb->dir_inode = dir_inode;
RtlZeroMemory(&Fcb->CommonFCBHeader, sizeof(FSRTL_COMMON_FCB_HEADER));
//Fcb->CommonFCBHeader.NodeTypeCode =
Fcb->CommonFCBHeader.NodeByteSize = sizeof(FSRTL_COMMON_FCB_HEADER);
Fcb->CommonFCBHeader.IsFastIoPossible = FastIoIsNotPossible;
Fcb->CommonFCBHeader.Resource = &(Fcb->MainResource);
Fcb->CommonFCBHeader.PagingIoResource = &(Fcb->PagingIoResource);
Fcb->CommonFCBHeader.AllocationSize.QuadPart = ext2_inode->i_size;
Fcb->CommonFCBHeader.FileSize.QuadPart = ext2_inode->i_size;
Fcb->CommonFCBHeader.ValidDataLength.QuadPart = ext2_inode->i_size;
Fcb->SectionObject.DataSectionObject = NULL;
Fcb->SectionObject.SharedCacheMap = NULL;
Fcb->SectionObject.ImageSectionObject = NULL;
ExInitializeResourceLite(&(Fcb->MainResource));
ExInitializeResourceLite(&(Fcb->PagingIoResource));
InsertTailList(&Vcb->FcbList, &Fcb->Next);
return Fcb;
}
VOID
Ext2FreeFcb (IN PEXT2_FCB Fcb)
{
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
FsRtlUninitializeFileLock(&Fcb->FileLockAnchor);
ExDeleteResourceLite(&Fcb->MainResource);
ExDeleteResourceLite(&Fcb->PagingIoResource);
RemoveEntryList(&Fcb->Next);
ExFreePool(Fcb->FileName.Buffer);
#if DBG
ExFreePool(Fcb->DbgFileName);
#endif
ExFreePool(Fcb->ext2_inode);
ExFreePool(Fcb);
}
PEXT2_CCB
Ext2AllocateCcb (VOID)
{
PEXT2_CCB Ccb;
Ccb = (PEXT2_CCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_CCB));
if (!Ccb)
{
return NULL;
}
Ccb->Identifier.Type = CCB;
Ccb->Identifier.Size = sizeof(EXT2_CCB);
Ccb->CurrentByteOffset = 0;
Ccb->DirectorySearchPattern.Length = 0;
Ccb->DirectorySearchPattern.MaximumLength = 0;
Ccb->DirectorySearchPattern.Buffer = 0;
return Ccb;
}
VOID
Ext2FreeCcb (IN PEXT2_CCB Ccb)
{
ASSERT(Ccb != NULL);
ASSERT((Ccb->Identifier.Type == CCB) &&
(Ccb->Identifier.Size == sizeof(EXT2_CCB)));
if (Ccb->DirectorySearchPattern.Buffer != NULL)
{
ExFreePool(Ccb->DirectorySearchPattern.Buffer);
}
ExFreePool(Ccb);
}
VOID
Ext2FreeVcb (IN PEXT2_VCB Vcb )
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
ExAcquireResourceExclusiveLite(
&Ext2Global->Resource,
TRUE );
RemoveEntryList(&Vcb->Next);
ExReleaseResourceForThreadLite(
&Ext2Global->Resource,
ExGetCurrentResourceThread() );
ExDeleteResourceLite(&Vcb->MainResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
if (Vcb->ext2_super_block)
ExFreePool(Vcb->ext2_super_block);
if (Vcb->ext2_group_desc)
ExFreePool(Vcb->ext2_group_desc);
IoDeleteDevice(Vcb->DeviceObject);
}
BOOLEAN
Ext2FastIoCheckIfPossible (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
)
{
BOOLEAN Status = FALSE;
PEXT2_FCB Fcb;
LARGE_INTEGER lLength;
lLength.QuadPart = Length;
PAGED_CODE();
__try
{
__try
{
if (DeviceObject == Ext2Global->DeviceObject)
{
Status = FALSE;
__leave;
}
Fcb = (PEXT2_FCB) FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == VCB)
{
Status = FALSE;
__leave;
}
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
if (Fcb->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
Status = FALSE;
__leave;
}
FsRtlEnterFileSystem();
if (CheckForReadOperation)
{
Status = FsRtlFastCheckLockForRead(
&Fcb->FileLockAnchor,
FileOffset,
&lLength,
LockKey,
FileObject,
PsGetCurrentProcess());
}
else
{
Status = FsRtlFastCheckLockForWrite(
&Fcb->FileLockAnchor,
FileOffset,
&lLength,
LockKey,
FileObject,
PsGetCurrentProcess());
}
#if DBG
KdPrint(("Ext2FastIOCheckPossible: %-16.16s %-31s %s\n",
PsGetCurrentProcess()->ImageFileName,
"FASTIO_CHECK_IF_POSSIBLE",
Fcb->DbgFileName));
#endif
KdPrint(("Ext2FastIIOCheckPossible: Offset: %I64u Length: %u Key: %u %s %s\n",
FileOffset->QuadPart,
Length,
LockKey,
(CheckForReadOperation ? "CheckForReadOperation:" : "CheckForWriteOperation:"),
(Status ? "Succeeded" : "Failed")));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = FALSE;
}
}
__finally
{
FsRtlExitFileSystem();
}
return Status;
}
#if DBG
BOOLEAN
Ext2FastIoRead (IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status;
PEXT2_FCB Fcb;
PAGED_CODE();
Fcb = (PEXT2_FCB) FileObject->FsContext;
ASSERT(Fcb != NULL);
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
Status = FsRtlCopyRead (
FileObject, FileOffset, Length, Wait,
LockKey, Buffer, IoStatus, DeviceObject);
return Status;
}
#endif /* DBG */
BOOLEAN
Ext2FastIoQueryBasicInfo (IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
BOOLEAN Status = FALSE;
PEXT2_FCB Fcb;
BOOLEAN FcbMainResourceAcquired = FALSE;
PAGED_CODE();
__try
{
__try
{
if (DeviceObject == Ext2Global->DeviceObject)
{
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
Status = TRUE;
__leave;
}
Fcb = (PEXT2_FCB) FileObject->FsContext;
ASSERT(Fcb != NULL);
if (Fcb->Identifier.Type == VCB)
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
Status = TRUE;
__leave;
}
ASSERT((Fcb->Identifier.Type == FCB) &&
(Fcb->Identifier.Size == sizeof(EXT2_FCB)));
#if DBG
KdPrint((
DRIVER_NAME ": %-16.16s %-31s %s\n",
PsGetCurrentProcess()->ImageFileName,
"FASTIO_QUERY_BASIC_INFO",
Fcb->DbgFileName
));
#endif
FsRtlEnterFileSystem();
if (!ExAcquireResourceSharedLite(
&Fcb->MainResource,
Wait))
{
Status = FALSE;
__leave;
}
FcbMainResourceAcquired = TRUE;
RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
/*
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
*/
Buffer->CreationTime = Ext2SysTime(Fcb->ext2_inode->i_ctime + TIMEZONE);
Buffer->LastAccessTime = Ext2SysTime(Fcb->ext2_inode->i_atime + TIMEZONE);
Buffer->LastWriteTime = Ext2SysTime(Fcb->ext2_inode->i_mtime + TIMEZONE);
Buffer->ChangeTime = Ext2SysTime(Fcb->ext2_inode->i_mtime + TIMEZONE);
Buffer->FileAttributes = Fcb->FileAttributes;
IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
IoStatus->Status = STATUS_SUCCESS;
Status = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -