]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BdsHelper.c
ArmPlatformPkg/Bds: Make ".EFI" files recognizable as EFI applications
[mirror_edk2.git] / ArmPlatformPkg / Bds / BdsHelper.c
index 91b42341e60f258da2ac56cab6b20f6b20cdb736..5e1b9935cb30a17d23fb254c4c9d0ea67701fe37 100644 (file)
-/** @file
-*
-*  Copyright (c) 2011, ARM Limited. All rights reserved.
-*  
-*  This program and the accompanying materials                          
-*  are licensed and made available under the terms and conditions of the BSD License         
-*  which accompanies this distribution.  The full text of the license may be found at        
-*  http://opensource.org/licenses/bsd-license.php                                            
-*
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
-*
-**/
-
-#include "BdsInternal.h"
-
-EFI_STATUS
-GetEnvironmentVariable (
-  IN     CONST CHAR16*   VariableName,
-  IN     VOID*           DefaultValue,
-  IN OUT UINTN*          Size,
-  OUT    VOID**          Value
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       VariableSize;
-
-  // Try to get the variable size.
-  *Value = NULL;
-  VariableSize = 0;
-  Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
-  if (Status == EFI_NOT_FOUND) {
-    if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
-      // If the environment variable does not exist yet then set it with the default value
-      Status = gRT->SetVariable (
-                    (CHAR16*)VariableName,
-                    &gEfiGlobalVariableGuid,
-                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
-                    *Size,
-                    DefaultValue
-                    );
-      *Value = DefaultValue;
-    } else {
-      return EFI_NOT_FOUND;
-    }
-  } else if (Status == EFI_BUFFER_TOO_SMALL) {
-    // Get the environment variable value
-    *Value = AllocatePool (VariableSize);
-    if (*Value == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-
-    Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
-    if (EFI_ERROR (Status)) {
-      FreePool(*Value);
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (Size) {
-      *Size = VariableSize;
-    }
-  } else {
-    *Value = DefaultValue;
-    return Status;
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EditHIInputStr (
-  IN OUT CHAR16  *CmdLine,
-  IN     UINTN   MaxCmdLine
-  )
-{
-  UINTN           CmdLineIndex;
-  UINTN           WaitIndex;
-  CHAR8           Char;
-  EFI_INPUT_KEY   Key;
-  EFI_STATUS      Status;
-
-  Print (CmdLine);
-
-  for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {
-    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
-    ASSERT_EFI_ERROR (Status);
-
-    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-    ASSERT_EFI_ERROR (Status);
-
-    // Unicode character is valid when Scancode is NUll
-    if (Key.ScanCode == SCAN_NULL) {
-      // Scan code is NUll, hence read Unicode character
-      Char = (CHAR8)Key.UnicodeChar;
-    } else {
-      Char = CHAR_NULL;
-    }
-
-    if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {
-      CmdLine[CmdLineIndex] = '\0';
-      Print (L"\n\r");
-
-      return EFI_SUCCESS;
-    } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
-      if (CmdLineIndex != 0) {
-        CmdLineIndex--;
-        Print (L"\b \b");
-      }
-    } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {
-      return EFI_INVALID_PARAMETER;
-    } else {
-      CmdLine[CmdLineIndex++] = Key.UnicodeChar;
-      Print (L"%c", Key.UnicodeChar);
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-GetHIInputStr (
-  IN OUT CHAR16  *CmdLine,
-  IN     UINTN   MaxCmdLine
-  )
-{
-  EFI_STATUS  Status;
-
-  // For a new input just passed an empty string
-  CmdLine[0] = L'\0';
-
-  Status = EditHIInputStr (CmdLine, MaxCmdLine);
-
-  return Status;
-}
-
-EFI_STATUS
-EditHIInputAscii (
-  IN OUT CHAR8   *CmdLine,
-  IN     UINTN   MaxCmdLine
-  )
-{
-  CHAR16*     Str;
-  EFI_STATUS  Status;
-
-  Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));
-  AsciiStrToUnicodeStr (CmdLine, Str);
-
-  Status = EditHIInputStr (Str, MaxCmdLine);
-
-  if (!EFI_ERROR(Status)) {
-    UnicodeStrToAsciiStr (Str, CmdLine);
-  }
-  FreePool (Str);
-
-  return Status;
-}
-
-EFI_STATUS
-GetHIInputAscii (
-  IN OUT CHAR8   *CmdLine,
-  IN     UINTN   MaxCmdLine
-  )
-{
-  // For a new input just passed an empty string
-  CmdLine[0] = '\0';
-
-  return EditHIInputAscii (CmdLine,MaxCmdLine);
-}
-
-EFI_STATUS
-GetHIInputInteger (
-  OUT UINTN   *Integer
-  )
-{
-  CHAR16      CmdLine[255];
-  EFI_STATUS  Status;
-
-  CmdLine[0] = '\0';
-  Status = EditHIInputStr (CmdLine, 255);
-  if (!EFI_ERROR(Status)) {
-    *Integer = StrDecimalToUintn (CmdLine);
-  }
-
-  return Status;
-}
-
-EFI_STATUS
-GetHIInputIP (
-  OUT EFI_IP_ADDRESS   *Ip
-  )
-{
-  CHAR16  CmdLine[255];
-  CHAR16  *Str;
-  EFI_STATUS  Status;
-
-  CmdLine[0] = '\0';
-  Status = EditHIInputStr (CmdLine,255);
-  if (!EFI_ERROR(Status)) {
-    Str = CmdLine;
-    Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);
-
-    Str = StrStr (Str, L".");
-    if (Str == NULL) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);
-
-    Str = StrStr (Str, L".");
-    if (Str == NULL) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);
-
-    Str = StrStr (Str, L".");
-    if (Str == NULL) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);
-  }
-
-  return Status;
-}
-
-EFI_STATUS
-GetHIInputBoolean (
-  OUT BOOLEAN *Value
-  )
-{
-  CHAR16      CmdBoolean[2];
-  EFI_STATUS  Status;
-
-  while(1) {
-    Print (L"[y/n] ");
-    Status = GetHIInputStr (CmdBoolean,2);
-    if (EFI_ERROR(Status)) {
-      return Status;
-    } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {
-      if (Value) *Value = TRUE;
-      return EFI_SUCCESS;
-    } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {
-      if (Value) *Value = FALSE;
-      return EFI_SUCCESS;
-    }
-  }
-}
-
-BOOLEAN
-HasFilePathEfiExtension (
-  IN CHAR16* FilePath
-  )
-{
-  return (StrCmp (FilePath + (StrSize(FilePath)/sizeof(CHAR16)) - 5, L".efi") == 0);
-}
-
-// Return the last non end-type Device Path Node from a Device Path
-EFI_DEVICE_PATH*
-GetLastDevicePathNode (
-  IN EFI_DEVICE_PATH*  DevicePath
-  )
-{
-  EFI_DEVICE_PATH*     PrevDevicePathNode;
-
-  PrevDevicePathNode = DevicePath;
-  while (!IsDevicePathEndType (DevicePath)) {
-    PrevDevicePathNode = DevicePath;
-    DevicePath = NextDevicePathNode (DevicePath);
-  }
-
-  return PrevDevicePathNode;
-}
-
-EFI_STATUS
-GenerateDeviceDescriptionName (
-  IN  EFI_HANDLE  Handle,
-  IN OUT CHAR16*  Description
-  )
-{
-  EFI_STATUS                        Status;
-  EFI_COMPONENT_NAME_PROTOCOL*      ComponentName2Protocol;
-  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
-  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;
-  CHAR16*                           DriverName;
-  CHAR16*                           DevicePathTxt;
-  EFI_DEVICE_PATH*                  DevicePathNode;
-
-  ComponentName2Protocol = NULL;
-  Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);
-  if (!EFI_ERROR(Status)) {
-    //TODO: Fixme. we must find the best langague
-    Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);
-    if (!EFI_ERROR(Status)) {
-      StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX);
-    }
-  }
-
-  if (EFI_ERROR(Status)) {
-    // Use the lastest non null entry of the Device path as a description
-    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
-    if (EFI_ERROR(Status)) {
-      return Status;
-    }
-
-    // Convert the last non end-type Device Path Node in text for the description
-    DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);
-    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
-    ASSERT_EFI_ERROR(Status);
-    DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE);
-    StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);
-    FreePool (DevicePathTxt);
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-BdsStartBootOption (
-  IN CHAR16* BootOption
-  )
-{
-  EFI_STATUS          Status;
-  EFI_LOAD_OPTION     EfiLoadOption;
-  UINTN               EfiLoadOptionSize;
-  BDS_LOAD_OPTION     *BdsLoadOption;
-
-  Status = GetEnvironmentVariable (BootOption, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);
-  if (!EFI_ERROR(Status)) {
-    Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, &BdsLoadOption);
-    if (!EFI_ERROR(Status)) {
-      Status = BootOptionStart (BdsLoadOption);
-      FreePool (BdsLoadOption);
-    }
-
-    if (!EFI_ERROR(Status)) {
-      Status = EFI_SUCCESS;
-    } else {
-      Status = EFI_NOT_STARTED;
-    }
-  } else {
-    Status = EFI_NOT_FOUND;
-  }
-  return Status;
-}
-
-UINTN
-GetUnalignedDevicePathSize (
-  IN EFI_DEVICE_PATH* DevicePath
-  )
-{
-  UINTN Size;
-  EFI_DEVICE_PATH* AlignedDevicePath;
-
-  if ((UINTN)DevicePath & 0x1) {
-    AlignedDevicePath = DuplicateDevicePath (DevicePath);
-    Size = GetDevicePathSize (AlignedDevicePath);
-    FreePool (AlignedDevicePath);
-  } else {
-    Size = GetDevicePathSize (DevicePath);
-  }
-  return Size;
-}
-
-EFI_DEVICE_PATH*
-GetAlignedDevicePath (
-  IN EFI_DEVICE_PATH* DevicePath
-  )
-{
-  if ((UINTN)DevicePath & 0x1) {
-    return DuplicateDevicePath (DevicePath);
-  } else {
-    return DevicePath;
-  }
-}
-
+/** @file\r
+*\r
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include "BdsInternal.h"\r
+\r
+EFI_STATUS\r
+EditHIInputStr (\r
+  IN OUT CHAR16  *CmdLine,\r
+  IN     UINTN   MaxCmdLine\r
+  )\r
+{\r
+  UINTN           CmdLineIndex;\r
+  UINTN           WaitIndex;\r
+  CHAR8           Char;\r
+  EFI_INPUT_KEY   Key;\r
+  EFI_STATUS      Status;\r
+\r
+  // The command line must be at least one character long\r
+  ASSERT (MaxCmdLine > 0);\r
+\r
+  // Ensure the last character of the buffer is the NULL character\r
+  CmdLine[MaxCmdLine - 1] = '\0';\r
+\r
+  Print (CmdLine);\r
+\r
+  // To prevent a buffer overflow, we only allow to enter (MaxCmdLine-1) characters\r
+  for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine - 1; ) {\r
+    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    // Unicode character is valid when Scancode is NUll\r
+    if (Key.ScanCode == SCAN_NULL) {\r
+      // Scan code is NUll, hence read Unicode character\r
+      Char = (CHAR8)Key.UnicodeChar;\r
+    } else {\r
+      Char = CHAR_NULL;\r
+    }\r
+\r
+    if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {\r
+      CmdLine[CmdLineIndex] = '\0';\r
+      Print (L"\n\r");\r
+\r
+      return EFI_SUCCESS;\r
+    } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){\r
+      if (CmdLineIndex != 0) {\r
+        CmdLineIndex--;\r
+        Print (L"\b \b");\r
+      }\r
+    } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    } else {\r
+      CmdLine[CmdLineIndex++] = Key.UnicodeChar;\r
+      Print (L"%c", Key.UnicodeChar);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetHIInputStr (\r
+  IN OUT CHAR16  *CmdLine,\r
+  IN     UINTN   MaxCmdLine\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  // For a new input just passed an empty string\r
+  CmdLine[0] = L'\0';\r
+\r
+  Status = EditHIInputStr (CmdLine, MaxCmdLine);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EditHIInputAscii (\r
+  IN OUT CHAR8   *CmdLine,\r
+  IN     UINTN   MaxCmdLine\r
+  )\r
+{\r
+  CHAR16*     Str;\r
+  EFI_STATUS  Status;\r
+\r
+  Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));\r
+  AsciiStrToUnicodeStr (CmdLine, Str);\r
+\r
+  Status = EditHIInputStr (Str, MaxCmdLine);\r
+  if (!EFI_ERROR(Status)) {\r
+    UnicodeStrToAsciiStr (Str, CmdLine);\r
+  }\r
+  FreePool (Str);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+GetHIInputAscii (\r
+  IN OUT CHAR8   *CmdLine,\r
+  IN     UINTN   MaxCmdLine\r
+  )\r
+{\r
+  // For a new input just passed an empty string\r
+  CmdLine[0] = '\0';\r
+\r
+  return EditHIInputAscii (CmdLine,MaxCmdLine);\r
+}\r
+\r
+EFI_STATUS\r
+GetHIInputInteger (\r
+  OUT UINTN   *Integer\r
+  )\r
+{\r
+  CHAR16      CmdLine[255];\r
+  EFI_STATUS  Status;\r
+\r
+  CmdLine[0] = '\0';\r
+  Status = EditHIInputStr (CmdLine, 255);\r
+  if (!EFI_ERROR(Status)) {\r
+    *Integer = StrDecimalToUintn (CmdLine);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+GetHIInputIP (\r
+  OUT EFI_IP_ADDRESS   *Ip\r
+  )\r
+{\r
+  CHAR16  CmdLine[255];\r
+  CHAR16  *Str;\r
+  EFI_STATUS  Status;\r
+\r
+  CmdLine[0] = '\0';\r
+  Status = EditHIInputStr (CmdLine,255);\r
+  if (!EFI_ERROR(Status)) {\r
+    Str = CmdLine;\r
+    Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);\r
+\r
+    Str = StrStr (Str, L".");\r
+    if (Str == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);\r
+\r
+    Str = StrStr (Str, L".");\r
+    if (Str == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);\r
+\r
+    Str = StrStr (Str, L".");\r
+    if (Str == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+GetHIInputBoolean (\r
+  OUT BOOLEAN *Value\r
+  )\r
+{\r
+  CHAR16      CmdBoolean[2];\r
+  EFI_STATUS  Status;\r
+\r
+  while(1) {\r
+    Print (L"[y/n] ");\r
+    Status = GetHIInputStr (CmdBoolean, 2);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {\r
+      if (Value) *Value = TRUE;\r
+      return EFI_SUCCESS;\r
+    } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {\r
+      if (Value) *Value = FALSE;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+}\r
+\r
+BOOLEAN\r
+HasFilePathEfiExtension (\r
+  IN CHAR16* FilePath\r
+  )\r
+{\r
+  return (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".EFI") == 0) ||\r
+         (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".efi") == 0);\r
+}\r
+\r
+// Return the last non end-type Device Path Node from a Device Path\r
+EFI_DEVICE_PATH*\r
+GetLastDevicePathNode (\r
+  IN EFI_DEVICE_PATH*  DevicePath\r
+  )\r
+{\r
+  EFI_DEVICE_PATH*     PrevDevicePathNode;\r
+\r
+  PrevDevicePathNode = DevicePath;\r
+  while (!IsDevicePathEndType (DevicePath)) {\r
+    PrevDevicePathNode = DevicePath;\r
+    DevicePath = NextDevicePathNode (DevicePath);\r
+  }\r
+\r
+  return PrevDevicePathNode;\r
+}\r
+\r
+EFI_STATUS\r
+GenerateDeviceDescriptionName (\r
+  IN  EFI_HANDLE  Handle,\r
+  IN OUT CHAR16*  Description\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_COMPONENT_NAME_PROTOCOL*      ComponentName2Protocol;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;\r
+  CHAR16*                           DriverName;\r
+  CHAR16*                           DevicePathTxt;\r
+  EFI_DEVICE_PATH*                  DevicePathNode;\r
+\r
+  ComponentName2Protocol = NULL;\r
+  Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);\r
+  if (!EFI_ERROR(Status)) {\r
+    //TODO: Fixme. we must find the best langague\r
+    Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);\r
+    if (!EFI_ERROR(Status)) {\r
+      StrnCpy (Description, DriverName, BOOT_DEVICE_DESCRIPTION_MAX);\r
+    }\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    // Use the lastest non null entry of the Device path as a description\r
+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+\r
+    // Convert the last non end-type Device Path Node in text for the description\r
+    DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);\r
+    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
+    ASSERT_EFI_ERROR(Status);\r
+    DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePathNode, TRUE, TRUE);\r
+    StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);\r
+    FreePool (DevicePathTxt);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+BdsStartBootOption (\r
+  IN CHAR16* BootOption\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  BDS_LOAD_OPTION     *BdsLoadOption;\r
+\r
+  Status = BootOptionFromLoadOptionVariable (BootOption, &BdsLoadOption);\r
+  if (!EFI_ERROR(Status)) {\r
+    Status = BootOptionStart (BdsLoadOption);\r
+    FreePool (BdsLoadOption);\r
+\r
+    if (!EFI_ERROR(Status)) {\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      Status = EFI_NOT_STARTED;\r
+    }\r
+  } else {\r
+    Status = EFI_NOT_FOUND;\r
+  }\r
+  return Status;\r
+}\r
+\r
+UINTN\r
+GetUnalignedDevicePathSize (\r
+  IN EFI_DEVICE_PATH* DevicePath\r
+  )\r
+{\r
+  UINTN Size;\r
+  EFI_DEVICE_PATH* AlignedDevicePath;\r
+\r
+  if ((UINTN)DevicePath & 0x1) {\r
+    AlignedDevicePath = DuplicateDevicePath (DevicePath);\r
+    Size = GetDevicePathSize (AlignedDevicePath);\r
+    FreePool (AlignedDevicePath);\r
+  } else {\r
+    Size = GetDevicePathSize (DevicePath);\r
+  }\r
+  return Size;\r
+}\r
+\r
+EFI_DEVICE_PATH*\r
+GetAlignedDevicePath (\r
+  IN EFI_DEVICE_PATH* DevicePath\r
+  )\r
+{\r
+  if ((UINTN)DevicePath & 0x1) {\r
+    return DuplicateDevicePath (DevicePath);\r
+  } else {\r
+    return DevicePath;\r
+  }\r
+}\r
+\r