]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg: Update Ppi/Protocol/Guid usage in INF files
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
index 3785c32f3c6ae47f4fa85a1d1a025522d56dcefb..9bda482a4ac3301a5a867cf03d11b798302a9d85 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
@@ -22,7 +22,7 @@ extern LIST_ENTRY      gBrowserStorageList;
   Initialize Statement header members.\r
 \r
   @param  OpCodeData             Pointer of the raw OpCode data.\r
-  @param  FormSet                Pointer of the current FormSe.\r
+  @param  FormSet                Pointer of the current FormSet.\r
   @param  Form                   Pointer of the current Form.\r
 \r
   @return The Statement.\r
@@ -59,6 +59,7 @@ CreateStatement (
 \r
   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
   Statement->OpCode  = (EFI_IFR_OP_HEADER *) OpCodeData;\r
+  Statement->QuestionReferToBitField = FALSE;\r
 \r
   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
@@ -116,7 +117,7 @@ UpdateCheckBoxStringToken (
   ASSERT (Statement != NULL);\r
   ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
 \r
-  UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
+  UnicodeValueToStringS (Str, sizeof (Str), 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
 \r
   Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
   if (Id == 0) {\r
@@ -688,6 +689,7 @@ InitializeRequestElement (
   LIST_ENTRY       *Link;\r
   BOOLEAN          Find;\r
   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+  UINTN            MaxLen;\r
 \r
   Storage = Question->Storage;\r
   if (Storage == NULL) {\r
@@ -714,6 +716,7 @@ InitializeRequestElement (
                Question->VarStoreInfo.VarOffset,\r
                Question->StorageWidth\r
                );\r
+    HiiToLower(RequestElement);\r
     Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
   } else {\r
     StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
@@ -732,6 +735,8 @@ InitializeRequestElement (
   //\r
   FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);\r
   ASSERT (FormsetStorage != NULL);\r
+  StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
+  MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;\r
 \r
   //\r
   // Append <RequestElement> to <ConfigRequest>\r
@@ -740,8 +745,8 @@ InitializeRequestElement (
     //\r
     // Old String buffer is not sufficient for RequestElement, allocate a new one\r
     //\r
-    StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
-    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+    NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
     ASSERT (NewStr != NULL);\r
     if (FormsetStorage->ConfigRequest != NULL) {\r
       CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);\r
@@ -751,7 +756,7 @@ InitializeRequestElement (
     FormsetStorage->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
   }\r
 \r
-  StrCat (FormsetStorage->ConfigRequest, RequestElement);\r
+  StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);\r
   FormsetStorage->ElementCount++;\r
   FormsetStorage->SpareStrLen -= StrLen;\r
 \r
@@ -782,6 +787,8 @@ InitializeRequestElement (
     ConfigInfo->Storage       = FormsetStorage->BrowserStorage;\r
     InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
   }\r
+  StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
+  MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;\r
 \r
   //\r
   // Append <RequestElement> to <ConfigRequest>\r
@@ -790,8 +797,8 @@ InitializeRequestElement (
     //\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
+    MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+    NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
     ASSERT (NewStr != NULL);\r
     if (ConfigInfo->ConfigRequest != NULL) {\r
       CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
@@ -801,7 +808,7 @@ InitializeRequestElement (
     ConfigInfo->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
   }\r
 \r
-  StrCat (ConfigInfo->ConfigRequest, RequestElement);\r
+  StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);\r
   ConfigInfo->ElementCount++;\r
   ConfigInfo->SpareStrLen -= StrLen;\r
   return EFI_SUCCESS;\r
@@ -1305,6 +1312,11 @@ ParseOpCodes (
   INTN                    ConditionalExprCount;\r
   BOOLEAN                 InUnknownScope;\r
   UINT8                   UnknownDepth;\r
+  FORMSET_DEFAULTSTORE    *PreDefaultStore;\r
+  LIST_ENTRY              *DefaultLink;\r
+  BOOLEAN                 HaveInserted;\r
+  UINT16                  TotalBits;\r
+  BOOLEAN                 QuestionReferBitField;\r
 \r
   SuppressForQuestion      = FALSE;\r
   SuppressForOption        = FALSE;\r
@@ -1326,6 +1338,7 @@ ParseOpCodes (
   ConditionalExprCount     = 0;\r
   InUnknownScope           = FALSE;\r
   UnknownDepth             = 0;\r
+  QuestionReferBitField    = FALSE;\r
 \r
   //\r
   // Get the number of Statements and Expressions\r
@@ -1709,6 +1722,7 @@ ParseOpCodes (
 \r
       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
+      FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset\r
 \r
       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
         //\r
@@ -1868,17 +1882,31 @@ ParseOpCodes (
     // DefaultStore\r
     //\r
     case EFI_IFR_DEFAULTSTORE_OP:\r
+      HaveInserted = FALSE;\r
       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
       ASSERT (DefaultStore != NULL);\r
       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
 \r
       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
-\r
       //\r
-      // Insert to DefaultStore list of this Formset\r
+      // Insert it to the DefaultStore list of this Formset with ascending order.\r
       //\r
-      InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+      if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
+        DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+        while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+          PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
+          DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
+          if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r
+            InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r
+            HaveInserted = TRUE;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (!HaveInserted) {\r
+        InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+      }\r
       break;\r
 \r
     //\r
@@ -1956,43 +1984,94 @@ ParseOpCodes (
       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
       Value = &CurrentStatement->HiiValue;\r
 \r
-      switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-      case EFI_IFR_NUMERIC_SIZE_1:\r
-        CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
-        CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
-        CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
-        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
-        Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
-        break;\r
+      if (QuestionReferBitField) {\r
+        //\r
+        // Get the bit var store info (bit/byte offset, bit/byte offset)\r
+        //\r
+        CurrentStatement->QuestionReferToBitField = TRUE;\r
+        CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+        CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
+        CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
+        TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
+        CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
 \r
-      case EFI_IFR_NUMERIC_SIZE_2:\r
-        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
-        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
-        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
-        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
-        Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
-        break;\r
+        //\r
+        // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)\r
+        //\r
+        CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;\r
+        CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;\r
+        CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;\r
 \r
-      case EFI_IFR_NUMERIC_SIZE_4:\r
-        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
-        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
-        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
-        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
-        Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
-        break;\r
+        //\r
+        // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,\r
+        // in order to make Browser handle these question with bit varstore correctly.\r
+        //\r
+        ((EFI_IFR_NUMERIC *) OpCodeData)->Flags &=  EDKII_IFR_DISPLAY_BIT;\r
+        ((EFI_IFR_NUMERIC *) OpCodeData)->Flags >>= 2;\r
+        switch (CurrentStatement->StorageWidth) {\r
+        case 1:\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue = (UINT8)CurrentStatement->Minimum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue = (UINT8)CurrentStatement->Maximum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step = (UINT8)CurrentStatement->Step;\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+          break;\r
+        case 2:\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue = (UINT16)CurrentStatement->Minimum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue = (UINT16)CurrentStatement->Maximum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step = (UINT16)CurrentStatement->Step;\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+          break;\r
+        case 3:\r
+        case 4:\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue = (UINT32)CurrentStatement->Minimum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue = (UINT32)CurrentStatement->Maximum;\r
+          ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step = (UINT32)CurrentStatement->Step;\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+          break;\r
+        default:\r
+          break;\r
+        }\r
+      } else {\r
+        switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+        case EFI_IFR_NUMERIC_SIZE_1:\r
+          CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
+          CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
+          CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
+          CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+          break;\r
 \r
-      case EFI_IFR_NUMERIC_SIZE_8:\r
-        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
-        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
-        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
-        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
-        Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
-        break;\r
+        case EFI_IFR_NUMERIC_SIZE_2:\r
+          CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
+          CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
+          CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
+          CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+          break;\r
 \r
-      default:\r
-        break;\r
-      }\r
+        case EFI_IFR_NUMERIC_SIZE_4:\r
+          CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
+          CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
+          CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
+          CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+          break;\r
 \r
+        case EFI_IFR_NUMERIC_SIZE_8:\r
+          CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
+          CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
+          CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
+          CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
+          Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+      }\r
       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
@@ -2023,6 +2102,18 @@ ParseOpCodes (
       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
 \r
+      if (QuestionReferBitField) {\r
+        //\r
+        // Get the bit var store info (bit/byte offset, bit/byte offset)\r
+        //\r
+        CurrentStatement->QuestionReferToBitField = TRUE;\r
+        CurrentStatement->BitStorageWidth = 1;\r
+        CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
+        CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
+        TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
+        CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
+      }\r
+\r
       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       break;\r
@@ -2570,14 +2661,19 @@ ParseOpCodes (
     //\r
     // Vendor specific\r
     //\r
-    case EFI_IFR_GUID_OP:     \r
+    case EFI_IFR_GUID_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+        Scope = 0;\r
+        QuestionReferBitField = TRUE;\r
+      }\r
       break;\r
 \r
     //\r
     // Scope End\r
     //\r
     case EFI_IFR_END_OP:\r
+      QuestionReferBitField = FALSE;\r
       Status = PopScope (&ScopeOpCode);\r
       if (EFI_ERROR (Status)) {\r
         ResetScopeStack ();\r