⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -