- Moved the code for freeing a segment to separate function (MmUnmapViewOfSegment).

- Freed all segments for an image section in MmUnmapViewOfSection.

svn path=/trunk/; revision=5276
This commit is contained in:
Hartmut Birr 2003-07-26 12:47:51 +00:00
parent fc9d49f8c0
commit bb9fe349f2

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c * FILE: ntoskrnl/mm/section.c
@ -3262,28 +3262,19 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
} }
} }
/* NTSTATUS
* @implemented MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace,
*/
NTSTATUS STDCALL
MmUnmapViewOfSection(PEPROCESS Process,
PVOID BaseAddress) PVOID BaseAddress)
{ {
NTSTATUS Status; NTSTATUS Status;
PMEMORY_AREA MemoryArea; PMEMORY_AREA MemoryArea;
PMADDRESS_SPACE AddressSpace;
PSECTION_OBJECT Section; PSECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
KIRQL oldIrql; KIRQL oldIrql;
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PMM_REGION CurrentRegion; 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, MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
BaseAddress); BaseAddress);
if (MemoryArea == NULL) if (MemoryArea == NULL)
@ -3300,36 +3291,112 @@ MmUnmapViewOfSection(PEPROCESS Process,
RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry); RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
KeReleaseSpinLock(&Section->ViewListLock, oldIrql); KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
CurrentEntry = MemoryArea->Data.SectionData.RegionListHead.Flink; RegionListHead = &MemoryArea->Data.SectionData.RegionListHead;
while (CurrentEntry != &MemoryArea->Data.SectionData.RegionListHead) while (!IsListEmpty(RegionListHead))
{ {
CurrentRegion = CurrentEntry = RemoveHeadList(RegionListHead);
CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry); CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry);
CurrentEntry = CurrentEntry->Flink;
ExFreePool(CurrentRegion); ExFreePool(CurrentRegion);
} }
if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) if (Section->AllocationAttributes & SEC_PHYSICALMEMORY)
{ {
Status = MmFreeMemoryArea(&Process->AddressSpace, Status = MmFreeMemoryArea(AddressSpace,
BaseAddress, BaseAddress,
0, 0,
NULL, NULL,
NULL); NULL);
} }
else else
{ {
Status = MmFreeMemoryArea(&Process->AddressSpace, Status = MmFreeMemoryArea(AddressSpace,
BaseAddress, BaseAddress,
0, 0,
MmFreeSectionPage, MmFreeSectionPage,
MemoryArea); MemoryArea);
} }
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
ObDereferenceObject(Section); ObDereferenceObject(Section);
return(STATUS_SUCCESS); 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 * NAME EXPORTED
* NtUnmapViewOfSection * NtUnmapViewOfSection
@ -3870,67 +3937,16 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
NTSTATUS STDCALL NTSTATUS STDCALL
MmUnmapViewInSystemSpace (IN PVOID MappedBase) MmUnmapViewInSystemSpace (IN PVOID MappedBase)
{ {
PMEMORY_AREA MemoryArea;
PMADDRESS_SPACE AddressSpace; PMADDRESS_SPACE AddressSpace;
PSECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
KIRQL oldIrql;
PLIST_ENTRY CurrentEntry;
PMM_REGION CurrentRegion;
NTSTATUS Status; NTSTATUS Status;
DPRINT("MmUnmapViewInSystemSpace() called\n"); DPRINT("MmUnmapViewInSystemSpace() called\n");
AddressSpace = MmGetKernelAddressSpace(); AddressSpace = MmGetKernelAddressSpace();
DPRINT("Opening memory area at base address %x\n", Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
MappedBase);
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
MappedBase);
if (MemoryArea == NULL)
{
return STATUS_UNSUCCESSFUL;
}
MemoryArea->DeleteInProgress = TRUE; return Status;
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);
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);
} }