Revision: 17345
          http://sourceforge.net/p/edk2/code/17345
Author:   ydong10
Date:     2015-05-06 12:30:13 +0000 (Wed, 06 May 2015)
Log Message:
-----------
MdeModulePkg: Enhance the check for numeric opcode with EFI_IFR_DISPLAY_INT_DEC 
attribute.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdeModulePkg/Library/UefiHiiLib/HiiLib.c
    trunk/edk2/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c
    trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c

Modified: trunk/edk2/MdeModulePkg/Library/UefiHiiLib/HiiLib.c
===================================================================
--- trunk/edk2/MdeModulePkg/Library/UefiHiiLib/HiiLib.c 2015-05-06 12:29:33 UTC 
(rev 17344)
+++ trunk/edk2/MdeModulePkg/Library/UefiHiiLib/HiiLib.c 2015-05-06 12:30:13 UTC 
(rev 17345)
@@ -1298,41 +1298,77 @@
             VarValue = 0;
             CopyMem (&VarValue, VarBuffer +  Offset, Width);
           }
-          switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
-          case EFI_IFR_NUMERIC_SIZE_1:
-            if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) 
VarValue > IfrNumeric->data.u8.MaxValue) {
-              //
-              // Not in the valid range.
-              //
-              return EFI_INVALID_PARAMETER;
+          if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {
+            switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
+            case EFI_IFR_NUMERIC_SIZE_1:
+              if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || 
(INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_2:
+              if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || 
(INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_4:
+              if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || 
(INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_8:
+              if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || 
(INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
             }
-            break;
-          case EFI_IFR_NUMERIC_SIZE_2:
-            if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) 
VarValue > IfrNumeric->data.u16.MaxValue) {
-              //
-              // Not in the valid range.
-              //
-              return EFI_INVALID_PARAMETER;
+          } else {
+            switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
+            case EFI_IFR_NUMERIC_SIZE_1:
+              if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) 
VarValue > IfrNumeric->data.u8.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_2:
+              if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || 
(UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_4:
+              if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || 
(UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
+            case EFI_IFR_NUMERIC_SIZE_8:
+              if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || 
(UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {
+                //
+                // Not in the valid range.
+                //
+                return EFI_INVALID_PARAMETER;
+              }
+              break;
             }
-            break;
-          case EFI_IFR_NUMERIC_SIZE_4:
-            if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) 
VarValue > IfrNumeric->data.u32.MaxValue) {
-              //
-              // Not in the valid range.
-              //
-              return EFI_INVALID_PARAMETER;
-            }
-            break;
-          case EFI_IFR_NUMERIC_SIZE_8:
-            if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) 
VarValue > IfrNumeric->data.u64.MaxValue) {
-              //
-              // Not in the valid range.
-              //
-              return EFI_INVALID_PARAMETER;
-            }
-            break;
           }
-
           break;
         case EFI_IFR_CHECKBOX_OP:
           //

Modified: trunk/edk2/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c   
2015-05-06 12:29:33 UTC (rev 17344)
+++ trunk/edk2/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c   
2015-05-06 12:30:13 UTC (rev 17345)
@@ -368,6 +368,9 @@
   Get field info from numeric opcode.
 
   @param  OpCode            Pointer to the current input opcode.
+  @param  IntInput          Whether question shows with 
EFI_IFR_DISPLAY_INT_DEC type.
+  @param  QuestionValue     Input question value, with EFI_HII_VALUE type.
+  @param  Value             Return question value, always return UINT64 type.
   @param  Minimum           The minimum size info for this opcode.
   @param  Maximum           The maximum size info for this opcode.
   @param  Step              The step size info for this opcode.
@@ -377,6 +380,9 @@
 VOID
 GetValueFromNum (
   IN  EFI_IFR_OP_HEADER     *OpCode,
+  IN  BOOLEAN               IntInput,
+  IN  EFI_HII_VALUE         *QuestionValue,
+  OUT UINT64                *Value,
   OUT UINT64                *Minimum,
   OUT UINT64                *Maximum,
   OUT UINT64                *Step,
@@ -389,29 +395,57 @@
   
   switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
   case EFI_IFR_NUMERIC_SIZE_1:
-    *Minimum = NumericOp->data.u8.MinValue;
-    *Maximum = NumericOp->data.u8.MaxValue;
+    if (IntInput) {
+      *Minimum = (INT64) (INT8) NumericOp->data.u8.MinValue;
+      *Maximum = (INT64) (INT8) NumericOp->data.u8.MaxValue;
+      *Value   = (INT64) (INT8) QuestionValue->Value.u8;
+    } else {
+      *Minimum = NumericOp->data.u8.MinValue;
+      *Maximum = NumericOp->data.u8.MaxValue;
+      *Value   = QuestionValue->Value.u8;
+    }
     *Step    = NumericOp->data.u8.Step;
     *StorageWidth = (UINT16) sizeof (UINT8);
     break;
   
   case EFI_IFR_NUMERIC_SIZE_2:
-    *Minimum = NumericOp->data.u16.MinValue;
-    *Maximum = NumericOp->data.u16.MaxValue;
+    if (IntInput) {
+      *Minimum = (INT64) (INT16) NumericOp->data.u16.MinValue;
+      *Maximum = (INT64) (INT16) NumericOp->data.u16.MaxValue;
+      *Value   = (INT64) (INT16) QuestionValue->Value.u16;
+    } else {
+      *Minimum = NumericOp->data.u16.MinValue;
+      *Maximum = NumericOp->data.u16.MaxValue;
+      *Value   = QuestionValue->Value.u16;
+    }
     *Step    = NumericOp->data.u16.Step;
     *StorageWidth = (UINT16) sizeof (UINT16);
     break;
   
   case EFI_IFR_NUMERIC_SIZE_4:
-    *Minimum = NumericOp->data.u32.MinValue;
-    *Maximum = NumericOp->data.u32.MaxValue;
+    if (IntInput) {
+      *Minimum = (INT64) (INT32) NumericOp->data.u32.MinValue;
+      *Maximum = (INT64) (INT32) NumericOp->data.u32.MaxValue;
+      *Value   = (INT64) (INT32) QuestionValue->Value.u32;
+    } else {
+      *Minimum = NumericOp->data.u32.MinValue;
+      *Maximum = NumericOp->data.u32.MaxValue;
+      *Value   = QuestionValue->Value.u32;
+    }
     *Step    = NumericOp->data.u32.Step;
     *StorageWidth = (UINT16) sizeof (UINT32);
     break;
   
   case EFI_IFR_NUMERIC_SIZE_8:
-    *Minimum = NumericOp->data.u64.MinValue;
-    *Maximum = NumericOp->data.u64.MaxValue;
+    if (IntInput) {
+      *Minimum = (INT64) NumericOp->data.u64.MinValue;
+      *Maximum = (INT64) NumericOp->data.u64.MaxValue;
+      *Value   = (INT64) QuestionValue->Value.u64;
+    } else {
+      *Minimum = NumericOp->data.u64.MinValue;
+      *Maximum = NumericOp->data.u64.MaxValue;
+      *Value   = QuestionValue->Value.u64;
+    }
     *Step    = NumericOp->data.u64.Step;
     *StorageWidth = (UINT16) sizeof (UINT64);
     break;
@@ -448,6 +482,9 @@
   UINTN                   Loop;
   BOOLEAN                 ManualInput;
   BOOLEAN                 HexInput;
+  BOOLEAN                 IntInput;
+  BOOLEAN                 Negative;
+  BOOLEAN                 ValidateFail;
   BOOLEAN                 DateOrTime;
   UINTN                   InputWidth;
   UINT64                  EditValue;
@@ -472,6 +509,10 @@
   Minimum           = 0;
   Maximum           = 0;
   NumericOp         = NULL;
+  IntInput          = FALSE;
+  HexInput          = FALSE;
+  Negative          = FALSE;
+  ValidateFail      = FALSE;
 
   Question      = MenuOption->ThisTag;
   QuestionValue = &Question->CurrentValue;
@@ -568,16 +609,19 @@
   } else {
     ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP);
     NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode;
-    GetValueFromNum(Question->OpCode, &Minimum, &Maximum, &Step, 
&StorageWidth);
-    EditValue = QuestionValue->Value.u64;
+    GetValueFromNum(Question->OpCode, (NumericOp->Flags & EFI_IFR_DISPLAY) == 
0, QuestionValue, &EditValue, &Minimum, &Maximum, &Step, &StorageWidth);
     EraseLen  = gOptionBlockWidth;
   }
 
-  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) 
&&
-      ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
-    HexInput = TRUE;
-  } else {
-    HexInput = FALSE;
+  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL)) 
{
+    if ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX){
+      HexInput = TRUE;
+    } else if ((NumericOp->Flags & EFI_IFR_DISPLAY) == 0){
+      //
+      // Display with EFI_IFR_DISPLAY_INT_DEC type. Support negative number.
+      //
+      IntInput = TRUE;
+    }
   }
 
   //
@@ -609,6 +653,13 @@
           InputWidth = 0;
           break;
         }
+
+        if (IntInput) {
+          //
+          // Support an extra '-' for negative number.
+          //
+          InputWidth += 1;
+        }
       }
 
       InputText[0] = LEFT_NUMERIC_DELIMITER;
@@ -691,13 +742,27 @@
 
     case '+':
     case '-':
-      if (Key.UnicodeChar == '+') {
-        Key.ScanCode = SCAN_RIGHT;
+      if (ManualInput && IntInput) {
+        //
+        // In Manual input mode, check whether input the negative flag.
+        //
+        if (Key.UnicodeChar == '-') {
+          if (Negative) {
+            break;
+          }
+          Negative = TRUE;
+          PrintCharAt (Column++, Row, Key.UnicodeChar);
+        }
       } else {
-        Key.ScanCode = SCAN_LEFT;
+        if (Key.UnicodeChar == '+') {
+          Key.ScanCode = SCAN_RIGHT;
+        } else {
+          Key.ScanCode = SCAN_LEFT;
+        }
+        Key.UnicodeChar = CHAR_NULL;
+        goto TheKey2;
       }
-      Key.UnicodeChar = CHAR_NULL;
-      goto TheKey2;
+      break;
 
     case CHAR_NULL:
       switch (Key.ScanCode) {
@@ -715,20 +780,40 @@
 
         if ((Step != 0) && !ManualInput) {
           if (Key.ScanCode == SCAN_LEFT) {
-            if (EditValue >= Minimum + Step) {
-              EditValue = EditValue - Step;
-            } else if (EditValue > Minimum){
-              EditValue = Minimum;
+            if (IntInput) {
+              if ((INT64) EditValue >= (INT64) Minimum + (INT64) Step) {
+                EditValue = EditValue - Step;
+              } else if ((INT64) EditValue > (INT64) Minimum){
+                EditValue = Minimum;
+              } else {
+                EditValue = Maximum;
+              }
             } else {
-              EditValue = Maximum;
+              if (EditValue >= Minimum + Step) {
+                EditValue = EditValue - Step;
+              } else if (EditValue > Minimum){
+                EditValue = Minimum;
+              } else {
+                EditValue = Maximum;
+              }
             }
           } else if (Key.ScanCode == SCAN_RIGHT) {
-            if (EditValue + Step <= Maximum) {
-              EditValue = EditValue + Step;
-            } else if (EditValue < Maximum) {
-              EditValue = Maximum;
+            if (IntInput) {
+              if ((INT64) EditValue + (INT64) Step <= (INT64) Maximum) {
+                EditValue = EditValue + Step;
+              } else if ((INT64) EditValue < (INT64) Maximum) {
+                EditValue = Maximum;
+              } else {
+                EditValue = Minimum;
+              }
             } else {
-              EditValue = Minimum;
+              if (EditValue + Step <= Maximum) {
+                EditValue = EditValue + Step;
+              } else if (EditValue < Maximum) {
+                EditValue = Maximum;
+              } else {
+                EditValue = Minimum;
+              }
             }
           }
 
@@ -808,13 +893,29 @@
       //
       // Validate input value with Minimum value.
       //
-      if (EditValue < Minimum) {
+      ValidateFail = FALSE;
+      if (IntInput) {
+        //
+        // After user input Enter, need to check whether the input value.
+        // If input a negative value, should compare with maximum value. 
+        // else compare with the minimum value.
+        //
+        if (Negative) {
+          ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE;
+        } else {
+          ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE;
+        }
+
+        if (ValidateFail) {
+          UpdateStatusBar (INPUT_ERROR, TRUE);
+          break;
+        }
+      } else if (EditValue < Minimum) {
         UpdateStatusBar (INPUT_ERROR, TRUE);
         break;
-      } else {
-        UpdateStatusBar (INPUT_ERROR, FALSE);
       }
-      
+
+      UpdateStatusBar (INPUT_ERROR, FALSE);
       CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof 
(EFI_HII_VALUE));
       QuestionValue = &gUserInput->InputValue;
       //
@@ -877,6 +978,11 @@
     case CHAR_BACKSPACE:
       if (ManualInput) {
         if (Count == 0) {
+          if (Negative) {
+            Negative = FALSE;
+            Column--;
+            PrintStringAt (Column, Row, L" ");
+          }
           break;
         }
         //
@@ -922,26 +1028,57 @@
         if (Count != 0) {
           if (HexInput) {
             EditValue = LShiftU64 (EditValue, 4) + Digital;
+          } else if (IntInput && Negative) {
+            //
+            // Save the negative number.
+            //
+            EditValue = ~(MultU64x32 (~(EditValue - 1), 10) + (Key.UnicodeChar 
- L'0')) + 1;
           } else {
             EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');
           }
         } else {
           if (HexInput) {
             EditValue = Digital;
+          } else if (IntInput && Negative) {
+            //
+            // Save the negative number.
+            //
+            EditValue = ~(Key.UnicodeChar - L'0') + 1;
           } else {
             EditValue = Key.UnicodeChar - L'0';
           }
         }
 
-        if (EditValue > Maximum) {
-          UpdateStatusBar (INPUT_ERROR, TRUE);
-          ASSERT (Count < sizeof (PreviousNumber) / sizeof 
(PreviousNumber[0]));
-          EditValue = PreviousNumber[Count];
-          break;
+        if (IntInput) {
+          ValidateFail = FALSE;
+          //
+          // When user input a new value, should check the current value.
+          // If user input a negative value, should compare it with minimum
+          // value, else compare it with maximum value.
+          //
+          if (Negative) {
+            ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE;
+          } else {
+            ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE;
+          }
+
+          if (ValidateFail) {
+            UpdateStatusBar (INPUT_ERROR, TRUE);
+            ASSERT (Count < sizeof (PreviousNumber) / sizeof 
(PreviousNumber[0]));
+            EditValue = PreviousNumber[Count];
+            break;
+          }
         } else {
-          UpdateStatusBar (INPUT_ERROR, FALSE);
+          if (EditValue > Maximum) {
+            UpdateStatusBar (INPUT_ERROR, TRUE);
+            ASSERT (Count < sizeof (PreviousNumber) / sizeof 
(PreviousNumber[0]));
+            EditValue = PreviousNumber[Count];
+            break;
+          }
         }
 
+        UpdateStatusBar (INPUT_ERROR, FALSE);
+
         Count++;
         ASSERT (Count < (sizeof (PreviousNumber) / sizeof 
(PreviousNumber[0])));
         PreviousNumber[Count] = EditValue;

Modified: trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c   2015-05-06 
12:29:33 UTC (rev 17344)
+++ trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c   2015-05-06 
12:30:13 UTC (rev 17345)
@@ -3944,9 +3944,43 @@
     //
     // Take minimum value as numeric default value
     //
-    if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > 
Question->Maximum)) {
-      HiiValue->Value.u64 = Question->Minimum;
-      Status = EFI_SUCCESS;
+    if ((Question->Flags & EFI_IFR_DISPLAY) == 0) {
+      //
+      // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type.
+      //
+      switch (Question->Flags & EFI_IFR_NUMERIC_SIZE) {
+      case EFI_IFR_NUMERIC_SIZE_1:
+        if (((INT8) HiiValue->Value.u8 < (INT8) Question->Minimum) || ((INT8) 
HiiValue->Value.u8 > (INT8) Question->Maximum)) {
+          HiiValue->Value.u8 = (UINT8) Question->Minimum;
+          Status = EFI_SUCCESS;
+        }
+        break;
+      case EFI_IFR_NUMERIC_SIZE_2:
+        if (((INT16) HiiValue->Value.u16 < (INT16) Question->Minimum) || 
((INT16) HiiValue->Value.u16 > (INT16) Question->Maximum)) {
+          HiiValue->Value.u16 = (UINT16) Question->Minimum;
+          Status = EFI_SUCCESS;
+        }
+        break;
+      case EFI_IFR_NUMERIC_SIZE_4:
+        if (((INT32) HiiValue->Value.u32 < (INT32) Question->Minimum) || 
((INT32) HiiValue->Value.u32 > (INT32) Question->Maximum)) {
+          HiiValue->Value.u32 = (UINT32) Question->Minimum;
+          Status = EFI_SUCCESS;
+        }
+        break;
+      case EFI_IFR_NUMERIC_SIZE_8:
+        if (((INT64) HiiValue->Value.u64 < (INT64) Question->Minimum) || 
((INT64) HiiValue->Value.u64 > (INT64) Question->Maximum)) {
+          HiiValue->Value.u64 = Question->Minimum;
+          Status = EFI_SUCCESS;
+        }
+        break;
+      default:
+        break;     
+      }
+    } else {
+      if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > 
Question->Maximum)) {
+        HiiValue->Value.u64 = Question->Minimum;
+        Status = EFI_SUCCESS;
+      }
     }
     break;
 


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to