+ //\r
+ // Clean the list which will not process.\r
+ //\r
+ while (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
+ Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_SAVE_FAIL_LINK (Link);\r
+ RemoveEntryList (&LocalFormSet->SaveFailLink);\r
+\r
+ while (!IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
+ StorageLink = GetFirstNode (&LocalFormSet->SaveFailStorageListHead);\r
+ FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (StorageLink);\r
+ RemoveEntryList (&FormSetStorage->SaveFailLink);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Submit data based on the input Setting level (Form, FormSet or System).\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param SettingScope Setting Scope for Submit action.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
+\r
+**/\r
+EFI_STATUS\r
+SubmitForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BROWSER_SETTING_SCOPE SettingScope\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ switch (SettingScope) {\r
+ case FormLevel:\r
+ Status = SubmitForForm (FormSet, Form);\r
+ break;\r
+\r
+ case FormSetLevel:\r
+ Status = SubmitForFormSet (FormSet, FALSE);\r
+ break;\r
+\r
+ case SystemLevel:\r
+ Status = SubmitForSystem ();\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Converts the unicode character of the string from uppercase to lowercase.\r
+ This is a internal function.\r
+\r
+ @param ConfigString String to be converted\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+ IN EFI_STRING ConfigString\r
+ )\r
+{\r
+ EFI_STRING String;\r
+ BOOLEAN Lower;\r
+\r
+ ASSERT (ConfigString != NULL);\r
+\r
+ //\r
+ // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
+ //\r
+ for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
+ if (*String == L'=') {\r
+ Lower = TRUE;\r
+ } else if (*String == L'&') {\r
+ Lower = FALSE;\r
+ } else if (Lower && (*String >= L'A') && (*String <= L'F')) {\r
+ *String = (CHAR16)(*String - L'A' + L'a');\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Find the point in the ConfigResp string for this question.\r
+\r
+ @param Question The question.\r
+ @param ConfigResp Get ConfigResp string.\r
+\r
+ @retval point to the offset where is for this question.\r
+\r
+**/\r
+CHAR16 *\r
+GetOffsetFromConfigResp (\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN CHAR16 *ConfigResp\r
+ )\r
+{\r
+ CHAR16 *RequestElement;\r
+ CHAR16 *BlockData;\r
+\r
+ //\r
+ // Type is EFI_HII_VARSTORE_NAME_VALUE.\r
+ //\r
+ if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ RequestElement = StrStr (ConfigResp, Question->VariableName);\r
+ if (RequestElement != NULL) {\r
+ //\r
+ // Skip the "VariableName=" field.\r
+ //\r
+ RequestElement += StrLen (Question->VariableName) + 1;\r
+ }\r
+\r
+ return RequestElement;\r
+ }\r
+\r
+ //\r
+ // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\r
+ //\r
+\r
+ //\r
+ // Convert all hex digits in ConfigResp to lower case before searching.\r
+ //\r
+ HiiToLower (ConfigResp);\r
+\r
+ //\r
+ // 1. Directly use Question->BlockName to find.\r
+ //\r
+ RequestElement = StrStr (ConfigResp, Question->BlockName);\r
+ if (RequestElement != NULL) {\r
+ //\r
+ // Skip the "Question->BlockName&VALUE=" field.\r
+ //\r
+ RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
+ return RequestElement;\r
+ }\r
+\r
+ //\r
+ // 2. Change all hex digits in Question->BlockName to lower and compare again.\r
+ //\r
+ BlockData = AllocateCopyPool (StrSize (Question->BlockName), Question->BlockName);\r
+ ASSERT (BlockData != NULL);\r
+ HiiToLower (BlockData);\r
+ RequestElement = StrStr (ConfigResp, BlockData);\r
+ FreePool (BlockData);\r
+\r
+ if (RequestElement != NULL) {\r
+ //\r
+ // Skip the "Question->BlockName&VALUE=" field.\r
+ //\r
+ RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
+ }\r
+\r
+ return RequestElement;\r
+}\r
+\r
+/**\r
+ Get Question default value from AltCfg string.\r
+\r
+ @param FormSet The form set.\r
+ @param Form The form\r
+ @param Question The question.\r
+\r
+ @retval EFI_SUCCESS Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetDefaultValueFromAltCfg (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN OUT FORM_BROWSER_STATEMENT *Question\r
+ )\r
+{\r
+ BROWSER_STORAGE *Storage;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Value;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+\r
+ Storage = Question->Storage;\r
+ if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Try to get AltCfg string from form. If not found it, then\r
+ // try to get it from formset.\r
+ //\r
+ ConfigResp = NULL;\r
+ Link = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+ if (Storage == ConfigInfo->Storage) {\r
+ ConfigResp = ConfigInfo->ConfigAltResp;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (ConfigResp == NULL) {\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (Storage == FormSetStorage->BrowserStorage) {\r
+ ConfigResp = FormSetStorage->ConfigAltResp;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (ConfigResp == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Value = GetOffsetFromConfigResp (Question, ConfigResp);\r
+ if (Value == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return BufferToValue (Question, Value);\r
+}\r
+\r
+/**\r
+ Get default Id value used for browser.\r
+\r
+ @param DefaultId The default id value used by hii.\r
+\r
+ @retval Browser used default value.\r
+\r
+**/\r
+INTN\r
+GetDefaultIdForCallBack (\r
+ UINTN DefaultId\r
+ )\r
+{\r
+ if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
+ } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
+ } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
+ } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000)) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
+ } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000)) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
+ } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000)) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
+ } else {\r
+ return -1;\r
+ }\r
+}\r
+\r
+/**\r
+ Return data element in an Array by its Index.\r
+\r
+ @param Array The data array.\r
+ @param Type Type of the data in this array.\r
+ @param Index Zero based index for data in this array.\r
+\r
+ @retval Value The data to be returned\r
+\r
+**/\r
+UINT64\r
+GetArrayData (\r
+ IN VOID *Array,\r
+ IN UINT8 Type,\r
+ IN UINTN Index\r
+ )\r
+{\r
+ UINT64 Data;\r
+\r
+ ASSERT (Array != NULL);\r
+\r
+ Data = 0;\r
+ switch (Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ Data = (UINT64)*(((UINT8 *)Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ Data = (UINT64)*(((UINT16 *)Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ Data = (UINT64)*(((UINT32 *)Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ Data = (UINT64)*(((UINT64 *)Array) + Index);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return Data;\r
+}\r
+\r
+/**\r
+ Set value of a data element in an Array by its Index.\r
+\r
+ @param Array The data array.\r
+ @param Type Type of the data in this array.\r
+ @param Index Zero based index for data in this array.\r
+ @param Value The value to be set.\r
+\r
+**/\r
+VOID\r
+SetArrayData (\r
+ IN VOID *Array,\r
+ IN UINT8 Type,\r
+ IN UINTN Index,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ ASSERT (Array != NULL);\r
+\r
+ switch (Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ *(((UINT8 *)Array) + Index) = (UINT8)Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ *(((UINT16 *)Array) + Index) = (UINT16)Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ *(((UINT32 *)Array) + Index) = (UINT32)Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ *(((UINT64 *)Array) + Index) = (UINT64)Value;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+/**\r
+ Search an Option of a Question by its value.\r
+\r
+ @param Question The Question\r
+ @param OptionValue Value for Option to be searched.\r
+\r
+ @retval Pointer Pointer to the found Option.\r
+ @retval NULL Option not found.\r
+\r
+**/\r
+QUESTION_OPTION *\r
+ValueToOption (\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN EFI_HII_VALUE *OptionValue\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_OPTION *Option;\r
+ INTN Result;\r
+\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+ if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
+ //\r
+ // Check the suppressif condition, only a valid option can be return.\r
+ //\r
+ if ((Option->SuppressExpression == NULL) ||\r
+ ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)))\r
+ {\r
+ return Option;\r
+ }\r
+ }\r
+\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Reset Question to its default value.\r
+\r
+ @param FormSet The form set.\r
+ @param Form The form.\r
+ @param Question The question.\r
+ @param DefaultId The Class of the default.\r
+\r
+ @retval EFI_SUCCESS Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetQuestionDefault (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN UINT16 DefaultId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ QUESTION_DEFAULT *Default;\r
+ QUESTION_OPTION *Option;\r
+ EFI_HII_VALUE *HiiValue;\r
+ UINT8 Index;\r
+ EFI_STRING StrValue;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ INTN Action;\r
+ CHAR16 *NewString;\r
+ EFI_IFR_TYPE_VALUE *TypeValue;\r
+ UINT16 OriginalDefaultId;\r
+ FORMSET_DEFAULTSTORE *DefaultStore;\r
+ LIST_ENTRY *DefaultLink;\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ StrValue = NULL;\r
+ OriginalDefaultId = DefaultId;\r
+ DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+\r
+ //\r
+ // Statement don't have storage, skip them\r
+ //\r
+ if (Question->QuestionId == 0) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // There are Five ways to specify default value for a Question:\r
+ // 1, use call back function (highest priority)\r
+ // 2, use ExtractConfig function\r
+ // 3, use nested EFI_IFR_DEFAULT\r
+ // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
+ // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
+ //\r
+ReGetDefault:\r
+ HiiValue = &Question->HiiValue;\r
+ TypeValue = &HiiValue->Value;\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ //\r
+ // For orderedlist, need to pass the BufferValue to Callback function.\r
+ //\r
+ TypeValue = (EFI_IFR_TYPE_VALUE *)Question->BufferValue;\r
+ }\r
+\r
+ //\r
+ // Get Question defaut value from call back function.\r
+ //\r
+ ConfigAccess = FormSet->ConfigAccess;\r
+ Action = GetDefaultIdForCallBack (DefaultId);\r
+ if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ Action,\r
+ Question->QuestionId,\r
+ HiiValue->Type,\r
+ TypeValue,\r
+ &ActionRequest\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ NewString = GetToken (Question->HiiValue.Value.string, FormSet->HiiHandle);\r
+ ASSERT (NewString != NULL);\r
+\r
+ ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth);\r
+ if (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth) {\r
+ ZeroMem (Question->BufferValue, Question->StorageWidth);\r
+ CopyMem (Question->BufferValue, NewString, StrSize (NewString));\r
+ } else {\r
+ CopyMem (Question->BufferValue, NewString, Question->StorageWidth);\r
+ }\r
+\r
+ FreePool (NewString);\r
+ }\r
+\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get default value from altcfg string.\r
+ //\r
+ if (ConfigAccess != NULL) {\r
+ Status = GetDefaultValueFromAltCfg (FormSet, Form, Question);\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // EFI_IFR_DEFAULT has highest priority\r
+ //\r
+ if (!IsListEmpty (&Question->DefaultListHead)) {\r
+ Link = GetFirstNode (&Question->DefaultListHead);\r
+ while (!IsNull (&Question->DefaultListHead, Link)) {\r
+ Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
+\r
+ if (Default->DefaultId == DefaultId) {\r
+ if (Default->ValueExpression != NULL) {\r
+ //\r
+ // Default is provided by an Expression, evaluate it\r
+ //\r
+ Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && Question->BufferValue != NULL);\r
+ if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) {\r
+ CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);\r
+ Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen;\r
+ } else {\r
+ CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth);\r
+ Question->HiiValue.BufferLen = Question->StorageWidth;\r
+ }\r
+\r
+ FreePool (Default->ValueExpression->Result.Buffer);\r
+ }\r
+\r
+ HiiValue->Type = Default->ValueExpression->Result.Type;\r
+ CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+ } else {\r
+ //\r
+ // Default value is embedded in EFI_IFR_DEFAULT\r
+ //\r
+ if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ASSERT (HiiValue->Buffer != NULL);\r
+ CopyMem (HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen);\r
+ } else {\r
+ CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
+ }\r
+ }\r
+\r
+ if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string, NULL);\r
+ if (StrValue == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (Question->StorageWidth > StrSize (StrValue)) {\r
+ ZeroMem (Question->BufferValue, Question->StorageWidth);\r
+ CopyMem (Question->BufferValue, StrValue, StrSize (StrValue));\r
+ } else {\r
+ CopyMem (Question->BufferValue, StrValue, Question->StorageWidth);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Link = GetNextNode (&Question->DefaultListHead, Link);\r
+ }\r
+ }\r
+\r
+ //\r
+ // EFI_ONE_OF_OPTION\r
+ //\r
+ if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
+ if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // OneOfOption could only provide Standard and Manufacturing default\r
+ //\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+ if ((Option->SuppressExpression != NULL) &&\r
+ (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
+ {\r
+ continue;\r
+ }\r
+\r
+ if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r
+ ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r
+ )\r
+ {\r
+ CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // EFI_IFR_CHECKBOX - lowest priority\r
+ //\r
+ if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
+ if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // Checkbox could only provide Standard and Manufacturing default\r
+ //\r
+ if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||\r
+ ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
+ )\r
+ {\r
+ HiiValue->Value.b = TRUE;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r
+ // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r
+ // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r
+ //\r
+ while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+ DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink);\r
+ DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
+ DefaultId = DefaultStore->DefaultId;\r
+ if (DefaultId == OriginalDefaultId) {\r
+ continue;\r
+ }\r
+\r
+ goto ReGetDefault;\r
+ }\r
+\r
+ //\r
+ // For Questions without default value for all the default id in the DefaultStoreList.\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ switch (Question->Operand) {\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ HiiValue->Value.b = FALSE;\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ //\r
+ // Take minimum value as numeric default value\r
+ //\r
+ if ((Question->Flags & EFI_IFR_DISPLAY) == 0) {\r
+ //\r
+ // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type.\r
+ //\r
+ switch (Question->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ if (((INT8)HiiValue->Value.u8 < (INT8)Question->Minimum) || ((INT8)HiiValue->Value.u8 > (INT8)Question->Maximum)) {\r
+ HiiValue->Value.u8 = (UINT8)Question->Minimum;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ if (((INT16)HiiValue->Value.u16 < (INT16)Question->Minimum) || ((INT16)HiiValue->Value.u16 > (INT16)Question->Maximum)) {\r
+ HiiValue->Value.u16 = (UINT16)Question->Minimum;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ if (((INT32)HiiValue->Value.u32 < (INT32)Question->Minimum) || ((INT32)HiiValue->Value.u32 > (INT32)Question->Maximum)) {\r
+ HiiValue->Value.u32 = (UINT32)Question->Minimum;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ if (((INT64)HiiValue->Value.u64 < (INT64)Question->Minimum) || ((INT64)HiiValue->Value.u64 > (INT64)Question->Maximum)) {\r
+ HiiValue->Value.u64 = Question->Minimum;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ } else {\r
+ if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r
+ HiiValue->Value.u64 = Question->Minimum;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ //\r
+ // Take first oneof option as oneof's default value\r
+ //\r
+ if (ValueToOption (Question, HiiValue) == NULL) {\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+ if ((Option->SuppressExpression != NULL) &&\r
+ (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
+ {\r
+ continue;\r
+ }\r
+\r
+ CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ //\r
+ // Take option sequence in IFR as ordered list's default value\r
+ //\r
+ Index = 0;\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Status = EFI_SUCCESS;\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+ if ((Option->SuppressExpression != NULL) &&\r
+ (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
+ {\r
+ continue;\r
+ }\r
+\r
+ SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r
+\r
+ Index++;\r
+ if (Index >= Question->MaxContainers) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Get AltCfg string for current form.\r
+\r
+ @param FormSet Form data structure.\r
+ @param Form Form data structure.\r
+ @param DefaultId The Class of the default.\r
+ @param BrowserStorage The input request storage for the questions.\r
+\r
+**/\r
+VOID\r
+ExtractAltCfgForForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN UINT16 DefaultId,\r
+ IN BROWSER_STORAGE *BrowserStorage\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Progress;\r
+ CHAR16 *Result;\r
+ BROWSER_STORAGE *Storage;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+\r
+ //\r
+ // Check whether has get AltCfg string for this formset.\r
+ // If yes, no need to get AltCfg for form.\r
+ //\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Storage = FormSetStorage->BrowserStorage;\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+ if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
+ continue;\r
+ }\r
+\r
+ if ((Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE) &&\r
+ (FormSetStorage->ElementCount != 0) &&\r
+ FormSetStorage->HasCallAltCfg)\r
+ {\r
+ return;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get AltCfg string for each form.\r
+ //\r
+ Link = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+ Storage = ConfigInfo->Storage;\r
+ if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
+ continue;\r
+ }\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 1. Skip if there is no RequestElement\r
+ //\r
+ if (ConfigInfo->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 2. Get value through hii config routine protocol.\r
+ //\r
+ Status = mHiiConfigRouting->ExtractConfig (\r
+ mHiiConfigRouting,\r
+ ConfigInfo->ConfigRequest,\r
+ &Progress,\r
+ &Result\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+ // Get the default configuration string according to the default ID.\r
+ //\r
+ Status = mHiiConfigRouting->GetAltConfig (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ &Storage->Guid,\r
+ Storage->Name,\r
+ NULL,\r
+ &DefaultId, // it can be NULL to get the current setting.\r
+ &ConfigResp\r
+ );\r
+ FreePool (Result);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ ConfigInfo->ConfigAltResp = ConfigResp;\r
+ }\r
+}\r
+\r
+/**\r
+ Clean AltCfg string for current form.\r
+\r
+ @param Form Form data structure.\r
+\r
+**/\r
+VOID\r
+CleanAltCfgForForm (\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+\r
+ Link = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+ if (ConfigInfo->ConfigAltResp != NULL) {\r
+ FreePool (ConfigInfo->ConfigAltResp);\r
+ ConfigInfo->ConfigAltResp = NULL;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Get AltCfg string for current formset.\r
+\r
+ @param FormSet Form data structure.\r
+ @param DefaultId The Class of the default.\r
+ @param BrowserStorage The input request storage for the questions.\r
+\r
+**/\r
+VOID\r
+ExtractAltCfgForFormSet (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN UINT16 DefaultId,\r
+ IN BROWSER_STORAGE *BrowserStorage\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Progress;\r
+ CHAR16 *Result;\r
+ BROWSER_STORAGE *Storage;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Storage = FormSetStorage->BrowserStorage;\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
+ continue;\r
+ }\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 1. Skip if there is no RequestElement\r
+ //\r
+ if (FormSetStorage->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ FormSetStorage->HasCallAltCfg = TRUE;\r
+\r
+ //\r
+ // 2. Get value through hii config routine protocol.\r
+ //\r
+ Status = mHiiConfigRouting->ExtractConfig (\r
+ mHiiConfigRouting,\r
+ FormSetStorage->ConfigRequest,\r
+ &Progress,\r
+ &Result\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+ // Get the default configuration string according to the default ID.\r
+ //\r
+ Status = mHiiConfigRouting->GetAltConfig (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ &Storage->Guid,\r
+ Storage->Name,\r
+ NULL,\r
+ &DefaultId, // it can be NULL to get the current setting.\r
+ &ConfigResp\r
+ );\r
+\r
+ FreePool (Result);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ FormSetStorage->ConfigAltResp = ConfigResp;\r
+ }\r
+}\r
+\r
+/**\r
+ Clean AltCfg string for current formset.\r
+\r
+ @param FormSet Form data structure.\r
+\r
+**/\r
+VOID\r
+CleanAltCfgForFormSet (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (FormSetStorage->ConfigAltResp != NULL) {\r
+ FreePool (FormSetStorage->ConfigAltResp);\r
+ FormSetStorage->ConfigAltResp = NULL;\r
+ }\r
+\r
+ FormSetStorage->HasCallAltCfg = FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Reset Questions to their initial value or default value in a Form, Formset or System.\r
+\r
+ GetDefaultValueScope parameter decides which questions will reset\r
+ to its default value.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param DefaultId The Class of the default.\r
+ @param SettingScope Setting Scope for Default action.\r
+ @param GetDefaultValueScope Get default value scope.\r
+ @param Storage Get default value only for this storage.\r
+ @param RetrieveValueFirst Whether call the retrieve call back to\r
+ get the initial value before get default\r
+ value.\r
+ @param SkipGetAltCfg Whether skip the get altcfg string process.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
+\r
+**/\r
+EFI_STATUS\r
+ExtractDefault (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN UINT16 DefaultId,\r
+ IN BROWSER_SETTING_SCOPE SettingScope,\r
+ IN BROWSER_GET_DEFAULT_VALUE GetDefaultValueScope,\r
+ IN BROWSER_STORAGE *Storage OPTIONAL,\r
+ IN BOOLEAN RetrieveValueFirst,\r
+ IN BOOLEAN SkipGetAltCfg\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *FormLink;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+ FORM_BROWSER_FORMSET *OldFormSet;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Check the supported setting level.\r
+ //\r
+ if ((SettingScope >= MaxLevel) || (GetDefaultValueScope >= GetDefaultForMax)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if ((GetDefaultValueScope == GetDefaultForStorage) && (Storage == NULL)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (SettingScope == FormLevel) {\r
+ //\r
+ // Prepare the AltCfg String for form.\r
+ //\r
+ if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
+ ExtractAltCfgForForm (FormSet, Form, DefaultId, Storage);\r
+ }\r
+\r
+ //\r
+ // Extract Form default\r
+ //\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+\r
+ //\r
+ // If get default value only for this storage, check the storage first.\r
+ //\r
+ if ((GetDefaultValueScope == GetDefaultForStorage) && (Question->Storage != Storage)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // If get default value only for no storage question, just skip the question which has storage.\r
+ //\r
+ if ((GetDefaultValueScope == GetDefaultForNoStorage) && (Question->Storage != NULL)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // If Question is disabled, don't reset it to default\r
+ //\r
+ if (Question->Expression != NULL) {\r
+ if (EvaluateExpressionList (Question->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (RetrieveValueFirst) {\r
+ //\r
+ // Call the Retrieve call back to get the initial question value.\r
+ //\r
+ Status = ProcessRetrieveForQuestion (FormSet->ConfigAccess, Question, FormSet);\r
+ }\r
+\r
+ //\r
+ // If not request to get the initial value or get initial value fail, then get default value.\r
+ //\r
+ if (!RetrieveValueFirst || EFI_ERROR (Status)) {\r
+ Status = GetQuestionDefault (FormSet, Form, Question, DefaultId);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Synchronize Buffer storage's Edit buffer\r
+ //\r
+ if ((Question->Storage != NULL) &&\r
+ (Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE))\r
+ {\r
+ SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Clean the AltCfg String.\r
+ //\r
+ if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
+ CleanAltCfgForForm (Form);\r
+ }\r
+ } else if (SettingScope == FormSetLevel) {\r
+ //\r
+ // Prepare the AltCfg String for formset.\r
+ //\r
+ if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
+ ExtractAltCfgForFormSet (FormSet, DefaultId, Storage);\r
+ }\r
+\r
+ FormLink = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
+ ExtractDefault (FormSet, Form, DefaultId, FormLevel, GetDefaultValueScope, Storage, RetrieveValueFirst, SkipGetAltCfg);\r
+ FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
+ }\r
+\r
+ //\r
+ // Clean the AltCfg String.\r
+ //\r
+ if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
+ CleanAltCfgForFormSet (FormSet);\r
+ }\r
+ } else if (SettingScope == SystemLevel) {\r
+ //\r
+ // Preload all Hii formset.\r
+ //\r
+ LoadAllHiiFormset ();\r
+\r
+ OldFormSet = mSystemLevelFormSet;\r
+\r
+ //\r
+ // Set Default Value for each FormSet in the maintain list.\r
+ //\r
+ Link = GetFirstNode (&gBrowserFormSetList);\r
+ while (!IsNull (&gBrowserFormSetList, Link)) {\r
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+ Link = GetNextNode (&gBrowserFormSetList, Link);\r
+ if (!ValidateFormSet (LocalFormSet)) {\r
+ continue;\r
+ }\r
+\r
+ mSystemLevelFormSet = LocalFormSet;\r
+\r
+ ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst, SkipGetAltCfg);\r
+ }\r
+\r
+ mSystemLevelFormSet = OldFormSet;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Validate whether this question's value has changed.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param Question Question to be initialized.\r
+ @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.\r
+\r
+ @retval TRUE Question's value has changed.\r
+ @retval FALSE Question's value has not changed\r
+\r
+**/\r
+BOOLEAN\r
+IsQuestionValueChanged (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN OUT FORM_BROWSER_STATEMENT *Question,\r
+ IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
+ )\r
+{\r
+ EFI_HII_VALUE BackUpValue;\r
+ CHAR8 *BackUpBuffer;\r
+ EFI_HII_VALUE BackUpValue2;\r
+ CHAR8 *BackUpBuffer2;\r
+ EFI_STATUS Status;\r
+ BOOLEAN ValueChanged;\r
+ UINTN BufferWidth;\r
+\r
+ //\r
+ // For quetion without storage, always mark it as data not changed.\r
+ //\r
+ if ((Question->Storage == NULL) && (Question->Operand != EFI_IFR_TIME_OP) && (Question->Operand != EFI_IFR_DATE_OP)) {\r
+ return FALSE;\r
+ }\r
+\r
+ BackUpBuffer = NULL;\r
+ BackUpBuffer2 = NULL;\r
+ ValueChanged = FALSE;\r
+\r
+ switch (Question->Operand) {\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ BufferWidth = Question->StorageWidth;\r
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer != NULL);\r
+ break;\r
+\r
+ case EFI_IFR_STRING_OP:\r
+ case EFI_IFR_PASSWORD_OP:\r
+ BufferWidth = (UINTN)Question->Maximum * sizeof (CHAR16);\r
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer != NULL);\r
+ break;\r
+\r
+ default:\r
+ BufferWidth = 0;\r
+ break;\r
+ }\r
+\r
+ CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
+\r
+ if (GetValueFrom == GetSetValueWithBothBuffer) {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ switch (Question->Operand) {\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ BufferWidth = Question->StorageWidth;\r
+ BackUpBuffer2 = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer2 != NULL);\r
+ break;\r
+\r
+ case EFI_IFR_STRING_OP:\r
+ case EFI_IFR_PASSWORD_OP:\r
+ BufferWidth = (UINTN)Question->Maximum * sizeof (CHAR16);\r
+ BackUpBuffer2 = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer2 != NULL);\r
+ break;\r
+\r
+ default:\r
+ BufferWidth = 0;\r
+ break;\r
+ }\r
+\r
+ CopyMem (&BackUpValue2, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
+\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if ((CompareMem (&BackUpValue2, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0) ||\r
+ (CompareMem (BackUpBuffer2, Question->BufferValue, BufferWidth) != 0))\r
+ {\r
+ ValueChanged = TRUE;\r
+ }\r
+ } else {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if ((CompareMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0) ||\r
+ (CompareMem (BackUpBuffer, Question->BufferValue, BufferWidth) != 0))\r
+ {\r
+ ValueChanged = TRUE;\r
+ }\r
+ }\r
+\r
+ CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
+ if (BackUpBuffer != NULL) {\r
+ CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);\r
+ FreePool (BackUpBuffer);\r
+ }\r
+\r
+ if (BackUpBuffer2 != NULL) {\r
+ FreePool (BackUpBuffer2);\r
+ }\r
+\r
+ Question->ValueChanged = ValueChanged;\r
+\r
+ return ValueChanged;\r
+}\r
+\r
+/**\r
+ Initialize Question's Edit copy from Storage.\r
+\r
+ @param Selection Selection contains the information about\r
+ the Selection, form and formset to be displayed.\r
+ Selection action may be updated in retrieve callback.\r
+ If Selection is NULL, only initialize Question value.\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+LoadFormConfig (\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+ //\r
+ // Initialize local copy of Value for each Question\r
+ //\r
+ if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == 0)) {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);\r
+ } else {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((Question->Operand == EFI_IFR_STRING_OP) || (Question->Operand == EFI_IFR_PASSWORD_OP)) {\r
+ HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16 *)Question->BufferValue, NULL);\r
+ }\r
+\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Initialize Question's Edit copy from Storage for the whole Formset.\r
+\r
+ @param Selection Selection contains the information about\r
+ the Selection, form and formset to be displayed.\r
+ Selection action may be updated in retrieve callback.\r
+ If Selection is NULL, only initialize Question value.\r
+ @param FormSet FormSet data structure.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+LoadFormSetConfig (\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ //\r
+ // Initialize local copy of Value for each Form\r
+ //\r
+ Status = LoadFormConfig (Selection, FormSet, Form);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ }\r
+\r
+ //\r
+ // Finished question initialization.\r
+ //\r
+ FormSet->QuestionInited = TRUE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Remove the Request element from the Config Request.\r
+\r
+ @param Storage Pointer to the browser storage.\r
+ @param RequestElement The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveElement (\r
+ IN OUT BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *RequestElement\r
+ )\r
+{\r
+ CHAR16 *NewStr;\r
+ CHAR16 *DestStr;\r
+\r
+ ASSERT (Storage->ConfigRequest != NULL && RequestElement != NULL);\r
+\r
+ NewStr = StrStr (Storage->ConfigRequest, RequestElement);\r
+\r
+ if (NewStr == NULL) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Remove this element from this ConfigRequest.\r
+ //\r
+ DestStr = NewStr;\r
+ NewStr += StrLen (RequestElement);\r
+ CopyMem (DestStr, NewStr, StrSize (NewStr));\r
+\r
+ Storage->SpareStrLen += StrLen (RequestElement);\r
+}\r
+\r
+/**\r
+ Adjust config request in storage, remove the request elements existed in the input ConfigRequest.\r
+\r
+ @param Storage Pointer to the formset storage.\r
+ @param ConfigRequest The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveConfigRequest (\r
+ FORMSET_STORAGE *Storage,\r
+ CHAR16 *ConfigRequest\r
+ )\r
+{\r
+ CHAR16 *RequestElement;\r
+ CHAR16 *NextRequestElement;\r
+ CHAR16 *SearchKey;\r
+\r
+ //\r
+ // No request element in it, just return.\r
+ //\r
+ if (ConfigRequest == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
+ //\r
+ SearchKey = L"&";\r
+ } else {\r
+ //\r
+ // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
+ //\r
+ SearchKey = L"&OFFSET";\r
+ }\r
+\r
+ //\r
+ // Find SearchKey storage\r
+ //\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ RequestElement = StrStr (ConfigRequest, L"PATH");\r
+ ASSERT (RequestElement != NULL);\r
+ RequestElement = StrStr (RequestElement, SearchKey);\r
+ } else {\r
+ RequestElement = StrStr (ConfigRequest, SearchKey);\r
+ }\r
+\r
+ while (RequestElement != NULL) {\r
+ //\r
+ // +1 to avoid find header itself.\r
+ //\r
+ NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
+\r
+ //\r
+ // The last Request element in configRequest string.\r
+ //\r
+ if (NextRequestElement != NULL) {\r
+ //\r
+ // Replace "&" with '\0'.\r
+ //\r
+ *NextRequestElement = L'\0';\r
+ }\r
+\r
+ RemoveElement (Storage->BrowserStorage, RequestElement);\r
+\r
+ if (NextRequestElement != NULL) {\r
+ //\r
+ // Restore '&' with '\0' for later used.\r
+ //\r
+ *NextRequestElement = L'&';\r
+ }\r
+\r
+ RequestElement = NextRequestElement;\r
+ }\r
+\r
+ //\r
+ // If no request element remain, just remove the ConfigRequest string.\r
+ //\r
+ if (StrCmp (Storage->BrowserStorage->ConfigRequest, Storage->ConfigHdr) == 0) {\r
+ FreePool (Storage->BrowserStorage->ConfigRequest);\r
+ Storage->BrowserStorage->ConfigRequest = NULL;\r
+ Storage->BrowserStorage->SpareStrLen = 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Base on the current formset info, clean the ConfigRequest string in browser storage.\r
+\r
+ @param FormSet Pointer of the FormSet\r
+\r
+**/\r
+VOID\r
+CleanBrowserStorage (\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *Storage;\r
+\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ if ((Storage->ConfigRequest == NULL) || (Storage->BrowserStorage->ConfigRequest == NULL)) {\r
+ continue;\r
+ }\r
+\r
+ RemoveConfigRequest (Storage, Storage->ConfigRequest);\r
+ } else if ((Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
+ (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE))\r
+ {\r
+ if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
+ FreePool (Storage->BrowserStorage->ConfigRequest);\r
+ Storage->BrowserStorage->ConfigRequest = NULL;\r
+ }\r
+\r
+ Storage->BrowserStorage->Initialized = FALSE;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Check whether current element in the ConfigReqeust string.\r
+\r
+ @param BrowserStorage Storage which includes ConfigReqeust.\r
+ @param RequestElement New element need to check.\r
+\r
+ @retval TRUE The Element is in the ConfigReqeust string.\r
+ @retval FALSE The Element not in the configReqeust String.\r
+\r
+**/\r
+BOOLEAN\r
+ElementValidation (\r
+ BROWSER_STORAGE *BrowserStorage,\r
+ CHAR16 *RequestElement\r
+ )\r
+{\r
+ return StrStr (BrowserStorage->ConfigRequest, RequestElement) != NULL ? TRUE : FALSE;\r