BL_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[512];
ULONG MmGlobalMemoryDescriptorCount;
PBL_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
-BOOLEAN MmGlobalMemoryDescriptorsUsed;
+ULONG MmGlobalMemoryDescriptorsUsed;
PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
ULONG MmDynamicMemoryDescriptorCount;
BL_MEMORY_CLASS Class1, Class2;
ULONG i, j;
- /* Descriptor is free RAM -- it preceeds */
+ /* Descriptor is free RAM -- it precedes */
if (Type1 == BlConventionalMemory)
{
return TRUE;
}
- /* It isn't free RAM, but the comparator is -- it suceeds it */
+ /* It isn't free RAM, but the comparator is -- it succeeds it */
if (Type2 == BlConventionalMemory)
{
return FALSE;
}
- /* Descriptor is not system, application, or loader class -- it preceeds */
+ /* Descriptor is not system, application, or loader class -- it precedes */
Class1 = Type1 >> BL_MEMORY_CLASS_SHIFT;
if ((Class1 != BlSystemClass) &&
(Class1 != BlApplicationClass) &&
return TRUE;
}
- /* It isn't one of those classes, but the comparator it -- it suceeds it */
+ /* It isn't one of those classes, but the comparator it -- it succeeds it */
Class2 = Type2 >> BL_MEMORY_CLASS_SHIFT;
if ((Class2 != BlSystemClass) &&
(Class2 != BlApplicationClass) &&
}
}
- /* The comparator isn't system, so it preceeds it */
+ /* The comparator isn't system, so it precedes it */
return TRUE;
}
- /* Descriptor is not system class, but comparator is -- it suceeds it */
+ /* Descriptor is not system class, but comparator is -- it succeeds it */
if (Class2 == BlSystemClass)
{
return FALSE;
}
- /* Descriptor is loader class -- it preceeds */
+ /* Descriptor is loader class -- it precedes */
if (Class1 == BlLoaderClass)
{
return TRUE;
}
- /* It isn't loader class -- if the other guy is, suceed it */
+ /* It isn't loader class -- if the other guy is, succeed it */
return Class2 != BlLoaderClass;
}
_In_ ULONG Count
)
{
- EarlyPrint(L"NOT SUPPORTED!!!\n");
+ EfiPrintf(L"dynamic switch NOT SUPPORTED!!!\r\n");
while (1);
}
else
{
/* It's a dynamic descriptor, so free it */
- EarlyPrint(L"Dynamic descriptors not yet supported\n");
+ EfiPrintf(L"Dynamic descriptors not yet supported\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
}
}
+ULONG
+MmMdCountList (
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
+ )
+{
+ PLIST_ENTRY First, NextEntry;
+ ULONG Count;
+
+ /* Iterate the list */
+ for (Count = 0, First = MdList->First, NextEntry = First->Flink;
+ NextEntry != First;
+ NextEntry = NextEntry->Flink, Count++);
+
+ /* Return the count */
+ return Count;
+}
+
+VOID
+MmMdInitializeList (
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ ULONG Type,
+ _In_ PLIST_ENTRY ListHead
+ )
+{
+ /* Check if a list was specified */
+ if (ListHead)
+ {
+ /* Use it */
+ MdList->First = ListHead;
+ }
+ else
+ {
+ /* Otherwise, use the internal, built-in list */
+ InitializeListHead(&MdList->ListHead);
+ MdList->First = &MdList->ListHead;
+ }
+
+ /* Set the type */
+ MdList->Type = Type;
+
+ /* Initialize current iterator to nothing */
+ MdList->This = NULL;
+}
+
+NTSTATUS
+MmMdCopyList (
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST DestinationList,
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST SourceList,
+ _In_opt_ PBL_MEMORY_DESCRIPTOR ListDescriptor,
+ _Out_ PULONG ActualCount,
+ _In_ ULONG Count,
+ _In_ ULONG Flags
+ )
+{
+ NTSTATUS Status;
+ PULONG Used;
+ PLIST_ENTRY First, NextEntry;
+ PBL_MEMORY_DESCRIPTOR Descriptor;
+
+ /* Both parameters must be present */
+ if (!(DestinationList) || !(SourceList))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Assume success */
+ Status = STATUS_SUCCESS;
+
+ /* Check if a descriptor is being used to store the list */
+ if (ListDescriptor)
+ {
+ /* See how big it is */
+ Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG;
+ Used = ActualCount;
+ }
+ else
+ {
+ /* We are using our internal descriptors instead */
+ Used = &MmGlobalMemoryDescriptorsUsed;
+ ++MmDescriptorCallTreeCount;
+
+ /* Use as many as are available */
+ Count = MmGlobalMemoryDescriptorCount;
+ ListDescriptor = MmGlobalMemoryDescriptors;
+ }
+
+ /* Never truncate descriptors during a list copy */
+ Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG;
+
+ /* Iterate through the list */
+ First = SourceList->First;
+ NextEntry = First->Flink;
+ while ((NextEntry != First) && (NT_SUCCESS(Status)))
+ {
+ /* Make sure there's still space */
+ if (Count <= *Used)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ /* Get the current descriptor */
+ Descriptor = CONTAINING_RECORD(NextEntry,
+ BL_MEMORY_DESCRIPTOR,
+ ListEntry);
+
+ /* Copy it into one of the descriptors we have */
+ RtlCopyMemory(&ListDescriptor[*Used],
+ Descriptor,
+ sizeof(*Descriptor));
+
+ /* Add it to the list we have */
+ Status = MmMdAddDescriptorToList(DestinationList,
+ &ListDescriptor[*Used],
+ Flags);
+ ++*Used;
+
+ /* Move to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Check if the global descriptors were used */
+ if (ListDescriptor == MmGlobalMemoryDescriptors)
+ {
+ /* Unwind our usage */
+ MmMdFreeGlobalDescriptors();
+ --MmDescriptorCallTreeCount;
+ }
+
+ /* Return back to caller */
+ return Status;
+}
+
VOID
MmMdRemoveDescriptorFromList (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
/* Remove the entry */
RemoveEntryList(&Entry->ListEntry);
- /* Check if this was the current link */
+ /* Check if this was the current link */
if (MdList->This == &Entry->ListEntry)
{
/* Remove the current link and set the next one */
/* If we're out of descriptors, bail out */
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount)
{
- EarlyPrint(L"Out of descriptors!\n");
+ EfiPrintf(L"Out of descriptors!\r\n");
return NULL;
}
/* Check for backward overlap */
if ((PreviousEntry != MdList->First) && (MemoryDescriptor->BasePage < PreviousEndPage))
{
- EarlyPrint(L"Overlap detected -- this is unexpected on x86/x64 platforms\n");
+ EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
}
/* Check for forward overlap */
if ((NextEntry != MdList->First) && (NextDescriptor->BasePage < EndPage))
{
- EarlyPrint(L"Overlap detected -- this is unexpected on x86/x64 platforms\n");
+ EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
}
/* Nothing to do */
((MemoryDescriptor->VirtualPage) && (PreviousDescriptor->VirtualPage) &&
(PreviousMappedEndPage == MemoryDescriptor->VirtualPage))))
{
- EarlyPrint(L"Previous descriptor coalescible!\n");
+ EfiPrintf(L"Previous descriptor coalescable!\r\n");
}
/* CHeck if the current entry touches the next entry, and is compatible */
((MemoryDescriptor->VirtualPage) && (PreviousDescriptor->VirtualPage) &&
(MappedEndPage == NextDescriptor->VirtualPage))))
{
- EarlyPrint(L"Next descriptor coalescible!\n");
+ EfiPrintf(L"Next descriptor coalescable!\r\n");
}
/* Nothing to do */
else
{
/* Coalesce if the descriptor requires it */
- if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG)
+ if (MemoryDescriptor->Flags & BlMemoryCoalesced)
{
Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
}
}
/* Update the current list pointer if the descriptor requires it */
- if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG)
+ if (MemoryDescriptor->Flags & BlMemoryUpdate)
{
Flags |= BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG;
}
}
}
-typedef enum _BL_MEMORY_DESCRIPTOR_TYPE
-{
- BlMdPhysical,
- BlMdVirtual,
-} BL_MEMORY_DESCRIPTOR_TYPE;
-
-#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000
-
NTSTATUS
MmMdRemoveRegionFromMdlEx (
__in PBL_MEMORY_DESCRIPTOR_LIST MdList,
PLIST_ENTRY ListHead, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor;
BL_MEMORY_DESCRIPTOR NewDescriptor;
+ ULONGLONG RegionSize;
ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
+ /* Set initial status */
+ Status = STATUS_SUCCESS;
+
/* Check if removed descriptors should go into a new list */
if (NewMdList != NULL)
{
FoundPageCount = Descriptor->PageCount;
FoundEndPage = FoundBasePage + FoundPageCount;
EndPage = PageCount + BasePage;
- EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in 0x%08I64X-0x%08I64X\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
+ //EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in 0x%08I64X-0x%08I64X\r\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
/* Make a copy of the original descriptor */
RtlCopyMemory(&NewDescriptor, NextEntry, sizeof(NewDescriptor));
if ((FoundBasePage >= BasePage) || (EndPage >= FoundEndPage))
{
/* This descriptor doesn't cover any part of the range */
- EarlyPrint(L"No part of this descriptor contains the region\n");
+ //EarlyPrint(L"No part of this descriptor contains the region\r\n");
}
else
{
/* This descriptor covers the head of the allocation */
- EarlyPrint(L"Descriptor covers the head of the region\n");
+ //EarlyPrint(L"Descriptor covers the head of the region\r\n");
}
}
else
{
/* This descriptor contains the entire allocation */
- EarlyPrint(L"Descriptor contains the entire region\n");
+ //EarlyPrint(L"Descriptor contains the entire region\r\n");
}
+
+ /* Keep going */
+ NextEntry = NextEntry->Flink;
}
else
{
- /* This descriptor covers the end of the allocation */
- EarlyPrint(L"Descriptor covers the end of the region\n");
- }
+ /*
+ * This descriptor contains the end of the allocation. It may:
+ *
+ * - Contain the full allocation (i.e.: the start is aligned)
+ * - Contain parts of the end of the allocation (i.e.: the end is beyond)
+ * - Contain the entire tail end of the allocation (i..e:the end is within)
+ *
+ * So first, figure out if we cover the entire end or not
+ */
+ if (EndPage > FoundEndPage)
+ {
+ /* The allocation goes past the end of this descriptor */
+ EndPage = FoundEndPage;
+ }
- /* Keep going */
- NextEntry = NextEntry->Flink;
+ /* This is how many pages we will eat away from the descriptor */
+ RegionSize = EndPage - FoundBasePage;
+
+ /* Update the descriptor to account for the consumed pages */
+ Descriptor->BasePage += RegionSize;
+ Descriptor->PageCount -= RegionSize;
+ if (Descriptor->VirtualPage)
+ {
+ Descriptor->VirtualPage += RegionSize;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+
+ /* Check if the descriptor is now empty */
+ if (!Descriptor->PageCount)
+ {
+ /* Remove it */
+ //EarlyPrint(L"Entire descriptor consumed\r\n");
+ MmMdRemoveDescriptorFromList(MdList, Descriptor);
+ MmMdFreeDescriptor(Descriptor);
+
+ /* Check if we're supposed to insert it into a new list */
+ if (HaveNewList)
+ {
+ EfiPrintf(L"Not yet implemented\r\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Quickie;
+ }
+ }
+ }
}
Quickie:
return Status;
}
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptorFromMdl (
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ ULONG Flags,
+ _In_ ULONGLONG Page
+ )
+{
+ BOOLEAN IsVirtual;
+ PLIST_ENTRY NextEntry, ListHead;
+ PBL_MEMORY_DESCRIPTOR Current;
+ ULONGLONG BasePage;
+
+ /* Assume physical */
+ IsVirtual = FALSE;
+
+ /* Check if the caller wants physical memory */
+ if (!(Flags & BL_MM_REMOVE_VIRTUAL_REGION_FLAG))
+ {
+ /* Check if this is a virtual memory list */
+ if (MdList->Type == BlMdVirtual)
+ {
+ /* We won't find anything */
+ return NULL;
+ }
+ }
+ else if (MdList->Type == BlMdPhysical)
+ {
+ /* Otherwise, caller wants virtual, but this is a physical list */
+ IsVirtual = TRUE;
+ NextEntry = MdList->First->Flink;
+ }
+
+ /* Check if this is a physical search */
+ if (!IsVirtual)
+ {
+ /* Check if we can use the current pointer */
+ NextEntry = MdList->This;
+ if (!NextEntry)
+ {
+ /* We can't -- start at the beginning */
+ NextEntry = MdList->First->Flink;
+ }
+ else
+ {
+ /* If the page is below the current pointer, restart */
+ Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+ if (Page < Current->BasePage)
+ {
+ NextEntry = MdList->First->Flink;
+ }
+ }
+ }
+
+ /* Loop the list of descriptors */
+ ListHead = MdList->First;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current one */
+ Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+
+ /* Check if we are looking for virtual memory */
+ if (IsVirtual)
+ {
+ /* Use the base address */
+ BasePage = Current->VirtualPage;
+ }
+ else
+ {
+ /* Use the page */
+ BasePage = Current->BasePage;
+ }
+
+ /* If this is a virtual descriptor, make sure it has a base address */
+ if ((!(IsVirtual) || (BasePage)) &&
+ (BasePage <= Page) &&
+ (Page < (BasePage + Current->PageCount)))
+ {
+ /* The descriptor fits the page being requested */
+ return Current;
+ }
+
+ /* Try the next one */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Nothing found if we're here */
+ return NULL;
+}
+
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptor (
+ _In_ ULONG WhichList,
+ _In_ ULONG Flags,
+ _In_ ULONGLONG Page
+ )
+{
+ PBL_MEMORY_DESCRIPTOR FoundDescriptor;
+
+ /* Check if the caller is looking for mapped, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_MAPPED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for mapped, unallocated memory */
+ if (WhichList & BL_MM_INCLUDE_MAPPED_UNALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedUnallocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for unmapped, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_UNMAPPED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for unmapped, unallocated memory */
+ if (WhichList & BL_MM_INCLUDE_UNMAPPED_UNALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedUnallocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for reserved, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_RESERVED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlReservedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for bad memory */
+ if (WhichList & BL_MM_INCLUDE_BAD_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlBadMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for truncated memory */
+ if (WhichList & BL_MM_INCLUDE_TRUNCATED_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlTruncatedMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for persistent memory */
+ if (WhichList & BL_MM_INCLUDE_PERSISTENT_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlPersistentMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Nothing if we got here */
+ return NULL;
+}
+
+BOOLEAN
+MmMdFindSatisfyingRegion (
+ _In_ PBL_MEMORY_DESCRIPTOR Descriptor,
+ _Out_ PBL_MEMORY_DESCRIPTOR NewDescriptor,
+ _In_ ULONGLONG Pages,
+ _In_ PBL_ADDRESS_RANGE BaseRange,
+ _In_ PBL_ADDRESS_RANGE VirtualRange,
+ _In_ BOOLEAN TopDown,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ ULONG Flags,
+ _In_ ULONG Alignment
+ )
+{
+ ULONGLONG BaseMin, BaseMax;
+ ULONGLONG VirtualPage, BasePage;
+
+ /* Extract the minimum and maximum range */
+ BaseMin = BaseRange->Minimum;
+ BaseMax = BaseRange->Maximum;
+
+ /* Don't go below where the descriptor starts */
+ if (BaseMin < Descriptor->BasePage)
+ {
+ BaseMin = Descriptor->BasePage;
+ }
+
+ /* Don't go beyond where the descriptor ends */
+ if (BaseMax > (Descriptor->BasePage + Descriptor->PageCount - 1))
+ {
+ BaseMax = (Descriptor->BasePage + Descriptor->PageCount - 1);
+ }
+
+ /* Check for start overflow */
+ if (BaseMin > BaseMax)
+ {
+ EfiPrintf(L"Descriptor overflow\r\n");
+ return FALSE;
+ }
+
+ /* Align the base as required */
+ if (Alignment != 1)
+ {
+ BaseMin = ALIGN_UP_BY(BaseMin, Alignment);
+ }
+
+ /* Check for range overflow */
+ if (((BaseMin + Pages - 1) < BaseMin) || ((BaseMin + Pages - 1) > BaseMax))
+ {
+ return FALSE;
+ }
+
+ /* Check if this was a top-down request */
+ if (TopDown)
+ {
+ /* Then get the highest page possible */
+ BasePage = BaseMax - Pages + 1;
+ if (Alignment != 1)
+ {
+ /* Align it as needed */
+ BasePage = ALIGN_DOWN_BY(BasePage, Alignment);
+ }
+ }
+ else
+ {
+ /* Otherwise, get the lowest page possible */
+ BasePage = BaseMin;
+ }
+
+ /* If a virtual address range was passed in, this must be a virtual descriptor */
+ if (((VirtualRange->Minimum) || (VirtualRange->Maximum)) &&
+ !(Descriptor->VirtualPage))
+ {
+ return FALSE;
+ }
+
+ /* Any mapped page already? */
+ if (Descriptor->VirtualPage)
+ {
+ EfiPrintf(L"Virtual memory not yet supported\r\n");
+ return FALSE;
+ }
+ else
+ {
+ /* Nothing to worry about */
+ VirtualPage = 0;
+ }
+
+ /* Bail out if the memory type attributes don't match */
+ if ((((Flags & 0xFF) & (Descriptor->Flags & 0xFF)) != (Flags & 0xFF)) ||
+ (((Flags & 0xFF00) & (Descriptor->Flags & 0xFF00)) != (Flags & 0xFF00)))
+ {
+ EfiPrintf(L"Incorrect memory attributes\r\n");
+ return FALSE;
+ }
+
+ /* Bail out if the allocation flags don't match */
+ if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown)))
+ {
+ //EfiPrintf(L"Incorrect memory allocation flags\r\n");
+ return FALSE;
+ }
+
+ /* Bail out if the type doesn't match */
+ if (Descriptor->Type != MemoryType)
+ {
+ //EfiPrintf(L"Incorrect descriptor type: %lx %lx\r\n", Descriptor->Type, MemoryType);
+ return FALSE;
+ }
+
+ /* We have a matching region, fill out the descriptor for it */
+ NewDescriptor->BasePage = BasePage;
+ NewDescriptor->PageCount = Pages;
+ NewDescriptor->Type = Descriptor->Type;
+ NewDescriptor->VirtualPage = VirtualPage;
+ NewDescriptor->Flags = Descriptor->Flags;
+ //EfiPrintf(L"Found a matching descriptor: %08I64X with %08I64X pages\r\n", BasePage, Pages);
+ return TRUE;
+}
+
+VOID
+MmMdFreeGlobalDescriptors (
+ VOID
+ )
+{
+ PBL_MEMORY_DESCRIPTOR Descriptor, OldDescriptor;
+ ULONG Index = 0;
+ PLIST_ENTRY OldFlink, OldBlink;
+
+ /* Make sure we're not int middle of a call using a descriptor */
+ if (MmDescriptorCallTreeCount != 1)
+ {
+ return;
+ }
+
+ /* Loop every current global descriptor */
+ while (Index < MmGlobalMemoryDescriptorsUsed)
+ {
+ /* Does it have any valid pageS? */
+ OldDescriptor = &MmGlobalMemoryDescriptors[Index];
+ if (OldDescriptor->PageCount)
+ {
+ /* Allocate a copy of it */
+ Descriptor = BlMmAllocateHeap(sizeof(*Descriptor));
+ if (!Descriptor)
+ {
+ return;
+ }
+
+ /* Save the links */
+ OldBlink = OldDescriptor->ListEntry.Blink;
+ OldFlink = OldDescriptor->ListEntry.Flink;
+
+ /* Make the copy */
+ *Descriptor = *OldDescriptor;
+
+ /* Fix the links */
+ OldBlink->Flink = &Descriptor->ListEntry;
+ OldFlink->Blink = &Descriptor->ListEntry;
+
+ /* Zero the descriptor */
+ RtlZeroMemory(OldDescriptor, sizeof(*OldDescriptor));
+ }
+
+ /* Keep going */
+ Index++;
+ }
+
+ /* All global descriptors freed */
+ MmGlobalMemoryDescriptorsUsed = 0;
+}
+
VOID
MmMdInitialize (
_In_ ULONG Phase,
MmGlobalMemoryDescriptorCount = RTL_NUMBER_OF(MmStaticMemoryDescriptors);
MmGlobalMemoryDescriptors = MmStaticMemoryDescriptors;
RtlZeroMemory(MmStaticMemoryDescriptors, sizeof(MmStaticMemoryDescriptors));
- MmGlobalMemoryDescriptorsUsed = FALSE;
+ MmGlobalMemoryDescriptorsUsed = 0;
}
}