Initial import.
[mirror_edk2.git] / EdkModulePkg / Library / EdkIfrSupportLib / IfrVariable.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 IfrVariable.c\r
14\r
15Abstract:\r
16 Variable/Map manipulations routines\r
17\r
18--*/\r
19\r
20VOID\r
21EfiLibHiiVariablePackGetMap (\r
22 IN EFI_HII_VARIABLE_PACK *Pack, \r
23 OUT CHAR16 **Name, OPTIONAL\r
24 OUT EFI_GUID **Guid, OPTIONAL\r
25 OUT UINT16 *Id, OPTIONAL\r
26 OUT VOID **Var, OPTIONAL\r
27 OUT UINTN *Size OPTIONAL\r
28 )\r
29/*++\r
30\r
31Routine Description:\r
32\r
33 Extracts a variable form a Pack.\r
34\r
35Arguments:\r
36\r
37 Pack - List of variables\r
38 Name - Name of the variable/map\r
39 Guid - GUID of the variable/map\r
40 Var - Pointer to the variable/map\r
41 Size - Size of the variable/map in bytes\r
42\r
43Returns: \r
44\r
45 VOID\r
46 \r
47--*/\r
48{\r
49 if (NULL != Name) {\r
50 *Name = (VOID *) (Pack + 1);\r
51 }\r
52 \r
53 if (NULL != Guid) { \r
54 *Guid = (EFI_GUID *)(UINTN)&Pack->VariableGuid;\r
55 }\r
56 \r
57 \r
58 if (NULL != Id) {\r
59 *Id = Pack->VariableId;\r
60 }\r
61 \r
62 if (NULL != Var) {\r
63 *Var = (VOID *) ((CHAR8 *) (Pack + 1) + Pack->VariableNameLength);\r
64 }\r
65 \r
66 if (NULL != Size) {\r
67 *Size = Pack->Header.Length - sizeof (*Pack) - Pack->VariableNameLength;\r
68 }\r
69}\r
70\r
71\r
72UINTN\r
73EfiLibHiiVariablePackListGetMapCnt (\r
74 IN EFI_HII_VARIABLE_PACK_LIST *List\r
75 )\r
76 \r
77/*++\r
78\r
79Routine Description:\r
80\r
81 Finds a count of the variables/maps in the List.\r
82\r
83Arguments:\r
84\r
85 List - List of variables\r
86\r
87Returns: \r
88\r
89 UINTN - The number of map count.\r
90\r
91--*/\r
92\r
93{\r
94 UINTN Cnt = 0;\r
95 while (NULL != List) {\r
96 Cnt++;\r
97 List = List->NextVariablePack;\r
98 }\r
99 return Cnt;\r
100}\r
101\r
102\r
103VOID\r
104EfiLibHiiVariablePackListForEachVar (\r
105 IN EFI_HII_VARIABLE_PACK_LIST *List,\r
106 IN EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK *Callback\r
107 )\r
108/*++\r
109\r
110Routine Description:\r
111\r
112 Will iterate all variable/maps as appearing \r
113 in List and for each, it will call the Callback.\r
114\r
115Arguments:\r
116\r
117 List - List of variables\r
118 Callback - Routine to be called for each iterated variable.\r
119\r
120Returns: \r
121\r
122 VOID\r
123 \r
124--*/\r
125\r
126{\r
127 CHAR16 *MapName;\r
128 EFI_GUID *MapGuid;\r
129 UINT16 MapId;\r
130 VOID *Map;\r
131 UINTN MapSize;\r
132\r
133 while (NULL != List) {\r
134 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
135 //\r
136 // call the callback\r
137 //\r
138 Callback (MapName, MapGuid, MapId, Map, MapSize); \r
139 List = List->NextVariablePack;\r
140 }\r
141}\r
142\r
143\r
144EFI_STATUS\r
145EfiLibHiiVariablePackListGetMapByIdx (\r
146 IN UINTN Idx, \r
147 IN EFI_HII_VARIABLE_PACK_LIST *List, \r
148 OUT CHAR16 **Name, OPTIONAL\r
149 OUT EFI_GUID **Guid, OPTIONAL\r
150 OUT UINT16 *Id, OPTIONAL\r
151 OUT VOID **Var,\r
152 OUT UINTN *Size\r
153 )\r
154\r
155/*++\r
156\r
157Routine Description:\r
158\r
159 Finds a variable form List given \r
160 the order number as appears in the List.\r
161\r
162Arguments:\r
163\r
164 Idx - The index of the variable/map to retrieve\r
165 List - List of variables\r
166 Name - Name of the variable/map\r
167 Guid - GUID of the variable/map\r
168 Var - Pointer to the variable/map\r
169 Size - Size of the variable/map in bytes\r
170\r
171Returns:\r
172\r
173 EFI_SUCCESS - Variable is found, OUT parameters are valid\r
174 EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid\r
175\r
176--*/\r
177{\r
178 CHAR16 *MapName;\r
179 EFI_GUID *MapGuid;\r
180 UINT16 MapId;\r
181 VOID *Map;\r
182 UINTN MapSize;\r
183\r
184 while (NULL != List) {\r
185 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
186 if (0 == Idx--) {\r
187 *Var = Map;\r
188 *Size = MapSize;\r
189\r
190 if (NULL != Name) {\r
191 *Name = MapName;\r
192 }\r
193\r
194 if (NULL != Guid) {\r
195 *Guid = MapGuid;\r
196 }\r
197 \r
198 if (NULL != Id) {\r
199 *Id = MapId;\r
200 }\r
201 \r
202 return EFI_SUCCESS; // Map found\r
203 }\r
204 List = List->NextVariablePack;\r
205 }\r
206 //\r
207 // If here, the map is not found\r
208 //\r
209 return EFI_NOT_FOUND; \r
210}\r
211\r
212\r
213EFI_STATUS\r
214EfiLibHiiVariablePackListGetMapById (\r
215 IN UINT16 Id, \r
216 IN EFI_HII_VARIABLE_PACK_LIST *List,\r
217 OUT CHAR16 **Name, OPTIONAL\r
218 OUT EFI_GUID **Guid, OPTIONAL\r
219 OUT VOID **Var,\r
220 OUT UINTN *Size\r
221 )\r
222 \r
223/*++\r
224\r
225Routine Description:\r
226\r
227 Finds a variable form List given the \r
228 order number as appears in the List.\r
229\r
230Arguments:\r
231\r
232 Id - The ID of the variable/map to retrieve\r
233 List - List of variables\r
234 Name - Name of the variable/map\r
235 Guid - GUID of the variable/map\r
236 Var - Pointer to the variable/map\r
237 Size - Size of the variable/map in bytes\r
238\r
239Returns:\r
240\r
241 EFI_SUCCESS - Variable is found, OUT parameters are valid\r
242 EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid\r
243\r
244--*/\r
245\r
246{ \r
247 CHAR16 *MapName;\r
248 EFI_GUID *MapGuid;\r
249 UINT16 MapId;\r
250 VOID *Map;\r
251 UINTN MapSize;\r
252\r
253 while (NULL != List) {\r
254 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
255 if (MapId == Id) {\r
256 *Var = Map;\r
257 *Size = MapSize;\r
258 if (NULL != Name) {\r
259 *Name = MapName;\r
260 }\r
261 if (NULL != Guid) {\r
262 *Guid = MapGuid;\r
263 }\r
264 //\r
265 // Map found\r
266 //\r
267 return EFI_SUCCESS; \r
268 }\r
269 List = List->NextVariablePack;\r
270 }\r
271 //\r
272 // If here, the map is not found\r
273 //\r
274 return EFI_NOT_FOUND; \r
275}\r
276\r
277\r
278EFI_STATUS\r
279EfiLibHiiVariablePackListGetMap (\r
280 IN EFI_HII_VARIABLE_PACK_LIST *List,\r
281 IN CHAR16 *Name,\r
282 IN EFI_GUID *Guid,\r
283 OUT UINT16 *Id,\r
284 OUT VOID **Var, \r
285 OUT UINTN *Size\r
286 )\r
287\r
288/*++\r
289\r
290Routine Description:\r
291\r
292 Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.\r
293\r
294Arguments:\r
295\r
296 List - List of variables\r
297 Name - Name of the variable/map to be found\r
298 Guid - GUID of the variable/map to be found\r
299 Var - Pointer to the variable/map found\r
300 Size - Size of the variable/map in bytes found\r
301\r
302Returns:\r
303\r
304 EFI_SUCCESS - variable is found, OUT parameters are valid\r
305 EFI_NOT_FOUND - variable is not found, OUT parameters are not valid\r
306\r
307--*/\r
308\r
309{ \r
310 VOID *Map;\r
311 UINTN MapSize;\r
312 UINT16 MapId;\r
313 CHAR16 *MapName;\r
314 EFI_GUID *MapGuid;\r
315\r
316 while (NULL != List) {\r
317 EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
318 if ((0 == StrCmp (Name, MapName)) && CompareGuid (Guid, MapGuid)) {\r
319 *Id = MapId;\r
320 *Var = Map;\r
321 *Size = MapSize;\r
322 return EFI_SUCCESS;\r
323 }\r
324 List = List->NextVariablePack;\r
325 }\r
326 //\r
327 // If here, the map is not found\r
328 //\r
329 return EFI_NOT_FOUND;\r
330}\r
331\r
332EFI_STATUS\r
333EfiLibHiiVariableRetrieveFromNv (\r
334 IN CHAR16 *Name,\r
335 IN EFI_GUID *Guid,\r
336 IN UINTN Size,\r
337 OUT VOID **Var\r
338 )\r
339/*++\r
340\r
341Routine Description:\r
342 Finds out if a variable of specific Name/Guid/Size exists in NV. \r
343 If it does, it will retrieve it into the Var. \r
344\r
345Arguments:\r
346 Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
347 Var - Variable will be retrieved into buffer pointed by this pointer.\r
348 If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.\r
349Returns:\r
350 EFI_SUCCESS - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.\r
351 EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
352 EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
353\r
354--*/\r
355{\r
356 EFI_STATUS Status;\r
357 UINTN SizeNv;\r
358\r
359 //\r
360 // Test for existence of the variable.\r
361 //\r
362 SizeNv = 0;\r
363 Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, NULL);\r
364 if (EFI_BUFFER_TOO_SMALL != Status) {\r
365 ASSERT (EFI_SUCCESS != Status);\r
366 return EFI_NOT_FOUND;\r
367 }\r
368 if (SizeNv != Size) {\r
369 //\r
370 // The variable is considered corrupt, as it has different size from expected.\r
371 //\r
372 return EFI_LOAD_ERROR; \r
373 }\r
374\r
375 if (NULL == *Var) {\r
376 *Var = AllocatePool (Size);\r
377 ASSERT (NULL != *Var);\r
378 }\r
379 SizeNv = Size;\r
380 //\r
381 // Final read into the Var\r
382 //\r
383 Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, *Var); \r
384 //\r
385 // No tolerance for random failures. Such behavior is undetermined and not validated.\r
386 //\r
387 ASSERT_EFI_ERROR (Status); \r
388 ASSERT (SizeNv == Size);\r
389 return EFI_SUCCESS;\r
390}\r
391\r
392\r
393\r
394EFI_STATUS\r
395EfiLibHiiVariableOverrideIfSuffix (\r
396 IN CHAR16 *Suffix,\r
397 IN CHAR16 *Name,\r
398 IN EFI_GUID *Guid,\r
399 IN UINTN Size,\r
400 OUT VOID *Var\r
401 ) \r
402/*++\r
403\r
404Routine Description:\r
405 Overrrides the variable with NV data if found.\r
406 But it only does it if the Name ends with specified Suffix.\r
407 For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",\r
408 the Suffix matches the end of Name, so the variable will be loaded from NV\r
409 provided the variable exists and the GUID and Size matches.\r
410\r
411Arguments:\r
412 Suffix - Suffix the Name should end with.\r
413 Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
414 Var - Variable will be retrieved into this buffer.\r
415 Caller is responsible for providing storage of exactly Size size in bytes.\r
416Returns:\r
417 EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.\r
418 EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.\r
419 EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
420 EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
421\r
422--*/\r
423{\r
424 UINTN StrLength;\r
425 UINTN StrLenSuffix;\r
426\r
427 StrLength = StrLen (Name);\r
428 StrLenSuffix = StrLen (Suffix);\r
429 if ((StrLength <= StrLenSuffix) || (0 != StrCmp (Suffix, &Name[StrLength - StrLenSuffix]))) {\r
430 //\r
431 // Not ending with <Suffix>.\r
432 //\r
433 return EFI_INVALID_PARAMETER; \r
434 }\r
435 return EfiLibHiiVariableRetrieveFromNv (Name, Guid, Size, &Var);\r
436}\r
437\r
438EFI_STATUS\r
439EfiLibHiiVariableOverrideBySuffix (\r
440 IN CHAR16 *Suffix,\r
441 IN CHAR16 *Name,\r
442 IN EFI_GUID *Guid,\r
443 IN UINTN Size,\r
444 OUT VOID *Var\r
445 ) \r
446/*++\r
447\r
448Routine Description:\r
449 Overrrides the variable with NV data if found.\r
450 But it only does it if the NV contains the same variable with Name is appended with Suffix. \r
451 For example, if Suffix="MyOverride" and the Name="XyzSetup",\r
452 the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"\r
453 will be loaded from NV provided the variable exists and the GUID and Size matches.\r
454\r
455Arguments:\r
456 Suffix - Suffix the variable will be appended with.\r
457 Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
458 Var - Variable will be retrieved into this buffer.\r
459 Caller is responsible for providing storage of exactly Size size in bytes.\r
460\r
461Returns:\r
462 EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.\r
463 EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
464 EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
465\r
466--*/\r
467{\r
468 EFI_STATUS Status;\r
469 CHAR16 *NameSuffixed;\r
470\r
471 //\r
472 // enough to concatenate both strings.\r
473 //\r
474 NameSuffixed = AllocateZeroPool ((StrLen (Name) + StrLen (Suffix) + 1) * sizeof (CHAR16)); \r
475 \r
476 StrCpy (NameSuffixed, Name);\r
477 StrCat (NameSuffixed, Suffix);\r
478 \r
479 Status = EfiLibHiiVariableRetrieveFromNv (NameSuffixed, Guid, Size, &Var);\r
480 gBS->FreePool (NameSuffixed);\r
481 \r
482 return Status;\r
483}\r
484\r