- Moved the code for freeing a segment to separate function (MmUnmapViewOfSegment).
authorHartmut Birr <osexpert@googlemail.com>
Sat, 26 Jul 2003 12:47:51 +0000 (12:47 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Sat, 26 Jul 2003 12:47:51 +0000 (12:47 +0000)
- Freed all segments for an image section in MmUnmapViewOfSection.

svn path=/trunk/; revision=5276

reactos/ntoskrnl/mm/section.c

index 630e5c4..a8fb990 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: section.c,v 1.125 2003/07/24 18:37:44 hbirr Exp $
+/* $Id: section.c,v 1.126 2003/07/26 12:47:51 hbirr Exp $
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/section.c
@@ -3262,28 +3262,19 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
     }
 }
 
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-MmUnmapViewOfSection(PEPROCESS Process,
+NTSTATUS
+MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace,
                     PVOID BaseAddress)
 {
-   NTSTATUS    Status;
+   NTSTATUS Status;
    PMEMORY_AREA MemoryArea;
-   PMADDRESS_SPACE AddressSpace;
    PSECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    KIRQL oldIrql;
    PLIST_ENTRY CurrentEntry;
    PMM_REGION CurrentRegion;
+   PLIST_ENTRY RegionListHead;
 
-   assert(Process);
-   
-   AddressSpace = &Process->AddressSpace;
-   
-   DPRINT("Opening memory area Process %x BaseAddress %x\n",
-         Process, BaseAddress);
    MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
                                          BaseAddress);
    if (MemoryArea == NULL)
@@ -3300,36 +3291,112 @@ MmUnmapViewOfSection(PEPROCESS Process,
    RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
    KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
 
-   CurrentEntry = MemoryArea->Data.SectionData.RegionListHead.Flink;
-   while (CurrentEntry != &MemoryArea->Data.SectionData.RegionListHead)
+   RegionListHead = &MemoryArea->Data.SectionData.RegionListHead;
+   while (!IsListEmpty(RegionListHead))
      {
-       CurrentRegion = 
-        CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
-       CurrentEntry = CurrentEntry->Flink;
+       CurrentEntry = RemoveHeadList(RegionListHead);
+       CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
        ExFreePool(CurrentRegion);
      }
 
    if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
      {
-       Status = MmFreeMemoryArea(&Process->AddressSpace,
-                                BaseAddress,
+       Status = MmFreeMemoryArea(AddressSpace,
+                                BaseAddress,
                                 0,
                                 NULL,
                                 NULL);
      }
    else
      {
-       Status = MmFreeMemoryArea(&Process->AddressSpace,
+       Status = MmFreeMemoryArea(AddressSpace,
                                 BaseAddress,
                                 0,
                                 MmFreeSectionPage,
                                 MemoryArea);
-      }
+     }
    MmUnlockSectionSegment(Segment);
    ObDereferenceObject(Section);
    return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+MmUnmapViewOfSection(PEPROCESS Process,
+                    PVOID BaseAddress)
+{
+   NTSTATUS    Status;
+   PMEMORY_AREA MemoryArea;
+   PMADDRESS_SPACE AddressSpace;
+   PSECTION_OBJECT Section;
+   
+   DPRINT("Opening memory area Process %x BaseAddress %x\n",
+         Process, BaseAddress);
+
+   assert(Process);
+   
+   AddressSpace = &Process->AddressSpace;
+   MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
+                                         BaseAddress);
+   if (MemoryArea == NULL)
+     {
+       return(STATUS_UNSUCCESSFUL);
+     }
+
+   Section = MemoryArea->Data.SectionData.Section;
+
+   if (Section->AllocationAttributes & SEC_IMAGE)
+     {
+       ULONG i;
+       ULONG NrSegments;
+       PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
+       PMM_SECTION_SEGMENT SectionSegments;
+       PVOID ImageBaseAddress;
+       PMM_SECTION_SEGMENT Segment;
+   
+       Segment = MemoryArea->Data.SectionData.Segment;
+       ImageSectionObject = Section->ImageSection;
+       SectionSegments = ImageSectionObject->Segments;
+       NrSegments = ImageSectionObject->NrSegments;
+
+       /* Search for the current segment within the section segments 
+        * and calculate the image base address */
+       for (i = 0; i < NrSegments; i++)
+         {
+          if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD))
+            {
+              if (Segment == &SectionSegments[i])
+                {
+                  ImageBaseAddress = BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
+                  break;
+                }
+            }
+        }
+       if (i >= NrSegments)
+         {
+           KEBUGCHECK(0);
+        }
+
+       for (i = 0; i < NrSegments; i++)
+        {
+          if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD))
+            {
+              PVOID SBaseAddress = (PVOID)
+                (ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
+
+              Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
+            }
+        }
+     }
+   else
+     {
+       Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
+     }
+   return(STATUS_SUCCESS);
+}
+
 /**********************************************************************
  * NAME                                                        EXPORTED
  *     NtUnmapViewOfSection
@@ -3870,67 +3937,16 @@ MmMapViewInSystemSpace (IN      PVOID   SectionObject,
 NTSTATUS STDCALL
 MmUnmapViewInSystemSpace (IN   PVOID   MappedBase)
 {
-  PMEMORY_AREA MemoryArea;
   PMADDRESS_SPACE AddressSpace;
-  PSECTION_OBJECT Section;
-  PMM_SECTION_SEGMENT Segment;
-  KIRQL oldIrql;
-  PLIST_ENTRY CurrentEntry;
-  PMM_REGION CurrentRegion;
   NTSTATUS Status;
 
   DPRINT("MmUnmapViewInSystemSpace() called\n");
 
   AddressSpace = MmGetKernelAddressSpace();
 
-  DPRINT("Opening memory area at base address %x\n",
-        MappedBase);
-  MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
-                                        MappedBase);
-  if (MemoryArea == NULL)
-    {
-      return STATUS_UNSUCCESSFUL;
-    }
-
-  MemoryArea->DeleteInProgress = TRUE;
-  Section = MemoryArea->Data.SectionData.Section;
-  Segment = MemoryArea->Data.SectionData.Segment;
-
-  MmLockSectionSegment(Segment);
-  KeAcquireSpinLock(&Section->ViewListLock, &oldIrql);
-  RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
-  KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
+  Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
 
-  CurrentEntry = MemoryArea->Data.SectionData.RegionListHead.Flink;
-  while (CurrentEntry != &MemoryArea->Data.SectionData.RegionListHead)
-    {
-      CurrentRegion =
-       CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
-      CurrentEntry = CurrentEntry->Flink;
-      ExFreePool(CurrentRegion);
-    }
-
-  if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
-    {
-      Status = MmFreeMemoryArea(AddressSpace,
-                               MappedBase,
-                               0,
-                               NULL,
-                               NULL);
-    }
-  else
-    {
-      Status = MmFreeMemoryArea(AddressSpace,
-                               MappedBase,
-                               0,
-                               MmFreeSectionPage,
-                               MemoryArea);
-    }
-
-  MmUnlockSectionSegment(Segment);
-  ObDereferenceObject(Section);
-
-  return(STATUS_SUCCESS);
+  return Status;
 }