]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Variable/Pei/Variable.c
Change EFI_OPTIONAL_POINTER to EFI_OPTIONAL_PTR
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
CommitLineData
504214c4
LG
1/** @file\r
2\r
3 Implement ReadOnly Variable Services required by PEIM and install\r
02c57ded 4 PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.\r
8d3a5c82 5\r
01f352a7 6Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
8d3a5c82 7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14Module Name:\r
15\r
504214c4 16**/\r
8d3a5c82 17\r
18\r
19#include "Variable.h"\r
20\r
21//\r
22// Module globals\r
23//\r
fe1e36e5 24EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {\r
8d3a5c82 25 PeiGetVariable,\r
26 PeiGetNextVariableName\r
27};\r
28\r
fe1e36e5 29EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {\r
8d3a5c82 30 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
31 &gEfiPeiReadOnlyVariable2PpiGuid,\r
32 &mVariablePpi\r
33};\r
34\r
35EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;\r
36\r
8d3a5c82 37\r
33479ddf 38/**\r
8d3a5c82 39 Provide the functionality of the variable services.\r
33479ddf 40 \r
41 @param FileHandle Handle of the file being invoked. \r
42 Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().\r
43 @param PeiServices General purpose services available to every PEIM.\r
8d3a5c82 44\r
33479ddf 45 @retval EFI_SUCCESS If the interface could be successfully installed\r
46 @retval Others Returned from PeiServicesInstallPpi()\r
8d3a5c82 47\r
33479ddf 48**/\r
49EFI_STATUS\r
50EFIAPI\r
51PeimInitializeVariableServices (\r
52 IN EFI_PEI_FILE_HANDLE FileHandle,\r
53 IN CONST EFI_PEI_SERVICES **PeiServices\r
54 )\r
8d3a5c82 55{\r
56 //\r
57 // Publish the variable capability to other modules\r
58 //\r
33479ddf 59 return PeiServicesInstallPpi (&mPpiListVariable);\r
8d3a5c82 60\r
61}\r
62\r
9cad030b 63\r
33479ddf 64/**\r
65 This code gets the pointer to the first variable memory pointer byte.\r
9cad030b 66\r
33479ddf 67 @param VarStoreHeader Pointer to the Variable Store Header.\r
9cad030b 68\r
33479ddf 69 @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
9cad030b 70\r
33479ddf 71**/\r
72VARIABLE_HEADER *\r
73GetStartPointer (\r
74 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
75 )\r
9cad030b 76{\r
77 //\r
78 // The end of variable store\r
79 //\r
80 return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
81}\r
82\r
9cad030b 83\r
33479ddf 84/**\r
85 This code gets the pointer to the last variable memory pointer byte.\r
9cad030b 86\r
33479ddf 87 @param VarStoreHeader Pointer to the Variable Store Header.\r
9cad030b 88\r
33479ddf 89 @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
9cad030b 90\r
33479ddf 91**/\r
92VARIABLE_HEADER *\r
93GetEndPointer (\r
94 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
95 )\r
9cad030b 96{\r
97 //\r
98 // The end of variable store\r
99 //\r
100 return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
101}\r
102\r
8d3a5c82 103\r
33479ddf 104/**\r
8d3a5c82 105 This code checks if variable header is valid or not.\r
106\r
33479ddf 107 @param Variable Pointer to the Variable Header.\r
8d3a5c82 108\r
33479ddf 109 @retval TRUE Variable header is valid.\r
110 @retval FALSE Variable header is not valid.\r
8d3a5c82 111\r
33479ddf 112**/\r
113BOOLEAN\r
114IsValidVariableHeader (\r
115 IN VARIABLE_HEADER *Variable\r
116 )\r
8d3a5c82 117{\r
130e2569 118 if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {\r
119 return FALSE;\r
120 }\r
121\r
122 return TRUE;\r
8d3a5c82 123}\r
124\r
130e2569 125\r
33479ddf 126/**\r
130e2569 127 This code gets the size of name of variable.\r
128\r
33479ddf 129 @param Variable Pointer to the Variable Header.\r
130e2569 130\r
33479ddf 131 @return Size of variable in bytes in type UINTN.\r
130e2569 132\r
33479ddf 133**/\r
134UINTN\r
135NameSizeOfVariable (\r
136 IN VARIABLE_HEADER *Variable\r
137 )\r
130e2569 138{\r
139 if (Variable->State == (UINT8) (-1) ||\r
140 Variable->DataSize == (UINT32) -1 ||\r
141 Variable->NameSize == (UINT32) -1 ||\r
142 Variable->Attributes == (UINT32) -1) {\r
143 return 0;\r
144 }\r
145 return (UINTN) Variable->NameSize;\r
146}\r
147\r
130e2569 148\r
33479ddf 149/**\r
150 This code gets the size of data of variable.\r
130e2569 151\r
33479ddf 152 @param Variable Pointer to the Variable Header.\r
130e2569 153\r
33479ddf 154 @return Size of variable in bytes in type UINTN.\r
130e2569 155\r
33479ddf 156**/\r
157UINTN\r
158DataSizeOfVariable (\r
159 IN VARIABLE_HEADER *Variable\r
160 )\r
130e2569 161{\r
162 if (Variable->State == (UINT8) -1 ||\r
163 Variable->DataSize == (UINT32) -1 ||\r
164 Variable->NameSize == (UINT32) -1 ||\r
165 Variable->Attributes == (UINT32) -1) {\r
166 return 0;\r
167 }\r
168 return (UINTN) Variable->DataSize;\r
169}\r
170\r
33479ddf 171/**\r
130e2569 172 This code gets the pointer to the variable name.\r
8d3a5c82 173\r
33479ddf 174 @param Variable Pointer to the Variable Header.\r
130e2569 175\r
33479ddf 176 @return A CHAR16* pointer to Variable Name.\r
130e2569 177\r
33479ddf 178**/\r
179CHAR16 *\r
180GetVariableNamePtr (\r
181 IN VARIABLE_HEADER *Variable\r
182 )\r
130e2569 183{\r
184\r
185 return (CHAR16 *) (Variable + 1);\r
186}\r
187\r
188\r
33479ddf 189/**\r
130e2569 190 This code gets the pointer to the variable data.\r
191\r
33479ddf 192 @param Variable Pointer to the Variable Header.\r
130e2569 193\r
33479ddf 194 @return A UINT8* pointer to Variable Data.\r
130e2569 195\r
33479ddf 196**/\r
197UINT8 *\r
198GetVariableDataPtr (\r
199 IN VARIABLE_HEADER *Variable\r
200 )\r
130e2569 201{\r
202 UINTN Value;\r
203 \r
204 //\r
205 // Be careful about pad size for alignment\r
206 //\r
207 Value = (UINTN) GetVariableNamePtr (Variable);\r
208 Value += NameSizeOfVariable (Variable);\r
209 Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));\r
210\r
211 return (UINT8 *) Value;\r
212}\r
213\r
130e2569 214\r
33479ddf 215/**\r
130e2569 216 This code gets the pointer to the next variable header.\r
217\r
33479ddf 218 @param Variable Pointer to the Variable Header.\r
130e2569 219\r
33479ddf 220 @return A VARIABLE_HEADER* pointer to next variable header.\r
8d3a5c82 221\r
33479ddf 222**/\r
223VARIABLE_HEADER *\r
224GetNextVariablePtr (\r
225 IN VARIABLE_HEADER *Variable\r
226 )\r
8d3a5c82 227{\r
130e2569 228 UINTN Value;\r
229\r
230 if (!IsValidVariableHeader (Variable)) {\r
231 return NULL;\r
8d3a5c82 232 }\r
233\r
130e2569 234 Value = (UINTN) GetVariableDataPtr (Variable);\r
235 Value += DataSizeOfVariable (Variable);\r
236 Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
237\r
238 //\r
239 // Be careful about pad size for alignment\r
240 //\r
241 return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
8d3a5c82 242}\r
243\r
33479ddf 244/**\r
245 This code gets the pointer to the variable name.\r
246\r
247 @param VarStoreHeader Pointer to the Variable Store Header.\r
248\r
249 @retval EfiRaw Variable store is raw\r
250 @retval EfiValid Variable store is valid\r
251 @retval EfiInvalid Variable store is invalid\r
130e2569 252\r
33479ddf 253**/\r
8d3a5c82 254VARIABLE_STORE_STATUS\r
8d3a5c82 255GetVariableStoreStatus (\r
256 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
257 )\r
8d3a5c82 258{\r
259 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
260 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
261 VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
262 ) {\r
263\r
264 return EfiValid;\r
265 }\r
266\r
267 if (VarStoreHeader->Signature == 0xffffffff &&\r
268 VarStoreHeader->Size == 0xffffffff &&\r
269 VarStoreHeader->Format == 0xff &&\r
270 VarStoreHeader->State == 0xff\r
271 ) {\r
272\r
273 return EfiRaw;\r
274 } else {\r
275 return EfiInvalid;\r
276 }\r
277}\r
278\r
33479ddf 279\r
280/**\r
281 This function compares a variable with variable entries in database.\r
282\r
283 @param Variable Pointer to the variable in our database\r
284 @param VariableName Name of the variable to compare to 'Variable'\r
285 @param VendorGuid GUID of the variable to compare to 'Variable'\r
286 @param PtrTrack Variable Track Pointer structure that contains Variable Information.\r
287\r
288 @retval EFI_SUCCESS Found match variable\r
289 @retval EFI_NOT_FOUND Variable not found\r
290\r
291**/\r
8d3a5c82 292EFI_STATUS\r
293CompareWithValidVariable (\r
294 IN VARIABLE_HEADER *Variable,\r
295 IN CONST CHAR16 *VariableName,\r
296 IN CONST EFI_GUID *VendorGuid,\r
297 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
298 )\r
8d3a5c82 299{\r
130e2569 300 VOID *Point;\r
301\r
8d3a5c82 302 if (VariableName[0] == 0) {\r
303 PtrTrack->CurrPtr = Variable;\r
304 return EFI_SUCCESS;\r
305 } else {\r
306 //\r
307 // Don't use CompareGuid function here for performance reasons.\r
308 // Instead we compare the GUID a UINT32 at a time and branch\r
309 // on the first failed comparison.\r
310 //\r
311 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&\r
312 (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&\r
313 (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&\r
314 (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])\r
315 ) {\r
130e2569 316 ASSERT (NameSizeOfVariable (Variable) != 0);\r
317 Point = (VOID *) GetVariableNamePtr (Variable);\r
dfc005c3 318 if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) {\r
8d3a5c82 319 PtrTrack->CurrPtr = Variable;\r
320 return EFI_SUCCESS;\r
321 }\r
322 }\r
323 }\r
324\r
325 return EFI_NOT_FOUND;\r
326}\r
327\r
33479ddf 328\r
329/**\r
330 This code finds variable in storage blocks (Non-Volatile).\r
331\r
332 @param PeiServices General purpose services available to every PEIM.\r
333 @param VariableName Name of the variable to be found\r
334 @param VendorGuid Vendor GUID to be found.\r
335 @param PtrTrack Variable Track Pointer structure that contains Variable Information.\r
336\r
337 @retval EFI_SUCCESS Variable found successfully\r
338 @retval EFI_NOT_FOUND Variable not found\r
339 @retval EFI_INVALID_PARAMETER Invalid variable name\r
340\r
341**/\r
8d3a5c82 342EFI_STATUS\r
8d3a5c82 343FindVariable (\r
284c8400 344 IN CONST EFI_PEI_SERVICES **PeiServices,\r
8d3a5c82 345 IN CONST CHAR16 *VariableName,\r
346 IN CONST EFI_GUID *VendorGuid,\r
347 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
348 )\r
8d3a5c82 349{\r
350 EFI_HOB_GUID_TYPE *GuidHob;\r
351 VARIABLE_STORE_HEADER *VariableStoreHeader;\r
352 VARIABLE_HEADER *Variable;\r
353 VARIABLE_HEADER *MaxIndex;\r
354 VARIABLE_INDEX_TABLE *IndexTable;\r
355 UINT32 Count;\r
356 UINT8 *VariableBase;\r
357\r
358 if (VariableName != 0 && VendorGuid == NULL) {\r
359 return EFI_INVALID_PARAMETER;\r
360 }\r
361 //\r
362 // No Variable Address equals zero, so 0 as initial value is safe.\r
363 //\r
364 MaxIndex = 0;\r
365\r
366 GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
367 if (GuidHob == NULL) {\r
368 IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
369 IndexTable->Length = 0;\r
370 IndexTable->StartPtr = NULL;\r
371 IndexTable->EndPtr = NULL;\r
372 IndexTable->GoneThrough = 0;\r
373 } else {\r
374 IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
33479ddf 375 for (Count = 0; Count < IndexTable->Length; Count++) {\r
8d3a5c82 376 MaxIndex = GetVariableByIndex (IndexTable, Count);\r
377\r
378 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
379 PtrTrack->StartPtr = IndexTable->StartPtr;\r
380 PtrTrack->EndPtr = IndexTable->EndPtr;\r
381\r
382 return EFI_SUCCESS;\r
383 }\r
384 }\r
385\r
33479ddf 386 if (IndexTable->GoneThrough != 0) {\r
8d3a5c82 387 return EFI_NOT_FOUND;\r
388 }\r
389 }\r
390 //\r
391 // If not found in HOB, then let's start from the MaxIndex we've found.\r
392 //\r
393 if (MaxIndex != NULL) {\r
394 Variable = GetNextVariablePtr (MaxIndex);\r
395 } else {\r
33479ddf 396 if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {\r
8d3a5c82 397 Variable = IndexTable->StartPtr;\r
398 } else {\r
399 VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);\r
400 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \\r
401 ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);\r
402\r
403 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {\r
404 return EFI_UNSUPPORTED;\r
405 }\r
406\r
407 if (~VariableStoreHeader->Size == 0) {\r
408 return EFI_NOT_FOUND;\r
409 }\r
410 //\r
411 // Find the variable by walk through non-volatile variable store\r
412 //\r
9cad030b 413 IndexTable->StartPtr = GetStartPointer (VariableStoreHeader);\r
414 IndexTable->EndPtr = GetEndPointer (VariableStoreHeader);\r
8d3a5c82 415\r
416 //\r
417 // Start Pointers for the variable.\r
418 // Actual Data Pointer where data can be written.\r
419 //\r
420 Variable = IndexTable->StartPtr;\r
421 }\r
422 }\r
423 //\r
424 // Find the variable by walk through non-volatile variable store\r
425 //\r
426 PtrTrack->StartPtr = IndexTable->StartPtr;\r
427 PtrTrack->EndPtr = IndexTable->EndPtr;\r
428\r
429 while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {\r
430 if (Variable->State == VAR_ADDED) {\r
431 //\r
432 // Record Variable in VariableIndex HOB\r
433 //\r
33479ddf 434 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
8d3a5c82 435 VariableIndexTableUpdate (IndexTable, Variable);\r
436 }\r
437\r
438 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
439 return EFI_SUCCESS;\r
440 }\r
441 }\r
442\r
443 Variable = GetNextVariablePtr (Variable);\r
444 }\r
445 //\r
446 // If gone through the VariableStore, that means we never find in Firmware any more.\r
447 //\r
448 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
449 IndexTable->GoneThrough = 1;\r
450 }\r
451\r
452 PtrTrack->CurrPtr = NULL;\r
453\r
454 return EFI_NOT_FOUND;\r
455}\r
456\r
33479ddf 457/**\r
458 This service retrieves a variable's value using its name and GUID.\r
459\r
460 Read the specified variable from the UEFI variable store. If the Data \r
461 buffer is too small to hold the contents of the variable, the error\r
462 EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer\r
463 size to obtain the data.\r
464\r
465 @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.\r
466 @param VariableName A pointer to a null-terminated string that is the variable's name.\r
467 @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of\r
468 VariableGuid and VariableName must be unique.\r
469 @param Attributes If non-NULL, on return, points to the variable's attributes.\r
470 @param DataSize On entry, points to the size in bytes of the Data buffer.\r
471 On return, points to the size of the data returned in Data.\r
472 @param Data Points to the buffer which will hold the returned variable value.\r
473\r
474 @retval EFI_SUCCESS The variable was read successfully.\r
475 @retval EFI_NOT_FOUND The variable could not be found.\r
476 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data. \r
477 DataSize is updated with the size required for \r
478 the specified variable.\r
479 @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL.\r
480 @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.\r
481\r
482**/\r
8d3a5c82 483EFI_STATUS\r
484EFIAPI\r
485PeiGetVariable (\r
486 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
487 IN CONST CHAR16 *VariableName,\r
488 IN CONST EFI_GUID *VariableGuid,\r
489 OUT UINT32 *Attributes,\r
490 IN OUT UINTN *DataSize,\r
491 OUT VOID *Data\r
492 )\r
8d3a5c82 493{\r
494 VARIABLE_POINTER_TRACK Variable;\r
495 UINTN VarDataSize;\r
496 EFI_STATUS Status;\r
284c8400 497 CONST EFI_PEI_SERVICES **PeiServices;\r
8d3a5c82 498\r
499 PeiServices = GetPeiServicesTablePointer ();\r
01f352a7 500 if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {\r
8d3a5c82 501 return EFI_INVALID_PARAMETER;\r
502 }\r
503 //\r
504 // Find existing variable\r
505 //\r
506 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
507 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
508 return Status;\r
509 }\r
510 //\r
511 // Get data size\r
512 //\r
130e2569 513 VarDataSize = DataSizeOfVariable (Variable.CurrPtr);\r
8d3a5c82 514 if (*DataSize >= VarDataSize) {\r
39aea48d 515 if (Data == NULL) {\r
516 return EFI_INVALID_PARAMETER;\r
517 }\r
518\r
33479ddf 519 CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);\r
8d3a5c82 520\r
521 if (Attributes != NULL) {\r
522 *Attributes = Variable.CurrPtr->Attributes;\r
523 }\r
524\r
525 *DataSize = VarDataSize;\r
526 return EFI_SUCCESS;\r
527 } else {\r
528 *DataSize = VarDataSize;\r
529 return EFI_BUFFER_TOO_SMALL;\r
530 }\r
531}\r
532\r
33479ddf 533/**\r
534 Return the next variable name and GUID.\r
535\r
536 This function is called multiple times to retrieve the VariableName \r
537 and VariableGuid of all variables currently available in the system. \r
538 On each call, the previous results are passed into the interface, \r
539 and, on return, the interface returns the data for the next \r
540 interface. When the entire variable list has been returned, \r
541 EFI_NOT_FOUND is returned.\r
542\r
543 @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.\r
544\r
545 @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName.\r
546 @param VariableName On entry, a pointer to a null-terminated string that is the variable's name.\r
547 On return, points to the next variable's null-terminated name string.\r
548 @param VariableGuid On entry, a pointer to an UEFI _GUID that is the variable's GUID. \r
549 On return, a pointer to the next variable's GUID.\r
550\r
551 @retval EFI_SUCCESS The variable was read successfully.\r
552 @retval EFI_NOT_FOUND The variable could not be found.\r
553 @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting\r
554 data. VariableNameSize is updated with the size\r
555 required for the specified variable.\r
556 @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or\r
557 VariableNameSize is NULL.\r
558 @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.\r
559\r
560**/\r
8d3a5c82 561EFI_STATUS\r
562EFIAPI\r
563PeiGetNextVariableName (\r
564 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
565 IN OUT UINTN *VariableNameSize,\r
566 IN OUT CHAR16 *VariableName,\r
567 IN OUT EFI_GUID *VariableGuid\r
568 )\r
8d3a5c82 569{\r
570 VARIABLE_POINTER_TRACK Variable;\r
571 UINTN VarNameSize;\r
572 EFI_STATUS Status;\r
284c8400 573 CONST EFI_PEI_SERVICES **PeiServices;\r
8d3a5c82 574\r
575 PeiServices = GetPeiServicesTablePointer ();\r
01f352a7 576 if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {\r
8d3a5c82 577 return EFI_INVALID_PARAMETER;\r
578 }\r
579\r
580 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
581 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
582 return Status;\r
583 }\r
584\r
585 if (VariableName[0] != 0) {\r
586 //\r
587 // If variable name is not NULL, get next variable\r
588 //\r
589 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
590 }\r
591\r
592 while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {\r
593 if (IsValidVariableHeader (Variable.CurrPtr)) {\r
594 if (Variable.CurrPtr->State == VAR_ADDED) {\r
130e2569 595 ASSERT (NameSizeOfVariable (Variable.CurrPtr) != 0);\r
9cad030b 596\r
130e2569 597 VarNameSize = (UINTN) NameSizeOfVariable (Variable.CurrPtr);\r
8d3a5c82 598 if (VarNameSize <= *VariableNameSize) {\r
33479ddf 599 CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);\r
8d3a5c82 600\r
33479ddf 601 CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));\r
8d3a5c82 602\r
603 Status = EFI_SUCCESS;\r
604 } else {\r
605 Status = EFI_BUFFER_TOO_SMALL;\r
606 }\r
607\r
608 *VariableNameSize = VarNameSize;\r
609 return Status;\r
610 //\r
611 // Variable is found\r
612 //\r
613 } else {\r
614 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
615 }\r
616 } else {\r
617 break;\r
618 }\r
619 }\r
620\r
621 return EFI_NOT_FOUND;\r
622}\r