+ if (!Find) {\r
+ CleanBrowserStorage(FormSet);\r
+ RemoveEntryList (&FormSet->Link);\r
+ DestroyFormSet (FormSet);\r
+ }\r
+\r
+ FreePool (HiiHandles);\r
+\r
+ return Find;\r
+}\r
+\r
+/**\r
+ Discard data based on the input setting scope (Form, FormSet or System).\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param SettingScope Setting Scope for Discard action.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
+\r
+**/\r
+EFI_STATUS\r
+DiscardForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BROWSER_SETTING_SCOPE SettingScope\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *Storage;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+\r
+ //\r
+ // Check the supported setting level.\r
+ //\r
+ if (SettingScope >= MaxLevel) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
+ ConfigInfo = 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 (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (ConfigInfo->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Prepare <ConfigResp>\r
+ //\r
+ SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);\r
+\r
+ //\r
+ // Call callback with Changed type to inform the driver.\r
+ //\r
+ SendDiscardInfoToDriver (FormSet, Form);\r
+ }\r
+\r
+ Form->NvUpdateRequired = FALSE;\r
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
+\r
+ //\r
+ // Discard Buffer storage or Name/Value 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) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (Storage->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ SynchronizeStorage(Storage->BrowserStorage, FALSE);\r
+ }\r
+\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ \r
+ //\r
+ // Call callback with Changed type to inform the driver.\r
+ //\r
+ SendDiscardInfoToDriver (FormSet, Form);\r
+ }\r
+\r
+ UpdateNvInfoInForm (FormSet, FALSE); \r
+ } else if (SettingScope == SystemLevel) {\r
+ //\r
+ // System Level Discard.\r
+ //\r
+ \r
+ //\r
+ // Discard changed 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
+ DiscardForm (LocalFormSet, NULL, FormSetLevel);\r
+ if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
+ //\r
+ // Remove maintain backup list after discard except for the current using FormSet.\r
+ //\r
+ CleanBrowserStorage(LocalFormSet);\r
+ RemoveEntryList (&LocalFormSet->Link);\r
+ DestroyFormSet (LocalFormSet);\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS; \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
+ LIST_ENTRY *Link;\r
+ EFI_STRING ConfigResp;\r
+ EFI_STRING Progress;\r
+ BROWSER_STORAGE *Storage;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+ UINTN BufferSize;\r
+ UINT8 *TmpBuf; \r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+\r
+ //\r
+ // Check the supported setting level.\r
+ //\r
+ if (SettingScope >= MaxLevel) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Validate the Form by NoSubmit check\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ if (SettingScope == FormLevel) {\r
+ Status = NoSubmitCheck (FormSet, Form);\r
+ } else if (SettingScope == FormSetLevel) {\r
+ Status = NoSubmitCheck (FormSet, NULL);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
+ ConfigInfo = 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
+ Storage = ConfigInfo->Storage;\r
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (ConfigInfo->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 1. Prepare <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // 2. Set value to hii driver or efi variable.\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // Send <ConfigResp> to Configuration Driver\r
+ //\r
+ if (FormSet->ConfigAccess != NULL) {\r
+ Status = FormSet->ConfigAccess->RouteConfig (\r
+ FormSet->ConfigAccess,\r
+ ConfigResp,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+ }\r
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ TmpBuf = NULL;\r
+ TmpBuf = AllocateZeroPool(Storage->Size);\r
+ if (TmpBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ return Status;\r
+ }\r
+\r
+ BufferSize = Storage->Size;\r
+ Status = gRT->GetVariable (\r
+ Storage->Name,\r
+ &Storage->Guid,\r
+ NULL,\r
+ &BufferSize,\r
+ TmpBuf\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (TmpBuf);\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+ ASSERT (BufferSize == Storage->Size); \r
+ Status = mHiiConfigRouting->ConfigToBlock (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ TmpBuf,\r
+ &BufferSize,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (TmpBuf);\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+\r
+ Status = gRT->SetVariable (\r
+ Storage->Name,\r
+ &Storage->Guid,\r
+ Storage->Attributes,\r
+ Storage->Size,\r
+ TmpBuf\r
+ );\r
+ FreePool (TmpBuf);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+ }\r
+ FreePool (ConfigResp);\r
+ //\r
+ // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
+ //\r
+ SynchronizeStorageForForm(FormSet, ConfigInfo, TRUE);\r
+ }\r
+\r
+ //\r
+ // 4. Update the NV flag.\r
+ // \r
+ Form->NvUpdateRequired = FALSE;\r
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
+ //\r
+ // Submit Buffer storage or Name/Value storage\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 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (FormSetStorage->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // 1. Prepare <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+\r
+ //\r
+ // 2. Send <ConfigResp> to Configuration Driver\r
+ //\r
+ if (FormSet->ConfigAccess != NULL) {\r
+ Status = FormSet->ConfigAccess->RouteConfig (\r
+ FormSet->ConfigAccess,\r
+ ConfigResp,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+ }\r
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ //\r
+ // 1&2. Set the edit data to the variable.\r
+ //\r
+ TmpBuf = NULL;\r
+ TmpBuf = AllocateZeroPool (Storage->Size);\r
+ if (TmpBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ return Status;\r
+ } \r
+ BufferSize = Storage->Size;\r
+ Status = gRT->GetVariable (\r
+ Storage->Name,\r
+ &Storage->Guid,\r
+ NULL,\r
+ &BufferSize,\r
+ TmpBuf\r
+ );\r
+ ASSERT (BufferSize == Storage->Size); \r
+ Status = mHiiConfigRouting->ConfigToBlock (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ TmpBuf,\r
+ &BufferSize,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (TmpBuf);\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+\r
+ Status = gRT->SetVariable (\r
+ Storage->Name,\r
+ &Storage->Guid,\r
+ Storage->Attributes,\r
+ Storage->Size,\r
+ TmpBuf\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (TmpBuf);\r
+ FreePool (ConfigResp);\r
+ return Status;\r
+ }\r
+ FreePool (TmpBuf);\r
+ }\r
+ FreePool (ConfigResp);\r
+ //\r
+ // 3. Config success, update storage shadow Buffer\r
+ //\r
+ SynchronizeStorage (Storage, TRUE);\r
+ }\r
+\r
+ //\r
+ // 4. Update the NV flag.\r
+ // \r
+ UpdateNvInfoInForm (FormSet, FALSE);\r
+ } else if (SettingScope == SystemLevel) {\r
+ //\r
+ // System Level Save.\r
+ //\r
+\r
+ //\r
+ // Save changed 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
+ SubmitForm (LocalFormSet, NULL, FormSetLevel);\r
+ if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
+ //\r
+ // Remove maintain backup list after save except for the current using FormSet.\r
+ //\r
+ CleanBrowserStorage(LocalFormSet);\r
+ RemoveEntryList (&LocalFormSet->Link);\r
+ DestroyFormSet (LocalFormSet);\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Get Question default value from AltCfg string.\r
+\r
+ @param FormSet The form set.\r
+ @param Question The question.\r
+ @param DefaultId The default Id.\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 OUT FORM_BROWSER_STATEMENT *Question,\r
+ IN UINT16 DefaultId\r
+ )\r
+{\r
+ BOOLEAN IsBufferStorage;\r
+ BOOLEAN IsString; \r
+ UINTN Length;\r
+ BROWSER_STORAGE *Storage;\r
+ CHAR16 *ConfigRequest;\r
+ CHAR16 *Progress;\r
+ CHAR16 *Result;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Value;\r
+ CHAR16 *StringPtr;\r
+ UINTN LengthStr;\r
+ UINT8 *Dst;\r
+ CHAR16 TemStr[5];\r
+ UINTN Index;\r
+ UINT8 DigitUint8;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ Length = 0;\r
+ Dst = NULL;\r
+ ConfigRequest = NULL;\r
+ Result = NULL;\r
+ ConfigResp = NULL;\r
+ Value = NULL;\r
+ Storage = Question->Storage;\r
+\r
+ if ((Storage == NULL) || \r
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) || \r
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Question Value is provided by Buffer Storage or NameValue Storage\r
+ //\r
+ if (Question->BufferValue != NULL) {\r
+ //\r
+ // This Question is password or orderedlist\r
+ //\r
+ Dst = Question->BufferValue;\r
+ } else {\r
+ //\r
+ // Other type of Questions\r
+ //\r
+ Dst = (UINT8 *) &Question->HiiValue.Value;\r
+ }\r
+\r
+ IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\r
+ IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
+\r
+ //\r
+ // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
+ // <ConfigHdr> + "&" + <VariableName>\r
+ //\r
+ if (IsBufferStorage) {\r
+ Length = StrLen (Storage->ConfigHdr);\r
+ Length += StrLen (Question->BlockName);\r
+ } else {\r
+ Length = StrLen (Storage->ConfigHdr);\r
+ Length += StrLen (Question->VariableName) + 1;\r
+ }\r
+ ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
+ ASSERT (ConfigRequest != NULL);\r
+\r
+ StrCpy (ConfigRequest, Storage->ConfigHdr);\r
+ if (IsBufferStorage) {\r
+ StrCat (ConfigRequest, Question->BlockName);\r
+ } else {\r
+ StrCat (ConfigRequest, L"&");\r
+ StrCat (ConfigRequest, Question->VariableName);\r
+ }\r
+\r
+ Status = FormSet->ConfigAccess->ExtractConfig (\r
+ FormSet->ConfigAccess,\r
+ ConfigRequest,\r
+ &Progress,\r
+ &Result\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // 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
+ //\r
+ // The required setting can't be found. So, it is not required to be validated and set.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Skip <ConfigRequest>\r
+ //\r
+ if (IsBufferStorage) {\r
+ Value = StrStr (ConfigResp, L"&VALUE");\r
+ ASSERT (Value != NULL);\r
+ //\r
+ // Skip "&VALUE"\r
+ //\r
+ Value = Value + 6;\r
+ } else {\r
+ Value = StrStr (ConfigResp, Question->VariableName);\r
+ ASSERT (Value != NULL);\r
+\r
+ Value = Value + StrLen (Question->VariableName);\r
+ }\r
+ if (*Value != '=') {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Skip '=', point to value\r
+ //\r
+ Value = Value + 1;\r
+\r
+ //\r
+ // Suppress <AltResp> if any\r
+ //\r
+ StringPtr = Value;\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr++;\r
+ }\r
+ *StringPtr = L'\0';\r
+\r
+ LengthStr = StrLen (Value);\r
+ if (!IsBufferStorage && IsString) {\r
+ StringPtr = (CHAR16 *) Dst;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < LengthStr; Index += 4) {\r
+ StrnCpy (TemStr, Value + Index, 4);\r
+ StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+ }\r
+ //\r
+ // Add tailing L'\0' character\r
+ //\r
+ StringPtr[Index/4] = L'\0';\r
+ } else {\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < LengthStr; Index ++) {\r
+ TemStr[0] = Value[LengthStr - Index - 1];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+ if ((Index & 1) == 0) {\r
+ Dst [Index/2] = DigitUint8;\r
+ } else {\r
+ Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+ }\r
+ }\r
+ }\r
+\r
+Done:\r
+ if (ConfigRequest != NULL){\r
+ FreePool (ConfigRequest);\r
+ }\r
+\r
+ if (ConfigResp != NULL) {\r
+ FreePool (ConfigResp);\r
+ }\r
+ \r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
+\r
+ return Status;\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
+ 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
+\r
+ Status = EFI_NOT_FOUND;\r
+ StrValue = NULL;\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
+ HiiValue = &Question->HiiValue;\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
+ &HiiValue->Value,\r
+ &ActionRequest\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get default value from altcfg string.\r
+ //\r
+ if (ConfigAccess != NULL) { \r
+ Status = GetDefaultValueFromAltCfg(FormSet, Question, DefaultId);\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
+ FreePool (Default->ValueExpression->Result.Buffer);\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
+ CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\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
+ if (Question->StorageWidth > StrSize (StrValue)) {\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
+ 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
+ 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
+ HiiValue->Value.b = TRUE;\r
+ } else {\r
+ HiiValue->Value.b = FALSE;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For Questions without default\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ switch (Question->Operand) {\r
+ case EFI_IFR_NUMERIC_OP:\r
+ //\r
+ // Take minimum value as numeric default value\r
+ //\r
+ if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r
+ HiiValue->Value.u64 = Question->Minimum;\r
+ Status = EFI_SUCCESS;\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