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

📄 memory.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -