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

📄 memory.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:
    ExDeleteResourceLite(&Fcb->MainResource);
    
    ExDeleteResourceLite(&Fcb->PagingIoResource);
    
    Fcb->RfsdMcb->RfsdFcb = NULL;

    if(IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
        if (Fcb->RfsdMcb) {
            RfsdDeleteMcbNode(Vcb, Fcb->RfsdMcb->Parent, Fcb->RfsdMcb);
            RfsdFreeMcb(Fcb->RfsdMcb);
        }
    }

    if (Fcb->LongName.Buffer) {
        ExFreePool(Fcb->LongName.Buffer);
        Fcb->LongName.Buffer = NULL;
    }

#if DBG    
    ExFreePool(Fcb->AnsiFileName.Buffer);
#endif

    ExFreePool(Fcb->Inode);

    Fcb->Header.NodeTypeCode = (SHORT)0xCCCC;
    Fcb->Header.NodeByteSize = (SHORT)0xC0C0;

    if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) {

        ExFreePool( Fcb );

    } else {

        ExAcquireResourceExclusiveLite(
                    &RfsdGlobal->LAResource,
                    TRUE );

        ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdFcbLookasideList), Fcb);

        ExReleaseResourceForThreadLite(
                    &RfsdGlobal->LAResource,
                    ExGetCurrentResourceThread() );
    }

#if DBG

    ExAcquireResourceExclusiveLite(
        &RfsdGlobal->CountResource,
        TRUE );

    RfsdGlobal->FcbAllocated--;

    ExReleaseResourceForThreadLite(
        &RfsdGlobal->CountResource,
        ExGetCurrentResourceThread() );
#endif

}

PRFSD_CCB
RfsdAllocateCcb (VOID)
{
    PRFSD_CCB Ccb;

    ExAcquireResourceExclusiveLite(
            &RfsdGlobal->LAResource,
            TRUE );

    Ccb = (PRFSD_CCB) (ExAllocateFromNPagedLookasideList( &(RfsdGlobal->RfsdCcbLookasideList)));

    ExReleaseResourceForThreadLite(
            &RfsdGlobal->LAResource,
            ExGetCurrentResourceThread() );
    
    if (Ccb == NULL) {
        Ccb = (PRFSD_CCB)ExAllocatePool(NonPagedPool, sizeof(RFSD_CCB));

        RtlZeroMemory(Ccb, sizeof(RFSD_CCB));

        SetFlag(Ccb->Flags, CCB_FROM_POOL);
    } else {
        RtlZeroMemory(Ccb, sizeof(RFSD_CCB));
    }

    if (!Ccb) {
        return NULL;
    }
    
    Ccb->Identifier.Type = RFSDCCB;
    Ccb->Identifier.Size = sizeof(RFSD_CCB);
    
    Ccb->CurrentByteOffset = 0;
    
    Ccb->DirectorySearchPattern.Length = 0;
    Ccb->DirectorySearchPattern.MaximumLength = 0;
    Ccb->DirectorySearchPattern.Buffer = 0;
    
    return Ccb;
}

VOID
RfsdFreeCcb (IN PRFSD_CCB Ccb)
{
    ASSERT(Ccb != NULL);
    
    ASSERT((Ccb->Identifier.Type == RFSDCCB) &&
        (Ccb->Identifier.Size == sizeof(RFSD_CCB)));
    
    if (Ccb->DirectorySearchPattern.Buffer != NULL) {
        ExFreePool(Ccb->DirectorySearchPattern.Buffer);
    }

    if (FlagOn(Ccb->Flags, CCB_FROM_POOL)) {

        ExFreePool( Ccb );

    } else {

        ExAcquireResourceExclusiveLite(
                &RfsdGlobal->LAResource,
                TRUE );

        ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdCcbLookasideList), Ccb);

        ExReleaseResourceForThreadLite(
                &RfsdGlobal->LAResource,
                ExGetCurrentResourceThread() );
    }
}

PRFSD_MCB
RfsdAllocateMcb (PRFSD_VCB Vcb, PUNICODE_STRING FileName, ULONG FileAttr)
{
    PRFSD_MCB   Mcb = NULL;
    PLIST_ENTRY List = NULL;

    ULONG       Extra = 0;

#define MCB_NUM_SHIFT   0x04

    if (RfsdGlobal->McbAllocated > (RfsdGlobal->MaxDepth <<  MCB_NUM_SHIFT))
        Extra = RfsdGlobal->McbAllocated - 
                (RfsdGlobal->MaxDepth << MCB_NUM_SHIFT) +
                RfsdGlobal->MaxDepth;

    RfsdPrint((DBG_INFO,
            "RfsdAllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n", 
            RfsdGlobal->McbAllocated,
            RfsdGlobal->MaxDepth << MCB_NUM_SHIFT,
            RfsdGlobal->FcbAllocated,
            FileName->Buffer));

    List = Vcb->McbList.Flink;

    while ((List != &(Vcb->McbList)) && (Extra > 0)) {
        Mcb = CONTAINING_RECORD(List, RFSD_MCB, Link);
        List = List->Flink;

        if ((!RFSD_IS_ROOT_KEY(Mcb->Key)) && (Mcb->Child == NULL) &&
            (Mcb->RfsdFcb == NULL) && (!IsMcbUsed(Mcb))) {
            RfsdPrint((DBG_INFO, "RfsdAllocateMcb: Mcb %S will be freed.\n",
                                 Mcb->ShortName.Buffer));

            if (RfsdDeleteMcbNode(Vcb, Vcb->McbTree, Mcb)) {
                RfsdFreeMcb(Mcb);

                Extra--;
            }
        }
    }

    ExAcquireResourceExclusiveLite(
            &RfsdGlobal->LAResource,
            TRUE );

    Mcb = (PRFSD_MCB) (ExAllocateFromPagedLookasideList(
                         &(RfsdGlobal->RfsdMcbLookasideList)));
  
    ExReleaseResourceForThreadLite(
            &RfsdGlobal->LAResource,
            ExGetCurrentResourceThread() );
    
    if (Mcb == NULL) {
        Mcb = (PRFSD_MCB)ExAllocatePool(PagedPool, sizeof(RFSD_MCB));
        
        RtlZeroMemory(Mcb, sizeof(RFSD_MCB));
        
        SetFlag(Mcb->Flags, MCB_FROM_POOL);
    } else {
        RtlZeroMemory(Mcb, sizeof(RFSD_MCB));
    }
    
    if (!Mcb) {
        return NULL;
    }

    Mcb->Identifier.Type = RFSDMCB;
    Mcb->Identifier.Size = sizeof(RFSD_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;

    ExAcquireResourceExclusiveLite(
        &RfsdGlobal->CountResource,
        TRUE );

    RfsdGlobal->McbAllocated++;

    ExReleaseResourceForThreadLite(
        &RfsdGlobal->CountResource,
        ExGetCurrentResourceThread() );

    return Mcb;

errorout:

    if (Mcb) {

        if (Mcb->ShortName.Buffer)
            ExFreePool(Mcb->ShortName.Buffer);

        if (FlagOn(Mcb->Flags, MCB_FROM_POOL)) {

            ExFreePool( Mcb );

        } else {

            ExAcquireResourceExclusiveLite(
                    &RfsdGlobal->LAResource,
                    TRUE );

            ExFreeToPagedLookasideList(&(RfsdGlobal->RfsdMcbLookasideList), Mcb);

            ExReleaseResourceForThreadLite(
                    &RfsdGlobal->LAResource,
                    ExGetCurrentResourceThread() );
        }
    }

    return NULL;
}

VOID
RfsdFreeMcb (IN PRFSD_MCB Mcb)
{
    PRFSD_MCB   Parent = Mcb->Parent;

    ASSERT(Mcb != NULL);
    
    ASSERT((Mcb->Identifier.Type == RFSDMCB) &&
        (Mcb->Identifier.Size == sizeof(RFSD_MCB)));

    RfsdPrint((DBG_INFO, "RfsdFreeMcb: 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 {

        ExAcquireResourceExclusiveLite(
                &RfsdGlobal->LAResource,
                TRUE );

        ExFreeToPagedLookasideList(&(RfsdGlobal->RfsdMcbLookasideList), Mcb);

        ExReleaseResourceForThreadLite(
                &RfsdGlobal->LAResource,
                ExGetCurrentResourceThread() );
    }

    ExAcquireResourceExclusiveLite(
        &RfsdGlobal->CountResource,
        TRUE );

    RfsdGlobal->McbAllocated--;

    ExReleaseResourceForThreadLite(
        &RfsdGlobal->CountResource,
        ExGetCurrentResourceThread() );
}

PRFSD_FCB
RfsdCreateFcbFromMcb(PRFSD_VCB Vcb, PRFSD_MCB Mcb)
{
    PRFSD_FCB       Fcb = NULL;
    RFSD_INODE      RfsdIno;

    if (Mcb->RfsdFcb)
        return Mcb->RfsdFcb;

	if (RfsdLoadInode(Vcb, &(Mcb->Key), &RfsdIno)) {
        PRFSD_INODE pTmpInode = ExAllocatePool(PagedPool, sizeof(RFSD_INODE));
        if (!pTmpInode) {
            goto errorout;
        }

        RtlCopyMemory(pTmpInode, &RfsdIno, sizeof(RFSD_INODE));
        Fcb = RfsdAllocateFcb(Vcb, Mcb, pTmpInode);
        if (!Fcb) {
            ExFreePool(pTmpInode);
        }
    }

errorout:

    return Fcb;
}

BOOLEAN
RfsdGetFullFileName(PRFSD_MCB Mcb, PUNICODE_STRING FileName)
{
    USHORT          Length = 0;
    PRFSD_MCB       TmpMcb = Mcb;
    PUNICODE_STRING FileNames[256];
    SHORT           Count = 0 , i = 0, j = 0;

    while(TmpMcb && Count < 256) {
        if (RFSD_IS_ROOT_KEY(TmpMcb->Key))
            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;
}

PRFSD_MCB
RfsdSearchMcbTree(  PRFSD_VCB Vcb,
                    PRFSD_MCB RfsdMcb,
                    PRFSD_KEY_IN_MEMORY Key)
{
    PRFSD_MCB   Mcb = NULL;
    PLIST_ENTRY List = NULL;
    BOOLEAN     bFind = FALSE;

    List = Vcb->McbList.Flink;

    while ((!bFind) && (List != &(Vcb->McbList))) {
        Mcb = CONTAINING_RECORD(List, RFSD_MCB, Link);
        List = List->Flink;

		if (CompareShortKeys(&(Mcb->Key), Key) == RFSD_KEYS_MATCH) {
            bFind = TRUE;
            break;
        }
    }

    if (bFind) {
        ASSERT(Mcb != NULL);
        RfsdRefreshMcb(Vcb, Mcb);
    } else {
        Mcb = NULL;
    }

    return Mcb;
}

/** 
 Returns NULL is the parent has no child, or if we search through the child's brothers and hit a NULL
 Otherwise, returns the MCB of one of the the parent's children, which matches FileName.
*/
PRFSD_MCB
RfsdSearchMcb(  PRFSD_VCB Vcb,
                PRFSD_MCB Parent,
                PUNICODE_STRING FileName )
{
    PRFSD_MCB TmpMcb = Parent->Child;

    while (TmpMcb) {
        if (!RtlCompareUnicodeString(
                    &(TmpMcb->ShortName),
                    FileName, TRUE ))
            break;

        TmpMcb = TmpMcb->Next;
    }

    if (TmpMcb) {
        RfsdRefreshMcb(Vcb, TmpMcb);
    }

    return TmpMcb;
}

VOID
RfsdRefreshMcb(PRFSD_VCB Vcb, PRFSD_MCB Mcb)
{
    ASSERT (IsFlagOn(Mcb->Flags, MCB_IN_TREE));

    RemoveEntryList(&(Mcb->Link));
    InsertTailList(&(Vcb->McbList), &(Mcb->Link));
}

VOID
RfsdAddMcbNode(PRFSD_VCB Vcb, PRFSD_MCB Parent, PRFSD_MCB Child)
{
    PRFSD_MCB TmpMcb = Parent->Child;

    if(IsFlagOn(Child->Flags, MCB_IN_TREE)) {
        DbgBreak();
        RfsdPrint((DBG_ERROR, "RfsdAddMcbNode: Child Mcb is alreay in the tree.\n"));
        return;
    }

    if (TmpMcb) {
        ASSERT(TmpMcb->Parent == Parent);

        while (TmpMcb->Next) {
            TmpMcb = TmpMcb->Next;
            ASSERT(TmpMcb->Parent == Parent);
        }

        TmpMcb->Next = Child;
        Child->Parent = Parent;
        Child->Next = NULL;
    } else {
        Parent->Child = Child;
        Child->Parent = Parent;
        Child->Next = NULL;
    }

    InsertTailList(&(Vcb->McbList), &(Child->Link));
    SetFlag(Child->Flags, MCB_IN_TREE);
}

BOOLEAN
RfsdDeleteMcbNode(PRFSD_VCB Vcb, PRFSD_MCB McbTree, PRFSD_MCB RfsdMcb)
{
    PRFSD_MCB   TmpMcb;

    if(!IsFlagOn(RfsdMcb->Flags, MCB_IN_TREE)) {
        return TRUE;
    }

    if (RfsdMcb->Parent) {
        if (RfsdMcb->Parent->Child == RfsdMcb) {
            RfsdMcb->Parent->Child = RfsdMcb->Next;
        } else {
            TmpMcb = RfsdMcb->Parent->Child;

            while (TmpMcb && TmpMcb->Next != RfsdMcb)
                TmpMcb = TmpMcb->Next;

            if (TmpMcb) {
                TmpMcb->Next = RfsdMcb->Next;
            } else {
                // error
                return FALSE;
            }
        }
    } else if (RfsdMcb->Child) {
        return FALSE;
    }

    RemoveEntryList(&(RfsdMcb->Link));
    ClearFlag(RfsdMcb->Flags, MCB_IN_TREE);

    return TRUE;
}


VOID RfsdFreeMcbTree(PRFSD_MCB McbTree)
{
    if (!McbTree)
        return;

    if (McbTree->Child) {
        RfsdFreeMcbTree(McbTree->Child);
    }

    if (McbTree->Next) {

        PRFSD_MCB   Current;
        PRFSD_MCB   Next;

        Current = McbTree->Next;

        while (Current) {

            Next = Current->Next;

            if (Current->Child) {
                RfsdFreeMcbTree(Current->Child);
            }

            RfsdFreeMcb(Current);
            Current = Next;
        }
    }

    RfsdFreeMcb(McbTree);
}

#if DISABLED
BOOLEAN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -