[BOOTLIB]: Implement BlFwGetParameters.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 5 Feb 2017 05:35:44 +0000 (05:35 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 5 Feb 2017 05:35:44 +0000 (05:35 +0000)
[BOOTLIB]: Implement ImgpCopyApplicationBootDevice except for partition devices;
[BOOTLIB]: Implement ImgpInitializeBootApplicationParameters.
[BOOTLIB]: Fix bug in BlMmGetMemoryMap.
[BOOTLIB]: Simplify MmMdCopyList.

svn path=/trunk/; revision=73692

reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/firmware/efi/firmware.c
reactos/boot/environ/lib/misc/image.c
reactos/boot/environ/lib/mm/descriptor.c
reactos/boot/environ/lib/mm/pagealloc.c

index 70649db..169700f 100644 (file)
@@ -184,7 +184,6 @@ C_ASSERT(BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY == 0x240);
 #define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH         0x10000
 #define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME       0x400000
 
 #define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH         0x10000
 #define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME       0x400000
 
-
 #define BL_UTL_CHECKSUM_COMPLEMENT                      0x10000
 #define BL_UTL_CHECKSUM_ROTATE                          0x20000
 #define BL_UTL_CHECKSUM_NEGATE                          0x40000
 #define BL_UTL_CHECKSUM_COMPLEMENT                      0x10000
 #define BL_UTL_CHECKSUM_ROTATE                          0x20000
 #define BL_UTL_CHECKSUM_NEGATE                          0x40000
@@ -1404,6 +1403,11 @@ EfiPrintf (
     ...
     );
 
     ...
     );
 
+NTSTATUS
+BlFwGetParameters(
+    _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
+    );
+
 NTSTATUS
 BlFwEnumerateDevice (
     _In_ PBL_DEVICE_DESCRIPTOR Device
 NTSTATUS
 BlFwEnumerateDevice (
     _In_ PBL_DEVICE_DESCRIPTOR Device
index 04d59d5..a88095d 100644 (file)
@@ -1784,6 +1784,22 @@ BlpFwInitialize (
     return Status;
 }
 
     return Status;
 }
 
+NTSTATUS
+BlFwGetParameters (
+    _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
+    )
+{
+    /* Make sure we got an argument */
+    if (!Parameters)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Copy the static data */
+    *Parameters = *EfiFirmwareParameters;
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 BlFwEnumerateDevice (
     _In_ PBL_DEVICE_DESCRIPTOR Device
 NTSTATUS
 BlFwEnumerateDevice (
     _In_ PBL_DEVICE_DESCRIPTOR Device
index be90108..2b4fb84 100644 (file)
@@ -1604,6 +1604,26 @@ BlpPdParseReturnArguments (
     return STATUS_NOT_IMPLEMENTED;
 }
 
     return STATUS_NOT_IMPLEMENTED;
 }
 
+NTSTATUS
+ImgpCopyApplicationBootDevice (
+    __in PBL_DEVICE_DESCRIPTOR DestinationDevice,
+    __in PBL_DEVICE_DESCRIPTOR SourceDevice
+    )
+{
+    /* Is this a partition device? */
+    if (SourceDevice->DeviceType != PartitionDevice)
+    {
+        /* It's not -- a simple copy will do */
+        RtlCopyMemory(DestinationDevice, SourceDevice, SourceDevice->Size);
+        return STATUS_SUCCESS;
+    }
+
+    /* TODO */
+    EfiPrintf(L"Partition copy not supported\r\n");
+    return STATUS_NOT_IMPLEMENTED;
+
+}
+
 NTSTATUS
 ImgpInitializeBootApplicationParameters (
     _In_ PBL_IMAGE_PARAMETERS ImageParameters,
 NTSTATUS
 ImgpInitializeBootApplicationParameters (
     _In_ PBL_IMAGE_PARAMETERS ImageParameters,
@@ -1616,6 +1636,13 @@ ImgpInitializeBootApplicationParameters (
     PIMAGE_NT_HEADERS NtHeaders;
     BL_IMAGE_PARAMETERS MemoryParameters;
     LIST_ENTRY MemoryList;
     PIMAGE_NT_HEADERS NtHeaders;
     BL_IMAGE_PARAMETERS MemoryParameters;
     LIST_ENTRY MemoryList;
+    PBL_FIRMWARE_DESCRIPTOR FirmwareParameters;
+    PBL_DEVICE_DESCRIPTOR BootDevice;
+    PBL_MEMORY_DATA MemoryData;
+    PBL_APPLICATION_ENTRY BootAppEntry;
+    PBL_RETURN_ARGUMENTS ReturnArguments;
+    PBOOT_APPLICATION_PARAMETER_BLOCK ParameterBlock;
+    ULONG EntrySize, BufferSize;
 
     /* Get the image headers and validate it */
     Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
 
     /* Get the image headers and validate it */
     Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
@@ -1636,10 +1663,138 @@ ImgpInitializeBootApplicationParameters (
                               0);
     if ((Status != STATUS_BUFFER_TOO_SMALL) && (Status != STATUS_SUCCESS))
     {
                               0);
     if ((Status != STATUS_BUFFER_TOO_SMALL) && (Status != STATUS_SUCCESS))
     {
+        /* We failed due to an unknown reason -- bail out */
         return Status;
     }
 
         return Status;
     }
 
-    EfiPrintf(L"Memory map needs %lx bytes\n", MemoryParameters.BufferSize);
+    /* Compute the list of the BCD plus the application entry */
+    EntrySize = BlGetBootOptionListSize(&AppEntry->BcdData) +
+                FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData);
+
+    /* Compute the total size required for the entire structure */
+    BufferSize = EntrySize +
+                 BlpBootDevice->Size +
+                 MemoryParameters.BufferSize +
+                 sizeof(*ReturnArguments) +
+                 sizeof(*MemoryData) + 
+                 sizeof(*FirmwareParameters) + 
+                 sizeof(*ParameterBlock);
+
+    /* Check if this gives us enough space */
+    if (ImageParameters->BufferSize < BufferSize)
+    {
+        /* It does not -- free the existing buffer */
+        if (ImageParameters->BufferSize)
+        {
+            BlMmFreeHeap(ImageParameters->Buffer);
+        }
+
+        /* Allocate a new buffer of sufficient size */
+        ImageParameters->BufferSize = BufferSize;
+        ImageParameters->Buffer = BlMmAllocateHeap(BufferSize);
+        if (!ImageParameters->Buffer)
+        {
+            /* Bail out if we couldn't allocate it */
+            return STATUS_NO_MEMORY;
+        }
+    }
+
+    /* Zero out the parameter block */
+    ParameterBlock = (PBOOT_APPLICATION_PARAMETER_BLOCK)ImageParameters->Buffer;
+    RtlZeroMemory(ParameterBlock, BufferSize);
+
+    /* Initialize it */
+    ParameterBlock->Version = BOOT_APPLICATION_VERSION;
+    ParameterBlock->Size = BufferSize;
+    ParameterBlock->Signature[0] = BOOT_APPLICATION_SIGNATURE_1;
+    ParameterBlock->Signature[1] = BOOT_APPLICATION_SIGNATURE_2;
+    ParameterBlock->MemoryTranslationType = MmTranslationType;
+    ParameterBlock->ImageType = IMAGE_FILE_MACHINE_I386;
+    ParameterBlock->ImageBase = (ULONGLONG)ImageBase;
+    ParameterBlock->ImageSize = NtHeaders->OptionalHeader.SizeOfImage;
+
+    /* Get the offset to the memory data */
+    ParameterBlock->MemoryDataOffset = sizeof(*ParameterBlock);
+
+    /* Fill it out */
+    MemoryData = (PBL_MEMORY_DATA)((ULONG_PTR)ParameterBlock +
+                                   ParameterBlock->MemoryDataOffset);
+    MemoryData->Version = BL_MEMORY_DATA_VERSION;
+    MemoryData->MdListOffset = sizeof(*MemoryData);
+    MemoryData->DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR);
+    MemoryData->DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage);
+
+    /* And populate the memory map */
+    MemoryParameters.Buffer = MemoryData + 1;
+    Status = BlMmGetMemoryMap(&MemoryList,
+                              &MemoryParameters,
+                              BL_MM_INCLUDE_PERSISTENT_MEMORY |
+                              BL_MM_INCLUDE_MAPPED_ALLOCATED |
+                              BL_MM_INCLUDE_MAPPED_UNALLOCATED |
+                              BL_MM_INCLUDE_UNMAPPED_ALLOCATED |
+                              BL_MM_INCLUDE_RESERVED_ALLOCATED,
+                              0);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Now that we have the map, indicate the number of descriptors */
+    MemoryData->DescriptorCount = MemoryParameters.ActualSize /
+                                  MemoryData->DescriptorSize;
+
+    /* Get the offset to the application entry */
+    ParameterBlock->AppEntryOffset = ParameterBlock->MemoryDataOffset +
+                                     MemoryData->MdListOffset +
+                                     MemoryParameters.BufferSize;
+
+    /* Fill it out */
+    BootAppEntry = (PBL_APPLICATION_ENTRY)((ULONG_PTR)ParameterBlock +
+                                           ParameterBlock->AppEntryOffset);
+    RtlCopyMemory(BootAppEntry, AppEntry, EntrySize);
+
+    /* Get the offset to the boot device */
+    ParameterBlock->BootDeviceOffset = ParameterBlock->AppEntryOffset +
+                                       EntrySize;
+
+    /* Fill it out */
+    BootDevice = (PBL_DEVICE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
+                                         ParameterBlock->BootDeviceOffset);
+    Status = ImgpCopyApplicationBootDevice(BootDevice, BlpBootDevice);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Get the offset to the firmware data */
+    ParameterBlock->FirmwareParametersOffset = ParameterBlock->BootDeviceOffset +
+                                               BootDevice->Size;
+
+    /* Fill it out */
+    FirmwareParameters = (PBL_FIRMWARE_DESCRIPTOR)((ULONG_PTR)ParameterBlock +
+                                                   ParameterBlock->
+                                                   FirmwareParametersOffset);
+    Status = BlFwGetParameters(FirmwareParameters);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Get the offset to the return arguments */
+    ParameterBlock->ReturnArgumentsOffset = ParameterBlock->FirmwareParametersOffset +
+                                            sizeof(BL_FIRMWARE_DESCRIPTOR);
+
+    /* Fill them out */
+    ReturnArguments = (PBL_RETURN_ARGUMENTS)((ULONG_PTR)ParameterBlock +
+                                             ParameterBlock->
+                                             ReturnArgumentsOffset);
+    ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
+    ReturnArguments->DataPage = 0;
+    ReturnArguments->DataSize = 0;
+
+    /* Structure complete */
+    ImageParameters->ActualSize = ParameterBlock->ReturnArgumentsOffset +
+                                  sizeof(*ReturnArguments);
     return STATUS_SUCCESS;
 }
 
     return STATUS_SUCCESS;
 }
 
index 2c7d859..a6843c4 100644 (file)
@@ -290,45 +290,33 @@ MmMdCopyList (
     /* Iterate through the list */
     First = SourceList->First;
     NextEntry = First->Flink;
     /* Iterate through the list */
     First = SourceList->First;
     NextEntry = First->Flink;
-    if (First->Flink != First)
+    while ((NextEntry != First) && (NT_SUCCESS(Status)))
     {
     {
-        /* As long as we have success */
-        while (NT_SUCCESS(Status))
+        /* Make sure there's still space */
+        if (Count <= *Used)
         {
         {
-            /* Check if 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));
+            Status = STATUS_NO_MEMORY;
+            break;
+        }
 
 
-            /* Add it to the list we have */
-            Status = MmMdAddDescriptorToList(DestinationList,
-                                             &ListDescriptor[*Used],
-                                             Flags);
-            ++*Used;
+        /* Get the current descriptor */
+        Descriptor = CONTAINING_RECORD(NextEntry,
+                                       BL_MEMORY_DESCRIPTOR,
+                                       ListEntry);
 
 
-            /* Before moving on, check if we're done */
-            Finished = NextEntry->Flink == SourceList->First;
+        /* Copy it into one of the descriptors we have */
+        RtlCopyMemory(&ListDescriptor[*Used],
+                      Descriptor,
+                      sizeof(*Descriptor));
 
 
-            /* Move to the next entry */
-            NextEntry = NextEntry->Flink;
+        /* Add it to the list we have */
+        Status = MmMdAddDescriptorToList(DestinationList,
+                                         &ListDescriptor[*Used],
+                                         Flags);
+        ++*Used;
 
 
-            if (Finished)
-            {
-                break;
-            }
-        }
+        /* Move to the next entry */
+        NextEntry = NextEntry->Flink;
     }
 
     /* Check if the global descriptors were used */
     }
 
     /* Check if the global descriptors were used */
index 886532d..453caa8 100644 (file)
@@ -660,6 +660,9 @@ BlMmGetMemoryMap (
         return STATUS_INVALID_PARAMETER;
     }
 
         return STATUS_INVALID_PARAMETER;
     }
 
+    /* Initialize the memory map list */
+    InitializeListHead(MemoryMap);
+
     /* Check which types of memory to dump */
     DoFirmware = WhichTypes & BL_MM_INCLUDE_FIRMWARE_MEMORY;
     DoPersistent = WhichTypes & BL_MM_INCLUDE_PERSISTENT_MEMORY;
     /* Check which types of memory to dump */
     DoFirmware = WhichTypes & BL_MM_INCLUDE_FIRMWARE_MEMORY;
     DoPersistent = WhichTypes & BL_MM_INCLUDE_PERSISTENT_MEMORY;