]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / DisplayEngineDxe / InputHandler.c
index f76937a442221295187e7c7ade31933a88d091e0..cf829a32145ffa955d8f32b7347e83738c667320 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Implementation for handling user input from the User Interfaces.\r
 \r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, 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
@@ -34,14 +34,14 @@ GetFieldFromOp (
   if (OpCode->OpCode == EFI_IFR_STRING_OP) {\r
     StringOp = (EFI_IFR_STRING *) OpCode;\r
     *Minimum = StringOp->MinSize;\r
-    *Maximum = StringOp->MaxSize;    \r
+    *Maximum = StringOp->MaxSize;\r
   } else if (OpCode->OpCode == EFI_IFR_PASSWORD_OP) {\r
     PasswordOp = (EFI_IFR_PASSWORD *) OpCode;\r
     *Minimum = PasswordOp->MinSize;\r
-    *Maximum = PasswordOp->MaxSize;       \r
+    *Maximum = PasswordOp->MaxSize;\r
   } else {\r
     *Minimum = 0;\r
-    *Maximum = 0;       \r
+    *Maximum = 0;\r
   }\r
 }\r
 \r
@@ -84,6 +84,7 @@ ReadString (
   UINTN                   Maximum;\r
   FORM_DISPLAY_ENGINE_STATEMENT  *Question;\r
   BOOLEAN                 IsPassword;\r
+  UINTN                   MaxLen;\r
 \r
   DimensionsWidth  = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;\r
   DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;\r
@@ -102,7 +103,8 @@ ReadString (
     IsPassword = FALSE;\r
   }\r
 \r
-  TempString = AllocateZeroPool ((Maximum + 1)* sizeof (CHAR16));\r
+  MaxLen = Maximum + 1;\r
+  TempString = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
   ASSERT (TempString);\r
 \r
   if (ScreenSize < (Maximum + 1)) {\r
@@ -158,11 +160,11 @@ ReadString (
     if (!IsPassword) {\r
       PrintStringAt (Start + 1, Top + 3, BufferedString);\r
     }\r
-    \r
+\r
     gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
     gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);\r
   }\r
-  \r
+\r
   do {\r
     Status = WaitForKeyStroke (&Key);\r
     ASSERT_EFI_ERROR (Status);\r
@@ -190,6 +192,13 @@ ReadString (
         gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
         return EFI_DEVICE_ERROR;\r
 \r
+       case SCAN_DELETE:\r
+        for (Index = CurrentCursor; StringPtr[Index] != CHAR_NULL; Index++) {\r
+          StringPtr[Index] = StringPtr[Index + 1];\r
+          PrintCharAt (Start + Index + 1, Top + 3, IsPassword && StringPtr[Index] != CHAR_NULL? L'*' : StringPtr[Index]);\r
+        }\r
+        break;\r
+\r
       default:\r
         break;\r
       }\r
@@ -220,7 +229,6 @@ ReadString (
         return EFI_DEVICE_ERROR;\r
       }\r
 \r
-      break;\r
 \r
     case CHAR_BACKSPACE:\r
       if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) {\r
@@ -237,7 +245,7 @@ ReadString (
         //\r
         // Effectively truncate string by 1 character\r
         //\r
-        StrCpy (StringPtr, TempString);\r
+        StrCpyS (StringPtr, MaxLen, TempString);\r
         CurrentCursor --;\r
       }\r
 \r
@@ -246,7 +254,7 @@ ReadString (
       // If it is the beginning of the string, don't worry about checking maximum limits\r
       //\r
       if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
-        StrnCpy (StringPtr, &Key.UnicodeChar, 1);\r
+        StrnCpyS (StringPtr, MaxLen, &Key.UnicodeChar, 1);\r
         CurrentCursor++;\r
       } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
         KeyPad[0] = Key.UnicodeChar;\r
@@ -256,12 +264,12 @@ ReadString (
           for (Index = 0; Index < CurrentCursor; Index++) {\r
             TempString[Index] = StringPtr[Index];\r
           }\r
-                 TempString[Index] = CHAR_NULL;\r
-          StrCat (TempString, KeyPad);\r
-          StrCat (TempString, StringPtr + CurrentCursor);\r
-          StrCpy (StringPtr, TempString);\r
+      TempString[Index] = CHAR_NULL;\r
+          StrCatS (TempString, MaxLen, KeyPad);\r
+          StrCatS (TempString, MaxLen, StringPtr + CurrentCursor);\r
+          StrCpyS (StringPtr, MaxLen, TempString);\r
         } else {\r
-          StrCat (StringPtr, KeyPad);\r
+          StrCatS (StringPtr, MaxLen, KeyPad);\r
         }\r
         CurrentCursor++;\r
       }\r
@@ -353,7 +361,7 @@ AdjustQuestionValue (
       QuestionValue->Value.date.Day = Maximum;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Change the Year area.\r
   //\r
@@ -368,6 +376,9 @@ AdjustQuestionValue (
   Get field info from numeric opcode.\r
 \r
   @param  OpCode            Pointer to the current input opcode.\r
+  @param  IntInput          Whether question shows with EFI_IFR_DISPLAY_INT_DEC type.\r
+  @param  QuestionValue     Input question value, with EFI_HII_VALUE type.\r
+  @param  Value             Return question value, always return UINT64 type.\r
   @param  Minimum           The minimum size info for this opcode.\r
   @param  Maximum           The maximum size info for this opcode.\r
   @param  Step              The step size info for this opcode.\r
@@ -377,6 +388,9 @@ AdjustQuestionValue (
 VOID\r
 GetValueFromNum (\r
   IN  EFI_IFR_OP_HEADER     *OpCode,\r
+  IN  BOOLEAN               IntInput,\r
+  IN  EFI_HII_VALUE         *QuestionValue,\r
+  OUT UINT64                *Value,\r
   OUT UINT64                *Minimum,\r
   OUT UINT64                *Maximum,\r
   OUT UINT64                *Step,\r
@@ -386,36 +400,64 @@ GetValueFromNum (
   EFI_IFR_NUMERIC       *NumericOp;\r
 \r
   NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
-  \r
+\r
   switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
   case EFI_IFR_NUMERIC_SIZE_1:\r
-    *Minimum = NumericOp->data.u8.MinValue;\r
-    *Maximum = NumericOp->data.u8.MaxValue;\r
+    if (IntInput) {\r
+      *Minimum = (INT64) (INT8) NumericOp->data.u8.MinValue;\r
+      *Maximum = (INT64) (INT8) NumericOp->data.u8.MaxValue;\r
+      *Value   = (INT64) (INT8) QuestionValue->Value.u8;\r
+    } else {\r
+      *Minimum = NumericOp->data.u8.MinValue;\r
+      *Maximum = NumericOp->data.u8.MaxValue;\r
+      *Value   = QuestionValue->Value.u8;\r
+    }\r
     *Step    = NumericOp->data.u8.Step;\r
     *StorageWidth = (UINT16) sizeof (UINT8);\r
     break;\r
-  \r
+\r
   case EFI_IFR_NUMERIC_SIZE_2:\r
-    *Minimum = NumericOp->data.u16.MinValue;\r
-    *Maximum = NumericOp->data.u16.MaxValue;\r
+    if (IntInput) {\r
+      *Minimum = (INT64) (INT16) NumericOp->data.u16.MinValue;\r
+      *Maximum = (INT64) (INT16) NumericOp->data.u16.MaxValue;\r
+      *Value   = (INT64) (INT16) QuestionValue->Value.u16;\r
+    } else {\r
+      *Minimum = NumericOp->data.u16.MinValue;\r
+      *Maximum = NumericOp->data.u16.MaxValue;\r
+      *Value   = QuestionValue->Value.u16;\r
+    }\r
     *Step    = NumericOp->data.u16.Step;\r
     *StorageWidth = (UINT16) sizeof (UINT16);\r
     break;\r
-  \r
+\r
   case EFI_IFR_NUMERIC_SIZE_4:\r
-    *Minimum = NumericOp->data.u32.MinValue;\r
-    *Maximum = NumericOp->data.u32.MaxValue;\r
+    if (IntInput) {\r
+      *Minimum = (INT64) (INT32) NumericOp->data.u32.MinValue;\r
+      *Maximum = (INT64) (INT32) NumericOp->data.u32.MaxValue;\r
+      *Value   = (INT64) (INT32) QuestionValue->Value.u32;\r
+    } else {\r
+      *Minimum = NumericOp->data.u32.MinValue;\r
+      *Maximum = NumericOp->data.u32.MaxValue;\r
+      *Value   = QuestionValue->Value.u32;\r
+    }\r
     *Step    = NumericOp->data.u32.Step;\r
     *StorageWidth = (UINT16) sizeof (UINT32);\r
     break;\r
-  \r
+\r
   case EFI_IFR_NUMERIC_SIZE_8:\r
-    *Minimum = NumericOp->data.u64.MinValue;\r
-    *Maximum = NumericOp->data.u64.MaxValue;\r
+    if (IntInput) {\r
+      *Minimum = (INT64) NumericOp->data.u64.MinValue;\r
+      *Maximum = (INT64) NumericOp->data.u64.MaxValue;\r
+      *Value   = (INT64) QuestionValue->Value.u64;\r
+    } else {\r
+      *Minimum = NumericOp->data.u64.MinValue;\r
+      *Maximum = NumericOp->data.u64.MaxValue;\r
+      *Value   = QuestionValue->Value.u64;\r
+    }\r
     *Step    = NumericOp->data.u64.Step;\r
     *StorageWidth = (UINT16) sizeof (UINT64);\r
     break;\r
-  \r
+\r
   default:\r
     break;\r
   }\r
@@ -448,6 +490,9 @@ GetNumericInput (
   UINTN                   Loop;\r
   BOOLEAN                 ManualInput;\r
   BOOLEAN                 HexInput;\r
+  BOOLEAN                 IntInput;\r
+  BOOLEAN                 Negative;\r
+  BOOLEAN                 ValidateFail;\r
   BOOLEAN                 DateOrTime;\r
   UINTN                   InputWidth;\r
   UINT64                  EditValue;\r
@@ -472,9 +517,14 @@ GetNumericInput (
   Minimum           = 0;\r
   Maximum           = 0;\r
   NumericOp         = NULL;\r
+  IntInput          = FALSE;\r
+  HexInput          = FALSE;\r
+  Negative          = FALSE;\r
+  ValidateFail      = FALSE;\r
 \r
   Question      = MenuOption->ThisTag;\r
   QuestionValue = &Question->CurrentValue;\r
+  ZeroMem (InputText, MAX_NUMERIC_INPUT_WIDTH * sizeof (CHAR16));\r
 \r
   //\r
   // Only two case, user can enter to this function: Enter and +/- case.\r
@@ -507,8 +557,8 @@ GetNumericInput (
     case 1:\r
       switch (QuestionValue->Value.date.Month) {\r
       case 2:\r
-        if ((QuestionValue->Value.date.Year % 4) == 0  && \r
-            ((QuestionValue->Value.date.Year % 100) != 0 || \r
+        if ((QuestionValue->Value.date.Year % 4) == 0  &&\r
+            ((QuestionValue->Value.date.Year % 100) != 0 ||\r
             (QuestionValue->Value.date.Year % 400) == 0)) {\r
           Maximum = 29;\r
         } else {\r
@@ -524,7 +574,7 @@ GetNumericInput (
       default:\r
         Maximum = 31;\r
         break;\r
-      } \r
+      }\r
 \r
       EraseLen = 3;\r
       EditValue = QuestionValue->Value.date.Day;\r
@@ -568,16 +618,19 @@ GetNumericInput (
   } else {\r
     ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP);\r
     NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode;\r
-    GetValueFromNum(Question->OpCode, &Minimum, &Maximum, &Step, &StorageWidth);\r
-    EditValue = QuestionValue->Value.u64;\r
+    GetValueFromNum(Question->OpCode, (NumericOp->Flags & EFI_IFR_DISPLAY) == 0, QuestionValue, &EditValue, &Minimum, &Maximum, &Step, &StorageWidth);\r
     EraseLen  = gOptionBlockWidth;\r
   }\r
 \r
-  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) &&\r
-      ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {\r
-    HexInput = TRUE;\r
-  } else {\r
-    HexInput = FALSE;\r
+  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL)) {\r
+    if ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX){\r
+      HexInput = TRUE;\r
+    } else if ((NumericOp->Flags & EFI_IFR_DISPLAY) == 0){\r
+      //\r
+      // Display with EFI_IFR_DISPLAY_INT_DEC type. Support negative number.\r
+      //\r
+      IntInput = TRUE;\r
+    }\r
   }\r
 \r
   //\r
@@ -609,6 +662,13 @@ GetNumericInput (
           InputWidth = 0;\r
           break;\r
         }\r
+\r
+        if (IntInput) {\r
+          //\r
+          // Support an extra '-' for negative number.\r
+          //\r
+          InputWidth += 1;\r
+        }\r
       }\r
 \r
       InputText[0] = LEFT_NUMERIC_DELIMITER;\r
@@ -631,16 +691,17 @@ GetNumericInput (
       if (MenuOption->Sequence == 0) {\r
         InputText[0] = LEFT_NUMERIC_DELIMITER;\r
         SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
-      } else {\r
+        InputText[InputWidth + 1] = DATE_SEPARATOR;\r
+        InputText[InputWidth + 2] = L'\0';\r
+      } else  if (MenuOption->Sequence == 1){\r
         SetUnicodeMem (InputText, InputWidth, L' ');\r
-      }\r
-\r
-      if (MenuOption->Sequence == 2) {\r
-        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
+        InputText[InputWidth] = DATE_SEPARATOR;\r
+        InputText[InputWidth + 1] = L'\0';\r
       } else {\r
-        InputText[InputWidth + 1] = DATE_SEPARATOR;\r
+        SetUnicodeMem (InputText, InputWidth, L' ');\r
+        InputText[InputWidth] = RIGHT_NUMERIC_DELIMITER;\r
+        InputText[InputWidth + 1] = L'\0';\r
       }\r
-      InputText[InputWidth + 2] = L'\0';\r
 \r
       PrintStringAt (Column, Row, InputText);\r
       if (MenuOption->Sequence == 0) {\r
@@ -654,16 +715,17 @@ GetNumericInput (
       if (MenuOption->Sequence == 0) {\r
         InputText[0] = LEFT_NUMERIC_DELIMITER;\r
         SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
-      } else {\r
+        InputText[InputWidth + 1] = TIME_SEPARATOR;\r
+        InputText[InputWidth + 2] = L'\0';\r
+      } else if (MenuOption->Sequence == 1){\r
         SetUnicodeMem (InputText, InputWidth, L' ');\r
-      }\r
-\r
-      if (MenuOption->Sequence == 2) {\r
-        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
+        InputText[InputWidth] = TIME_SEPARATOR;\r
+        InputText[InputWidth + 1] = L'\0';\r
       } else {\r
-        InputText[InputWidth + 1] = TIME_SEPARATOR;\r
+        SetUnicodeMem (InputText, InputWidth, L' ');\r
+        InputText[InputWidth] = RIGHT_NUMERIC_DELIMITER;\r
+        InputText[InputWidth + 1] = L'\0';\r
       }\r
-      InputText[InputWidth + 2] = L'\0';\r
 \r
       PrintStringAt (Column, Row, InputText);\r
       if (MenuOption->Sequence == 0) {\r
@@ -691,13 +753,27 @@ TheKey2:
 \r
     case '+':\r
     case '-':\r
-      if (Key.UnicodeChar == '+') {\r
-        Key.ScanCode = SCAN_RIGHT;\r
+      if (ManualInput && IntInput) {\r
+        //\r
+        // In Manual input mode, check whether input the negative flag.\r
+        //\r
+        if (Key.UnicodeChar == '-') {\r
+          if (Negative) {\r
+            break;\r
+          }\r
+          Negative = TRUE;\r
+          PrintCharAt (Column++, Row, Key.UnicodeChar);\r
+        }\r
       } else {\r
-        Key.ScanCode = SCAN_LEFT;\r
+        if (Key.UnicodeChar == '+') {\r
+          Key.ScanCode = SCAN_RIGHT;\r
+        } else {\r
+          Key.ScanCode = SCAN_LEFT;\r
+        }\r
+        Key.UnicodeChar = CHAR_NULL;\r
+        goto TheKey2;\r
       }\r
-      Key.UnicodeChar = CHAR_NULL;\r
-      goto TheKey2;\r
+      break;\r
 \r
     case CHAR_NULL:\r
       switch (Key.ScanCode) {\r
@@ -715,20 +791,40 @@ TheKey2:
 \r
         if ((Step != 0) && !ManualInput) {\r
           if (Key.ScanCode == SCAN_LEFT) {\r
-            if (EditValue >= Minimum + Step) {\r
-              EditValue = EditValue - Step;\r
-            } else if (EditValue > Minimum){\r
-              EditValue = Minimum;\r
+            if (IntInput) {\r
+              if ((INT64) EditValue >= (INT64) Minimum + (INT64) Step) {\r
+                EditValue = EditValue - Step;\r
+              } else if ((INT64) EditValue > (INT64) Minimum){\r
+                EditValue = Minimum;\r
+              } else {\r
+                EditValue = Maximum;\r
+              }\r
             } else {\r
-              EditValue = Maximum;\r
+              if (EditValue >= Minimum + Step) {\r
+                EditValue = EditValue - Step;\r
+              } else if (EditValue > Minimum){\r
+                EditValue = Minimum;\r
+              } else {\r
+                EditValue = Maximum;\r
+              }\r
             }\r
           } else if (Key.ScanCode == SCAN_RIGHT) {\r
-            if (EditValue + Step <= Maximum) {\r
-              EditValue = EditValue + Step;\r
-            } else if (EditValue < Maximum) {\r
-              EditValue = Maximum;\r
+            if (IntInput) {\r
+              if ((INT64) EditValue + (INT64) Step <= (INT64) Maximum) {\r
+                EditValue = EditValue + Step;\r
+              } else if ((INT64) EditValue < (INT64) Maximum) {\r
+                EditValue = Maximum;\r
+              } else {\r
+                EditValue = Minimum;\r
+              }\r
             } else {\r
-              EditValue = Minimum;\r
+              if (EditValue + Step <= Maximum) {\r
+                EditValue = EditValue + Step;\r
+              } else if (EditValue < Maximum) {\r
+                EditValue = Maximum;\r
+              } else {\r
+                EditValue = Minimum;\r
+              }\r
             }\r
           }\r
 \r
@@ -787,7 +883,6 @@ TheKey2:
         }\r
 \r
         goto EnterCarriageReturn;\r
-        break;\r
 \r
       case SCAN_UP:\r
       case SCAN_DOWN:\r
@@ -808,13 +903,29 @@ EnterCarriageReturn:
       //\r
       // Validate input value with Minimum value.\r
       //\r
-      if (EditValue < Minimum) {\r
+      ValidateFail = FALSE;\r
+      if (IntInput) {\r
+        //\r
+        // After user input Enter, need to check whether the input value.\r
+        // If input a negative value, should compare with maximum value.\r
+        // else compare with the minimum value.\r
+        //\r
+        if (Negative) {\r
+          ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE;\r
+        } else {\r
+          ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE;\r
+        }\r
+\r
+        if (ValidateFail) {\r
+          UpdateStatusBar (INPUT_ERROR, TRUE);\r
+          break;\r
+        }\r
+      } else if (EditValue < Minimum) {\r
         UpdateStatusBar (INPUT_ERROR, TRUE);\r
         break;\r
-      } else {\r
-        UpdateStatusBar (INPUT_ERROR, FALSE);\r
       }\r
-      \r
+\r
+      UpdateStatusBar (INPUT_ERROR, FALSE);\r
       CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof (EFI_HII_VALUE));\r
       QuestionValue = &gUserInput->InputValue;\r
       //\r
@@ -866,17 +977,21 @@ EnterCarriageReturn:
       // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01\r
       //              2013.03.29 -> 2013.02.29 -> 2013.02.28\r
       //\r
-      if (Question->OpCode->OpCode  == EFI_IFR_DATE_OP && \r
+      if (Question->OpCode->OpCode  == EFI_IFR_DATE_OP &&\r
         (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {\r
         AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence);\r
       }\r
 \r
       return EFI_SUCCESS;\r
-      break;\r
 \r
     case CHAR_BACKSPACE:\r
       if (ManualInput) {\r
         if (Count == 0) {\r
+          if (Negative) {\r
+            Negative = FALSE;\r
+            Column--;\r
+            PrintStringAt (Column, Row, L" ");\r
+          }\r
           break;\r
         }\r
         //\r
@@ -922,28 +1037,59 @@ EnterCarriageReturn:
         if (Count != 0) {\r
           if (HexInput) {\r
             EditValue = LShiftU64 (EditValue, 4) + Digital;\r
+          } else if (IntInput && Negative) {\r
+            //\r
+            // Save the negative number.\r
+            //\r
+            EditValue = ~(MultU64x32 (~(EditValue - 1), 10) + (Key.UnicodeChar - L'0')) + 1;\r
           } else {\r
             EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');\r
           }\r
         } else {\r
           if (HexInput) {\r
             EditValue = Digital;\r
+          } else if (IntInput && Negative) {\r
+            //\r
+            // Save the negative number.\r
+            //\r
+            EditValue = ~(Key.UnicodeChar - L'0') + 1;\r
           } else {\r
             EditValue = Key.UnicodeChar - L'0';\r
           }\r
         }\r
 \r
-        if (EditValue > Maximum) {\r
-          UpdateStatusBar (INPUT_ERROR, TRUE);\r
-          ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));\r
-          EditValue = PreviousNumber[Count];\r
-          break;\r
+        if (IntInput) {\r
+          ValidateFail = FALSE;\r
+          //\r
+          // When user input a new value, should check the current value.\r
+          // If user input a negative value, should compare it with minimum\r
+          // value, else compare it with maximum value.\r
+          //\r
+          if (Negative) {\r
+            ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE;\r
+          } else {\r
+            ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE;\r
+          }\r
+\r
+          if (ValidateFail) {\r
+            UpdateStatusBar (INPUT_ERROR, TRUE);\r
+            ASSERT (Count < ARRAY_SIZE (PreviousNumber));\r
+            EditValue = PreviousNumber[Count];\r
+            break;\r
+          }\r
         } else {\r
-          UpdateStatusBar (INPUT_ERROR, FALSE);\r
+          if (EditValue > Maximum) {\r
+            UpdateStatusBar (INPUT_ERROR, TRUE);\r
+            ASSERT (Count < ARRAY_SIZE (PreviousNumber));\r
+            EditValue = PreviousNumber[Count];\r
+            break;\r
+          }\r
         }\r
 \r
+        UpdateStatusBar (INPUT_ERROR, FALSE);\r
+\r
         Count++;\r
-        ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));\r
+        ASSERT (Count < (ARRAY_SIZE (PreviousNumber)));\r
         PreviousNumber[Count] = EditValue;\r
 \r
         gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
@@ -990,12 +1136,12 @@ AdjustOptionOrder (
       break;\r
     }\r
   }\r
-  \r
+\r
   *PopUpMenuLines = Index;\r
-  \r
+\r
   //\r
   // Prepare HiiValue array\r
-  //  \r
+  //\r
   HiiValueArray = AllocateZeroPool (*PopUpMenuLines * sizeof (EFI_HII_VALUE));\r
   ASSERT (HiiValueArray != NULL);\r
 \r
@@ -1003,21 +1149,21 @@ AdjustOptionOrder (
     HiiValueArray[Index].Type = ValueType;\r
     HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
   }\r
-  \r
+\r
   for (Index = 0; Index < *PopUpMenuLines; Index++) {\r
     OneOfOption = ValueToOption (Question, &HiiValueArray[*PopUpMenuLines - Index - 1]);\r
     if (OneOfOption == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
-  \r
+\r
     RemoveEntryList (&OneOfOption->Link);\r
-  \r
+\r
     //\r
     // Insert to head.\r
     //\r
     InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);\r
   }\r
-  \r
+\r
   FreePool (HiiValueArray);\r
 \r
   return EFI_SUCCESS;\r
@@ -1045,13 +1191,13 @@ IsValuesEqual (
   case EFI_IFR_TYPE_BOOLEAN:\r
   case EFI_IFR_TYPE_NUM_SIZE_8:\r
     return (BOOLEAN) (Value1->u8 == Value2->u8);\r
-  \r
+\r
   case EFI_IFR_TYPE_NUM_SIZE_16:\r
     return (BOOLEAN) (Value1->u16 == Value2->u16);\r
-  \r
+\r
   case EFI_IFR_TYPE_NUM_SIZE_32:\r
     return (BOOLEAN) (Value1->u32 == Value2->u32);\r
-  \r
+\r
   case EFI_IFR_TYPE_NUM_SIZE_64:\r
     return (BOOLEAN) (Value1->u64 == Value2->u64);\r
 \r
@@ -1156,9 +1302,6 @@ GetSelectionInputPopUp (
   ShowDownArrow     = FALSE;\r
   ShowUpArrow       = FALSE;\r
 \r
-  StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);\r
-  ASSERT (StringPtr);\r
-\r
   ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE));\r
 \r
   Question = MenuOption->ThisTag;\r
@@ -1303,7 +1446,7 @@ GetSelectionInputPopUp (
         CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));\r
         FreePool (StringPtr);\r
         StringPtr = TempStringPtr;\r
-        StrCat (StringPtr, L"...");\r
+        StrCatS (StringPtr, PopUpWidth - 1, L"...");\r
       }\r
 \r
       if (Index == HighlightOptionIndex) {\r
@@ -1517,7 +1660,7 @@ TheKey:
       gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);\r
 \r
       return EFI_SUCCESS;\r
-      \r
+\r
     default:\r
       break;\r
     }\r