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

📄 mm.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
	// Make sure we didn't get a bogus pointer
	if (MemoryPointer >= (PVOID)(TotalPagesInLookupTable * MM_PAGE_SIZE))
	{
		BugCheck((DPRINT_MEMORY, "Bogus memory pointer (0x%x) passed to MmFreeMemory()\n", MemoryPointer));
	}
#endif // DBG

	// Find out the page number of the first
	// page of memory they allocated
	PageNumber = MmGetPageNumberFromAddress(MemoryPointer);
	PageCount = RealPageLookupTable[PageNumber].PageAllocationLength;

#ifdef DBG
	// Make sure we didn't get a bogus pointer
	if ((PageCount < 1) || (PageCount > (TotalPagesInLookupTable - PageNumber)))
	{
		BugCheck((DPRINT_MEMORY, "Invalid page count in lookup table. PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
	}

	// Loop through our array check all the pages
	// to make sure they are allocated with a length of 0
	for (Idx=PageNumber+1; Idx<(PageNumber + PageCount); Idx++)
	{
		if ((RealPageLookupTable[Idx].PageAllocated == LoaderFree) ||
			(RealPageLookupTable[Idx].PageAllocationLength != 0))
		{
			BugCheck((DPRINT_MEMORY, "Invalid page entry in lookup table, PageAllocated should = 1 and PageAllocationLength should = 0 because this is not the first block in the run. PageLookupTable[%d].PageAllocated = %d PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocated, PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
		}
	}

#endif

	/* If this allocation is only a single page, it could be a sub-allocated page.
	 * Just don't free it */
	if (1 == PageCount)
	{
		return;
	}

	// Loop through our array and mark all the
	// blocks as free
	for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
	{
		RealPageLookupTable[Idx].PageAllocated = LoaderFree;
		RealPageLookupTable[Idx].PageAllocationLength = 0;
	}

	FreePagesInLookupTable += PageCount;

#ifdef DBG
	DecrementAllocationCount();
	DbgPrint((DPRINT_MEMORY, "Freed %d pages of memory starting at page %d. AllocationCount: %d\n", PageCount, PageNumber, AllocationCount));
	//VerifyHeap();
#endif // DBG
}

#ifdef DBG
VOID VerifyHeap(VOID)
{
	ULONG							Idx;
	ULONG							Idx2;
	ULONG							Count;
	PPAGE_LOOKUP_TABLE_ITEM		RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;

	if (DUMP_MEM_MAP_ON_VERIFY)
	{
		DumpMemoryAllocMap();
	}

	// Loop through the array and verify that
	// everything is kosher
	for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
	{
		// Check if this block is allocated
		if (RealPageLookupTable[Idx].PageAllocated != LoaderFree)
		{
			// This is the first block in the run so it
			// had better have a length that is within range
			if ((RealPageLookupTable[Idx].PageAllocationLength < 1) || (RealPageLookupTable[Idx].PageAllocationLength > (TotalPagesInLookupTable - Idx)))
			{
				BugCheck((DPRINT_MEMORY, "Allocation length out of range in heap table. PageLookupTable[Idx].PageAllocationLength = %d\n", RealPageLookupTable[Idx].PageAllocationLength));
			}

			// Now go through and verify that the rest of
			// this run has the blocks marked allocated
			// with a length of zero but don't check the
			// first one because we already did
			Count = RealPageLookupTable[Idx].PageAllocationLength;
			for (Idx2=1; Idx2<Count; Idx2++)
			{
				// Make sure it's allocated
				if (RealPageLookupTable[Idx + Idx2].PageAllocated == LoaderFree)
				{
					BugCheck((DPRINT_MEMORY, "Lookup table indicates hole in memory allocation. RealPageLookupTable[Idx + Idx2].PageAllocated == 0\n"));
				}

				// Make sure the length is zero
				if (RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0)
				{
					BugCheck((DPRINT_MEMORY, "Allocation chain has non-zero value in non-first block in lookup table. RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0\n"));
				}
			}

			// Move on to the next run
			Idx += (Count - 1);
		}
		else
		{
			// Nope, not allocated so make sure the length is zero
			if (RealPageLookupTable[Idx].PageAllocationLength != 0)
			{
				BugCheck((DPRINT_MEMORY, "Free block is start of memory allocation. RealPageLookupTable[Idx].PageAllocationLength != 0\n"));
			}
		}
	}
}

VOID DumpMemoryAllocMap(VOID)
{
	ULONG							Idx;
	PPAGE_LOOKUP_TABLE_ITEM		RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;

	DbgPrint((DPRINT_MEMORY, "----------- Memory Allocation Bitmap -----------\n"));

	for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
	{
		if ((Idx % 32) == 0)
		{
			DbgPrint((DPRINT_MEMORY, "\n"));
			DbgPrint((DPRINT_MEMORY, "%x:\t", (Idx * MM_PAGE_SIZE)));
		}
		else if ((Idx % 4) == 0)
		{
			DbgPrint((DPRINT_MEMORY, " "));
		}

		switch (RealPageLookupTable[Idx].PageAllocated)
		{
		case LoaderFree:
			DbgPrint((DPRINT_MEMORY, "*"));
			break;
		case LoaderBad:
			DbgPrint((DPRINT_MEMORY, "-"));
			break;
		case LoaderLoadedProgram:
			DbgPrint((DPRINT_MEMORY, "O"));
			break;
		case LoaderFirmwareTemporary:
			DbgPrint((DPRINT_MEMORY, "T"));
			break;
		case LoaderFirmwarePermanent:
			DbgPrint((DPRINT_MEMORY, "P"));
			break;
		case LoaderOsloaderHeap:
			DbgPrint((DPRINT_MEMORY, "H"));
			break;
		case LoaderOsloaderStack:
			DbgPrint((DPRINT_MEMORY, "S"));
			break;
		case LoaderSystemCode:
			DbgPrint((DPRINT_MEMORY, "K"));
			break;
		case LoaderHalCode:
			DbgPrint((DPRINT_MEMORY, "L"));
			break;
		case LoaderBootDriver:
			DbgPrint((DPRINT_MEMORY, "B"));
			break;
		case LoaderStartupPcrPage:
			DbgPrint((DPRINT_MEMORY, "G"));
			break;
		case LoaderRegistryData:
			DbgPrint((DPRINT_MEMORY, "R"));
			break;
		case LoaderMemoryData:
			DbgPrint((DPRINT_MEMORY, "M"));
			break;
		case LoaderNlsData:
			DbgPrint((DPRINT_MEMORY, "N"));
			break;
		case LoaderSpecialMemory:
			DbgPrint((DPRINT_MEMORY, "C"));
			break;
		default:
			DbgPrint((DPRINT_MEMORY, "?"));
			break;
		}
	}

	DbgPrint((DPRINT_MEMORY, "\n"));
}

VOID IncrementAllocationCount(VOID)
{
	AllocationCount++;
}

VOID DecrementAllocationCount(VOID)
{
	AllocationCount--;
}

VOID MemAllocTest(VOID)
{
	PVOID	MemPtr1;
	PVOID	MemPtr2;
	PVOID	MemPtr3;
	PVOID	MemPtr4;
	PVOID	MemPtr5;

	MemPtr1 = MmAllocateMemory(4096);
	printf("MemPtr1: 0x%x\n", (int)MemPtr1);
	MachConsGetCh();
	MemPtr2 = MmAllocateMemory(4096);
	printf("MemPtr2: 0x%x\n", (int)MemPtr2);
	MachConsGetCh();
	MemPtr3 = MmAllocateMemory(4096);
	printf("MemPtr3: 0x%x\n", (int)MemPtr3);
	DumpMemoryAllocMap();
	VerifyHeap();
	MachConsGetCh();

	MmFreeMemory(MemPtr2);
	MachConsGetCh();

	MemPtr4 = MmAllocateMemory(2048);
	printf("MemPtr4: 0x%x\n", (int)MemPtr4);
	MachConsGetCh();
	MemPtr5 = MmAllocateMemory(4096);
	printf("MemPtr5: 0x%x\n", (int)MemPtr5);
	MachConsGetCh();
}
#endif // DBG

ULONG GetSystemMemorySize(VOID)
{
	return (TotalPagesInLookupTable * MM_PAGE_SIZE);
}

PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries)
{
	PPAGE_LOOKUP_TABLE_ITEM		RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;

	*NoEntries = TotalPagesInLookupTable;

	return RealPageLookupTable;
}

⌨️ 快捷键说明

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