17c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/** @file
27c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongImplementation for handling the User Interface option processing.
37c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
47c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan BiCopyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
67c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongThis program and the accompanying materials
77c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongare licensed and made available under the terms and conditions of the BSD License
87c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dongwhich accompanies this distribution.  The full text of the license may be found at
97c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Donghttp://opensource.org/licenses/bsd-license.php
107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong#include "FormDisplay.h"
177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
181c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong#define MAX_TIME_OUT_LEN  0x10
191c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Concatenate a narrow string to another string.
227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param Destination The destination string.
2401a9598e31b0ac27476daa7a114fd3b3e2c14751Dandan Bi  @param DestMax     The Max length of destination string.
257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param Source      The source string. The string to be concatenated.
267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                     to the end of Destination.
277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongNewStrCat (
317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT CHAR16               *Destination,
325ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  IN     UINTN                DestMax,
337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN     CHAR16               *Source
347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN Length;
377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Length = 0; Destination[Length] != 0; Length++)
397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ;
407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // We now have the length of the original string
437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // We can safely assume for now that we are concatenating a narrow value to this string.
447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // For instance, the string is "XYZ" and cat'ing ">"
457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // If this assumption changes, we need to make this routine a bit more complex
467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Destination[Length] = NARROW_CHAR;
487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Length++;
497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
505ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  StrCpyS (Destination + Length, DestMax - Length, Source);
517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
54d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  Get UINT64 type value.
55d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
56d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  @param  Value                  Input Hii value.
57d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
58d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  @retval UINT64                 Return the UINT64 type value.
59d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
60d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong**/
61d63a9eb477e67bbc6b344a99f2d14813b61d247aEric DongUINT64
62d63a9eb477e67bbc6b344a99f2d14813b61d247aEric DongHiiValueToUINT64 (
63d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  IN EFI_HII_VALUE      *Value
64d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  )
65d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong{
66d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  UINT64  RetVal;
67d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
68d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  RetVal = 0;
69d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
70d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  switch (Value->Type) {
71d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_NUM_SIZE_8:
72d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = Value->Value.u8;
73d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
74d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
75d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_NUM_SIZE_16:
76d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = Value->Value.u16;
77d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
78d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
79d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_NUM_SIZE_32:
80d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = Value->Value.u32;
81d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
82d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
83d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_BOOLEAN:
84d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = Value->Value.b;
85d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
86d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
87d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_DATE:
88d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = *(UINT64*) &Value->Value.date;
89d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
90d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
91d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  case EFI_IFR_TYPE_TIME:
92d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
93d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
94d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
95d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  default:
96d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    RetVal = Value->Value.u64;
97d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong    break;
98d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  }
99d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
100d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong  return RetVal;
101d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong}
102d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong
103d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong/**
10440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.
10540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
10640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to
10740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  EFI_IFR_TYPE_BUFFER when do the value compare.
10840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
10940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @param  Value                  Expression value to compare on.
11040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
11140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.
11240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.
11340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
11440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong**/
11540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongBOOLEAN
11640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongIsTypeInBuffer (
11740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  IN  EFI_HII_VALUE   *Value
11840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  )
11940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong{
12040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  switch (Value->Type) {
12140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_BUFFER:
12240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_DATE:
12340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_TIME:
12440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_REF:
12540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    return TRUE;
12640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
12740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  default:
12840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    return FALSE;
12940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  }
13040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong}
13140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
13240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong/**
13340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64
13440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
13540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @param  Value                  Expression value to compare on.
13640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
13740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.
13840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.
13940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
14040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong**/
14140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongBOOLEAN
14240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongIsTypeInUINT64 (
14340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  IN  EFI_HII_VALUE   *Value
14440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  )
14540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong{
14640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  switch (Value->Type) {
14740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_8:
14840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_16:
14940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_32:
15040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_64:
15140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_BOOLEAN:
15240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    return TRUE;
15340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
15440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  default:
15540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    return FALSE;
15640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  }
15740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong}
15840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
15940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong/**
16040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  Return the buffer length and buffer pointer for this value.
16140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
16240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to
16340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  EFI_IFR_TYPE_BUFFER when do the value compare.
16440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
16540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @param  Value                  Expression value to compare on.
16640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @param  Buf                    Return the buffer pointer.
16740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  @param  BufLen                 Return the buffer length.
16840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
16940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong**/
17040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongVOID
17140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric DongGetBufAndLenForValue (
17240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  IN  EFI_HII_VALUE   *Value,
17340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  OUT UINT8           **Buf,
17440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  OUT UINT16          *BufLen
17540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  )
17640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong{
17740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  switch (Value->Type) {
17840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_BUFFER:
17940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Buf    = Value->Buffer;
18040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *BufLen = Value->BufferLen;
18140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    break;
18240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
18340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_DATE:
18440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Buf    = (UINT8 *) (&Value->Value.date);
18540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *BufLen = (UINT16) sizeof (EFI_HII_DATE);
18640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    break;
18740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
18840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_TIME:
18940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Buf    = (UINT8 *) (&Value->Value.time);
19040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *BufLen = (UINT16) sizeof (EFI_HII_TIME);
19140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    break;
19240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
19340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  case EFI_IFR_TYPE_REF:
19440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Buf    = (UINT8 *) (&Value->Value.ref);
19540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *BufLen = (UINT16) sizeof (EFI_HII_REF);
19640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    break;
19740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
19840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  default:
19940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Buf    = NULL;
20040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *BufLen = 0;
20140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  }
20240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong}
20340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
20440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong/**
2057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Compare two Hii value.
2067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Value1                 Expression value to compare on left-hand.
2087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Value2                 Expression value to compare on right-hand.
2097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Result                 Return value after compare.
2107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 retval 0                      Two operators equal.
2117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 return Positive value if Value1 is greater than Value2.
2127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong                                 retval Negative value if Value1 is less than Value2.
2137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  HiiHandle              Only required for string compare.
2147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval other                  Could not perform compare on two values.
2167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            Compare the value success.
2177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
2197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
2207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCompareHiiValue (
2217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_HII_VALUE   *Value1,
2227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_HII_VALUE   *Value2,
2237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT INTN            *Result,
2247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL
2257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
2267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
2277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INT64   Temp64;
2287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *Str1;
2297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *Str2;
2307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Len;
23140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  UINT8   *Buf1;
23240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  UINT16  Buf1Len;
23340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  UINT8   *Buf2;
23440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  UINT16  Buf2Len;
2357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
23640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {
2377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Value1->Value.string == 0 || Value2->Value.string == 0) {
2387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
2397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // StringId 0 is reserved
2407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
2417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_INVALID_PARAMETER;
2427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
2437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Value1->Value.string == Value2->Value.string) {
2457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *Result = 0;
2467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_SUCCESS;
2477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
2487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Str1 = GetToken (Value1->Value.string, HiiHandle);
2507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Str1 == NULL) {
2517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
2527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // String not found
2537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
2547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_NOT_FOUND;
2557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
2567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Str2 = GetToken (Value2->Value.string, HiiHandle);
2587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Str2 == NULL) {
2597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (Str1);
2607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return EFI_NOT_FOUND;
2617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
2627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *Result = StrCmp (Str1, Str2);
2647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (Str1);
2667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (Str2);
2677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_SUCCESS;
2697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
2707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
27140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  //
27240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  // Take types(date, time, ref, buffer) as buffer
27340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  //
27440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {
27540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    GetBufAndLenForValue(Value1, &Buf1, &Buf1Len);
27640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    GetBufAndLenForValue(Value2, &Buf2, &Buf2Len);
27740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong
27840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;
27940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    *Result = CompareMem (Buf1, Buf2, Len);
28040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    if ((*Result == 0) && (Buf1Len != Buf2Len)) {
2817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
2827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // In this case, means base on samll number buffer, the data is same
2837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // So which value has more data, which value is bigger.
2847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
28540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong      *Result = Buf1Len > Buf2Len ? 1 : -1;
2867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
2877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_SUCCESS;
2887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
2897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
2907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
2917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Take remain types(integer, boolean, date/time) as integer
2927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
29340578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {
29440578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
29540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    if (Temp64 > 0) {
29640578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong      *Result = 1;
29740578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    } else if (Temp64 < 0) {
29840578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong      *Result = -1;
29940578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    } else {
30040578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong      *Result = 0;
30140578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    }
30240578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong    return EFI_SUCCESS;
3037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
30540578d09d1f9e8864e6d1eff95b9eeabee4b9947Eric Dong  return EFI_UNSUPPORTED;
3067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Search an Option of a Question by its value.
3107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Question               The Question
3127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionValue            Value for Option to be searched.
3137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Pointer                Pointer to the found Option.
3157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval NULL                   Option not found.
3167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
3187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongDISPLAY_QUESTION_OPTION *
3197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongValueToOption (
3207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,
3217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN EFI_HII_VALUE                   *OptionValue
3227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
3237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY               *Link;
3257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DISPLAY_QUESTION_OPTION  *Option;
3267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INTN                     Result;
3277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_HII_VALUE            Value;
3287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Link = GetFirstNode (&Question->OptionListHead);
3307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while (!IsNull (&Question->OptionListHead, Link)) {
3317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
3327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ZeroMem (&Value, sizeof (EFI_HII_VALUE));
3347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Value.Type = Option->OptionOpCode->Type;
3357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CopyMem (&Value.Value, &Option->OptionOpCode->Value, Option->OptionOpCode->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
3367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if ((CompareHiiValue (&Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
3387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return Option;
3397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
3407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetNextNode (&Question->OptionListHead, Link);
3427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return NULL;
3457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Return data element in an Array by its Index.
3507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Array                  The data array.
3527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Type                   Type of the data in this array.
3537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Index                  Zero based index for data in this array.
3547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Value                  The data to be returned
3567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
3587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINT64
3597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongGetArrayData (
3607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN VOID                     *Array,
3617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT8                    Type,
3627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINTN                    Index
3637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
3647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
3657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64 Data;
3667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (Array != NULL);
3687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Data = 0;
3707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Type) {
3717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_8:
3727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Data = (UINT64) *(((UINT8 *) Array) + Index);
3737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
3747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_16:
3767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Data = (UINT64) *(((UINT16 *) Array) + Index);
3777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
3787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_32:
3807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Data = (UINT64) *(((UINT32 *) Array) + Index);
3817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
3827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_64:
3847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Data = (UINT64) *(((UINT64 *) Array) + Index);
3857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
3867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
3887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
3897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
3907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Data;
3927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
3937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
3967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Set value of a data element in an Array by its Index.
3977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
3987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Array                  The data array.
3997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Type                   Type of the data in this array.
4007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Index                  Zero based index for data in this array.
4017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Value                  The value to be set.
4027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
4047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
4057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongSetArrayData (
4067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN VOID                     *Array,
4077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT8                    Type,
4087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINTN                    Index,
4097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT64                   Value
4107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
4117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
4127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (Array != NULL);
4147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Type) {
4167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_8:
4177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(((UINT8 *) Array) + Index) = (UINT8) Value;
4187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_16:
4217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(((UINT16 *) Array) + Index) = (UINT16) Value;
4227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_32:
4257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(((UINT32 *) Array) + Index) = (UINT32) Value;
4267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_64:
4297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    *(((UINT64 *) Array) + Index) = (UINT64) Value;
4307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
4337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
4367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
4387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Check whether this value already in the array, if yes, return the index.
4397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Array                  The data array.
4417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Type                   Type of the data in this array.
4427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Value                  The value to be find.
4437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Index                  The index in the array which has same value with Value.
4447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval   TRUE Found the value in the array.
4467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval   FALSE Not found the value.
4477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
4497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongBOOLEAN
4507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongFindArrayData (
4517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN VOID                     *Array,
4527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT8                    Type,
4537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINT64                   Value,
4547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT UINTN                   *Index OPTIONAL
4557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
4567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
4577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN  Count;
4587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64 TmpValue;
4597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT64 ValueComp;
4607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (Array != NULL);
4627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count    = 0;
4647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TmpValue = 0;
4657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Type) {
4677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_8:
4687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueComp = (UINT8) Value;
4697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_16:
4727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueComp = (UINT16) Value;
4737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_32:
4767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueComp = (UINT32) Value;
4777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TYPE_NUM_SIZE_64:
4807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueComp = (UINT64) Value;
4817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
4847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueComp = 0;
4857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
4867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {
4897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (ValueComp == TmpValue) {
4907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Index != NULL) {
4917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *Index = Count;
4927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
4937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return TRUE;
4947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
4957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Count ++;
4977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
4987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
4997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return FALSE;
5007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
5017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
5037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Print Question Value according to it's storage width and display attributes.
5047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Question               The Question to be printed.
5067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormattedNumber        Buffer for output string.
5077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  BufferSize             The FormattedNumber buffer size in bytes.
5087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            Print success.
5107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.
5117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
5137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
5147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongPrintFormattedNumber (
5157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,
5167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN OUT CHAR16               *FormattedNumber,
5177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN UINTN                    BufferSize
5187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
5197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
5207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  INT64          Value;
5217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16         *Format;
5227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_HII_VALUE  *QuestionValue;
5237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_NUMERIC *NumericOp;
5247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (BufferSize < (21 * sizeof (CHAR16))) {
5267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_BUFFER_TOO_SMALL;
5277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  QuestionValue = &Question->CurrentValue;
5307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  NumericOp     = (EFI_IFR_NUMERIC *) Question->OpCode;
5317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Value = (INT64) QuestionValue->Value.u64;
5337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (NumericOp->Flags & EFI_IFR_DISPLAY) {
5347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_DISPLAY_INT_DEC:
5357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    switch (QuestionValue->Type) {
5367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_SIZE_1:
5377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Value = (INT64) ((INT8) QuestionValue->Value.u8);
5387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
5397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_SIZE_2:
5417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Value = (INT64) ((INT16) QuestionValue->Value.u16);
5427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
5437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_SIZE_4:
5457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Value = (INT64) ((INT32) QuestionValue->Value.u32);
5467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
5477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    case EFI_IFR_NUMERIC_SIZE_8:
5497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    default:
5507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
5517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Value < 0) {
5547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Value = -Value;
5557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Format = L"-%ld";
5567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
5577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Format = L"%ld";
5587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
5597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
5607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_DISPLAY_UINT_DEC:
5627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Format = L"%ld";
5637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
5647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_DISPLAY_UINT_HEX:
5667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Format = L"%lx";
5677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
5687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
5707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_UNSUPPORTED;
5717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
5727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);
5747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return EFI_SUCCESS;
5767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
5777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
5807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Draw a pop up windows based on the dimension, number of lines and
5817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  strings specified.
5827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param RequestedWidth  The width of the pop-up.
5847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param NumberOfLines   The number of lines.
5857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param Marker          The variable argument list for the list of string to be printed.
5867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
5877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
5887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
5897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCreateSharedPopUp (
5907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UINTN                       RequestedWidth,
5917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UINTN                       NumberOfLines,
5927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  VA_LIST                     Marker
5937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
5947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
5957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Index;
5967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Count;
5977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  Character;
5987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Start;
5997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   End;
6007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Top;
6017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Bottom;
6027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *String;
6037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   DimensionsWidth;
6047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   DimensionsHeight;
6057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DimensionsWidth   = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
6077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DimensionsHeight  = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;
6087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
6107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if ((RequestedWidth + 2) > DimensionsWidth) {
6127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    RequestedWidth = DimensionsWidth - 2;
6137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
6167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Subtract the PopUp width from total Columns, allow for one space extra on
6177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // each end plus a border.
6187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
6197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Start     = (DimensionsWidth - RequestedWidth - 2) / 2 + gStatementDimensions.LeftColumn + 1;
6207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  End       = Start + RequestedWidth + 1;
6217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + gStatementDimensions.TopRow - 1;
6237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Bottom    = Top + NumberOfLines + 2;
6247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_DOWN_RIGHT;
6267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PrintCharAt (Start, Top, Character);
6277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_HORIZONTAL;
6287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = Start; Index + 2 < End; Index++) {
6297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
6307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_DOWN_LEFT;
6337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
6347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_VERTICAL;
6357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Count = 0;
6377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
6387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    String = VA_ARG (Marker, CHAR16*);
6397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // This will clear the background of the line - we never know who might have been
6427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // here before us.  This differs from the next clear in that it used the non-reverse
6437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // video for normal printing.
6447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (GetStringWidth (String) / 2 > 1) {
6467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
6477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Passing in a space results in the assumption that this is where typing will occur
6517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[0] == L' ') {
6537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, GetPopupInverseColor ());
6547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Passing in a NULL results in a blank space
6587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
6597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (String[0] == CHAR_NULL) {
6607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
6617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
6627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PrintStringAt (
6647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gStatementDimensions.LeftColumn + 1,
6657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Index + 1,
6667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      String
6677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      );
6687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
6697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PrintCharAt (Start, Index + 1, Character);
6707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PrintCharAt (End - 1, Index + 1, Character);
6717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_UP_RIGHT;
6747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PrintCharAt (Start, Bottom - 1, Character);
6757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_HORIZONTAL;
6767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  for (Index = Start; Index + 2 < End; Index++) {
6777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
6787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
6797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character = BOXDRAW_UP_LEFT;
6817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
6827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
6837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
6857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Draw a pop up windows based on the dimension, number of lines and
6867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  strings specified.
6877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param RequestedWidth  The width of the pop-up.
6897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param NumberOfLines   The number of lines.
6907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param ...             A series of text strings that displayed in the pop-up.
6917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
6927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
6937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
6947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFIAPI
6957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongCreateMultiStringPopUp (
6967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UINTN                       RequestedWidth,
6977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UINTN                       NumberOfLines,
6987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ...
6997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VA_LIST Marker;
7027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VA_START (Marker, NumberOfLines);
7047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);
7067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VA_END (Marker);
7087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
7097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
7111c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  Process nothing.
7121c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7131c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  @param Event    The Event need to be process
7141c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  @param Context  The context of the event.
7151c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7161c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong**/
7171c0d306fe026cb1f9527585ec037e6d44a00877fEric DongVOID
7181c0d306fe026cb1f9527585ec037e6d44a00877fEric DongEFIAPI
7191c0d306fe026cb1f9527585ec037e6d44a00877fEric DongEmptyEventProcess (
7201c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  IN  EFI_EVENT    Event,
7211c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  IN  VOID         *Context
7221c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  )
7231c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong{
7241c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong}
7251c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7261c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong/**
7271c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  Process for the refresh interval statement.
7281c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7291c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  @param Event    The Event need to be process
7301c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  @param Context  The context of the event.
7311c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7321c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong**/
7331c0d306fe026cb1f9527585ec037e6d44a00877fEric DongVOID
7341c0d306fe026cb1f9527585ec037e6d44a00877fEric DongEFIAPI
7351c0d306fe026cb1f9527585ec037e6d44a00877fEric DongRefreshTimeOutProcess (
7361c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  IN  EFI_EVENT    Event,
7371c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  IN  VOID         *Context
7381c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  )
7391c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong{
7401c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  WARNING_IF_CONTEXT     *EventInfo;
7411c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  CHAR16                 TimeOutString[MAX_TIME_OUT_LEN];
7421c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7431c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  EventInfo   = (WARNING_IF_CONTEXT *) Context;
7441c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7451c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  if (*(EventInfo->TimeOut) == 0) {
7461c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong    gBS->CloseEvent (Event);
7471c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7481c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong    gBS->SignalEvent (EventInfo->SyncEvent);
7491c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong    return;
7501c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  }
7511c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7521c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  UnicodeSPrint(TimeOutString, MAX_TIME_OUT_LEN, L"%d", *(EventInfo->TimeOut));
7531c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7541c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  CreateDialog (NULL, gEmptyString, EventInfo->ErrorInfo, gPressEnter, gEmptyString, TimeOutString, NULL);
7551c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7561c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong  *(EventInfo->TimeOut) -= 1;
7571c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong}
7581c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong
7591c0d306fe026cb1f9527585ec037e6d44a00877fEric Dong/**
7607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Display error message for invalid password.
7617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
7637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongVOID
7647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongPasswordInvalid (
7657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  VOID
7667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY  Key;
7697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
7717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Invalid password, prompt error message
7727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
7737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  do {
7747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CreateDialog (&Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString, NULL);
7757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
7767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
7777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
7797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Process password op code.
7807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The menu for current password op code.
7827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            Question Option process success.
7847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Other                  Question Option process fail.
7857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
7867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
7877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
7887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongPasswordProcess (
7897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UI_MENU_OPTION              *MenuOption
7907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
7917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
7927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *StringPtr;
7937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *TempString;
7947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Maximum;
7957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                      Status;
7967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_PASSWORD                *PasswordInfo;
7977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Question;
7987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                   Key;
7997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Question     = MenuOption->ThisTag;
8017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  PasswordInfo = (EFI_IFR_PASSWORD *) Question->OpCode;
8027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Maximum      = PasswordInfo->MaxSize;
8037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status       = EFI_SUCCESS;
8047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
8067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (StringPtr);
8077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Use a NULL password to test whether old password is required
8107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *StringPtr = 0;
8127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = Question->PasswordCheck (gFormData, Question, StringPtr);
8137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {
8147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Password can't be set now.
8167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (StringPtr);
8187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return EFI_SUCCESS;
8197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (EFI_ERROR (Status)) {
8227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Old password exist, ask user for the old password
8247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
8267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (EFI_ERROR (Status)) {
8277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (StringPtr);
8287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return Status;
8297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check user input old password
8337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Status = Question->PasswordCheck (gFormData, Question, StringPtr);
8357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (EFI_ERROR (Status)) {
8367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Status == EFI_NOT_READY) {
8377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
8387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        // Typed in old password incorrect
8397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        //
8407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        PasswordInvalid ();
8417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
8427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Status = EFI_SUCCESS;
8437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
8447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (StringPtr);
8467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      return Status;
8477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Ask for new password
8527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
8547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
8557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (EFI_ERROR (Status)) {
8567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Reset state machine for password
8587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Question->PasswordCheck (gFormData, Question, NULL);
8607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (StringPtr);
8617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return Status;
8627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Confirm new password
8667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
8687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (TempString);
8697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status = ReadString (MenuOption, gConfirmPassword, TempString);
8707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (EFI_ERROR (Status)) {
8717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Reset state machine for password
8737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
8747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Question->PasswordCheck (gFormData, Question, NULL);
8757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (StringPtr);
8767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (TempString);
8777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return Status;
8787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
8797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Compare two typed-in new passwords
8827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
8837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  if (StrCmp (StringPtr, TempString) == 0) {
8847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
8857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
8867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gUserInput->InputValue.Type = Question->CurrentValue.Type;
8877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);
8887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (StringPtr);
8897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
890bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong    Status = EFI_SUCCESS;
8917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (EFI_ERROR (Status)) {
8937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Reset state machine for password
8957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
8967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Question->PasswordCheck (gFormData, Question, NULL);
8977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
8987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
8997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    return Status;
9007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  } else {
9017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Reset state machine for password
9037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Question->PasswordCheck (gFormData, Question, NULL);
9057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Two password mismatch, prompt error message
9087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    do {
9107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      CreateDialog (&Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString, NULL);
9117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
9127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Status = EFI_INVALID_PARAMETER;
9147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
9157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (TempString);
9177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FreePool (StringPtr);
9187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Status;
9207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
9217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
9237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Process a Question's Option (whether selected or un-selected).
9247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  MenuOption             The MenuOption for this Question.
9267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  Selected               TRUE: if Question is selected.
9277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  OptionString           Pointer of the Option String to be displayed.
9287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  SkipErrorValue         Whether need to return when value without option for it.
9297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval EFI_SUCCESS            Question Option process success.
9317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @retval Other                  Question Option process fail.
9327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
9347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongEFI_STATUS
9357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongProcessOptions (
9367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UI_MENU_OPTION              *MenuOption,
9377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  BOOLEAN                     Selected,
9387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT CHAR16                      **OptionString,
9397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  BOOLEAN                     SkipErrorValue
9407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
9417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
9427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_STATUS                      Status;
9437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          *StringPtr;
9447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Index;
9457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FORM_DISPLAY_ENGINE_STATEMENT   *Question;
9467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          FormattedNumber[21];
9477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16                          Number;
9487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16                          Character[2];
9497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_INPUT_KEY                   Key;
9507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           BufferSize;
9517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DISPLAY_QUESTION_OPTION         *OneOfOption;
9527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LIST_ENTRY                      *Link;
9537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_HII_VALUE                   HiiValue;
9547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_HII_VALUE                   *QuestionValue;
9557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  DISPLAY_QUESTION_OPTION         *Option;
9567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN                           Index2;
9577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT8                           *ValueArray;
9587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT8                           ValueType;
9597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  EFI_IFR_ORDERED_LIST            *OrderList;
9607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BOOLEAN                         ValueInvalid;
9615ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi  UINTN                           MaxLen;
9627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Status        = EFI_SUCCESS;
9647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  StringPtr     = NULL;
9667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Character[1]  = L'\0';
9677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *OptionString = NULL;
9687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ValueInvalid  = FALSE;
9697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
9717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  BufferSize = (gOptionBlockWidth + 1) * 2 * gStatementDimensions.BottomRow;
9727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Question = MenuOption->ThisTag;
9747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  QuestionValue = &Question->CurrentValue;
9757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  switch (Question->OpCode->OpCode) {
9777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_ORDERED_LIST_OP:
9787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check whether there are Options of this OrderedList
9817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
9827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (IsListEmpty (&Question->OptionListHead)) {
9837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
9847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
9857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;
9877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    Link = GetFirstNode (&Question->OptionListHead);
9897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
9907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueType =  OneOfOption->OptionOpCode->Type;
9927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    ValueArray = Question->CurrentValue.Buffer;
9937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
9947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
9957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Go ask for input
9977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
9987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = GetSelectionInputPopUp (MenuOption);
9997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
10007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // We now know how many strings we will have, so we can allocate the
10027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // space required for the array or strings.
10037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10045ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      MaxLen = OrderList->MaxContainers * BufferSize / sizeof (CHAR16);
10055ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      *OptionString = AllocateZeroPool (MaxLen * sizeof (CHAR16));
10067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
10077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      HiiValue.Type = ValueType;
10097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      HiiValue.Value.u64 = 0;
10107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      for (Index = 0; Index < OrderList->MaxContainers; Index++) {
10117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
10127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (HiiValue.Value.u64 == 0) {
10137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Values for the options in ordered lists should never be a 0
10157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          break;
10177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
10187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        OneOfOption = ValueToOption (Question, &HiiValue);
10207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (OneOfOption == NULL) {
10217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          if (SkipErrorValue) {
10227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
10237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            // Just try to get the option string, skip the value which not has option.
10247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            //
10257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            continue;
10267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
10277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Show error message
10307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          do {
10327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
10337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
10347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // The initial value of the orderedlist is invalid, force to be valid value
10377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Exit current DisplayForm with new value.
10387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->SelectedStatement = Question;
104042645c3dcf0488c616422dcdfd1596939223f432Eric Dong          gMisMatch = TRUE;
10417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);
10427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (ValueArray != NULL);
10437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.Buffer    = ValueArray;
10447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
10457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.Type      = Question->CurrentValue.Type;
10467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Link = GetFirstNode (&Question->OptionListHead);
10487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Index2 = 0;
10497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          while (!IsNull (&Question->OptionListHead, Link) && Index2 < OrderList->MaxContainers) {
10507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
10517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Link = GetNextNode (&Question->OptionListHead, Link);
10527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            SetArrayData (ValueArray, ValueType, Index2, Option->OptionOpCode->Value.u64);
10537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            Index2++;
10547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          }
10557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          SetArrayData (ValueArray, ValueType, Index2, 0);
10567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (*OptionString);
10587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          *OptionString = NULL;
10597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          return EFI_NOT_FOUND;
10607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
10617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Character[0] = LEFT_ONEOF_DELIMITER;
10635ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi        NewStrCat (OptionString[0], MaxLen, Character);
10647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
10657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        ASSERT (StringPtr != NULL);
10665ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi        NewStrCat (OptionString[0], MaxLen, StringPtr);
10677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Character[0] = RIGHT_ONEOF_DELIMITER;
10685ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi        NewStrCat (OptionString[0], MaxLen, Character);
10697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Character[0] = CHAR_CARRIAGE_RETURN;
10705ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi        NewStrCat (OptionString[0], MaxLen, Character);
10717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (StringPtr);
10727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
10737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // If valid option more than the max container, skip these options.
10767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (Index >= OrderList->MaxContainers) {
10787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
10797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
10807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Search the other options, try to find the one not in the container.
10837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
10847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Link = GetFirstNode (&Question->OptionListHead);
10857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      while (!IsNull (&Question->OptionListHead, Link)) {
10867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
10877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        Link = GetNextNode (&Question->OptionListHead, Link);
10887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (FindArrayData (ValueArray, ValueType, OneOfOption->OptionOpCode->Value.u64, NULL)) {
10907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          continue;
10917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
10927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
10937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (SkipErrorValue) {
10947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Not report error, just get the correct option string info.
10967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
10977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Character[0] = LEFT_ONEOF_DELIMITER;
10985ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi          NewStrCat (OptionString[0], MaxLen, Character);
10997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
11007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (StringPtr != NULL);
11015ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi          NewStrCat (OptionString[0], MaxLen, StringPtr);
11027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Character[0] = RIGHT_ONEOF_DELIMITER;
11035ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi          NewStrCat (OptionString[0], MaxLen, Character);
11047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Character[0] = CHAR_CARRIAGE_RETURN;
11055ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi          NewStrCat (OptionString[0], MaxLen, Character);
11067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (StringPtr);
11077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          continue;
11097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
11107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (!ValueInvalid) {
11127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ValueInvalid = TRUE;
11137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Show error message
11157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          do {
11177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
11187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
11197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // The initial value of the orderedlist is invalid, force to be valid value
11227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Exit current DisplayForm with new value.
11237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->SelectedStatement = Question;
112542645c3dcf0488c616422dcdfd1596939223f432Eric Dong          gMisMatch = TRUE;
11267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer);
11277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          ASSERT (ValueArray != NULL);
11287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.Buffer    = ValueArray;
11297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
11307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.Type      = Question->CurrentValue.Type;
11317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
11327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SetArrayData (ValueArray, ValueType, Index++, OneOfOption->OptionOpCode->Value.u64);
11347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
11357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (ValueInvalid) {
11377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (*OptionString);
11387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *OptionString = NULL;
11397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        return EFI_NOT_FOUND;
11407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
11417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
11437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_ONE_OF_OP:
11457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    // Check whether there are Options of this OneOf
11477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    //
11487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (IsListEmpty (&Question->OptionListHead)) {
11497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      break;
11507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
11517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
11527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Go ask for input
11547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
11557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = GetSelectionInputPopUp (MenuOption);
11567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
11575ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      MaxLen = BufferSize / sizeof(CHAR16);
11587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
11597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
11607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      OneOfOption = ValueToOption (Question, QuestionValue);
11627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (OneOfOption == NULL) {
11637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (SkipErrorValue) {
11647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Not report error, just get the correct option string info.
11667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Link = GetFirstNode (&Question->OptionListHead);
11687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
11697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        } else {
11707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Show error message
11727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          do {
11747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
11757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
11767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Force the Question value to be valid
11797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          // Exit current DisplayForm with new value.
11807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          //
11817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Link = GetFirstNode (&Question->OptionListHead);
11827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
11837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
11847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->InputValue.Type = Option->OptionOpCode->Type;
1185d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          switch (gUserInput->InputValue.Type) {
1186d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          case EFI_IFR_TYPE_NUM_SIZE_8:
1187d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8;
1188d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            break;
1189d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          case EFI_IFR_TYPE_NUM_SIZE_16:
1190d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16));
1191d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            break;
1192d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          case EFI_IFR_TYPE_NUM_SIZE_32:
1193d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32));
1194d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            break;
1195d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          case EFI_IFR_TYPE_NUM_SIZE_64:
1196d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64));
1197d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            break;
1198d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          default:
1199d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            ASSERT (FALSE);
1200d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong            break;
1201d63a9eb477e67bbc6b344a99f2d14813b61d247aEric Dong          }
12027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          gUserInput->SelectedStatement = Question;
120342645c3dcf0488c616422dcdfd1596939223f432Eric Dong          gMisMatch = TRUE;
12047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          FreePool (*OptionString);
12057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          *OptionString = NULL;
12067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          return EFI_NOT_FOUND;
12077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
12087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
12097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Character[0] = LEFT_ONEOF_DELIMITER;
12115ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      NewStrCat (OptionString[0], MaxLen, Character);
12127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
12137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (StringPtr != NULL);
12145ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      NewStrCat (OptionString[0], MaxLen, StringPtr);
12157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Character[0] = RIGHT_ONEOF_DELIMITER;
12165ad66ec6925f1564137752be4d8656d462ebeaf2Dandan Bi      NewStrCat (OptionString[0], MaxLen, Character);
12177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (StringPtr);
12197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
12217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_CHECKBOX_OP:
12237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
12247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Since this is a BOOLEAN operation, flip it upon selection
12267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.Type    = QuestionValue->Type;
12287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
12297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Perform inconsistent check
12327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
1233bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong      return EFI_SUCCESS;
12347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
12357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
12367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
12377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString[0] = LEFT_CHECKBOX_DELIMITER;
12397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (QuestionValue->Value.b) {
12417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 1) = CHECK_ON;
12427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
12437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 1) = CHECK_OFF;
12447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
12457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
12467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
12487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_NUMERIC_OP:
12507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
12517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Go ask for input
12537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = GetNumericInput (MenuOption);
12557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
12567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
12577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
12587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString[0] = LEFT_NUMERIC_DELIMITER;
12607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // Formatted print
12637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
12657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Number = (UINT16) GetStringWidth (FormattedNumber);
12667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      CopyMem (OptionString[0] + 1, FormattedNumber, Number);
12677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
12697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
12707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
12717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_DATE_OP:
12737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
12747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // This is similar to numerics
12767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
12777c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = GetNumericInput (MenuOption);
12787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
12797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
12807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
12817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (MenuOption->Sequence) {
12837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 0:
12847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
1285cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.date.Month == 0xff){
1286cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??");
1287cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1288cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);
1289cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
12907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 3) = DATE_SEPARATOR;
12917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
12927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
12937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 1:
12947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SetUnicodeMem (OptionString[0], 4, L' ');
1295cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.date.Day == 0xff){
1296cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??");
1297cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1298cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);
1299cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
13007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 6) = DATE_SEPARATOR;
13017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
13027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 2:
13047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SetUnicodeMem (OptionString[0], 7, L' ');
1305cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.date.Year == 0xff){
1306cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"????");
1307cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1308cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);
1309cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
13107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
13117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
13127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
13137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_TIME_OP:
13177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
13187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
13197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      // This is similar to numerics
13207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      //
13217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = GetNumericInput (MenuOption);
13227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
13237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
13247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
13257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      switch (MenuOption->Sequence) {
13277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 0:
13287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
1329cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.time.Hour == 0xff){
1330cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??");
1331cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1332cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);
1333cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
13347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 3) = TIME_SEPARATOR;
13357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
13367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 1:
13387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SetUnicodeMem (OptionString[0], 4, L' ');
1339cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.time.Minute == 0xff){
1340cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??");
1341cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1342cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);
1343cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
13447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 6) = TIME_SEPARATOR;
13457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
13467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      case 2:
13487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        SetUnicodeMem (OptionString[0], 7, L' ');
1349cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        if (QuestionValue->Value.time.Second == 0xff){
1350cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"??");
1351cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        } else {
1352cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);
1353cc63add853d4b5c16b74b4d4ceb59c015a2adcc4Dandan Bi        }
13547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
13557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        break;
13567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
13577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_STRING_OP:
13617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
13627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      StringPtr = AllocateZeroPool (Question->CurrentValue.BufferLen + sizeof (CHAR16));
13637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (StringPtr);
13647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      CopyMem(StringPtr, Question->CurrentValue.Buffer, Question->CurrentValue.BufferLen);
13657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = ReadString (MenuOption, gPromptForData, StringPtr);
13677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (EFI_ERROR (Status)) {
13687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        FreePool (StringPtr);
13697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        return Status;
13707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
13717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
13737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
13747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.Type = Question->CurrentValue.Type;
13757c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);
13767c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      FreePool (StringPtr);
1377bfae1330cc2e7749fcf349a3a633e2e77f5f01c9Eric Dong      return EFI_SUCCESS;
13787c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    } else {
13797c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      *OptionString = AllocateZeroPool (BufferSize);
13807c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      ASSERT (*OptionString);
13817c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13827c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      if (((CHAR16 *) Question->CurrentValue.Buffer)[0] == 0x0000) {
13837c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        *(OptionString[0]) = '_';
13847c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      } else {
13857c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        if (Question->CurrentValue.BufferLen < BufferSize) {
13867c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong          BufferSize = Question->CurrentValue.BufferLen;
13877c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        }
13887c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong        CopyMem (OptionString[0], (CHAR16 *) Question->CurrentValue.Buffer, BufferSize);
13897c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      }
13907c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13917c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13927c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13937c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  case EFI_IFR_PASSWORD_OP:
13947c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (Selected) {
13957c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      Status = PasswordProcess (MenuOption);
13967c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
13977c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
13987c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
13997c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  default:
14007c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    break;
14017c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14027c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14037c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return Status;
14047c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
14057c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14067c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14077c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong/**
14087c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Process the help string: Split StringPtr to several lines of strings stored in
14097c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
14107c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14117c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  StringPtr              The entire help string.
14127c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  FormattedString        The oupput formatted string.
14137c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  EachLineWidth          The max string length of each line in the formatted string.
14147c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  @param  RowCount               TRUE: if Question is selected.
14157c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14167c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong**/
14177c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongUINTN
14187c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric DongProcessHelpString (
14197c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  CHAR16  *StringPtr,
14207c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT CHAR16  **FormattedString,
14217c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  OUT UINT16  *EachLineWidth,
14227c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  IN  UINTN   RowCount
14237c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  )
14247c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong{
14257c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   Index;
14267c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CHAR16  *OutputString;
14277c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   TotalRowNum;
14287c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINTN   CheckedNum;
14297c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  GlyphWidth;
14307c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  LineWidth;
14317c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  MaxStringLen;
14327c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  UINT16  StringLen;
14337c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14347c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  TotalRowNum    = 0;
14357c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  CheckedNum     = 0;
14367c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth     = 1;
14377c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Index          = 0;
14387c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  MaxStringLen   = 0;
14397c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  StringLen      = 0;
14407c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14417c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14427c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Set default help string width.
14437c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14447c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  LineWidth      = (UINT16) (gHelpBlockWidth - 1);
14457c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14467c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14477c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Get row number of the String.
14487c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14497c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
14507c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    if (StringLen > MaxStringLen) {
14517c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong      MaxStringLen = StringLen;
14527c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    }
14537c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14547c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    TotalRowNum ++;
14557c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OutputString);
14567c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14577c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *EachLineWidth = MaxStringLen;
14587c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14597c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));
14607c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  ASSERT (*FormattedString != NULL);
14617c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14627c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14637c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  // Generate formatted help string array.
14647c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  //
14657c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  GlyphWidth  = 1;
14667c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  Index       = 0;
14677c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
14687c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));
14697c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    CheckedNum ++;
14707c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong    FreePool (OutputString);
14717c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  }
14727c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong
14737c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong  return TotalRowNum;
14747c6c064ca8ebb5baf5104e8a4764cd3c19ef8bf1Eric Dong}
1475