- Implement BmpFwGetApplicationDirectoryPath and most of BmFwInitializeBootDirectoryPath.
authorAlex Ionescu <aionescu@gmail.com>
Wed, 9 Sep 2015 18:09:04 +0000 (18:09 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Wed, 9 Sep 2015 18:09:04 +0000 (18:09 +0000)
- Implement boolean, integer, and string BCD reading.
- Fix a more bugs.
- We are now ready to open the BCD hive!

svn path=/trunk/; revision=69155

reactos/boot/environ/app/bootmgr/bootmgr.c
reactos/boot/environ/app/bootmgr/bootmgr.h
reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/bootlib.c
reactos/boot/environ/lib/misc/bcd.c

index 7afd6f2..ab84d03 100644 (file)
@@ -12,7 +12,6 @@
 
 /* DATA VARIABLES ************************************************************/
 
-#include <initguid.h>
 DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
             0x9DEA862C,
             0x5CDD,
@@ -26,6 +25,103 @@ PWCHAR BootDirectory;
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS
+BmpFwGetApplicationDirectoryPath (
+    _In_ PUNICODE_STRING ApplicationDirectoryPath
+    )
+{
+    NTSTATUS Status;
+    ULONG i, AppPathLength;
+    PWCHAR ApplicationPath, PathCopy;
+
+    /* Clear the incoming string */
+    ApplicationDirectoryPath->Length = 0;
+    ApplicationDirectoryPath->MaximumLength = 0;
+    ApplicationDirectoryPath->Buffer = 0;
+
+    /* Get the boot application path */
+    ApplicationPath = NULL;
+    Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
+                                   BcdLibraryString_ApplicationPath,
+                                   &ApplicationPath);
+    if (NT_SUCCESS(Status))
+    {
+        /* Calculate the length of the application path */
+        for (i = wcslen(ApplicationPath) - 1; i > 0; i--)
+        {
+            /* Keep going until the path separator */
+            if (ApplicationPath[i] == OBJ_NAME_PATH_SEPARATOR)
+            {
+                break;
+            }
+        }
+
+        /* Check if we have space for one more character */
+        AppPathLength = i + 1;
+        if (AppPathLength < i)
+        {
+            /* Nope, we'll overflow */
+            AppPathLength = -1;
+            Status = STATUS_INTEGER_OVERFLOW;
+        }
+        else
+        {
+            /* Go ahead */
+            Status = STATUS_SUCCESS;
+        }
+
+        /* No overflow? */
+        if (NT_SUCCESS(Status))
+        {
+            /* Check if it's safe to multiply by two */
+            if ((AppPathLength * sizeof(WCHAR)) > 0xFFFFFFFF)
+            {
+                /* Nope */
+                AppPathLength = -1;
+                Status = STATUS_INTEGER_OVERFLOW;
+            }
+            else
+            {
+                /* We're good, do the multiplication */
+                Status = STATUS_SUCCESS;
+                AppPathLength *= sizeof(WCHAR);
+            }
+
+            /* Allocate a copy for the string */
+            if (NT_SUCCESS(Status))
+            {
+                PathCopy = BlMmAllocateHeap(AppPathLength);
+                if (PathCopy)
+                {
+                    /* NULL-terminate it */
+                    RtlCopyMemory(PathCopy,
+                                  ApplicationPath,
+                                  AppPathLength - sizeof(UNICODE_NULL));
+                    PathCopy[AppPathLength] = UNICODE_NULL;
+
+                    /* Finally, initialize the outoing string */
+                    RtlInitUnicodeString(ApplicationDirectoryPath, PathCopy);
+                }
+                else
+                {
+                    /* No memory, fail */
+                    Status = STATUS_NO_MEMORY;
+                }
+            }
+        }
+    }
+
+    /* Check if we had an application path */
+    if (ApplicationPath)
+    {
+        /* No longer need this, free it */
+        BlMmFreeHeap(ApplicationPath);
+    }
+
+    /* All done! */
+    return Status;
+
+}
 NTSTATUS
 BmFwInitializeBootDirectoryPath (
     VOID
@@ -34,13 +130,13 @@ BmFwInitializeBootDirectoryPath (
     PWCHAR FinalPath;
     NTSTATUS Status;
     PWCHAR BcdDirectory;
-   // UNICODE_STRING BcdPath;
-    //ULONG FinalSize;
+    UNICODE_STRING BcdPath;
+    ULONG FinalSize;
     ULONG FileHandle, DeviceHandle;
 
     /* Initialize everything for failure */
-   // BcdPath.MaximumLength = 0;
-   // BcdPath.Buffer = NULL;
+    BcdPath.MaximumLength = 0;
+    BcdPath.Buffer = NULL;
     BcdDirectory = NULL;
     FinalPath = NULL;
     FileHandle = -1;
@@ -51,39 +147,40 @@ BmFwInitializeBootDirectoryPath (
     if (!NT_SUCCESS(Status))
     {
         EfiPrintf(L"Device open failed: %lx\r\n", Status);
-        EfiStall(2000000);
         goto Quickie;
     }
 
-    /* For now, do nothing */
-    EfiPrintf(L"Successfully opened boot device: %lx\r\n", DeviceHandle);
-    EfiStall(2000000);
-
-#if 0
+    /* Get the directory path */
     Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
     BcdDirectory = BcdPath.Buffer;
     if (!NT_SUCCESS(Status))
     {
+        EfiPrintf(L"path failed: %lx\n", Status);
         goto Quickie;
     }
 
+    /* Add the BCD file name to it */
     FinalSize = BcdPath.MaximumLength + sizeof(L"\\BCD") - sizeof(UNICODE_NULL);
     if (FinalSize < BcdPath.MaximumLength)
     {
         goto Quickie;
     }
 
+    /* Allocate space for the final path */
     FinalPath = BlMmAllocateHeap(FinalSize);
     if (!FinalPath)
     {
         goto Quickie;
     }
 
+    /* Build it */
     RtlZeroMemory(FinalPath, FinalSize);
     RtlCopyMemory(FinalPath, BcdDirectory, BcdPath.MaximumLength);
     wcsncat(FinalPath, L"\\BCD", FinalSize / sizeof(WCHAR));
 
+    /* Try to open the file */
     EfiPrintf(L"Opening: %s\r\n", FinalPath);
+#if 0
     Status = BlFileOpen(DeviceHandle, FinalPath, 1u, &FileHandle);
     if (!NT_SUCCESS(Status))
     {
index 13d5bcd..de39b77 100644 (file)
@@ -17,6 +17,7 @@
 #include <wchar.h>
 
 /* NT Base Headers */
+#include <initguid.h>
 #include <ntifs.h>
 
 /* UEFI Headers */
@@ -25,6 +26,9 @@
 /* Boot Library Headers */
 #include <bl.h>
 
+/* BCD Headers */
+#include <bcd.h>
+
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS
index 093867a..2bf8a18 100644 (file)
@@ -506,6 +506,13 @@ typedef struct _BL_APPLICATION_ENTRY
     BL_BCD_OPTION BcdData;
 } BL_APPLICATION_ENTRY, *PBL_APPLICATION_ENTRY;
 
+typedef struct _BL_LOADED_APPLICATION_ENTRY
+{
+    ULONG Flags;
+    GUID Guid;
+    PBL_BCD_OPTION BcdData;
+} BL_LOADED_APPLICATION_ENTRY, *PBL_LOADED_APPLICATION_ENTRY;
+
 typedef struct _BL_HARDDISK_DEVICE
 {
     ULONG PartitionType;
@@ -1123,6 +1130,27 @@ BlGetBootOptionSize (
     _In_ PBL_BCD_OPTION BcdOption
     );
 
+NTSTATUS
+BlGetBootOptionString (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PWCHAR* Value
+    );
+
+NTSTATUS
+BlGetBootOptionInteger (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PULONGLONG Value
+    );
+
+NTSTATUS
+BlGetBootOptionBoolean (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PBOOLEAN Value
+    );
+
 /* CONTEXT ROUTINES **********************************************************/
 
 VOID
@@ -1412,7 +1440,7 @@ extern BL_LIBRARY_PARAMETERS BlpLibraryParameters;
 extern BL_TRANSLATION_TYPE  MmTranslationType;
 extern PBL_ARCH_CONTEXT CurrentExecutionContext;
 extern PBL_DEVICE_DESCRIPTOR BlpBootDevice;
-extern BL_APPLICATION_ENTRY BlpApplicationEntry;
+extern BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry;
 extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
 extern EFI_GUID EfiGraphicsOutputProtocol;
 extern EFI_GUID EfiUgaDrawProtocol;
index fbbb946..43ef213 100644 (file)
@@ -16,7 +16,7 @@ BL_LIBRARY_PARAMETERS BlpLibraryParameters;
 PBL_DEVICE_DESCRIPTOR BlpBootDevice;
 PWCHAR BlpApplicationBaseDirectory;
 PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters;
-BL_APPLICATION_ENTRY BlpApplicationEntry;
+BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry;
 BOOLEAN BlpLibraryParametersInitialized;
 
 ULONG PdPersistAllocations;
@@ -86,12 +86,16 @@ InitializeLibrary (
     BlpApplicationParameters = BootAppParameters;
     BlpLibraryParameters = *LibraryParameters;
 
-    /* Save the application entry */
+    /* Save the application entry flags */
     if (AppEntry->Flags & 2)
     {
         AppEntry->Flags = (AppEntry->Flags & ~0x2) | 0x80;
     }
-    BlpApplicationEntry = *AppEntry;
+    BlpApplicationEntry.Flags = AppEntry->Flags;
+
+    /* Copy the GUID and point to the options */
+    BlpApplicationEntry.Guid = AppEntry->Guid;
+    BlpApplicationEntry.BcdData = &AppEntry->BcdData;
 
     /* Everything has been captured */
     BlpLibraryParametersInitialized = TRUE;
index 903f1f1..58eed43 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+PBL_BCD_OPTION
+MiscGetBootOption (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type
+    )
+{
+    ULONG_PTR NextOption = 0, ListOption;
+    PBL_BCD_OPTION Option;
+
+    /* No options, bail out */
+    if (!List)
+    {
+        return NULL;
+    }
+
+    /* Loop while we find an option */
+    while (TRUE)
+    {
+        /* Get the next option and see if it matches the type */
+        Option = (PBL_BCD_OPTION)((ULONG_PTR)List + NextOption);
+        if ((Option->Type == Type) && !(Option->Empty))
+        {
+            break;
+        }
+
+        /* Store the offset of the next option */
+        NextOption = Option->NextEntryOffset;
+
+        /* Failed to match. Check for list options */
+        ListOption = Option->ListOffset;
+        if (ListOption)
+        {
+            /* Try to get a match in the associated option */
+            Option = MiscGetBootOption((PBL_BCD_OPTION)((ULONG_PTR)Option +
+                                       ListOption),
+                                       Type);
+
+            /* Found one, return it */
+            if (Option)
+            {
+                return Option;
+            }
+        }
+    }
+
+    /* We found the option, return it */
+    return Option;
+}
+
+NTSTATUS
+BlGetBootOptionString (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PWCHAR* Value
+    )
+{
+    NTSTATUS Status;
+    PBL_BCD_OPTION Option;
+    PWCHAR String, StringCopy;
+    ULONG StringLength, CopyLength;
+    //PGUID AppIdentifier;
+
+    /* Make sure this is a BCD_STRING */
+    if ((Type & 0xF000000) != 0x2000000)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return the data */
+    Option = MiscGetBootOption(List, Type);
+    if (Option)
+    {
+        /* Extract the string */
+        String = (PWCHAR)((ULONG_PTR)Option + Option->DataOffset);
+    }
+    else
+    {
+        /* No string is present */
+        String = NULL;
+    }
+
+    /* Compute the data size */
+    StringLength = Option->DataSize / sizeof(WCHAR);
+
+#ifdef _SECURE_BOOT_
+    /* Filter out SecureBoot Options */
+    AppIdentifier = BlGetApplicationIdentifier();
+    Status = BlpBootOptionCallbackString(AppIdentifier, Type, String, StringLength, &String, &StringLength);
+#else
+    Status = STATUS_SUCCESS;
+#endif
+
+    /* Check if we have space for one more character */
+    CopyLength = StringLength + 1;
+    if (CopyLength < StringLength)
+    {
+        /* Nope, we'll overflow */
+        CopyLength = -1;
+        Status = STATUS_INTEGER_OVERFLOW;
+    }
+    else
+    {
+        /* Go ahead */
+        Status = STATUS_SUCCESS;
+    }
+
+    /* No overflow? */
+    if (NT_SUCCESS(Status))
+    {
+        /* Check if it's safe to multiply by two */
+        if ((CopyLength * sizeof(WCHAR)) > 0xFFFFFFFF)
+        {
+            /* Nope */
+            CopyLength = -1;
+            Status = STATUS_INTEGER_OVERFLOW;
+        }
+        else
+        {
+            /* We're good, do the multiplication */
+            Status = STATUS_SUCCESS;
+            CopyLength *= sizeof(WCHAR);
+        }
+
+        /* Allocate a copy for the string */
+        if (NT_SUCCESS(Status))
+        {
+            StringCopy = BlMmAllocateHeap(CopyLength);
+            if (StringCopy)
+            {
+                /* NULL-terminate it */
+                RtlCopyMemory(StringCopy,
+                              String,
+                              CopyLength - sizeof(UNICODE_NULL));
+                StringCopy[CopyLength] = UNICODE_NULL;
+                *Value = StringCopy;
+                Status = STATUS_SUCCESS;
+            }
+            else
+            {
+                /* No memory, fail */
+                Status = STATUS_NO_MEMORY;
+            }
+        }
+    }
+
+    /* All done */
+    return Status;
+}
+
+NTSTATUS
+BlGetBootOptionInteger (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PULONGLONG Value
+    )
+{
+    NTSTATUS Status;
+    PBL_BCD_OPTION Option;
+    //PGUID AppIdentifier;
+
+    /* Make sure this is a BCD_INTEGER */
+    if ((Type & 0xF000000) != 0x5000000)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return the data */
+    Option = MiscGetBootOption(List, Type);
+    if (Option)
+    {
+        *Value = *(PULONGLONG)((ULONG_PTR)Option + Option->DataOffset);
+    }
+
+#ifdef _SECURE_BOOT_
+    /* Filter out SecureBoot Options */
+    AppIdentifier = BlGetApplicationIdentifier();
+    Status = BlpBootOptionCallbackULongLong(AppIdentifier, Type, Value);
+#else
+    /* Option found */
+    Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND;
+#endif
+    return Status;
+}
+
+NTSTATUS
+BlGetBootOptionBoolean (
+    _In_ PBL_BCD_OPTION List,
+    _In_ ULONG Type,
+    _Out_ PBOOLEAN Value
+    )
+{
+    NTSTATUS Status;
+    PBL_BCD_OPTION Option;
+    //PGUID AppIdentifier;
+
+    /* Make sure this is a BCD_BOOLEAN */
+    if ((Type & 0xF000000) != 0x6000000)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return the data */
+    Option = MiscGetBootOption(List, Type);
+    if (Option)
+    {
+        *Value = *(PBOOLEAN)((ULONG_PTR)Option + Option->DataOffset);
+    }
+
+#ifdef _SECURE_BOOT_
+    /* Filter out SecureBoot Options */
+    AppIdentifier = BlGetApplicationIdentifier();
+    Status = BlpBootOptionCallbackBoolean(AppIdentifier, Type, Value);
+#else
+    /* Option found */
+    Status = Option ? STATUS_SUCCESS : STATUS_NOT_FOUND;
+#endif
+    return Status;
+}
+
 /*++
  * @name BlGetBootOptionListSize
  *