]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/UefiHiiLib: Validate question with bit fields
authorDandan Bi <dandan.bi@intel.com>
Wed, 20 Sep 2017 11:43:45 +0000 (19:43 +0800)
committerEric Dong <eric.dong@intel.com>
Thu, 21 Sep 2017 08:17:41 +0000 (16:17 +0800)
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=545

In UefiHiiLib, there are codes to validate the current setting of
questions, now update the logic to handle question with bit storage.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
MdeModulePkg/Library/UefiHiiLib/HiiLib.c
MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h
MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf

index 583b9e516c65645d06c6e98cc674fd9f6bd1ff3e..ce894c08b573b529313c5048c1dea3f9b23a7ebe 100644 (file)
@@ -1169,6 +1169,13 @@ ValidateQuestionFromVfr (
   UINTN                        Index;\r
   CHAR16                       *QuestionName;\r
   CHAR16                       *StringPtr;\r
+  UINT16                       BitOffset;\r
+  UINT16                       BitWidth;\r
+  UINT16                       TotalBits;\r
+  UINTN                        StartBit;\r
+  UINTN                        EndBit;\r
+  BOOLEAN                      QuestionReferBitField;\r
+  UINT32                       BufferValue;\r
 \r
   //\r
   // Initialize the local variables.\r
@@ -1182,6 +1189,9 @@ ValidateQuestionFromVfr (
   IfrEfiVarStore    = NULL;\r
   ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));\r
   ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
+  BitOffset = 0;\r
+  BitWidth = 0;\r
+  QuestionReferBitField = FALSE;\r
 \r
   //\r
   // Check IFR value is in block data, then Validate Value\r
@@ -1345,8 +1355,19 @@ ValidateQuestionFromVfr (
             //\r
             // Get Offset by Question header and Width by DataType Flags\r
             //\r
-            Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
-            Width  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+            if (QuestionReferBitField) {\r
+              //\r
+              // Get the byte offset/width for bit field.\r
+              //\r
+              BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+              BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+              Offset = BitOffset / 8;\r
+              TotalBits = BitOffset % 8 + BitWidth;\r
+              Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+            } else {\r
+              Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+              Width  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+            }\r
             //\r
             // Check whether this question is in current block array.\r
             //\r
@@ -1370,7 +1391,17 @@ ValidateQuestionFromVfr (
             // Get the current value for oneof opcode\r
             //\r
             VarValue = 0;\r
-            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+            if (QuestionReferBitField) {\r
+              //\r
+              // Get the value in bit fields.\r
+              //\r
+              StartBit = BitOffset % 8;\r
+              EndBit = StartBit + BitWidth - 1;\r
+              CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+              VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+            } else {\r
+              CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+            }\r
           }\r
           //\r
           // Set Block Data, to be checked in the following Oneof option opcode.\r
@@ -1416,8 +1447,19 @@ ValidateQuestionFromVfr (
             //\r
             // Get Offset by Question header and Width by DataType Flags\r
             //\r
-            Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
-            Width  = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
+            if (QuestionReferBitField) {\r
+              //\r
+              // Get the byte offset/width for bit field.\r
+              //\r
+              BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+              BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+              Offset = BitOffset / 8;\r
+              TotalBits = BitOffset % 8 + BitWidth;\r
+              Width  = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+            } else {\r
+              Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+              Width  = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
+            }\r
             //\r
             // Check whether this question is in current block array.\r
             //\r
@@ -1441,77 +1483,108 @@ ValidateQuestionFromVfr (
             // Check the current value is in the numeric range.\r
             //\r
             VarValue = 0;\r
-            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
-          }\r
-          if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {\r
-            switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-            case EFI_IFR_NUMERIC_SIZE_1:\r
-              if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_2:\r
-              if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_4:\r
-              if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_8:\r
-              if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
+            if (QuestionReferBitField) {\r
+              //\r
+              // Get the value in the bit fields.\r
+              //\r
+              StartBit = BitOffset % 8;\r
+              EndBit = StartBit + BitWidth - 1;\r
+              CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+              VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+            } else {\r
+              CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
             }\r
+          }\r
+          if ( QuestionReferBitField) {\r
+             //\r
+             // Value in bit fields was stored as UINt32 type.\r
+             //\r
+             if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) {\r
+               if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+             } else {\r
+               if (VarValue < IfrNumeric->data.u32.MinValue || VarValue > IfrNumeric->data.u32.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+             }\r
           } else {\r
-            switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-            case EFI_IFR_NUMERIC_SIZE_1:\r
-              if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_2:\r
-              if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
-              }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_4:\r
-              if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
+            if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {\r
+              switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+              case EFI_IFR_NUMERIC_SIZE_1:\r
+                if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_2:\r
+                if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_4:\r
+                if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_8:\r
+                if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
               }\r
-              break;\r
-            case EFI_IFR_NUMERIC_SIZE_8:\r
-              if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {\r
-                //\r
-                // Not in the valid range.\r
-                //\r
-                return EFI_INVALID_PARAMETER;\r
+            } else {\r
+              switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+              case EFI_IFR_NUMERIC_SIZE_1:\r
+                if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_2:\r
+                if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_4:\r
+                if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
+              case EFI_IFR_NUMERIC_SIZE_8:\r
+                if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {\r
+                  //\r
+                  // Not in the valid range.\r
+                  //\r
+                  return EFI_INVALID_PARAMETER;\r
+                }\r
+                break;\r
               }\r
-              break;\r
             }\r
           }\r
           break;\r
@@ -1554,8 +1627,19 @@ ValidateQuestionFromVfr (
             //\r
             // Get Offset by Question header\r
             //\r
-            Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
-            Width  = (UINT16) sizeof (BOOLEAN);\r
+           if (QuestionReferBitField) {\r
+              //\r
+              // Get the byte offset/width for bit field.\r
+              //\r
+              BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+              BitWidth = 1;\r
+              Offset = BitOffset / 8;\r
+              TotalBits = BitOffset % 8 + BitWidth;\r
+              Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+            } else {\r
+              Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+              Width  = (UINT16) sizeof (BOOLEAN);\r
+            }\r
             //\r
             // Check whether this question is in current block array.\r
             //\r
@@ -1578,7 +1662,17 @@ ValidateQuestionFromVfr (
             // Check the current value is in the numeric range.\r
             //\r
             VarValue = 0;\r
-            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+            if (QuestionReferBitField) {\r
+              //\r
+              // Get the value in bit fields.\r
+              //\r
+              StartBit = BitOffset % 8;\r
+              EndBit = StartBit + BitWidth - 1;\r
+              CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+              VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+            } else {\r
+              CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+            }\r
           }\r
           //\r
           // Boolean type, only 1 and 0 is valid.\r
@@ -1703,6 +1797,7 @@ ValidateQuestionFromVfr (
           }\r
           break;\r
         case EFI_IFR_END_OP:\r
+          QuestionReferBitField = FALSE;\r
           //\r
           // Decrease opcode scope for the validated opcode\r
           //\r
@@ -1717,6 +1812,11 @@ ValidateQuestionFromVfr (
             return EFI_INVALID_PARAMETER;\r
           }\r
           break;\r
+        case EFI_IFR_GUID_OP:\r
+          if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+            QuestionReferBitField = TRUE;\r
+          }\r
+          break;\r
         default:\r
           //\r
           // Increase Scope for the validated opcode\r
index 9bf7696ea380b320dd9844f6a7e33059894b5389..293c22666d27dcdd37a4cef94480f5530fcfc78b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Internal include file for the HII Library instance.\r
 \r
-  Copyright (c) 2007, 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
@@ -20,6 +20,8 @@
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/FormBrowser2.h>\r
 \r
+#include <Guid/MdeModuleHii.h>\r
+\r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/HiiLib.h>\r
index 62f435a089bea9fc2dffd7b6208486cf29d28985..7ee68428a1f513f21e3a654ecd7088a371008e66 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  HII Library implementation using UEFI HII protocols and services.\r
 #\r
-#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -51,3 +51,6 @@
 [Protocols]\r
   gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES\r
   gEfiDevicePathProtocolGuid   ## SOMETIMES_CONSUMES\r
+\r
+[Guids]\r
+  gEdkiiIfrBitVarstoreGuid       ## SOMETIMES_CONSUMES ## GUID\r