2 Implementation for handling the User Interface option processing.
5 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Process Question Config.
22 @param Selection The UI menu selection.
23 @param Question The Question to be peocessed.
25 @retval EFI_SUCCESS Question Config process success.
26 @retval Other Question Config process fail.
30 ProcessQuestionConfig (
31 IN UI_MENU_SELECTION
*Selection
,
32 IN FORM_BROWSER_STATEMENT
*Question
38 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
40 if (Question
->QuestionConfig
== 0) {
47 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
48 if (ConfigResp
== NULL
) {
53 // Send config to Configuration Driver
55 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
56 if (ConfigAccess
== NULL
) {
57 return EFI_UNSUPPORTED
;
59 Status
= ConfigAccess
->RouteConfig (
70 Search an Option of a Question by its value.
72 @param Question The Question
73 @param OptionValue Value for Option to be searched.
75 @retval Pointer Pointer to the found Option.
76 @retval NULL Option not found.
81 IN FORM_BROWSER_STATEMENT
*Question
,
82 IN EFI_HII_VALUE
*OptionValue
86 QUESTION_OPTION
*Option
;
89 Link
= GetFirstNode (&Question
->OptionListHead
);
90 while (!IsNull (&Question
->OptionListHead
, Link
)) {
91 Option
= QUESTION_OPTION_FROM_LINK (Link
);
93 if ((CompareHiiValue (&Option
->Value
, OptionValue
, &Result
, NULL
) == EFI_SUCCESS
) && (Result
== 0)) {
97 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
105 Return data element in an Array by its Index.
107 @param Array The data array.
108 @param Type Type of the data in this array.
109 @param Index Zero based index for data in this array.
111 @retval Value The data to be returned
123 ASSERT (Array
!= NULL
);
127 case EFI_IFR_TYPE_NUM_SIZE_8
:
128 Data
= (UINT64
) *(((UINT8
*) Array
) + Index
);
131 case EFI_IFR_TYPE_NUM_SIZE_16
:
132 Data
= (UINT64
) *(((UINT16
*) Array
) + Index
);
135 case EFI_IFR_TYPE_NUM_SIZE_32
:
136 Data
= (UINT64
) *(((UINT32
*) Array
) + Index
);
139 case EFI_IFR_TYPE_NUM_SIZE_64
:
140 Data
= (UINT64
) *(((UINT64
*) Array
) + Index
);
152 Set value of a data element in an Array by its Index.
154 @param Array The data array.
155 @param Type Type of the data in this array.
156 @param Index Zero based index for data in this array.
157 @param Value The value to be set.
169 ASSERT (Array
!= NULL
);
172 case EFI_IFR_TYPE_NUM_SIZE_8
:
173 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
176 case EFI_IFR_TYPE_NUM_SIZE_16
:
177 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
180 case EFI_IFR_TYPE_NUM_SIZE_32
:
181 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
184 case EFI_IFR_TYPE_NUM_SIZE_64
:
185 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
195 Print Question Value according to it's storage width and display attributes.
197 @param Question The Question to be printed.
198 @param FormattedNumber Buffer for output string.
199 @param BufferSize The FormattedNumber buffer size in bytes.
201 @retval EFI_SUCCESS Print success.
202 @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
206 PrintFormattedNumber (
207 IN FORM_BROWSER_STATEMENT
*Question
,
208 IN OUT CHAR16
*FormattedNumber
,
214 EFI_HII_VALUE
*QuestionValue
;
216 if (BufferSize
< (21 * sizeof (CHAR16
))) {
217 return EFI_BUFFER_TOO_SMALL
;
220 QuestionValue
= &Question
->HiiValue
;
222 Value
= (INT64
) QuestionValue
->Value
.u64
;
223 switch (Question
->Flags
& EFI_IFR_DISPLAY
) {
224 case EFI_IFR_DISPLAY_INT_DEC
:
225 switch (QuestionValue
->Type
) {
226 case EFI_IFR_NUMERIC_SIZE_1
:
227 Value
= (INT64
) ((INT8
) QuestionValue
->Value
.u8
);
230 case EFI_IFR_NUMERIC_SIZE_2
:
231 Value
= (INT64
) ((INT16
) QuestionValue
->Value
.u16
);
234 case EFI_IFR_NUMERIC_SIZE_4
:
235 Value
= (INT64
) ((INT32
) QuestionValue
->Value
.u32
);
238 case EFI_IFR_NUMERIC_SIZE_8
:
251 case EFI_IFR_DISPLAY_UINT_DEC
:
255 case EFI_IFR_DISPLAY_UINT_HEX
:
260 return EFI_UNSUPPORTED
;
264 UnicodeSPrint (FormattedNumber
, BufferSize
, Format
, Value
);
271 Password may be stored as encrypted by Configuration Driver. When change a
272 password, user will be challenged with old password. To validate user input old
273 password, we will send the clear text to Configuration Driver via Callback().
274 Configuration driver is responsible to check the passed in password and return
275 the validation result. If validation pass, state machine in password Callback()
276 will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
277 After user type in new password twice, Callback() will be invoked to send the
278 new password to Configuration Driver.
280 @param Selection Pointer to UI_MENU_SELECTION.
281 @param MenuOption The MenuOption for this password Question.
282 @param String The clear text of password.
284 @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
285 @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
286 @retval EFI_SUCCESS Password correct, Browser will prompt for new
288 @retval EFI_NOT_READY Password incorrect, Browser will show error
290 @retval Other Browser will do nothing.
291 @return In state of BROWSER_STATE_SET_PASSWORD:
292 @retval EFI_SUCCESS Set password success.
293 @retval Other Set password failed.
298 IN UI_MENU_SELECTION
*Selection
,
299 IN UI_MENU_OPTION
*MenuOption
,
304 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
305 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
306 EFI_IFR_TYPE_VALUE IfrTypeValue
;
308 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
309 if (ConfigAccess
== NULL
) {
310 return EFI_UNSUPPORTED
;
314 // Prepare password string in HII database
316 if (String
!= NULL
) {
317 IfrTypeValue
.string
= NewString (String
, Selection
->FormSet
->HiiHandle
);
319 IfrTypeValue
.string
= 0;
323 // Send password to Configuration Driver for validation
325 Status
= ConfigAccess
->Callback (
327 EFI_BROWSER_ACTION_CHANGING
,
328 MenuOption
->ThisTag
->QuestionId
,
329 MenuOption
->ThisTag
->HiiValue
.Type
,
335 // Remove password string from HII database
337 if (String
!= NULL
) {
338 DeleteString (IfrTypeValue
.string
, Selection
->FormSet
->HiiHandle
);
346 Display error message for invalid password.
357 // Invalid password, prompt error message
360 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gPassowordInvalid
, gPressEnter
, gEmptyString
);
361 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
366 Process a Question's Option (whether selected or un-selected).
368 @param Selection Pointer to UI_MENU_SELECTION.
369 @param MenuOption The MenuOption for this Question.
370 @param Selected TRUE: if Question is selected.
371 @param OptionString Pointer of the Option String to be displayed.
373 @retval EFI_SUCCESS Question Option process success.
374 @retval Other Question Option process fail.
379 IN UI_MENU_SELECTION
*Selection
,
380 IN UI_MENU_OPTION
*MenuOption
,
382 OUT CHAR16
**OptionString
389 FORM_BROWSER_STATEMENT
*Question
;
390 CHAR16 FormattedNumber
[21];
395 QUESTION_OPTION
*OneOfOption
;
397 EFI_HII_VALUE HiiValue
;
398 EFI_HII_VALUE
*QuestionValue
;
401 QUESTION_OPTION
*Option
;
405 EFI_STRING_ID StringId
;
407 Status
= EFI_SUCCESS
;
410 Character
[1] = L
'\0';
411 *OptionString
= NULL
;
414 ZeroMem (FormattedNumber
, 21 * sizeof (CHAR16
));
415 BufferSize
= (gOptionBlockWidth
+ 1) * 2 * gScreenDimensions
.BottomRow
;
417 Question
= MenuOption
->ThisTag
;
418 QuestionValue
= &Question
->HiiValue
;
419 Maximum
= (UINT16
) Question
->Maximum
;
421 ValueArray
= Question
->BufferValue
;
422 ValueType
= Question
->ValueType
;
424 switch (Question
->Operand
) {
425 case EFI_IFR_ORDERED_LIST_OP
:
427 // Check whether there are Options of this OrderedList
429 if (IsListEmpty (&Question
->OptionListHead
)) {
433 // Initialize Option value array
435 if (GetArrayData (ValueArray
, ValueType
, 0) == 0) {
436 GetQuestionDefault (Selection
->FormSet
, Selection
->Form
, Question
, 0);
443 Status
= GetSelectionInputPopUp (Selection
, MenuOption
);
446 // We now know how many strings we will have, so we can allocate the
447 // space required for the array or strings.
449 *OptionString
= AllocateZeroPool (Question
->MaxContainers
* BufferSize
);
450 ASSERT (*OptionString
);
452 HiiValue
.Type
= ValueType
;
453 HiiValue
.Value
.u64
= 0;
454 for (Index
= 0; Index
< Question
->MaxContainers
; Index
++) {
455 HiiValue
.Value
.u64
= GetArrayData (ValueArray
, ValueType
, Index
);
456 if (HiiValue
.Value
.u64
== 0) {
458 // Values for the options in ordered lists should never be a 0
463 OneOfOption
= ValueToOption (Question
, &HiiValue
);
464 if (OneOfOption
== NULL
) {
466 // Show error message
469 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gOptionMismatch
, gPressEnter
, gEmptyString
);
470 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
473 // The initial value of the orderedlist is invalid, force to be valid value
475 Link
= GetFirstNode (&Question
->OptionListHead
);
477 while (!IsNull (&Question
->OptionListHead
, Link
) && Index2
< Question
->MaxContainers
) {
478 Option
= QUESTION_OPTION_FROM_LINK (Link
);
479 SetArrayData (ValueArray
, ValueType
, Index2
, Option
->Value
.Value
.u64
);
481 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
483 SetArrayData (ValueArray
, ValueType
, Index2
, 0);
485 Status
= SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, TRUE
);
486 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
488 FreePool (*OptionString
);
489 *OptionString
= NULL
;
490 return EFI_NOT_FOUND
;
494 if ((OneOfOption
->SuppressExpression
!= NULL
) &&
495 (EvaluateExpressionList(OneOfOption
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
)) {
497 // This option is suppressed
503 Character
[0] = LEFT_ONEOF_DELIMITER
;
504 NewStrCat (OptionString
[0], Character
);
505 StringPtr
= GetToken (OneOfOption
->Text
, Selection
->Handle
);
506 ASSERT (StringPtr
!= NULL
);
507 NewStrCat (OptionString
[0], StringPtr
);
508 Character
[0] = RIGHT_ONEOF_DELIMITER
;
509 NewStrCat (OptionString
[0], Character
);
510 Character
[0] = CHAR_CARRIAGE_RETURN
;
511 NewStrCat (OptionString
[0], Character
);
513 FreePool (StringPtr
);
519 case EFI_IFR_ONE_OF_OP
:
521 // Check whether there are Options of this OneOf
523 if (IsListEmpty (&Question
->OptionListHead
)) {
530 Status
= GetSelectionInputPopUp (Selection
, MenuOption
);
532 *OptionString
= AllocateZeroPool (BufferSize
);
533 ASSERT (*OptionString
);
535 OneOfOption
= ValueToOption (Question
, QuestionValue
);
536 if (OneOfOption
== NULL
) {
538 // Show error message
541 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gOptionMismatch
, gPressEnter
, gEmptyString
);
542 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
545 // Force the Question value to be valid
547 Link
= GetFirstNode (&Question
->OptionListHead
);
548 while (!IsNull (&Question
->OptionListHead
, Link
)) {
549 Option
= QUESTION_OPTION_FROM_LINK (Link
);
551 if ((Option
->SuppressExpression
== NULL
) ||
552 (EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressFalse
)) {
553 CopyMem (QuestionValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
554 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, TRUE
);
555 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
559 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
562 FreePool (*OptionString
);
563 *OptionString
= NULL
;
564 return EFI_NOT_FOUND
;
567 if ((OneOfOption
->SuppressExpression
!= NULL
) &&
568 ((EvaluateExpressionList(OneOfOption
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
570 // This option is suppressed
579 // Current selected option happen to be suppressed,
580 // enforce to select on a non-suppressed option
582 Link
= GetFirstNode (&Question
->OptionListHead
);
583 while (!IsNull (&Question
->OptionListHead
, Link
)) {
584 OneOfOption
= QUESTION_OPTION_FROM_LINK (Link
);
586 if ((OneOfOption
->SuppressExpression
== NULL
) ||
587 (EvaluateExpressionList(OneOfOption
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressFalse
)) {
589 CopyMem (QuestionValue
, &OneOfOption
->Value
, sizeof (EFI_HII_VALUE
));
590 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, TRUE
);
591 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
592 gST
->ConOut
->SetAttribute (gST
->ConOut
, PcdGet8 (PcdBrowserFieldTextColor
) | FIELD_BACKGROUND
);
596 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
601 Character
[0] = LEFT_ONEOF_DELIMITER
;
602 NewStrCat (OptionString
[0], Character
);
603 StringPtr
= GetToken (OneOfOption
->Text
, Selection
->Handle
);
604 ASSERT (StringPtr
!= NULL
);
605 NewStrCat (OptionString
[0], StringPtr
);
606 Character
[0] = RIGHT_ONEOF_DELIMITER
;
607 NewStrCat (OptionString
[0], Character
);
609 FreePool (StringPtr
);
614 case EFI_IFR_CHECKBOX_OP
:
615 *OptionString
= AllocateZeroPool (BufferSize
);
616 ASSERT (*OptionString
);
618 *OptionString
[0] = LEFT_CHECKBOX_DELIMITER
;
622 // Since this is a BOOLEAN operation, flip it upon selection
624 QuestionValue
->Value
.b
= (BOOLEAN
) (QuestionValue
->Value
.b
? FALSE
: TRUE
);
627 // Perform inconsistent check
629 Status
= ValidateQuestion (Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
630 if (EFI_ERROR (Status
)) {
632 // Inconsistent check fail, restore Question Value
634 QuestionValue
->Value
.b
= (BOOLEAN
) (QuestionValue
->Value
.b
? FALSE
: TRUE
);
635 FreePool (*OptionString
);
636 *OptionString
= NULL
;
641 // Save Question value
643 Status
= SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, TRUE
);
644 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
647 if (QuestionValue
->Value
.b
) {
648 *(OptionString
[0] + 1) = CHECK_ON
;
650 *(OptionString
[0] + 1) = CHECK_OFF
;
652 *(OptionString
[0] + 2) = RIGHT_CHECKBOX_DELIMITER
;
655 case EFI_IFR_NUMERIC_OP
:
660 Status
= GetNumericInput (Selection
, MenuOption
);
662 *OptionString
= AllocateZeroPool (BufferSize
);
663 ASSERT (*OptionString
);
665 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
670 PrintFormattedNumber (Question
, FormattedNumber
, 21 * sizeof (CHAR16
));
671 Number
= (UINT16
) GetStringWidth (FormattedNumber
);
672 CopyMem (OptionString
[0] + 1, FormattedNumber
, Number
);
674 *(OptionString
[0] + Number
/ 2) = RIGHT_NUMERIC_DELIMITER
;
678 case EFI_IFR_DATE_OP
:
681 // This is similar to numerics
683 Status
= GetNumericInput (Selection
, MenuOption
);
685 *OptionString
= AllocateZeroPool (BufferSize
);
686 ASSERT (*OptionString
);
688 switch (MenuOption
->Sequence
) {
690 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
691 UnicodeSPrint (OptionString
[0] + 1, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.date
.Month
);
692 *(OptionString
[0] + 3) = DATE_SEPARATOR
;
696 SetUnicodeMem (OptionString
[0], 4, L
' ');
697 UnicodeSPrint (OptionString
[0] + 4, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.date
.Day
);
698 *(OptionString
[0] + 6) = DATE_SEPARATOR
;
702 SetUnicodeMem (OptionString
[0], 7, L
' ');
703 UnicodeSPrint (OptionString
[0] + 7, 21 * sizeof (CHAR16
), L
"%04d", QuestionValue
->Value
.date
.Year
);
704 *(OptionString
[0] + 11) = RIGHT_NUMERIC_DELIMITER
;
710 case EFI_IFR_TIME_OP
:
713 // This is similar to numerics
715 Status
= GetNumericInput (Selection
, MenuOption
);
717 *OptionString
= AllocateZeroPool (BufferSize
);
718 ASSERT (*OptionString
);
720 switch (MenuOption
->Sequence
) {
722 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
723 UnicodeSPrint (OptionString
[0] + 1, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Hour
);
724 *(OptionString
[0] + 3) = TIME_SEPARATOR
;
728 SetUnicodeMem (OptionString
[0], 4, L
' ');
729 UnicodeSPrint (OptionString
[0] + 4, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Minute
);
730 *(OptionString
[0] + 6) = TIME_SEPARATOR
;
734 SetUnicodeMem (OptionString
[0], 7, L
' ');
735 UnicodeSPrint (OptionString
[0] + 7, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Second
);
736 *(OptionString
[0] + 9) = RIGHT_NUMERIC_DELIMITER
;
742 case EFI_IFR_STRING_OP
:
744 StringPtr
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
746 CopyMem(StringPtr
, Question
->BufferValue
, Maximum
* sizeof (CHAR16
));
748 Status
= ReadString (MenuOption
, gPromptForData
, StringPtr
);
749 if (!EFI_ERROR (Status
)) {
750 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, StringPtr
, NULL
);
751 Status
= ValidateQuestion(Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
752 if (EFI_ERROR (Status
)) {
753 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
755 CopyMem (Question
->BufferValue
, StringPtr
, Maximum
* sizeof (CHAR16
));
756 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, TRUE
);
758 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
762 FreePool (StringPtr
);
764 *OptionString
= AllocateZeroPool (BufferSize
);
765 ASSERT (*OptionString
);
767 if (((CHAR16
*) Question
->BufferValue
)[0] == 0x0000) {
768 *(OptionString
[0]) = '_';
770 if ((Maximum
* sizeof (CHAR16
)) < BufferSize
) {
771 BufferSize
= Maximum
* sizeof (CHAR16
);
773 CopyMem (OptionString
[0], (CHAR16
*) Question
->BufferValue
, BufferSize
);
778 case EFI_IFR_PASSWORD_OP
:
780 StringPtr
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
784 // For interactive passwords, old password is validated by callback
786 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
788 // Use a NULL password to test whether old password is required
791 Status
= PasswordCallback (Selection
, MenuOption
, StringPtr
);
792 if (Status
== EFI_NOT_AVAILABLE_YET
|| Status
== EFI_UNSUPPORTED
) {
794 // Callback is not supported, or
795 // Callback request to terminate password input
797 FreePool (StringPtr
);
801 if (EFI_ERROR (Status
)) {
803 // Old password exist, ask user for the old password
805 Status
= ReadString (MenuOption
, gPromptForPassword
, StringPtr
);
806 if (EFI_ERROR (Status
)) {
807 FreePool (StringPtr
);
812 // Check user input old password
814 Status
= PasswordCallback (Selection
, MenuOption
, StringPtr
);
815 if (EFI_ERROR (Status
)) {
816 if (Status
== EFI_NOT_READY
) {
818 // Typed in old password incorrect
822 Status
= EFI_SUCCESS
;
825 FreePool (StringPtr
);
831 // For non-interactive password, validate old password in local
833 if (*((CHAR16
*) Question
->BufferValue
) != 0) {
835 // There is something there! Prompt for password
837 Status
= ReadString (MenuOption
, gPromptForPassword
, StringPtr
);
838 if (EFI_ERROR (Status
)) {
839 FreePool (StringPtr
);
843 TempString
= AllocateCopyPool ((Maximum
+ 1) * sizeof (CHAR16
), Question
->BufferValue
);
844 ASSERT (TempString
!= NULL
);
846 TempString
[Maximum
] = L
'\0';
848 if (StrCmp (StringPtr
, TempString
) != 0) {
850 // Typed in old password incorrect
854 FreePool (StringPtr
);
855 FreePool (TempString
);
859 FreePool (TempString
);
864 // Ask for new password
866 ZeroMem (StringPtr
, (Maximum
+ 1) * sizeof (CHAR16
));
867 Status
= ReadString (MenuOption
, gPromptForNewPassword
, StringPtr
);
868 if (EFI_ERROR (Status
)) {
870 // Reset state machine for interactive password
872 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
873 PasswordCallback (Selection
, MenuOption
, NULL
);
876 FreePool (StringPtr
);
881 // Confirm new password
883 TempString
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
885 Status
= ReadString (MenuOption
, gConfirmPassword
, TempString
);
886 if (EFI_ERROR (Status
)) {
888 // Reset state machine for interactive password
890 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
891 PasswordCallback (Selection
, MenuOption
, NULL
);
894 FreePool (StringPtr
);
895 FreePool (TempString
);
900 // Compare two typed-in new passwords
902 if (StrCmp (StringPtr
, TempString
) == 0) {
904 // Prepare the Question->HiiValue.Value.string for ValidateQuestion use.
906 if((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
907 StringId
= Question
->HiiValue
.Value
.string
;
908 Question
->HiiValue
.Value
.string
= NewString (StringPtr
, Selection
->FormSet
->HiiHandle
);
910 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, StringPtr
, NULL
);
913 Status
= ValidateQuestion(Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
916 // Researve the Question->HiiValue.Value.string.
918 if((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
919 DeleteString(Question
->HiiValue
.Value
.string
, Selection
->FormSet
->HiiHandle
);
920 Question
->HiiValue
.Value
.string
= StringId
;
923 if (EFI_ERROR (Status
)) {
925 // Reset state machine for interactive password
927 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
928 PasswordCallback (Selection
, MenuOption
, NULL
);
931 // Researve the Question->HiiValue.Value.string.
933 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
937 // Two password match, send it to Configuration Driver
939 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
940 PasswordCallback (Selection
, MenuOption
, StringPtr
);
942 CopyMem (Question
->BufferValue
, StringPtr
, Maximum
* sizeof (CHAR16
));
943 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, FALSE
);
948 // Reset state machine for interactive password
950 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
951 PasswordCallback (Selection
, MenuOption
, NULL
);
955 // Two password mismatch, prompt error message
958 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gConfirmError
, gPressEnter
, gEmptyString
);
959 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
962 FreePool (TempString
);
963 FreePool (StringPtr
);
976 Process the help string: Split StringPtr to several lines of strings stored in
977 FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
979 @param StringPtr The entire help string.
980 @param FormattedString The oupput formatted string.
981 @param RowCount TRUE: if Question is selected.
986 IN CHAR16
*StringPtr
,
987 OUT CHAR16
**FormattedString
,
992 CHAR16
*OutputString
;
1000 // Get row number of the String.
1002 for (Index
= 0; GetLineByWidth (StringPtr
, (UINT16
) (gHelpBlockWidth
- 1), &Index
, &OutputString
) != 0x0000; ) {
1004 FreePool (OutputString
);
1007 *FormattedString
= AllocateZeroPool (TotalRowNum
* gHelpBlockWidth
* sizeof (CHAR16
) * 2);
1008 ASSERT (*FormattedString
!= NULL
);
1010 for (Index
= 0; GetLineByWidth (StringPtr
, (UINT16
) (gHelpBlockWidth
- 1), &Index
, &OutputString
) != 0x0000; CheckedNum
++) {
1011 CopyMem (*FormattedString
+ CheckedNum
* gHelpBlockWidth
* sizeof (CHAR16
), OutputString
, gHelpBlockWidth
* sizeof (CHAR16
));
1012 FreePool (OutputString
);
1015 ASSERT (CheckedNum
== TotalRowNum
);