]>
Commit | Line | Data |
---|---|---|
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 | 28 | EFI_STATUS\r |
0c72676d OM |
29 | LocateEfiApplicationInFvByName (\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 | |
130 | FREE_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 | |
146 | EFI_STATUS\r | |
0c72676d OM |
147 | LocateEfiApplicationInFvByGuid (\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 |
242 | FREE_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 |