📄 memory.c
字号:
RTL_BITMAP BlockBitmap;
PVOID BitmapCache;
PBCB BitmapBcb;
LARGE_INTEGER Offset;
BOOLEAN bModified = FALSE;
Group = (Block - EXT2_FIRST_DATA_BLOCK) / (Vcb->ext2_super_block->s_blocks_per_group);
dwBlk = (Block - EXT2_FIRST_DATA_BLOCK) % Vcb->ext2_super_block->s_blocks_per_group;
Offset.QuadPart = (LONGLONG) Vcb->ext2_block;
Offset.QuadPart = Offset.QuadPart * Vcb->ext2_group_desc[Group].bg_block_bitmap;
if (Group == Vcb->ext2_groups - 1)
Length = Vcb->ext2_super_block->s_blocks_count % Vcb->ext2_super_block->s_blocks_per_group;
else
Length = Vcb->ext2_super_block->s_blocks_per_group;
if (dwBlk >= Length)
return FALSE;
if (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->ext2_block,
TRUE,
&BitmapBcb,
&BitmapCache ) )
{
Ext2DbgPrint(D_MEMORY, "Ext2DeleteBlock: PinReading error ...\n");
return FALSE;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
if (RtlCheckBit(&BlockBitmap, dwBlk) == 0)
{
Ext2DbgBreakPoint();
RtlSetBits(&BlockBitmap, dwBlk, 1);
bModified = TRUE;
}
if (bModified)
{
CcSetDirtyPinnedData(BitmapBcb, NULL );
Ext2RepinBcb(IrpContext, BitmapBcb);
Ext2AddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->ext2_block);
}
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
return (!bModified);
}
BOOLEAN
Ext2CheckBitmapConsistency(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb)
{
ULONG i, j, InodeBlocks;
for (i = 0; i < Vcb->ext2_groups; i++)
{
Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_block_bitmap);
Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_inode_bitmap);
if (i == Vcb->ext2_groups - 1)
{
InodeBlocks = ((Vcb->ext2_super_block->s_inodes_count % Vcb->ext2_super_block->s_inodes_per_group) * sizeof(EXT2_INODE) + Vcb->ext2_block - 1) / (Vcb->ext2_block);
}
else
{
InodeBlocks = (Vcb->ext2_super_block->s_inodes_per_group * sizeof(EXT2_INODE) + Vcb->ext2_block - 1) / (Vcb->ext2_block);
}
for (j = 0; j < InodeBlocks; j++ )
Ext2CheckSetBlock(IrpContext, Vcb, Vcb->ext2_group_desc[i].bg_inode_table + j);
}
return TRUE;
}
NTSTATUS
Ext2InitializeVcb(IN PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb,
PEXT2_SUPER_BLOCK Ext2Sb, PDEVICE_OBJECT TargetDevice,
PDEVICE_OBJECT VolumeDevice, PVPB Vpb)
{
BOOLEAN VcbResourceInitialized = FALSE;
USHORT VolumeLabelLength;
ULONG IoctlSize;
BOOLEAN NotifySyncInitialized = FALSE;
LONGLONG DiskSize;
LONGLONG PartSize;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING RootNode;
USHORT Buffer[2];
__try
{
if (!Vpb)
{
Status = STATUS_DEVICE_NOT_READY;
__leave;
}
RtlZeroMemory(Vcb, sizeof(EXT2_VCB));
Vcb->Identifier.Type = EXT2VCB;
Vcb->Identifier.Size = sizeof(EXT2_VCB);
Buffer[0] = L'\\';
Buffer[1] = 0;
RootNode.Buffer = Buffer;
RootNode.MaximumLength = RootNode.Length = 2;
Vcb->Ext2McbTree = Ext2AllocateMcb(Vcb, &RootNode, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);
if (!Vcb->Ext2McbTree)
__leave;
#if EXT2_READ_ONLY
SetFlag(Vcb->Flags, VCB_READ_ONLY);
#endif //READ_ONLY
if (FlagOn(gExt2Global->Flags, EXT2_SUPPORT_WRITING))
ClearFlag(Vcb->Flags, VCB_READ_ONLY);
if (FlagOn(Ext2Sb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) ||
FlagOn(Ext2Sb->s_feature_incompat, EXT3_FEATURE_INCOMPAT_RECOVER) ||
FlagOn(Ext2Sb->s_feature_compat, EXT3_FEATURE_COMPAT_HAS_JOURNAL) )
{
SetFlag(Vcb->Flags, VCB_READ_ONLY);
}
ExInitializeResourceLite(&Vcb->MainResource);
ExInitializeResourceLite(&Vcb->PagingIoResource);
ExInitializeResourceLite(&Vcb->CountResource);
VcbResourceInitialized = TRUE;
Vcb->Ext2McbTree->Inode = EXT2_ROOT_INO;
Vcb->Vpb = Vpb;
Vpb->DeviceObject = VolumeDevice;
{
VolumeLabelLength = 16;
while( (VolumeLabelLength > 0) &&
((Ext2Sb->s_volume_name[VolumeLabelLength-1] == 0x00) ||
(Ext2Sb->s_volume_name[VolumeLabelLength-1] == 0x20)) )
VolumeLabelLength--;
Ext2CharToWchar(
Vcb->Vpb->VolumeLabel,
Ext2Sb->s_volume_name,
VolumeLabelLength );
Vpb->VolumeLabelLength = VolumeLabelLength * 2;
}
Vpb->SerialNumber = ((ULONG*)Ext2Sb->s_uuid)[0] + ((ULONG*)Ext2Sb->s_uuid)[1] +
((ULONG*)Ext2Sb->s_uuid)[2] + ((ULONG*)Ext2Sb->s_uuid)[3];
Vcb->StreamObj = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice);
if (Vcb->StreamObj)
{
Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject);
Vcb->StreamObj->Vpb = Vcb->Vpb;
Vcb->StreamObj->ReadAccess = TRUE;
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
else
{
Vcb->StreamObj->WriteAccess = TRUE;
Vcb->StreamObj->DeleteAccess = TRUE;
}
Vcb->StreamObj->FsContext = (PVOID) Vcb;
Vcb->StreamObj->FsContext2 = NULL;
Vcb->StreamObj->Vpb = Vcb->Vpb;
SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING);
}
else
{
__leave;
}
InitializeListHead(&Vcb->FcbList);
InitializeListHead(&Vcb->NotifyList);
FsRtlNotifyInitializeSync(&Vcb->NotifySync);
NotifySyncInitialized = TRUE;
Vcb->DeviceObject = VolumeDevice;
Vcb->TargetDeviceObject = TargetDevice;
Vcb->OpenFileHandleCount = 0;
Vcb->ReferenceCount = 0;
Vcb->ext2_super_block = Ext2Sb;
Vcb->CommonFCBHeader.NodeTypeCode = (USHORT) EXT2VCB;
Vcb->CommonFCBHeader.NodeByteSize = sizeof(EXT2_VCB);
Vcb->CommonFCBHeader.IsFastIoPossible = FastIoIsNotPossible;
Vcb->CommonFCBHeader.Resource = &(Vcb->MainResource);
Vcb->CommonFCBHeader.PagingIoResource = &(Vcb->PagingIoResource);
Vcb->Vpb->SerialNumber = 'MATT';
IoctlSize = sizeof(DISK_GEOMETRY);
Status = Ext2DiskIoControl(
TargetDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&Vcb->DiskGeometry,
&IoctlSize );
if (!NT_SUCCESS(Status))
{
__leave;
}
DiskSize =
Vcb->DiskGeometry.Cylinders.QuadPart *
Vcb->DiskGeometry.TracksPerCylinder *
Vcb->DiskGeometry.SectorsPerTrack *
Vcb->DiskGeometry.BytesPerSector;
IoctlSize = sizeof(PARTITION_INFORMATION);
Status = Ext2DiskIoControl(
TargetDevice,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&Vcb->PartitionInformation,
&IoctlSize );
PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart;
if (!NT_SUCCESS(Status))
{
Vcb->PartitionInformation.StartingOffset.QuadPart = 0;
Vcb->PartitionInformation.PartitionLength.QuadPart =
DiskSize;
PartSize = DiskSize;
Status = STATUS_SUCCESS;
}
Vcb->CommonFCBHeader.AllocationSize.QuadPart =
Vcb->CommonFCBHeader.FileSize.QuadPart = PartSize;
Vcb->CommonFCBHeader.ValidDataLength.QuadPart =
(LONGLONG)(0x7fffffffffffffff);
/*
Vcb->CommonFCBHeader.AllocationSize.QuadPart = (LONGLONG)(ext2_super_block->s_blocks_count - ext2_super_block->s_free_blocks_count)
* (EXT2_MIN_BLOCK << ext2_super_block->s_log_block_size);
Vcb->CommonFCBHeader.FileSize.QuadPart = Vcb->CommonFCBHeader.AllocationSize.QuadPart;
Vcb->CommonFCBHeader.ValidDataLength.QuadPart = Vcb->CommonFCBHeader.AllocationSize.QuadPart;
*/
{
CC_FILE_SIZES FileSizes;
FileSizes.AllocationSize.QuadPart =
FileSizes.FileSize.QuadPart =
Vcb->CommonFCBHeader.AllocationSize.QuadPart;
FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff);
CcInitializeCacheMap( Vcb->StreamObj,
&FileSizes,
TRUE,
&(gExt2Global->CacheManagerNoOpCallbacks),
Vcb );
}
Vcb->ext2_group_desc = Ext2LoadGroup(Vcb);
if (!Vcb->ext2_group_desc)
{
Status = STATUS_UNSUCCESSFUL;
__leave;
}
FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool);
#if 0
// Understanding Mcb Routines
{
LONGLONG ByteOffset;
LONGLONG DirtyVba;
LONGLONG DirtyLba;
LONGLONG DirtyLength;
int i;
Ext2AddMcbEntry(Vcb, 0x00000000, (LONGLONG)0x400);
Ext2AddMcbEntry(Vcb, 0x00001000, (LONGLONG)0x400);
FsRtlAddLargeMcbEntry (&(Vcb->DirtyMcbs), (LONGLONG)0x3000, (LONGLONG)0x30003000FFFF0000, (LONGLONG)0x1000);
Ext2AddMcbEntry(Vcb, 0x00010000, (LONGLONG)0x400);
Ext2AddMcbEntry(Vcb, 0x00100000, (LONGLONG)0x400);
Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: initial mcb lists:\n");
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
ByteOffset = 0x100;
Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
(PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
{
Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
ByteOffset = 0x1000;
Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
(PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
{
Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
ByteOffset = 0x2000;
Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
(PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
{
Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
ByteOffset = 0x110000;
Ext2LookupMcbEntry(Vcb, ByteOffset, &DirtyLba, &DirtyLength,
(PLONGLONG)NULL, (PLONGLONG)NULL, (PULONG)NULL);
{
Ext2DbgPrint(D_MEMORY, "Lookup DirtyVba = %I64xh:\n", ByteOffset);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
Ext2RemoveMcbEntry(Vcb, 0x00003000, (LONGLONG)0x400);
Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: After Removing 0x300(0x400):\n");
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
Ext2RemoveMcbEntry(Vcb, 0x00003000, (LONGLONG)0x1000);
Ext2DbgPrint(D_MEMORY, "Ext2InitializeVcb: After Removing 0x300(0x1000):\n");
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n", DirtyLength);
}
Ext2RemoveMcbEntry(Vcb, 0x00000000, (LONGLONG)0x400);
Ext2RemoveMcbEntry(Vcb, 0x00001000, (LONGLONG)0x400);
Ext2RemoveMcbEntry(Vcb, 0x00010000, (LONGLONG)0x400);
Ext2RemoveMcbEntry(Vcb, 0x00100000, (LONGLONG)0x400);
}
#endif
InsertTailList(&(gExt2Global->VcbList), &Vcb->Next);
if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
Ext2CheckBitmapConsistency(IrpContext, Vcb);
SetFlag(Vcb->Flags, VCB_INITIALIZED);
}
__finally
{
if (!NT_SUCCESS(Status))
{
if (NotifySyncInitialized)
{
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
}
if (Vcb->ext2_group_desc)
{
ExFreePool(Vcb->ext2_group_desc);
}
if (VcbResourceInitialized)
{
ExDeleteResourceLite(&Vcb->CountResource);
ExDeleteResourceLite(&Vcb->MainResource);
ExDeleteResourceLite(&Vcb->PagingIoResource);
}
}
}
return Status;
}
VOID
Ext2FreeVcb (IN PEXT2_VCB Vcb )
{
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
(Vcb->Identifier.Size == sizeof(EXT2_VCB)));
Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
ExAcquireResourceExclusiveLite(
&gExt2Global->Resource,
TRUE );
if (Vcb->StreamObj)
{
if (Vcb->StreamObj->PrivateCacheMap)
Ext2SyncUninitializeCacheMap(Vcb->StreamObj);
ObDereferenceObject(Vcb->StreamObj);
Vcb->StreamObj = NULL;
}
RemoveEntryList(&Vcb->Next);
ExReleaseResourceForThreadLite(
&gExt2Global->Resource,
ExGetCurrentResourceThread() );
ExDeleteResourceLite(&Vcb->CountResource);
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);
}
#if DBG
if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0)
{
LONGLONG DirtyVba;
LONGLONG DirtyLba;
LONGLONG DirtyLength;
int i;
for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++)
{
Ext2DbgPrint(D_MEMORY, "DirtyVba = %I64xh\n", DirtyVba);
Ext2DbgPrint(D_MEMORY, "DirtyLba = %I64xh\n", DirtyLba);
Ext2DbgPrint(D_MEMORY, "DirtyLen = %I64xh\n\n", DirtyLength);
}
Ext2DbgBreakPoint();
}
#endif
FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs));
Ext2FreeMcbTree(Vcb->Ext2McbTree);
IoDeleteDevice(Vcb->DeviceObject);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -