Home | History | Annotate | Download | only in HiiPack
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   IfrParse.c
     15 
     16 Abstract:
     17 
     18   Routines for parsing and managing HII IFR packs.
     19 
     20 --*/
     21 
     22 #include <stdio.h>
     23 #include <string.h>
     24 #include <stdlib.h>
     25 
     26 #include "Tiano.h"
     27 #include "EfiUtilityMsgs.h"
     28 #include "EfiInternalFormRepresentation.h"
     29 #include "Hii.h"
     30 #include "IfrParse.h"
     31 #include "HiiPack.h"
     32 
     33 typedef struct _VARIABLE_STORE_ENTRY {
     34   struct _VARIABLE_STORE_ENTRY  *Next;
     35   CHAR8                         VarName[MAX_VARIABLE_NAME];
     36   char                          *VarBuffer;
     37   int                           VarBufferSize;
     38   EFI_HII_VARIABLE_PACK         *VarPack;
     39   int                           VarPackSize;
     40 } VARIABLE_STORE_ENTRY;
     41 
     42 typedef STATUS (*IFR_PARSE_FUNCTION) (IFR_PARSE_CONTEXT * Context);
     43 
     44 typedef struct {
     45   INT8                *Name;
     46   INT32               Size;
     47   IFR_PARSE_FUNCTION  Parse;
     48 } IFR_PARSE_TABLE_ENTRY;
     49 
     50 static
     51 STATUS
     52 IfrParse01 (
     53   IFR_PARSE_CONTEXT *Context
     54   );
     55 static
     56 STATUS
     57 IfrParse02 (
     58   IFR_PARSE_CONTEXT *Context
     59   );
     60 static
     61 STATUS
     62 IfrParse03 (
     63   IFR_PARSE_CONTEXT *Context
     64   );
     65 static
     66 STATUS
     67 IfrParse05 (
     68   IFR_PARSE_CONTEXT *Context
     69   );
     70 static
     71 STATUS
     72 IfrParse06 (
     73   IFR_PARSE_CONTEXT *Context
     74   );
     75 static
     76 STATUS
     77 IfrParse07 (
     78   IFR_PARSE_CONTEXT *Context
     79   );
     80 static
     81 STATUS
     82 IfrParse08 (
     83   IFR_PARSE_CONTEXT *Context
     84   );
     85 static
     86 STATUS
     87 IfrParse09 (
     88   IFR_PARSE_CONTEXT *Context
     89   );
     90 static
     91 STATUS
     92 IfrParse0A (
     93   IFR_PARSE_CONTEXT *Context
     94   );
     95 static
     96 STATUS
     97 IfrParse0B (
     98   IFR_PARSE_CONTEXT *Context
     99   );
    100 static
    101 STATUS
    102 IfrParse0C (
    103   IFR_PARSE_CONTEXT *Context
    104   );
    105 static
    106 STATUS
    107 IfrParse0D (
    108   IFR_PARSE_CONTEXT *Context
    109   );
    110 static
    111 STATUS
    112 IfrParse0E (
    113   IFR_PARSE_CONTEXT *Context
    114   );
    115 static
    116 STATUS
    117 IfrParse0F (
    118   IFR_PARSE_CONTEXT *Context
    119   );
    120 static
    121 STATUS
    122 IfrParse10 (
    123   IFR_PARSE_CONTEXT *Context
    124   );
    125 static
    126 STATUS
    127 IfrParse11 (
    128   IFR_PARSE_CONTEXT *Context
    129   );
    130 static
    131 STATUS
    132 IfrParse12 (
    133   IFR_PARSE_CONTEXT *Context
    134   );
    135 static
    136 STATUS
    137 IfrParse13 (
    138   IFR_PARSE_CONTEXT *Context
    139   );
    140 static
    141 STATUS
    142 IfrParse14 (
    143   IFR_PARSE_CONTEXT *Context
    144   );
    145 static
    146 STATUS
    147 IfrParse15 (
    148   IFR_PARSE_CONTEXT *Context
    149   );
    150 static
    151 STATUS
    152 IfrParse16 (
    153   IFR_PARSE_CONTEXT *Context
    154   );
    155 static
    156 STATUS
    157 IfrParse17 (
    158   IFR_PARSE_CONTEXT *Context
    159   );
    160 static
    161 STATUS
    162 IfrParse18 (
    163   IFR_PARSE_CONTEXT *Context
    164   );
    165 static
    166 STATUS
    167 IfrParse19 (
    168   IFR_PARSE_CONTEXT *Context
    169   );
    170 static
    171 STATUS
    172 IfrParse1A (
    173   IFR_PARSE_CONTEXT *Context
    174   );
    175 static
    176 STATUS
    177 IfrParse1B (
    178   IFR_PARSE_CONTEXT *Context
    179   );
    180 static
    181 STATUS
    182 IfrParse1C (
    183   IFR_PARSE_CONTEXT *Context
    184   );
    185 static
    186 STATUS
    187 IfrParse1D (
    188   IFR_PARSE_CONTEXT *Context
    189   );
    190 static
    191 STATUS
    192 IfrParse1E (
    193   IFR_PARSE_CONTEXT *Context
    194   );
    195 static
    196 STATUS
    197 IfrParse1F (
    198   IFR_PARSE_CONTEXT *Context
    199   );
    200 static
    201 STATUS
    202 IfrParse20 (
    203   IFR_PARSE_CONTEXT *Context
    204   );
    205 static
    206 STATUS
    207 IfrParse21 (
    208   IFR_PARSE_CONTEXT *Context
    209   );
    210 static
    211 STATUS
    212 IfrParse22 (
    213   IFR_PARSE_CONTEXT *Context
    214   );
    215 static
    216 STATUS
    217 IfrParse23 (
    218   IFR_PARSE_CONTEXT *Context
    219   );
    220 static
    221 STATUS
    222 IfrParse24 (
    223   IFR_PARSE_CONTEXT *Context
    224   );
    225 static
    226 STATUS
    227 IfrParse25 (
    228   IFR_PARSE_CONTEXT *Context
    229   );
    230 static
    231 STATUS
    232 IfrParse26 (
    233   IFR_PARSE_CONTEXT *Context
    234   );
    235 static
    236 STATUS
    237 IfrParse27 (
    238   IFR_PARSE_CONTEXT *Context
    239   );
    240 static
    241 STATUS
    242 IfrParse28 (
    243   IFR_PARSE_CONTEXT *Context
    244   );
    245 static
    246 STATUS
    247 IfrParse29 (
    248   IFR_PARSE_CONTEXT *Context
    249   );
    250 static
    251 STATUS
    252 IfrParse2A (
    253   IFR_PARSE_CONTEXT *Context
    254   );
    255 
    256 static const IFR_PARSE_TABLE_ENTRY  mIfrParseTable[] = {
    257   {
    258     0,
    259     0,
    260     NULL
    261   },  // invalid
    262   {
    263     "EFI_IFR_FORM",
    264     sizeof (EFI_IFR_FORM),
    265     IfrParse01
    266   },
    267   {
    268     "EFI_IFR_SUBTITLE",
    269     sizeof (EFI_IFR_SUBTITLE),
    270     IfrParse02
    271   },
    272   {
    273     "EFI_IFR_TEXT",
    274     -6,
    275     IfrParse03
    276   },  // sizeof (EFI_IFR_TEXT) },
    277   {
    278     "unused 0x04 opcode",
    279     0,
    280     NULL
    281   },  // EFI_IFR_GRAPHIC_OP
    282   {
    283     "EFI_IFR_ONE_OF",
    284     sizeof (EFI_IFR_ONE_OF),
    285     IfrParse05
    286   },
    287   {
    288     "EFI_IFR_CHECK_BOX",
    289     sizeof (EFI_IFR_CHECK_BOX),
    290     IfrParse06
    291   },
    292   {
    293     "EFI_IFR_NUMERIC",
    294     sizeof (EFI_IFR_NUMERIC),
    295     IfrParse07
    296   },
    297   {
    298     "EFI_IFR_PASSWORD",
    299     sizeof (EFI_IFR_PASSWORD),
    300     IfrParse08
    301   },
    302   {
    303     "EFI_IFR_ONE_OF_OPTION",
    304     sizeof (EFI_IFR_ONE_OF_OPTION),
    305     IfrParse09
    306   },
    307   {
    308     "EFI_IFR_SUPPRESS",
    309     sizeof (EFI_IFR_SUPPRESS),
    310     IfrParse0A
    311   },
    312   {
    313     "EFI_IFR_END_FORM",
    314     sizeof (EFI_IFR_END_FORM),
    315     IfrParse0B
    316   },
    317   {
    318     "EFI_IFR_HIDDEN",
    319     sizeof (EFI_IFR_HIDDEN),
    320     IfrParse0C
    321   },
    322   {
    323     "EFI_IFR_END_FORM_SET",
    324     sizeof (EFI_IFR_END_FORM_SET),
    325     IfrParse0D
    326   },
    327   {
    328     "EFI_IFR_FORM_SET",
    329     sizeof (EFI_IFR_FORM_SET),
    330     IfrParse0E
    331   },
    332   {
    333     "EFI_IFR_REF",
    334     sizeof (EFI_IFR_REF),
    335     IfrParse0F
    336   },
    337   {
    338     "EFI_IFR_END_ONE_OF",
    339     sizeof (EFI_IFR_END_ONE_OF),
    340     IfrParse10
    341   },
    342   {
    343     "EFI_IFR_INCONSISTENT",
    344     sizeof (EFI_IFR_INCONSISTENT),
    345     IfrParse11
    346   },
    347   {
    348     "EFI_IFR_EQ_ID_VAL",
    349     sizeof (EFI_IFR_EQ_ID_VAL),
    350     IfrParse12
    351   },
    352   {
    353     "EFI_IFR_EQ_ID_ID",
    354     sizeof (EFI_IFR_EQ_ID_ID),
    355     IfrParse13
    356   },
    357   {
    358     "EFI_IFR_EQ_ID_LIST",
    359     -(int) (sizeof (EFI_IFR_EQ_ID_LIST)),
    360     IfrParse14
    361   },
    362   {
    363     "EFI_IFR_AND",
    364     sizeof (EFI_IFR_AND),
    365     IfrParse15
    366   },
    367   {
    368     "EFI_IFR_OR",
    369     sizeof (EFI_IFR_OR),
    370     IfrParse16
    371   },
    372   {
    373     "EFI_IFR_NOT",
    374     sizeof (EFI_IFR_NOT),
    375     IfrParse17
    376   },
    377   {
    378     "EFI_IFR_END_IF",
    379     sizeof (EFI_IFR_END_IF),
    380     IfrParse18
    381   },
    382   {
    383     "EFI_IFR_GRAYOUT",
    384     sizeof (EFI_IFR_GRAYOUT),
    385     IfrParse19
    386   },
    387   {
    388     "EFI_IFR_DATE",
    389     sizeof (EFI_IFR_DATE) / 3,
    390     IfrParse1A
    391   },
    392   {
    393     "EFI_IFR_TIME",
    394     sizeof (EFI_IFR_TIME) / 3,
    395     IfrParse1B
    396   },
    397   {
    398     "EFI_IFR_STRING",
    399     sizeof (EFI_IFR_STRING),
    400     IfrParse1C
    401   },
    402   {
    403     "EFI_IFR_LABEL",
    404     sizeof (EFI_IFR_LABEL),
    405     IfrParse1D
    406   },
    407   {
    408     "EFI_IFR_SAVE_DEFAULTS",
    409     sizeof (EFI_IFR_SAVE_DEFAULTS),
    410     IfrParse1E
    411   },
    412   {
    413     "EFI_IFR_RESTORE_DEFAULTS",
    414     sizeof (EFI_IFR_RESTORE_DEFAULTS),
    415     IfrParse1F
    416   },
    417   {
    418     "EFI_IFR_BANNER",
    419     sizeof (EFI_IFR_BANNER),
    420     IfrParse20
    421   },
    422   {
    423     "EFI_IFR_INVENTORY",
    424     sizeof (EFI_IFR_INVENTORY),
    425     IfrParse21
    426   },
    427   {
    428     "EFI_IFR_EQ_VAR_VAL_OP",
    429     sizeof (EFI_IFR_EQ_VAR_VAL),
    430     IfrParse22
    431   },
    432   {
    433     "EFI_IFR_ORDERED_LIST_OP",
    434     sizeof (EFI_IFR_ORDERED_LIST),
    435     IfrParse23
    436   },
    437   {
    438     "EFI_IFR_VARSTORE_OP",
    439     -(int) (sizeof (EFI_IFR_VARSTORE)),
    440     IfrParse24
    441   },
    442   {
    443     "EFI_IFR_VARSTORE_SELECT_OP",
    444     sizeof (EFI_IFR_VARSTORE_SELECT),
    445     IfrParse25
    446   },
    447   {
    448     "EFI_IFR_VARSTORE_SELECT_PAIR_OP",
    449     sizeof (EFI_IFR_VARSTORE_SELECT_PAIR),
    450     IfrParse26
    451   },
    452   {
    453     "EFI_IFR_TRUE",
    454     sizeof (EFI_IFR_TRUE),
    455     IfrParse27
    456   },
    457   {
    458     "EFI_IFR_FALSE",
    459     sizeof (EFI_IFR_FALSE),
    460     IfrParse28
    461   },
    462   {
    463     "EFI_IFR_GT",
    464     sizeof (EFI_IFR_GT),
    465     IfrParse29
    466   },
    467   {
    468     "EFI_IFR_GE",
    469     sizeof (EFI_IFR_GE),
    470     IfrParse2A
    471   },
    472 };
    473 #define PARSE_TABLE_ENTRIES (sizeof (mIfrParseTable) / sizeof (mIfrParseTable[0]))
    474 
    475 static
    476 STATUS
    477 GetVarStoreInfo (
    478   IFR_PARSE_CONTEXT   *Context,
    479   UINT16              VarId,
    480   EFI_GUID            **VarStoreGuid,
    481   char                **VarStoreName
    482   );
    483 
    484 static
    485 void
    486 FreeVarStores (
    487   VOID
    488   );
    489 
    490 static
    491 STATUS
    492 CreateVarStore (
    493   EFI_GUID *VarGuid,
    494   CHAR8    *VarName,
    495   int      VarStoreSize
    496   );
    497 
    498 static
    499 STATUS
    500 SetDefaults (
    501   IFR_PARSE_CONTEXT *Context,
    502   UINT32            MfgDefaults
    503   );
    504 
    505 //
    506 // Globals
    507 //
    508 static IFR_PARSE_CONTEXT            *mParseContext    = NULL;
    509 static VARIABLE_STORE_ENTRY         *mVariableStores  = NULL;
    510 static int                          BreakOnOpcodeTag  = 0;
    511 static int                          OpcodeTag         = 1;
    512 
    513 /*****************************************************************************/
    514 STATUS
    515 IfrParseCheck (
    516   char    *Buffer,
    517   long    BufferSize
    518   )
    519 /*++
    520 
    521 Routine Description:
    522 
    523   Check a buffer to ensure that is is parseable IFR
    524 
    525 Arguments:
    526 
    527   Buffer      - pointer to raw IFR bytes
    528   BufferSize  - size of IFR pointed to by Buffer
    529 
    530 Returns:
    531 
    532   STATUS_SUCCESS      if successful
    533   STATUS_ERROR        otherwise
    534 
    535 --*/
    536 {
    537   char              *Start;
    538 
    539   char              *End;
    540 
    541   char              *Pos;
    542   EFI_IFR_OP_HEADER *OpHeader;
    543   char              *FileName;
    544   FileName = "";
    545   //
    546   // Walk the list of IFR statements in the IFR pack
    547   //
    548   Start = Buffer;
    549   Pos   = Buffer;
    550   End   = Start + BufferSize;
    551   while ((Pos >= Start) && (Pos < End)) {
    552     OpHeader = (EFI_IFR_OP_HEADER *) Pos;
    553     //
    554     // Check range on size
    555     //
    556     if (Pos + OpHeader->Length > End) {
    557       Error (NULL, 0, 0, FileName, "invalid IFR opcode size at offset 0x%X", (int) Pos - (int) Start);
    558       return STATUS_ERROR;
    559     }
    560 
    561     if (OpHeader->Length == 0) {
    562       Error (NULL, 0, 0, FileName, "IFR opcode size=0 at offset 0x%X", (int) Pos - (int) Start);
    563       return STATUS_ERROR;
    564     }
    565     //
    566     // See if it's the END_FORMSET opcode
    567     //
    568     if (OpHeader->OpCode == EFI_IFR_END_FORM_SET_OP) {
    569       break;
    570     }
    571     //
    572     // Advance to next IFR statement/opcode
    573     //
    574     Pos += OpHeader->Length;
    575   }
    576 
    577   return STATUS_SUCCESS;
    578 }
    579 
    580 STATUS
    581 IfrParseInit (
    582   VOID
    583   )
    584 /*++
    585 
    586 Routine Description:
    587 
    588   Initialize this module for IFR pack parsing
    589 
    590 Arguments:
    591 
    592 Returns:
    593 
    594   STATUS_SUCCESS      always
    595 
    596 --*/
    597 {
    598   return STATUS_SUCCESS;
    599 }
    600 
    601 STATUS
    602 IfrParseEnd (
    603   VOID
    604   )
    605 /*++
    606 
    607 Routine Description:
    608 
    609   Free up memory allocated during IFR pack parsing done by this module
    610 
    611 Arguments:
    612   None
    613 
    614 Returns:
    615 
    616   STATUS_SUCCESS      always
    617 
    618 --*/
    619 {
    620   IFR_PARSE_CONTEXT *NextContext;
    621   IFR_PARSE_ENTRY   *NextEntry;
    622   //
    623   // Free up the memory from our parse contexts
    624   //
    625   while (mParseContext != NULL) {
    626     while (mParseContext->Ifr != NULL) {
    627       NextEntry = mParseContext->Ifr->Next;
    628       //
    629       // We pointed directly into the user buffer, rather than make
    630       // a copy, so don't free up the bytes.
    631       //
    632       free (mParseContext->Ifr);
    633       mParseContext->Ifr = NextEntry;
    634     }
    635 
    636     NextContext = mParseContext->Next;
    637     free (mParseContext->PackHeader);
    638     free (mParseContext);
    639     mParseContext = NextContext;
    640   }
    641 
    642   return STATUS_SUCCESS;
    643 }
    644 
    645 static
    646 void
    647 FreeVarStores (
    648   VOID
    649   )
    650 /*++
    651 
    652 Routine Description:
    653 
    654   GC_TODO: Add function description
    655 
    656 Arguments:
    657 
    658   None
    659 
    660 Returns:
    661 
    662   GC_TODO: add return values
    663 
    664 --*/
    665 {
    666   VARIABLE_STORE_ENTRY  *NextVarStore;
    667   //
    668   // Free up memory from our variable stores
    669   //
    670   while (mVariableStores != NULL) {
    671     if (mVariableStores->VarPack != NULL) {
    672       free (mVariableStores->VarPack);
    673     }
    674 
    675     NextVarStore = mVariableStores->Next;
    676     free (mVariableStores);
    677     mVariableStores = NextVarStore;
    678   }
    679 }
    680 
    681 /******************************************************************************
    682   FUNCTION: IfrParsePack()
    683 
    684   DESCRIPTION:  Given a pointer to an IFR pack, parse it to create a linked
    685     list of opcodes and relevant data required for later dumping.
    686 
    687 
    688 *******************************************************************************/
    689 STATUS
    690 IfrParsePack (
    691   int               Handle,
    692   EFI_HII_IFR_PACK  *PackHeader,
    693   EFI_GUID          *PackageGuid
    694   )
    695 /*++
    696 
    697 Routine Description:
    698 
    699   Given a pointer to an IFR pack, parse it to create a linked
    700   list of opcodes and relevant data required for later dumping.
    701 
    702 Arguments:
    703 
    704   Handle          - the handle number associated with this IFR pack. It
    705                     can be used later to retrieve more info on the particular
    706                     pack
    707   PackHeader      - pointer to IFR pack to parse
    708   PackageGuid     - on input, it comes from the HII data table entry for this pack.
    709                     On output, we'll return the IFR formset GUID.
    710 
    711 Returns:
    712 
    713   STATUS_SUCCESS      always
    714 
    715 --*/
    716 {
    717   EFI_IFR_OP_HEADER *OpHeader;
    718   IFR_PARSE_CONTEXT *Context;
    719   IFR_PARSE_CONTEXT *TempContext;
    720   IFR_PARSE_ENTRY   *IfrEntry;
    721   //
    722   // Initialize our context
    723   //
    724   Context = (IFR_PARSE_CONTEXT *) malloc (sizeof (IFR_PARSE_CONTEXT));
    725   if (Context == NULL) {
    726     Error (NULL, 0, 0, "memory allocation failure", NULL);
    727     return STATUS_ERROR;
    728   }
    729 
    730   memset ((void *) Context, 0, sizeof (IFR_PARSE_CONTEXT));
    731   //
    732   // Cache a copy of the input pack so the caller can free their copy
    733   //
    734   Context->PackHeader = (EFI_HII_IFR_PACK *) malloc (PackHeader->Header.Length);
    735   if (Context->PackHeader == NULL) {
    736     Error (NULL, 0, 0, "memory allocation failure", NULL);
    737     free (Context);
    738     return STATUS_ERROR;
    739   }
    740 
    741   memcpy (Context->PackHeader, PackHeader, PackHeader->Header.Length);
    742   Context->IfrBufferStart = (char *) (Context->PackHeader + 1);
    743   Context->CurrentPos     = Context->IfrBufferStart;
    744   Context->IfrBufferLen   = PackHeader->Header.Length - sizeof (EFI_HII_IFR_PACK);
    745   Context->Handle         = Handle;
    746   Context->FormsetGuid    = &Context->NullGuid;
    747   Context->PackageGuid    = *PackageGuid;
    748   //
    749   // Add it to the end of our list
    750   //
    751   if (mParseContext == NULL) {
    752     mParseContext = Context;
    753   } else {
    754     TempContext = mParseContext;
    755     while (TempContext->Next != NULL) {
    756       TempContext = TempContext->Next;
    757     }
    758 
    759     TempContext->Next = Context;
    760   }
    761   //
    762   // Walk the opcodes in the pack
    763   //
    764   while
    765   (
    766     (Context->CurrentPos >= Context->IfrBufferStart) &&
    767     (Context->CurrentPos < Context->IfrBufferStart + Context->IfrBufferLen)
    768   ) {
    769     OpHeader = (EFI_IFR_OP_HEADER *) Context->CurrentPos;
    770     //
    771     // Allocate a new IFR entry to put in our linked list, then
    772     // point directly to the caller's raw data.
    773     //
    774     IfrEntry = (IFR_PARSE_ENTRY *) malloc (sizeof (IFR_PARSE_ENTRY));
    775     if (IfrEntry == NULL) {
    776       Error (NULL, 0, 0, "memory allocation failure", NULL);
    777       free (Context->PackHeader);
    778       free (Context);
    779       return STATUS_ERROR;
    780     }
    781 
    782     memset ((void *) IfrEntry, 0, sizeof (IFR_PARSE_ENTRY));
    783     IfrEntry->Tag = ++OpcodeTag;
    784     if (OpcodeTag == BreakOnOpcodeTag) {
    785       EFI_BREAKPOINT ();
    786     }
    787 
    788     IfrEntry->RawIfrHeader = (EFI_IFR_OP_HEADER *) (Context->CurrentPos);
    789     //
    790     // Add this entry to our linked list. If it's not the first, then
    791     // forward the variable store settings from the previous entry.
    792     //
    793     if (Context->LastIfr != NULL) {
    794       IfrEntry->VarStoreGuid1 = Context->LastIfr->VarStoreGuid1;
    795       IfrEntry->VarStoreName1 = Context->LastIfr->VarStoreName1;
    796       IfrEntry->VarStoreGuid2 = Context->LastIfr->VarStoreGuid2;
    797       IfrEntry->VarStoreName2 = Context->LastIfr->VarStoreName2;
    798       Context->LastIfr->Next  = IfrEntry;
    799     } else {
    800       Context->Ifr = IfrEntry;
    801     }
    802 
    803     Context->LastIfr = IfrEntry;
    804     //
    805     // Switch on the opcode to parse it
    806     //
    807     if (OpHeader->OpCode < PARSE_TABLE_ENTRIES) {
    808       if (mIfrParseTable[OpHeader->OpCode].Parse != NULL) {
    809         mIfrParseTable[OpHeader->OpCode].Parse (Context);
    810       }
    811     } else {
    812       Error (
    813         NULL,
    814         0,
    815         0,
    816         "invalid opcode found in IFR",
    817         "offset=0x%X opcode=0x%02X",
    818         (int) OpHeader - (int) Context->PackHeader,
    819         (int) OpHeader->OpCode
    820         );
    821       free (IfrEntry);
    822       free (Context->PackHeader);
    823       free (Context);
    824       return STATUS_ERROR;
    825     }
    826     //
    827     // If it's the END_FORMSET opcode, then we're done
    828     //
    829     if (OpHeader->OpCode == EFI_IFR_END_FORM_SET_OP) {
    830       break;
    831     }
    832     //
    833     // Advance to next IFR statement/opcode
    834     //
    835     if (OpHeader->Length == 0) {
    836       Error (NULL, 0, 0, "0-length IFR opcode encountered", NULL);
    837       free (IfrEntry);
    838       free (Context->PackHeader);
    839       free (Context);
    840       return STATUS_ERROR;
    841     }
    842 
    843     Context->CurrentPos += OpHeader->Length;
    844   }
    845   //
    846   // Return the form GUID.
    847   //
    848   *PackageGuid = *Context->FormsetGuid;
    849   return STATUS_SUCCESS;
    850 }
    851 
    852 /******************************************************************************
    853   FUNCTION:  GetVarStoreInfo()
    854 
    855   DESCRIPTION:  IFR contains VARSTORE opcodes to specify where variable data
    856     for following opcodes is supposed to be stored. One VARSTORE statement
    857     allows you to specify the variable store GUID and a key, and another
    858     VARSTORE (select) allows you to specify the key of a VARSTORE statement.
    859     Given the key from a VARSTORE_SELECT statement, go find the corresponding
    860     VARSTORE statement with a matching key and return the varstore GUID and
    861     name. If key == 0, then the variable store is FormsetGuid."Setup"
    862 *******************************************************************************/
    863 static
    864 STATUS
    865 GetVarStoreInfo (
    866   IFR_PARSE_CONTEXT     *Context,
    867   UINT16                VarId,
    868   EFI_GUID              **VarStoreGuid,
    869   char                  **VarStoreName
    870   )
    871 /*++
    872 
    873 Routine Description:
    874 
    875   Get variable store information from an IFR pack for a given variable store ID.
    876 
    877 Arguments:
    878 
    879   Context       - pointer to IFR parse context
    880   VarId         - variable store ID referenced by IFR being parsed
    881   VarStoreGuid  - outgoing GUID of the variable store corresponding to VarId
    882   VarStoreName  - outgoing variable name of variable store corresponding to VarId
    883 
    884 Returns:
    885 
    886   STATUS_SUCCESS      - variable store with matching VarId found, and outoing GUID/Name are valid
    887   STATUS_ERROR        - otherwise
    888 
    889 --*/
    890 {
    891   IFR_PARSE_ENTRY   *Ptr;
    892   EFI_IFR_VARSTORE  *VarStore;
    893   if (Context == NULL) {
    894     return STATUS_ERROR;
    895   }
    896 
    897   //
    898   // Walk the entire IFR form and find a variable store opcode that
    899   // has a matching variable store ID.
    900   //
    901   for (Ptr = Context->Ifr; Ptr != NULL; Ptr = Ptr->Next) {
    902     if (Ptr->RawIfrHeader->OpCode == EFI_IFR_FORM_SET_OP) {
    903       if (VarId == 0) {
    904         *VarStoreGuid = &((EFI_IFR_FORM_SET *) (Ptr->RawIfrHeader))->Guid;
    905         *VarStoreName = DEFAULT_VARIABLE_NAME;
    906         return STATUS_SUCCESS;
    907       }
    908     } else if (Ptr->RawIfrHeader->OpCode == EFI_IFR_VARSTORE_OP) {
    909       //
    910       // See if it's a variable ID match
    911       //
    912       VarStore = (EFI_IFR_VARSTORE *) Ptr->RawIfrHeader;
    913       if (VarStore->VarId == VarId) {
    914         *VarStoreGuid = &VarStore->Guid;
    915         *VarStoreName = (char *) (VarStore + 1);
    916         return STATUS_SUCCESS;
    917       }
    918     }
    919   }
    920 
    921   return STATUS_ERROR;
    922 }
    923 
    924 STATUS
    925 IfrSetDefaults (
    926   int MfgDefaults
    927   )
    928 /*++
    929 
    930 Routine Description:
    931 
    932   Go through all the IFR forms we've parsed so far and create and set variable
    933   defaults.
    934 
    935 Arguments:
    936 
    937   MfgDefaults   - non-zero if manufacturing defaults are desired
    938 
    939 Returns:
    940 
    941   STATUS_SUCCESS      - always
    942 
    943 --*/
    944 {
    945   IFR_PARSE_CONTEXT *Context;
    946   //
    947   // First free up any variable stores we've created so far.
    948   //
    949   FreeVarStores ();
    950   for (Context = mParseContext; Context != NULL; Context = Context->Next) {
    951     //
    952     // Call our internal function to handle it
    953     //
    954     SetDefaults (Context, MfgDefaults);
    955   }
    956 
    957   return STATUS_SUCCESS;
    958 
    959 }
    960 
    961 /******************************************************************************/
    962 STATUS
    963 IfrGetIfrPack (
    964   int               Handle,
    965   EFI_HII_IFR_PACK  **PackHeader,
    966   EFI_GUID          *FormsetGuid
    967   )
    968 /*++
    969 
    970 Routine Description:
    971 
    972   GC_TODO: Add function description
    973 
    974 Arguments:
    975 
    976   Handle      - GC_TODO: add argument description
    977   PackHeader  - GC_TODO: add argument description
    978   FormsetGuid - GC_TODO: add argument description
    979 
    980 Returns:
    981 
    982   GC_TODO: add return values
    983 
    984 --*/
    985 {
    986   IFR_PARSE_CONTEXT *Context;
    987 
    988   for (Context = mParseContext; Context != NULL; Context = Context->Next) {
    989     if (Context->Handle == Handle) {
    990       *PackHeader = Context->PackHeader;
    991       memcpy (FormsetGuid, Context->FormsetGuid, sizeof (EFI_GUID));
    992       return STATUS_SUCCESS;
    993     }
    994   }
    995 
    996   return STATUS_ERROR;
    997 }
    998 
    999 STATUS
   1000 IfrReferencesVarPack (
   1001   int                   IfrHandle,
   1002   EFI_HII_VARIABLE_PACK *VarPack
   1003   )
   1004 /*++
   1005 
   1006 Routine Description:
   1007 
   1008   Given an HII handle number (which corrresponds to a handle number passed
   1009   in to IfrParsePack()), see if the IFR references the specified variable
   1010   pack.
   1011 
   1012 Arguments:
   1013 
   1014   IfrHandle   - handle number for the IFR pack to check (passed to IfrParsePack())
   1015   VarPack     - variable pack to check to see if the IFR references
   1016 
   1017 Returns:
   1018 
   1019   STATUS_SUCCESS      if the IFR on the given handle references the variable pack
   1020   STATUS_WARNING      the IFR does not reference the variable pack
   1021   STATUS_ERROR        invalid IFR handle
   1022 
   1023 --*/
   1024 {
   1025   IFR_PARSE_CONTEXT *Context;
   1026   char              VarName[MAX_VARIABLE_NAME];
   1027   IFR_PARSE_ENTRY   *ParseEntry;
   1028 
   1029   for (Context = mParseContext; Context != NULL; Context = Context->Next) {
   1030     if (Context->Handle == IfrHandle) {
   1031       //
   1032       // Create an ASCII version of the variable name, since that's what is
   1033       // referenced in IFR.
   1034       //
   1035       sprintf (VarName, "%S", (CHAR16 *) (VarPack + 1));
   1036       //
   1037       // Walk all the opcodes and see if the IFR references this variable pack
   1038       //
   1039       for (ParseEntry = Context->Ifr; ParseEntry != NULL; ParseEntry = ParseEntry->Next) {
   1040         //
   1041         // Check for Name.Guid match for primary IFR variable store
   1042         //
   1043         if ((strcmp (VarName, ParseEntry->VarStoreName1) == 0) &&
   1044             (memcmp (&VarPack->VariableGuid, ParseEntry->VarStoreGuid1, sizeof (EFI_GUID)) == 0)
   1045             ) {
   1046           return STATUS_SUCCESS;
   1047         }
   1048         //
   1049         // Check for Name.Guid match for secondary IFR variable store
   1050         //
   1051         if ((ParseEntry->VarStoreName2 != NULL) &&
   1052             (strcmp (VarName, ParseEntry->VarStoreName2) == 0) &&
   1053             (memcmp (&VarPack->VariableGuid, ParseEntry->VarStoreGuid2, sizeof (EFI_GUID)) == 0)
   1054             ) {
   1055           return STATUS_SUCCESS;
   1056         }
   1057       }
   1058 
   1059       return STATUS_WARNING;
   1060     }
   1061   }
   1062 
   1063   return STATUS_ERROR;
   1064 }
   1065 
   1066 STATUS
   1067 IfrGetVarPack (
   1068   int                     VarIndex,
   1069   EFI_HII_VARIABLE_PACK   **VarPack
   1070   )
   1071 /*++
   1072 
   1073 Routine Description:
   1074 
   1075   Get the variable defaults. It is expected that the caller
   1076   called IfrSetDefaults() previously to walk all the IFR forms we know about
   1077   and create and initialize default values.
   1078 
   1079 Arguments:
   1080 
   1081   VarIndex - a 0-based index into all the variable stores we know about
   1082   VarPack  - outgoing pointer to a variable pack
   1083 
   1084 Returns:
   1085 
   1086   STATUS_ERROR    - VarIndex exceeds the number of variable packs we know of
   1087   STATUS_SUCCESS  - otherwise
   1088 
   1089 --*/
   1090 {
   1091   VARIABLE_STORE_ENTRY  *Entry;
   1092   //
   1093   // Initialize outgoing parameters
   1094   //
   1095   *VarPack = NULL;
   1096   for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {
   1097     if (VarIndex == 0) {
   1098       *VarPack = Entry->VarPack;
   1099       return STATUS_SUCCESS;
   1100     }
   1101 
   1102     VarIndex--;
   1103   }
   1104 
   1105   return STATUS_ERROR;
   1106 }
   1107 
   1108 static
   1109 STATUS
   1110 SetVariableValue (
   1111   EFI_GUID    *VarGuid,
   1112   char        *VarName,
   1113   int         VarOffset,
   1114   int         VarSize,
   1115   void        *VarValue
   1116   )
   1117 /*++
   1118 
   1119 Routine Description:
   1120 
   1121   Given a variable GUID.Name, offset, size, and value, set the bytes in
   1122   the variable to the provided value.
   1123 
   1124 Arguments:
   1125   VarGuid           - GUID of variable to set
   1126   VarName           - name of variable to set
   1127   VarOffset         - byte offset into the variable store
   1128   VarSize           - size of the value in the variable store (in bytes)
   1129   VarValue          - pointer to buffer containing the value to set
   1130 
   1131 Returns:
   1132 
   1133 
   1134 --*/
   1135 {
   1136   VARIABLE_STORE_ENTRY  *Entry;
   1137   char                  *Src;
   1138   char                  *Dest;
   1139   //
   1140   // Go through our list of variable stores to find the match
   1141   //
   1142   for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {
   1143     if (memcmp (VarGuid, &Entry->VarPack->VariableGuid, sizeof (EFI_GUID)) == 0) {
   1144       if (strcmp (VarName, Entry->VarName) == 0) {
   1145         //
   1146         // Found match -- check offset. If it's beyond the size of the variable store
   1147         // buffer, then return a warning. Note that date-time can be beyond the
   1148         // end of the varstore, which is ok.
   1149         //
   1150         if (VarOffset + VarSize <= Entry->VarBufferSize) {
   1151           //
   1152           // Stuff the data
   1153           //
   1154           Dest  = Entry->VarBuffer + VarOffset;
   1155           Src   = (char *) VarValue;
   1156           while (VarSize > 0) {
   1157             *Dest = *Src;
   1158             Src++;
   1159             Dest++;
   1160             VarSize--;
   1161           }
   1162 
   1163           return STATUS_SUCCESS;
   1164         }
   1165 
   1166         return STATUS_WARNING;
   1167       }
   1168     }
   1169   }
   1170 
   1171   return STATUS_ERROR;
   1172 }
   1173 
   1174 static
   1175 STATUS
   1176 SetDefaults (
   1177   IFR_PARSE_CONTEXT *Context,
   1178   UINT32            MfgDefaults
   1179   )
   1180 /*++
   1181 
   1182 Routine Description:
   1183 
   1184   Set variable defaults by walking a single IFR form.
   1185 
   1186 Arguments:
   1187 
   1188   Context     - Pointer to the IFR context.
   1189   MfgDefaults - Number of Mfg defaults
   1190 
   1191 Returns:
   1192 
   1193   EFI_INVALID_PARAMETER - arguments to function are invalid
   1194   STATUS_SUCCESS        - function executed successfully
   1195 
   1196 --*/
   1197 {
   1198   int                   Size;
   1199   int                   CachedVarOffset;
   1200   int                   CachedVarSize;
   1201   int                   OrderedList;
   1202   IFR_PARSE_ENTRY       *SavedParseEntry;
   1203   EFI_IFR_CHECK_BOX     *IfrCheckBox;
   1204   EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
   1205   EFI_IFR_NUMERIC       *IfrNumeric;
   1206   STATUS                Status;
   1207   char                  ZeroByte;
   1208 
   1209   //
   1210   // Walk the opcodes to set default values and stuff them into the variable stores
   1211   //
   1212 
   1213   if (Context == NULL) {
   1214     return EFI_INVALID_PARAMETER;
   1215   }
   1216   Status              = STATUS_SUCCESS;
   1217   Context->CurrentIfr = Context->Ifr;
   1218   SavedParseEntry     = NULL;
   1219   OrderedList         = 0;
   1220   CachedVarOffset     = 0;
   1221   CachedVarSize       = 0;
   1222   ZeroByte            = 0;
   1223 
   1224   while (Context->CurrentIfr != NULL) {
   1225     if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_FORM_SET_OP) {
   1226       //
   1227       // Formset opcode -- create a variable pack
   1228       //
   1229       Status = CreateVarStore (
   1230                 &((EFI_IFR_FORM_SET *) (Context->CurrentIfr->RawIfrHeader))->Guid,
   1231                 DEFAULT_VARIABLE_NAME,
   1232                 ((EFI_IFR_FORM_SET *) (Context->CurrentIfr->RawIfrHeader))->NvDataSize
   1233                 );
   1234     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_VARSTORE_OP) {
   1235       //
   1236       // Variable store opcode -- create a variable pack
   1237       //
   1238       Status = CreateVarStore (
   1239                 &((EFI_IFR_VARSTORE *) (Context->CurrentIfr->RawIfrHeader))->Guid,
   1240                 (char *) Context->CurrentIfr->RawIfrHeader + sizeof (EFI_IFR_VARSTORE),
   1241                 ((EFI_IFR_VARSTORE *) (Context->CurrentIfr->RawIfrHeader))->Size
   1242                 );
   1243     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ONE_OF_OP) {
   1244       //
   1245       // Need this parse context later when we find the default ONE_OF_OPTION.
   1246       // Clear out the variable store first, so that we're covered if someone
   1247       // has two one-of opcode that operate on the same data.
   1248       // So "last one wins" is the behavior.
   1249       //
   1250       OrderedList     = 0;
   1251       SavedParseEntry = Context->CurrentIfr;
   1252       CachedVarOffset = ((EFI_IFR_ONE_OF *) Context->CurrentIfr->RawIfrHeader)->QuestionId;
   1253       CachedVarSize   = ((EFI_IFR_ONE_OF *) Context->CurrentIfr->RawIfrHeader)->Width;
   1254     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ORDERED_LIST_OP) {
   1255       //
   1256       // Need this parse context later as we parse the ONE_OF_OP's in the ordered list
   1257       //
   1258       OrderedList     = 1;
   1259       SavedParseEntry = Context->CurrentIfr;
   1260       CachedVarOffset = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->QuestionId;
   1261       CachedVarSize   = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->MaxEntries;
   1262 
   1263       while (CachedVarSize > 0) {
   1264         Status = SetVariableValue (
   1265                   SavedParseEntry->VarStoreGuid1, // GUID of variable store to write
   1266                   SavedParseEntry->VarStoreName1, // name of variable store to write
   1267                   CachedVarOffset,                // offset into variable store
   1268                   1,                              // variable data size
   1269                   (void *) &ZeroByte
   1270                   );
   1271         //
   1272         // variable value
   1273         //
   1274         CachedVarSize--;
   1275         CachedVarOffset++;
   1276       }
   1277 
   1278       CachedVarOffset = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->QuestionId;
   1279       CachedVarSize   = 1;
   1280       //
   1281       // ((EFI_IFR_ORDERED_LIST *)Context->CurrentIfr->RawIfrHeader)->Width;
   1282       //
   1283     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ONE_OF_OPTION_OP) {
   1284       IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) Context->CurrentIfr->RawIfrHeader;
   1285       //
   1286       // If we're in an ordered list, then copy the value to the data store
   1287       //
   1288       if (OrderedList) {
   1289         Status = SetVariableValue (
   1290                   SavedParseEntry->VarStoreGuid1, // GUID of variable store to write
   1291                   SavedParseEntry->VarStoreName1, // name of variable store to write
   1292                   CachedVarOffset,                // offset into variable store
   1293                   1,                              // variable data size
   1294                   (void *) &IfrOneOfOption->Value
   1295                   );
   1296         //
   1297         // variable value
   1298         //
   1299         // Advance the offset for the next ordered list item
   1300         //
   1301         CachedVarOffset += CachedVarSize;
   1302       } else {
   1303         //
   1304         // ONE-OF list. See if the default flag is set (provided we're not doing mfg defaults)
   1305         //
   1306         if (!MfgDefaults) {
   1307           if (IfrOneOfOption->Flags & EFI_IFR_FLAG_DEFAULT) {
   1308             Status = SetVariableValue (
   1309                       SavedParseEntry->VarStoreGuid1, // GUID of variable store to write
   1310                       SavedParseEntry->VarStoreName1, // name of variable store to write
   1311                       CachedVarOffset,                // offset into variable store
   1312                       CachedVarSize,                  // variable data size
   1313                       &IfrOneOfOption->Value
   1314                       );
   1315             //
   1316             // variable value
   1317             //
   1318           }
   1319         } else {
   1320           if (IfrOneOfOption->Flags & EFI_IFR_FLAG_MANUFACTURING) {
   1321             Status = SetVariableValue (
   1322                       SavedParseEntry->VarStoreGuid1, // GUID of variable store to write
   1323                       SavedParseEntry->VarStoreName1, // name of variable store to write
   1324                       CachedVarOffset,                // offset into variable store
   1325                       CachedVarSize,                  // variable data size
   1326                       &IfrOneOfOption->Value
   1327                       );
   1328             //
   1329             // variable value
   1330             //
   1331           }
   1332         }
   1333       }
   1334     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_CHECKBOX_OP) {
   1335       //
   1336       // If we're saving defaults, and the default flag is set, or we're saving
   1337       // manufacturing defaults and the manufacturing flag is set, then save a 1.
   1338       // By default the varstore buffer is cleared, so we don't need to save a 0 ever.
   1339       //
   1340       IfrCheckBox = (EFI_IFR_CHECK_BOX *) Context->CurrentIfr->RawIfrHeader;
   1341       if (((MfgDefaults == 0) && (IfrCheckBox->Flags & EFI_IFR_FLAG_DEFAULT)) ||
   1342           ((MfgDefaults != 0) && (IfrCheckBox->Flags & EFI_IFR_FLAG_MANUFACTURING))
   1343           ) {
   1344         Size = 1;
   1345         Status = SetVariableValue (
   1346                   Context->CurrentIfr->VarStoreGuid1, // GUID of variable store to write
   1347                   Context->CurrentIfr->VarStoreName1, // name of variable store to write
   1348                   IfrCheckBox->QuestionId,            // offset into variable store
   1349                   IfrCheckBox->Width,                 // variable data size
   1350                   (void *) &Size
   1351                   );
   1352         //
   1353         // variable value
   1354         //
   1355       }
   1356     } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_NUMERIC_OP) {
   1357       IfrNumeric = (EFI_IFR_NUMERIC *) Context->CurrentIfr->RawIfrHeader;
   1358       Status = SetVariableValue (
   1359                 Context->CurrentIfr->VarStoreGuid1, // GUID of variable store to write
   1360                 Context->CurrentIfr->VarStoreName1, // name of variable store to write
   1361                 IfrNumeric->QuestionId,             // offset into variable store
   1362                 IfrNumeric->Width,                  // variable data size
   1363                 (void *) &IfrNumeric->Default
   1364                 );
   1365       //
   1366       // variable value
   1367       //
   1368     }
   1369 
   1370     Context->CurrentIfr = Context->CurrentIfr->Next;
   1371   }
   1372 
   1373   return STATUS_SUCCESS;
   1374 }
   1375 
   1376 static
   1377 STATUS
   1378 CreateVarStore (
   1379   EFI_GUID  *VarGuid,
   1380   CHAR8     *VarName,
   1381   int       VarStoreSize
   1382   )
   1383 /*++
   1384 
   1385 Routine Description:
   1386 
   1387   Given a variable GUID.Name and the size of the variable store, allocate
   1388   storage for maintaining the variable value.
   1389 
   1390 Arguments:
   1391 
   1392   VarGuid - GUID for a variable
   1393   VarName - Name of the variable
   1394   VarStoreSize - size of the variable store
   1395 
   1396 Returns:
   1397 
   1398   STATUS_ERROR   - problem with storage allocation
   1399   STATUS_SUCCESS - function executed successfully
   1400 
   1401 --*/
   1402 {
   1403   VARIABLE_STORE_ENTRY  *Entry;
   1404 
   1405   VARIABLE_STORE_ENTRY  *TempEntry;
   1406   int                   PackSize;
   1407   int                   VarNameLen;
   1408   //
   1409   // If the variable store size is zero, then do nothing. This could be valid
   1410   // if variable steering is used in the IFR such that FormsetGUID."Setup" variable
   1411   // store is never used.
   1412   //
   1413   // OPEN: What about a form that only has a time/date question? Then if some other
   1414   // function called SetDefaults(), attempting to set time/date would result in an
   1415   // error in the SetVarValue() function.
   1416   //
   1417    if (VarStoreSize == 0) {
   1418     return STATUS_SUCCESS;
   1419    }
   1420   //
   1421   // Go through our list of variable stores and see if we've already created one
   1422   // for this Guid.Name. If so, check the size and return. Otherwise create
   1423   // one and add it to the list.
   1424   //
   1425   for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {
   1426     if (memcmp (VarGuid, &Entry->VarPack->VariableGuid, sizeof (EFI_GUID)) == 0) {
   1427       if (strcmp (VarName, Entry->VarName) == 0) {
   1428         //
   1429         // Already have one. Check size.
   1430         //
   1431         if (Entry->VarBufferSize != VarStoreSize) {
   1432           Error (NULL, 0, 0, "mismatched variable store size between two formsets", VarName);
   1433           return STATUS_ERROR;
   1434         }
   1435 
   1436         return STATUS_SUCCESS;
   1437       }
   1438     }
   1439   }
   1440   //
   1441   // Create a new one.
   1442   //
   1443   Entry = (VARIABLE_STORE_ENTRY *) malloc (sizeof (VARIABLE_STORE_ENTRY));
   1444   if (Entry == NULL) {
   1445     Error (NULL, 0, 0, "memory allocation failure", NULL);
   1446     return STATUS_ERROR;
   1447   }
   1448 
   1449   memset ((void *) Entry, 0, sizeof (VARIABLE_STORE_ENTRY));
   1450   //
   1451   // Compute size of the varpack
   1452   //
   1453   VarNameLen      = strlen (VarName) + 1;
   1454   PackSize        = sizeof (EFI_HII_VARIABLE_PACK) + VarNameLen * sizeof (CHAR16) + VarStoreSize;
   1455   Entry->VarPack  = (EFI_HII_VARIABLE_PACK *) malloc (PackSize);
   1456   if (Entry->VarPack == NULL) {
   1457     Error (NULL, 0, 0, "memory allocation failure", NULL);
   1458     free (Entry);
   1459     return STATUS_ERROR;
   1460   }
   1461 
   1462   Entry->VarPack->Header.Length       = PackSize;
   1463   Entry->VarPack->Header.Type         = EFI_HII_VARIABLE;
   1464   Entry->VarPack->VariableNameLength  = VarNameLen * sizeof (CHAR16);
   1465   Entry->VarName[MAX_VARIABLE_NAME - 1] = 0;
   1466   strncpy (Entry->VarName, VarName, MAX_VARIABLE_NAME - 1);
   1467 #ifdef USE_VC8
   1468   swprintf ((CHAR16 *) (Entry->VarPack + 1), (strlen (VarName) + 1) * sizeof (CHAR16), L"%S", VarName);
   1469 #else
   1470   swprintf ((CHAR16 *) (Entry->VarPack + 1), L"%S", VarName);
   1471 #endif
   1472   memcpy (&Entry->VarPack->VariableGuid, VarGuid, sizeof (EFI_GUID));
   1473   //
   1474   // Point VarBuffer into the allocated buffer (for convenience)
   1475   //
   1476   Entry->VarBuffer = (char *) Entry->VarPack + sizeof (EFI_HII_VARIABLE_PACK) + VarNameLen * sizeof (CHAR16);
   1477   memset ((void *) Entry->VarBuffer, 0, VarStoreSize);
   1478   Entry->VarBufferSize = VarStoreSize;
   1479   //
   1480   // Add this new varstore to our list
   1481   //
   1482   if (mVariableStores == NULL) {
   1483     mVariableStores = Entry;
   1484   } else {
   1485     for (TempEntry = mVariableStores; TempEntry->Next != NULL; TempEntry = TempEntry->Next)
   1486       ;
   1487     TempEntry->Next = Entry;
   1488   }
   1489   return STATUS_SUCCESS;
   1490 }
   1491 
   1492 /******************************************************************************/
   1493 
   1494 /*++
   1495 
   1496 Routine Description:
   1497 
   1498   The following IfrParseXX() functions are used to parse an IFR opcode numbered
   1499   XX via a dispatch table.
   1500 
   1501 Arguments:
   1502 
   1503   Context - IFR parsing context into which pertinent data for the
   1504             current opcode can be saved. Context->LastIfr->RawIfrHeader points to
   1505             the raw IFR bytes currently being parsed.
   1506 
   1507 Returns:
   1508 
   1509   STATUS_SUCCESS  - always
   1510 
   1511 --*/
   1512 
   1513 /*******************************************************************************/
   1514 static
   1515 STATUS
   1516 IfrParse01 (
   1517   IFR_PARSE_CONTEXT *Context
   1518   )
   1519 /*++
   1520 
   1521 Routine Description:
   1522 
   1523   GC_TODO: Add function description
   1524 
   1525 Arguments:
   1526 
   1527   Context - GC_TODO: add argument description
   1528 
   1529 Returns:
   1530 
   1531   GC_TODO: add return values
   1532 
   1533 --*/
   1534 {
   1535   return STATUS_SUCCESS;
   1536 }
   1537 
   1538 static
   1539 STATUS
   1540 IfrParse02 (
   1541   IFR_PARSE_CONTEXT *Context
   1542   )
   1543 /*++
   1544 
   1545 Routine Description:
   1546 
   1547   GC_TODO: Add function description
   1548 
   1549 Arguments:
   1550 
   1551   Context - GC_TODO: add argument description
   1552 
   1553 Returns:
   1554 
   1555   GC_TODO: add return values
   1556 
   1557 --*/
   1558 {
   1559   return STATUS_SUCCESS;
   1560 }
   1561 
   1562 static
   1563 STATUS
   1564 IfrParse03 (
   1565   IFR_PARSE_CONTEXT *Context
   1566   )
   1567 /*++
   1568 
   1569 Routine Description:
   1570 
   1571   GC_TODO: Add function description
   1572 
   1573 Arguments:
   1574 
   1575   Context - GC_TODO: add argument description
   1576 
   1577 Returns:
   1578 
   1579   GC_TODO: add return values
   1580 
   1581 --*/
   1582 {
   1583   return STATUS_SUCCESS;
   1584 }
   1585 //
   1586 // Parse the IFR EFI_IFR_ONE_OF opcode.
   1587 //
   1588 static
   1589 STATUS
   1590 IfrParse05 (
   1591   IFR_PARSE_CONTEXT *Context
   1592   )
   1593 /*++
   1594 
   1595 Routine Description:
   1596 
   1597   GC_TODO: Add function description
   1598 
   1599 Arguments:
   1600 
   1601   Context - GC_TODO: add argument description
   1602 
   1603 Returns:
   1604 
   1605   GC_TODO: add return values
   1606 
   1607 --*/
   1608 {
   1609   return STATUS_SUCCESS;
   1610 }
   1611 
   1612 static
   1613 STATUS
   1614 IfrParse06 (
   1615   IFR_PARSE_CONTEXT *Context
   1616   )
   1617 /*++
   1618 
   1619 Routine Description:
   1620 
   1621   GC_TODO: Add function description
   1622 
   1623 Arguments:
   1624 
   1625   Context - GC_TODO: add argument description
   1626 
   1627 Returns:
   1628 
   1629   GC_TODO: add return values
   1630 
   1631 --*/
   1632 {
   1633   return STATUS_SUCCESS;
   1634 }
   1635 
   1636 static
   1637 STATUS
   1638 IfrParse07 (
   1639   IFR_PARSE_CONTEXT *Context
   1640   )
   1641 /*++
   1642 
   1643 Routine Description:
   1644 
   1645   GC_TODO: Add function description
   1646 
   1647 Arguments:
   1648 
   1649   Context - GC_TODO: add argument description
   1650 
   1651 Returns:
   1652 
   1653   GC_TODO: add return values
   1654 
   1655 --*/
   1656 {
   1657   return STATUS_SUCCESS;
   1658 }
   1659 
   1660 static
   1661 STATUS
   1662 IfrParse08 (
   1663   IFR_PARSE_CONTEXT *Context
   1664   )
   1665 /*++
   1666 
   1667 Routine Description:
   1668 
   1669   GC_TODO: Add function description
   1670 
   1671 Arguments:
   1672 
   1673   Context - GC_TODO: add argument description
   1674 
   1675 Returns:
   1676 
   1677   GC_TODO: add return values
   1678 
   1679 --*/
   1680 {
   1681   return STATUS_SUCCESS;
   1682 }
   1683 
   1684 static
   1685 STATUS
   1686 IfrParse09 (
   1687   IFR_PARSE_CONTEXT *Context
   1688   )
   1689 /*++
   1690 
   1691 Routine Description:
   1692 
   1693   GC_TODO: Add function description
   1694 
   1695 Arguments:
   1696 
   1697   Context - GC_TODO: add argument description
   1698 
   1699 Returns:
   1700 
   1701   GC_TODO: add return values
   1702 
   1703 --*/
   1704 {
   1705   return STATUS_SUCCESS;
   1706 }
   1707 
   1708 static
   1709 STATUS
   1710 IfrParse0A (
   1711   IFR_PARSE_CONTEXT *Context
   1712   )
   1713 /*++
   1714 
   1715 Routine Description:
   1716 
   1717   GC_TODO: Add function description
   1718 
   1719 Arguments:
   1720 
   1721   Context - GC_TODO: add argument description
   1722 
   1723 Returns:
   1724 
   1725   GC_TODO: add return values
   1726 
   1727 --*/
   1728 {
   1729   return STATUS_SUCCESS;
   1730 }
   1731 
   1732 static
   1733 STATUS
   1734 IfrParse0B (
   1735   IFR_PARSE_CONTEXT *Context
   1736   )
   1737 /*++
   1738 
   1739 Routine Description:
   1740 
   1741   GC_TODO: Add function description
   1742 
   1743 Arguments:
   1744 
   1745   Context - GC_TODO: add argument description
   1746 
   1747 Returns:
   1748 
   1749   GC_TODO: add return values
   1750 
   1751 --*/
   1752 {
   1753   return STATUS_SUCCESS;
   1754 }
   1755 
   1756 static
   1757 STATUS
   1758 IfrParse0C (
   1759   IFR_PARSE_CONTEXT *Context
   1760   )
   1761 /*++
   1762 
   1763 Routine Description:
   1764 
   1765   GC_TODO: Add function description
   1766 
   1767 Arguments:
   1768 
   1769   Context - GC_TODO: add argument description
   1770 
   1771 Returns:
   1772 
   1773   GC_TODO: add return values
   1774 
   1775 --*/
   1776 {
   1777   return STATUS_SUCCESS;
   1778 }
   1779 
   1780 static
   1781 STATUS
   1782 IfrParse0D (
   1783   IFR_PARSE_CONTEXT *Context
   1784   )
   1785 /*++
   1786 
   1787 Routine Description:
   1788 
   1789   GC_TODO: Add function description
   1790 
   1791 Arguments:
   1792 
   1793   Context - GC_TODO: add argument description
   1794 
   1795 Returns:
   1796 
   1797   GC_TODO: add return values
   1798 
   1799 --*/
   1800 {
   1801   return STATUS_SUCCESS;
   1802 }
   1803 
   1804 static
   1805 STATUS
   1806 IfrParse0E (
   1807   IFR_PARSE_CONTEXT *Context
   1808   )
   1809 /*++
   1810 
   1811 Routine Description:
   1812 
   1813   GC_TODO: Add function description
   1814 
   1815 Arguments:
   1816 
   1817   Context - GC_TODO: add argument description
   1818 
   1819 Returns:
   1820 
   1821   GC_TODO: add return values
   1822 
   1823 --*/
   1824 {
   1825   EFI_IFR_FORM_SET  *Op;
   1826   Op  = (EFI_IFR_FORM_SET *) Context->LastIfr->RawIfrHeader;
   1827   Context->LastIfr->VarStoreGuid1 = &Op->Guid;
   1828   Context->LastIfr->VarStoreName1 = "Setup";
   1829   Context->FormsetGuid            = &Op->Guid;
   1830   return STATUS_SUCCESS;
   1831 }
   1832 
   1833 static
   1834 STATUS
   1835 IfrParse0F (
   1836   IFR_PARSE_CONTEXT *Context
   1837   )
   1838 /*++
   1839 
   1840 Routine Description:
   1841 
   1842   GC_TODO: Add function description
   1843 
   1844 Arguments:
   1845 
   1846   Context - GC_TODO: add argument description
   1847 
   1848 Returns:
   1849 
   1850   GC_TODO: add return values
   1851 
   1852 --*/
   1853 {
   1854   return STATUS_SUCCESS;
   1855 }
   1856 
   1857 static
   1858 STATUS
   1859 IfrParse10 (
   1860   IFR_PARSE_CONTEXT *Context
   1861   )
   1862 /*++
   1863 
   1864 Routine Description:
   1865 
   1866   GC_TODO: Add function description
   1867 
   1868 Arguments:
   1869 
   1870   Context - GC_TODO: add argument description
   1871 
   1872 Returns:
   1873 
   1874   GC_TODO: add return values
   1875 
   1876 --*/
   1877 {
   1878   return STATUS_SUCCESS;
   1879 }
   1880 
   1881 static
   1882 STATUS
   1883 IfrParse11 (
   1884   IFR_PARSE_CONTEXT *Context
   1885   )
   1886 /*++
   1887 
   1888 Routine Description:
   1889 
   1890   GC_TODO: Add function description
   1891 
   1892 Arguments:
   1893 
   1894   Context - GC_TODO: add argument description
   1895 
   1896 Returns:
   1897 
   1898   GC_TODO: add return values
   1899 
   1900 --*/
   1901 {
   1902   return STATUS_SUCCESS;
   1903 }
   1904 
   1905 static
   1906 STATUS
   1907 IfrParse12 (
   1908   IFR_PARSE_CONTEXT *Context
   1909   )
   1910 /*++
   1911 
   1912 Routine Description:
   1913 
   1914   GC_TODO: Add function description
   1915 
   1916 Arguments:
   1917 
   1918   Context - GC_TODO: add argument description
   1919 
   1920 Returns:
   1921 
   1922   GC_TODO: add return values
   1923 
   1924 --*/
   1925 {
   1926   return STATUS_SUCCESS;
   1927 }
   1928 
   1929 static
   1930 STATUS
   1931 IfrParse13 (
   1932   IFR_PARSE_CONTEXT *Context
   1933   )
   1934 /*++
   1935 
   1936 Routine Description:
   1937 
   1938   GC_TODO: Add function description
   1939 
   1940 Arguments:
   1941 
   1942   Context - GC_TODO: add argument description
   1943 
   1944 Returns:
   1945 
   1946   GC_TODO: add return values
   1947 
   1948 --*/
   1949 {
   1950   return STATUS_SUCCESS;
   1951 }
   1952 
   1953 static
   1954 STATUS
   1955 IfrParse14 (
   1956   IFR_PARSE_CONTEXT *Context
   1957   )
   1958 /*++
   1959 
   1960 Routine Description:
   1961 
   1962   GC_TODO: Add function description
   1963 
   1964 Arguments:
   1965 
   1966   Context - GC_TODO: add argument description
   1967 
   1968 Returns:
   1969 
   1970   GC_TODO: add return values
   1971 
   1972 --*/
   1973 {
   1974   return STATUS_SUCCESS;
   1975 }
   1976 
   1977 static
   1978 STATUS
   1979 IfrParse15 (
   1980   IFR_PARSE_CONTEXT *Context
   1981   )
   1982 /*++
   1983 
   1984 Routine Description:
   1985 
   1986   GC_TODO: Add function description
   1987 
   1988 Arguments:
   1989 
   1990   Context - GC_TODO: add argument description
   1991 
   1992 Returns:
   1993 
   1994   GC_TODO: add return values
   1995 
   1996 --*/
   1997 {
   1998   return STATUS_SUCCESS;
   1999 }
   2000 
   2001 static
   2002 STATUS
   2003 IfrParse16 (
   2004   IFR_PARSE_CONTEXT *Context
   2005   )
   2006 /*++
   2007 
   2008 Routine Description:
   2009 
   2010   GC_TODO: Add function description
   2011 
   2012 Arguments:
   2013 
   2014   Context - GC_TODO: add argument description
   2015 
   2016 Returns:
   2017 
   2018   GC_TODO: add return values
   2019 
   2020 --*/
   2021 {
   2022   return STATUS_SUCCESS;
   2023 }
   2024 
   2025 static
   2026 STATUS
   2027 IfrParse17 (
   2028   IFR_PARSE_CONTEXT *Context
   2029   )
   2030 /*++
   2031 
   2032 Routine Description:
   2033 
   2034   GC_TODO: Add function description
   2035 
   2036 Arguments:
   2037 
   2038   Context - GC_TODO: add argument description
   2039 
   2040 Returns:
   2041 
   2042   GC_TODO: add return values
   2043 
   2044 --*/
   2045 {
   2046   return STATUS_SUCCESS;
   2047 }
   2048 
   2049 static
   2050 STATUS
   2051 IfrParse18 (
   2052   IFR_PARSE_CONTEXT *Context
   2053   )
   2054 /*++
   2055 
   2056 Routine Description:
   2057 
   2058   GC_TODO: Add function description
   2059 
   2060 Arguments:
   2061 
   2062   Context - GC_TODO: add argument description
   2063 
   2064 Returns:
   2065 
   2066   GC_TODO: add return values
   2067 
   2068 --*/
   2069 {
   2070   return STATUS_SUCCESS;
   2071 }
   2072 
   2073 static
   2074 STATUS
   2075 IfrParse19 (
   2076   IFR_PARSE_CONTEXT *Context
   2077   )
   2078 /*++
   2079 
   2080 Routine Description:
   2081 
   2082   GC_TODO: Add function description
   2083 
   2084 Arguments:
   2085 
   2086   Context - GC_TODO: add argument description
   2087 
   2088 Returns:
   2089 
   2090   GC_TODO: add return values
   2091 
   2092 --*/
   2093 {
   2094   return STATUS_SUCCESS;
   2095 }
   2096 
   2097 static
   2098 STATUS
   2099 IfrParse1A (
   2100   IFR_PARSE_CONTEXT *Context
   2101   )
   2102 /*++
   2103 
   2104 Routine Description:
   2105 
   2106   GC_TODO: Add function description
   2107 
   2108 Arguments:
   2109 
   2110   Context - GC_TODO: add argument description
   2111 
   2112 Returns:
   2113 
   2114   GC_TODO: add return values
   2115 
   2116 --*/
   2117 {
   2118   return STATUS_SUCCESS;
   2119 }
   2120 
   2121 static
   2122 STATUS
   2123 IfrParse1B (
   2124   IFR_PARSE_CONTEXT *Context
   2125   )
   2126 /*++
   2127 
   2128 Routine Description:
   2129 
   2130   GC_TODO: Add function description
   2131 
   2132 Arguments:
   2133 
   2134   Context - GC_TODO: add argument description
   2135 
   2136 Returns:
   2137 
   2138   GC_TODO: add return values
   2139 
   2140 --*/
   2141 {
   2142   return STATUS_SUCCESS;
   2143 }
   2144 
   2145 static
   2146 STATUS
   2147 IfrParse1C (
   2148   IFR_PARSE_CONTEXT *Context
   2149   )
   2150 /*++
   2151 
   2152 Routine Description:
   2153 
   2154   GC_TODO: Add function description
   2155 
   2156 Arguments:
   2157 
   2158   Context - GC_TODO: add argument description
   2159 
   2160 Returns:
   2161 
   2162   GC_TODO: add return values
   2163 
   2164 --*/
   2165 {
   2166   return STATUS_SUCCESS;
   2167 }
   2168 
   2169 static
   2170 STATUS
   2171 IfrParse1D (
   2172   IFR_PARSE_CONTEXT *Context
   2173   )
   2174 /*++
   2175 
   2176 Routine Description:
   2177 
   2178   GC_TODO: Add function description
   2179 
   2180 Arguments:
   2181 
   2182   Context - GC_TODO: add argument description
   2183 
   2184 Returns:
   2185 
   2186   GC_TODO: add return values
   2187 
   2188 --*/
   2189 {
   2190   return STATUS_SUCCESS;
   2191 }
   2192 
   2193 static
   2194 STATUS
   2195 IfrParse1E (
   2196   IFR_PARSE_CONTEXT *Context
   2197   )
   2198 /*++
   2199 
   2200 Routine Description:
   2201 
   2202   GC_TODO: Add function description
   2203 
   2204 Arguments:
   2205 
   2206   Context - GC_TODO: add argument description
   2207 
   2208 Returns:
   2209 
   2210   GC_TODO: add return values
   2211 
   2212 --*/
   2213 {
   2214   return STATUS_SUCCESS;
   2215 }
   2216 
   2217 static
   2218 STATUS
   2219 IfrParse1F (
   2220   IFR_PARSE_CONTEXT *Context
   2221   )
   2222 /*++
   2223 
   2224 Routine Description:
   2225 
   2226   GC_TODO: Add function description
   2227 
   2228 Arguments:
   2229 
   2230   Context - GC_TODO: add argument description
   2231 
   2232 Returns:
   2233 
   2234   GC_TODO: add return values
   2235 
   2236 --*/
   2237 {
   2238   return STATUS_SUCCESS;
   2239 }
   2240 
   2241 static
   2242 STATUS
   2243 IfrParse20 (
   2244   IFR_PARSE_CONTEXT *Context
   2245   )
   2246 /*++
   2247 
   2248 Routine Description:
   2249 
   2250   GC_TODO: Add function description
   2251 
   2252 Arguments:
   2253 
   2254   Context - GC_TODO: add argument description
   2255 
   2256 Returns:
   2257 
   2258   GC_TODO: add return values
   2259 
   2260 --*/
   2261 {
   2262   return STATUS_SUCCESS;
   2263 }
   2264 
   2265 static
   2266 STATUS
   2267 IfrParse21 (
   2268   IFR_PARSE_CONTEXT *Context
   2269   )
   2270 /*++
   2271 
   2272 Routine Description:
   2273 
   2274   GC_TODO: Add function description
   2275 
   2276 Arguments:
   2277 
   2278   Context - GC_TODO: add argument description
   2279 
   2280 Returns:
   2281 
   2282   GC_TODO: add return values
   2283 
   2284 --*/
   2285 {
   2286   return STATUS_SUCCESS;
   2287 }
   2288 
   2289 static
   2290 STATUS
   2291 IfrParse22 (
   2292   IFR_PARSE_CONTEXT *Context
   2293   )
   2294 /*++
   2295 
   2296 Routine Description:
   2297 
   2298   GC_TODO: Add function description
   2299 
   2300 Arguments:
   2301 
   2302   Context - GC_TODO: add argument description
   2303 
   2304 Returns:
   2305 
   2306   GC_TODO: add return values
   2307 
   2308 --*/
   2309 {
   2310   return STATUS_SUCCESS;
   2311 }
   2312 
   2313 static
   2314 STATUS
   2315 IfrParse23 (
   2316   IFR_PARSE_CONTEXT *Context
   2317   )
   2318 /*++
   2319 
   2320 Routine Description:
   2321 
   2322   GC_TODO: Add function description
   2323 
   2324 Arguments:
   2325 
   2326   Context - GC_TODO: add argument description
   2327 
   2328 Returns:
   2329 
   2330   GC_TODO: add return values
   2331 
   2332 --*/
   2333 {
   2334   return STATUS_SUCCESS;
   2335 }
   2336 //
   2337 // EFI_IFR_VARSTORE
   2338 //
   2339 static
   2340 STATUS
   2341 IfrParse24 (
   2342   IFR_PARSE_CONTEXT *Context
   2343   )
   2344 /*++
   2345 
   2346 Routine Description:
   2347 
   2348   GC_TODO: Add function description
   2349 
   2350 Arguments:
   2351 
   2352   Context - GC_TODO: add argument description
   2353 
   2354 Returns:
   2355 
   2356   GC_TODO: add return values
   2357 
   2358 --*/
   2359 {
   2360   EFI_IFR_VARSTORE  *Op;
   2361   Op = (EFI_IFR_VARSTORE *) Context->LastIfr->RawIfrHeader;
   2362   return STATUS_SUCCESS;
   2363 }
   2364 //
   2365 // VARSTORE_SELECT
   2366 //
   2367 static
   2368 STATUS
   2369 IfrParse25 (
   2370   IFR_PARSE_CONTEXT *Context
   2371   )
   2372 /*++
   2373 
   2374 Routine Description:
   2375 
   2376   GC_TODO: Add function description
   2377 
   2378 Arguments:
   2379 
   2380   Context - GC_TODO: add argument description
   2381 
   2382 Returns:
   2383 
   2384   GC_TODO: add return values
   2385 
   2386 --*/
   2387 {
   2388   STATUS                  Status;
   2389   EFI_IFR_VARSTORE_SELECT *Op;
   2390   Op      = (EFI_IFR_VARSTORE_SELECT *) Context->LastIfr->RawIfrHeader;
   2391   Status  = GetVarStoreInfo (Context, Op->VarId, &Context->LastIfr->VarStoreGuid1, &Context->LastIfr->VarStoreName1);
   2392   //
   2393   // VARSTORE_SELECT sets both
   2394   //
   2395   Context->LastIfr->VarStoreGuid2 = Context->LastIfr->VarStoreGuid1;
   2396   Context->LastIfr->VarStoreName2 = Context->LastIfr->VarStoreName1;
   2397   return Status;
   2398 }
   2399 //
   2400 // VARSTORE_SELECT_PAIR
   2401 //
   2402 static
   2403 STATUS
   2404 IfrParse26 (
   2405   IFR_PARSE_CONTEXT *Context
   2406   )
   2407 /*++
   2408 
   2409 Routine Description:
   2410 
   2411   GC_TODO: Add function description
   2412 
   2413 Arguments:
   2414 
   2415   Context - GC_TODO: add argument description
   2416 
   2417 Returns:
   2418 
   2419   GC_TODO: add return values
   2420 
   2421 --*/
   2422 {
   2423   STATUS                        Status;
   2424   EFI_IFR_VARSTORE_SELECT_PAIR  *Op;
   2425 
   2426   Op      = (EFI_IFR_VARSTORE_SELECT_PAIR *) Context->LastIfr->RawIfrHeader;
   2427   Status  = GetVarStoreInfo (Context, Op->VarId, &Context->LastIfr->VarStoreGuid1, &Context->LastIfr->VarStoreName1);
   2428   Status = GetVarStoreInfo (
   2429             Context,
   2430             Op->SecondaryVarId,
   2431             &Context->LastIfr->VarStoreGuid2,
   2432             &Context->LastIfr->VarStoreName2
   2433             );
   2434   return Status;
   2435 }
   2436 //
   2437 // TRUE
   2438 //
   2439 static
   2440 STATUS
   2441 IfrParse27 (
   2442   IFR_PARSE_CONTEXT *Context
   2443   )
   2444 /*++
   2445 
   2446 Routine Description:
   2447 
   2448   GC_TODO: Add function description
   2449 
   2450 Arguments:
   2451 
   2452   Context - GC_TODO: add argument description
   2453 
   2454 Returns:
   2455 
   2456   GC_TODO: add return values
   2457 
   2458 --*/
   2459 {
   2460   return STATUS_SUCCESS;
   2461 }
   2462 //
   2463 // FALSe
   2464 //
   2465 static
   2466 STATUS
   2467 IfrParse28 (
   2468   IFR_PARSE_CONTEXT *Context
   2469   )
   2470 /*++
   2471 
   2472 Routine Description:
   2473 
   2474   GC_TODO: Add function description
   2475 
   2476 Arguments:
   2477 
   2478   Context - GC_TODO: add argument description
   2479 
   2480 Returns:
   2481 
   2482   GC_TODO: add return values
   2483 
   2484 --*/
   2485 {
   2486   return STATUS_SUCCESS;
   2487 }
   2488 static
   2489 STATUS
   2490 IfrParse29 (
   2491   IFR_PARSE_CONTEXT *Context
   2492   )
   2493 /*++
   2494 
   2495 Routine Description:
   2496 
   2497   GC_TODO: Add function description
   2498 
   2499 Arguments:
   2500 
   2501   Context - GC_TODO: add argument description
   2502 
   2503 Returns:
   2504 
   2505   GC_TODO: add return values
   2506 
   2507 --*/
   2508 {
   2509   return STATUS_SUCCESS;
   2510 }
   2511 static
   2512 STATUS
   2513 IfrParse2A (
   2514   IFR_PARSE_CONTEXT *Context
   2515   )
   2516 /*++
   2517 
   2518 Routine Description:
   2519 
   2520   GC_TODO: Add function description
   2521 
   2522 Arguments:
   2523 
   2524   Context - GC_TODO: add argument description
   2525 
   2526 Returns:
   2527 
   2528   GC_TODO: add return values
   2529 
   2530 --*/
   2531 {
   2532   return STATUS_SUCCESS;
   2533 }
   2534