SaveReminder\r
},\r
{\r
- BROWSER_EXTENSION2_VERSION_1,\r
+ BROWSER_EXTENSION2_VERSION_1_1,\r
SetScope,\r
RegisterHotKey,\r
RegiserExitHandler,\r
IsBrowserDataModified,\r
ExecuteAction,\r
+ {NULL,NULL},\r
+ {NULL,NULL},\r
+ IsResetRequired\r
}\r
};\r
\r
LIST_ENTRY gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);\r
LIST_ENTRY gBrowserHotKeyList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
+LIST_ENTRY gBrowserSaveFailFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserSaveFailFormSetList);\r
\r
-BOOLEAN gFinishRetrieveCall;\r
+BOOLEAN mSystemSubmit = FALSE;\r
BOOLEAN gResetRequired;\r
BOOLEAN gExitRequired;\r
BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
\r
EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
\r
-extern UINT32 gBrowserStatus;\r
-extern CHAR16 *gErrorInfo;\r
extern EFI_GUID mCurrentFormSetGuid;\r
extern EFI_HII_HANDLE mCurrentHiiHandle;\r
extern UINT16 mCurrentFormId;\r
Find parent menu for current menu.\r
\r
@param CurrentMenu Current Menu\r
+ @param SettingLevel Whether find parent menu in Form Level or Formset level.\r
+ In form level, just find the parent menu; \r
+ In formset level, find the parent menu which has different\r
+ formset guid value.\r
\r
@retval The parent menu for current menu.\r
**/\r
FORM_ENTRY_INFO *\r
UiFindParentMenu (\r
- IN FORM_ENTRY_INFO *CurrentMenu\r
+ IN FORM_ENTRY_INFO *CurrentMenu,\r
+ IN BROWSER_SETTING_SCOPE SettingLevel\r
)\r
{\r
FORM_ENTRY_INFO *ParentMenu;\r
+ LIST_ENTRY *Link;\r
+\r
+ ASSERT (SettingLevel == FormLevel || SettingLevel == FormSetLevel);\r
\r
+ if (CurrentMenu == NULL) {\r
+ return NULL;\r
+ }\r
+ \r
ParentMenu = NULL;\r
- if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
- ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);\r
+ Link = &CurrentMenu->Link;\r
+\r
+ while (Link->BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
+ ParentMenu = FORM_ENTRY_INFO_FROM_LINK (Link->BackLink);\r
+\r
+ if (SettingLevel == FormLevel) {\r
+ //\r
+ // For FormLevel, just find the parent menu, return.\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (!CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
+ //\r
+ // For SystemLevel, must find the menu which has different formset.\r
+ //\r
+ break;\r
+ }\r
+\r
+ Link = Link->BackLink;\r
+ }\r
+\r
+ //\r
+ // Not find the parent menu, just return NULL.\r
+ //\r
+ if (Link->BackLink == &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
+ return NULL;\r
}\r
\r
return ParentMenu;\r
}\r
}\r
\r
+/**\r
+ Copy current Menu list to the new menu list.\r
+ \r
+ @param NewMenuListHead New create Menu list.\r
+ @param CurrentMenuListHead Current Menu list.\r
+\r
+**/\r
+VOID\r
+UiCopyMenuList (\r
+ OUT LIST_ENTRY *NewMenuListHead,\r
+ IN LIST_ENTRY *CurrentMenuListHead\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_ENTRY_INFO *MenuList;\r
+ FORM_ENTRY_INFO *NewMenuEntry;\r
+\r
+ //\r
+ // If new menu list not empty, free it first.\r
+ //\r
+ UiFreeMenuList (NewMenuListHead);\r
+\r
+ Link = GetFirstNode (CurrentMenuListHead);\r
+ while (!IsNull (CurrentMenuListHead, Link)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);\r
+ Link = GetNextNode (CurrentMenuListHead, Link);\r
+\r
+ NewMenuEntry = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));\r
+ ASSERT (NewMenuEntry != NULL);\r
+ NewMenuEntry->Signature = FORM_ENTRY_INFO_SIGNATURE;\r
+ NewMenuEntry->HiiHandle = MenuList->HiiHandle;\r
+ CopyMem (&NewMenuEntry->FormSetGuid, &MenuList->FormSetGuid, sizeof (EFI_GUID));\r
+ NewMenuEntry->FormId = MenuList->FormId;\r
+ NewMenuEntry->QuestionId = MenuList->QuestionId;\r
+\r
+ InsertTailList (NewMenuListHead, &NewMenuEntry->Link);\r
+ }\r
+}\r
+\r
/**\r
Load all hii formset to the browser.\r
\r
EFI_GUID ZeroGuid;\r
EFI_STATUS Status;\r
FORM_BROWSER_FORMSET *OldFormset;\r
- BOOLEAN OldRetrieveValue;\r
\r
OldFormset = mSystemLevelFormSet;\r
- OldRetrieveValue = gFinishRetrieveCall;\r
- gFinishRetrieveCall = FALSE;\r
\r
//\r
// Get all the Hii handles\r
//\r
FreePool (HiiHandles);\r
\r
- gFinishRetrieveCall = OldRetrieveValue;\r
mSystemLevelFormSet = OldFormset;\r
}\r
\r
+/**\r
+ Pop up the error info.\r
+\r
+ @param BrowserStatus The input browser status.\r
+ @param HiiHandle The Hiihandle for this opcode.\r
+ @param OpCode The opcode use to get the erro info and timeout value.\r
+ @param ErrorString Error string used by BROWSER_NO_SUBMIT_IF.\r
+\r
+**/\r
+UINT32\r
+PopupErrorMessage (\r
+ IN UINT32 BrowserStatus,\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_IFR_OP_HEADER *OpCode, OPTIONAL\r
+ IN CHAR16 *ErrorString\r
+ )\r
+{\r
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+ USER_INPUT UserInputData;\r
+\r
+ Statement = NULL;\r
+\r
+ if (OpCode != NULL) {\r
+ Statement = AllocateZeroPool (sizeof(FORM_DISPLAY_ENGINE_STATEMENT));\r
+ ASSERT (Statement != NULL);\r
+ Statement->OpCode = OpCode;\r
+ gDisplayFormData.HighLightedStatement = Statement;\r
+ }\r
+\r
+ //\r
+ // Used to compatible with old display engine.\r
+ // New display engine not use this field.\r
+ //\r
+ gDisplayFormData.ErrorString = ErrorString;\r
+ gDisplayFormData.BrowserStatus = BrowserStatus;\r
+\r
+ if (HiiHandle != NULL) {\r
+ gDisplayFormData.HiiHandle = HiiHandle;\r
+ }\r
+\r
+ mFormDisplay->FormDisplay (&gDisplayFormData, &UserInputData);\r
+\r
+ gDisplayFormData.BrowserStatus = BROWSER_SUCCESS;\r
+ gDisplayFormData.ErrorString = NULL;\r
+\r
+ if (OpCode != NULL) {\r
+ FreePool (Statement);\r
+ }\r
+\r
+ return UserInputData.Action;\r
+}\r
+\r
/**\r
This is the routine which an external caller uses to direct the browser\r
where to obtain it's information.\r
//\r
SaveBrowserContext ();\r
\r
- gFinishRetrieveCall = FALSE;\r
gResetRequired = FALSE;\r
gExitRequired = FALSE;\r
Status = EFI_SUCCESS;\r
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
ASSERT (FormSet != NULL);\r
\r
+ //\r
+ // Validate the HiiHandle\r
+ // if validate failed, find the first validate parent HiiHandle.\r
+ //\r
+ if (!ValidateHiiHandle(Selection->Handle)) {\r
+ FindNextMenu (Selection, FormSetLevel);\r
+ }\r
+\r
//\r
// Initialize internal data structures of FormSet\r
//\r
FreePool (Selection);\r
}\r
\r
- //\r
- // Still has error info, pop up a message.\r
- //\r
- if (gBrowserStatus != BROWSER_SUCCESS) {\r
- gDisplayFormData.BrowserStatus = gBrowserStatus;\r
- gDisplayFormData.ErrorString = gErrorInfo;\r
-\r
- gBrowserStatus = BROWSER_SUCCESS;\r
- gErrorInfo = NULL;\r
-\r
- mFormDisplay->FormDisplay (&gDisplayFormData, NULL);\r
- }\r
-\r
if (ActionRequest != NULL) {\r
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
if (gResetRequired) {\r
Found = FALSE;\r
Status = EFI_SUCCESS;\r
\r
- //\r
- // If set browser data, pre load all hii formset to avoid set the varstore which is not \r
- // saved in browser.\r
- //\r
- if (!RetrieveData && (gBrowserSettingScope == SystemLevel)) {\r
- LoadAllHiiFormset();\r
- }\r
-\r
if (VariableGuid != NULL) {\r
//\r
// Try to find target storage in the current formset.\r
return Status;\r
}\r
\r
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ ConfigRequestAdjust (Storage, ResultsData, TRUE);\r
+ }\r
+\r
//\r
// Different formsets may have same varstore, so here just set the flag\r
// not exit the circle.\r
return Status;\r
}\r
\r
+/**\r
+ Convert the buffer value to HiiValue.\r
+\r
+ @param Question The question.\r
+ @param Value Unicode buffer save the question value.\r
+\r
+ @retval Status whether convert the value success.\r
+\r
+**/\r
+EFI_STATUS\r
+BufferToValue (\r
+ IN OUT FORM_BROWSER_STATEMENT *Question,\r
+ IN CHAR16 *Value\r
+ )\r
+{\r
+ CHAR16 *StringPtr;\r
+ BOOLEAN IsBufferStorage;\r
+ CHAR16 *DstBuf;\r
+ CHAR16 TempChar;\r
+ UINTN LengthStr;\r
+ UINT8 *Dst;\r
+ CHAR16 TemStr[5];\r
+ UINTN Index;\r
+ UINT8 DigitUint8;\r
+ BOOLEAN IsString;\r
+ UINTN Length;\r
+ EFI_STATUS Status;\r
+\r
+ IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
+ if (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ IsBufferStorage = TRUE;\r
+ } else {\r
+ IsBufferStorage = FALSE;\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
+ //\r
+ // Temp cut at the end of this section, end with '\0' or '&'.\r
+ //\r
+ StringPtr = Value;\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr++;\r
+ }\r
+ TempChar = *StringPtr;\r
+ *StringPtr = L'\0';\r
+\r
+ LengthStr = StrLen (Value);\r
+ Status = EFI_SUCCESS;\r
+ if (!IsBufferStorage && IsString) {\r
+ //\r
+ // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
+ // Add string tail char L'\0' into Length\r
+ //\r
+ Length = Question->StorageWidth + sizeof (CHAR16);\r
+ if (Length < ((LengthStr / 4 + 1) * 2)) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ DstBuf = (CHAR16 *) Dst;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < LengthStr; Index += 4) {\r
+ StrnCpy (TemStr, Value + Index, 4);\r
+ DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+ }\r
+ //\r
+ // Add tailing L'\0' character\r
+ //\r
+ DstBuf[Index/4] = L'\0';\r
+ }\r
+ } else {\r
+ if (Question->StorageWidth < ((LengthStr + 1) / 2)) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\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
+\r
+ *StringPtr = TempChar;\r
+\r
+ return Status;\r
+}\r
\r
/**\r
Get Question's current Value.\r
CHAR16 *Progress;\r
CHAR16 *Result;\r
CHAR16 *Value;\r
- CHAR16 *StringPtr;\r
UINTN Length;\r
- UINTN Index;\r
- UINTN LengthStr;\r
BOOLEAN IsBufferStorage;\r
- BOOLEAN IsString;\r
- CHAR16 TemStr[5];\r
- UINT8 DigitUint8;\r
\r
Status = EFI_SUCCESS;\r
Value = NULL;\r
} else {\r
IsBufferStorage = FALSE;\r
}\r
- IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
if (GetValueFrom == GetSetValueWithEditBuffer || GetValueFrom == GetSetValueWithBuffer ) {\r
if (IsBufferStorage) {\r
if (GetValueFrom == GetSetValueWithEditBuffer) {\r
}\r
\r
ASSERT (Value != NULL);\r
- LengthStr = StrLen (Value);\r
- Status = EFI_SUCCESS;\r
- if (IsString) {\r
- //\r
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
- // Add string tail char L'\0' into Length\r
- //\r
- Length = StorageWidth + sizeof (CHAR16);\r
- if (Length < ((LengthStr / 4 + 1) * 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- } else {\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
- }\r
- } else {\r
- if (StorageWidth < ((LengthStr + 1) / 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\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
-\r
+ Status = BufferToValue (Question, Value);\r
FreePool (Value);\r
}\r
} else {\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
- Status = EFI_SUCCESS;\r
- if (!IsBufferStorage && IsString) {\r
- //\r
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
- // Add string tail char L'\0' into Length\r
- //\r
- Length = StorageWidth + sizeof (CHAR16);\r
- if (Length < ((LengthStr / 4 + 1) * 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- } else {\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
- }\r
- } else {\r
- if (StorageWidth < ((LengthStr + 1) / 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\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
-\r
+ Status = BufferToValue (Question, Value);\r
if (EFI_ERROR (Status)) {\r
FreePool (Result);\r
return Status;\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
LIST_ENTRY *ListHead;\r
- EFI_STRING PopUp;\r
FORM_EXPRESSION *Expression;\r
+ UINT32 BrowserStatus;\r
+ CHAR16 *ErrorStr;\r
+\r
+ BrowserStatus = BROWSER_SUCCESS;\r
+ ErrorStr = NULL;\r
+\r
+ switch (Type) {\r
+ case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
+ ListHead = &Question->InconsistentListHead;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_WARNING_IF:\r
+ ListHead = &Question->WarningListHead;\r
+ break;\r
\r
- if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+ case EFI_HII_EXPRESSION_NO_SUBMIT_IF:\r
ListHead = &Question->NoSubmitListHead;\r
- } else {\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
return EFI_UNSUPPORTED;\r
}\r
\r
return Status;\r
}\r
\r
- if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {\r
- //\r
- // Condition meet, show up error message\r
- //\r
- if (Expression->Error != 0) {\r
- PopUp = GetToken (Expression->Error, FormSet->HiiHandle);\r
- if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
- gBrowserStatus = BROWSER_NO_SUBMIT_IF;\r
- gErrorInfo = PopUp;\r
+ if (IsTrue (&Expression->Result)) {\r
+ switch (Type) {\r
+ case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
+ BrowserStatus = BROWSER_INCONSISTENT_IF;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_WARNING_IF:\r
+ BrowserStatus = BROWSER_WARNING_IF;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_NO_SUBMIT_IF:\r
+ BrowserStatus = BROWSER_NO_SUBMIT_IF;\r
+ //\r
+ // This code only used to compatible with old display engine,\r
+ // New display engine will not use this field.\r
+ //\r
+ if (Expression->Error != 0) {\r
+ ErrorStr = GetToken (Expression->Error, FormSet->HiiHandle);\r
}\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
}\r
\r
- return EFI_NOT_READY;\r
+ if (!((Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) && mSystemSubmit)) {\r
+ //\r
+ // If in system submit process and for no_submit_if check, not popup this error message.\r
+ // Will process this fail again later in not system submit process.\r
+ //\r
+ PopupErrorMessage(BrowserStatus, FormSet->HiiHandle, Expression->OpCode, ErrorStr);\r
+ }\r
+\r
+ if (ErrorStr != NULL) {\r
+ FreePool (ErrorStr);\r
+ }\r
+\r
+ if (Type == EFI_HII_EXPRESSION_WARNING_IF) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_READY;\r
+ }\r
}\r
\r
Link = GetNextNode (ListHead, Link);\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Perform question check. \r
+ \r
+ If one question has more than one check, process form high priority to low. \r
+ Only one error info will be popup.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param Question The Question to be validated.\r
+\r
+ @retval EFI_SUCCESS Form validation pass.\r
+ @retval other Form validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValueChangedValidation (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN FORM_BROWSER_STATEMENT *Question\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Do the inconsistentif check.\r
+ //\r
+ if (!IsListEmpty (&Question->InconsistentListHead)) {\r
+ Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Do the warningif check.\r
+ //\r
+ if (!IsListEmpty (&Question->WarningListHead)) {\r
+ Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_WARNING_IF);\r
+ }\r
+\r
+ return Status;\r
+}\r
\r
/**\r
Perform NoSubmit check for each Form in FormSet.\r
\r
@param FormSet FormSet data structure.\r
@param CurrentForm Current input form data structure.\r
+ @param Statement The statement for this check.\r
\r
@retval EFI_SUCCESS Form validation pass.\r
@retval other Form validation failed.\r
**/\r
EFI_STATUS\r
NoSubmitCheck (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *CurrentForm\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN OUT FORM_BROWSER_FORM **CurrentForm,\r
+ OUT FORM_BROWSER_STATEMENT **Statement\r
)\r
{\r
EFI_STATUS Status;\r
Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);\r
LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
\r
- if (CurrentForm != NULL && CurrentForm != Form) {\r
+ if (*CurrentForm != NULL && *CurrentForm != Form) {\r
continue;\r
}\r
\r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-\r
Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
if (EFI_ERROR (Status)) {\r
+ if (*CurrentForm == NULL) {\r
+ *CurrentForm = Form;\r
+ }\r
+ if (Statement != NULL) {\r
+ *Statement = Question;\r
+ }\r
return Status;\r
}\r
\r
/**\r
Fill storage's edit copy with settings requested from Configuration Driver.\r
\r
- @param FormSet FormSet data structure.\r
@param Storage The storage which need to sync.\r
@param ConfigRequest The config request string which used to sync storage.\r
@param SyncOrRestore Sync the buffer to editbuffer or Restore the \r
**/\r
EFI_STATUS\r
SynchronizeStorage (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
OUT BROWSER_STORAGE *Storage,\r
IN CHAR16 *ConfigRequest,\r
IN BOOLEAN SyncOrRestore\r
EFI_IFR_TYPE_VALUE *TypeValue;\r
EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
\r
+ if (FormSet->ConfigAccess == NULL) {\r
+ return;\r
+ }\r
+\r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
continue;\r
}\r
\r
- if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
continue;\r
}\r
\r
- if (!Question->ValueChanged) {\r
+ if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+ continue;\r
+ }\r
+\r
+ if (!Question->ValueChanged) {\r
continue;\r
}\r
\r
+ //\r
+ // Restore the question value before call the CHANGED callback type.\r
+ //\r
+ GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+\r
if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;\r
} else {\r
}\r
\r
/**\r
- Validate the FormSet. If the formset is not validate, remove it from the list.\r
+ Validate the HiiHandle.\r
\r
- @param FormSet The input FormSet which need to validate.\r
+ @param HiiHandle The input HiiHandle which need to validate.\r
\r
@retval TRUE The handle is validate.\r
@retval FALSE The handle is invalidate.\r
\r
**/\r
BOOLEAN\r
-ValidateFormSet (\r
- FORM_BROWSER_FORMSET *FormSet\r
+ValidateHiiHandle (\r
+ EFI_HII_HANDLE HiiHandle\r
)\r
{\r
EFI_HII_HANDLE *HiiHandles;\r
UINTN Index;\r
BOOLEAN Find;\r
\r
- ASSERT (FormSet != NULL);\r
+ if (HiiHandle == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
Find = FALSE;\r
- //\r
- // Get all the Hii handles\r
- //\r
+\r
HiiHandles = HiiGetHiiHandles (NULL);\r
ASSERT (HiiHandles != NULL);\r
\r
- //\r
- // Search for formset of each class type\r
- //\r
for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
- if (HiiHandles[Index] == FormSet->HiiHandle) {\r
+ if (HiiHandles[Index] == HiiHandle) {\r
Find = TRUE;\r
break;\r
}\r
}\r
\r
- if (!Find) {\r
+ FreePool (HiiHandles);\r
+\r
+ return Find;\r
+}\r
+\r
+/**\r
+ Validate the FormSet. If the formset is not validate, remove it from the list.\r
+\r
+ @param FormSet The input FormSet which need to validate.\r
+\r
+ @retval TRUE The handle is validate.\r
+ @retval FALSE The handle is invalidate.\r
+\r
+**/\r
+BOOLEAN\r
+ValidateFormSet (\r
+ FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ BOOLEAN Find;\r
+\r
+ ASSERT (FormSet != NULL);\r
+\r
+ Find = ValidateHiiHandle(FormSet->HiiHandle);\r
+ //\r
+ // Should not remove the formset which is being used.\r
+ //\r
+ if (!Find && (FormSet != gCurrentSelection->FormSet)) {\r
CleanBrowserStorage(FormSet);\r
RemoveEntryList (&FormSet->Link);\r
DestroyFormSet (FormSet);\r
}\r
\r
- FreePool (HiiHandles);\r
-\r
return Find;\r
}\r
/**\r
Also clean all ValueChanged flag in question.\r
\r
@param SetFlag Whether need to set the Reset Flag.\r
+ @param FormSet FormSet data structure.\r
@param Form Form data structure.\r
\r
**/\r
VOID\r
UpdateFlagForForm (\r
IN BOOLEAN SetFlag,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
IN FORM_BROWSER_FORM *Form\r
)\r
{\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
- BOOLEAN FindOne;\r
+ BOOLEAN OldValue;\r
\r
- FindOne = FALSE;\r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
- \r
- if (SetFlag && Question->ValueChanged && ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {\r
- gResetRequired = TRUE;\r
- } \r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
\r
- if (Question->ValueChanged) {\r
- Question->ValueChanged = FALSE;\r
+ if (!Question->ValueChanged) {\r
+ continue;\r
}\r
- \r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
+\r
+ OldValue = Question->ValueChanged;\r
+\r
+ //\r
+ // Compare the buffer and editbuffer data to see whether the data has been saved.\r
+ //\r
+ Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBothBuffer);\r
+\r
+ //\r
+ // Only the changed data has been saved, then need to set the reset flag.\r
+ //\r
+ if (SetFlag && OldValue && !Question->ValueChanged && ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {\r
+ gResetRequired = TRUE;\r
+ } \r
}\r
}\r
\r
FORM_BROWSER_FORM *CurrentForm;\r
LIST_ENTRY *Link;\r
\r
- //\r
- // Form != NULL means only check form level.\r
- //\r
if (Form != NULL) {\r
- UpdateFlagForForm(SetFlag, Form);\r
+ UpdateFlagForForm(SetFlag, FormSet, Form);\r
return;\r
}\r
\r
CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);\r
Link = GetNextNode (&FormSet->FormListHead, Link);\r
\r
- UpdateFlagForForm(SetFlag, CurrentForm);\r
+ UpdateFlagForForm(SetFlag, FormSet, CurrentForm);\r
+ }\r
+}\r
+\r
+/**\r
+ Base on the return Progress string to find the form. \r
+ \r
+ Base on the first return Offset/Width (Name) string to find the form\r
+ which keep this string.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Storage Storage which has this Progress string.\r
+ @param Progress The Progress string which has the first fail string.\r
+ @param RetForm The return form for this progress string.\r
+ @param RetQuestion The return question for the error progress string.\r
+\r
+ @retval TRUE Find the error form and statement for this error progress string.\r
+ @retval FALSE Not find the error form.\r
+\r
+**/\r
+BOOLEAN\r
+FindQuestionFromProgress (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN BROWSER_STORAGE *Storage,\r
+ IN EFI_STRING Progress,\r
+ OUT FORM_BROWSER_FORM **RetForm,\r
+ OUT FORM_BROWSER_STATEMENT **RetQuestion\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *LinkStorage;\r
+ LIST_ENTRY *LinkStatement;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+ FORM_BROWSER_FORM *Form;\r
+ EFI_STRING EndStr;\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+\r
+ ASSERT ((*Progress == '&') || (*Progress == 'G'));\r
+\r
+ ConfigInfo = NULL;\r
+ *RetForm = NULL;\r
+ *RetQuestion = NULL;\r
+\r
+ //\r
+ // Skip the first "&" or the ConfigHdr part.\r
+ //\r
+ if (*Progress == '&') {\r
+ Progress++;\r
+ } else {\r
+ //\r
+ // Prepare the "NAME" or "OFFSET=0x####&WIDTH=0x####" string.\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // For Name/Value type, Skip the ConfigHdr part.\r
+ //\r
+ EndStr = StrStr (Progress, L"PATH=");\r
+ ASSERT (EndStr != NULL);\r
+ while (*EndStr != '&') {\r
+ EndStr++;\r
+ }\r
+\r
+ *EndStr = '\0';\r
+ } else {\r
+ //\r
+ // For Buffer type, Skip the ConfigHdr part.\r
+ //\r
+ EndStr = StrStr (Progress, L"&OFFSET=");\r
+ ASSERT (EndStr != NULL);\r
+ *EndStr = '\0';\r
+ }\r
+\r
+ Progress = EndStr + 1;\r
+ }\r
+\r
+ //\r
+ // Prepare the "NAME" or "OFFSET=0x####&WIDTH=0x####" string.\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // For Name/Value type, the data is "&Fred=16&George=16&Ron=12" formset,\r
+ // here, just keep the "Fred" string.\r
+ //\r
+ EndStr = StrStr (Progress, L"=");\r
+ ASSERT (EndStr != NULL);\r
+ *EndStr = '\0';\r
+ } else {\r
+ //\r
+ // For Buffer type, the data is "OFFSET=0x####&WIDTH=0x####&VALUE=0x####",\r
+ // here, just keep the "OFFSET=0x####&WIDTH=0x####" string.\r
+ //\r
+ EndStr = StrStr (Progress, L"&VALUE=");\r
+ ASSERT (EndStr != NULL);\r
+ *EndStr = '\0';\r
+ }\r
+\r
+ //\r
+ // Search in the form list.\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
+ // Search in the ConfigReqeust list in this form.\r
+ //\r
+ LinkStorage = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, LinkStorage)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (LinkStorage);\r
+ LinkStorage = GetNextNode (&Form->ConfigRequestHead, LinkStorage);\r
+\r
+ if (Storage != ConfigInfo->Storage) {\r
+ continue;\r
+ }\r
+\r
+ if (StrStr (ConfigInfo->ConfigRequest, Progress) != NULL) {\r
+ //\r
+ // Find the OffsetWidth string in this form.\r
+ //\r
+ *RetForm = Form;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (*RetForm != NULL) {\r
+ LinkStatement = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, LinkStatement)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (LinkStatement);\r
+ LinkStatement = GetNextNode (&Form->StatementListHead, LinkStatement);\r
+\r
+ if (Statement->BlockName != NULL && StrStr (Statement->BlockName, Progress) != NULL) {\r
+ *RetQuestion = Statement;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (*RetForm != NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // restore the OffsetWidth string to the original format.\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ *EndStr = '=';\r
+ } else {\r
+ *EndStr = '&';\r
}\r
+\r
+ return (BOOLEAN) (*RetForm != NULL);\r
+}\r
+\r
+/**\r
+ Popup an save error info and get user input.\r
+\r
+ @param TitleId The form title id.\r
+ @param HiiHandle The hii handle for this package.\r
+\r
+ @retval UINT32 The user select option for the save fail.\r
+ BROWSER_ACTION_DISCARD or BROWSER_ACTION_JUMP_TO_FORMSET\r
+**/\r
+UINT32\r
+ConfirmSaveFail (\r
+ IN EFI_STRING_ID TitleId,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ CHAR16 *FormTitle;\r
+ CHAR16 *StringBuffer;\r
+ UINT32 RetVal;\r
+\r
+ FormTitle = GetToken (TitleId, HiiHandle);\r
+\r
+ StringBuffer = AllocateZeroPool (256 * sizeof (CHAR16));\r
+ ASSERT (StringBuffer != NULL);\r
+\r
+ UnicodeSPrint (\r
+ StringBuffer, \r
+ 24 * sizeof (CHAR16) + StrSize (FormTitle), \r
+ L"Submit Fail For Form: %s.", \r
+ FormTitle\r
+ );\r
+\r
+ RetVal = PopupErrorMessage(BROWSER_SUBMIT_FAIL, NULL, NULL, StringBuffer);\r
+\r
+ FreePool (StringBuffer);\r
+ FreePool (FormTitle);\r
+\r
+ return RetVal;\r
+}\r
+\r
+/**\r
+ Popup an NO_SUBMIT_IF error info and get user input.\r
+\r
+ @param TitleId The form title id.\r
+ @param HiiHandle The hii handle for this package.\r
+\r
+ @retval UINT32 The user select option for the save fail.\r
+ BROWSER_ACTION_DISCARD or BROWSER_ACTION_JUMP_TO_FORMSET\r
+**/\r
+UINT32\r
+ConfirmNoSubmitFail (\r
+ IN EFI_STRING_ID TitleId,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ CHAR16 *FormTitle;\r
+ CHAR16 *StringBuffer;\r
+ UINT32 RetVal;\r
+\r
+ FormTitle = GetToken (TitleId, HiiHandle);\r
+\r
+ StringBuffer = AllocateZeroPool (256 * sizeof (CHAR16));\r
+ ASSERT (StringBuffer != NULL);\r
+\r
+ UnicodeSPrint (\r
+ StringBuffer, \r
+ 24 * sizeof (CHAR16) + StrSize (FormTitle), \r
+ L"NO_SUBMIT_IF error For Form: %s.", \r
+ FormTitle\r
+ );\r
+\r
+ RetVal = PopupErrorMessage(BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF, NULL, NULL, StringBuffer);\r
+\r
+ FreePool (StringBuffer);\r
+ FreePool (FormTitle);\r
+\r
+ return RetVal;\r
}\r
\r
/**\r
//\r
// Prepare <ConfigResp>\r
//\r
- SynchronizeStorage(FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
+ SynchronizeStorage(ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
\r
//\r
// Call callback with Changed type to inform the driver.\r
SendDiscardInfoToDriver (FormSet, Form);\r
}\r
\r
- ValueChangeResetFlagUpdate (FALSE, NULL, Form);\r
+ ValueChangeResetFlagUpdate (FALSE, FormSet, Form);\r
} else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
\r
//\r
continue;\r
}\r
\r
- SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
+ SynchronizeStorage(Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
}\r
\r
Link = GetFirstNode (&FormSet->FormListHead);\r
}\r
\r
/**\r
- Submit data based on the input Setting level (Form, FormSet or System).\r
+ Submit data for a form.\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
+SubmitForForm (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN BROWSER_SETTING_SCOPE SettingScope\r
+ IN FORM_BROWSER_FORM *Form\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STRING ConfigResp;\r
EFI_STRING Progress;\r
BROWSER_STORAGE *Storage;\r
- FORMSET_STORAGE *FormSetStorage;\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
+ if (!IsNvUpdateRequiredForForm (Form)) {\r
+ return EFI_SUCCESS;\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
+ Status = NoSubmitCheck (FormSet, &Form, NULL);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {\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
+ 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
+ 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
+ // 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, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ //\r
+ // 1. Prepare <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- //\r
- // 2. Set value to hii config routine protocol.\r
- //\r
- Status = mHiiConfigRouting->RouteConfig (\r
- mHiiConfigRouting,\r
- ConfigResp,\r
- &Progress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (ConfigResp);\r
- return Status;\r
- }\r
+ //\r
+ // 2. Set value to hii config routine protocol.\r
+ //\r
+ Status = mHiiConfigRouting->RouteConfig (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ &Progress\r
+ );\r
+ FreePool (ConfigResp);\r
\r
- FreePool (ConfigResp);\r
- //\r
- // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
- //\r
- SynchronizeStorage (FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ InsertTailList (&gBrowserSaveFailFormSetList, &ConfigInfo->SaveFailLink);\r
+ continue;\r
}\r
\r
//\r
- // 4. Update the NV flag.\r
- // \r
- ValueChangeResetFlagUpdate(TRUE, NULL, Form);\r
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
- //\r
- // Submit Buffer storage or Name/Value storage\r
+ // 3. Config success, update storage shadow Buffer, only update the data belong to this 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
+ SynchronizeStorage (ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);\r
+ }\r
\r
- if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- continue;\r
+ //\r
+ // 4. Process the save failed storage.\r
+ //\r
+ if (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
+ if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
+ Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
+ while (!IsNull (&gBrowserSaveFailFormSetList, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_SAVE_FAIL_LINK (Link);\r
+ Link = GetNextNode (&gBrowserSaveFailFormSetList, Link);\r
+\r
+ SynchronizeStorage(ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
+\r
+ Status = EFI_SUCCESS;\r
}\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
\r
+ //\r
+ // Free Form save fail list.\r
+ //\r
+ while (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
+ Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_SAVE_FAIL_LINK (Link);\r
+ RemoveEntryList (&ConfigInfo->SaveFailLink);\r
+ }\r
+ }\r
+\r
+ //\r
+ // 5. Update the NV flag.\r
+ //\r
+ ValueChangeResetFlagUpdate(TRUE, FormSet, Form);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Submit data for a formset.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param SkipProcessFail Whether skip to process the save failed storage.\r
+ If submit formset is called when do system level save, \r
+ set this value to true and process the failed formset \r
+ together. \r
+ if submit formset is called when do formset level save,\r
+ set the value to false and process the failed storage\r
+ right after process all storages for this formset.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
+\r
+**/\r
+EFI_STATUS\r
+SubmitForFormSet (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN BOOLEAN SkipProcessFail\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
+ FORM_BROWSER_FORM *Form;\r
+ BOOLEAN HasInserted;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ HasInserted = FALSE;\r
+\r
+ if (!IsNvUpdateRequiredForFormSet (FormSet)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Form = NULL; \r
+ Status = NoSubmitCheck (FormSet, &Form, &Question);\r
+ if (EFI_ERROR (Status)) {\r
+ if (SkipProcessFail) {\r
//\r
- // Skip if there is no RequestElement\r
+ // Process NO_SUBMIT check first, so insert it at head.\r
//\r
- if (FormSetStorage->ElementCount == 0) {\r
- continue;\r
+ FormSet->SaveFailForm = Form;\r
+ FormSet->SaveFailStatement = Question;\r
+ InsertHeadList (&gBrowserSaveFailFormSetList, &FormSet->SaveFailLink);\r
+ }\r
+\r
+ return Status;\r
+ }\r
+\r
+ Form = NULL;\r
+ Question = NULL;\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, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // 2. Send <ConfigResp> to Routine config Protocol.\r
+ //\r
+ Status = mHiiConfigRouting->RouteConfig (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ InsertTailList (&FormSet->SaveFailStorageListHead, &FormSetStorage->SaveFailLink);\r
+ if (!HasInserted) {\r
+ //\r
+ // Call submit formset for system level, save the formset info\r
+ // and process later.\r
+ //\r
+ FindQuestionFromProgress(FormSet, Storage, Progress, &Form, &Question);\r
+ ASSERT (Form != NULL && Question != NULL);\r
+ FormSet->SaveFailForm = Form;\r
+ FormSet->SaveFailStatement = Question;\r
+ if (SkipProcessFail) {\r
+ InsertTailList (&gBrowserSaveFailFormSetList, &FormSet->SaveFailLink);\r
+ }\r
+ HasInserted = TRUE;\r
}\r
\r
+ FreePool (ConfigResp);\r
+ continue;\r
+ }\r
+\r
+ FreePool (ConfigResp);\r
+ //\r
+ // 3. Config success, update storage shadow Buffer\r
+ //\r
+ SynchronizeStorage (Storage, FormSetStorage->ConfigRequest, TRUE);\r
+ }\r
+\r
+ //\r
+ // 4. Has save fail storage need to handle.\r
+ //\r
+ if (Form != NULL) {\r
+ if (!SkipProcessFail) {\r
//\r
- // 1. Prepare <ConfigResp>\r
+ // If not in system level, just handl the save failed storage here.\r
//\r
- Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
+ Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
+ while (!IsNull (&FormSet->SaveFailStorageListHead, Link)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
+ Storage = FormSetStorage->BrowserStorage;\r
+ Link = GetNextNode (&FormSet->SaveFailStorageListHead, Link);\r
+\r
+ SynchronizeStorage(FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, FALSE);\r
+\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ } else {\r
+ UiCopyMenuList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &Form->FormViewListHead);\r
+\r
+ gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ gCurrentSelection->Handle = FormSet->HiiHandle;\r
+ CopyGuid (&gCurrentSelection->FormSetGuid, &FormSet->Guid);\r
+ gCurrentSelection->FormId = Form->FormId;\r
+ gCurrentSelection->QuestionId = Question->QuestionId;\r
+\r
+ Status = EFI_UNSUPPORTED;\r
}\r
\r
//\r
- // 2. Send <ConfigResp> to Routine config Protocol.\r
+ // Free FormSet save fail list.\r
//\r
- Status = mHiiConfigRouting->RouteConfig (\r
- mHiiConfigRouting,\r
- ConfigResp,\r
- &Progress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (ConfigResp);\r
- return Status;\r
+ while (!IsListEmpty (&FormSet->SaveFailStorageListHead)) {\r
+ Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
+ FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
+ RemoveEntryList (&FormSetStorage->SaveFailLink);\r
}\r
-\r
- FreePool (ConfigResp);\r
+ } else {\r
//\r
- // 3. Config success, update storage shadow Buffer\r
+ // If in system level, just return error and handle the failed formset later.\r
//\r
- SynchronizeStorage (FormSet, Storage, FormSetStorage->ConfigRequest, TRUE);\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // 5. Update the NV flag.\r
+ // \r
+ ValueChangeResetFlagUpdate(TRUE, FormSet, NULL);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Submit data for all formsets.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
+\r
+**/\r
+EFI_STATUS\r
+SubmitForSystem (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *StorageLink;\r
+ BROWSER_STORAGE *Storage;\r
+ FORMSET_STORAGE *FormSetStorage;\r
+ FORM_BROWSER_FORM *Form;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+ UINT32 UserSelection;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ mSystemSubmit = TRUE;\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
+ Status = SubmitForFormSet (LocalFormSet, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
}\r
\r
//\r
- // 4. Update the NV flag.\r
- // \r
- ValueChangeResetFlagUpdate(TRUE, FormSet, NULL);\r
- } else if (SettingScope == SystemLevel) {\r
- //\r
- // System Level Save.\r
- //\r
+ // Remove maintain backup list after save except for the current using FormSet.\r
+ // \r
+ if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
+ CleanBrowserStorage(LocalFormSet);\r
+ RemoveEntryList (&LocalFormSet->Link);\r
+ DestroyFormSet (LocalFormSet);\r
+ }\r
+ }\r
+ mSystemSubmit = FALSE;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Process the save failed formsets.\r
+ //\r
+ Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
+ while (!IsNull (&gBrowserSaveFailFormSetList, Link)) {\r
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_SAVE_FAIL_LINK (Link);\r
+ Link = GetNextNode (&gBrowserSaveFailFormSetList, Link);\r
+\r
+ if (!ValidateFormSet(LocalFormSet)) {\r
+ continue;\r
+ }\r
+\r
+ Form = LocalFormSet->SaveFailForm;\r
+ Question= LocalFormSet->SaveFailStatement;\r
\r
//\r
- // Save changed value for each FormSet in the maintain list.\r
+ // Confirm with user, get user input.\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
+ if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
+ //\r
+ // NULL for SaveFailStorageListHead means error caused by NO_SUBMIT_IF check.\r
+ //\r
+ UserSelection = ConfirmNoSubmitFail (Form->FormTitle, LocalFormSet->HiiHandle);\r
+ } else {\r
+ UserSelection = ConfirmSaveFail (Form->FormTitle, LocalFormSet->HiiHandle);\r
+ }\r
+\r
+ if (UserSelection == BROWSER_ACTION_DISCARD) {\r
+ if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
+ StorageLink = GetFirstNode (&LocalFormSet->StorageListHead);\r
+ while (!IsNull (&LocalFormSet->StorageListHead, StorageLink)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
+ Storage = FormSetStorage->BrowserStorage;\r
+ StorageLink = GetNextNode (&LocalFormSet->StorageListHead, StorageLink);\r
+\r
+ SynchronizeStorage(FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, FALSE);\r
+ }\r
+ } else {\r
+ StorageLink = GetFirstNode (&LocalFormSet->SaveFailStorageListHead);\r
+ while (!IsNull (&LocalFormSet->SaveFailStorageListHead, StorageLink)) {\r
+ FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (StorageLink);\r
+ Storage = FormSetStorage->BrowserStorage;\r
+ StorageLink = GetNextNode (&LocalFormSet->SaveFailStorageListHead, StorageLink);\r
+\r
+ SynchronizeStorage(FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, FALSE);\r
+ }\r
}\r
- SubmitForm (LocalFormSet, NULL, FormSetLevel);\r
+\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
+ RemoveEntryList (&LocalFormSet->SaveFailLink);\r
DestroyFormSet (LocalFormSet);\r
+ } else {\r
+ ValueChangeResetFlagUpdate(FALSE, LocalFormSet, NULL);\r
}\r
+ } else {\r
+ if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
+ NoSubmitCheck (LocalFormSet, &Form, &Question);\r
+ }\r
+\r
+ UiCopyMenuList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &Form->FormViewListHead);\r
+\r
+ gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ gCurrentSelection->Handle = LocalFormSet->HiiHandle;\r
+ CopyGuid (&gCurrentSelection->FormSetGuid, &LocalFormSet->Guid);\r
+ gCurrentSelection->FormId = Form->FormId;\r
+ gCurrentSelection->QuestionId = Question->QuestionId;\r
+\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
}\r
}\r
\r
- return EFI_SUCCESS;\r
+ //\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
- Get Question default value from AltCfg string.\r
+ Submit data based on the input Setting level (Form, FormSet or System).\r
\r
- @param FormSet The form set.\r
- @param Question The question.\r
- @param DefaultId The default Id.\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 Question is reset to default value.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.\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
+SubmitForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BROWSER_SETTING_SCOPE SettingScope\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
+ 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
+ switch (SettingScope) {\r
+ case FormLevel:\r
+ Status = SubmitForForm(FormSet, Form);\r
+ break;\r
\r
- if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
- return Status;\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
- // Question Value is provided by Buffer Storage or NameValue Storage\r
+ // Convert all hex digits in range [A-F] in the configuration header to [a-f]\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
+ 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
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- IsBufferStorage = TRUE;\r
- } else {\r
- IsBufferStorage = FALSE;\r
- }\r
- IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\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
- // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
- // <ConfigHdr> + "&" + <VariableName>\r
+ // Type is EFI_HII_VARSTORE_NAME_VALUE.\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
+ 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
- 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 = mHiiConfigRouting->ExtractConfig (\r
- mHiiConfigRouting,\r
- ConfigRequest,\r
- &Progress,\r
- &Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ return RequestElement;\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
+ // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\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
//\r
- // The required setting can't be found. So, it is not required to be validated and set.\r
+ // 1. Directly use Question->BlockName to find.\r
//\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (ConfigResp == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\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
//\r
- // Skip <ConfigRequest>\r
+ // 2. Change all hex digits in Question->BlockName to lower and compare again.\r
//\r
- if (IsBufferStorage) {\r
- Value = StrStr (ConfigResp, L"&VALUE");\r
- ASSERT (Value != NULL);\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 "&VALUE"\r
+ // Skip the "Question->BlockName&VALUE=" field.\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
+ RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
}\r
- if (*Value != '=') {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\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
- // Skip '=', point to value\r
- //\r
- Value = Value + 1;\r
\r
//\r
- // Suppress <AltResp> if any\r
+ // Try to get AltCfg string from form. If not found it, then\r
+ // try to get it from formset.\r
//\r
- StringPtr = Value;\r
- while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
- StringPtr++;\r
- }\r
- *StringPtr = L'\0';\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
- 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
+ if (Storage == ConfigInfo->Storage) {\r
+ ConfigResp = ConfigInfo->ConfigAltResp;\r
+ break;\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
+ 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
-Done:\r
- if (ConfigRequest != NULL){\r
- FreePool (ConfigRequest);\r
+ if (ConfigResp == NULL) {\r
+ return EFI_NOT_FOUND;\r
}\r
\r
- if (ConfigResp != NULL) {\r
- FreePool (ConfigResp);\r
- }\r
- \r
- if (Result != NULL) {\r
- FreePool (Result);\r
+ Value = GetOffsetFromConfigResp (Question, ConfigResp);\r
+ if (Value == NULL) {\r
+ return EFI_NOT_FOUND;\r
}\r
\r
- return Status;\r
+ return BufferToValue (Question, Value);\r
}\r
\r
/**\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
INTN Action;\r
+ CHAR16 *NewString;\r
\r
Status = EFI_NOT_FOUND;\r
StrValue = NULL;\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
+ CopyMem (Question->BufferValue, NewString, StrSize (NewString));\r
+ } else {\r
+ CopyMem (Question->BufferValue, NewString, Question->StorageWidth);\r
+ }\r
+\r
+ FreePool (NewString);\r
+ }\r
return Status;\r
}\r
}\r
// Get default value from altcfg string.\r
//\r
if (ConfigAccess != NULL) { \r
- Status = GetDefaultValueFromAltCfg(FormSet, Question, DefaultId);\r
+ Status = GetDefaultValueFromAltCfg(FormSet, Form, Question);\r
if (!EFI_ERROR (Status)) {\r
return Status;\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
+\r
+**/\r
+VOID\r
+ExtractAltCfgForForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN UINT16 DefaultId\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
+\r
+ if (Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE &&\r
+ FormSetStorage->ElementCount != 0 &&\r
+ FormSetStorage->ConfigAltResp != NULL) {\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 (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
+\r
+**/\r
+VOID\r
+ExtractAltCfgForFormSet (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN UINT16 DefaultId\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 (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
+ //\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
+/**\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
+}\r
\r
/**\r
Reset Questions to their initial value or default value in a Form, Formset or System.\r
if (GetDefaultValueScope == GetDefaultForStorage && Storage == NULL) {\r
return EFI_UNSUPPORTED;\r
}\r
- \r
+\r
if (SettingScope == FormLevel) {\r
+ //\r
+ // Prepare the AltCfg String for form.\r
+ //\r
+ ExtractAltCfgForForm (FormSet, Form, DefaultId);\r
+\r
//\r
// Extract Form default\r
//\r
//\r
// Call the Retrieve call back to get the initial question value.\r
//\r
- Status = ProcessRetrieveForQuestion(FormSet->ConfigAccess, Question);\r
+ Status = ProcessRetrieveForQuestion(FormSet->ConfigAccess, Question, FormSet);\r
}\r
\r
//\r
SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
}\r
}\r
+\r
+ //\r
+ // Clean the AltCfg String.\r
+ //\r
+ CleanAltCfgForForm(Form);\r
} else if (SettingScope == FormSetLevel) {\r
+ //\r
+ // Prepare the AltCfg String for formset.\r
+ //\r
+ ExtractAltCfgForFormSet (FormSet, DefaultId);\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);\r
FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
}\r
+\r
+ //\r
+ // Clean the AltCfg String.\r
+ //\r
+ CleanAltCfgForFormSet (FormSet);\r
} else if (SettingScope == SystemLevel) {\r
//\r
// Preload all Hii formset.\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
BackUpBuffer = NULL;\r
+ BackUpBuffer2 = NULL;\r
ValueChanged = FALSE;\r
\r
switch (Question->Operand) {\r
}\r
CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
\r
- Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);\r
- ASSERT_EFI_ERROR(Status);\r
+ if (GetValueFrom == GetSetValueWithBothBuffer) {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\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
- ValueChanged = TRUE;\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
+ 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
+ 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
+ ValueChanged = TRUE;\r
+ }\r
}\r
\r
CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
- CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);\r
-\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
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
- UINT8 *BufferValue;\r
- UINTN StorageWidth;\r
\r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);\r
}\r
\r
- //\r
- // Call the Retrieve call back function for all questions.\r
- //\r
- if ((FormSet->ConfigAccess != NULL) && (Selection != NULL) &&\r
- ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
- !gFinishRetrieveCall) {\r
- //\r
- // Check QuestionValue does exist.\r
- //\r
- StorageWidth = Question->StorageWidth;\r
- if (Question->BufferValue != NULL) {\r
- BufferValue = Question->BufferValue;\r
- } else {\r
- BufferValue = (UINT8 *) &Question->HiiValue.Value;\r
- }\r
-\r
- //\r
- // For efivarstore storage, initial question value first.\r
- //\r
- if ((Question->Storage != NULL) && (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
- Status = gRT->GetVariable (\r
- Question->VariableName,\r
- &Question->Storage->Guid,\r
- NULL,\r
- &StorageWidth,\r
- BufferValue\r
- );\r
- }\r
-\r
- Status = ProcessCallBackFunction(Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
- }\r
-\r
Link = GetNextNode (&Form->StatementListHead, Link);\r
}\r
\r
{\r
LIST_ENTRY *Link;\r
FORMSET_STORAGE *Storage;\r
- CHAR16 *ConfigRequest;\r
\r
Link = GetFirstNode (&FormSet->StorageListHead);\r
while (!IsNull (&FormSet->StorageListHead, Link)) {\r
continue;\r
}\r
\r
- ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;\r
- RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);\r
+ RemoveConfigRequest (Storage->BrowserStorage, Storage->ConfigRequest);\r
} else if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
if (Storage->BrowserStorage->ConfigRequest != NULL) { \r
Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
\r
@param Storage Form set Storage.\r
+ @param Request The input request string.\r
+ @param RespString Whether the input is ConfigRequest or ConfigResp format.\r
\r
@retval TRUE Has element not covered by current used elements, need to continue to call ExtractConfig\r
@retval FALSE All elements covered by current used elements.\r
**/\r
BOOLEAN \r
ConfigRequestAdjust (\r
- IN FORMSET_STORAGE *Storage\r
+ IN BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *Request,\r
+ IN BOOLEAN RespString\r
)\r
{\r
CHAR16 *RequestElement;\r
CHAR16 *NextRequestElement;\r
- CHAR16 *RetBuf;\r
+ CHAR16 *NextElementBakup;\r
UINTN SpareBufLen;\r
CHAR16 *SearchKey;\r
+ CHAR16 *ValueKey;\r
BOOLEAN RetVal;\r
+ CHAR16 *ConfigRequest;\r
\r
SpareBufLen = 0;\r
- RetBuf = NULL;\r
RetVal = FALSE;\r
+ NextElementBakup = NULL;\r
+ ValueKey = NULL;\r
\r
- if (Storage->BrowserStorage->ConfigRequest == NULL) {\r
- Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
- if (Storage->ConfigElements != NULL) {\r
- FreePool (Storage->ConfigElements);\r
- }\r
- Storage->ConfigElements = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+ if (Request != NULL) {\r
+ ConfigRequest = Request;\r
+ } else {\r
+ ConfigRequest = Storage->ConfigRequest;\r
+ }\r
+\r
+ if (Storage->ConfigRequest == NULL) {\r
+ Storage->ConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
return TRUE;\r
}\r
\r
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
//\r
// "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
//\r
// "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
//\r
SearchKey = L"&OFFSET";\r
+ ValueKey = L"&VALUE";\r
}\r
\r
- //\r
- // Prepare the config header.\r
- // \r
- RetBuf = AllocateCopyPool(StrSize (Storage->BrowserStorage->ConfigHdr), Storage->BrowserStorage->ConfigHdr);\r
- ASSERT (RetBuf != NULL);\r
-\r
//\r
// Find SearchKey storage\r
//\r
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
- RequestElement = StrStr (Storage->ConfigRequest, L"PATH");\r
+ if (Storage->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 (Storage->ConfigRequest, SearchKey);\r
+ RequestElement = StrStr (ConfigRequest, SearchKey);\r
}\r
\r
while (RequestElement != NULL) {\r
+\r
//\r
// +1 to avoid find header itself.\r
//\r
// The last Request element in configRequest string.\r
//\r
if (NextRequestElement != NULL) {\r
+ if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ NextElementBakup = NextRequestElement;\r
+ NextRequestElement = StrStr (RequestElement, ValueKey);\r
+ ASSERT (NextRequestElement != NULL);\r
+ }\r
//\r
// Replace "&" with '\0'.\r
//\r
*NextRequestElement = L'\0';\r
+ } else {\r
+ if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ NextElementBakup = NextRequestElement;\r
+ NextRequestElement = StrStr (RequestElement, ValueKey);\r
+ ASSERT (NextRequestElement != NULL);\r
+ //\r
+ // Replace "&" with '\0'.\r
+ //\r
+ *NextRequestElement = L'\0';\r
+ }\r
}\r
\r
- if (!ElementValidation (Storage->BrowserStorage, RequestElement)) {\r
+ if (!ElementValidation (Storage, RequestElement)) {\r
//\r
// Add this element to the Storage->BrowserStorage->AllRequestElement.\r
//\r
- AppendConfigRequest(&Storage->BrowserStorage->ConfigRequest, &Storage->BrowserStorage->SpareStrLen, RequestElement);\r
- AppendConfigRequest (&RetBuf, &SpareBufLen, RequestElement);\r
+ AppendConfigRequest(&Storage->ConfigRequest, &Storage->SpareStrLen, RequestElement);\r
RetVal = TRUE;\r
}\r
\r
*NextRequestElement = L'&';\r
}\r
\r
- RequestElement = NextRequestElement;\r
- }\r
-\r
- if (RetVal) {\r
- if (Storage->ConfigElements != NULL) {\r
- FreePool (Storage->ConfigElements);\r
+ if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ RequestElement = NextElementBakup;\r
+ } else {\r
+ RequestElement = NextRequestElement;\r
}\r
- Storage->ConfigElements = RetBuf;\r
- } else {\r
- FreePool (RetBuf);\r
}\r
\r
return RetVal;\r
}\r
\r
TmpNode = AllocateCopyPool (sizeof (NAME_VALUE_NODE), Node);\r
+ ASSERT (TmpNode != NULL);\r
TmpNode->Name = AllocateCopyPool (StrSize(Node->Name) * sizeof (CHAR16), Node->Name);\r
+ ASSERT (TmpNode->Name != NULL);\r
TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);\r
+ ASSERT (TmpNode->EditValue != NULL);\r
\r
InsertTailList(&BackUpList, &TmpNode->Link);\r
}\r
\r
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
- ConfigRequestAdjust(Storage);\r
+ ConfigRequestAdjust(Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
return;\r
}\r
break;\r
// Just update the ConfigRequest, if storage already initialized. \r
//\r
if (Storage->BrowserStorage->Initialized) {\r
- ConfigRequestAdjust(Storage);\r
+ ConfigRequestAdjust(Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
return;\r
}\r
\r
//\r
// Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer. \r
//\r
- SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);\r
+ SynchronizeStorage(Storage->BrowserStorage, NULL, TRUE);\r
\r
if (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) {\r
if (ConfigRequest != NULL) {\r
\r
return DataSavedAction;\r
}\r
+\r
+/**\r
+ Check whether the Reset Required for the browser\r
+\r
+ @retval TRUE Browser required to reset after exit.\r
+ @retval FALSE Browser not need to reset after exit.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsResetRequired (\r
+ VOID\r
+ )\r
+{\r
+ return gResetRequired;\r
+}\r
+\r