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)) {
95 // Check the suppressif condition, only a valid option can be return.
97 if ((Option
->SuppressExpression
== NULL
) ||
98 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressFalse
))) {
103 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
111 Return data element in an Array by its Index.
113 @param Array The data array.
114 @param Type Type of the data in this array.
115 @param Index Zero based index for data in this array.
117 @retval Value The data to be returned
129 ASSERT (Array
!= NULL
);
133 case EFI_IFR_TYPE_NUM_SIZE_8
:
134 Data
= (UINT64
) *(((UINT8
*) Array
) + Index
);
137 case EFI_IFR_TYPE_NUM_SIZE_16
:
138 Data
= (UINT64
) *(((UINT16
*) Array
) + Index
);
141 case EFI_IFR_TYPE_NUM_SIZE_32
:
142 Data
= (UINT64
) *(((UINT32
*) Array
) + Index
);
145 case EFI_IFR_TYPE_NUM_SIZE_64
:
146 Data
= (UINT64
) *(((UINT64
*) Array
) + Index
);
158 Set value of a data element in an Array by its Index.
160 @param Array The data array.
161 @param Type Type of the data in this array.
162 @param Index Zero based index for data in this array.
163 @param Value The value to be set.
175 ASSERT (Array
!= NULL
);
178 case EFI_IFR_TYPE_NUM_SIZE_8
:
179 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
182 case EFI_IFR_TYPE_NUM_SIZE_16
:
183 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
186 case EFI_IFR_TYPE_NUM_SIZE_32
:
187 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
190 case EFI_IFR_TYPE_NUM_SIZE_64
:
191 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
200 Check whether this value already in the array, if yes, return the index.
202 @param Array The data array.
203 @param Type Type of the data in this array.
204 @param Value The value to be find.
205 @param Index The index in the array which has same value with Value.
207 @retval TRUE Found the value in the array.
208 @retval FALSE Not found the value.
216 OUT UINTN
*Index OPTIONAL
222 ASSERT (Array
!= NULL
);
227 while ((TmpValue
= GetArrayData (Array
, Type
, Count
)) != 0) {
228 if (Value
== TmpValue
) {
242 Print Question Value according to it's storage width and display attributes.
244 @param Question The Question to be printed.
245 @param FormattedNumber Buffer for output string.
246 @param BufferSize The FormattedNumber buffer size in bytes.
248 @retval EFI_SUCCESS Print success.
249 @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
253 PrintFormattedNumber (
254 IN FORM_BROWSER_STATEMENT
*Question
,
255 IN OUT CHAR16
*FormattedNumber
,
261 EFI_HII_VALUE
*QuestionValue
;
263 if (BufferSize
< (21 * sizeof (CHAR16
))) {
264 return EFI_BUFFER_TOO_SMALL
;
267 QuestionValue
= &Question
->HiiValue
;
269 Value
= (INT64
) QuestionValue
->Value
.u64
;
270 switch (Question
->Flags
& EFI_IFR_DISPLAY
) {
271 case EFI_IFR_DISPLAY_INT_DEC
:
272 switch (QuestionValue
->Type
) {
273 case EFI_IFR_NUMERIC_SIZE_1
:
274 Value
= (INT64
) ((INT8
) QuestionValue
->Value
.u8
);
277 case EFI_IFR_NUMERIC_SIZE_2
:
278 Value
= (INT64
) ((INT16
) QuestionValue
->Value
.u16
);
281 case EFI_IFR_NUMERIC_SIZE_4
:
282 Value
= (INT64
) ((INT32
) QuestionValue
->Value
.u32
);
285 case EFI_IFR_NUMERIC_SIZE_8
:
298 case EFI_IFR_DISPLAY_UINT_DEC
:
302 case EFI_IFR_DISPLAY_UINT_HEX
:
307 return EFI_UNSUPPORTED
;
311 UnicodeSPrint (FormattedNumber
, BufferSize
, Format
, Value
);
318 Password may be stored as encrypted by Configuration Driver. When change a
319 password, user will be challenged with old password. To validate user input old
320 password, we will send the clear text to Configuration Driver via Callback().
321 Configuration driver is responsible to check the passed in password and return
322 the validation result. If validation pass, state machine in password Callback()
323 will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
324 After user type in new password twice, Callback() will be invoked to send the
325 new password to Configuration Driver.
327 @param Selection Pointer to UI_MENU_SELECTION.
328 @param MenuOption The MenuOption for this password Question.
329 @param String The clear text of password.
331 @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
332 @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
333 @retval EFI_SUCCESS Password correct, Browser will prompt for new
335 @retval EFI_NOT_READY Password incorrect, Browser will show error
337 @retval Other Browser will do nothing.
338 @return In state of BROWSER_STATE_SET_PASSWORD:
339 @retval EFI_SUCCESS Set password success.
340 @retval Other Set password failed.
345 IN UI_MENU_SELECTION
*Selection
,
346 IN UI_MENU_OPTION
*MenuOption
,
351 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
352 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
353 EFI_IFR_TYPE_VALUE IfrTypeValue
;
355 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
356 if (ConfigAccess
== NULL
) {
357 return EFI_UNSUPPORTED
;
361 // Prepare password string in HII database
363 if (String
!= NULL
) {
364 IfrTypeValue
.string
= NewString (String
, Selection
->FormSet
->HiiHandle
);
366 IfrTypeValue
.string
= 0;
370 // Send password to Configuration Driver for validation
372 Status
= ConfigAccess
->Callback (
374 EFI_BROWSER_ACTION_CHANGING
,
375 MenuOption
->ThisTag
->QuestionId
,
376 MenuOption
->ThisTag
->HiiValue
.Type
,
382 // Remove password string from HII database
384 if (String
!= NULL
) {
385 DeleteString (IfrTypeValue
.string
, Selection
->FormSet
->HiiHandle
);
393 Display error message for invalid password.
404 // Invalid password, prompt error message
407 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gPassowordInvalid
, gPressEnter
, gEmptyString
);
408 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
413 Process a Question's Option (whether selected or un-selected).
415 @param Selection Pointer to UI_MENU_SELECTION.
416 @param MenuOption The MenuOption for this Question.
417 @param Selected TRUE: if Question is selected.
418 @param OptionString Pointer of the Option String to be displayed.
420 @retval EFI_SUCCESS Question Option process success.
421 @retval Other Question Option process fail.
426 IN UI_MENU_SELECTION
*Selection
,
427 IN UI_MENU_OPTION
*MenuOption
,
429 OUT CHAR16
**OptionString
436 FORM_BROWSER_STATEMENT
*Question
;
437 CHAR16 FormattedNumber
[21];
442 QUESTION_OPTION
*OneOfOption
;
444 EFI_HII_VALUE HiiValue
;
445 EFI_HII_VALUE
*QuestionValue
;
447 QUESTION_OPTION
*Option
;
451 EFI_STRING_ID StringId
;
453 Status
= EFI_SUCCESS
;
456 Character
[1] = L
'\0';
457 *OptionString
= NULL
;
460 ZeroMem (FormattedNumber
, 21 * sizeof (CHAR16
));
461 BufferSize
= (gOptionBlockWidth
+ 1) * 2 * gScreenDimensions
.BottomRow
;
463 Question
= MenuOption
->ThisTag
;
464 QuestionValue
= &Question
->HiiValue
;
465 Maximum
= (UINT16
) Question
->Maximum
;
467 ValueArray
= Question
->BufferValue
;
468 ValueType
= Question
->ValueType
;
470 switch (Question
->Operand
) {
471 case EFI_IFR_ORDERED_LIST_OP
:
473 // Check whether there are Options of this OrderedList
475 if (IsListEmpty (&Question
->OptionListHead
)) {
479 // Initialize Option value array
481 if (GetArrayData (ValueArray
, ValueType
, 0) == 0) {
482 GetQuestionDefault (Selection
->FormSet
, Selection
->Form
, Question
, 0);
489 Status
= GetSelectionInputPopUp (Selection
, MenuOption
);
492 // We now know how many strings we will have, so we can allocate the
493 // space required for the array or strings.
495 *OptionString
= AllocateZeroPool (Question
->MaxContainers
* BufferSize
);
496 ASSERT (*OptionString
);
498 HiiValue
.Type
= ValueType
;
499 HiiValue
.Value
.u64
= 0;
500 for (Index
= 0; Index
< Question
->MaxContainers
; Index
++) {
501 HiiValue
.Value
.u64
= GetArrayData (ValueArray
, ValueType
, Index
);
502 if (HiiValue
.Value
.u64
== 0) {
504 // Values for the options in ordered lists should never be a 0
509 OneOfOption
= ValueToOption (Question
, &HiiValue
);
510 if (OneOfOption
== NULL
) {
512 // Show error message
515 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gOptionMismatch
, gPressEnter
, gEmptyString
);
516 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
519 // The initial value of the orderedlist is invalid, force to be valid value
521 Link
= GetFirstNode (&Question
->OptionListHead
);
523 while (!IsNull (&Question
->OptionListHead
, Link
) && Index2
< Question
->MaxContainers
) {
524 Option
= QUESTION_OPTION_FROM_LINK (Link
);
525 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
526 if ((Option
->SuppressExpression
!= NULL
) &&
527 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
530 SetArrayData (ValueArray
, ValueType
, Index2
, Option
->Value
.Value
.u64
);
533 SetArrayData (ValueArray
, ValueType
, Index2
, 0);
535 Status
= SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, GetSetValueWithEditBuffer
);
536 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
538 FreePool (*OptionString
);
539 *OptionString
= NULL
;
540 return EFI_NOT_FOUND
;
543 Character
[0] = LEFT_ONEOF_DELIMITER
;
544 NewStrCat (OptionString
[0], Character
);
545 StringPtr
= GetToken (OneOfOption
->Text
, Selection
->Handle
);
546 ASSERT (StringPtr
!= NULL
);
547 NewStrCat (OptionString
[0], StringPtr
);
548 Character
[0] = RIGHT_ONEOF_DELIMITER
;
549 NewStrCat (OptionString
[0], Character
);
550 Character
[0] = CHAR_CARRIAGE_RETURN
;
551 NewStrCat (OptionString
[0], Character
);
552 FreePool (StringPtr
);
556 // Search the other options, try to find the one not in the container.
558 Link
= GetFirstNode (&Question
->OptionListHead
);
559 while (!IsNull (&Question
->OptionListHead
, Link
)) {
560 OneOfOption
= QUESTION_OPTION_FROM_LINK (Link
);
561 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
562 if ((OneOfOption
->SuppressExpression
!= NULL
) &&
563 ((EvaluateExpressionList(OneOfOption
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
567 if (FindArrayData (ValueArray
, ValueType
, OneOfOption
->Value
.Value
.u64
, NULL
)) {
571 SetArrayData (ValueArray
, ValueType
, Index
++, OneOfOption
->Value
.Value
.u64
);
573 Character
[0] = LEFT_ONEOF_DELIMITER
;
574 NewStrCat (OptionString
[0], Character
);
575 StringPtr
= GetToken (OneOfOption
->Text
, Selection
->Handle
);
576 ASSERT (StringPtr
!= NULL
);
577 NewStrCat (OptionString
[0], StringPtr
);
578 Character
[0] = RIGHT_ONEOF_DELIMITER
;
579 NewStrCat (OptionString
[0], Character
);
580 Character
[0] = CHAR_CARRIAGE_RETURN
;
581 NewStrCat (OptionString
[0], Character
);
582 FreePool (StringPtr
);
587 case EFI_IFR_ONE_OF_OP
:
589 // Check whether there are Options of this OneOf
591 if (IsListEmpty (&Question
->OptionListHead
)) {
598 Status
= GetSelectionInputPopUp (Selection
, MenuOption
);
600 *OptionString
= AllocateZeroPool (BufferSize
);
601 ASSERT (*OptionString
);
603 OneOfOption
= ValueToOption (Question
, QuestionValue
);
604 if (OneOfOption
== NULL
) {
606 // Show error message
609 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gOptionMismatch
, gPressEnter
, gEmptyString
);
610 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
613 // Force the Question value to be valid
615 Link
= GetFirstNode (&Question
->OptionListHead
);
616 while (!IsNull (&Question
->OptionListHead
, Link
)) {
617 Option
= QUESTION_OPTION_FROM_LINK (Link
);
619 if ((Option
->SuppressExpression
== NULL
) ||
620 (EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressFalse
)) {
621 CopyMem (QuestionValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
622 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, GetSetValueWithEditBuffer
);
623 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
627 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
630 FreePool (*OptionString
);
631 *OptionString
= NULL
;
632 return EFI_NOT_FOUND
;
635 Character
[0] = LEFT_ONEOF_DELIMITER
;
636 NewStrCat (OptionString
[0], Character
);
637 StringPtr
= GetToken (OneOfOption
->Text
, Selection
->Handle
);
638 ASSERT (StringPtr
!= NULL
);
639 NewStrCat (OptionString
[0], StringPtr
);
640 Character
[0] = RIGHT_ONEOF_DELIMITER
;
641 NewStrCat (OptionString
[0], Character
);
643 FreePool (StringPtr
);
647 case EFI_IFR_CHECKBOX_OP
:
648 *OptionString
= AllocateZeroPool (BufferSize
);
649 ASSERT (*OptionString
);
651 *OptionString
[0] = LEFT_CHECKBOX_DELIMITER
;
655 // Since this is a BOOLEAN operation, flip it upon selection
657 QuestionValue
->Value
.b
= (BOOLEAN
) (QuestionValue
->Value
.b
? FALSE
: TRUE
);
660 // Perform inconsistent check
662 Status
= ValidateQuestion (Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
663 if (EFI_ERROR (Status
)) {
665 // Inconsistent check fail, restore Question Value
667 QuestionValue
->Value
.b
= (BOOLEAN
) (QuestionValue
->Value
.b
? FALSE
: TRUE
);
668 FreePool (*OptionString
);
669 *OptionString
= NULL
;
674 // Save Question value
676 Status
= SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, GetSetValueWithEditBuffer
);
677 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
680 if (QuestionValue
->Value
.b
) {
681 *(OptionString
[0] + 1) = CHECK_ON
;
683 *(OptionString
[0] + 1) = CHECK_OFF
;
685 *(OptionString
[0] + 2) = RIGHT_CHECKBOX_DELIMITER
;
688 case EFI_IFR_NUMERIC_OP
:
693 Status
= GetNumericInput (Selection
, MenuOption
);
695 *OptionString
= AllocateZeroPool (BufferSize
);
696 ASSERT (*OptionString
);
698 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
703 PrintFormattedNumber (Question
, FormattedNumber
, 21 * sizeof (CHAR16
));
704 Number
= (UINT16
) GetStringWidth (FormattedNumber
);
705 CopyMem (OptionString
[0] + 1, FormattedNumber
, Number
);
707 *(OptionString
[0] + Number
/ 2) = RIGHT_NUMERIC_DELIMITER
;
711 case EFI_IFR_DATE_OP
:
714 // This is similar to numerics
716 Status
= GetNumericInput (Selection
, MenuOption
);
718 *OptionString
= AllocateZeroPool (BufferSize
);
719 ASSERT (*OptionString
);
721 switch (MenuOption
->Sequence
) {
723 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
724 UnicodeSPrint (OptionString
[0] + 1, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.date
.Month
);
725 *(OptionString
[0] + 3) = DATE_SEPARATOR
;
729 SetUnicodeMem (OptionString
[0], 4, L
' ');
730 UnicodeSPrint (OptionString
[0] + 4, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.date
.Day
);
731 *(OptionString
[0] + 6) = DATE_SEPARATOR
;
735 SetUnicodeMem (OptionString
[0], 7, L
' ');
736 UnicodeSPrint (OptionString
[0] + 7, 21 * sizeof (CHAR16
), L
"%04d", QuestionValue
->Value
.date
.Year
);
737 *(OptionString
[0] + 11) = RIGHT_NUMERIC_DELIMITER
;
743 case EFI_IFR_TIME_OP
:
746 // This is similar to numerics
748 Status
= GetNumericInput (Selection
, MenuOption
);
750 *OptionString
= AllocateZeroPool (BufferSize
);
751 ASSERT (*OptionString
);
753 switch (MenuOption
->Sequence
) {
755 *OptionString
[0] = LEFT_NUMERIC_DELIMITER
;
756 UnicodeSPrint (OptionString
[0] + 1, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Hour
);
757 *(OptionString
[0] + 3) = TIME_SEPARATOR
;
761 SetUnicodeMem (OptionString
[0], 4, L
' ');
762 UnicodeSPrint (OptionString
[0] + 4, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Minute
);
763 *(OptionString
[0] + 6) = TIME_SEPARATOR
;
767 SetUnicodeMem (OptionString
[0], 7, L
' ');
768 UnicodeSPrint (OptionString
[0] + 7, 21 * sizeof (CHAR16
), L
"%02d", QuestionValue
->Value
.time
.Second
);
769 *(OptionString
[0] + 9) = RIGHT_NUMERIC_DELIMITER
;
775 case EFI_IFR_STRING_OP
:
777 StringPtr
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
779 CopyMem(StringPtr
, Question
->BufferValue
, Maximum
* sizeof (CHAR16
));
781 Status
= ReadString (MenuOption
, gPromptForData
, StringPtr
);
782 if (!EFI_ERROR (Status
)) {
783 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, StringPtr
, NULL
);
784 Status
= ValidateQuestion(Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
785 if (EFI_ERROR (Status
)) {
786 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
788 CopyMem (Question
->BufferValue
, StringPtr
, Maximum
* sizeof (CHAR16
));
789 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, GetSetValueWithEditBuffer
);
791 UpdateStatusBar (Selection
, NV_UPDATE_REQUIRED
, Question
->QuestionFlags
, TRUE
);
795 FreePool (StringPtr
);
797 *OptionString
= AllocateZeroPool (BufferSize
);
798 ASSERT (*OptionString
);
800 if (((CHAR16
*) Question
->BufferValue
)[0] == 0x0000) {
801 *(OptionString
[0]) = '_';
803 if ((Maximum
* sizeof (CHAR16
)) < BufferSize
) {
804 BufferSize
= Maximum
* sizeof (CHAR16
);
806 CopyMem (OptionString
[0], (CHAR16
*) Question
->BufferValue
, BufferSize
);
811 case EFI_IFR_PASSWORD_OP
:
813 StringPtr
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
817 // For interactive passwords, old password is validated by callback
819 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
821 // Use a NULL password to test whether old password is required
824 Status
= PasswordCallback (Selection
, MenuOption
, StringPtr
);
825 if (Status
== EFI_NOT_AVAILABLE_YET
|| Status
== EFI_UNSUPPORTED
) {
827 // Callback is not supported, or
828 // Callback request to terminate password input
830 FreePool (StringPtr
);
834 if (EFI_ERROR (Status
)) {
836 // Old password exist, ask user for the old password
838 Status
= ReadString (MenuOption
, gPromptForPassword
, StringPtr
);
839 if (EFI_ERROR (Status
)) {
840 FreePool (StringPtr
);
845 // Check user input old password
847 Status
= PasswordCallback (Selection
, MenuOption
, StringPtr
);
848 if (EFI_ERROR (Status
)) {
849 if (Status
== EFI_NOT_READY
) {
851 // Typed in old password incorrect
855 Status
= EFI_SUCCESS
;
858 FreePool (StringPtr
);
864 // For non-interactive password, validate old password in local
866 if (*((CHAR16
*) Question
->BufferValue
) != 0) {
868 // There is something there! Prompt for password
870 Status
= ReadString (MenuOption
, gPromptForPassword
, StringPtr
);
871 if (EFI_ERROR (Status
)) {
872 FreePool (StringPtr
);
876 TempString
= AllocateCopyPool ((Maximum
+ 1) * sizeof (CHAR16
), Question
->BufferValue
);
877 ASSERT (TempString
!= NULL
);
879 TempString
[Maximum
] = L
'\0';
881 if (StrCmp (StringPtr
, TempString
) != 0) {
883 // Typed in old password incorrect
887 FreePool (StringPtr
);
888 FreePool (TempString
);
892 FreePool (TempString
);
897 // Ask for new password
899 ZeroMem (StringPtr
, (Maximum
+ 1) * sizeof (CHAR16
));
900 Status
= ReadString (MenuOption
, gPromptForNewPassword
, StringPtr
);
901 if (EFI_ERROR (Status
)) {
903 // Reset state machine for interactive password
905 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
906 PasswordCallback (Selection
, MenuOption
, NULL
);
909 FreePool (StringPtr
);
914 // Confirm new password
916 TempString
= AllocateZeroPool ((Maximum
+ 1) * sizeof (CHAR16
));
918 Status
= ReadString (MenuOption
, gConfirmPassword
, TempString
);
919 if (EFI_ERROR (Status
)) {
921 // Reset state machine for interactive password
923 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
924 PasswordCallback (Selection
, MenuOption
, NULL
);
927 FreePool (StringPtr
);
928 FreePool (TempString
);
933 // Compare two typed-in new passwords
935 if (StrCmp (StringPtr
, TempString
) == 0) {
937 // Prepare the Question->HiiValue.Value.string for ValidateQuestion use.
939 if((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
940 StringId
= Question
->HiiValue
.Value
.string
;
941 Question
->HiiValue
.Value
.string
= NewString (StringPtr
, Selection
->FormSet
->HiiHandle
);
943 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, StringPtr
, NULL
);
946 Status
= ValidateQuestion(Selection
->FormSet
, Selection
->Form
, Question
, EFI_HII_EXPRESSION_INCONSISTENT_IF
);
949 // Researve the Question->HiiValue.Value.string.
951 if((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
952 DeleteString(Question
->HiiValue
.Value
.string
, Selection
->FormSet
->HiiHandle
);
953 Question
->HiiValue
.Value
.string
= StringId
;
956 if (EFI_ERROR (Status
)) {
958 // Reset state machine for interactive password
960 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
961 PasswordCallback (Selection
, MenuOption
, NULL
);
964 // Researve the Question->HiiValue.Value.string.
966 HiiSetString(Selection
->FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
970 // Two password match, send it to Configuration Driver
972 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
973 PasswordCallback (Selection
, MenuOption
, StringPtr
);
975 CopyMem (Question
->BufferValue
, StringPtr
, Maximum
* sizeof (CHAR16
));
976 SetQuestionValue (Selection
->FormSet
, Selection
->Form
, Question
, GetSetValueWithHiiDriver
);
981 // Reset state machine for interactive password
983 if ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
984 PasswordCallback (Selection
, MenuOption
, NULL
);
988 // Two password mismatch, prompt error message
991 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, gConfirmError
, gPressEnter
, gEmptyString
);
992 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
995 FreePool (TempString
);
996 FreePool (StringPtr
);
1009 Process the help string: Split StringPtr to several lines of strings stored in
1010 FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
1012 @param StringPtr The entire help string.
1013 @param FormattedString The oupput formatted string.
1014 @param EachLineWidth The max string length of each line in the formatted string.
1015 @param RowCount TRUE: if Question is selected.
1020 IN CHAR16
*StringPtr
,
1021 OUT CHAR16
**FormattedString
,
1022 OUT UINT16
*EachLineWidth
,
1027 CHAR16
*OutputString
;
1032 UINT16 MaxStringLen
;
1043 // Set default help string width.
1045 LineWidth
= (UINT16
) (gHelpBlockWidth
- 1);
1048 // Get row number of the String.
1050 while ((StringLen
= GetLineByWidth (StringPtr
, LineWidth
, &GlyphWidth
, &Index
, &OutputString
)) != 0) {
1051 if (StringLen
> MaxStringLen
) {
1052 MaxStringLen
= StringLen
;
1056 FreePool (OutputString
);
1058 *EachLineWidth
= MaxStringLen
;
1060 *FormattedString
= AllocateZeroPool (TotalRowNum
* MaxStringLen
* sizeof (CHAR16
));
1061 ASSERT (*FormattedString
!= NULL
);
1064 // Generate formatted help string array.
1068 while((StringLen
= GetLineByWidth (StringPtr
, LineWidth
, &GlyphWidth
, &Index
, &OutputString
)) != 0) {
1069 CopyMem (*FormattedString
+ CheckedNum
* MaxStringLen
, OutputString
, StringLen
* sizeof (CHAR16
));
1071 FreePool (OutputString
);