ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

NTSTATUS NTAPI MmAlterRegion ( PMMSUPPORT  AddressSpace,
PVOID  BaseAddress,
PLIST_ENTRY  RegionListHead,
PVOID  StartAddress,
SIZE_T  Length,
ULONG  NewType,
ULONG  NewProtect,
PMM_ALTER_REGION_FUNC  AlterFunc 
)

Definition at line 108 of file region.c.

Referenced by MiRosAllocateVirtualMemory(), and MmProtectSectionView().

{
   PMM_REGION InitialRegion;
   PVOID InitialBaseAddress = NULL;
   PMM_REGION NewRegion;
   PLIST_ENTRY CurrentEntry;
   PMM_REGION CurrentRegion = NULL;
   PVOID CurrentBaseAddress;
   SIZE_T RemainingLength;

   /*
    * Find the first region containing part of the range of addresses to
    * be altered.
    */
   InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
                                &InitialBaseAddress);
   /*
    * If necessary then split the region into the affected and unaffected parts.
    */
   if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
   {
      NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
                                StartAddress, Length, NewType, NewProtect,
                                AddressSpace, AlterFunc);
      if (NewRegion == NULL)
      {
         return(STATUS_NO_MEMORY);
      }
      if(NewRegion->Length < Length)
         RemainingLength = Length - NewRegion->Length;
      else
         RemainingLength = 0;
   }
   else
   {
      NewRegion = InitialRegion;
      if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
            ((ULONG_PTR)StartAddress + Length))
         RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
      else
         RemainingLength = 0;
   }

   /*
    * Free any complete regions that are containing in the range of addresses
    * and call the helper function to actually do the changes.
    */
   CurrentEntry = NewRegion->RegionListEntry.Flink;
   CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
                                     RegionListEntry);
   CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
   while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
          CurrentEntry != RegionListHead)
   {
      if (CurrentRegion->Type != NewType ||
            CurrentRegion->Protect != NewProtect)
      {
         AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
                   CurrentRegion->Type, CurrentRegion->Protect,
                   NewType, NewProtect);
      }

      CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
      NewRegion->Length += CurrentRegion->Length;
      RemainingLength -= CurrentRegion->Length;
      CurrentEntry = CurrentEntry->Flink;
      RemoveEntryList(&CurrentRegion->RegionListEntry);
      ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
      CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
                                        RegionListEntry);
   }

   /*
    * Split any final region.
    */
   if (RemainingLength > 0 && CurrentEntry != RegionListHead)
   {
      CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
                                        RegionListEntry);
      if (CurrentRegion->Type != NewType ||
            CurrentRegion->Protect != NewProtect)
      {
         AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
                   CurrentRegion->Type, CurrentRegion->Protect,
                   NewType, NewProtect);
      }
      NewRegion->Length += RemainingLength;
      CurrentRegion->Length -= RemainingLength;
   }

   /*
    * If the region after the new region has the same type then merge them.
    */
   if (NewRegion->RegionListEntry.Flink != RegionListHead)
   {
      CurrentEntry = NewRegion->RegionListEntry.Flink;
      CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
                                        RegionListEntry);
      if (CurrentRegion->Type == NewRegion->Type &&
            CurrentRegion->Protect == NewRegion->Protect)
      {
         NewRegion->Length += CurrentRegion->Length;
         RemoveEntryList(&CurrentRegion->RegionListEntry);
         ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
      }
   }

   /*
    * If the region before the new region has the same type then merge them.
    */
   if (NewRegion->RegionListEntry.Blink != RegionListHead)
   {
      CurrentEntry = NewRegion->RegionListEntry.Blink;
      CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
                                        RegionListEntry);
      if (CurrentRegion->Type == NewRegion->Type &&
            CurrentRegion->Protect == NewRegion->Protect)
      {
         NewRegion->Length += CurrentRegion->Length;
         RemoveEntryList(&CurrentRegion->RegionListEntry);
         ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
      }
   }

   return(STATUS_SUCCESS);
}

Generated on Sat May 26 2012 05:08:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.