/** @file\r
*\r
-* Copyright (c) 2011, 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
+* Copyright (c) 2011-2015, ARM Limited. All rights reserved.\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
+* 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
-BdsLoadPeCoff (\r
- IN BDS_FILE *EfiAppFile\r
- )\r
+LocateEfiApplicationInFvByName (\r
+ IN CONST CHAR16* EfiAppName,\r
+ OUT EFI_DEVICE_PATH **DevicePath\r
+ )\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE ImageHandle;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH NewNode;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- // Only support loading from FV right now\r
- ASSERT(EfiAppFile->Type == BDS_FILETYPE_FV);\r
-\r
- // Generate the Device Path for the file\r
- DevicePath = DuplicateDevicePath(EfiAppFile->DevicePath);\r
- EfiInitializeFwVolDevicepathNode (&NewNode, &(EfiAppFile->File.Fv.Guid));\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);\r
-\r
- Status = gBS->LoadImage (TRUE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->StartImage (ImageHandle, NULL, NULL);\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
\r
-EFI_STATUS BdsLoadApplicationFromPath(\r
- IN CHAR16* EfiAppPath\r
-) {\r
- EFI_STATUS Status;\r
- BDS_FILE EfiAppFile;\r
-\r
- // Need to connect every drivers to ensure no dependencies are missing for the application\r
- Status = BdsConnectAllDrivers();\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
- return Status;\r
- }\r
+ *DevicePath = NULL;\r
\r
- // Locate the application from a device path\r
- Status = BdsLoadFilePath(EfiAppPath, &EfiAppFile);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "ERROR: Do not find EFI application %s\n",EfiAppPath));\r
- return Status;\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
- // Start the application\r
- Status = BdsLoadPeCoff(&EfiAppFile);\r
+ // Allocate Key\r
+ Key = AllocatePool (FvInstance->KeySize);\r
+ ASSERT (Key != NULL);\r
+ ZeroMem (Key, FvInstance->KeySize);\r
\r
- return Status;\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
-EFI_STATUS BdsLoadApplication(\r
- IN CHAR16* EfiApp\r
-) {\r
- EFI_STATUS Status;\r
- UINTN NoHandles, HandleIndex;\r
- EFI_HANDLE *Handles;\r
- BDS_FILE EfiAppFile;\r
-\r
- // Need to connect every drivers to ensure no dependencies are missing for the application\r
- Status = BdsConnectAllDrivers();\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
- return Status;\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
- // Search the application in any Firmware Volume\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);\r
- if (EFI_ERROR (Status) || (NoHandles == 0)) {\r
- DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));\r
- return Status;\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
- // Search in all Firmware Volume for the EFI Application\r
- for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {\r
- Status = BdsLoadFileFromFirmwareVolume(Handles[HandleIndex],EfiApp,EFI_FV_FILETYPE_APPLICATION,&EfiAppFile);\r
- if (!EFI_ERROR (Status)) {\r
- // Start the application\r
- Status = BdsLoadPeCoff(&EfiAppFile);\r
- return Status;\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
- return Status;\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