--- /dev/null
+/*++\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