]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/HiiPack/IfrParse.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / HiiPack / IfrParse.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/HiiPack/IfrParse.c b/EdkCompatibilityPkg/Sample/Tools/Source/HiiPack/IfrParse.c
new file mode 100644 (file)
index 0000000..e69af5c
--- /dev/null
@@ -0,0 +1,2533 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  IfrParse.c  \r
+\r
+Abstract:\r
+\r
+  Routines for parsing and managing HII IFR packs.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include "Tiano.h"\r
+#include "EfiUtilityMsgs.h"\r
+#include "EfiInternalFormRepresentation.h"\r
+#include "Hii.h"\r
+#include "IfrParse.h"\r
+#include "HiiPack.h"\r
+\r
+typedef struct _VARIABLE_STORE_ENTRY {\r
+  struct _VARIABLE_STORE_ENTRY  *Next;\r
+  CHAR8                         VarName[MAX_VARIABLE_NAME];\r
+  char                          *VarBuffer;\r
+  int                           VarBufferSize;\r
+  EFI_HII_VARIABLE_PACK         *VarPack;\r
+  int                           VarPackSize;\r
+} VARIABLE_STORE_ENTRY;\r
+\r
+typedef STATUS (*IFR_PARSE_FUNCTION) (IFR_PARSE_CONTEXT * Context);\r
+\r
+typedef struct {\r
+  INT8                *Name;\r
+  INT32               Size;\r
+  IFR_PARSE_FUNCTION  Parse;\r
+} IFR_PARSE_TABLE_ENTRY;\r
+\r
+static\r
+STATUS\r
+IfrParse01 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse02 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse03 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse05 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse06 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse07 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse08 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse09 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0B (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0C (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0D (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0E (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse0F (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse10 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse11 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse12 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse13 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse14 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse15 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse16 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse17 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse18 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse19 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1B (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1C (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1D (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1E (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse1F (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse20 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse21 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse22 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse23 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse24 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse25 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse26 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse27 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse28 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse29 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+static\r
+STATUS\r
+IfrParse2A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  );\r
+\r
+static const IFR_PARSE_TABLE_ENTRY  mIfrParseTable[] = {\r
+  {\r
+    0,\r
+    0,\r
+    NULL\r
+  },  // invalid\r
+  {\r
+    "EFI_IFR_FORM",\r
+    sizeof (EFI_IFR_FORM),\r
+    IfrParse01\r
+  },\r
+  {\r
+    "EFI_IFR_SUBTITLE",\r
+    sizeof (EFI_IFR_SUBTITLE),\r
+    IfrParse02\r
+  },\r
+  {\r
+    "EFI_IFR_TEXT",\r
+    -6,\r
+    IfrParse03\r
+  },  // sizeof (EFI_IFR_TEXT) },\r
+  {\r
+    "unused 0x04 opcode",\r
+    0,\r
+    NULL\r
+  },  // EFI_IFR_GRAPHIC_OP\r
+  {\r
+    "EFI_IFR_ONE_OF",\r
+    sizeof (EFI_IFR_ONE_OF),\r
+    IfrParse05\r
+  },\r
+  {\r
+    "EFI_IFR_CHECK_BOX",\r
+    sizeof (EFI_IFR_CHECK_BOX),\r
+    IfrParse06\r
+  },\r
+  {\r
+    "EFI_IFR_NUMERIC",\r
+    sizeof (EFI_IFR_NUMERIC),\r
+    IfrParse07\r
+  },\r
+  {\r
+    "EFI_IFR_PASSWORD",\r
+    sizeof (EFI_IFR_PASSWORD),\r
+    IfrParse08\r
+  },\r
+  {\r
+    "EFI_IFR_ONE_OF_OPTION",\r
+    sizeof (EFI_IFR_ONE_OF_OPTION),\r
+    IfrParse09\r
+  },\r
+  {\r
+    "EFI_IFR_SUPPRESS",\r
+    sizeof (EFI_IFR_SUPPRESS),\r
+    IfrParse0A\r
+  },\r
+  {\r
+    "EFI_IFR_END_FORM",\r
+    sizeof (EFI_IFR_END_FORM),\r
+    IfrParse0B\r
+  },\r
+  {\r
+    "EFI_IFR_HIDDEN",\r
+    sizeof (EFI_IFR_HIDDEN),\r
+    IfrParse0C\r
+  },\r
+  {\r
+    "EFI_IFR_END_FORM_SET",\r
+    sizeof (EFI_IFR_END_FORM_SET),\r
+    IfrParse0D\r
+  },\r
+  {\r
+    "EFI_IFR_FORM_SET",\r
+    sizeof (EFI_IFR_FORM_SET),\r
+    IfrParse0E\r
+  },\r
+  {\r
+    "EFI_IFR_REF",\r
+    sizeof (EFI_IFR_REF),\r
+    IfrParse0F\r
+  },\r
+  {\r
+    "EFI_IFR_END_ONE_OF",\r
+    sizeof (EFI_IFR_END_ONE_OF),\r
+    IfrParse10\r
+  },\r
+  {\r
+    "EFI_IFR_INCONSISTENT",\r
+    sizeof (EFI_IFR_INCONSISTENT),\r
+    IfrParse11\r
+  },\r
+  {\r
+    "EFI_IFR_EQ_ID_VAL",\r
+    sizeof (EFI_IFR_EQ_ID_VAL),\r
+    IfrParse12\r
+  },\r
+  {\r
+    "EFI_IFR_EQ_ID_ID",\r
+    sizeof (EFI_IFR_EQ_ID_ID),\r
+    IfrParse13\r
+  },\r
+  {\r
+    "EFI_IFR_EQ_ID_LIST",\r
+    -(int) (sizeof (EFI_IFR_EQ_ID_LIST)),\r
+    IfrParse14\r
+  },\r
+  {\r
+    "EFI_IFR_AND",\r
+    sizeof (EFI_IFR_AND),\r
+    IfrParse15\r
+  },\r
+  {\r
+    "EFI_IFR_OR",\r
+    sizeof (EFI_IFR_OR),\r
+    IfrParse16\r
+  },\r
+  {\r
+    "EFI_IFR_NOT",\r
+    sizeof (EFI_IFR_NOT),\r
+    IfrParse17\r
+  },\r
+  {\r
+    "EFI_IFR_END_IF",\r
+    sizeof (EFI_IFR_END_IF),\r
+    IfrParse18\r
+  },\r
+  {\r
+    "EFI_IFR_GRAYOUT",\r
+    sizeof (EFI_IFR_GRAYOUT),\r
+    IfrParse19\r
+  },\r
+  {\r
+    "EFI_IFR_DATE",\r
+    sizeof (EFI_IFR_DATE) / 3,\r
+    IfrParse1A\r
+  },\r
+  {\r
+    "EFI_IFR_TIME",\r
+    sizeof (EFI_IFR_TIME) / 3,\r
+    IfrParse1B\r
+  },\r
+  {\r
+    "EFI_IFR_STRING",\r
+    sizeof (EFI_IFR_STRING),\r
+    IfrParse1C\r
+  },\r
+  {\r
+    "EFI_IFR_LABEL",\r
+    sizeof (EFI_IFR_LABEL),\r
+    IfrParse1D\r
+  },\r
+  {\r
+    "EFI_IFR_SAVE_DEFAULTS",\r
+    sizeof (EFI_IFR_SAVE_DEFAULTS),\r
+    IfrParse1E\r
+  },\r
+  {\r
+    "EFI_IFR_RESTORE_DEFAULTS",\r
+    sizeof (EFI_IFR_RESTORE_DEFAULTS),\r
+    IfrParse1F\r
+  },\r
+  {\r
+    "EFI_IFR_BANNER",\r
+    sizeof (EFI_IFR_BANNER),\r
+    IfrParse20\r
+  },\r
+  {\r
+    "EFI_IFR_INVENTORY",\r
+    sizeof (EFI_IFR_INVENTORY),\r
+    IfrParse21\r
+  },\r
+  {\r
+    "EFI_IFR_EQ_VAR_VAL_OP",\r
+    sizeof (EFI_IFR_EQ_VAR_VAL),\r
+    IfrParse22\r
+  },\r
+  {\r
+    "EFI_IFR_ORDERED_LIST_OP",\r
+    sizeof (EFI_IFR_ORDERED_LIST),\r
+    IfrParse23\r
+  },\r
+  {\r
+    "EFI_IFR_VARSTORE_OP",\r
+    -(int) (sizeof (EFI_IFR_VARSTORE)),\r
+    IfrParse24\r
+  },\r
+  {\r
+    "EFI_IFR_VARSTORE_SELECT_OP",\r
+    sizeof (EFI_IFR_VARSTORE_SELECT),\r
+    IfrParse25\r
+  },\r
+  {\r
+    "EFI_IFR_VARSTORE_SELECT_PAIR_OP",\r
+    sizeof (EFI_IFR_VARSTORE_SELECT_PAIR),\r
+    IfrParse26\r
+  },\r
+  {\r
+    "EFI_IFR_TRUE",\r
+    sizeof (EFI_IFR_TRUE),\r
+    IfrParse27\r
+  },\r
+  {\r
+    "EFI_IFR_FALSE",\r
+    sizeof (EFI_IFR_FALSE),\r
+    IfrParse28\r
+  },\r
+  {\r
+    "EFI_IFR_GT",\r
+    sizeof (EFI_IFR_GT),\r
+    IfrParse29\r
+  },\r
+  {\r
+    "EFI_IFR_GE",\r
+    sizeof (EFI_IFR_GE),\r
+    IfrParse2A\r
+  },\r
+};\r
+#define PARSE_TABLE_ENTRIES (sizeof (mIfrParseTable) / sizeof (mIfrParseTable[0]))\r
+\r
+static\r
+STATUS\r
+GetVarStoreInfo (\r
+  IFR_PARSE_CONTEXT   *Context,\r
+  UINT16              VarId,\r
+  EFI_GUID            **VarStoreGuid,\r
+  char                **VarStoreName\r
+  );\r
+\r
+static\r
+void\r
+FreeVarStores (\r
+  VOID\r
+  );\r
+\r
+static\r
+STATUS\r
+CreateVarStore (\r
+  EFI_GUID *VarGuid,\r
+  CHAR8    *VarName,\r
+  int      VarStoreSize\r
+  );\r
+\r
+static\r
+STATUS\r
+SetDefaults (\r
+  IFR_PARSE_CONTEXT *Context,\r
+  UINT32            MfgDefaults\r
+  );\r
+\r
+//\r
+// Globals\r
+//\r
+static IFR_PARSE_CONTEXT            *mParseContext    = NULL;\r
+static VARIABLE_STORE_ENTRY         *mVariableStores  = NULL;\r
+static int                          BreakOnOpcodeTag  = 0;\r
+static int                          OpcodeTag         = 1;\r
+\r
+/*****************************************************************************/\r
+STATUS\r
+IfrParseCheck (\r
+  char    *Buffer,\r
+  long    BufferSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check a buffer to ensure that is is parseable IFR\r
+  \r
+Arguments:\r
+\r
+  Buffer      - pointer to raw IFR bytes\r
+  BufferSize  - size of IFR pointed to by Buffer\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      if successful\r
+  STATUS_ERROR        otherwise\r
+  \r
+--*/\r
+{\r
+  char              *Start;\r
+\r
+  char              *End;\r
+\r
+  char              *Pos;\r
+  EFI_IFR_OP_HEADER *OpHeader;\r
+  char              *FileName;\r
+  FileName = "";\r
+  //\r
+  // Walk the list of IFR statements in the IFR pack\r
+  //\r
+  Start = Buffer;\r
+  Pos   = Buffer;\r
+  End   = Start + BufferSize;\r
+  while ((Pos >= Start) && (Pos < End)) {\r
+    OpHeader = (EFI_IFR_OP_HEADER *) Pos;\r
+    //\r
+    // Check range on size\r
+    //\r
+    if (Pos + OpHeader->Length > End) {\r
+      Error (NULL, 0, 0, FileName, "invalid IFR opcode size at offset 0x%X", (int) Pos - (int) Start);\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    if (OpHeader->Length == 0) {\r
+      Error (NULL, 0, 0, FileName, "IFR opcode size=0 at offset 0x%X", (int) Pos - (int) Start);\r
+      return STATUS_ERROR;\r
+    }\r
+    //\r
+    // See if it's the END_FORMSET opcode\r
+    //\r
+    if (OpHeader->OpCode == EFI_IFR_END_FORM_SET_OP) {\r
+      break;\r
+    }\r
+    //\r
+    // Advance to next IFR statement/opcode\r
+    //\r
+    Pos += OpHeader->Length;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+IfrParseInit (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize this module for IFR pack parsing\r
+  \r
+Arguments:\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      always\r
+  \r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+IfrParseEnd (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free up memory allocated during IFR pack parsing done by this module\r
+  \r
+Arguments:\r
+  None\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      always\r
+  \r
+--*/\r
+{\r
+  IFR_PARSE_CONTEXT *NextContext;\r
+  IFR_PARSE_ENTRY   *NextEntry;\r
+  //\r
+  // Free up the memory from our parse contexts\r
+  //\r
+  while (mParseContext != NULL) {\r
+    while (mParseContext->Ifr != NULL) {\r
+      NextEntry = mParseContext->Ifr->Next;\r
+      //\r
+      // We pointed directly into the user buffer, rather than make\r
+      // a copy, so don't free up the bytes.\r
+      //\r
+      free (mParseContext->Ifr);\r
+      mParseContext->Ifr = NextEntry;\r
+    }\r
+\r
+    NextContext = mParseContext->Next;\r
+    free (mParseContext->PackHeader);\r
+    free (mParseContext);\r
+    mParseContext = NextContext;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+FreeVarStores (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  VARIABLE_STORE_ENTRY  *NextVarStore;\r
+  //\r
+  // Free up memory from our variable stores\r
+  //\r
+  while (mVariableStores != NULL) {\r
+    if (mVariableStores->VarPack != NULL) {\r
+      free (mVariableStores->VarPack);\r
+    }\r
+\r
+    NextVarStore = mVariableStores->Next;\r
+    free (mVariableStores);\r
+    mVariableStores = NextVarStore;\r
+  }\r
+}\r
+\r
+/******************************************************************************\r
+  FUNCTION: IfrParsePack() \r
+   \r
+  DESCRIPTION:  Given a pointer to an IFR pack, parse it to create a linked\r
+    list of opcodes and relevant data required for later dumping.\r
+\r
+\r
+*******************************************************************************/\r
+STATUS\r
+IfrParsePack (\r
+  int               Handle,\r
+  EFI_HII_IFR_PACK  *PackHeader,\r
+  EFI_GUID          *PackageGuid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a pointer to an IFR pack, parse it to create a linked\r
+  list of opcodes and relevant data required for later dumping.\r
+  \r
+Arguments:\r
+\r
+  Handle          - the handle number associated with this IFR pack. It\r
+                    can be used later to retrieve more info on the particular\r
+                    pack\r
+  PackHeader      - pointer to IFR pack to parse\r
+  PackageGuid     - on input, it comes from the HII data table entry for this pack. \r
+                    On output, we'll return the IFR formset GUID.\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      always\r
+\r
+--*/\r
+{\r
+  EFI_IFR_OP_HEADER *OpHeader;\r
+  IFR_PARSE_CONTEXT *Context;\r
+  IFR_PARSE_CONTEXT *TempContext;\r
+  IFR_PARSE_ENTRY   *IfrEntry;\r
+  //\r
+  // Initialize our context\r
+  //\r
+  Context = (IFR_PARSE_CONTEXT *) malloc (sizeof (IFR_PARSE_CONTEXT));\r
+  if (Context == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  memset ((void *) Context, 0, sizeof (IFR_PARSE_CONTEXT));\r
+  //\r
+  // Cache a copy of the input pack so the caller can free their copy\r
+  //\r
+  Context->PackHeader = (EFI_HII_IFR_PACK *) malloc (PackHeader->Header.Length);\r
+  if (Context->PackHeader == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    free (Context);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  memcpy (Context->PackHeader, PackHeader, PackHeader->Header.Length);\r
+  Context->IfrBufferStart = (char *) (Context->PackHeader + 1);\r
+  Context->CurrentPos     = Context->IfrBufferStart;\r
+  Context->IfrBufferLen   = PackHeader->Header.Length - sizeof (EFI_HII_IFR_PACK);\r
+  Context->Handle         = Handle;\r
+  Context->FormsetGuid    = &Context->NullGuid;\r
+  Context->PackageGuid    = *PackageGuid;\r
+  //\r
+  // Add it to the end of our list\r
+  //\r
+  if (mParseContext == NULL) {\r
+    mParseContext = Context;\r
+  } else {\r
+    TempContext = mParseContext;\r
+    while (TempContext->Next != NULL) {\r
+      TempContext = TempContext->Next;\r
+    }\r
+\r
+    TempContext->Next = Context;\r
+  }\r
+  //\r
+  // Walk the opcodes in the pack\r
+  //\r
+  while\r
+  (\r
+    (Context->CurrentPos >= Context->IfrBufferStart) &&\r
+    (Context->CurrentPos < Context->IfrBufferStart + Context->IfrBufferLen)\r
+  ) {\r
+    OpHeader = (EFI_IFR_OP_HEADER *) Context->CurrentPos;\r
+    //\r
+    // Allocate a new IFR entry to put in our linked list, then\r
+    // point directly to the caller's raw data.\r
+    //\r
+    IfrEntry = (IFR_PARSE_ENTRY *) malloc (sizeof (IFR_PARSE_ENTRY));\r
+    if (IfrEntry == NULL) {\r
+      Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+      free (Context->PackHeader);\r
+      free (Context);\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    memset ((void *) IfrEntry, 0, sizeof (IFR_PARSE_ENTRY));\r
+    IfrEntry->Tag = ++OpcodeTag;\r
+    if (OpcodeTag == BreakOnOpcodeTag) {\r
+      EFI_BREAKPOINT ();\r
+    }\r
+\r
+    IfrEntry->RawIfrHeader = (EFI_IFR_OP_HEADER *) (Context->CurrentPos);\r
+    //\r
+    // Add this entry to our linked list. If it's not the first, then\r
+    // forward the variable store settings from the previous entry.\r
+    //\r
+    if (Context->LastIfr != NULL) {\r
+      IfrEntry->VarStoreGuid1 = Context->LastIfr->VarStoreGuid1;\r
+      IfrEntry->VarStoreName1 = Context->LastIfr->VarStoreName1;\r
+      IfrEntry->VarStoreGuid2 = Context->LastIfr->VarStoreGuid2;\r
+      IfrEntry->VarStoreName2 = Context->LastIfr->VarStoreName2;\r
+      Context->LastIfr->Next  = IfrEntry;\r
+    } else {\r
+      Context->Ifr = IfrEntry;\r
+    }\r
+\r
+    Context->LastIfr = IfrEntry;\r
+    //\r
+    // Switch on the opcode to parse it\r
+    //\r
+    if (OpHeader->OpCode < PARSE_TABLE_ENTRIES) {\r
+      if (mIfrParseTable[OpHeader->OpCode].Parse != NULL) {\r
+        mIfrParseTable[OpHeader->OpCode].Parse (Context);\r
+      }\r
+    } else {\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        "invalid opcode found in IFR",\r
+        "offset=0x%X opcode=0x%02X",\r
+        (int) OpHeader - (int) Context->PackHeader,\r
+        (int) OpHeader->OpCode\r
+        );\r
+      free (IfrEntry);\r
+      free (Context->PackHeader);\r
+      free (Context);\r
+      return STATUS_ERROR;\r
+    }\r
+    //\r
+    // If it's the END_FORMSET opcode, then we're done\r
+    //\r
+    if (OpHeader->OpCode == EFI_IFR_END_FORM_SET_OP) {\r
+      break;\r
+    }\r
+    //\r
+    // Advance to next IFR statement/opcode\r
+    //\r
+    if (OpHeader->Length == 0) {\r
+      Error (NULL, 0, 0, "0-length IFR opcode encountered", NULL);\r
+      free (IfrEntry);\r
+      free (Context->PackHeader);\r
+      free (Context);\r
+      return STATUS_ERROR;\r
+    }\r
+\r
+    Context->CurrentPos += OpHeader->Length;\r
+  }\r
+  //\r
+  // Return the form GUID.\r
+  //\r
+  *PackageGuid = *Context->FormsetGuid;  \r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/******************************************************************************\r
+  FUNCTION:  GetVarStoreInfo()\r
+   \r
+  DESCRIPTION:  IFR contains VARSTORE opcodes to specify where variable data \r
+    for following opcodes is supposed to be stored. One VARSTORE statement\r
+    allows you to specify the variable store GUID and a key, and another\r
+    VARSTORE (select) allows you to specify the key of a VARSTORE statement. \r
+    Given the key from a VARSTORE_SELECT statement, go find the corresponding\r
+    VARSTORE statement with a matching key and return the varstore GUID and \r
+    name. If key == 0, then the variable store is FormsetGuid."Setup"\r
+*******************************************************************************/\r
+static\r
+STATUS\r
+GetVarStoreInfo (\r
+  IFR_PARSE_CONTEXT     *Context,\r
+  UINT16                VarId,\r
+  EFI_GUID              **VarStoreGuid,\r
+  char                  **VarStoreName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get variable store information from an IFR pack for a given variable store ID.\r
+  \r
+Arguments:\r
+\r
+  Context       - pointer to IFR parse context\r
+  VarId         - variable store ID referenced by IFR being parsed\r
+  VarStoreGuid  - outgoing GUID of the variable store corresponding to VarId\r
+  VarStoreName  - outgoing variable name of variable store corresponding to VarId\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      - variable store with matching VarId found, and outoing GUID/Name are valid\r
+  STATUS_ERROR        - otherwise\r
+\r
+--*/\r
+{\r
+  IFR_PARSE_ENTRY   *Ptr;\r
+  EFI_IFR_VARSTORE  *VarStore;\r
+  if (Context == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Walk the entire IFR form and find a variable store opcode that\r
+  // has a matching variable store ID.\r
+  //\r
+  for (Ptr = Context->Ifr; Ptr != NULL; Ptr = Ptr->Next) {\r
+    if (Ptr->RawIfrHeader->OpCode == EFI_IFR_FORM_SET_OP) {\r
+      if (VarId == 0) {\r
+        *VarStoreGuid = &((EFI_IFR_FORM_SET *) (Ptr->RawIfrHeader))->Guid;\r
+        *VarStoreName = DEFAULT_VARIABLE_NAME;\r
+        return STATUS_SUCCESS;\r
+      }\r
+    } else if (Ptr->RawIfrHeader->OpCode == EFI_IFR_VARSTORE_OP) {\r
+      //\r
+      // See if it's a variable ID match\r
+      //\r
+      VarStore = (EFI_IFR_VARSTORE *) Ptr->RawIfrHeader;\r
+      if (VarStore->VarId == VarId) {\r
+        *VarStoreGuid = &VarStore->Guid;\r
+        *VarStoreName = (char *) (VarStore + 1);\r
+        return STATUS_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+STATUS\r
+IfrSetDefaults (\r
+  int MfgDefaults\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Go through all the IFR forms we've parsed so far and create and set variable\r
+  defaults.\r
+  \r
+Arguments:\r
+\r
+  MfgDefaults   - non-zero if manufacturing defaults are desired\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      - always\r
+\r
+--*/\r
+{\r
+  IFR_PARSE_CONTEXT *Context;\r
+  //\r
+  // First free up any variable stores we've created so far.\r
+  //\r
+  FreeVarStores ();\r
+  for (Context = mParseContext; Context != NULL; Context = Context->Next) {\r
+    //\r
+    // Call our internal function to handle it\r
+    //\r
+    SetDefaults (Context, MfgDefaults);\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+\r
+}\r
+\r
+/******************************************************************************/\r
+STATUS\r
+IfrGetIfrPack (\r
+  int               Handle,\r
+  EFI_HII_IFR_PACK  **PackHeader,\r
+  EFI_GUID          *FormsetGuid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Handle      - GC_TODO: add argument description\r
+  PackHeader  - GC_TODO: add argument description\r
+  FormsetGuid - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  IFR_PARSE_CONTEXT *Context;\r
+\r
+  for (Context = mParseContext; Context != NULL; Context = Context->Next) {\r
+    if (Context->Handle == Handle) {\r
+      *PackHeader = Context->PackHeader;\r
+      memcpy (FormsetGuid, Context->FormsetGuid, sizeof (EFI_GUID));\r
+      return STATUS_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+STATUS\r
+IfrReferencesVarPack (\r
+  int                   IfrHandle,\r
+  EFI_HII_VARIABLE_PACK *VarPack\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given an HII handle number (which corrresponds to a handle number passed \r
+  in to IfrParsePack()), see if the IFR references the specified variable\r
+  pack.\r
+  \r
+Arguments:\r
+\r
+  IfrHandle   - handle number for the IFR pack to check (passed to IfrParsePack())\r
+  VarPack     - variable pack to check to see if the IFR references\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS      if the IFR on the given handle references the variable pack\r
+  STATUS_WARNING      the IFR does not reference the variable pack\r
+  STATUS_ERROR        invalid IFR handle\r
+  \r
+--*/\r
+{\r
+  IFR_PARSE_CONTEXT *Context;\r
+  char              VarName[MAX_VARIABLE_NAME];\r
+  IFR_PARSE_ENTRY   *ParseEntry;\r
+\r
+  for (Context = mParseContext; Context != NULL; Context = Context->Next) {\r
+    if (Context->Handle == IfrHandle) {\r
+      //\r
+      // Create an ASCII version of the variable name, since that's what is\r
+      // referenced in IFR.\r
+      //\r
+      sprintf (VarName, "%S", (CHAR16 *) (VarPack + 1));\r
+      //\r
+      // Walk all the opcodes and see if the IFR references this variable pack\r
+      //\r
+      for (ParseEntry = Context->Ifr; ParseEntry != NULL; ParseEntry = ParseEntry->Next) {\r
+        //\r
+        // Check for Name.Guid match for primary IFR variable store\r
+        //\r
+        if ((strcmp (VarName, ParseEntry->VarStoreName1) == 0) &&\r
+            (memcmp (&VarPack->VariableGuid, ParseEntry->VarStoreGuid1, sizeof (EFI_GUID)) == 0)\r
+            ) {\r
+          return STATUS_SUCCESS;\r
+        }\r
+        //\r
+        // Check for Name.Guid match for secondary IFR variable store\r
+        //\r
+        if ((ParseEntry->VarStoreName2 != NULL) &&\r
+            (strcmp (VarName, ParseEntry->VarStoreName2) == 0) &&\r
+            (memcmp (&VarPack->VariableGuid, ParseEntry->VarStoreGuid2, sizeof (EFI_GUID)) == 0)\r
+            ) {\r
+          return STATUS_SUCCESS;\r
+        }\r
+      }\r
+\r
+      return STATUS_WARNING;\r
+    }\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+STATUS\r
+IfrGetVarPack (\r
+  int                     VarIndex,\r
+  EFI_HII_VARIABLE_PACK   **VarPack\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the variable defaults. It is expected that the caller\r
+  called IfrSetDefaults() previously to walk all the IFR forms we know about\r
+  and create and initialize default values.\r
+  \r
+Arguments:\r
+\r
+  VarIndex - a 0-based index into all the variable stores we know about\r
+  VarPack  - outgoing pointer to a variable pack\r
+\r
+Returns:\r
+\r
+  STATUS_ERROR    - VarIndex exceeds the number of variable packs we know of\r
+  STATUS_SUCCESS  - otherwise\r
+  \r
+--*/\r
+{\r
+  VARIABLE_STORE_ENTRY  *Entry;\r
+  //\r
+  // Initialize outgoing parameters\r
+  //\r
+  *VarPack = NULL;\r
+  for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {\r
+    if (VarIndex == 0) {\r
+      *VarPack = Entry->VarPack;\r
+      return STATUS_SUCCESS;\r
+    }\r
+\r
+    VarIndex--;\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+static\r
+STATUS\r
+SetVariableValue (\r
+  EFI_GUID    *VarGuid,\r
+  char        *VarName,\r
+  int         VarOffset,\r
+  int         VarSize,\r
+  void        *VarValue\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a variable GUID.Name, offset, size, and value, set the bytes in\r
+  the variable to the provided value.\r
+  \r
+Arguments:\r
+  VarGuid           - GUID of variable to set\r
+  VarName           - name of variable to set\r
+  VarOffset         - byte offset into the variable store \r
+  VarSize           - size of the value in the variable store (in bytes)\r
+  VarValue          - pointer to buffer containing the value to set\r
+\r
+Returns:\r
+\r
+  \r
+--*/\r
+{\r
+  VARIABLE_STORE_ENTRY  *Entry;\r
+  char                  *Src;\r
+  char                  *Dest;\r
+  //\r
+  // Go through our list of variable stores to find the match\r
+  //\r
+  for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {\r
+    if (memcmp (VarGuid, &Entry->VarPack->VariableGuid, sizeof (EFI_GUID)) == 0) {\r
+      if (strcmp (VarName, Entry->VarName) == 0) {\r
+        //\r
+        // Found match -- check offset. If it's beyond the size of the variable store\r
+        // buffer, then return a warning. Note that date-time can be beyond the\r
+        // end of the varstore, which is ok.\r
+        //\r
+        if (VarOffset + VarSize <= Entry->VarBufferSize) {\r
+          //\r
+          // Stuff the data\r
+          //\r
+          Dest  = Entry->VarBuffer + VarOffset;\r
+          Src   = (char *) VarValue;\r
+          while (VarSize > 0) {\r
+            *Dest = *Src;\r
+            Src++;\r
+            Dest++;\r
+            VarSize--;\r
+          }\r
+\r
+          return STATUS_SUCCESS;\r
+        }\r
+\r
+        return STATUS_WARNING;\r
+      }\r
+    }\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+static\r
+STATUS\r
+SetDefaults (\r
+  IFR_PARSE_CONTEXT *Context,\r
+  UINT32            MfgDefaults\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set variable defaults by walking a single IFR form.\r
+  \r
+Arguments:\r
+  \r
+  Context     - Pointer to the IFR context.\r
+  MfgDefaults - Number of Mfg defaults\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - arguments to function are invalid\r
+  STATUS_SUCCESS        - function executed successfully\r
+  \r
+--*/\r
+{\r
+  int                   Size;\r
+  int                   CachedVarOffset;\r
+  int                   CachedVarSize;\r
+  int                   OrderedList;\r
+  IFR_PARSE_ENTRY       *SavedParseEntry;\r
+  EFI_IFR_CHECK_BOX     *IfrCheckBox;\r
+  EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;\r
+  EFI_IFR_NUMERIC       *IfrNumeric;\r
+  STATUS                Status;\r
+  char                  ZeroByte;\r
+\r
+  //\r
+  // Walk the opcodes to set default values and stuff them into the variable stores\r
+  //\r
+\r
+  if (Context == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  Status              = STATUS_SUCCESS;\r
+  Context->CurrentIfr = Context->Ifr;\r
+  SavedParseEntry     = NULL;\r
+  OrderedList         = 0;\r
+  CachedVarOffset     = 0;\r
+  CachedVarSize       = 0;\r
+  ZeroByte            = 0;\r
+\r
+  while (Context->CurrentIfr != NULL) {\r
+    if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_FORM_SET_OP) {\r
+      //\r
+      // Formset opcode -- create a variable pack\r
+      //\r
+      Status = CreateVarStore (\r
+                &((EFI_IFR_FORM_SET *) (Context->CurrentIfr->RawIfrHeader))->Guid,\r
+                DEFAULT_VARIABLE_NAME,\r
+                ((EFI_IFR_FORM_SET *) (Context->CurrentIfr->RawIfrHeader))->NvDataSize\r
+                );\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_VARSTORE_OP) {\r
+      //\r
+      // Variable store opcode -- create a variable pack\r
+      //\r
+      Status = CreateVarStore (\r
+                &((EFI_IFR_VARSTORE *) (Context->CurrentIfr->RawIfrHeader))->Guid,\r
+                (char *) Context->CurrentIfr->RawIfrHeader + sizeof (EFI_IFR_VARSTORE),\r
+                ((EFI_IFR_VARSTORE *) (Context->CurrentIfr->RawIfrHeader))->Size\r
+                );\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ONE_OF_OP) {\r
+      //\r
+      // Need this parse context later when we find the default ONE_OF_OPTION.\r
+      // Clear out the variable store first, so that we're covered if someone\r
+      // has two one-of opcode that operate on the same data.\r
+      // So "last one wins" is the behavior.\r
+      //\r
+      OrderedList     = 0;\r
+      SavedParseEntry = Context->CurrentIfr;\r
+      CachedVarOffset = ((EFI_IFR_ONE_OF *) Context->CurrentIfr->RawIfrHeader)->QuestionId;\r
+      CachedVarSize   = ((EFI_IFR_ONE_OF *) Context->CurrentIfr->RawIfrHeader)->Width;\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+      //\r
+      // Need this parse context later as we parse the ONE_OF_OP's in the ordered list\r
+      //\r
+      OrderedList     = 1;\r
+      SavedParseEntry = Context->CurrentIfr;\r
+      CachedVarOffset = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->QuestionId;\r
+      CachedVarSize   = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->MaxEntries;\r
+\r
+      while (CachedVarSize > 0) {\r
+        Status = SetVariableValue (\r
+                  SavedParseEntry->VarStoreGuid1, // GUID of variable store to write\r
+                  SavedParseEntry->VarStoreName1, // name of variable store to write\r
+                  CachedVarOffset,                // offset into variable store\r
+                  1,                              // variable data size\r
+                  (void *) &ZeroByte\r
+                  );\r
+        //\r
+        // variable value\r
+        //\r
+        CachedVarSize--;\r
+        CachedVarOffset++;\r
+      }\r
+\r
+      CachedVarOffset = ((EFI_IFR_ORDERED_LIST *) Context->CurrentIfr->RawIfrHeader)->QuestionId;\r
+      CachedVarSize   = 1;\r
+      //\r
+      // ((EFI_IFR_ORDERED_LIST *)Context->CurrentIfr->RawIfrHeader)->Width;\r
+      //\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_ONE_OF_OPTION_OP) {\r
+      IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) Context->CurrentIfr->RawIfrHeader;\r
+      //\r
+      // If we're in an ordered list, then copy the value to the data store\r
+      //\r
+      if (OrderedList) {\r
+        Status = SetVariableValue (\r
+                  SavedParseEntry->VarStoreGuid1, // GUID of variable store to write\r
+                  SavedParseEntry->VarStoreName1, // name of variable store to write\r
+                  CachedVarOffset,                // offset into variable store\r
+                  1,                              // variable data size\r
+                  (void *) &IfrOneOfOption->Value\r
+                  );\r
+        //\r
+        // variable value\r
+        //\r
+        // Advance the offset for the next ordered list item\r
+        //\r
+        CachedVarOffset += CachedVarSize;\r
+      } else {\r
+        //\r
+        // ONE-OF list. See if the default flag is set (provided we're not doing mfg defaults)\r
+        //\r
+        if (!MfgDefaults) {\r
+          if (IfrOneOfOption->Flags & EFI_IFR_FLAG_DEFAULT) {\r
+            Status = SetVariableValue (\r
+                      SavedParseEntry->VarStoreGuid1, // GUID of variable store to write\r
+                      SavedParseEntry->VarStoreName1, // name of variable store to write\r
+                      CachedVarOffset,                // offset into variable store\r
+                      CachedVarSize,                  // variable data size\r
+                      &IfrOneOfOption->Value\r
+                      );\r
+            //\r
+            // variable value\r
+            //\r
+          }\r
+        } else {\r
+          if (IfrOneOfOption->Flags & EFI_IFR_FLAG_MANUFACTURING) {\r
+            Status = SetVariableValue (\r
+                      SavedParseEntry->VarStoreGuid1, // GUID of variable store to write\r
+                      SavedParseEntry->VarStoreName1, // name of variable store to write\r
+                      CachedVarOffset,                // offset into variable store\r
+                      CachedVarSize,                  // variable data size\r
+                      &IfrOneOfOption->Value\r
+                      );\r
+            //\r
+            // variable value\r
+            //\r
+          }\r
+        }\r
+      }\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_CHECKBOX_OP) {\r
+      //\r
+      // If we're saving defaults, and the default flag is set, or we're saving\r
+      // manufacturing defaults and the manufacturing flag is set, then save a 1.\r
+      // By default the varstore buffer is cleared, so we don't need to save a 0 ever.\r
+      //\r
+      IfrCheckBox = (EFI_IFR_CHECK_BOX *) Context->CurrentIfr->RawIfrHeader;\r
+      if (((MfgDefaults == 0) && (IfrCheckBox->Flags & EFI_IFR_FLAG_DEFAULT)) ||\r
+          ((MfgDefaults != 0) && (IfrCheckBox->Flags & EFI_IFR_FLAG_MANUFACTURING))\r
+          ) {\r
+        Size = 1;\r
+        Status = SetVariableValue (\r
+                  Context->CurrentIfr->VarStoreGuid1, // GUID of variable store to write\r
+                  Context->CurrentIfr->VarStoreName1, // name of variable store to write\r
+                  IfrCheckBox->QuestionId,            // offset into variable store\r
+                  IfrCheckBox->Width,                 // variable data size\r
+                  (void *) &Size\r
+                  );\r
+        //\r
+        // variable value\r
+        //\r
+      }\r
+    } else if (Context->CurrentIfr->RawIfrHeader->OpCode == EFI_IFR_NUMERIC_OP) {\r
+      IfrNumeric = (EFI_IFR_NUMERIC *) Context->CurrentIfr->RawIfrHeader;\r
+      Status = SetVariableValue (\r
+                Context->CurrentIfr->VarStoreGuid1, // GUID of variable store to write\r
+                Context->CurrentIfr->VarStoreName1, // name of variable store to write\r
+                IfrNumeric->QuestionId,             // offset into variable store\r
+                IfrNumeric->Width,                  // variable data size\r
+                (void *) &IfrNumeric->Default\r
+                );\r
+      //\r
+      // variable value\r
+      //\r
+    }\r
+\r
+    Context->CurrentIfr = Context->CurrentIfr->Next;\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+CreateVarStore (\r
+  EFI_GUID  *VarGuid,\r
+  CHAR8     *VarName,\r
+  int       VarStoreSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a variable GUID.Name and the size of the variable store, allocate\r
+  storage for maintaining the variable value.\r
+  \r
+Arguments:\r
+\r
+  VarGuid - GUID for a variable\r
+  VarName - Name of the variable\r
+  VarStoreSize - size of the variable store\r
+\r
+Returns:\r
+\r
+  STATUS_ERROR   - problem with storage allocation \r
+  STATUS_SUCCESS - function executed successfully\r
\r
+--*/\r
+{\r
+  VARIABLE_STORE_ENTRY  *Entry;\r
+\r
+  VARIABLE_STORE_ENTRY  *TempEntry;\r
+  int                   PackSize;\r
+  int                   VarNameLen;\r
+  //\r
+  // If the variable store size is zero, then do nothing. This could be valid\r
+  // if variable steering is used in the IFR such that FormsetGUID."Setup" variable\r
+  // store is never used.\r
+  //\r
+  // OPEN: What about a form that only has a time/date question? Then if some other\r
+  // function called SetDefaults(), attempting to set time/date would result in an\r
+  // error in the SetVarValue() function.\r
+  //\r
+   if (VarStoreSize == 0) {\r
+    return STATUS_SUCCESS;\r
+   }\r
+  //\r
+  // Go through our list of variable stores and see if we've already created one\r
+  // for this Guid.Name. If so, check the size and return. Otherwise create\r
+  // one and add it to the list.\r
+  //\r
+  for (Entry = mVariableStores; Entry != NULL; Entry = Entry->Next) {\r
+    if (memcmp (VarGuid, &Entry->VarPack->VariableGuid, sizeof (EFI_GUID)) == 0) {\r
+      if (strcmp (VarName, Entry->VarName) == 0) {\r
+        //\r
+        // Already have one. Check size.\r
+        //\r
+        if (Entry->VarBufferSize != VarStoreSize) {\r
+          Error (NULL, 0, 0, "mismatched variable store size between two formsets", VarName);\r
+          return STATUS_ERROR;\r
+        }\r
+\r
+        return STATUS_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Create a new one.\r
+  //\r
+  Entry = (VARIABLE_STORE_ENTRY *) malloc (sizeof (VARIABLE_STORE_ENTRY));\r
+  if (Entry == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  memset ((void *) Entry, 0, sizeof (VARIABLE_STORE_ENTRY));\r
+  //\r
+  // Compute size of the varpack\r
+  //\r
+  VarNameLen      = strlen (VarName) + 1;\r
+  PackSize        = sizeof (EFI_HII_VARIABLE_PACK) + VarNameLen * sizeof (CHAR16) + VarStoreSize;\r
+  Entry->VarPack  = (EFI_HII_VARIABLE_PACK *) malloc (PackSize);\r
+  if (Entry->VarPack == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    free (Entry);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  Entry->VarPack->Header.Length       = PackSize;\r
+  Entry->VarPack->Header.Type         = EFI_HII_VARIABLE;\r
+  Entry->VarPack->VariableNameLength  = VarNameLen * sizeof (CHAR16);\r
+  Entry->VarName[MAX_VARIABLE_NAME - 1] = 0;\r
+  strncpy (Entry->VarName, VarName, MAX_VARIABLE_NAME - 1);\r
+#ifdef USE_VC8\r
+  swprintf ((CHAR16 *) (Entry->VarPack + 1), (strlen (VarName) + 1) * sizeof (CHAR16), L"%S", VarName);\r
+#else\r
+  swprintf ((CHAR16 *) (Entry->VarPack + 1), L"%S", VarName);\r
+#endif\r
+  memcpy (&Entry->VarPack->VariableGuid, VarGuid, sizeof (EFI_GUID));\r
+  //\r
+  // Point VarBuffer into the allocated buffer (for convenience)\r
+  //\r
+  Entry->VarBuffer = (char *) Entry->VarPack + sizeof (EFI_HII_VARIABLE_PACK) + VarNameLen * sizeof (CHAR16);\r
+  memset ((void *) Entry->VarBuffer, 0, VarStoreSize);\r
+  Entry->VarBufferSize = VarStoreSize;\r
+  //\r
+  // Add this new varstore to our list\r
+  //\r
+  if (mVariableStores == NULL) {\r
+    mVariableStores = Entry;\r
+  } else {\r
+    for (TempEntry = mVariableStores; TempEntry->Next != NULL; TempEntry = TempEntry->Next)\r
+      ;\r
+    TempEntry->Next = Entry;\r
+  }\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+/******************************************************************************/\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The following IfrParseXX() functions are used to parse an IFR opcode numbered\r
+  XX via a dispatch table. \r
+  \r
+Arguments:\r
+\r
+  Context - IFR parsing context into which pertinent data for the \r
+            current opcode can be saved. Context->LastIfr->RawIfrHeader points to \r
+            the raw IFR bytes currently being parsed.\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS  - always\r
+  \r
+--*/\r
+\r
+/*******************************************************************************/\r
+static\r
+STATUS\r
+IfrParse01 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse02 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse03 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// Parse the IFR EFI_IFR_ONE_OF opcode.\r
+//\r
+static\r
+STATUS\r
+IfrParse05 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse06 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse07 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse08 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse09 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0B (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0C (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0D (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0E (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  EFI_IFR_FORM_SET  *Op;\r
+  Op  = (EFI_IFR_FORM_SET *) Context->LastIfr->RawIfrHeader;\r
+  Context->LastIfr->VarStoreGuid1 = &Op->Guid;\r
+  Context->LastIfr->VarStoreName1 = "Setup";\r
+  Context->FormsetGuid            = &Op->Guid;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse0F (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse10 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse11 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse12 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse13 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse14 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse15 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse16 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse17 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse18 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse19 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1B (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1C (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1D (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1E (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse1F (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse20 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse21 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse22 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+IfrParse23 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// EFI_IFR_VARSTORE\r
+//\r
+static\r
+STATUS\r
+IfrParse24 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  EFI_IFR_VARSTORE  *Op;\r
+  Op = (EFI_IFR_VARSTORE *) Context->LastIfr->RawIfrHeader;\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// VARSTORE_SELECT\r
+//\r
+static\r
+STATUS\r
+IfrParse25 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  STATUS                  Status;\r
+  EFI_IFR_VARSTORE_SELECT *Op;\r
+  Op      = (EFI_IFR_VARSTORE_SELECT *) Context->LastIfr->RawIfrHeader;\r
+  Status  = GetVarStoreInfo (Context, Op->VarId, &Context->LastIfr->VarStoreGuid1, &Context->LastIfr->VarStoreName1);\r
+  //\r
+  // VARSTORE_SELECT sets both\r
+  //\r
+  Context->LastIfr->VarStoreGuid2 = Context->LastIfr->VarStoreGuid1;\r
+  Context->LastIfr->VarStoreName2 = Context->LastIfr->VarStoreName1;\r
+  return Status;\r
+}\r
+//\r
+// VARSTORE_SELECT_PAIR\r
+//\r
+static\r
+STATUS\r
+IfrParse26 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  STATUS                        Status;\r
+  EFI_IFR_VARSTORE_SELECT_PAIR  *Op;\r
+\r
+  Op      = (EFI_IFR_VARSTORE_SELECT_PAIR *) Context->LastIfr->RawIfrHeader;\r
+  Status  = GetVarStoreInfo (Context, Op->VarId, &Context->LastIfr->VarStoreGuid1, &Context->LastIfr->VarStoreName1);\r
+  Status = GetVarStoreInfo (\r
+            Context,\r
+            Op->SecondaryVarId,\r
+            &Context->LastIfr->VarStoreGuid2,\r
+            &Context->LastIfr->VarStoreName2\r
+            );\r
+  return Status;\r
+}\r
+//\r
+// TRUE\r
+//\r
+static\r
+STATUS\r
+IfrParse27 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+//\r
+// FALSe\r
+//\r
+static\r
+STATUS\r
+IfrParse28 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+static\r
+STATUS\r
+IfrParse29 (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r
+static\r
+STATUS\r
+IfrParse2A (\r
+  IFR_PARSE_CONTEXT *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return STATUS_SUCCESS;\r
+}\r