]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/BdsLib/BdsAppLoader.c
ArmPkg/BdsLib: Replaced BdsLoadApplication() by LocateEfiApplicationInFv()
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsAppLoader.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
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
9 *
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.
12 *
13 **/
14
15 #include "BdsInternal.h"
16
17 /**
18 Locate an EFI application in a the Firmware Volumes by its Name
19
20 @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
21 @param DevicePath EFI Device Path of the EFI application
22
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.
26
27 **/
28 EFI_STATUS
29 LocateEfiApplicationInFvByName (
30 IN CONST CHAR16* EfiAppName,
31 OUT EFI_DEVICE_PATH **DevicePath
32 )
33 {
34 VOID *Key;
35 EFI_STATUS Status, FileStatus;
36 EFI_GUID NameGuid;
37 EFI_FV_FILETYPE FileType;
38 EFI_FV_FILE_ATTRIBUTES Attributes;
39 UINTN Size;
40 UINTN UiStringLen;
41 CHAR16 *UiSection;
42 UINT32 Authentication;
43 EFI_DEVICE_PATH *FvDevicePath;
44 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
45 EFI_HANDLE *HandleBuffer;
46 UINTN NumberOfHandles;
47 UINTN Index;
48 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
49
50 ASSERT (DevicePath != NULL);
51
52 // Length of FilePath
53 UiStringLen = StrLen (EfiAppName);
54
55 // Locate all the Firmware Volume protocols.
56 Status = gBS->LocateHandleBuffer (
57 ByProtocol,
58 &gEfiFirmwareVolume2ProtocolGuid,
59 NULL,
60 &NumberOfHandles,
61 &HandleBuffer
62 );
63 if (EFI_ERROR (Status)) {
64 return Status;
65 }
66
67 *DevicePath = NULL;
68
69 // Looking for FV with ACPI storage file
70 for (Index = 0; Index < NumberOfHandles; Index++) {
71 //
72 // Get the protocol on this handle
73 // This should not fail because of LocateHandleBuffer
74 //
75 Status = gBS->HandleProtocol (
76 HandleBuffer[Index],
77 &gEfiFirmwareVolume2ProtocolGuid,
78 (VOID**) &FvInstance
79 );
80 if (EFI_ERROR (Status)) {
81 goto FREE_HANDLE_BUFFER;
82 }
83
84 // Allocate Key
85 Key = AllocatePool (FvInstance->KeySize);
86 ASSERT (Key != NULL);
87 ZeroMem (Key, FvInstance->KeySize);
88
89 do {
90 // Search in all files
91 FileType = EFI_FV_FILETYPE_ALL;
92
93 Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);
94 if (!EFI_ERROR (Status)) {
95 UiSection = NULL;
96 FileStatus = FvInstance->ReadSection (
97 FvInstance,
98 &NameGuid,
99 EFI_SECTION_USER_INTERFACE,
100 0,
101 (VOID **)&UiSection,
102 &Size,
103 &Authentication
104 );
105 if (!EFI_ERROR (FileStatus)) {
106 if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {
107 //
108 // We found a UiString match.
109 //
110 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
111
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);
116
117 FreePool (Key);
118 FreePool (UiSection);
119 FreePool (HandleBuffer);
120 return FileStatus;
121 }
122 FreePool (UiSection);
123 }
124 }
125 } while (!EFI_ERROR (Status));
126
127 FreePool (Key);
128 }
129
130 FREE_HANDLE_BUFFER:
131 FreePool (HandleBuffer);
132 return EFI_NOT_FOUND;
133 }
134
135 /**
136 Locate an EFI application in a the Firmware Volumes by its GUID
137
138 @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
139 @param DevicePath EFI Device Path of the EFI application
140
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.
144
145 **/
146 EFI_STATUS
147 LocateEfiApplicationInFvByGuid (
148 IN CONST EFI_GUID *EfiAppGuid,
149 OUT EFI_DEVICE_PATH **DevicePath
150 )
151 {
152 EFI_STATUS Status;
153 EFI_DEVICE_PATH *FvDevicePath;
154 EFI_HANDLE *HandleBuffer;
155 UINTN NumberOfHandles;
156 UINTN Index;
157 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
158 EFI_FV_FILE_ATTRIBUTES Attributes;
159 UINT32 AuthenticationStatus;
160 EFI_FV_FILETYPE Type;
161 UINTN Size;
162 CHAR16 *UiSection;
163 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;
164
165 ASSERT (DevicePath != NULL);
166
167 // Locate all the Firmware Volume protocols.
168 Status = gBS->LocateHandleBuffer (
169 ByProtocol,
170 &gEfiFirmwareVolume2ProtocolGuid,
171 NULL,
172 &NumberOfHandles,
173 &HandleBuffer
174 );
175 if (EFI_ERROR (Status)) {
176 return Status;
177 }
178
179 *DevicePath = NULL;
180
181 // Looking for FV with ACPI storage file
182 for (Index = 0; Index < NumberOfHandles; Index++) {
183 //
184 // Get the protocol on this handle
185 // This should not fail because of LocateHandleBuffer
186 //
187 Status = gBS->HandleProtocol (
188 HandleBuffer[Index],
189 &gEfiFirmwareVolume2ProtocolGuid,
190 (VOID**) &FvInstance
191 );
192 if (EFI_ERROR (Status)) {
193 goto FREE_HANDLE_BUFFER;
194 }
195
196 Status = FvInstance->ReadFile (
197 FvInstance,
198 EfiAppGuid,
199 NULL,
200 &Size,
201 &Type,
202 &Attributes,
203 &AuthenticationStatus
204 );
205 if (EFI_ERROR (Status)) {
206 //
207 // Skip if no EFI application file in the FV
208 //
209 continue;
210 } else {
211 UiSection = NULL;
212 Status = FvInstance->ReadSection (
213 FvInstance,
214 EfiAppGuid,
215 EFI_SECTION_USER_INTERFACE,
216 0,
217 (VOID **)&UiSection,
218 &Size,
219 &AuthenticationStatus
220 );
221 if (!EFI_ERROR (Status)) {
222 //
223 // Create the EFI Device Path for the application using the Filename of the application
224 //
225 *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);
226 } else {
227 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);
228 ASSERT_EFI_ERROR (Status);
229
230 //
231 // Create the EFI Device Path for the application using the EFI GUID of the application
232 //
233 EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);
234
235 *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);
236 ASSERT (*DevicePath != NULL);
237 }
238 break;
239 }
240 }
241
242 FREE_HANDLE_BUFFER:
243 //
244 // Free any allocated buffers
245 //
246 FreePool (HandleBuffer);
247
248 if (*DevicePath == NULL) {
249 return EFI_NOT_FOUND;
250 } else {
251 return EFI_SUCCESS;
252 }
253 }