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