📄 memory.c
字号:
if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) {
ExFreePool( Fcb );
} else {
ExFreeToNPagedLookasideList(&(gExt2Global->Ext2FcbLookasideList), Fcb);
}
#if DBG
ExAcquireResourceExclusiveLite(
&gExt2Global->Resource,
TRUE );
gExt2Global->FcbAllocated--;
ExReleaseResourceForThreadLite(
&gExt2Global->Resource,
ExGetCurrentResourceThread() );
#endif
}
PEXT2_CCB
Ext2AllocateCcb (VOID)
{
PEXT2_CCB Ccb;
Ccb = (PEXT2_CCB) (ExAllocateFromNPagedLookasideList( &(gExt2Global->Ext2CcbLookasideList)));
if (Ccb == NULL)
{
Ccb = (PEXT2_CCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_CCB));
RtlZeroMemory(Ccb, sizeof(EXT2_CCB));
SetFlag(Ccb->Flags, CCB_FROM_POOL);
}
else
{
RtlZeroMemory(Ccb, sizeof(EXT2_CCB));
}
if (!Ccb)
{
return NULL;
}
Ccb->Identifier.Type = EXT2CCB;
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 == EXT2CCB) &&
(Ccb->Identifier.Size == sizeof(EXT2_CCB)));
if (Ccb->DirectorySearchPattern.Buffer != NULL)
{
ExFreePool(Ccb->DirectorySearchPattern.Buffer);
}
if (FlagOn(Ccb->Flags, CCB_FROM_POOL)) {
ExFreePool( Ccb );
} else {
ExFreeToNPagedLookasideList(&(gExt2Global->Ext2CcbLookasideList), Ccb);
}
}
PEXT2_MCB
Ext2AllocateMcb (PEXT2_VCB Vcb, PUNICODE_STRING FileName, ULONG FileAttr)
{
PEXT2_MCB Mcb = NULL;
ULONG i, Extra = 0;
if (gExt2Global->McbAllocated > (gExt2Global->MaxDepth << 1))
Extra = gExt2Global->McbAllocated - (gExt2Global->MaxDepth << 1) + gExt2Global->MaxDepth;
#if DBG
Ext2DbgPrint(D_MEMORY, "Ext2AllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n",
gExt2Global->McbAllocated,
gExt2Global->MaxDepth << 1,
gExt2Global->FcbAllocated,
FileName->Buffer);
#endif
for (i = 0; i < Extra; i++)
{
Ext2FindUnusedMcb(Vcb->Ext2McbTree, &Mcb);
if (Mcb && (Mcb->Inode != 2))
{
Ext2DbgPrint(D_MEMORY, "Ext2AllocateMcb: Mcb %S will be freed.\n", Mcb->ShortName.Buffer);
if (Ext2DeleteMcbNode(Vcb->Ext2McbTree, Mcb))
Ext2FreeMcb(Mcb);
Mcb = NULL;
}
else
{
Ext2DbgPrint(D_MEMORY, "Ext2AllocateMcb: (%xh/%xh) Could not find free mcbs.\n", i, Extra);
break;
}
}
Mcb = (PEXT2_MCB) (ExAllocateFromPagedLookasideList( &(gExt2Global->Ext2McbLookasideList)));
if (Mcb == NULL)
{
Mcb = (PEXT2_MCB)ExAllocatePool(PagedPool, sizeof(EXT2_MCB));
RtlZeroMemory(Mcb, sizeof(EXT2_MCB));
SetFlag(Mcb->Flags, MCB_FROM_POOL);
}
else
{
RtlZeroMemory(Mcb, sizeof(EXT2_MCB));
}
if (!Mcb)
{
return NULL;
}
Mcb->Identifier.Type = EXT2MCB;
Mcb->Identifier.Size = sizeof(EXT2_MCB);
if (FileName && FileName->Length)
{
Mcb->ShortName.Length = FileName->Length;
Mcb->ShortName.MaximumLength = Mcb->ShortName.Length + 2;
Mcb->ShortName.Buffer = ExAllocatePool(PagedPool, Mcb->ShortName.MaximumLength);
if (!Mcb->ShortName.Buffer)
goto errorout;
RtlZeroMemory(Mcb->ShortName.Buffer, Mcb->ShortName.MaximumLength);
RtlCopyMemory(Mcb->ShortName.Buffer, FileName->Buffer, Mcb->ShortName.Length);
}
Mcb->FileAttr = FileAttr;
KeQuerySystemTime((PLARGE_INTEGER) (&Mcb->TickerCount));
ExAcquireResourceExclusiveLite(
&gExt2Global->Resource,
TRUE );
gExt2Global->McbAllocated++;
ExReleaseResourceForThreadLite(
&gExt2Global->Resource,
ExGetCurrentResourceThread() );
return Mcb;
errorout:
if (Mcb)
{
if (Mcb->ShortName.Buffer)
ExFreePool(Mcb->ShortName.Buffer);
if (FlagOn(Mcb->Flags, MCB_FROM_POOL)) {
ExFreePool( Mcb );
} else {
ExFreeToPagedLookasideList(&(gExt2Global->Ext2McbLookasideList), Mcb);
}
}
return NULL;
}
VOID
Ext2FreeMcb (IN PEXT2_MCB Mcb)
{
ASSERT(Mcb != NULL);
ASSERT((Mcb->Identifier.Type == EXT2MCB) &&
(Mcb->Identifier.Size == sizeof(EXT2_MCB)));
Ext2DbgPrint(D_MEMORY, "Ext2FreeMcb: Mcb %S will be freed.\n", Mcb->ShortName.Buffer);
if (Mcb->ShortName.Buffer)
ExFreePool(Mcb->ShortName.Buffer);
if (FlagOn(Mcb->Flags, MCB_FROM_POOL)) {
ExFreePool( Mcb );
} else {
ExFreeToPagedLookasideList(&(gExt2Global->Ext2McbLookasideList), Mcb);
}
ExAcquireResourceExclusiveLite(
&gExt2Global->Resource,
TRUE );
gExt2Global->McbAllocated--;
ExReleaseResourceForThreadLite(
&gExt2Global->Resource,
ExGetCurrentResourceThread() );
}
PEXT2_FCB
Ext2CreateFcbFromMcb(PEXT2_VCB Vcb, PEXT2_MCB Mcb)
{
PEXT2_FCB Fcb = NULL;
EXT2_INODE Ext2Ino;
if (Mcb->Ext2Fcb)
return Mcb->Ext2Fcb;
if (Ext2LoadInode(Vcb, Mcb->Inode, &Ext2Ino))
{
PEXT2_INODE pTmpInode = ExAllocatePool(PagedPool, sizeof(EXT2_INODE));
if (!pTmpInode)
{
goto errorout;
}
RtlCopyMemory(pTmpInode, &Ext2Ino, sizeof(EXT2_INODE));
Fcb = Ext2AllocateFcb(Vcb, Mcb, pTmpInode);
if (!Fcb)
{
ExFreePool(pTmpInode);
}
}
errorout:
return Fcb;
}
BOOLEAN
Ext2GetFullFileName(PEXT2_MCB Mcb, PUNICODE_STRING FileName)
{
USHORT Length = 0;
PEXT2_MCB TmpMcb = Mcb;
PUNICODE_STRING FileNames[256];
SHORT Count = 0 , i = 0, j = 0;
while(TmpMcb && Count < 256)
{
if (TmpMcb->Inode == EXT2_ROOT_INO)
break;
FileNames[Count++] = &TmpMcb->ShortName;
Length += (2 + TmpMcb->ShortName.Length);
TmpMcb = TmpMcb->Parent;
}
if (Count >= 256)
return FALSE;
if (Count ==0)
Length = 2;
FileName->Length = Length;
FileName->MaximumLength = Length + 2;
FileName->Buffer = ExAllocatePool(PagedPool, Length + 2);
if (!FileName->Buffer)
return FALSE;
RtlZeroMemory(FileName->Buffer, FileName->MaximumLength);
if (Count ==0)
{
FileName->Buffer[0] = L'\\';
return TRUE;
}
for (i = Count - 1; i >= 0 && j < (SHORT)(FileName->MaximumLength); i--)
{
FileName->Buffer[j++] = L'\\';
RtlCopyMemory(&(FileName->Buffer[j]), FileNames[i]->Buffer, FileNames[i]->Length);
j += FileNames[i]->Length / 2;
}
return TRUE;
}
PEXT2_MCB
Ext2SearchMcbTree(PEXT2_MCB Ext2Mcb, ULONG Inode)
{
PEXT2_MCB TmpMcb = NULL;
if (!Ext2Mcb)
return NULL;
if (Ext2Mcb->Inode == Inode)
return Ext2Mcb;
TmpMcb = Ext2SearchMcbTree(Ext2Mcb->Next, Inode);
if (TmpMcb)
return TmpMcb;
TmpMcb = Ext2SearchMcbTree(Ext2Mcb->Child, Inode);
return TmpMcb;
}
PEXT2_MCB
Ext2SearchMcb(PEXT2_MCB Parent, PUNICODE_STRING FileName)
{
PEXT2_MCB TmpMcb = Parent->Child;
while (TmpMcb)
{
if (!RtlCompareUnicodeString(
&(TmpMcb->ShortName),
FileName, TRUE ))
break;
TmpMcb = TmpMcb->Next;
}
return TmpMcb;
}
VOID
Ext2AddMcbNode(PEXT2_MCB Parent, PEXT2_MCB Child)
{
PEXT2_MCB TmpMcb = Parent->Child;
if(IsFlagOn(Child->Flags, MCB_IN_TREE))
{
Ext2DbgPrint(D_MEMORY, "Ext2AddMcbNode: Child Mcb is alreay in the tree.\n");
return;
}
if (TmpMcb)
{
while (TmpMcb->Next)
{
TmpMcb = TmpMcb->Next;
}
TmpMcb->Next = Child;
Child->Parent = TmpMcb->Parent;
Child->Next = NULL;
}
else
{
Parent->Child = Child;
Child->Parent = Parent;
Child->Next = NULL;
}
SetFlag(Child->Flags, MCB_IN_TREE);
}
BOOLEAN
Ext2DeleteMcbNode(PEXT2_MCB Ext2McbTree, PEXT2_MCB Ext2Mcb)
{
PEXT2_MCB TmpMcb;
if(!IsFlagOn(Ext2Mcb->Flags, MCB_IN_TREE))
{
Ext2DbgPrint(D_MEMORY, "Ext2DeleteMcbNode: Child Mcb is not in the tree.\n");
return TRUE;
}
if (Ext2Mcb->Parent)
{
if (Ext2Mcb->Parent->Child == Ext2Mcb)
{
Ext2Mcb->Parent->Child = Ext2Mcb->Next;
}
else
{
TmpMcb = Ext2Mcb->Parent->Child;
while (TmpMcb && TmpMcb->Next != Ext2Mcb)
TmpMcb = TmpMcb->Next;
if (TmpMcb)
{
TmpMcb->Next = Ext2Mcb->Next;
}
else
{
// error
return FALSE;
}
}
}
else if (Ext2Mcb->Child)
{
return FALSE;
}
ClearFlag(Ext2Mcb->Flags, MCB_IN_TREE);
return TRUE;
}
int Ext2GetMcbDepth(PEXT2_MCB Ext2Mcb)
{
int i=0;
PEXT2_MCB TmpMcb = Ext2Mcb;
while (TmpMcb)
{
TmpMcb = TmpMcb->Parent;
i++;
}
return i;
}
BOOLEAN
Ext2CompareMcb(PEXT2_MCB Ext2Mcb1, PEXT2_MCB Ext2Mcb2)
{
if (Ext2Mcb2 && Ext2Mcb2->Ext2Fcb == NULL && Ext2Mcb2->Child == NULL)
{
if (Ext2Mcb1 == NULL)
{
return TRUE;
}
else
{
if (!FlagOn(Ext2Mcb2->FileAttr, FILE_ATTRIBUTE_DIRECTORY) &&
FlagOn(Ext2Mcb1->FileAttr, FILE_ATTRIBUTE_DIRECTORY) )
{
return TRUE;
}
else if (Ext2Mcb2->TickerCount < Ext2Mcb1->TickerCount)
{
return TRUE;
}
else
{
int Depth1, Depth2;
Depth1 = Ext2GetMcbDepth(Ext2Mcb1);
Depth2 = Ext2GetMcbDepth(Ext2Mcb2);
if (Depth2 > Depth1)
{
return TRUE;
}
}
}
}
return FALSE;
}
VOID
Ext2FindUnusedMcb (PEXT2_MCB Ext2McbTree, PEXT2_MCB* Ext2Mcb)
{
if (!Ext2McbTree)
return;
if (Ext2CompareMcb(*Ext2Mcb, Ext2McbTree))
*Ext2Mcb = Ext2McbTree;
//Ext2DbgPrint(D_MEMORY, "Ext2FindUnusedMcb: Mcb->Inode=%xh Name=%S\n", Ext2McbTree->Inode, Ext2McbTree->ShortName.Buffer);
Ext2FindUnusedMcb(Ext2McbTree->Child, Ext2Mcb);
Ext2FindUnusedMcb(Ext2McbTree->Next, Ext2Mcb);
}
VOID Ext2FreeMcbTree(PEXT2_MCB McbTree)
{
if (!McbTree)
return;
if (McbTree->Child)
Ext2FreeMcbTree(McbTree->Child);
if (McbTree->Next)
Ext2FreeMcbTree(McbTree->Next);
Ext2FreeMcb(McbTree);
}
BOOLEAN
Ext2CheckSetBlock(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, ULONG Block)
{
ULONG Group, dwBlk, Length;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -