📄 memory.c
字号:
Fcb->SectionObject.ImageSectionObject = NULL;
ExInitializeResourceLite(&(Fcb->MainResource));
ExInitializeResourceLite(&(Fcb->PagingIoResource));
InsertTailList(&Vcb->FcbList, &Fcb->Next);
#if DBG
ExAcquireResourceExclusiveLite(
&FFSGlobal->CountResource,
TRUE);
FFSGlobal->FcbAllocated++;
ExReleaseResourceForThreadLite(
&FFSGlobal->CountResource,
ExGetCurrentResourceThread());
#endif
return Fcb;
#if DBG
errorout:
#endif
if (Fcb)
{
#if DBG
if (Fcb->AnsiFileName.Buffer)
ExFreePool(Fcb->AnsiFileName.Buffer);
#endif
if (FlagOn(Fcb->Flags, FCB_FROM_POOL))
{
ExFreePool(Fcb);
}
else
{
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb);
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
}
PFFS_CCB
FFSAllocateCcb(
VOID)
{
PFFS_CCB Ccb;
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
Ccb = (PFFS_CCB)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSCcbLookasideList)));
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
if (Ccb == NULL)
{
Ccb = (PFFS_CCB)ExAllocatePool(NonPagedPool, sizeof(FFS_CCB));
RtlZeroMemory(Ccb, sizeof(FFS_CCB));
SetFlag(Ccb->Flags, CCB_FROM_POOL);
}
else
{
RtlZeroMemory(Ccb, sizeof(FFS_CCB));
}
if (!Ccb)
{
return NULL;
}
Ccb->Identifier.Type = FFSCCB;
Ccb->Identifier.Size = sizeof(FFS_CCB);
Ccb->CurrentByteOffset = 0;
Ccb->DirectorySearchPattern.Length = 0;
Ccb->DirectorySearchPattern.MaximumLength = 0;
Ccb->DirectorySearchPattern.Buffer = 0;
return Ccb;
}
VOID
FFSFreeCcb(
IN PFFS_CCB Ccb)
{
ASSERT(Ccb != NULL);
ASSERT((Ccb->Identifier.Type == FFSCCB) &&
(Ccb->Identifier.Size == sizeof(FFS_CCB)));
if (Ccb->DirectorySearchPattern.Buffer != NULL)
{
ExFreePool(Ccb->DirectorySearchPattern.Buffer);
}
if (FlagOn(Ccb->Flags, CCB_FROM_POOL))
{
ExFreePool(Ccb);
}
else
{
ExAcquireResourceExclusiveLite(
&FFSGlobal->LAResource,
TRUE);
ExFreeToNPagedLookasideList(&(FFSGlobal->FFSCcbLookasideList), Ccb);
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
}
}
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
FFSFreeMcb(
IN PFFS_MCB Mcb)
{
PFFS_MCB Parent = Mcb->Parent;
ASSERT(Mcb != NULL);
ASSERT((Mcb->Identifier.Type == FFSMCB) &&
(Mcb->Identifier.Size == sizeof(FFS_MCB)));
FFSPrint((DBG_INFO, "FFSFreeMcb: 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(
&FFSGlobal->LAResource,
TRUE);
ExFreeToPagedLookasideList(&(FFSGlobal->FFSMcbLookasideList), Mcb);
ExReleaseResourceForThreadLite(
&FFSGlobal->LAResource,
ExGetCurrentResourceThread());
}
ExAcquireResourceExclusiveLite(
&FFSGlobal->CountResource,
TRUE);
FFSGlobal->McbAllocated--;
ExReleaseResourceForThreadLite(
&FFSGlobal->CountResource,
ExGetCurrentResourceThread());
}
PFFS_FCB
FFSCreateFcbFromMcb(
PFFS_VCB Vcb,
PFFS_MCB Mcb)
{
PFFS_FCB Fcb = NULL;
FFSv1_INODE dinode1;
FFSv2_INODE dinode2;
if (Mcb->FFSFcb)
return Mcb->FFSFcb;
if (FS_VERSION == 1)
{
if (FFSv1LoadInode(Vcb, Mcb->Inode, &dinode1))
{
PFFSv1_INODE pTmpInode = ExAllocatePool(PagedPool, DINODE1_SIZE);
if (!pTmpInode)
{
goto errorout;
}
RtlCopyMemory(pTmpInode, &dinode1, DINODE1_SIZE);
Fcb = FFSv1AllocateFcb(Vcb, Mcb, pTmpInode);
if (!Fcb)
{
ExFreePool(pTmpInode);
}
}
}
else
{
if (FFSv2LoadInode(Vcb, Mcb->Inode, &dinode2))
{
PFFSv2_INODE pTmpInode = ExAllocatePool(PagedPool, DINODE2_SIZE);
if (!pTmpInode)
{
goto errorout;
}
RtlCopyMemory(pTmpInode, &dinode2, DINODE2_SIZE);
Fcb = FFSv2AllocateFcb(Vcb, Mcb, pTmpInode);
if (!Fcb)
{
ExFreePool(pTmpInode);
}
}
}
errorout:
return Fcb;
}
BOOLEAN
FFSGetFullFileName(
PFFS_MCB Mcb,
PUNICODE_STRING FileName)
{
USHORT Length = 0;
PFFS_MCB TmpMcb = Mcb;
PUNICODE_STRING FileNames[256];
SHORT Count = 0 , i = 0, j = 0;
while(TmpMcb && Count < 256)
{
if (TmpMcb->Inode == FFS_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;
}
PFFS_MCB
FFSSearchMcbTree(
PFFS_VCB Vcb,
PFFS_MCB FFSMcb,
ULONG Inode)
{
PFFS_MCB Mcb = NULL;
PLIST_ENTRY List = NULL;
BOOLEAN bFind = FALSE;
List = Vcb->McbList.Flink;
while ((!bFind) && (List != &(Vcb->McbList)))
{
Mcb = CONTAINING_RECORD(List, FFS_MCB, Link);
List = List->Flink;
if (Mcb->Inode == Inode)
{
bFind = TRUE;
break;
}
}
if (bFind)
{
ASSERT(Mcb != NULL);
FFSRefreshMcb(Vcb, Mcb);
}
else
{
Mcb = NULL;
}
return Mcb;
}
PFFS_MCB
FFSSearchMcb(
PFFS_VCB Vcb,
PFFS_MCB Parent,
PUNICODE_STRING FileName)
{
PFFS_MCB TmpMcb = Parent->Child;
while (TmpMcb)
{
if (!RtlCompareUnicodeString(
&(TmpMcb->ShortName),
FileName, TRUE))
break;
TmpMcb = TmpMcb->Next;
}
if (TmpMcb)
{
FFSRefreshMcb(Vcb, TmpMcb);
}
return TmpMcb;
}
VOID
FFSRefreshMcb(
PFFS_VCB Vcb,
PFFS_MCB Mcb)
{
ASSERT (IsFlagOn(Mcb->Flags, MCB_IN_TREE));
RemoveEntryList(&(Mcb->Link));
InsertTailList(&(Vcb->McbList), &(Mcb->Link));
}
VOID
FFSAddMcbNode(
PFFS_VCB Vcb,
PFFS_MCB Parent,
PFFS_MCB Child)
{
PFFS_MCB TmpMcb = Parent->Child;
if(IsFlagOn(Child->Flags, MCB_IN_TREE))
{
FFSBreakPoint();
FFSPrint((DBG_ERROR, "FFSAddMcbNode: 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
FFSDeleteMcbNode(
PFFS_VCB Vcb,
PFFS_MCB McbTree,
PFFS_MCB FFSMcb)
{
PFFS_MCB TmpMcb;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -