📄 memory.c
字号:
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 + -