Implement GetQuestionDefault() in HiiUtilityLib. Caller can get question default value from this interface. GetQuestionDefault() is created and modifed from SetupBrowserDxe\Setup.c under MdeModulePkg.
Signed-off-by: Nickle Wang <nick...@nvidia.com> Cc: Abner Chang <abner.ch...@amd.com> Cc: Igor Kulchytskyy <ig...@ami.com> Cc: Nick Ramirez <nrami...@nvidia.com> --- RedfishPkg/Include/Library/HiiUtilityLib.h | 31 +- .../Library/HiiUtilityLib/HiiExpression.c | 77 +++ .../Library/HiiUtilityLib/HiiExpression.h | 23 + .../HiiUtilityLib/HiiUtilityInternal.c | 614 ++++++++++++++++++ 4 files changed, 728 insertions(+), 17 deletions(-) diff --git a/RedfishPkg/Include/Library/HiiUtilityLib.h b/RedfishPkg/Include/Library/HiiUtilityLib.h index 1f164ba49c..f4be485423 100644 --- a/RedfishPkg/Include/Library/HiiUtilityLib.h +++ b/RedfishPkg/Include/Library/HiiUtilityLib.h @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1168,28 +1169,24 @@ GetHiiExpressionDependency ( ); /** - Evaluate the result of a HII expression. - - If Expression is NULL, then ASSERT. + Get default value of question. - @param FormSet FormSet associated with this expression. - @param Form Form associated with this expression. - @param Expression Expression to be evaluated. + @param FormSet The form set. + @param Form The form. + @param Question The question. + @param DefaultId The Class of the default. + @param DefaultValue The default value of given question. - @retval EFI_SUCCESS The expression evaluated successfuly - @retval EFI_NOT_FOUND The Question which referenced by a QuestionId - could not be found. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the - stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack - @retval EFI_INVALID_PARAMETER Syntax error with the Expression + @retval EFI_SUCCESS Question is reset to default value. **/ EFI_STATUS -HpEvaluateHiiExpression ( - IN HII_FORMSET *FormSet, - IN HII_FORM *Form, - IN OUT HII_EXPRESSION *Expression +GetQuestionDefault ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question, + IN UINT16 DefaultId, + OUT HII_STATEMENT_VALUE *DefaultValue ); #endif // _HII_UTILITY_LIB_ diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c index 7111b40acf..c6954587f5 100644 --- a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1365,3 +1366,79 @@ GetHiiExpressionDependency ( Done: return Status; } + +/** + Return the result of the expression list. Check the expression list and + return the highest priority express result. + Priority: DisableIf > SuppressIf > GrayOutIf > FALSE + + @param ExpList The input expression list. + @param Evaluate Whether need to evaluate the expression first. + @param FormSet FormSet associated with this expression. + @param Form Form associated with this expression. + + @retval EXPRESS_RESULT Return the higher priority express result. + DisableIf > SuppressIf > GrayOutIf > FALSE + +**/ +EXPRESS_RESULT +EvaluateExpressionList ( + IN HII_EXPRESSION_LIST *ExpList, + IN BOOLEAN Evaluate, + IN HII_FORMSET *FormSet, OPTIONAL + IN HII_FORM *Form OPTIONAL + ) +{ + UINTN Index; + EXPRESS_RESULT ReturnVal; + EXPRESS_RESULT CompareOne; + EFI_STATUS Status; + + if (ExpList == NULL) { + return ExpressFalse; + } + + ASSERT (ExpList->Signature == HII_EXPRESSION_LIST_SIGNATURE); + Index = 0; + + // + // Check whether need to evaluate the expression first. + // + if (Evaluate) { + while (ExpList->Count > Index) { + Status = EvaluateHiiExpression (FormSet, Form, ExpList->Expression[Index++]); + if (EFI_ERROR (Status)) { + return ExpressFalse; + } + } + } + + // + // Run the list of expressions. + // + ReturnVal = ExpressFalse; + for (Index = 0; Index < ExpList->Count; Index++) { + if (IsTrue (&ExpList->Expression[Index]->Result)) { + switch (ExpList->Expression[Index]->Type) { + case EFI_HII_EXPRESSION_SUPPRESS_IF: + CompareOne = ExpressSuppress; + break; + + case EFI_HII_EXPRESSION_GRAY_OUT_IF: + CompareOne = ExpressGrayOut; + break; + + case EFI_HII_EXPRESSION_DISABLE_IF: + CompareOne = ExpressDisable; + break; + + default: + return ExpressFalse; + } + + ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal; + } + } + + return ReturnVal; +} diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h index e96c07b4de..25a3a44b48 100644 --- a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -187,4 +188,26 @@ PopScope ( OUT UINT8 *Operand ); +/** + Return the result of the expression list. Check the expression list and + return the highest priority express result. + Priority: DisableIf > SuppressIf > GrayOutIf > FALSE + + @param ExpList The input expression list. + @param Evaluate Whether need to evaluate the expression first. + @param FormSet FormSet associated with this expression. + @param Form Form associated with this expression. + + @retval EXPRESS_RESULT Return the higher priority express result. + DisableIf > SuppressIf > GrayOutIf > FALSE + +**/ +EXPRESS_RESULT +EvaluateExpressionList ( + IN HII_EXPRESSION_LIST *ExpList, + IN BOOLEAN Evaluate, + IN HII_FORMSET *FormSet, OPTIONAL + IN HII_FORM *Form OPTIONAL + ); + #endif diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c index 55b78315d1..b4dd61f360 100644 --- a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c +++ b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -5043,3 +5044,616 @@ Done: return Status; } + +/** + Set value of a data element in an Array by its Index. + + @param Array The data array. + @param Type Type of the data in this array. + @param Index Zero based index for data in this array. + @param Value The value to be set. + +**/ +VOID +SetArrayData ( + IN VOID *Array, + IN UINT8 Type, + IN UINTN Index, + IN UINT64 Value + ) +{ + ASSERT (Array != NULL); + + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + *(((UINT8 *)Array) + Index) = (UINT8)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + *(((UINT16 *)Array) + Index) = (UINT16)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + *(((UINT32 *)Array) + Index) = (UINT32)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_64: + *(((UINT64 *)Array) + Index) = (UINT64)Value; + break; + + default: + break; + } +} + +/** + Search an Option of a Question by its value. + + @param Question The Question + @param OptionValue Value for Option to be searched. + + @retval Pointer Pointer to the found Option. + @retval NULL Option not found. + +**/ +HII_QUESTION_OPTION * +ValueToOption ( + IN HII_STATEMENT *Question, + IN HII_STATEMENT_VALUE *OptionValue + ) +{ + LIST_ENTRY *Link; + HII_QUESTION_OPTION *Option; + EFI_HII_VALUE Data1; + EFI_HII_VALUE Data2; + INTN Result; + EFI_STATUS Status; + + Status = HiiStatementValueToHiiValue (OptionValue, &Data1); + ASSERT_EFI_ERROR (Status); + + Link = GetFirstNode (&Question->OptionListHead); + while (!IsNull (&Question->OptionListHead, Link)) { + Option = HII_QUESTION_OPTION_FROM_LINK (Link); + + Status = HiiStatementValueToHiiValue (&Option->Value, &Data2); + ASSERT_EFI_ERROR (Status); + + if ((CompareHiiValue (&Data1, &Data2, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) { + // + // Check the suppressif condition, only a valid option can be return. + // + if ((Option->SuppressExpression == NULL) || + ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) + { + return Option; + } + } + + Link = GetNextNode (&Question->OptionListHead, Link); + } + + return NULL; +} + +/** + Find the point in the ConfigResp string for this question. + + @param Question The question. + @param ConfigResp Get ConfigResp string. + + @retval point to the offset where is for this question. + +**/ +CHAR16 * +GetOffsetFromConfigResp ( + IN HII_STATEMENT *Question, + IN CHAR16 *ConfigResp + ) +{ + CHAR16 *RequestElement; + CHAR16 *BlockData; + + // + // Type is EFI_HII_VARSTORE_NAME_VALUE. + // + if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { + RequestElement = StrStr (ConfigResp, Question->VariableName); + if (RequestElement != NULL) { + // + // Skip the "VariableName=" field. + // + RequestElement += StrLen (Question->VariableName) + 1; + } + + return RequestElement; + } + + // + // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER + // + + // + // Convert all hex digits in ConfigResp to lower case before searching. + // + HiiToLower (ConfigResp); + + // + // 1. Directly use Question->BlockName to find. + // + RequestElement = StrStr (ConfigResp, Question->BlockName); + if (RequestElement != NULL) { + // + // Skip the "Question->BlockName&VALUE=" field. + // + RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE="); + return RequestElement; + } + + // + // 2. Change all hex digits in Question->BlockName to lower and compare again. + // + BlockData = AllocateCopyPool (StrSize (Question->BlockName), Question->BlockName); + ASSERT (BlockData != NULL); + HiiToLower (BlockData); + RequestElement = StrStr (ConfigResp, BlockData); + FreePool (BlockData); + + if (RequestElement != NULL) { + // + // Skip the "Question->BlockName&VALUE=" field. + // + RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE="); + } + + return RequestElement; +} + +/** + Get Question default value from AltCfg string. + + @param FormSet The form set. + @param Form The form + @param Question The question. + @param DefaultValue Default value. + + @retval EFI_SUCCESS Question is reset to default value. + +**/ +EFI_STATUS +GetDefaultValueFromAltCfg ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question, + OUT HII_STATEMENT_VALUE *DefaultValue + ) +{ + HII_FORMSET_STORAGE *Storage; + CHAR16 *ConfigResp; + CHAR16 *Value; + LIST_ENTRY *Link; + HII_FORM_CONFIG_REQUEST *ConfigInfo; + + Storage = Question->Storage; + if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) { + return EFI_NOT_FOUND; + } + + // + // Try to get AltCfg string from form. If not found it, then + // try to get it from formset. + // + ConfigResp = NULL; + Link = GetFirstNode (&Form->ConfigRequestHead); + while (!IsNull (&Form->ConfigRequestHead, Link)) { + ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link); + Link = GetNextNode (&Form->ConfigRequestHead, Link); + + if (Storage == ConfigInfo->Storage) { + ConfigResp = ConfigInfo->ConfigAltResp; + break; + } + } + + if (ConfigResp == NULL) { + return EFI_NOT_FOUND; + } + + Value = GetOffsetFromConfigResp (Question, ConfigResp); + if (Value == NULL) { + return EFI_NOT_FOUND; + } + + return BufferToValue (Question, Value, DefaultValue); +} + +/** + Get default Id value used for browser. + + @param DefaultId The default id value used by hii. + + @retval Browser used default value. + +**/ +INTN +GetDefaultIdForCallBack ( + UINTN DefaultId + ) +{ + if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) { + return EFI_BROWSER_ACTION_DEFAULT_STANDARD; + } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) { + return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING; + } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) { + return EFI_BROWSER_ACTION_DEFAULT_SAFE; + } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000)) { + return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN; + } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000)) { + return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN; + } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000)) { + return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN; + } else { + return -1; + } +} + +/** + Get default value of question. + + @param FormSet The form set. + @param Form The form. + @param Question The question. + @param DefaultId The Class of the default. + @param DefaultValue The default value of given question. + + @retval EFI_SUCCESS Question is reset to default value. + +**/ +EFI_STATUS +GetQuestionDefault ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question, + IN UINT16 DefaultId, + OUT HII_STATEMENT_VALUE *DefaultValue + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Link; + HII_QUESTION_DEFAULT *Default; + HII_QUESTION_OPTION *Option; + HII_STATEMENT_VALUE *HiiValue; + UINT8 Index; + EFI_STRING StrValue; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + EFI_BROWSER_ACTION_REQUEST ActionRequest; + INTN Action; + EFI_IFR_TYPE_VALUE *TypeValue; + UINT16 OriginalDefaultId; + HII_FORMSET_DEFAULTSTORE *DefaultStore; + LIST_ENTRY *DefaultLink; + + if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) || (DefaultValue == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_NOT_FOUND; + StrValue = NULL; + OriginalDefaultId = DefaultId; + DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead); + + // + // Statement don't have storage, skip them + // + if (Question->QuestionId == 0) { + return Status; + } + + // + // There are Five ways to specify default value for a Question: + // 1, use call back function (highest priority) + // 2, use ExtractConfig function + // 3, use nested EFI_IFR_DEFAULT + // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default) + // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority) + // + CopyMem (DefaultValue, &Question->Value, sizeof (HII_STATEMENT_VALUE)); +ReGetDefault: + HiiValue = DefaultValue; + TypeValue = &HiiValue->Value; + if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) { + // + // For orderedlist, need to pass the BufferValue to Callback function. + // + DefaultValue->BufferLen = Question->Value.BufferLen; + DefaultValue->Buffer = AllocateZeroPool (DefaultValue->BufferLen); + ASSERT (DefaultValue->Buffer != NULL); + if (DefaultValue->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TypeValue = (EFI_IFR_TYPE_VALUE *)DefaultValue->Buffer; + } + + // + // Get Question defaut value from call back function. + // The string type of question cause HII driver to set string to its default value. + // So, we don't do this otherwise it will actually set question to default value. + // We only want to get default value of question. + // + if (HiiValue->Type != EFI_IFR_TYPE_STRING) { + ConfigAccess = FormSet->ConfigAccess; + Action = GetDefaultIdForCallBack (DefaultId); + if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) { + ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + Status = ConfigAccess->Callback ( + ConfigAccess, + Action, + Question->QuestionId, + HiiValue->Type, + TypeValue, + &ActionRequest + ); + if (!EFI_ERROR (Status)) { + return Status; + } + } + } + + // + // Get default value from altcfg string. + // + if (ConfigAccess != NULL) { + Status = GetDefaultValueFromAltCfg (FormSet, Form, Question, DefaultValue); + if (!EFI_ERROR (Status)) { + return Status; + } + } + + // + // EFI_IFR_DEFAULT has highest priority + // + if (!IsListEmpty (&Question->DefaultListHead)) { + Link = GetFirstNode (&Question->DefaultListHead); + while (!IsNull (&Question->DefaultListHead, Link)) { + Default = HII_QUESTION_DEFAULT_FROM_LINK (Link); + + if (Default->DefaultId == DefaultId) { + if (Default->ValueExpression != NULL) { + // + // Default is provided by an Expression, evaluate it + // + Status = EvaluateHiiExpression (FormSet, Form, Default->ValueExpression); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) { + ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && DefaultValue->Buffer != NULL); + if (DefaultValue->BufferLen > Default->ValueExpression->Result.BufferLen) { + CopyMem (DefaultValue->Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen); + DefaultValue->BufferLen = Default->ValueExpression->Result.BufferLen; + } else { + CopyMem (DefaultValue->Buffer, Default->ValueExpression->Result.Buffer, DefaultValue->BufferLen); + } + + FreePool (Default->ValueExpression->Result.Buffer); + } + + HiiValue->Type = Default->ValueExpression->Result.Type; + CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); + } else { + // + // Default value is embedded in EFI_IFR_DEFAULT + // + if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) { + ASSERT (HiiValue->Buffer != NULL); + CopyMem (HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen); + } else { + CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE)); + } + } + + if (HiiValue->Type == EFI_IFR_TYPE_STRING) { + StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string, NULL); + if (StrValue == NULL) { + return EFI_NOT_FOUND; + } + + if (DefaultValue->BufferLen > StrSize (StrValue)) { + ZeroMem (DefaultValue->Buffer, DefaultValue->BufferLen); + CopyMem (DefaultValue->Buffer, StrValue, StrSize (StrValue)); + } else { + CopyMem (DefaultValue->Buffer, StrValue, DefaultValue->BufferLen); + } + } + + return EFI_SUCCESS; + } + + Link = GetNextNode (&Question->DefaultListHead, Link); + } + } + + // + // EFI_ONE_OF_OPTION + // + if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) { + if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) { + // + // OneOfOption could only provide Standard and Manufacturing default + // + Link = GetFirstNode (&Question->OptionListHead); + while (!IsNull (&Question->OptionListHead, Link)) { + Option = HII_QUESTION_OPTION_FROM_LINK (Link); + Link = GetNextNode (&Question->OptionListHead, Link); + + if ((Option->SuppressExpression != NULL) && + (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse)) + { + continue; + } + + if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) || + ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0)) + ) + { + CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE)); + + return EFI_SUCCESS; + } + } + } + } + + // + // EFI_IFR_CHECKBOX - lowest priority + // + if (Question->Operand == EFI_IFR_CHECKBOX_OP) { + if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) { + // + // Checkbox could only provide Standard and Manufacturing default + // + if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) || + ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0)) + ) + { + HiiValue->Value.b = TRUE; + } + + return EFI_SUCCESS; + } + } + + // + // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList. + // If get, will exit the function, if not, will choose next default id in the DefaultStoreList. + // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time. + // + while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) { + DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink); + DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink); + DefaultId = DefaultStore->DefaultId; + if (DefaultId == OriginalDefaultId) { + continue; + } + + goto ReGetDefault; + } + + // + // For Questions without default value for all the default id in the DefaultStoreList. + // + Status = EFI_NOT_FOUND; + switch (Question->Operand) { + case EFI_IFR_CHECKBOX_OP: + HiiValue->Value.b = FALSE; + Status = EFI_SUCCESS; + break; + + case EFI_IFR_NUMERIC_OP: + // + // Take minimum value as numeric default value + // + if ((Question->ExtraData.NumData.Flags & EFI_IFR_DISPLAY) == 0) { + // + // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type. + // + switch (Question->ExtraData.NumData.Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + if (((INT8)HiiValue->Value.u8 < (INT8)Question->ExtraData.NumData.Minimum) || ((INT8)HiiValue->Value.u8 > (INT8)Question->ExtraData.NumData.Maximum)) { + HiiValue->Value.u8 = (UINT8)Question->ExtraData.NumData.Minimum; + Status = EFI_SUCCESS; + } + + break; + case EFI_IFR_NUMERIC_SIZE_2: + if (((INT16)HiiValue->Value.u16 < (INT16)Question->ExtraData.NumData.Minimum) || ((INT16)HiiValue->Value.u16 > (INT16)Question->ExtraData.NumData.Maximum)) { + HiiValue->Value.u16 = (UINT16)Question->ExtraData.NumData.Minimum; + Status = EFI_SUCCESS; + } + + break; + case EFI_IFR_NUMERIC_SIZE_4: + if (((INT32)HiiValue->Value.u32 < (INT32)Question->ExtraData.NumData.Minimum) || ((INT32)HiiValue->Value.u32 > (INT32)Question->ExtraData.NumData.Maximum)) { + HiiValue->Value.u32 = (UINT32)Question->ExtraData.NumData.Minimum; + Status = EFI_SUCCESS; + } + + break; + case EFI_IFR_NUMERIC_SIZE_8: + if (((INT64)HiiValue->Value.u64 < (INT64)Question->ExtraData.NumData.Minimum) || ((INT64)HiiValue->Value.u64 > (INT64)Question->ExtraData.NumData.Maximum)) { + HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum; + Status = EFI_SUCCESS; + } + + break; + default: + break; + } + } else { + if ((HiiValue->Value.u64 < Question->ExtraData.NumData.Minimum) || (HiiValue->Value.u64 > Question->ExtraData.NumData.Maximum)) { + HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum; + Status = EFI_SUCCESS; + } + } + + break; + + case EFI_IFR_ONE_OF_OP: + // + // Take first oneof option as oneof's default value + // + if (ValueToOption (Question, HiiValue) == NULL) { + Link = GetFirstNode (&Question->OptionListHead); + while (!IsNull (&Question->OptionListHead, Link)) { + Option = HII_QUESTION_OPTION_FROM_LINK (Link); + Link = GetNextNode (&Question->OptionListHead, Link); + + if ((Option->SuppressExpression != NULL) && + (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse)) + { + continue; + } + + CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE)); + Status = EFI_SUCCESS; + break; + } + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + // + // Take option sequence in IFR as ordered list's default value + // + Index = 0; + Link = GetFirstNode (&Question->OptionListHead); + while (!IsNull (&Question->OptionListHead, Link)) { + Status = EFI_SUCCESS; + Option = HII_QUESTION_OPTION_FROM_LINK (Link); + Link = GetNextNode (&Question->OptionListHead, Link); + + if ((Option->SuppressExpression != NULL) && + (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse)) + { + continue; + } + + SetArrayData (DefaultValue->Buffer, Question->Value.Type, Index, Option->Value.Value.u64); + + Index++; + if (Index >= Question->ExtraData.OrderListData.MaxContainers) { + break; + } + } + + break; + + default: + break; + } + + return Status; +} -- 2.38.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#97078): https://edk2.groups.io/g/devel/message/97078 Mute This Topic: https://groups.io/mt/95515739/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-