]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/BdsLib/BdsAppLoader.c
ArmPkg/BdsLib: Replaced BdsLoadApplication() by LocateEfiApplicationInFv()
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsAppLoader.c
index 4f359cda10b66708b1ac1c223e85a35a4b2d06f8..1f208f8dd796c3c3f01a842cf736258d5fa6cbdb 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"
-
-//#include <Library/DxeServicesLib.h>
-
-STATIC
-EFI_STATUS
-BdsLoadFileFromFirmwareVolume (
-  IN  EFI_HANDLE      FvHandle,
-  IN  CHAR16    *FilePath,
-  IN  EFI_FV_FILETYPE FileTypeFilter,
-  OUT EFI_DEVICE_PATH     **EfiAppDevicePath
-  )
-{
-  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
-  VOID                          *Key;
-  EFI_STATUS                    Status, FileStatus;
-  EFI_GUID                      NameGuid;
-  EFI_FV_FILETYPE               FileType;
-  EFI_FV_FILE_ATTRIBUTES        Attributes;
-  UINTN                         Size;
-  UINTN                         UiStringLen;
-  CHAR16                        *UiSection;
-  UINT32                        Authentication;
-  EFI_DEVICE_PATH               *FvDevicePath;
-  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;
-
-  Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
-  if (EFI_ERROR(Status)) {
-    return Status;
-  }
-
-  // Length of FilePath
-  UiStringLen = StrLen (FilePath);
-
-  // Allocate Key
-  Key = AllocatePool (FvProtocol->KeySize);
-  ASSERT (Key != NULL);
-  ZeroMem (Key, FvProtocol->KeySize);
-
-  do {
-    // Search in all files
-    FileType = FileTypeFilter;
-
-    Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
-    if (!EFI_ERROR (Status)) {
-      UiSection = NULL;
-      FileStatus = FvProtocol->ReadSection (
-                    FvProtocol,
-                    &NameGuid,
-                    EFI_SECTION_USER_INTERFACE,
-                    0,
-                    (VOID **)&UiSection,
-                    &Size,
-                    &Authentication
-                    );
-      if (!EFI_ERROR (FileStatus)) {
-        if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
-          //
-          // We found a UiString match.
-          //
-          Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
-
-          // Generate the Device Path for the file
-          //DevicePath = DuplicateDevicePath(FvDevicePath);
-          EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
-          *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
-
-          FreePool (Key);
-          FreePool (UiSection);
-          return FileStatus;
-        }
-        FreePool (UiSection);
-      }
-    }
-  } while (!EFI_ERROR (Status));
-
-  FreePool(Key);
-  return Status;
-}
-
-/**
-  Start an EFI Application from any Firmware Volume
-
-  @param  EfiApp                EFI Application Name
-
-  @retval EFI_SUCCESS           All drivers have been connected
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsLoadApplication (
-  IN EFI_HANDLE                  ParentImageHandle,
-  IN CHAR16*                     EfiApp,
-  IN UINTN                       LoadOptionsSize,
-  IN VOID*                       LoadOptions
-  )
-{
-  EFI_STATUS                      Status;
-  UINTN                           NoHandles, HandleIndex;
-  EFI_HANDLE                      *Handles;
-  EFI_DEVICE_PATH                 *EfiAppDevicePath;
-
-  // Need to connect every drivers to ensure no dependencies are missing for the application
-  Status = BdsConnectAllDrivers();
-  if (EFI_ERROR(Status)) {
-    DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
-    return Status;
-  }
-
-  // Search the application in any Firmware Volume
-  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
-  if (EFI_ERROR (Status) || (NoHandles == 0)) {
-    DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
-    return Status;
-  }
-
-  // Search in all Firmware Volume for the EFI Application
-  for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
-    EfiAppDevicePath = NULL;
-    Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
-    if (!EFI_ERROR (Status)) {
-      // Start the application
-      Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
-      return Status;
-    }
-  }
-
-  return Status;
-}
+/** @file\r
+*\r
+*  Copyright (c) 2011-2015, 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
+/**\r
+  Locate an EFI application in a the Firmware Volumes by its Name\r
+\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateEfiApplicationInFvByName (\r
+  IN  CONST CHAR16*             EfiAppName,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
+  )\r
+{\r
+  VOID                          *Key;\r
+  EFI_STATUS                    Status, FileStatus;\r
+  EFI_GUID                      NameGuid;\r
+  EFI_FV_FILETYPE               FileType;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  UINTN                         UiStringLen;\r
+  CHAR16                        *UiSection;\r
+  UINT32                        Authentication;\r
+  EFI_DEVICE_PATH               *FvDevicePath;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  // Length of FilePath\r
+  UiStringLen = StrLen (EfiAppName);\r
+\r
+  // Locate all the Firmware Volume protocols.\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *DevicePath = NULL;\r
+\r
+  // Looking for FV with ACPI storage file\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FREE_HANDLE_BUFFER;\r
+    }\r
+\r
+    // Allocate Key\r
+    Key = AllocatePool (FvInstance->KeySize);\r
+    ASSERT (Key != NULL);\r
+    ZeroMem (Key, FvInstance->KeySize);\r
+\r
+    do {\r
+      // Search in all files\r
+      FileType = EFI_FV_FILETYPE_ALL;\r
+\r
+      Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);\r
+      if (!EFI_ERROR (Status)) {\r
+        UiSection = NULL;\r
+        FileStatus = FvInstance->ReadSection (\r
+                      FvInstance,\r
+                      &NameGuid,\r
+                      EFI_SECTION_USER_INTERFACE,\r
+                      0,\r
+                      (VOID **)&UiSection,\r
+                      &Size,\r
+                      &Authentication\r
+                      );\r
+        if (!EFI_ERROR (FileStatus)) {\r
+          if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {\r
+            //\r
+            // We found a UiString match.\r
+            //\r
+            Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
+\r
+            // Generate the Device Path for the file\r
+            EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);\r
+            *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);\r
+            ASSERT (*DevicePath != NULL);\r
+\r
+            FreePool (Key);\r
+            FreePool (UiSection);\r
+            FreePool (HandleBuffer);\r
+            return FileStatus;\r
+          }\r
+          FreePool (UiSection);\r
+        }\r
+      }\r
+    } while (!EFI_ERROR (Status));\r
+\r
+    FreePool (Key);\r
+  }\r
+\r
+FREE_HANDLE_BUFFER:\r
+  FreePool (HandleBuffer);\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Locate an EFI application in a the Firmware Volumes by its GUID\r
+\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateEfiApplicationInFvByGuid (\r
+  IN  CONST EFI_GUID            *EfiAppGuid,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_DEVICE_PATH               *FvDevicePath;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINT32                        AuthenticationStatus;\r
+  EFI_FV_FILETYPE               Type;\r
+  UINTN                         Size;\r
+  CHAR16                        *UiSection;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  // Locate all the Firmware Volume protocols.\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *DevicePath = NULL;\r
+\r
+  // Looking for FV with ACPI storage file\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FREE_HANDLE_BUFFER;\r
+    }\r
+\r
+    Status = FvInstance->ReadFile (\r
+                  FvInstance,\r
+                  EfiAppGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  &Type,\r
+                  &Attributes,\r
+                  &AuthenticationStatus\r
+                  );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Skip if no EFI application file in the FV\r
+      //\r
+      continue;\r
+    } else {\r
+      UiSection = NULL;\r
+      Status = FvInstance->ReadSection (\r
+                    FvInstance,\r
+                    EfiAppGuid,\r
+                    EFI_SECTION_USER_INTERFACE,\r
+                    0,\r
+                    (VOID **)&UiSection,\r
+                    &Size,\r
+                    &AuthenticationStatus\r
+                    );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Create the EFI Device Path for the application using the Filename of the application\r
+        //\r
+        *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);\r
+      } else {\r
+        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        //\r
+        // Create the EFI Device Path for the application using the EFI GUID of the application\r
+        //\r
+        EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);\r
+\r
+        *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);\r
+        ASSERT (*DevicePath != NULL);\r
+      }\r
+      break;\r
+    }\r
+  }\r
+\r
+FREE_HANDLE_BUFFER:\r
+  //\r
+  // Free any allocated buffers\r
+  //\r
+  FreePool (HandleBuffer);\r
+\r
+  if (*DevicePath == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r