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