VOID FFSFreeMcbTree( PFFS_MCB McbTree) { if (!McbTree) return; if (McbTree->Child) { FFSFreeMcbTree(McbTree->Child); } if (McbTree->Next) { PFFS_MCB Current; PFFS_MCB Next; Current = McbTree->Next; while (Current) { Next = Current->Next; if (Current->Child) { FFSFreeMcbTree(Current->Child); } FFSFreeMcb(Current); Current = Next; } } FFSFreeMcb(McbTree); }
__drv_mustHoldCriticalRegion VOID FFSFreeMcbTree( PFFS_MCB McbTree) { PAGED_CODE(); if (!McbTree) return; if (McbTree->Child) { FFSFreeMcbTree(McbTree->Child); } if (McbTree->Next) { PFFS_MCB Current; PFFS_MCB Next; Current = McbTree->Next; while (Current) { Next = Current->Next; if (Current->Child) { FFSFreeMcbTree(Current->Child); } FFSFreeMcb(Current); Current = Next; } } FFSFreeMcb(McbTree); }
PFFS_MCB FFSAllocateMcb( PFFS_VCB Vcb, PUNICODE_STRING FileName, ULONG FileAttr) { PFFS_MCB Mcb = NULL; PLIST_ENTRY List = NULL; ULONG Extra = 0; #define MCB_NUM_SHIFT 0x04 if (FFSGlobal->McbAllocated > (FFSGlobal->MaxDepth << MCB_NUM_SHIFT)) Extra = FFSGlobal->McbAllocated - (FFSGlobal->MaxDepth << MCB_NUM_SHIFT) + FFSGlobal->MaxDepth; FFSPrint((DBG_INFO, "FFSAllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n", FFSGlobal->McbAllocated, FFSGlobal->MaxDepth << MCB_NUM_SHIFT, FFSGlobal->FcbAllocated, FileName->Buffer)); List = Vcb->McbList.Flink; while ((List != &(Vcb->McbList)) && (Extra > 0)) { Mcb = CONTAINING_RECORD(List, FFS_MCB, Link); List = List->Flink; if ((Mcb->Inode != 2) && (Mcb->Child == NULL) && (Mcb->FFSFcb == NULL) && (!IsMcbUsed(Mcb))) { FFSPrint((DBG_INFO, "FFSAllocateMcb: Mcb %S will be freed.\n", Mcb->ShortName.Buffer)); if (FFSDeleteMcbNode(Vcb, Vcb->McbTree, Mcb)) { FFSFreeMcb(Mcb); Extra--; } } } ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); Mcb = (PFFS_MCB)(ExAllocateFromPagedLookasideList( &(FFSGlobal->FFSMcbLookasideList))); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); if (Mcb == NULL) { Mcb = (PFFS_MCB)ExAllocatePool(PagedPool, sizeof(FFS_MCB)); RtlZeroMemory(Mcb, sizeof(FFS_MCB)); SetFlag(Mcb->Flags, MCB_FROM_POOL); } else { RtlZeroMemory(Mcb, sizeof(FFS_MCB)); } if (!Mcb) { return NULL; } Mcb->Identifier.Type = FFSMCB; Mcb->Identifier.Size = sizeof(FFS_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( &FFSGlobal->CountResource, TRUE); FFSGlobal->McbAllocated++; ExReleaseResourceForThreadLite( &FFSGlobal->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( &FFSGlobal->LAResource, TRUE); ExFreeToPagedLookasideList(&(FFSGlobal->FFSMcbLookasideList), Mcb); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); } } return NULL; }
VOID FFSFreeFcb( IN PFFS_FCB Fcb) { PFFS_VCB Vcb; ASSERT(Fcb != NULL); ASSERT((Fcb->Identifier.Type == FFSFCB) && (Fcb->Identifier.Size == sizeof(FFS_FCB))); Vcb = Fcb->Vcb; FsRtlUninitializeFileLock(&Fcb->FileLockAnchor); ExDeleteResourceLite(&Fcb->MainResource); ExDeleteResourceLite(&Fcb->PagingIoResource); Fcb->FFSMcb->FFSFcb = NULL; if(IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) { if (Fcb->FFSMcb) { FFSDeleteMcbNode(Vcb, Fcb->FFSMcb->Parent, Fcb->FFSMcb); FFSFreeMcb(Fcb->FFSMcb); } } if (Fcb->LongName.Buffer) { ExFreePool(Fcb->LongName.Buffer); Fcb->LongName.Buffer = NULL; } #if DBG ExFreePool(Fcb->AnsiFileName.Buffer); #endif if (FS_VERSION == 1) { ExFreePool(Fcb->dinode1); } else { ExFreePool(Fcb->dinode2); } Fcb->Header.NodeTypeCode = (SHORT)0xCCCC; Fcb->Header.NodeByteSize = (SHORT)0xC0C0; if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) { ExFreePool(Fcb); } else { ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); } #if DBG ExAcquireResourceExclusiveLite( &FFSGlobal->CountResource, TRUE); FFSGlobal->FcbAllocated--; ExReleaseResourceForThreadLite( &FFSGlobal->CountResource, ExGetCurrentResourceThread()); #endif }