3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsInternal.h"
18 Locate an EFI application in a the Firmware Volumes by its Name
20 @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
21 @param DevicePath EFI Device Path of the EFI application
23 @return EFI_SUCCESS The function completed successfully.
24 @return EFI_NOT_FOUND The protocol could not be located.
25 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
29 LocateEfiApplicationInFvByName (
30 IN CONST CHAR16
* EfiAppName
,
31 OUT EFI_DEVICE_PATH
**DevicePath
35 EFI_STATUS Status
, FileStatus
;
37 EFI_FV_FILETYPE FileType
;
38 EFI_FV_FILE_ATTRIBUTES Attributes
;
42 UINT32 Authentication
;
43 EFI_DEVICE_PATH
*FvDevicePath
;
44 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath
;
45 EFI_HANDLE
*HandleBuffer
;
46 UINTN NumberOfHandles
;
48 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FvInstance
;
50 ASSERT (DevicePath
!= NULL
);
53 UiStringLen
= StrLen (EfiAppName
);
55 // Locate all the Firmware Volume protocols.
56 Status
= gBS
->LocateHandleBuffer (
58 &gEfiFirmwareVolume2ProtocolGuid
,
63 if (EFI_ERROR (Status
)) {
69 // Looking for FV with ACPI storage file
70 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
72 // Get the protocol on this handle
73 // This should not fail because of LocateHandleBuffer
75 Status
= gBS
->HandleProtocol (
77 &gEfiFirmwareVolume2ProtocolGuid
,
80 if (EFI_ERROR (Status
)) {
81 goto FREE_HANDLE_BUFFER
;
85 Key
= AllocatePool (FvInstance
->KeySize
);
87 ZeroMem (Key
, FvInstance
->KeySize
);
90 // Search in all files
91 FileType
= EFI_FV_FILETYPE_ALL
;
93 Status
= FvInstance
->GetNextFile (FvInstance
, Key
, &FileType
, &NameGuid
, &Attributes
, &Size
);
94 if (!EFI_ERROR (Status
)) {
96 FileStatus
= FvInstance
->ReadSection (
99 EFI_SECTION_USER_INTERFACE
,
105 if (!EFI_ERROR (FileStatus
)) {
106 if (StrnCmp (EfiAppName
, UiSection
, UiStringLen
) == 0) {
108 // We found a UiString match.
110 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&FvDevicePath
);
112 // Generate the Device Path for the file
113 EfiInitializeFwVolDevicepathNode (&FileDevicePath
, &NameGuid
);
114 *DevicePath
= AppendDevicePathNode (FvDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&FileDevicePath
);
115 ASSERT (*DevicePath
!= NULL
);
118 FreePool (UiSection
);
119 FreePool (HandleBuffer
);
122 FreePool (UiSection
);
125 } while (!EFI_ERROR (Status
));
131 FreePool (HandleBuffer
);
132 return EFI_NOT_FOUND
;
136 Locate an EFI application in a the Firmware Volumes by its GUID
138 @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
139 @param DevicePath EFI Device Path of the EFI application
141 @return EFI_SUCCESS The function completed successfully.
142 @return EFI_NOT_FOUND The protocol could not be located.
143 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
147 LocateEfiApplicationInFvByGuid (
148 IN CONST EFI_GUID
*EfiAppGuid
,
149 OUT EFI_DEVICE_PATH
**DevicePath
153 EFI_DEVICE_PATH
*FvDevicePath
;
154 EFI_HANDLE
*HandleBuffer
;
155 UINTN NumberOfHandles
;
157 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FvInstance
;
158 EFI_FV_FILE_ATTRIBUTES Attributes
;
159 UINT32 AuthenticationStatus
;
160 EFI_FV_FILETYPE Type
;
163 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath
;
165 ASSERT (DevicePath
!= NULL
);
167 // Locate all the Firmware Volume protocols.
168 Status
= gBS
->LocateHandleBuffer (
170 &gEfiFirmwareVolume2ProtocolGuid
,
175 if (EFI_ERROR (Status
)) {
181 // Looking for FV with ACPI storage file
182 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
184 // Get the protocol on this handle
185 // This should not fail because of LocateHandleBuffer
187 Status
= gBS
->HandleProtocol (
189 &gEfiFirmwareVolume2ProtocolGuid
,
192 if (EFI_ERROR (Status
)) {
193 goto FREE_HANDLE_BUFFER
;
196 Status
= FvInstance
->ReadFile (
203 &AuthenticationStatus
205 if (EFI_ERROR (Status
)) {
207 // Skip if no EFI application file in the FV
212 Status
= FvInstance
->ReadSection (
215 EFI_SECTION_USER_INTERFACE
,
219 &AuthenticationStatus
221 if (!EFI_ERROR (Status
)) {
223 // Create the EFI Device Path for the application using the Filename of the application
225 *DevicePath
= FileDevicePath (HandleBuffer
[Index
], UiSection
);
227 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&FvDevicePath
);
228 ASSERT_EFI_ERROR (Status
);
231 // Create the EFI Device Path for the application using the EFI GUID of the application
233 EfiInitializeFwVolDevicepathNode (&FvFileDevicePath
, EfiAppGuid
);
235 *DevicePath
= AppendDevicePathNode (FvDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&FvFileDevicePath
);
236 ASSERT (*DevicePath
!= NULL
);
244 // Free any allocated buffers
246 FreePool (HandleBuffer
);
248 if (*DevicePath
== NULL
) {
249 return EFI_NOT_FOUND
;