]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Correct definition to follow spec.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
index ef862e4e985531dcbe107720e65d1dc88f7cda75..a2befcb6613782b708d7724e95e97e11a203714e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2012, 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
@@ -329,7 +329,8 @@ InitializeConfigHdr (
 {\r
   CHAR16      *Name;\r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+      Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
     Name = Storage->Name;\r
   } else {\r
     Name = NULL;\r
@@ -357,6 +358,7 @@ InitializeConfigHdr (
 \r
   @param  FormSet                Pointer of the current FormSet.\r
   @param  Question               The Question to be initialized.\r
+  @param  Form                   Pointer of the current form.\r
 \r
   @retval EFI_SUCCESS            Function success.\r
   @retval EFI_INVALID_PARAMETER  No storage associated with the Question.\r
@@ -365,7 +367,8 @@ InitializeConfigHdr (
 EFI_STATUS\r
 InitializeRequestElement (\r
   IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
-  IN OUT FORM_BROWSER_STATEMENT   *Question\r
+  IN OUT FORM_BROWSER_STATEMENT   *Question,\r
+  IN OUT FORM_BROWSER_FORM        *Form\r
   )\r
 {\r
   FORMSET_STORAGE  *Storage;\r
@@ -373,6 +376,9 @@ InitializeRequestElement (
   UINTN            StringSize;\r
   CHAR16           *NewStr;\r
   CHAR16           RequestElement[30];\r
+  LIST_ENTRY       *Link;\r
+  BOOLEAN          Find;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   Storage = Question->Storage;\r
   if (Storage == NULL) {\r
@@ -390,7 +396,8 @@ InitializeRequestElement (
   //\r
   // Prepare <RequestElement>\r
   //\r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+      Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
     StrLen = UnicodeSPrint (\r
                RequestElement,\r
                30 * sizeof (CHAR16),\r
@@ -433,6 +440,54 @@ InitializeRequestElement (
   Storage->ElementCount++;\r
   Storage->SpareStrLen -= StrLen;\r
 \r
+  //\r
+  // Update the Config Request info saved in the form.\r
+  //\r
+  ConfigInfo = NULL;\r
+  Find       = FALSE;\r
+  Link = GetFirstNode (&Form->ConfigRequestHead);\r
+  while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+\r
+    if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) {\r
+      Find = TRUE;\r
+      break;\r
+    }\r
+\r
+    Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+  }\r
+\r
+  if (!Find) {\r
+    ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));\r
+    ASSERT (ConfigInfo != NULL);\r
+    ConfigInfo->Signature     = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;\r
+    ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
+    ConfigInfo->SpareStrLen   = 0;\r
+    ConfigInfo->Storage       = Storage;\r
+    InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
+  }\r
+\r
+  //\r
+  // Append <RequestElement> to <ConfigRequest>\r
+  //\r
+  if (StrLen > ConfigInfo->SpareStrLen) {\r
+    //\r
+    // Old String buffer is not sufficient for RequestElement, allocate a new one\r
+    //\r
+    StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
+    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    ASSERT (NewStr != NULL);\r
+    if (ConfigInfo->ConfigRequest != NULL) {\r
+      CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
+      FreePool (ConfigInfo->ConfigRequest);\r
+    }\r
+    ConfigInfo->ConfigRequest = NewStr;\r
+    ConfigInfo->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
+  }\r
+\r
+  StrCat (ConfigInfo->ConfigRequest, RequestElement);\r
+  ConfigInfo->ElementCount++;\r
+  ConfigInfo->SpareStrLen -= StrLen;\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -632,6 +687,7 @@ DestroyForm (
   LIST_ENTRY              *Link;\r
   FORM_EXPRESSION         *Expression;\r
   FORM_BROWSER_STATEMENT  *Statement;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   //\r
   // Free Form Expressions\r
@@ -655,6 +711,18 @@ DestroyForm (
     DestroyStatement (FormSet, Statement);\r
   }\r
 \r
+  //\r
+  // Free ConfigRequest string.\r
+  //\r
+  while (!IsListEmpty (&Form->ConfigRequestHead)) {\r
+    Link = GetFirstNode (&Form->ConfigRequestHead);\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+    RemoveEntryList (&ConfigInfo->Link);\r
+\r
+    FreePool (ConfigInfo->ConfigRequest);\r
+    FreePool (ConfigInfo);\r
+  }\r
+\r
   //\r
   // Free this Form\r
   //\r
@@ -924,6 +992,7 @@ ParseOpCodes (
   InitializeListHead (&FormSet->StorageListHead);\r
   InitializeListHead (&FormSet->DefaultStoreListHead);\r
   InitializeListHead (&FormSet->FormListHead);\r
+  InitializeListHead (&FormSet->ExpressionListHead);\r
   ResetCurrentExpressionStack ();\r
   ResetMapExpressionListStack ();\r
 \r
@@ -994,7 +1063,7 @@ ParseOpCodes (
         CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
         break;\r
 \r
-      case EFI_IFR_EQ_ID_LIST_OP:\r
+      case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
         CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
         ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
@@ -1077,6 +1146,10 @@ ParseOpCodes (
           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);\r
           break;\r
 \r
+        case EFI_IFR_TYPE_REF:\r
+          ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r
+          break;\r
+\r
         case EFI_IFR_TYPE_OTHER:\r
         case EFI_IFR_TYPE_UNDEFINED:\r
         case EFI_IFR_TYPE_ACTION:\r
@@ -1260,8 +1333,6 @@ ParseOpCodes (
         FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
         CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
       }\r
-\r
-      InitializeListHead (&FormSet->ExpressionListHead);\r
       break;\r
 \r
     case EFI_IFR_FORM_OP:\r
@@ -1273,8 +1344,10 @@ ParseOpCodes (
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
+      InitializeListHead (&CurrentForm->ConfigRequestHead);\r
 \r
       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
 \r
@@ -1305,8 +1378,10 @@ ParseOpCodes (
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
       ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
+      InitializeListHead (&CurrentForm->ConfigRequestHead);\r
       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
 \r
       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
@@ -1406,11 +1481,32 @@ ParseOpCodes (
       // Create a EFI variable Storage for this FormSet\r
       //\r
       Storage = CreateStorage (FormSet);\r
-      Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
 \r
       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
       CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
+      CopyMem (&Storage->Size,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size,       sizeof (UINT16));\r
+\r
+      if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+        Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
+        break;\r
+      } \r
+\r
+      Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
+      Storage->Buffer = AllocateZeroPool (Storage->Size);\r
+      Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
+\r
+      AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;\r
+      Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
+      ASSERT (Storage->Name != NULL);\r
+      for (Index = 0; AsciiString[Index] != 0; Index++) {\r
+        Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
+      }\r
+\r
+      //\r
+      // Initialize <ConfigHdr>\r
+      //\r
+      InitializeConfigHdr (FormSet, Storage);\r
       break;\r
 \r
     //\r
@@ -1478,19 +1574,25 @@ ParseOpCodes (
     case EFI_IFR_REF_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
-      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
-      CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
-      if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
-        CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+      Value = &CurrentStatement->HiiValue;\r
+      Value->Type = EFI_IFR_TYPE_REF;\r
+      if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r
+        CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
 \r
-        if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
-          CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
+        if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
+          CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
 \r
-          if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
-            CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
+          if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
+            CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
+\r
+            if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
+              CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
+            }\r
           }\r
         }\r
       }\r
+      CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);        \r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       break;\r
 \r
     case EFI_IFR_ONE_OF_OP:\r
@@ -1538,7 +1640,7 @@ ParseOpCodes (
         break;\r
       }\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
         SuppressForOption = TRUE;\r
@@ -1568,7 +1670,7 @@ ParseOpCodes (
       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       break;\r
 \r
@@ -1589,7 +1691,7 @@ ParseOpCodes (
       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       break;\r
 \r
     case EFI_IFR_PASSWORD_OP:\r
@@ -1608,7 +1710,7 @@ ParseOpCodes (
       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       break;\r
 \r
     case EFI_IFR_DATE_OP:\r
@@ -1621,7 +1723,7 @@ ParseOpCodes (
       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       } else {\r
         //\r
         // Don't assign storage for RTC type of date/time\r
@@ -1641,7 +1743,7 @@ ParseOpCodes (
       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       } else {\r
         //\r
         // Don't assign storage for RTC type of date/time\r
@@ -1739,8 +1841,12 @@ ParseOpCodes (
         CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
         CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
         CurrentStatement->ValueType = CurrentOption->Value.Type;\r
+        if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
+          CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;\r
+          CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;\r
+        }\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       }\r
       break;\r
 \r
@@ -1999,6 +2105,44 @@ ParseOpCodes (
       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
       break;\r
 \r
+    //\r
+    // Refresh guid.\r
+    //\r
+    case EFI_IFR_REFRESH_ID_OP:\r
+      ASSERT (CurrentStatement != NULL);\r
+      CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+      break;\r
+\r
+    //\r
+    // Modal tag\r
+    //\r
+    case EFI_IFR_MODAL_TAG_OP:\r
+      ASSERT (CurrentForm != NULL);\r
+      CurrentForm->ModalForm = TRUE;\r
+      break;\r
+\r
+    //\r
+    // Lock tag, used by form and statement.\r
+    //\r
+    case EFI_IFR_LOCKED_OP:\r
+      //\r
+      // Get ScopeOpcode from top of stack\r
+      //\r
+      PopScope (&ScopeOpCode);\r
+      PushScope (ScopeOpCode);\r
+      switch (ScopeOpCode) {\r
+      case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
+        ASSERT (CurrentForm != NULL);\r
+        CurrentForm->Locked = TRUE;\r
+        break;\r
+\r
+      default:\r
+        ASSERT (CurrentStatement != NULL);\r
+        CurrentStatement->Locked = TRUE;\r
+      }      \r
+      break;\r
+\r
     //\r
     // Vendor specific\r
     //\r