Code Scrub:
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
1 /** @file\r
2 \r
3   Implement ReadOnly Variable Services required by PEIM and install\r
4   PI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.\r
5 \r
6 Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
7 All rights reserved. This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution.  The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11 \r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14 Module Name:\r
15 \r
16 **/\r
17 \r
18 \r
19 #include "Variable.h"\r
20 \r
21 //\r
22 // Module globals\r
23 //\r
24 EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {\r
25   PeiGetVariable,\r
26   PeiGetNextVariableName\r
27 };\r
28 \r
29 EFI_PEI_PPI_DESCRIPTOR     mPpiListVariable = {\r
30   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
31   &gEfiPeiReadOnlyVariable2PpiGuid,\r
32   &mVariablePpi\r
33 };\r
34 \r
35 EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;\r
36 \r
37 \r
38 /**\r
39   Provide the functionality of the variable services.\r
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
44 \r
45   @retval EFI_SUCCESS  If the interface could be successfully installed\r
46   @retval Others       Returned from PeiServicesInstallPpi()\r
47 \r
48 **/\r
49 EFI_STATUS\r
50 EFIAPI\r
51 PeimInitializeVariableServices (\r
52   IN       EFI_PEI_FILE_HANDLE       FileHandle,\r
53   IN CONST EFI_PEI_SERVICES          **PeiServices\r
54   )\r
55 {\r
56   //\r
57   // Publish the variable capability to other modules\r
58   //\r
59   return PeiServicesInstallPpi (&mPpiListVariable);\r
60 \r
61 }\r
62 \r
63 \r
64 /**\r
65   This code gets the pointer to the first variable memory pointer byte.\r
66 \r
67   @param  VarStoreHeader   Pointer to the Variable Store Header.\r
68 \r
69   @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
70 \r
71 **/\r
72 VARIABLE_HEADER *\r
73 GetStartPointer (\r
74   IN VARIABLE_STORE_HEADER       *VarStoreHeader\r
75   )\r
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
83 \r
84 /**\r
85   This code gets the pointer to the last variable memory pointer byte.\r
86 \r
87   @param  VarStoreHeader  Pointer to the Variable Store Header.\r
88 \r
89   @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
90 \r
91 **/\r
92 VARIABLE_HEADER *\r
93 GetEndPointer (\r
94   IN VARIABLE_STORE_HEADER       *VarStoreHeader\r
95   )\r
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
103 \r
104 /**\r
105   This code checks if variable header is valid or not.\r
106 \r
107   @param  Variable  Pointer to the Variable Header.\r
108 \r
109   @retval TRUE      Variable header is valid.\r
110   @retval FALSE     Variable header is not valid.\r
111 \r
112 **/\r
113 BOOLEAN\r
114 IsValidVariableHeader (\r
115   IN  VARIABLE_HEADER   *Variable\r
116   )\r
117 {\r
118   if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {\r
119     return FALSE;\r
120   }\r
121 \r
122   return TRUE;\r
123 }\r
124 \r
125 \r
126 /**\r
127   This code gets the size of name of variable.\r
128 \r
129   @param  Variable  Pointer to the Variable Header.\r
130 \r
131   @return Size of variable in bytes in type UINTN.\r
132 \r
133 **/\r
134 UINTN\r
135 NameSizeOfVariable (\r
136   IN  VARIABLE_HEADER   *Variable\r
137   )\r
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
148 \r
149 /**\r
150   This code gets the size of data of variable.\r
151 \r
152   @param  Variable  Pointer to the Variable Header.\r
153 \r
154   @return Size of variable in bytes in type UINTN.\r
155 \r
156 **/\r
157 UINTN\r
158 DataSizeOfVariable (\r
159   IN  VARIABLE_HEADER   *Variable\r
160   )\r
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
171 /**\r
172   This code gets the pointer to the variable name.\r
173 \r
174   @param   Variable  Pointer to the Variable Header.\r
175 \r
176   @return  A CHAR16* pointer to Variable Name.\r
177 \r
178 **/\r
179 CHAR16 *\r
180 GetVariableNamePtr (\r
181   IN  VARIABLE_HEADER   *Variable\r
182   )\r
183 {\r
184 \r
185   return (CHAR16 *) (Variable + 1);\r
186 }\r
187 \r
188 \r
189 /**\r
190   This code gets the pointer to the variable data.\r
191 \r
192   @param   Variable  Pointer to the Variable Header.\r
193 \r
194   @return  A UINT8* pointer to Variable Data.\r
195 \r
196 **/\r
197 UINT8 *\r
198 GetVariableDataPtr (\r
199   IN  VARIABLE_HEADER   *Variable\r
200   )\r
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
214 \r
215 /**\r
216   This code gets the pointer to the next variable header.\r
217 \r
218   @param  Variable  Pointer to the Variable Header.\r
219 \r
220   @return  A VARIABLE_HEADER* pointer to next variable header.\r
221 \r
222 **/\r
223 VARIABLE_HEADER *\r
224 GetNextVariablePtr (\r
225   IN  VARIABLE_HEADER   *Variable\r
226   )\r
227 {\r
228   UINTN Value;\r
229 \r
230   if (!IsValidVariableHeader (Variable)) {\r
231     return NULL;\r
232   }\r
233 \r
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
242 }\r
243 \r
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
252 \r
253 **/\r
254 VARIABLE_STORE_STATUS\r
255 GetVariableStoreStatus (\r
256   IN VARIABLE_STORE_HEADER *VarStoreHeader\r
257   )\r
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
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
292 EFI_STATUS\r
293 CompareWithValidVariable (\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
299 {\r
300   VOID  *Point;\r
301 \r
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
316       ASSERT (NameSizeOfVariable (Variable) != 0);\r
317       Point = (VOID *) GetVariableNamePtr (Variable);\r
318       if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) {\r
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
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
342 EFI_STATUS\r
343 FindVariable (\r
344   IN CONST EFI_PEI_SERVICES   **PeiServices,\r
345   IN CONST  CHAR16            *VariableName,\r
346   IN CONST  EFI_GUID          *VendorGuid,\r
347   OUT VARIABLE_POINTER_TRACK  *PtrTrack\r
348   )\r
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
375     for (Count = 0; Count < IndexTable->Length; Count++) {\r
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
386     if (IndexTable->GoneThrough != 0) {\r
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
396     if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {\r
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
413       IndexTable->StartPtr  = GetStartPointer (VariableStoreHeader);\r
414       IndexTable->EndPtr    = GetEndPointer (VariableStoreHeader);\r
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
434       if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
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
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
483 EFI_STATUS\r
484 EFIAPI\r
485 PeiGetVariable (\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
493 {\r
494   VARIABLE_POINTER_TRACK  Variable;\r
495   UINTN                   VarDataSize;\r
496   EFI_STATUS              Status;\r
497   CONST EFI_PEI_SERVICES  **PeiServices;\r
498 \r
499   PeiServices = GetPeiServicesTablePointer ();\r
500   if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {\r
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
513   VarDataSize = DataSizeOfVariable (Variable.CurrPtr);\r
514   if (*DataSize >= VarDataSize) {\r
515     if (Data == NULL) {\r
516       return EFI_INVALID_PARAMETER;\r
517     }\r
518 \r
519     CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);\r
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
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
561 EFI_STATUS\r
562 EFIAPI\r
563 PeiGetNextVariableName (\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
569 {\r
570   VARIABLE_POINTER_TRACK  Variable;\r
571   UINTN                   VarNameSize;\r
572   EFI_STATUS              Status;\r
573   CONST EFI_PEI_SERVICES  **PeiServices;\r
574 \r
575   PeiServices = GetPeiServicesTablePointer ();\r
576   if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {\r
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
595         ASSERT (NameSizeOfVariable (Variable.CurrPtr) != 0);\r
596 \r
597         VarNameSize = (UINTN) NameSizeOfVariable (Variable.CurrPtr);\r
598         if (VarNameSize <= *VariableNameSize) {\r
599           CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);\r
600 \r
601           CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));\r
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