3.1.1ReactOS系统中搜索给定长度的空间地址区间函数的实现

系列文章目录

//搜索给定长度的空间地址区间
MmFindGap();
PMADDRESS_SPACE AddressSpace,//该进程用户空间
ULONG_PTR Length,//寻找的空间间隔大小
ULONG_PTR Granularity,//粒度位,表明空间起点的对齐要求,注意是起点地址
ULONG_PTR TopDown);
函数的定义:
PVOID
NTAPI
MmFindGap(
PMADDRESS_SPACE AddressSpace,
ULONG_PTR Length,
ULONG_PTR Granularity,
BOOLEAN TopDown
);


MmFindGap函数的实现

//搜索给定长度的空间地址区间

//所属给定长度的空间地址区间


PVOID STDCALL
MmFindGap(
   PMADDRESS_SPACE AddressSpace,
   ULONG_PTR Length,
   ULONG_PTR Granularity,
   BOOLEAN TopDown)
{
   if (TopDown)//表示寻找的方向时从高端到低段还是从低端往高端
      return MmFindGapTopDown(AddressSpace, Length, Granularity);//高端往地段

   return MmFindGapBottomUp(AddressSpace, Length, Granularity);//低端往高端
}

//搜索给定长度的空间地址区间
PMADDRESS_SPACE AddressSpace,//该进程用户空间
ULONG_PTR Length,//寻找的空间间隔大小
ULONG_PTR Granularity,//粒度位,表明空间起点的对齐要求,注意是起点地址
ULONG_PTR TopDown);

参数TopDown表示孕照的方向是从高往低端搜索还是低端往高端搜索。我们开看其中之一,即MmFindGapBottomUp().参数Granularity表明对于区间起点地址的颗粒度要求,即边界对齐的要求,大哥比方,假设颗粒度位16字节,长度要求为8,那么空间【0x3,0x14】是不符合要求的。这个区间的绝对长度大于8,但是我如把区间的起始与0x10对齐,剩下的长度就不够了。 而空间【0x10,0x18】绝对长度虽然小于前者,去能满足要求。


static PVOID
MmFindGapBottomUp(
   PMADDRESS_SPACE AddressSpace,
   ULONG_PTR Length,
   ULONG_PTR Granularity)
{
   PVOID HighestAddress = AddressSpace->LowestAddress < MmSystemRangeStart ?
                          (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
   PVOID AlignedAddress;
   PMEMORY_AREA Node;
   PMEMORY_AREA FirstNode;
   PMEMORY_AREA PreviousNode;

   MmVerifyMemoryAreas(AddressSpace);

   DPRINT("LowestAddress: %p HighestAddress: %p\n",
          AddressSpace->LowestAddress, HighestAddress);

   AlignedAddress = MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);

   /* Special case for empty tree. */
   if (AddressSpace->MemoryAreaRoot == NULL)
   {
      if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
      {
         DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
         return AlignedAddress;
      }
      DPRINT("MmFindGapBottomUp: 0\n");
      return 0;
   }

   /* Go to the node with lowest address in the tree. */
   FirstNode = Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);

   /* Traverse the tree from left to right. */
   PreviousNode = Node;
   for (;;)
   {
      Node = MmIterateNextNode(Node);
      if (Node == NULL)
         break;

      AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
      if (Node->StartingAddress > AlignedAddress &&
          (ULONG_PTR)Node->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
      {
         DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
         return AlignedAddress;
      }

      PreviousNode = Node;
   }

   /* Check if there is enough space after the last memory area. */
   AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
   if ((ULONG_PTR)HighestAddress > (ULONG_PTR)AlignedAddress &&
       (ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
   {
      DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
      return AlignedAddress;
   }

   /* Check if there is enough space before the first memory area. */
   AlignedAddress = MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);
   if (FirstNode->StartingAddress > AlignedAddress &&
       (ULONG_PTR)FirstNode->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
   {
      DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
      return AlignedAddress;
   }

   DPRINT("MmFindGapBottomUp: 0\n");
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值