[BOOTMGFW]
authorAlex Ionescu <aionescu@gmail.com>
Sun, 6 Sep 2015 19:22:37 +0000 (19:22 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 6 Sep 2015 19:22:37 +0000 (19:22 +0000)
- Implement most of the physical memory allocator. The heap manager now gets its page allocation fulfilled.

svn path=/trunk/; revision=69067

reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/mm/descriptor.c
reactos/boot/environ/lib/mm/pagealloc.c

index f0d2d47..28ae39f 100644 (file)
@@ -61,8 +61,15 @@ EarlyPrint(_In_ PWCHAR Format, ...);
 #define BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG        0x20
 #define BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG   0x2000
 
+#define BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG            0x40000
 #define BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG       0x2000000
 #define BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG         0x4000000
+#define BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG        0x8000000
+#define BL_MM_DESCRIPTOR_SPECIAL_PAGES_FLAG             0x20000000
+#define BL_MM_DESCRIPTOR_CAME_FROM_FIRMWARE_FLAG        0x80000000
+
+#define BL_MM_REQUEST_DEFAULT_TYPE                      1
+#define BL_MM_REQUEST_TOP_DOWN_TYPE                     2
 
 #define BL_MM_REMOVE_VIRTUAL_REGION_FLAG                0x80000000
 
@@ -474,6 +481,15 @@ BlpMmInitialize (
     _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
     );
 
+/* FIRMWARE ROUTINES *********************************************************/
+
+NTSTATUS
+EfiAllocatePages (
+    _In_ ULONG Type,
+    _In_ ULONG Pages,
+    _Inout_ EFI_PHYSICAL_ADDRESS* Memory
+    );
+
 /* UTILITY ROUTINES **********************************************************/
 
 EFI_STATUS
@@ -553,6 +569,11 @@ MmMdInitByteGranularDescriptor (
     _In_ ULONGLONG PageCount
     );
 
+VOID
+MmMdFreeGlobalDescriptors (
+    VOID
+    );
+
 NTSTATUS
 MmMdAddDescriptorToList (
     _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
@@ -560,6 +581,25 @@ MmMdAddDescriptorToList (
     _In_ ULONG Flags
     );
 
+VOID
+MmMdRemoveDescriptorFromList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+    _In_ PBL_MEMORY_DESCRIPTOR Entry
+    );
+
+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
+    );
+
 NTSTATUS
 MmMdRemoveRegionFromMdlEx (
     __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
@@ -569,6 +609,11 @@ MmMdRemoveRegionFromMdlEx (
     __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList
     );
 
+NTSTATUS
+MmMdFreeDescriptor (
+    _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor
+    );
+
 NTSTATUS
 MmPapAllocatePagesInRange (
     _Inout_ PULONG PhysicalAddress,
index 527c82e..5157e1f 100644 (file)
@@ -646,6 +646,151 @@ Quickie:
     return Status;
 }
 
+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)
+    {
+        EarlyPrint(L"Descriptor overflow\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)
+    {
+        EarlyPrint(L"Virtual memory not yet supported\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)))
+    {
+        EarlyPrint(L"Incorrect memory attributes\n");
+        return FALSE;
+    }
+
+    /* Bail out if the allocation flags don't match */
+    if (((Flags ^ Descriptor->Flags) & 0x190000))
+    {
+        EarlyPrint(L"Incorrect memory allocation flags\n");
+        return FALSE;
+    }
+
+    /* Bail out if the type doesn't match */
+    if (Descriptor->Type != MemoryType)
+    {
+        //EarlyPrint(L"Incorrect descriptor type\n");
+        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;
+    //EarlyPrint(L"Found a matching descriptor: %08I64X with %08I64X pages\n", BasePage, Pages);
+    return TRUE;
+}
+
+VOID
+MmMdFreeGlobalDescriptors (
+    VOID
+    )
+{
+    ULONG Index = 0;
+
+    /* 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)
+    {
+        EarlyPrint(L"Global descriptors not yet supported\n");
+
+        /* Keep going */
+        Index++;
+    }
+
+    /* All global descriptors freed */
+    MmGlobalMemoryDescriptorsUsed = 0;
+}
+
 VOID
 MmMdInitialize (
     _In_ ULONG Phase,
index 80c273e..f084a98 100644 (file)
 
 #include "bl.h"
 
+
+typedef struct _BL_PA_REQUEST
+{
+    BL_ADDRESS_RANGE BaseRange;
+    BL_ADDRESS_RANGE VirtualRange;
+    ULONG Type;
+    ULONGLONG Pages;
+    ULONG MemoryType;
+    ULONG Alignment;
+    ULONG Flags;
+} BL_PA_REQUEST, *PBL_PA_REQUEST;
+
 /* DATA VARIABLES ************************************************************/
 
 ULONGLONG PapMaximumPhysicalPage, PapMinimumPhysicalPage;
@@ -42,6 +54,341 @@ BlpMmInitializeConstraints (
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+MmPapAllocateRegionFromMdl (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
+    _Out_opt_ PBL_MEMORY_DESCRIPTOR Descriptor,
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST CurrentList,
+    _In_ PBL_PA_REQUEST Request, 
+    _In_ BL_MEMORY_TYPE Type
+    )
+{
+    NTSTATUS Status;
+    BL_MEMORY_DESCRIPTOR LocalDescriptor = {{0}};
+    PBL_MEMORY_DESCRIPTOR FoundDescriptor, TempDescriptor;
+    PLIST_ENTRY ListHead, NextEntry;
+    BOOLEAN TopDown, GotFwPages;
+    EFI_PHYSICAL_ADDRESS EfiAddress;
+    ULONGLONG LocalEndPage, FoundEndPage, LocalVirtualEndPage;
+
+    /* Check if any parameters were not passed in correctly */
+    if ( !(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Set failure by default */
+    Status = STATUS_NO_MEMORY;
+
+    /* Take the head and next entry in the list, as appropriate */
+    ListHead = CurrentList->First;
+    if (Request->Type & BL_MM_REQUEST_TOP_DOWN_TYPE)
+    {
+        NextEntry = ListHead->Flink;
+        TopDown = FALSE;
+    }
+    else
+    {
+        NextEntry = ListHead->Blink;
+        TopDown = TRUE;
+    }
+
+    /* Loop through the list */
+    GotFwPages = FALSE;
+    while (NextEntry != ListHead)
+    {
+        /* Grab a descriptor */
+        FoundDescriptor = CONTAINING_RECORD(NextEntry,
+                                            BL_MEMORY_DESCRIPTOR,
+                                            ListEntry);
+
+        /* See if it matches  the request */
+        if (MmMdFindSatisfyingRegion(FoundDescriptor,
+                                     &LocalDescriptor,
+                                     Request->Pages,
+                                     &Request->BaseRange,
+                                     &Request->VirtualRange,
+                                     TopDown,
+                                     Request->MemoryType,
+                                     Request->Flags,
+                                     Request->Alignment))
+        {
+            /* It does, get out */
+            break;
+        }
+
+        /* It doesn't, move to the next appropriate entry */
+        if (TopDown)
+        {
+            NextEntry = NextEntry->Blink;
+        }
+        else
+        {
+            NextEntry = NextEntry->Flink;
+        }
+    }
+
+    /* Check if we exhausted the list */
+    if (NextEntry == ListHead)
+    {
+        EarlyPrint(L"No matching memory found\n");
+        return Status;
+    }
+
+    /* Copy all the flags that are not request flag */
+    LocalDescriptor.Flags = (Request->Flags & 0xFFFF0000) |
+                            (LocalDescriptor.Flags & 0x0000FFFF);
+
+    /* Are we using the physical memory list, and are we OK with using firmware? */
+    if ((CurrentList == &MmMdlUnmappedUnallocated) &&
+        !((Request->Flags & BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG) ||
+          (LocalDescriptor.Flags & BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG)))
+    {
+        /* Allocate the requested address from EFI */
+        EfiAddress = LocalDescriptor.BasePage << PAGE_SHIFT;
+        Status = EfiAllocatePages(AllocateAddress,
+                                  (ULONG)LocalDescriptor.PageCount,
+                                  &EfiAddress);
+        if (!NT_SUCCESS(Status))
+        {
+            EarlyPrint(L"EFI memory allocation failure\n");
+            return Status;
+        }
+
+        /* Remember we got memory from EFI */
+        GotFwPages = TRUE;
+    }
+
+    /* Remove the descriptor from the original list it was on */
+    MmMdRemoveDescriptorFromList(CurrentList, FoundDescriptor);
+
+    /* Are we allocating from the virtual memory list? */
+    if (CurrentList == &MmMdlMappedUnallocated)
+    {
+        EarlyPrint(L"Virtual memory not yet supported\n");
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Does the memory we received not exactly fall onto the beginning of its descriptor? */
+    if (LocalDescriptor.BasePage != FoundDescriptor->BasePage)
+    {
+        EarlyPrint(L"Local Page: %08I64X Found Page: %08I64X\n", LocalDescriptor.BasePage, FoundDescriptor->BasePage);
+        TempDescriptor = MmMdInitByteGranularDescriptor(FoundDescriptor->Flags,
+                                                        FoundDescriptor->Type,
+                                                        FoundDescriptor->BasePage,
+                                                        FoundDescriptor->VirtualPage,
+                                                        LocalDescriptor.BasePage -
+                                                        FoundDescriptor->BasePage);
+        Status = MmMdAddDescriptorToList(CurrentList, TempDescriptor, 0);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+    }
+
+    /* Does the memory we received not exactly fall onto the end of its descriptor? */
+    LocalEndPage = LocalDescriptor.PageCount + LocalDescriptor.BasePage;
+    FoundEndPage = FoundDescriptor->PageCount + FoundDescriptor->BasePage;
+    LocalVirtualEndPage = LocalDescriptor.VirtualPage ?
+                          LocalDescriptor.VirtualPage + LocalDescriptor.PageCount : 0;
+    if (LocalEndPage != FoundEndPage)
+    {
+        EarlyPrint(L"Local Page: %08I64X Found Page: %08I64X\n", LocalEndPage, FoundEndPage);
+        TempDescriptor = MmMdInitByteGranularDescriptor(FoundDescriptor->Flags,
+                                                        FoundDescriptor->Type,
+                                                        LocalEndPage,
+                                                        LocalVirtualEndPage,
+                                                        FoundEndPage - LocalEndPage);
+        Status = MmMdAddDescriptorToList(CurrentList, TempDescriptor, 0);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+    }
+
+    /* We got the memory we needed */
+    Status = STATUS_SUCCESS;
+
+    /* Are we supposed to insert it into a new list? */
+    if (NewList)
+    {
+        /* Copy the allocated region descriptor into the one we found */
+        FoundDescriptor->BaseAddress = LocalDescriptor.BaseAddress;
+        FoundDescriptor->VirtualPage = LocalDescriptor.VirtualPage;
+        FoundDescriptor->PageCount = LocalDescriptor.PageCount;
+        FoundDescriptor->Type = Type;
+        FoundDescriptor->Flags = LocalDescriptor.Flags;
+
+        /* Remember if it came from EFI */
+        if (GotFwPages)
+        {
+            FoundDescriptor->Flags |= BL_MM_DESCRIPTOR_CAME_FROM_FIRMWARE_FLAG;
+        }
+
+        /* Add the descriptor to the requested list */
+        Status = MmMdAddDescriptorToList(NewList, FoundDescriptor, 0);
+    }
+    else
+    {
+        /* Free the descriptor, nobody wants to know about it anymore */
+        MmMdFreeDescriptor(FoundDescriptor);
+    }
+
+    /* Return the allocation region back */
+    RtlCopyMemory(Descriptor, &LocalDescriptor, sizeof(LocalDescriptor));
+    return Status;
+}
+
+NTSTATUS
+MmPaAllocatePages (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
+    _In_ PBL_MEMORY_DESCRIPTOR Descriptor, 
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST CurrentList,
+    _In_ PBL_PA_REQUEST Request,
+    _In_ BL_MEMORY_TYPE MemoryType
+    )
+{
+    NTSTATUS Status;
+
+    /* Heap and page directory/table pages have a special flag */
+    if ((MemoryType >= BlLoaderHeap) && (MemoryType <= BlLoaderReferencePage))
+    {
+        Request->Flags |= BL_MM_DESCRIPTOR_SPECIAL_PAGES_FLAG;
+    }
+
+    /* Try to find a free region of RAM matching this range and request */
+    Request->MemoryType = BlConventionalMemory;
+    Status = MmPapAllocateRegionFromMdl(NewList,
+                                        Descriptor,
+                                        CurrentList,
+                                        Request,
+                                        MemoryType);
+    if (Status == STATUS_NOT_FOUND)
+    {
+        /* Need to re-synchronize the memory map and check other lists */
+        EarlyPrint(L"No RAM found -- backup plan not yet implemented\n");
+    }
+
+    /* Did we get the region we wanted? */
+    if (NT_SUCCESS(Status))
+    {
+        /* All good, return back */
+        return Status;
+    }
+
+    /* Nope, we have to hunt for it elsewhere */
+    EarlyPrint(L"TODO\n");
+    return Status;
+}
+
+NTSTATUS
+MmPapAllocatePhysicalPagesInRange (
+    _Inout_ PPHYSICAL_ADDRESS BaseAddress,
+    _In_ BL_MEMORY_TYPE MemoryType,
+    _In_ ULONGLONG Pages,
+    _In_ ULONG Attributes,
+    _In_ ULONG Alignment,
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
+    _In_opt_ PBL_ADDRESS_RANGE Range, 
+    _In_ ULONG RangeType
+    )
+{
+    NTSTATUS Status;
+    BL_PA_REQUEST Request;
+    BL_MEMORY_DESCRIPTOR Descriptor;
+
+    /* Increase nesting depth */
+    ++MmDescriptorCallTreeCount;
+
+    /* Bail out if no address was specified */
+    if (!BaseAddress)
+    {
+        Status = STATUS_INVALID_PARAMETER;
+        goto Quickie;
+    }
+
+    /* Bail out if no page count was passed in, or a bad list was specified  */
+    if (!(Pages) ||
+        ((NewList != &MmMdlUnmappedAllocated) &&
+         (NewList != &MmMdlPersistentMemory)))
+    {
+        Status = STATUS_INVALID_PARAMETER;
+        goto Quickie;
+    }
+
+    /* Bail out if the passed in range is invalid */
+    if ((Range) && (Range->Minimum >= Range->Maximum))
+    {
+        Status = STATUS_INVALID_PARAMETER;
+        goto Quickie;
+    }
+
+    /* Adjust alignment as needed */
+    if (!Alignment)
+    {
+        Alignment = 1;
+    }
+
+    /* Clear the virtual range */
+    Request.VirtualRange.Minimum = 0;
+    Request.VirtualRange.Maximum = 0;
+
+    /* Check if a fixed allocation was requested*/
+    if (Attributes & BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG)
+    {
+        /* Force the only available range to be the passed in address */
+        Request.BaseRange.Minimum = BaseAddress->QuadPart >> PAGE_SHIFT;
+        Request.BaseRange.Maximum = Request.BaseRange.Minimum + Pages - 1;
+    }
+    else if (Range)
+    {
+        /* Otherwise, a manual range was specified, use it */
+        Request.BaseRange.Minimum = Range->Minimum >> PAGE_SHIFT;
+        Request.BaseRange.Maximum = Request.BaseRange.Minimum +
+                                    (Range->Maximum >> PAGE_SHIFT) - 1;
+    }
+    else
+    {
+        /* Otherwise, use any possible range of pages */
+        Request.BaseRange.Minimum = PapMinimumPhysicalPage;
+        Request.BaseRange.Maximum = MAXULONG >> PAGE_SHIFT;
+    }
+
+    /* Check if no type was specified, or if it was invalid */
+    if (!(RangeType) ||
+         (RangeType & ~(BL_MM_REQUEST_TOP_DOWN_TYPE | BL_MM_REQUEST_DEFAULT_TYPE)))
+    {
+        /* Use default type */
+        Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
+    }
+    else
+    {
+        /* Use the requested type */
+        Request.Type = RangeType;
+    }
+
+    /* Capture the other request parameters */
+    Request.Alignment = Alignment;
+    Request.Pages = Pages;
+    Request.Flags = Attributes;
+    Status = MmPaAllocatePages(NewList,
+                               &Descriptor,
+                               &MmMdlUnmappedUnallocated,
+                               &Request,
+                               MemoryType);
+    if (NT_SUCCESS(Status))
+    {
+        /* We got a descriptor back, return its address */
+        BaseAddress->QuadPart = Descriptor.BasePage << PAGE_SHIFT;
+    }
+
+Quickie:
+    /* Restore the nesting depth */
+    MmMdFreeGlobalDescriptors();
+    --MmDescriptorCallTreeCount;
+    return Status;
+}
+
 NTSTATUS
 MmPapAllocatePagesInRange (
     _Inout_ PULONG PhysicalAddress,
@@ -53,7 +400,56 @@ MmPapAllocatePagesInRange (
     _In_ ULONG Type
     )
 {
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    PHYSICAL_ADDRESS BaseAddress;
+
+    /* Increment nesting depth */
+    ++MmDescriptorCallTreeCount;
+
+    /* Check for missing parameters or invalid range */
+    if (!(PhysicalAddress) ||
+        !(Pages) ||
+        ((Range) && (Range->Minimum >= Range->Maximum)))
+    {
+        Status = STATUS_INVALID_PARAMETER;
+        goto Exit;
+    }
+
+    /* What translation mode are we using? */
+    if (MmTranslationType != BlNone)
+    {
+        /* We don't support virtual memory yet */
+        Status = STATUS_NOT_IMPLEMENTED;
+        goto Exit;
+    }
+    else
+    {
+        /* Check if this is a fixed allocation */
+        BaseAddress.QuadPart = (Attributes & BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG) ?
+                               *PhysicalAddress : 0;
+
+        /* Allocate the pages */
+        Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,
+                                                   MemoryType,
+                                                   Pages,
+                                                   Attributes,
+                                                   Alignment,
+                                                   (&MmMdlMappedAllocated !=
+                                                    &MmMdlPersistentMemory) ?
+                                                   &MmMdlUnmappedAllocated :
+                                                   &MmMdlMappedAllocated,
+                                                   Range,
+                                                   Type);
+
+        /* Return the allocated address */
+        *PhysicalAddress = BaseAddress.LowPart;
+    }
+
+Exit:
+    /* Restore the nesting depth */
+    MmMdFreeGlobalDescriptors();
+    --MmDescriptorCallTreeCount;
+    return Status;
 }
 
 NTSTATUS