📄 ext2.c
字号:
nBeg = offset / Vcb->ext2_block;
nEnd = (size + offset + Vcb->ext2_block - 1) / Vcb->ext2_block;
nBlocks = 0;
if ((nEnd - nBeg) > 0)
{
ext2bdl = ExAllocatePool(PagedPool, sizeof(EXT2_BDL) * (nEnd - nBeg));
if (ext2bdl)
{
RtlZeroMemory(ext2bdl, sizeof(EXT2_BDL) * (nEnd - nBeg));
for (i = nBeg; i < nEnd; i++)
{
dwBlk = Ext2BlockMap(Vcb, ext2_inode, i);
if (dwBlk > 0)
{
lba = (LONGLONG) dwBlk;
lba = lba * Vcb->ext2_block;
if (nBeg == nEnd - 1) // ie. (nBeg == nEnd - 1)
{
dwBytes = size;
ext2bdl[nBlocks].Lba = lba + (LONGLONG)(offset % (Vcb->ext2_block));
ext2bdl[nBlocks].Length = dwBytes;
ext2bdl[nBlocks].Offset = 0;
nBlocks++;
}
else
{
if (i == nBeg)
{
dwBytes = Vcb->ext2_block - (offset % (Vcb->ext2_block));
ext2bdl[nBlocks].Lba = lba + (LONGLONG)(offset % (Vcb->ext2_block));
ext2bdl[nBlocks].Length = dwBytes;
ext2bdl[nBlocks].Offset = 0;
nBlocks++;
}
else if (i == nEnd - 1)
{
if (ext2bdl[nBlocks - 1].Lba + ext2bdl[nBlocks - 1].Length == lba)
{
ext2bdl[nBlocks - 1].Length += size - dwBytes;
}
else
{
ext2bdl[nBlocks].Lba = lba;
ext2bdl[nBlocks].Length = size - dwBytes;
ext2bdl[nBlocks].Offset = dwBytes;
nBlocks++;
}
dwBytes = size;
}
else
{
if (ext2bdl[nBlocks - 1].Lba + ext2bdl[nBlocks - 1].Length == lba)
{
ext2bdl[nBlocks - 1].Length += Vcb->ext2_block;
}
else
{
ext2bdl[nBlocks].Lba = lba;
ext2bdl[nBlocks].Length = Vcb->ext2_block;
ext2bdl[nBlocks].Offset = dwBytes;
nBlocks++;
}
dwBytes += Vcb->ext2_block;
}
}
}
else
{
break;
}
}
*ext2_bdl = ext2bdl;
return nBlocks;
}
}
// Error
return 0;
}
BOOLEAN Ext2NewBlock( PEXT2_IRP_CONTEXT IrpContext,
PEXT2_VCB Vcb,
ULONG GroupHint,
ULONG BlockHint,
PULONG dwRet )
{
RTL_BITMAP BlockBitmap;
LARGE_INTEGER Offset;
ULONG Length;
PBCB BitmapBcb;
PVOID BitmapCache;
ULONG Group = 0, dwBlk, dwHint = 0;
*dwRet = 0;
dwBlk = 0XFFFFFFFF;
if (GroupHint > Vcb->ext2_groups)
GroupHint = Vcb->ext2_groups - 1;
if (BlockHint != 0)
{
GroupHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) / Vcb->ext2_super_block->s_blocks_per_group;
dwHint = (BlockHint - EXT2_FIRST_DATA_BLOCK) % Vcb->ext2_super_block->s_blocks_per_group;
}
ScanBitmap:
// Perform Prefered Group
if (Vcb->ext2_group_desc[GroupHint].bg_free_blocks_count)
{
Offset.QuadPart = (LONGLONG) Vcb->ext2_block;
Offset.QuadPart = Offset.QuadPart * Vcb->ext2_group_desc[GroupHint].bg_block_bitmap;
if (GroupHint == 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 (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->ext2_block,
TRUE,
&BitmapBcb,
&BitmapCache ) )
{
Ext2DbgPrint(D_EXT2, "Ext2NewBlock: PinReading error ...\n");
return FALSE;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
Group = GroupHint;
if (RtlCheckBit(&BlockBitmap, dwHint) == 0)
{
dwBlk = dwHint;
}
else
{
dwBlk = RtlFindClearBits(&BlockBitmap, 1, dwHint);
}
// We could not get new block in the prefered group.
if (dwBlk == 0xFFFFFFFF)
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
}
if (dwBlk == 0xFFFFFFFF)
{
for(Group = 0; Group < Vcb->ext2_groups; Group++)
if (Vcb->ext2_group_desc[Group].bg_free_blocks_count)
{
if (Group == GroupHint)
continue;
Offset.QuadPart = (LONGLONG) Vcb->ext2_block;
Offset.QuadPart = Offset.QuadPart * Vcb->ext2_group_desc[Group].bg_block_bitmap;
if (Vcb->ext2_groups == 1)
{
Length = Vcb->ext2_super_block->s_blocks_count;
}
else
{
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 (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->ext2_block,
TRUE,
&BitmapBcb,
&BitmapCache ) )
{
Ext2DbgPrint(D_EXT2, "Ext2NewBlock: PinReading error ...\n");
return FALSE;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
dwBlk = RtlFindClearBits(&BlockBitmap, 1, 0);
if (dwBlk != 0xFFFFFFFF)
{
break;
}
else
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
}
}
if (dwBlk < Length)
{
RtlSetBits(&BlockBitmap, dwBlk, 1);
CcSetDirtyPinnedData(BitmapBcb, NULL );
Ext2RepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
Ext2AddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->ext2_block);
*dwRet = dwBlk + EXT2_FIRST_DATA_BLOCK + Group * Vcb->ext2_super_block->s_blocks_per_group;
//Updating Group Desc / Superblock
Vcb->ext2_group_desc[Group].bg_free_blocks_count--;
Ext2SaveGroup(IrpContext, Vcb);
Vcb->ext2_super_block->s_free_blocks_count--;
Ext2SaveSuper(IrpContext, Vcb);
{
ULONG i=0;
for (i=0; i < Vcb->ext2_groups; i++)
{
if ((Vcb->ext2_group_desc[i].bg_block_bitmap == *dwRet) ||
(Vcb->ext2_group_desc[i].bg_inode_bitmap == *dwRet) ||
(Vcb->ext2_group_desc[i].bg_inode_table == *dwRet) )
{
Ext2DbgBreakPoint();
GroupHint = Group;
goto ScanBitmap;
}
}
}
return TRUE;
}
return FALSE;
}
BOOLEAN Ext2FreeBlock( PEXT2_IRP_CONTEXT IrpContext,
PEXT2_VCB Vcb,
ULONG Block )
{
RTL_BITMAP BlockBitmap;
LARGE_INTEGER Offset;
ULONG Length;
PBCB BitmapBcb;
PVOID BitmapCache;
ULONG Group, dwBlk;
BOOLEAN bModified = FALSE;
if (Block < EXT2_FIRST_DATA_BLOCK || Block > (Vcb->ext2_super_block->s_blocks_per_group * Vcb->ext2_groups))
{
Ext2DbgBreakPoint();
return TRUE;
}
Ext2DbgPrint(D_EXT2, "Ext2FreeBlock: Block %xh to be freed.\n", Block);
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 (!CcPinRead( Vcb->StreamObj,
&Offset,
Vcb->ext2_block,
TRUE,
&BitmapBcb,
&BitmapCache ) )
{
Ext2DbgPrint(D_EXT2, "Ext2DeleteBlock: PinReading error ...\n");
return FALSE;
}
RtlInitializeBitMap( &BlockBitmap,
BitmapCache,
Length );
if (RtlCheckBit(&BlockBitmap, dwBlk) == 0)
{
}
else
{
RtlClearBits(&BlockBitmap, dwBlk, 1);
bModified = TRUE;
}
if (!bModified)
{
CcUnpinData(BitmapBcb);
BitmapBcb = NULL;
BitmapCache = NULL;
RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
}
}
if (bModified)
{
CcSetDirtyPinnedData(BitmapBcb, NULL );
Ext2RepinBcb(IrpContext, BitmapBcb);
CcUnpinData(BitmapBcb);
Ext2AddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->ext2_block);
//Updating Group Desc / Superblock
Vcb->ext2_group_desc[Group].bg_free_blocks_count++;
Ext2SaveGroup(IrpContext, Vcb);
Vcb->ext2_super_block->s_free_blocks_count++;
Ext2SaveSuper(IrpContext, Vcb);
return TRUE;
}
return FALSE;
}
BOOLEAN Ext2ExpandBlock(PEXT2_IRP_CONTEXT IrpContext,
PEXT2_VCB Vcb,
PEXT2_FCB Fcb,
ULONG dwContent,
ULONG Index,
ULONG layer,
BOOLEAN bNew,
ULONG *dwRet)
{
ULONG *pData = NULL;
ULONG i = 0, j = 0, temp = 1;
ULONG dwNewBlk = 0, dwBlk = 0;
BOOLEAN bDirty = FALSE;
BOOLEAN bRet = TRUE;
PEXT2_SUPER_BLOCK pExt2Sb = Vcb->ext2_super_block;
pData = (ULONG *) ExAllocatePool(PagedPool, Vcb->ext2_block);
if (!pData)
{
return FALSE;
}
RtlZeroMemory(pData, Vcb->ext2_block);
if (bNew)
{
if (layer == 0 && !IsFlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
LARGE_INTEGER Offset;
Offset.QuadPart = (LONGLONG) dwContent;
Offset.QuadPart = Offset.QuadPart * Vcb->ext2_block;
Ext2RemoveMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->ext2_block);
/*
if (Vcb->SectionObject)
{
CcFlushCache( &(Vcb->SectionObject),
(PLARGE_INTEGER)&(Offset),
Vcb->ext2_block,
NULL);
if (Vcb->SectionObject.DataSectionObject != NULL)
{
ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
ExReleaseResource(&Vcb->PagingIoResource);
CcPurgeCacheSection( &(Vcb->SectionObject),
(PLARGE_INTEGER)(&Offset),
Vcb->ext2_block,
FALSE );
}
}
*/
}
else
{
if (!Ext2SaveBlock(IrpContext, Vcb, dwContent, (PVOID)pData))
{
bRet = FALSE;
goto errorout;
}
}
}
if (layer == 0)
{
dwNewBlk = dwContent;
}
else if (layer <= 3)
{
if (!bNew)
{
bRet = Ext2LoadBlock(Vcb, dwContent, (void *)pData);
if (!bRet) goto errorout;
}
temp = 1 << ((10 + pExt2Sb->s_log_block_size - 2) * (layer - 1));
i = Index / temp;
j = Index % temp;
dwBlk = pData[i];
if (dwBlk == 0)
{
if (!Ext2NewBlock(IrpContext, Vcb, 0, dwContent, &dwBlk))
{
bRet = FALSE;
Ext2DbgPrint(D_EXT2, "Ext2ExpandBlock: get new block error.\n");
goto errorout;
}
pData[i] = dwBlk;
bDirty = TRUE;
}
if (!Ext2ExpandBlock(IrpContext, Vcb, Fcb, dwBlk, j, layer - 1, bDirty, &dwNewBlk))
{
bRet = FALSE;
Ext2DbgPrint(D_EXT2, "Ext2ExpandBlockk: ... error recuise...\n");
goto errorout;
}
if (bDirty)
{
bRet = Ext2SaveBlock(IrpContext, Vcb, dwContent, (void *)pData);
}
}
errorout:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -