3.1.1 ReactOS系统中二叉树创建一个MEMORY_AREA节点

news/2024/10/25 7:05:15/

二叉树中创建一个MEMORY_AREA节点:

二叉树中创建一个MEMORY_AREA节点:
MmCreateMemoryArea()
参数AddressSpace是MADDRESS SPACE结构指针,所指向的数据结构代表着一个进程的用 户空间。
参数BaseAddress是个指针,用来给定和返回内存区块的基地址

文章目录

  • 二叉树中创建一个MEMORY_AREA节点:
  • MmCreateMemoryArea()


MmCreateMemoryArea()


/*** @name MmCreateMemoryArea** Create a memory area.** @param AddressSpace*        Address space to create the area in.* @param Type*        Type of the memory area.* @param BaseAddress*        Base address for the memory area we're about the create. On*        input it contains either 0 (auto-assign address) or preferred*        address. On output it contains the starting address of the*        newly created area.* @param Length*        Length of the area to allocate.* @param Attributes*        Protection attributes for the memory area.* @param Result*        Receives a pointer to the memory area on successful exit.** @return Status** @remarks Lock the address space before calling this function.*/NTSTATUS STDCALL
MmCreateMemoryArea(PMADDRESS_SPACE AddressSpace,ULONG Type,PVOID *BaseAddress,ULONG_PTR Length,ULONG Protect,PMEMORY_AREA *Result,BOOLEAN FixedAddress,ULONG AllocationFlags,PHYSICAL_ADDRESS BoundaryAddressMultiple)
{PVOID EndAddress;ULONG Granularity;ULONG tmpLength;PMEMORY_AREA MemoryArea;DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %p, ""*BaseAddress %p, Length %p, AllocationFlags %x, ""FixedAddress %x, Result %p)\n",Type, BaseAddress, *BaseAddress, Length, AllocationFlags,FixedAddress, Result);MmVerifyMemoryAreas(AddressSpace);//检测该AVL树是否存在问题//根据Type选择相应的粒度Granularity = (MEMORY_AREA_VIRTUAL_MEMORY == Type ? MM_VIRTMEM_GRANULARITY : PAGE_SIZE);//if 用户不要求从固定地址处开始分配if ((*BaseAddress) == 0 && !FixedAddress){//不受给定地址的约束,只要找到一个够大的空隙即可tmpLength = PAGE_ROUND_UP(Length);//根据用户空间找到一块符合的Area,并返回其首地址*BaseAddress = MmFindGap(AddressSpace,tmpLength,Granularity,(AllocationFlags & MEM_TOP_DOWN) == MEM_TOP_DOWN);if ((*BaseAddress) == 0){DPRINT("No suitable gap\n");return STATUS_NO_MEMORY;}}else//用户给定了基址,就必须从那儿开始分配{tmpLength = Length + ((ULONG_PTR) *BaseAddress- (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity));*BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity);if (AddressSpace->LowestAddress == MmSystemRangeStart &&*BaseAddress < MmSystemRangeStart){//给定的空间为系统空间,但是地址落在用户空间,严重错误CHECKPOINT;CHECKPOINT;return STATUS_ACCESS_VIOLATION;}if (AddressSpace->LowestAddress < MmSystemRangeStart &&(ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart){//所要求的区间跨越用户空间和系统空间的分界,严重错误CHECKPOINT;CHECKPOINT;return STATUS_ACCESS_VIOLATION;}//测试要分配的区域完全落在指定地址空间内部if (BoundaryAddressMultiple.QuadPart != 0){EndAddress = ((char*)(*BaseAddress)) + tmpLength-1;ASSERT(((ULONG_PTR)*BaseAddress/BoundaryAddressMultiple.QuadPart) == ((DWORD_PTR)EndAddress/BoundaryAddressMultiple.QuadPart));}//确认所要求的区间尚术分配if (MmLocateMemoryAreaByRegion(AddressSpace,*BaseAddress,tmpLength) != NULL){//所要求的区间已经分配,失敗DPRINT("Memory area already occupied\n");return STATUS_CONFLICTING_ADDRESSES;}}//创建MEMORY AREA节点,把这块区域分配出去MemoryArea = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),TAG_MAREA);RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA));MemoryArea->Type = Type;MemoryArea->StartingAddress = *BaseAddress;MemoryArea->EndingAddress = (PVOID)((ULONG_PTR)*BaseAddress + tmpLength);MemoryArea->Protect = Protect;MemoryArea->Flags = AllocationFlags;//MemoryArea->LockCount = 0;MemoryArea->PageOpCount = 0;MemoryArea->DeleteInProgress = FALSE;//将所创建节点插入一又树MmInsertMemoryArea(AddressSpace, MemoryArea);*Result = MemoryArea;DPRINT("MmCreateMemoryArea() succeeded (%p)\n", *BaseAddress);return STATUS_SUCCESS;
}

//二叉树中创建-个MEMORY AREA节点
/*
参数AddressSpace是MADDRESS SPACE结构指针,所指向的数据结构代表着一个进程的用 户空间。
参数BaseAddress是个指针,用来给定和返回内存区块的基地址 :
参数Length、Protect的意义 则不言自明。
参数FixedAddress为TRUE说明给定的地址不容改变,为FALSE则表示若不能满足 要求也可以浮动, 。
参数AllocationFlags : 分配标志TopDown ? TopUp
参数BoundaryAddressMultiple此分配不得跨越的物理地址倍数
*/


http://www.ppmy.cn/news/1541775.html

相关文章

【Android】使用 Compose 自定义 View 实现从 0 ~ 1 仿 EChat 柱状图

目录 前言DrawScopeDrawScope Api 绘制柱状图绘制 X 轴绘制 Y 轴绘制柱状背景绘制柱状前景完整代码最终效果 存在的问题 前言 本文讲的是使用 compose 去自定义 View &#xff0c;如果您未曾通过继承 View 的方式去实现自定义 View&#xff0c;那么&#xff0c;我建议在观看本…

3D虚拟服装试穿技术:迈向元宇宙与AR电商的新时代

随着电子商务的不断进化,消费者对于在线购物体验的需求也在不断提升。在这样的背景下,3D虚拟服装试穿技术正逐渐成为连接现实世界与数字世界的桥梁,为用户带来前所未有的沉浸式购物体验。本文将介绍一种创新的3D虚拟服装试穿系统——GS-VTON,它旨在克服现有技术局限,并提供…

ECharts饼图-富文本标签,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…

【Mac 上将 MOV 格式转换为 MP4 格式的简易指南】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

无人机之室内定位技术篇

无人机的室内定位技术是实现无人机在室内环境中精准导航和定位的关键技术。由于室内环境复杂&#xff0c;卫星导航系统&#xff08;如GPS&#xff09;无法提供有效的信号&#xff0c;因此需要依赖其他室内定位技术。 一、主要技术类型 基于视觉的定位技术 原理&#xff1a;利…

智联招聘×Milvus:向量召回技术提升招聘匹配效率

01. 业务背景 在智联招聘平台&#xff0c;求职者和招聘者之间的高效匹配至关重要。招聘者可以发布职位寻找合适的人才&#xff0c;求职者则通过上传简历寻找合适的工作。在这种复杂的场景中&#xff0c;我们的核心目标是为双方提供精准的匹配结果。在搜索推荐场景下&#xff0c…

客户端与服务端通信的端口以及新增ARP缓存

客户端&#xff08;例如浏览器&#xff09;在与服务器通信时确实会使用一个随机的、高于1024的端口。不过&#xff0c;在端口转发的场景中&#xff0c;我们主要关注的是两个不同的层面&#xff1a;服务器的监听端口&#xff08;即最终目的地的端口&#xff09;和客户端的源端口…

Linux -- 进程间通信、初识匿名管道

目录 进程间通信 什么是进程间通信 进程间通信的一般规律 前言&#xff1a; 管道 代码预准备&#xff1a; 如何创建管道 -- pipe 函数 参数&#xff1a; 返回值&#xff1a; wait 函数 参数&#xff1a; 验证管道的运行&#xff1a; 源文件 test.c &#xff1a; m…