RegisterHotKey,\r
RegiserExitHandler,\r
SaveReminder\r
+ },\r
+ {\r
+ BROWSER_EXTENSION2_VERSION_1,\r
+ SetScope,\r
+ RegisterHotKey,\r
+ RegiserExitHandler,\r
+ IsBrowserDataModified,\r
+ ExecuteAction,\r
}\r
};\r
\r
EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
-EFI_HII_STRING_PROTOCOL *mHiiString;\r
EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;\r
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
+EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;\r
\r
UINTN gBrowserContextCount = 0;\r
LIST_ENTRY gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\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 gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
\r
-BANNER_DATA *gBannerData;\r
-EFI_HII_HANDLE gFrontPageHandle;\r
-UINTN gClassOfVfr;\r
-UINTN gFunctionKeySetting;\r
+BOOLEAN gFinishRetrieveCall;\r
BOOLEAN gResetRequired;\r
-EFI_HII_HANDLE gHiiHandle;\r
-UINT16 gDirection;\r
-EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
+BOOLEAN gExitRequired;\r
BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
BOOLEAN mBrowserScopeFirstSet = TRUE;\r
EXIT_HANDLER ExitHandlerFunction = NULL;\r
-UINTN gFooterHeight;\r
+FORM_BROWSER_FORMSET *mSystemLevelFormSet;\r
\r
//\r
// Browser Global Strings\r
//\r
-CHAR16 *gSaveFailed;\r
-CHAR16 *gDiscardFailed;\r
-CHAR16 *gDefaultFailed;\r
-CHAR16 *gEnterString;\r
-CHAR16 *gEnterCommitString;\r
-CHAR16 *gEnterEscapeString;\r
-CHAR16 *gEscapeString;\r
-CHAR16 *gMoveHighlight;\r
-CHAR16 *gMakeSelection;\r
-CHAR16 *gDecNumericInput;\r
-CHAR16 *gHexNumericInput;\r
-CHAR16 *gToggleCheckBox;\r
-CHAR16 *gPromptForData;\r
-CHAR16 *gPromptForPassword;\r
-CHAR16 *gPromptForNewPassword;\r
-CHAR16 *gConfirmPassword;\r
-CHAR16 *gConfirmError;\r
-CHAR16 *gPassowordInvalid;\r
-CHAR16 *gPressEnter;\r
CHAR16 *gEmptyString;\r
-CHAR16 *gAreYouSure;\r
-CHAR16 *gYesResponse;\r
-CHAR16 *gNoResponse;\r
-CHAR16 *gMiniString;\r
-CHAR16 *gPlusString;\r
-CHAR16 *gMinusString;\r
-CHAR16 *gAdjustNumber;\r
-CHAR16 *gSaveChanges;\r
-CHAR16 *gOptionMismatch;\r
-CHAR16 *gFormSuppress;\r
-CHAR16 *gProtocolNotFound;\r
-\r
CHAR16 *mUnknownString = L"!";\r
\r
-CHAR16 gPromptBlockWidth;\r
-CHAR16 gOptionBlockWidth;\r
-CHAR16 gHelpBlockWidth;\r
-\r
EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
-EFI_GUID gSetupBrowserGuid = {\r
- 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}\r
-};\r
\r
-FORM_BROWSER_FORMSET *gOldFormSet = NULL;\r
+extern UINT32 gBrowserStatus;\r
+extern CHAR16 *gErrorInfo;\r
+extern EFI_GUID mCurrentFormSetGuid;\r
+extern EFI_HII_HANDLE mCurrentHiiHandle;\r
+extern UINT16 mCurrentFormId;\r
+extern FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
+\r
+/**\r
+ Create a menu with specified formset GUID and form ID, and add it as a child\r
+ of the given parent menu.\r
+\r
+ @param HiiHandle Hii handle related to this formset.\r
+ @param FormSetGuid The Formset Guid of menu to be added.\r
+ @param FormId The Form ID of menu to be added.\r
+ @param QuestionId The question id of this menu to be added.\r
+\r
+ @return A pointer to the newly added menu or NULL if memory is insufficient.\r
+\r
+**/\r
+FORM_ENTRY_INFO *\r
+UiAddMenuList (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *FormSetGuid,\r
+ IN UINT16 FormId,\r
+ IN UINT16 QuestionId\r
+ )\r
+{\r
+ FORM_ENTRY_INFO *MenuList;\r
+\r
+ MenuList = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));\r
+ if (MenuList == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ MenuList->Signature = FORM_ENTRY_INFO_SIGNATURE;\r
+\r
+ MenuList->HiiHandle = HiiHandle;\r
+ CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
+ MenuList->FormId = FormId;\r
+ MenuList->QuestionId = QuestionId;\r
\r
-FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {\r
//\r
- // Boot Manager\r
+ // If parent is not specified, it is the root Form of a Formset\r
//\r
- {\r
- {\r
- 0x847bc3fe,\r
- 0xb974,\r
- 0x446d,\r
- {\r
- 0x94,\r
- 0x49,\r
- 0x5a,\r
- 0xd5,\r
- 0x41,\r
- 0x2e,\r
- 0x99,\r
- 0x3b\r
+ InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
+\r
+ return MenuList;\r
+}\r
+\r
+/**\r
+ Return the form id for the input hiihandle and formset.\r
+\r
+ @param HiiHandle HiiHandle for FormSet.\r
+ @param FormSetGuid The Formset GUID of the menu to search.\r
+\r
+ @return First form's id for this form set.\r
+\r
+**/\r
+EFI_FORM_ID\r
+GetFirstFormId (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *FormSetGuid\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+\r
+ Link = GetFirstNode (&gCurrentSelection->FormSet->FormListHead);\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ return Form->FormId;\r
+}\r
+\r
+/**\r
+ Search Menu with given FormSetGuid and FormId in all cached menu list.\r
+\r
+ @param HiiHandle HiiHandle for FormSet.\r
+ @param FormSetGuid The Formset GUID of the menu to search.\r
+ @param FormId The Form ID of menu to search.\r
+\r
+ @return A pointer to menu found or NULL if not found.\r
+\r
+**/\r
+FORM_ENTRY_INFO *\r
+UiFindMenuList (\r
+ IN EFI_HII_HANDLE HiiHandle, \r
+ IN EFI_GUID *FormSetGuid,\r
+ IN UINT16 FormId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_ENTRY_INFO *MenuList;\r
+ FORM_ENTRY_INFO *RetMenu;\r
+ EFI_FORM_ID FirstFormId;\r
+\r
+ RetMenu = NULL;\r
+\r
+ Link = GetFirstNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
+ while (!IsNull (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);\r
+ Link = GetNextNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link);\r
+ \r
+ //\r
+ // If already find the menu, free the menus behind it.\r
+ //\r
+ if (RetMenu != NULL) {\r
+ RemoveEntryList (&MenuList->Link);\r
+ FreePool (MenuList);\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Find the same FromSet.\r
+ //\r
+ if (MenuList->HiiHandle == HiiHandle) {\r
+ if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {\r
+ //\r
+ // FormSetGuid is not specified.\r
+ //\r
+ RetMenu = MenuList;\r
+ } else if (CompareGuid (&MenuList->FormSetGuid, FormSetGuid)) {\r
+ if (MenuList->FormId == FormId) {\r
+ RetMenu = MenuList;\r
+ } else if (FormId == 0 || MenuList->FormId == 0 ) {\r
+ FirstFormId = GetFirstFormId (HiiHandle, FormSetGuid);\r
+ if ((FormId == 0 && FirstFormId == MenuList->FormId) || (MenuList->FormId ==0 && FirstFormId == FormId)) {\r
+ RetMenu = MenuList;\r
+ }\r
+ }\r
}\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
+ }\r
+ }\r
+\r
+ return RetMenu;\r
+}\r
+\r
+/**\r
+ Find parent menu for current menu.\r
+\r
+ @param CurrentMenu Current Menu\r
+\r
+ @retval The parent menu for current menu.\r
+**/\r
+FORM_ENTRY_INFO *\r
+UiFindParentMenu (\r
+ IN FORM_ENTRY_INFO *CurrentMenu\r
+ )\r
+{\r
+ FORM_ENTRY_INFO *ParentMenu;\r
+\r
+ ParentMenu = NULL;\r
+ if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
+ ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);\r
+ }\r
+\r
+ return ParentMenu;\r
+}\r
+\r
+/**\r
+ Free Menu list linked list.\r
+\r
+ @param MenuListHead One Menu list point in the menu list.\r
+\r
+**/\r
+VOID\r
+UiFreeMenuList (\r
+ LIST_ENTRY *MenuListHead\r
+ )\r
+{\r
+ FORM_ENTRY_INFO *MenuList;\r
+\r
+ while (!IsListEmpty (MenuListHead)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (MenuListHead->ForwardLink);\r
+ RemoveEntryList (&MenuList->Link);\r
+\r
+ FreePool (MenuList);\r
+ }\r
+}\r
+\r
+/**\r
+ Load all hii formset to the browser.\r
+\r
+**/\r
+VOID\r
+LoadAllHiiFormset (\r
+ VOID\r
+ )\r
+{\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ UINTN Index;\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
- // Device Manager\r
+ // Get all the Hii handles\r
//\r
- {\r
- {\r
- 0x3ebfa8e6,\r
- 0x511d,\r
- 0x4b5b,\r
- {\r
- 0xa9,\r
- 0x5f,\r
- 0xfb,\r
- 0x38,\r
- 0x26,\r
- 0xf,\r
- 0x1c,\r
- 0x27\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ ASSERT (HiiHandles != NULL);\r
+\r
//\r
- // BMM FormSet.\r
+ // Search for formset of each class type\r
//\r
- {\r
- {\r
- 0x642237c7,\r
- 0x35d4,\r
- 0x472d,\r
- {\r
- 0x83,\r
- 0x65,\r
- 0x12,\r
- 0xe0,\r
- 0xcc,\r
- 0xf2,\r
- 0x7a,\r
- 0x22\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+ //\r
+ // Check HiiHandles[Index] does exist in global maintain list.\r
+ //\r
+ if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Initilize FormSet Setting\r
+ //\r
+ LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
+ ASSERT (LocalFormSet != NULL);\r
+ mSystemLevelFormSet = LocalFormSet;\r
+\r
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
+ Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);\r
+ if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
+ DestroyFormSet (LocalFormSet);\r
+ continue;\r
+ }\r
+ InitializeCurrentSetting (LocalFormSet);\r
+\r
+ //\r
+ // Initilize Questions' Value\r
+ //\r
+ Status = LoadFormSetConfig (NULL, LocalFormSet);\r
+ if (EFI_ERROR (Status)) {\r
+ DestroyFormSet (LocalFormSet);\r
+ continue;\r
+ }\r
+ }\r
+\r
//\r
- // BMM File Explorer FormSet.\r
+ // Free resources, and restore gOldFormSet and gClassOfVfr\r
//\r
- {\r
- {\r
- 0x1f2d63e1,\r
- 0xfebd,\r
- 0x4dc7,\r
- {\r
- 0x9c,\r
- 0xc5,\r
- 0xba,\r
- 0x2b,\r
- 0x1c,\r
- 0xef,\r
- 0x9c,\r
- 0x5b\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
-};\r
+ FreePool (HiiHandles);\r
+\r
+ gFinishRetrieveCall = OldRetrieveValue;\r
+ mSystemLevelFormSet = OldFormset;\r
+}\r
\r
/**\r
This is the routine which an external caller uses to direct the browser\r
UI_MENU_SELECTION *Selection;\r
UINTN Index;\r
FORM_BROWSER_FORMSET *FormSet;\r
- LIST_ENTRY *Link;\r
+ FORM_ENTRY_INFO *MenuList;\r
\r
//\r
- // Calculate total number of Register HotKeys. \r
+ // If EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found, return EFI_UNSUPPORTED.\r
//\r
- Index = 0;\r
- Link = GetFirstNode (&gBrowserHotKeyList);\r
- while (!IsNull (&gBrowserHotKeyList, Link)) {\r
- Link = GetNextNode (&gBrowserHotKeyList, Link);\r
- Index ++;\r
+ if (mFormDisplay == NULL) {\r
+ return EFI_UNSUPPORTED;\r
}\r
- //\r
- // Show three HotKeys help information on one ROW.\r
- //\r
- gFooterHeight = FOOTER_HEIGHT + (Index / 3);\r
-\r
- //\r
- // Clean the history menu list.\r
- //\r
- InitializeListHead (&gMenuList);\r
\r
//\r
// Save globals used by SendForm()\r
//\r
SaveBrowserContext ();\r
\r
+ gFinishRetrieveCall = FALSE;\r
gResetRequired = FALSE;\r
- Status = EFI_SUCCESS;\r
- ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-\r
- //\r
- // Seed the dimensions in the global\r
- //\r
- gST->ConOut->QueryMode (\r
- gST->ConOut,\r
- gST->ConOut->Mode->Mode,\r
- &gScreenDimensions.RightColumn,\r
- &gScreenDimensions.BottomRow\r
- );\r
-\r
- if (ScreenDimensions != NULL) {\r
- //\r
- // Check local dimension vs. global dimension.\r
- //\r
- if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||\r
- (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)\r
- ) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- } else {\r
- //\r
- // Local dimension validation.\r
- //\r
- if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&\r
- (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&\r
- ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&\r
- (\r
- (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
- SCROLL_ARROW_HEIGHT *\r
- 2 +\r
- FRONT_PAGE_HEADER_HEIGHT +\r
- gFooterHeight +\r
- 1\r
- )\r
- ) {\r
- CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
- } else {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
- gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
- gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);\r
- gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);\r
-\r
- //\r
- // Initialize the strings for the browser, upon exit of the browser, the strings will be freed\r
- //\r
- InitializeBrowserStrings ();\r
-\r
- //\r
- // Ensure we are in Text mode\r
- //\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+ gExitRequired = FALSE;\r
+ Status = EFI_SUCCESS;\r
+ gEmptyString = L"";\r
+ gDisplayFormData.ScreenDimensions = (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions;\r
\r
for (Index = 0; Index < HandleCount; Index++) {\r
Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));\r
//\r
// Initialize internal data structures of FormSet\r
//\r
- Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet, TRUE);\r
+ Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);\r
if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {\r
DestroyFormSet (FormSet);\r
break;\r
}\r
Selection->FormSet = FormSet;\r
-\r
- //\r
- // Try to find pre FormSet in the maintain backup list.\r
- //\r
- gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle);\r
+ mSystemLevelFormSet = FormSet;\r
\r
//\r
// Display this formset\r
Status = SetupBrowser (Selection);\r
\r
gCurrentSelection = NULL;\r
+ mSystemLevelFormSet = NULL;\r
\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);\r
-\r
- if (gOldFormSet != NULL) {\r
//\r
// If no data is changed, don't need to save current FormSet into the maintain list.\r
//\r
- if (!IsNvUpdateRequired (gOldFormSet)) {\r
- RemoveEntryList (&gOldFormSet->Link);\r
- DestroyFormSet (gOldFormSet);\r
+ if (!IsNvUpdateRequiredForFormSet (FormSet) && !IsStorageDataChangedForFormSet(FormSet)) {\r
+ CleanBrowserStorage(FormSet);\r
+ RemoveEntryList (&FormSet->Link);\r
+ DestroyFormSet (FormSet);\r
}\r
- gOldFormSet = NULL;\r
- }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ } while (Selection->Action == UI_ACTION_REFRESH_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
}\r
}\r
\r
- FreeBrowserStrings ();\r
- UiFreeMenuList(&gMenuList);\r
+ mFormDisplay->ExitDisplay();\r
\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
+ //\r
+ // Clear the menu history data.\r
+ //\r
+ while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
+ RemoveEntryList (&MenuList->Link);\r
+ FreePool (MenuList);\r
+ }\r
\r
-Done:\r
//\r
// Restore globals used by SendForm()\r
//\r
return Status;\r
}\r
\r
+/**\r
+ Get or set data to the storage.\r
+\r
+ @param ResultsDataSize The size of the buffer associatedwith ResultsData.\r
+ @param ResultsData A string returned from an IFR browser or\r
+ equivalent. The results string will have no\r
+ routing information in them.\r
+ @param RetrieveData A BOOLEAN field which allows an agent to retrieve\r
+ (if RetrieveData = TRUE) data from the uncommitted\r
+ browser state information or set (if RetrieveData\r
+ = FALSE) data in the uncommitted browser state\r
+ information.\r
+ @param Storage The pointer to the storage.\r
+\r
+ @retval EFI_SUCCESS The results have been distributed or are awaiting\r
+ distribution.\r
+\r
+**/\r
+EFI_STATUS \r
+ProcessStorage (\r
+ IN OUT UINTN *ResultsDataSize,\r
+ IN OUT EFI_STRING *ResultsData,\r
+ IN BOOLEAN RetrieveData,\r
+ IN BROWSER_STORAGE *Storage\r
+ )\r
+{\r
+ CHAR16 *ConfigResp;\r
+ EFI_STATUS Status;\r
+ CHAR16 *StrPtr;\r
+ UINTN BufferSize;\r
+ UINTN TmpSize;\r
+\r
+ if (RetrieveData) {\r
+ //\r
+ // Generate <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (Storage, &ConfigResp, Storage->ConfigRequest, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Skip <ConfigHdr> and '&' to point to <ConfigBody> when first copy the configbody.\r
+ // Also need to consider add "\0" at first time.\r
+ //\r
+ StrPtr = ConfigResp + StrLen (Storage->ConfigHdr) + 1;\r
+ BufferSize = StrSize (StrPtr);\r
+\r
+\r
+ //\r
+ // Copy the data if the input buffer is bigger enough.\r
+ //\r
+ if (*ResultsDataSize >= BufferSize) {\r
+ StrCpy (*ResultsData, StrPtr);\r
+ }\r
+\r
+ *ResultsDataSize = BufferSize;\r
+ FreePool (ConfigResp);\r
+ } else {\r
+ //\r
+ // Prepare <ConfigResp>\r
+ //\r
+ TmpSize = StrLen (*ResultsData);\r
+ BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);\r
+ ConfigResp = AllocateZeroPool (BufferSize);\r
+ ASSERT (ConfigResp != NULL);\r
+\r
+ StrCpy (ConfigResp, Storage->ConfigHdr);\r
+ StrCat (ConfigResp, L"&");\r
+ StrCat (ConfigResp, *ResultsData);\r
+\r
+ //\r
+ // Update Browser uncommited data\r
+ //\r
+ Status = ConfigRespToStorage (Storage, ConfigResp);\r
+ FreePool (ConfigResp);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
\r
/**\r
- This function is called by a callback handler to retrieve uncommitted state\r
- data from the browser.\r
+ This routine called this service in the browser to retrieve or set certain uncommitted \r
+ state information that resides in the open formsets. \r
\r
@param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL\r
instance.\r
{\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
- FORMSET_STORAGE *Storage;\r
- FORM_BROWSER_FORMSET *FormSet;\r
+ BROWSER_STORAGE *Storage;\r
+ FORMSET_STORAGE *FormsetStorage;\r
+ UINTN TotalSize;\r
BOOLEAN Found;\r
- CHAR16 *ConfigResp;\r
- CHAR16 *StrPtr;\r
- UINTN BufferSize;\r
- UINTN TmpSize;\r
\r
if (ResultsDataSize == NULL || ResultsData == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (gCurrentSelection == NULL) {\r
- return EFI_NOT_READY;\r
- }\r
-\r
- Storage = NULL;\r
- ConfigResp = NULL;\r
- FormSet = gCurrentSelection->FormSet;\r
+ TotalSize = *ResultsDataSize;\r
+ Storage = NULL;\r
+ Found = FALSE;\r
+ Status = EFI_SUCCESS;\r
\r
//\r
- // Find target storage\r
+ // If set browser data, pre load all hii formset to avoid set the varstore which is not \r
+ // saved in browser.\r
//\r
- Link = GetFirstNode (&FormSet->StorageListHead);\r
- if (IsNull (&FormSet->StorageListHead, Link)) {\r
- return EFI_UNSUPPORTED;\r
+ if (!RetrieveData && (gBrowserSettingScope == SystemLevel)) {\r
+ LoadAllHiiFormset();\r
}\r
\r
if (VariableGuid != NULL) {\r
//\r
- // Try to find target storage\r
+ // Try to find target storage in the current formset.\r
//\r
- Found = FALSE;\r
- while (!IsNull (&FormSet->StorageListHead, Link)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
- Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+ Link = GetFirstNode (&gBrowserStorageList);\r
+ while (!IsNull (&gBrowserStorageList, Link)) {\r
+ Storage = BROWSER_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&gBrowserStorageList, Link);\r
+ //\r
+ // Check the current storage.\r
+ //\r
+ if (!CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {\r
+ continue;\r
+ }\r
\r
- if (CompareGuid (&Storage->BrowserStorage->Guid, (EFI_GUID *) VariableGuid)) {\r
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
- Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- //\r
- // Buffer storage require both GUID and Name\r
- //\r
- if (VariableName == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||\r
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ //\r
+ // Buffer storage require both GUID and Name\r
+ //\r
+ if (VariableName == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- if (StrCmp (Storage->BrowserStorage->Name, (CHAR16 *) VariableName) != 0) {\r
- continue;\r
- }\r
+ if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE ||\r
+ Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+ if (mSystemLevelFormSet == NULL || mSystemLevelFormSet->HiiHandle == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (Storage->HiiHandle != mSystemLevelFormSet->HiiHandle) {\r
+ continue;\r
}\r
- Found = TRUE;\r
- break;\r
}\r
+\r
+ Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Different formsets may have same varstore, so here just set the flag\r
+ // not exit the circle.\r
+ // \r
+ Found = TRUE;\r
+ break;\r
}\r
\r
if (!Found) {\r
//\r
// GUID/Name is not specified, take the first storage in FormSet\r
//\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
- }\r
-\r
- if (RetrieveData) {\r
- //\r
- // Skip if there is no RequestElement\r
- //\r
- if (Storage->ElementCount == 0) {\r
- return EFI_SUCCESS;\r
+ if (mSystemLevelFormSet == NULL) {\r
+ return EFI_NOT_READY;\r
}\r
\r
//\r
// Generate <ConfigResp>\r
//\r
- Status = StorageToConfigResp (Storage->BrowserStorage, &ConfigResp, Storage->ConfigRequest);\r
+ Link = GetFirstNode (&mSystemLevelFormSet->StorageListHead);\r
+ if (IsNull (&mSystemLevelFormSet->StorageListHead, Link)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ \r
+ Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, FormsetStorage->BrowserStorage);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ }\r
\r
- //\r
- // Skip <ConfigHdr> and '&' to point to <ConfigBody>\r
- //\r
- StrPtr = ConfigResp + StrLen (Storage->BrowserStorage->ConfigHdr) + 1;\r
+ if (RetrieveData) {\r
+ Status = TotalSize <= *ResultsDataSize ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
+ *ResultsDataSize = TotalSize;\r
+ }\r
+ \r
+ return Status;\r
\r
- BufferSize = StrSize (StrPtr);\r
- if (*ResultsDataSize < BufferSize) {\r
- *ResultsDataSize = BufferSize;\r
+}\r
\r
- FreePool (ConfigResp);\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
\r
- *ResultsDataSize = BufferSize;\r
- CopyMem (ResultsData, StrPtr, BufferSize);\r
+/**\r
+ Callback function for SimpleTextInEx protocol install events\r
\r
- FreePool (ConfigResp);\r
- } else {\r
- //\r
- // Prepare <ConfigResp>\r
- //\r
- TmpSize = StrLen (ResultsData);\r
- BufferSize = (TmpSize + StrLen (Storage->BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);\r
- ConfigResp = AllocateZeroPool (BufferSize);\r
- ASSERT (ConfigResp != NULL);\r
+ @param Event the event that is signaled.\r
+ @param Context not used here.\r
\r
- StrCpy (ConfigResp, Storage->BrowserStorage->ConfigHdr);\r
- StrCat (ConfigResp, L"&");\r
- StrCat (ConfigResp, ResultsData);\r
+**/\r
+VOID\r
+EFIAPI\r
+FormDisplayCallback (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
\r
- //\r
- // Update Browser uncommited data\r
- //\r
- Status = ConfigRespToStorage (Storage->BrowserStorage, ConfigResp);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ if (mFormDisplay != NULL) {\r
+ return;\r
}\r
\r
- return EFI_SUCCESS;\r
+ Status = gBS->LocateProtocol (\r
+ &gEdkiiFormDisplayEngineProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mFormDisplay\r
+ );\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_INPUT_KEY DefaultHotKey;\r
- EFI_STRING HelpString;\r
+ VOID *Registration;\r
\r
//\r
// Locate required Hii relative protocols\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = gBS->LocateProtocol (\r
- &gEfiHiiStringProtocolGuid,\r
- NULL,\r
- (VOID **) &mHiiString\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
Status = gBS->LocateProtocol (\r
&gEfiHiiConfigRoutingProtocolGuid,\r
NULL,\r
(VOID **) &mPathFromText\r
);\r
\r
- //\r
- // Publish our HII data\r
- //\r
- gHiiHandle = HiiAddPackages (\r
- &gSetupBrowserGuid,\r
- ImageHandle,\r
- SetupBrowserStrings,\r
- NULL\r
- );\r
- ASSERT (gHiiHandle != NULL);\r
-\r
- //\r
- // Initialize Driver private data\r
- //\r
- gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
- ASSERT (gBannerData != NULL);\r
- \r
- //\r
- // Initialize generic help strings.\r
- //\r
- gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
- gDiscardFailed = GetToken (STRING_TOKEN (DISCARD_FAILED), gHiiHandle);\r
- gDefaultFailed = GetToken (STRING_TOKEN (DEFAULT_FAILED), gHiiHandle);\r
-\r
//\r
// Install FormBrowser2 protocol\r
//\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
- // Install default HotKey F10 for Save\r
- //\r
- DefaultHotKey.UnicodeChar = CHAR_NULL;\r
- HelpString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);\r
- DefaultHotKey.ScanCode = SCAN_F10;\r
- RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_SUBMIT, 0, HelpString);\r
- FreePool (HelpString);\r
- //\r
- // Install default HotKey F9 for Reset To Defaults\r
- //\r
- DefaultHotKey.ScanCode = SCAN_F9;\r
- HelpString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);\r
- RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, HelpString);\r
- FreePool (HelpString);\r
-\r
- //\r
- // Install FormBrowserEx protocol\r
+ // Install FormBrowserEx2 protocol\r
//\r
+ InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
+ InitializeListHead (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
mPrivateData.Handle = NULL;\r
+ Status = gBS->InstallProtocolInterface (\r
+ &mPrivateData.Handle,\r
+ &gEdkiiFormBrowserEx2ProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mPrivateData.FormBrowserEx2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
Status = gBS->InstallProtocolInterface (\r
&mPrivateData.Handle,\r
&gEfiFormBrowserExProtocolGuid,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- return Status;\r
+ InitializeDisplayFormData ();\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gEdkiiFormDisplayEngineProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mFormDisplay\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ EfiCreateProtocolNotifyEvent (\r
+ &gEdkiiFormDisplayEngineProtocolGuid,\r
+ TPL_CALLBACK,\r
+ FormDisplayCallback,\r
+ NULL,\r
+ &Registration\r
+ );\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
}\r
\r
\r
return;\r
}\r
\r
- TmpSize = StrSize (*Dest);\r
- NewString = AllocateZeroPool (TmpSize + StrSize (Src) - 1);\r
- ASSERT (NewString != NULL);\r
-\r
- StrCpy (NewString, *Dest);\r
- StrCat (NewString, Src);\r
-\r
- FreePool (*Dest);\r
- *Dest = NewString;\r
-}\r
-\r
-\r
-/**\r
- Synchronize or restore Storage's Edit copy and Shadow copy.\r
-\r
- @param Storage The Storage to be synchronized.\r
- @param SyncOrRestore Sync the buffer to editbuffer or Restore the \r
- editbuffer to buffer\r
- if TRUE, copy the editbuffer to the buffer.\r
- if FALSE, copy the buffer to the editbuffer.\r
-\r
-**/\r
-VOID\r
-SynchronizeStorage (\r
- IN BROWSER_STORAGE *Storage,\r
- IN BOOLEAN SyncOrRestore\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- NAME_VALUE_NODE *Node;\r
-\r
- switch (Storage->Type) {\r
- case EFI_HII_VARSTORE_BUFFER:\r
- case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
- if (SyncOrRestore) {\r
- CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);\r
- } else {\r
- CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);\r
- }\r
- break;\r
-\r
- case EFI_HII_VARSTORE_NAME_VALUE:\r
- Link = GetFirstNode (&Storage->NameValueListHead);\r
- while (!IsNull (&Storage->NameValueListHead, Link)) {\r
- Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-\r
- if (SyncOrRestore) {\r
- NewStringCpy (&Node->Value, Node->EditValue);\r
- } else {\r
- NewStringCpy (&Node->EditValue, Node->Value);\r
- }\r
-\r
- Link = GetNextNode (&Storage->NameValueListHead, Link);\r
- }\r
- break;\r
+ TmpSize = StrSize (*Dest);\r
+ NewString = AllocateZeroPool (TmpSize + StrSize (Src) - 1);\r
+ ASSERT (NewString != NULL);\r
\r
- case EFI_HII_VARSTORE_EFI_VARIABLE:\r
- default:\r
- break;\r
- }\r
-}\r
+ StrCpy (NewString, *Dest);\r
+ StrCat (NewString, Src);\r
\r
+ FreePool (*Dest);\r
+ *Dest = NewString;\r
+}\r
\r
/**\r
Get Value for given Name from a NameValue Storage.\r
@param Name The Name.\r
@param Value The Value to set.\r
@param SetValueTo Whether update editValue or Value.\r
+ @param ReturnNode The node use the input name.\r
\r
@retval EFI_SUCCESS Value found for given Name.\r
@retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
**/\r
EFI_STATUS\r
SetValueByName (\r
- IN BROWSER_STORAGE *Storage,\r
- IN CHAR16 *Name,\r
- IN CHAR16 *Value,\r
- IN GET_SET_QUESTION_VALUE_WITH SetValueTo\r
+ IN BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *Name,\r
+ IN CHAR16 *Value,\r
+ IN GET_SET_QUESTION_VALUE_WITH SetValueTo,\r
+ OUT NAME_VALUE_NODE **ReturnNode\r
)\r
{\r
LIST_ENTRY *Link;\r
} else {\r
Node->Value = Buffer;\r
}\r
+\r
+ if (ReturnNode != NULL) {\r
+ *ReturnNode = Node;\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r
\r
@param Storage The Storage to be conveted.\r
@param ConfigResp The returned <ConfigResp>.\r
@param ConfigRequest The ConfigRequest string.\r
+ @param GetEditBuf Get the data from editbuffer or buffer.\r
\r
@retval EFI_SUCCESS Convert success.\r
@retval EFI_INVALID_PARAMETER Incorrect storage type.\r
StorageToConfigResp (\r
IN BROWSER_STORAGE *Storage,\r
IN CHAR16 **ConfigResp,\r
- IN CHAR16 *ConfigRequest\r
+ IN CHAR16 *ConfigRequest,\r
+ IN BOOLEAN GetEditBuf\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STRING Progress;\r
LIST_ENTRY *Link;\r
NAME_VALUE_NODE *Node;\r
+ UINT8 *SourceBuf;\r
\r
Status = EFI_SUCCESS;\r
\r
switch (Storage->Type) {\r
case EFI_HII_VARSTORE_BUFFER:\r
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
+ SourceBuf = GetEditBuf ? Storage->EditBuffer : Storage->Buffer;\r
Status = mHiiConfigRouting->BlockToConfig (\r
mHiiConfigRouting,\r
ConfigRequest,\r
- Storage->EditBuffer,\r
+ SourceBuf,\r
Storage->Size,\r
ConfigResp,\r
&Progress\r
NewStringCat (ConfigResp, L"&");\r
NewStringCat (ConfigResp, Node->Name);\r
NewStringCat (ConfigResp, L"=");\r
- NewStringCat (ConfigResp, Node->EditValue);\r
+ if (GetEditBuf) {\r
+ NewStringCat (ConfigResp, Node->EditValue);\r
+ } else {\r
+ NewStringCat (ConfigResp, Node->Value);\r
+ }\r
}\r
Link = GetNextNode (&Storage->NameValueListHead, Link);\r
}\r
if (StrPtr != NULL) {\r
*StrPtr = 0;\r
}\r
- SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer);\r
+ SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer, NULL);\r
}\r
break;\r
\r
BOOLEAN IsString;\r
CHAR16 TemStr[5];\r
UINT8 DigitUint8;\r
- UINT8 *TemBuffer;\r
\r
Status = EFI_SUCCESS;\r
Value = NULL;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- //\r
- // Statement don't have storage, skip them\r
- //\r
- if (Question->QuestionId == 0) {\r
- return Status;\r
- }\r
-\r
//\r
// Question value is provided by an Expression, evaluate it\r
//\r
FreePool (Value);\r
}\r
} else {\r
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
- //\r
- // Request current settings from Configuration Driver\r
- //\r
- if (FormSet->ConfigAccess == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\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
+ // <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
+ 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
- FreePool (ConfigRequest);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ //\r
+ // Request current settings from Configuration Driver\r
+ //\r
+ Status = mHiiConfigRouting->ExtractConfig (\r
+ mHiiConfigRouting,\r
+ ConfigRequest,\r
+ &Progress,\r
+ &Result\r
+ );\r
+ FreePool (ConfigRequest);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- //\r
- // Skip <ConfigRequest>\r
- //\r
- if (IsBufferStorage) {\r
- Value = StrStr (Result, L"&VALUE");\r
- if (Value == NULL) {\r
- FreePool (Result);\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Skip "&VALUE"\r
- //\r
- Value = Value + 6;\r
- } else {\r
- Value = Result + Length;\r
- }\r
- if (*Value != '=') {\r
+ //\r
+ // Skip <ConfigRequest>\r
+ //\r
+ if (IsBufferStorage) {\r
+ Value = StrStr (Result, L"&VALUE");\r
+ if (Value == NULL) {\r
FreePool (Result);\r
return EFI_NOT_FOUND;\r
}\r
//\r
- // Skip '=', point to value\r
+ // Skip "&VALUE"\r
//\r
- Value = Value + 1;\r
+ Value = Value + 6;\r
+ } else {\r
+ Value = Result + Length;\r
+ }\r
+ if (*Value != '=') {\r
+ FreePool (Result);\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
+ //\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
- // Suppress <AltResp> if any\r
+ // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
+ // Add string tail char L'\0' into Length\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
+ 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
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
- // Add string tail char L'\0' into Length\r
+ // Add tailing L'\0' character\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
+ StringPtr[Index/4] = L'\0';\r
+ }\r
+ } else {\r
+ if (StorageWidth < ((LengthStr + 1) / 2)) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\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
+ 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
- if (EFI_ERROR (Status)) {\r
- FreePool (Result);\r
- return Status;\r
- }\r
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- TemBuffer = NULL;\r
- TemBuffer = AllocateZeroPool (Storage->Size);\r
- if (TemBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- return Status;\r
- }\r
- Length = Storage->Size;\r
- Status = gRT->GetVariable (\r
- Storage->Name,\r
- &Storage->Guid,\r
- NULL,\r
- &Length,\r
- TemBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreePool (TemBuffer);\r
- return Status;\r
- }\r
-\r
- CopyMem (Dst, TemBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
-\r
- FreePool (TemBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (Result);\r
+ return Status;\r
}\r
\r
//\r
if (IsBufferStorage) {\r
CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
} else {\r
- SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer);\r
+ SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer, NULL);\r
}\r
\r
if (Result != NULL) {\r
CHAR16 *TemName;\r
CHAR16 *TemString;\r
UINTN Index;\r
+ NAME_VALUE_NODE *Node;\r
\r
Status = EFI_SUCCESS;\r
+ Node = NULL;\r
\r
if (SetValueTo >= GetSetValueWithMax) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- //\r
- // Statement don't have storage, skip them\r
- //\r
- if (Question->QuestionId == 0) {\r
- return Status;\r
- }\r
-\r
//\r
// If Question value is provided by an Expression, then it is read only\r
//\r
// \r
CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
}\r
+ //\r
+ // Check whether question value has been changed.\r
+ //\r
+ if (CompareMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth) != 0) {\r
+ Question->ValueChanged = TRUE;\r
+ } else {\r
+ Question->ValueChanged = FALSE;\r
+ }\r
} else {\r
if (IsString) {\r
//\r
}\r
}\r
\r
- Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo);\r
+ Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo, &Node);\r
FreePool (Value);\r
- }\r
- } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
//\r
- // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
- // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
+ // Check whether question value has been changed.\r
//\r
- if (IsBufferStorage) {\r
- Length = StrLen (Question->BlockName) + 7;\r
- } else {\r
- Length = StrLen (Question->VariableName) + 2;\r
- }\r
- if (!IsBufferStorage && IsString) {\r
- Length += (StrLen ((CHAR16 *) Src) * 4);\r
- } else {\r
- Length += (StorageWidth * 2);\r
- }\r
- ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));\r
- ASSERT (ConfigResp != NULL);\r
-\r
- StrCpy (ConfigResp, Storage->ConfigHdr);\r
- if (IsBufferStorage) {\r
- StrCat (ConfigResp, Question->BlockName);\r
- StrCat (ConfigResp, L"&VALUE=");\r
+ if (StrCmp (Node->Value, Node->EditValue) != 0) {\r
+ Question->ValueChanged = TRUE;\r
} else {\r
- StrCat (ConfigResp, L"&");\r
- StrCat (ConfigResp, Question->VariableName);\r
- StrCat (ConfigResp, L"=");\r
+ Question->ValueChanged = FALSE;\r
}\r
+ }\r
+ } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
+ //\r
+ // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
+ // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
+ //\r
+ if (IsBufferStorage) {\r
+ Length = StrLen (Question->BlockName) + 7;\r
+ } else {\r
+ Length = StrLen (Question->VariableName) + 2;\r
+ }\r
+ if (!IsBufferStorage && IsString) {\r
+ Length += (StrLen ((CHAR16 *) Src) * 4);\r
+ } else {\r
+ Length += (StorageWidth * 2);\r
+ }\r
+ ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));\r
+ ASSERT (ConfigResp != NULL);\r
\r
- Value = ConfigResp + StrLen (ConfigResp);\r
+ StrCpy (ConfigResp, Storage->ConfigHdr);\r
+ if (IsBufferStorage) {\r
+ StrCat (ConfigResp, Question->BlockName);\r
+ StrCat (ConfigResp, L"&VALUE=");\r
+ } else {\r
+ StrCat (ConfigResp, L"&");\r
+ StrCat (ConfigResp, Question->VariableName);\r
+ StrCat (ConfigResp, L"=");\r
+ }\r
\r
- if (!IsBufferStorage && IsString) {\r
- //\r
- // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
- //\r
- TemName = (CHAR16 *) Src;\r
- TemString = Value;\r
- for (; *TemName != L'\0'; TemName++) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
- }\r
- } else {\r
- //\r
- // Convert Buffer to Hex String\r
- //\r
- TemBuffer = Src + StorageWidth - 1;\r
- TemString = Value;\r
- for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
- }\r
- }\r
+ Value = ConfigResp + StrLen (ConfigResp);\r
\r
+ if (!IsBufferStorage && IsString) {\r
//\r
- // Convert to lower char.\r
+ // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
//\r
- for (TemString = Value; *Value != L'\0'; Value++) {\r
- if (*Value >= L'A' && *Value <= L'Z') {\r
- *Value = (CHAR16) (*Value - L'A' + L'a');\r
- }\r
+ TemName = (CHAR16 *) Src;\r
+ TemString = Value;\r
+ for (; *TemName != L'\0'; TemName++) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
}\r
-\r
+ } else {\r
//\r
- // Submit Question Value to Configuration Driver\r
+ // Convert Buffer to Hex String\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
- FreePool (ConfigResp);\r
- \r
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- TemBuffer = NULL;\r
- TemBuffer = AllocateZeroPool(Storage->Size);\r
- if (TemBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- return Status;\r
+ TemBuffer = Src + StorageWidth - 1;\r
+ TemString = Value;\r
+ for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
}\r
- Length = Storage->Size;\r
- Status = gRT->GetVariable (\r
- Storage->Name,\r
- &Storage->Guid,\r
- NULL,\r
- &Length,\r
- TemBuffer\r
- );\r
-\r
- CopyMem (TemBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
- \r
- Status = gRT->SetVariable (\r
- Storage->Name,\r
- &Storage->Guid,\r
- Storage->Attributes,\r
- Storage->Size,\r
- TemBuffer\r
- );\r
- FreePool (TemBuffer);\r
- if (EFI_ERROR (Status)){\r
- return Status;\r
+ }\r
+\r
+ //\r
+ // Convert to lower char.\r
+ //\r
+ for (TemString = Value; *Value != L'\0'; Value++) {\r
+ if (*Value >= L'A' && *Value <= L'Z') {\r
+ *Value = (CHAR16) (*Value - L'A' + L'a');\r
}\r
}\r
+\r
+ //\r
+ // Submit Question Value to Configuration Driver\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
+ FreePool (ConfigResp);\r
+ \r
//\r
// Sync storage, from editbuffer to buffer.\r
//\r
\r
\r
/**\r
- Perform inconsistent check for a Form.\r
+ Perform nosubmitif check for a Form.\r
\r
@param FormSet FormSet data structure.\r
@param Form Form data structure.\r
@param Question The Question to be validated.\r
- @param Type Validation type: InConsistent or NoSubmit\r
+ @param Type Validation type: NoSubmit\r
\r
@retval EFI_SUCCESS Form validation pass.\r
@retval other Form validation failed.\r
LIST_ENTRY *Link;\r
LIST_ENTRY *ListHead;\r
EFI_STRING PopUp;\r
- EFI_INPUT_KEY Key;\r
FORM_EXPRESSION *Expression;\r
\r
- if (Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) {\r
- ListHead = &Question->InconsistentListHead;\r
- } else if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+ if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
ListHead = &Question->NoSubmitListHead;\r
} else {\r
return EFI_UNSUPPORTED;\r
//\r
if (Expression->Error != 0) {\r
PopUp = GetToken (Expression->Error, FormSet->HiiHandle);\r
- do {\r
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, PopUp, gPressEnter, gEmptyString);\r
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
- FreePool (PopUp);\r
+ if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+ gBrowserStatus = BROWSER_NO_SUBMIT_IF;\r
+ gErrorInfo = PopUp;\r
+ }\r
}\r
\r
return EFI_NOT_READY;\r
Fill storage's edit copy with settings requested from Configuration Driver.\r
\r
@param FormSet FormSet data structure.\r
- @param ConfigInfo The config info related to this form.\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
editbuffer to buffer\r
if TRUE, copy the editbuffer to the buffer.\r
\r
**/\r
EFI_STATUS\r
-SynchronizeStorageForForm (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,\r
- IN BOOLEAN SyncOrRestore\r
+SynchronizeStorage (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ OUT BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *ConfigRequest,\r
+ IN BOOLEAN SyncOrRestore\r
)\r
{\r
EFI_STATUS Status;\r
\r
Status = EFI_SUCCESS;\r
Result = NULL;\r
- if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {\r
- return EFI_NOT_FOUND;\r
- }\r
\r
- if (ConfigInfo->ElementCount == 0) {\r
- //\r
- // Skip if there is no RequestElement\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
- (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
- BufferSize = ConfigInfo->Storage->Size;\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ BufferSize = Storage->Size;\r
\r
if (SyncOrRestore) {\r
- Src = ConfigInfo->Storage->EditBuffer;\r
- Dst = ConfigInfo->Storage->Buffer;\r
+ Src = Storage->EditBuffer;\r
+ Dst = Storage->Buffer;\r
} else {\r
- Src = ConfigInfo->Storage->Buffer;\r
- Dst = ConfigInfo->Storage->EditBuffer;\r
+ Src = Storage->Buffer;\r
+ Dst = Storage->EditBuffer;\r
}\r
\r
- Status = mHiiConfigRouting->BlockToConfig(\r
- mHiiConfigRouting,\r
- ConfigInfo->ConfigRequest,\r
- Src,\r
- BufferSize,\r
- &Result,\r
- &Progress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ if (ConfigRequest != NULL) {\r
+ Status = mHiiConfigRouting->BlockToConfig(\r
+ mHiiConfigRouting,\r
+ ConfigRequest,\r
+ Src,\r
+ BufferSize,\r
+ &Result,\r
+ &Progress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- Status = mHiiConfigRouting->ConfigToBlock (\r
- mHiiConfigRouting,\r
- Result,\r
- Dst,\r
- &BufferSize,\r
- &Progress\r
- );\r
- if (Result != NULL) {\r
- FreePool (Result);\r
+ Status = mHiiConfigRouting->ConfigToBlock (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ Dst,\r
+ &BufferSize,\r
+ &Progress\r
+ );\r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
+ } else {\r
+ CopyMem (Dst, Src, BufferSize);\r
}\r
- } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
- Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);\r
- while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {\r
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ Link = GetFirstNode (&Storage->NameValueListHead);\r
+ while (!IsNull (&Storage->NameValueListHead, Link)) {\r
Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
\r
- if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {\r
+ if ((ConfigRequest != NULL && StrStr (ConfigRequest, Node->Name) != NULL) ||\r
+ (ConfigRequest == NULL)) {\r
if (SyncOrRestore) {\r
NewStringCpy (&Node->Value, Node->EditValue);\r
} else {\r
}\r
}\r
\r
- Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);\r
+ Link = GetNextNode (&Storage->NameValueListHead, Link);\r
}\r
}\r
\r
{\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE HiiValue;\r
- UINT8 *BufferValue;\r
- BOOLEAN ValueChanged;\r
EFI_IFR_TYPE_VALUE *TypeValue;\r
EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
\r
- ValueChanged = FALSE;\r
- BufferValue = NULL;\r
-\r
- if(!Form->NvUpdateRequired) {\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->BufferValue != NULL) {\r
- BufferValue = AllocateZeroPool (Question->StorageWidth);\r
- ASSERT (BufferValue != NULL);\r
- CopyMem (BufferValue, Question->BufferValue, Question->StorageWidth);\r
- } else {\r
- HiiValue.Type = Question->HiiValue.Type;\r
- CopyMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
- }\r
-\r
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);\r
- if (EFI_ERROR (Status)) {\r
- if (BufferValue != NULL) {\r
- FreePool (BufferValue);\r
- BufferValue = NULL;\r
- }\r
- continue;\r
- }\r
-\r
- if (Question->BufferValue != NULL) {\r
- if (CompareMem (BufferValue, Question->BufferValue, Question->StorageWidth)) {\r
- ValueChanged = TRUE;\r
- }\r
- } else {\r
- if (CompareMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE))) {\r
- ValueChanged = TRUE;\r
- }\r
- }\r
-\r
- if (BufferValue != NULL) {\r
- FreePool (BufferValue);\r
- BufferValue = NULL;\r
- }\r
-\r
- if (!ValueChanged) {\r
+ if (!Question->ValueChanged) {\r
continue;\r
}\r
\r
- ValueChanged = FALSE;\r
-\r
if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;\r
} else {\r
}\r
\r
if (!Find) {\r
+ CleanBrowserStorage(FormSet);\r
RemoveEntryList (&FormSet->Link);\r
DestroyFormSet (FormSet);\r
}\r
\r
return Find;\r
}\r
+/**\r
+ Check whether need to enable the reset flag in form level.\r
+ Also clean all ValueChanged flag in question.\r
+\r
+ @param SetFlag Whether need to set the Reset Flag.\r
+ @param Form Form data structure.\r
+\r
+**/\r
+VOID\r
+UpdateFlagForForm (\r
+ IN BOOLEAN SetFlag,\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+ BOOLEAN FindOne;\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
+\r
+ if (Question->ValueChanged) {\r
+ Question->ValueChanged = FALSE;\r
+ }\r
+ \r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+ }\r
+}\r
+\r
+/**\r
+ Check whether need to enable the reset flag.\r
+ Also clean ValueChanged flag for all statements.\r
+\r
+ Form level or formset level, only one.\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
+ValueChangeResetFlagUpdate (\r
+ IN BOOLEAN SetFlag,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form \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
+ return;\r
+ }\r
+\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+\r
+ UpdateFlagForForm(SetFlag, CurrentForm);\r
+ }\r
+}\r
\r
/**\r
Discard data based on the input setting scope (Form, FormSet or System).\r
LIST_ENTRY *Link;\r
FORMSET_STORAGE *Storage;\r
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
- FORM_BROWSER_FORMSET *LocalFormSet;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+ FORM_BROWSER_FORMSET *OldFormSet;\r
\r
//\r
// Check the supported setting level.\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
+ if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {\r
ConfigInfo = NULL;\r
Link = GetFirstNode (&Form->ConfigRequestHead);\r
while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
//\r
// Prepare <ConfigResp>\r
//\r
- SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);\r
+ SynchronizeStorage(FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
\r
//\r
// Call callback with Changed type to inform the driver.\r
SendDiscardInfoToDriver (FormSet, Form);\r
}\r
\r
- Form->NvUpdateRequired = FALSE;\r
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
+ ValueChangeResetFlagUpdate (FALSE, NULL, Form);\r
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
\r
//\r
// Discard Buffer storage or Name/Value storage\r
continue;\r
}\r
\r
- SynchronizeStorage(Storage->BrowserStorage, FALSE);\r
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
}\r
\r
Link = GetFirstNode (&FormSet->FormListHead);\r
SendDiscardInfoToDriver (FormSet, Form);\r
}\r
\r
- UpdateNvInfoInForm (FormSet, FALSE); \r
+ ValueChangeResetFlagUpdate(FALSE, FormSet, NULL);\r
} else if (SettingScope == SystemLevel) {\r
//\r
// System Level Discard.\r
//\r
- \r
+ OldFormSet = mSystemLevelFormSet;\r
+\r
//\r
// Discard changed value for each FormSet in the maintain list.\r
//\r
if (!ValidateFormSet(LocalFormSet)) {\r
continue;\r
}\r
+\r
+ mSystemLevelFormSet = LocalFormSet;\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
+ mSystemLevelFormSet = OldFormSet;\r
}\r
\r
return EFI_SUCCESS; \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
return Status;\r
}\r
\r
- if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
+ if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {\r
ConfigInfo = NULL;\r
Link = GetFirstNode (&Form->ConfigRequestHead);\r
while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
//\r
// 1. Prepare <ConfigResp>\r
//\r
- Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);\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 driver or efi variable.\r
+ // 2. Set value to hii config routine protocol.\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
+ Status = mHiiConfigRouting->RouteConfig (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ &Progress\r
+ );\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
+ SynchronizeStorage (FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);\r
}\r
\r
//\r
// 4. Update the NV flag.\r
// \r
- Form->NvUpdateRequired = FALSE;\r
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
+ ValueChangeResetFlagUpdate(TRUE, NULL, Form);\r
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
//\r
// Submit Buffer storage or Name/Value storage\r
//\r
//\r
// 1. Prepare <ConfigResp>\r
//\r
- Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);\r
+ Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);\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
+ // 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
+ FreePool (ConfigResp);\r
+ return Status;\r
}\r
+\r
FreePool (ConfigResp);\r
//\r
// 3. Config success, update storage shadow Buffer\r
//\r
- SynchronizeStorage (Storage, TRUE);\r
+ SynchronizeStorage (FormSet, Storage, FormSetStorage->ConfigRequest, TRUE);\r
}\r
\r
//\r
// 4. Update the NV flag.\r
// \r
- UpdateNvInfoInForm (FormSet, FALSE);\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
+ CleanBrowserStorage(LocalFormSet);\r
RemoveEntryList (&LocalFormSet->Link);\r
DestroyFormSet (LocalFormSet);\r
}\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
+ if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
return Status;\r
}\r
\r
Dst = (UINT8 *) &Question->HiiValue.Value;\r
}\r
\r
- IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\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
//\r
StrCat (ConfigRequest, Question->VariableName);\r
}\r
\r
- Status = FormSet->ConfigAccess->ExtractConfig (\r
- FormSet->ConfigAccess,\r
+ Status = mHiiConfigRouting->ExtractConfig (\r
+ mHiiConfigRouting,\r
ConfigRequest,\r
&Progress,\r
&Result\r
goto Done;\r
}\r
\r
+ if (ConfigResp == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+\r
//\r
// Skip <ConfigRequest>\r
//\r
}\r
}\r
\r
+\r
+\r
+/**\r
+ Return data element in an Array by its Index.\r
+\r
+ @param Array The data array.\r
+ @param Type Type of the data in this array.\r
+ @param Index Zero based index for data in this array.\r
+\r
+ @retval Value The data to be returned\r
+\r
+**/\r
+UINT64\r
+GetArrayData (\r
+ IN VOID *Array,\r
+ IN UINT8 Type,\r
+ IN UINTN Index\r
+ )\r
+{\r
+ UINT64 Data;\r
+\r
+ ASSERT (Array != NULL);\r
+\r
+ Data = 0;\r
+ switch (Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ Data = (UINT64) *(((UINT8 *) Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ Data = (UINT64) *(((UINT16 *) Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ Data = (UINT64) *(((UINT32 *) Array) + Index);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ Data = (UINT64) *(((UINT64 *) Array) + Index);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return Data;\r
+}\r
+\r
+\r
+/**\r
+ Set value of a data element in an Array by its Index.\r
+\r
+ @param Array The data array.\r
+ @param Type Type of the data in this array.\r
+ @param Index Zero based index for data in this array.\r
+ @param Value The value to be set.\r
+\r
+**/\r
+VOID\r
+SetArrayData (\r
+ IN VOID *Array,\r
+ IN UINT8 Type,\r
+ IN UINTN Index,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+\r
+ ASSERT (Array != NULL);\r
+\r
+ switch (Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+/**\r
+ Search an Option of a Question by its value.\r
+\r
+ @param Question The Question\r
+ @param OptionValue Value for Option to be searched.\r
+\r
+ @retval Pointer Pointer to the found Option.\r
+ @retval NULL Option not found.\r
+\r
+**/\r
+QUESTION_OPTION *\r
+ValueToOption (\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN EFI_HII_VALUE *OptionValue\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_OPTION *Option;\r
+ INTN Result;\r
+\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+ if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
+ //\r
+ // Check the suppressif condition, only a valid option can be return.\r
+ //\r
+ if ((Option->SuppressExpression == NULL) ||\r
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {\r
+ return Option;\r
+ }\r
+ }\r
+\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+\r
/**\r
Reset Question to its default value.\r
\r
LIST_ENTRY *FormLink;\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
- FORM_BROWSER_FORMSET *BackUpFormSet;\r
FORM_BROWSER_FORMSET *LocalFormSet;\r
- EFI_HII_HANDLE *HiiHandles;\r
- UINTN Index;\r
- EFI_GUID ZeroGuid;\r
+ FORM_BROWSER_FORMSET *OldFormSet;\r
\r
Status = EFI_SUCCESS;\r
\r
if ((Question->Storage != NULL) &&\r
(Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
- //\r
- // Update Form NV flag.\r
- //\r
- Form->NvUpdateRequired = TRUE;\r
}\r
}\r
} else if (SettingScope == FormSetLevel) {\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
- } else if (SettingScope == SystemLevel) {\r
- //\r
- // Open all FormSet by locate HII packages.\r
- // Initiliaze the maintain FormSet to store default data as back up data.\r
- //\r
- BackUpFormSet = gOldFormSet;\r
- gOldFormSet = NULL;\r
-\r
- //\r
- // Get all the Hii handles\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
- //\r
- // Check HiiHandles[Index] does exist in global maintain list. \r
- //\r
- if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {\r
- continue;\r
- }\r
- \r
- //\r
- // Initilize FormSet Setting\r
- //\r
- LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
- ASSERT (LocalFormSet != NULL);\r
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
- Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet, FALSE);\r
- if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
- DestroyFormSet (LocalFormSet);\r
- continue;\r
- }\r
- Status = InitializeCurrentSetting (LocalFormSet);\r
- if (EFI_ERROR (Status)) {\r
- DestroyFormSet (LocalFormSet);\r
- continue;\r
- }\r
- //\r
- // Initilize Questions' Value\r
- //\r
- Status = LoadFormSetConfig (NULL, LocalFormSet);\r
- if (EFI_ERROR (Status)) {\r
- DestroyFormSet (LocalFormSet);\r
- continue;\r
- }\r
-\r
- //\r
- // Add FormSet into the maintain list.\r
- //\r
- InsertTailList (&gBrowserFormSetList, &LocalFormSet->Link);\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
+ } else if (SettingScope == SystemLevel) {\r
//\r
- // Free resources, and restore gOldFormSet and gClassOfVfr\r
+ // Preload all Hii formset.\r
//\r
- FreePool (HiiHandles);\r
- gOldFormSet = BackUpFormSet;\r
- \r
+ LoadAllHiiFormset();\r
+\r
+ OldFormSet = mSystemLevelFormSet;\r
+\r
//\r
// Set Default Value for each FormSet in the maintain list.\r
//\r
if (!ValidateFormSet(LocalFormSet)) {\r
continue;\r
}\r
+\r
+ mSystemLevelFormSet = LocalFormSet;\r
+\r
ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);\r
}\r
+\r
+ mSystemLevelFormSet = OldFormSet;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Validate whether this question's value has changed.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param Question Question to be initialized.\r
+ @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.\r
+\r
+ @retval TRUE Question's value has changed.\r
+ @retval FALSE Question's value has not changed\r
+\r
+**/\r
+BOOLEAN\r
+IsQuestionValueChanged (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN OUT FORM_BROWSER_STATEMENT *Question,\r
+ IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
+ )\r
+{\r
+ EFI_HII_VALUE BackUpValue;\r
+ CHAR8 *BackUpBuffer;\r
+ EFI_STATUS Status;\r
+ BOOLEAN ValueChanged;\r
+ UINTN BufferWidth;\r
+\r
+ //\r
+ // For quetion without storage, always mark it as data not changed.\r
+ //\r
+ if (Question->Storage == NULL && Question->Operand != EFI_IFR_TIME_OP && Question->Operand != EFI_IFR_DATE_OP) {\r
+ return FALSE;\r
+ }\r
+\r
+ BackUpBuffer = NULL;\r
+ ValueChanged = FALSE;\r
+\r
+ switch (Question->Operand) {\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ BufferWidth = Question->StorageWidth;\r
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer != NULL);\r
+ break;\r
+\r
+ case EFI_IFR_STRING_OP:\r
+ case EFI_IFR_PASSWORD_OP:\r
+ BufferWidth = (UINTN) Question->Maximum * sizeof (CHAR16);\r
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
+ ASSERT (BackUpBuffer != NULL);\r
+ break;\r
+\r
+ default:\r
+ BufferWidth = 0;\r
+ break;\r
+ }\r
+ CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
+\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
+ CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
+ CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);\r
+\r
+ if (BackUpBuffer != NULL) {\r
+ FreePool (BackUpBuffer);\r
+ }\r
+\r
+ return ValueChanged;\r
+}\r
+\r
/**\r
Initialize Question's Edit copy from Storage.\r
\r
//\r
// Initialize local copy of Value for each Question\r
//\r
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+ if (Question->Operand == EFI_IFR_PASSWORD_OP && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)== 0) {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);\r
+ } else {\r
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+ }\r
if (EFI_ERROR (Status)) {\r
return Status;\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
+ ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
+ !gFinishRetrieveCall) {\r
//\r
// Check QuestionValue does exist.\r
//\r
);\r
}\r
\r
- Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
+ Status = ProcessCallBackFunction(Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
}\r
\r
+ //\r
+ // Update Question Value changed flag.\r
+ //\r
+ Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);\r
+\r
Link = GetNextNode (&Form->StatementListHead, Link);\r
}\r
\r
Link = GetNextNode (&FormSet->FormListHead, Link);\r
}\r
\r
+ //\r
+ // Finished question initialization.\r
+ // \r
+ FormSet->QuestionInited = TRUE;\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Remove the Request element from the Config Request.\r
+\r
+ @param Storage Pointer to the browser storage.\r
+ @param RequestElement The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveElement (\r
+ IN OUT BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *RequestElement\r
+ )\r
+{\r
+ CHAR16 *NewStr;\r
+ CHAR16 *DestStr;\r
+\r
+ ASSERT (Storage->ConfigRequest != NULL && RequestElement != NULL);\r
+\r
+ NewStr = StrStr (Storage->ConfigRequest, RequestElement);\r
+\r
+ if (NewStr == NULL) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Remove this element from this ConfigRequest.\r
+ //\r
+ DestStr = NewStr;\r
+ NewStr += StrLen (RequestElement);\r
+ CopyMem (DestStr, NewStr, StrSize (NewStr));\r
+ \r
+ Storage->SpareStrLen += StrLen (RequestElement); \r
+}\r
+\r
+/**\r
+ Adjust config request in storage, remove the request elements existed in the input ConfigRequest.\r
+\r
+ @param Storage Pointer to the browser storage.\r
+ @param ConfigRequest The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveConfigRequest (\r
+ BROWSER_STORAGE *Storage,\r
+ CHAR16 *ConfigRequest\r
+ )\r
+{\r
+ CHAR16 *RequestElement;\r
+ CHAR16 *NextRequestElement;\r
+ CHAR16 *SearchKey;\r
+\r
+ //\r
+ // No request element in it, just return.\r
+ //\r
+ if (ConfigRequest == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
+ //\r
+ SearchKey = L"&";\r
+ } else {\r
+ //\r
+ // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
+ //\r
+ SearchKey = L"&OFFSET";\r
+ }\r
+\r
+ //\r
+ // Find SearchKey storage\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ RequestElement = StrStr (ConfigRequest, L"PATH");\r
+ ASSERT (RequestElement != NULL);\r
+ RequestElement = StrStr (RequestElement, SearchKey); \r
+ } else {\r
+ RequestElement = StrStr (ConfigRequest, SearchKey);\r
+ }\r
+\r
+ while (RequestElement != NULL) {\r
+ //\r
+ // +1 to avoid find header itself.\r
+ //\r
+ NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
+\r
+ //\r
+ // The last Request element in configRequest string.\r
+ //\r
+ if (NextRequestElement != NULL) {\r
+ //\r
+ // Replace "&" with '\0'.\r
+ //\r
+ *NextRequestElement = L'\0';\r
+ }\r
+\r
+ RemoveElement (Storage, RequestElement);\r
+\r
+ if (NextRequestElement != NULL) {\r
+ //\r
+ // Restore '&' with '\0' for later used.\r
+ //\r
+ *NextRequestElement = L'&';\r
+ }\r
+\r
+ RequestElement = NextRequestElement;\r
+ }\r
+\r
+ //\r
+ // If no request element remain, just remove the ConfigRequest string.\r
+ //\r
+ if (StrCmp (Storage->ConfigRequest, Storage->ConfigHdr) == 0) {\r
+ FreePool (Storage->ConfigRequest);\r
+ Storage->ConfigRequest = NULL;\r
+ Storage->SpareStrLen = 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Base on the current formset info, clean the ConfigRequest string in browser storage.\r
+\r
+ @param FormSet Pointer of the FormSet\r
+\r
+**/\r
+VOID\r
+CleanBrowserStorage (\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *Storage;\r
+ CHAR16 *ConfigRequest;\r
+\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {\r
+ continue;\r
+ }\r
+\r
+ ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;\r
+ RemoveConfigRequest (Storage->BrowserStorage, 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
+ FreePool (Storage->BrowserStorage->ConfigRequest);\r
+ }\r
+ Storage->BrowserStorage->Initialized = FALSE;\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Check whether current element in the ConfigReqeust string.\r
\r
UINTN StringSize;\r
UINTN StrLength;\r
\r
- StrLength = StrLen (RequestElement) * sizeof (CHAR16);\r
+ StrLength = StrLen (RequestElement);\r
\r
//\r
// Append <RequestElement> to <ConfigRequest>\r
Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
\r
@param Storage Form set Storage.\r
- @param ConfigRequest Return the ConfigRequest info.\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
- OUT CHAR16 **ConfigRequest\r
+ IN FORMSET_STORAGE *Storage\r
)\r
{\r
CHAR16 *RequestElement;\r
\r
if (Storage->BrowserStorage->ConfigRequest == NULL) {\r
Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
- *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
return TRUE;\r
}\r
\r
}\r
\r
if (RetVal) {\r
- *ConfigRequest = RetBuf;\r
+ if (Storage->ConfigElements != NULL) {\r
+ FreePool (Storage->ConfigElements);\r
+ }\r
+ Storage->ConfigElements = RetBuf;\r
} else {\r
FreePool (RetBuf);\r
}\r
}\r
\r
/**\r
- Fill storage's edit copy with settings requested from Configuration Driver.\r
\r
+ Base on ConfigRequest info to get default value for current formset. \r
+\r
+ ConfigRequest info include the info about which questions in current formset need to \r
+ get default value. This function only get these questions default value.\r
+ \r
@param FormSet FormSet data structure.\r
- @param Storage Buffer Storage.\r
+ @param Storage Storage need to update value.\r
+ @param ConfigRequest The config request string.\r
\r
- @retval EFI_SUCCESS The function completed successfully.\r
+**/\r
+VOID\r
+GetDefaultForFormset (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN BROWSER_STORAGE *Storage,\r
+ IN CHAR16 *ConfigRequest\r
+ )\r
+{\r
+ UINT8 *BackUpBuf;\r
+ UINTN BufferSize;\r
+ LIST_ENTRY BackUpList;\r
+ NAME_VALUE_NODE *Node;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NodeLink;\r
+ NAME_VALUE_NODE *TmpNode;\r
+ EFI_STATUS Status;\r
+ EFI_STRING Progress;\r
+ EFI_STRING Result;\r
+\r
+ BackUpBuf = NULL;\r
+ InitializeListHead(&BackUpList);\r
+\r
+ //\r
+ // Back update the edit buffer.\r
+ // \r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ BackUpBuf = AllocateCopyPool (Storage->Size, Storage->EditBuffer);\r
+ ASSERT (BackUpBuf != NULL);\r
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ Link = GetFirstNode (&Storage->NameValueListHead);\r
+ while (!IsNull (&Storage->NameValueListHead, Link)) {\r
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+ Link = GetNextNode (&Storage->NameValueListHead, Link);\r
+\r
+ //\r
+ // Only back Node belong to this formset.\r
+ //\r
+ if (StrStr (Storage->ConfigRequest, Node->Name) == NULL) {\r
+ continue;\r
+ }\r
+\r
+ TmpNode = AllocateCopyPool (sizeof (NAME_VALUE_NODE), Node);\r
+ TmpNode->Name = AllocateCopyPool (StrSize(Node->Name) * sizeof (CHAR16), Node->Name);\r
+ TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);\r
+\r
+ InsertTailList(&BackUpList, &TmpNode->Link);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get default value.\r
+ //\r
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage, TRUE);\r
+\r
+ //\r
+ // Update the question value based on the input ConfigRequest.\r
+ //\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+ ASSERT (BackUpBuf != NULL);\r
+ BufferSize = Storage->Size;\r
+ Status = mHiiConfigRouting->BlockToConfig(\r
+ mHiiConfigRouting,\r
+ ConfigRequest,\r
+ Storage->EditBuffer,\r
+ BufferSize,\r
+ &Result,\r
+ &Progress\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ Status = mHiiConfigRouting->ConfigToBlock (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ BackUpBuf,\r
+ &BufferSize,\r
+ &Progress\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
+ \r
+ CopyMem (Storage->EditBuffer, BackUpBuf, Storage->Size);\r
+ FreePool (BackUpBuf);\r
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // Update question value, only element in ConfigReqeust will be update.\r
+ //\r
+ Link = GetFirstNode (&BackUpList);\r
+ while (!IsNull (&BackUpList, Link)) {\r
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+ Link = GetNextNode (&BackUpList, Link);\r
+\r
+ if (StrStr (ConfigRequest, Node->Name) != NULL) {\r
+ continue;\r
+ }\r
+\r
+ NodeLink = GetFirstNode (&Storage->NameValueListHead);\r
+ while (!IsNull (&Storage->NameValueListHead, NodeLink)) {\r
+ TmpNode = NAME_VALUE_NODE_FROM_LINK (NodeLink);\r
+ NodeLink = GetNextNode (&Storage->NameValueListHead, NodeLink);\r
+ \r
+ if (StrCmp (Node->Name, TmpNode->Name) != 0) {\r
+ continue;\r
+ }\r
+\r
+ FreePool (TmpNode->EditValue);\r
+ TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);\r
+\r
+ RemoveEntryList (&Node->Link);\r
+ FreePool (Node->EditValue);\r
+ FreePool (Node->Name);\r
+ FreePool (Node);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Restore the Name/Value node.\r
+ // \r
+ Link = GetFirstNode (&BackUpList);\r
+ while (!IsNull (&BackUpList, Link)) {\r
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+ Link = GetNextNode (&BackUpList, Link);\r
+ \r
+ //\r
+ // Free this node.\r
+ //\r
+ RemoveEntryList (&Node->Link);\r
+ FreePool (Node->EditValue);\r
+ FreePool (Node->Name);\r
+ FreePool (Node);\r
+ }\r
+ }\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 Buffer Storage.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
LoadStorage (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
IN FORMSET_STORAGE *Storage\r
EFI_STRING Progress;\r
EFI_STRING Result;\r
CHAR16 *StrPtr;\r
- CHAR16 *ConfigRequest;\r
+ EFI_STRING ConfigRequest;\r
+ UINTN StrLen;\r
\r
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- return EFI_SUCCESS;\r
- }\r
+ ConfigRequest = NULL;\r
\r
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- Status = EFI_SUCCESS;\r
- //\r
- // EFI varstore data all get from variable, so no need to get again.\r
- //\r
- if (Storage->BrowserStorage->ReferenceCount == 1) {\r
- Status = gRT->GetVariable (\r
- Storage->BrowserStorage->Name,\r
- &Storage->BrowserStorage->Guid,\r
- NULL,\r
- (UINTN*)&Storage->BrowserStorage->Size,\r
- Storage->BrowserStorage->EditBuffer\r
- );\r
- }\r
- return Status;\r
- }\r
+ switch (Storage->BrowserStorage->Type) {\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+ return;\r
\r
- if (FormSet->ConfigAccess == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
+ if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
+ ConfigRequestAdjust(Storage);\r
+ return;\r
+ }\r
\r
- if (Storage->ElementCount == 0) {\r
- //\r
- // Skip if there is no RequestElement\r
- //\r
- return EFI_SUCCESS;\r
- }\r
+ //\r
+ // Create the config request string to get all fields for this storage.\r
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
+ // followed by "&OFFSET=0&WIDTH=WWWW"followed by a Null-terminator\r
+ //\r
+ StrLen = StrSize (Storage->BrowserStorage->ConfigHdr) + 20 * sizeof (CHAR16);\r
+ ConfigRequest = AllocateZeroPool (StrLen);\r
+ ASSERT (ConfigRequest != NULL);\r
+ UnicodeSPrint (\r
+ ConfigRequest, \r
+ StrLen, \r
+ L"%s&OFFSET=0&WIDTH=%04x", \r
+ Storage->BrowserStorage->ConfigHdr,\r
+ Storage->BrowserStorage->Size);\r
+ break;\r
\r
- //\r
- // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig\r
- // will used to call ExtractConfig.\r
- //\r
- if (!ConfigRequestAdjust(Storage, &ConfigRequest)) {\r
- return EFI_SUCCESS;\r
+ case EFI_HII_VARSTORE_BUFFER:\r
+ case EFI_HII_VARSTORE_NAME_VALUE:\r
+ //\r
+ // Skip if there is no RequestElement or data has initilized.\r
+ //\r
+ if (Storage->ElementCount == 0 || Storage->BrowserStorage->Initialized) {\r
+ return;\r
+ }\r
+ Storage->BrowserStorage->Initialized = TRUE;\r
+ ConfigRequest = Storage->ConfigRequest;\r
+ break;\r
+\r
+ default:\r
+ return;\r
}\r
\r
//\r
// Request current settings from Configuration Driver\r
//\r
- Status = FormSet->ConfigAccess->ExtractConfig (\r
- FormSet->ConfigAccess,\r
+ Status = mHiiConfigRouting->ExtractConfig (\r
+ mHiiConfigRouting,\r
ConfigRequest,\r
&Progress,\r
&Result\r
);\r
- FreePool (ConfigRequest);\r
\r
+ //\r
+ // If get value fail, extract default from IFR binary\r
+ //\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
+ } else {\r
+ //\r
+ // Convert Result from <ConfigAltResp> to <ConfigResp>\r
+ //\r
+ StrPtr = StrStr (Result, L"&GUID=");\r
+ if (StrPtr != NULL) {\r
+ *StrPtr = L'\0';\r
+ }\r
+ \r
+ Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
+ FreePool (Result);\r
}\r
\r
+ Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+\r
//\r
- // Convert Result from <ConfigAltResp> to <ConfigResp>\r
+ // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer. \r
//\r
- StrPtr = StrStr (Result, L"&GUID=");\r
- if (StrPtr != NULL) {\r
- *StrPtr = L'\0';\r
- }\r
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);\r
\r
- Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
- FreePool (Result);\r
- return Status;\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ if (ConfigRequest != NULL) {\r
+ FreePool (ConfigRequest);\r
+ }\r
+ }\r
}\r
\r
/**\r
\r
@param FormSet FormSet data structure.\r
\r
- @retval EFI_SUCCESS The function completed successfully.\r
-\r
**/\r
-EFI_STATUS\r
+VOID\r
InitializeCurrentSetting (\r
IN OUT FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
LIST_ENTRY *Link;\r
- LIST_ENTRY *Link2;\r
FORMSET_STORAGE *Storage;\r
- FORMSET_STORAGE *StorageSrc;\r
- FORMSET_STORAGE *OldStorage;\r
- FORM_BROWSER_FORM *Form;\r
- FORM_BROWSER_FORM *Form2;\r
- EFI_STATUS Status;\r
+ FORM_BROWSER_FORMSET *OldFormSet;\r
+\r
+ //\r
+ // Try to find pre FormSet in the maintain backup list.\r
+ // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.\r
+ //\r
+ OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);\r
+ if (OldFormSet != NULL) {\r
+ RemoveEntryList (&OldFormSet->Link);\r
+ DestroyFormSet (OldFormSet);\r
+ }\r
+ InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
\r
//\r
// Extract default from IFR binary for no storage questions.\r
while (!IsNull (&FormSet->StorageListHead, Link)) {\r
Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
\r
- OldStorage = NULL;\r
- if (gOldFormSet != NULL) {\r
- //\r
- // Try to find the Storage in backup formset gOldFormSet\r
- //\r
- Link2 = GetFirstNode (&gOldFormSet->StorageListHead);\r
- while (!IsNull (&gOldFormSet->StorageListHead, Link2)) {\r
- StorageSrc = FORMSET_STORAGE_FROM_LINK (Link2);\r
-\r
- if (StorageSrc->VarStoreId == Storage->VarStoreId) {\r
- OldStorage = StorageSrc;\r
- break;\r
- }\r
-\r
- Link2 = GetNextNode (&gOldFormSet->StorageListHead, Link2);\r
- }\r
- }\r
-\r
- //\r
- // Storage is not found in backup formset and current global storage not has other driver used,\r
- // request it from ConfigDriver\r
- //\r
- if (OldStorage == NULL) {\r
- Status = LoadStorage (FormSet, Storage);\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // If get last time changed value failed, extract default from IFR binary\r
- //\r
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
- //\r
- // ExtractDefault will set the NV flag to TRUE, so need this function to clean the flag\r
- // in current situation.\r
- //\r
- UpdateNvInfoInForm (FormSet, FALSE);\r
- }\r
-\r
- //\r
- // Now Edit Buffer is filled with default values(lower priority) or current\r
- // settings(higher priority), sychronize it to shadow Buffer\r
- //\r
- SynchronizeStorage (Storage->BrowserStorage, TRUE);\r
- }\r
+ LoadStorage (FormSet, Storage);\r
\r
Link = GetNextNode (&FormSet->StorageListHead, Link);\r
}\r
-\r
- //\r
- // If has old formset, get the old nv update status.\r
- //\r
- if (gOldFormSet != NULL) {\r
- Link = GetFirstNode (&FormSet->FormListHead);\r
- while (!IsNull (&FormSet->FormListHead, Link)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
- Link2 = GetFirstNode (&gOldFormSet->FormListHead);\r
- while (!IsNull (&gOldFormSet->FormListHead, Link2)) {\r
- Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);\r
-\r
- if (Form->FormId == Form2->FormId) {\r
- Form->NvUpdateRequired = Form2->NvUpdateRequired;\r
- break;\r
- }\r
-\r
- Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);\r
- }\r
- Link = GetNextNode (&FormSet->FormListHead, Link);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
\r
found in package list.\r
On output, GUID of the formset found(if not NULL).\r
@param FormSet FormSet data structure.\r
- @param UpdateGlobalVar Whether need to update the global variable.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
@retval EFI_NOT_FOUND The specified FormSet could not be found.\r
InitializeFormSet (\r
IN EFI_HII_HANDLE Handle,\r
IN OUT EFI_GUID *FormSetGuid,\r
- OUT FORM_BROWSER_FORMSET *FormSet,\r
- IN BOOLEAN UpdateGlobalVar \r
+ OUT FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
EFI_STATUS Status;\r
EFI_HANDLE DriverHandle;\r
- UINT16 Index;\r
\r
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
if (EFI_ERROR (Status)) {\r
FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;\r
FormSet->HiiHandle = Handle;\r
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
+ FormSet->QuestionInited = FALSE;\r
\r
//\r
// Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
// Parse the IFR binary OpCodes\r
//\r
Status = ParseOpCodes (FormSet);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- // \r
- // If not need to update the global variable, just return.\r
- //\r
- if (!UpdateGlobalVar) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Set VFR type by FormSet SubClass field\r
- //\r
- gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
- if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
- gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;\r
- }\r
- \r
- //\r
- // Set VFR type by FormSet class guid\r
- //\r
- for (Index = 0; Index < 3; Index ++) {\r
- if (CompareGuid (&FormSet->ClassGuid[Index], &gEfiHiiPlatformSetupFormsetGuid)) {\r
- gClassOfVfr |= FORMSET_CLASS_PLATFORM_SETUP;\r
- break;\r
- }\r
- }\r
-\r
- gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;\r
-\r
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
- gFrontPageHandle = FormSet->HiiHandle;\r
- gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;\r
- }\r
-\r
- //\r
- // Match GUID to find out the function key setting. If match fail, use the default setting.\r
- //\r
- for (Index = 0; Index < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index++) {\r
- if (CompareGuid (&FormSet->Guid, &(gFunctionKeySettingTable[Index].FormSetGuid))) {\r
- //\r
- // Update the function key setting.\r
- //\r
- gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;\r
- }\r
- }\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
\r
)\r
{\r
BROWSER_CONTEXT *Context;\r
+ FORM_ENTRY_INFO *MenuList;\r
\r
gBrowserContextCount++;\r
if (gBrowserContextCount == 1) {\r
//\r
// Save FormBrowser context\r
//\r
- Context->BannerData = gBannerData;\r
- Context->ClassOfVfr = gClassOfVfr;\r
- Context->FunctionKeySetting = gFunctionKeySetting;\r
+ Context->Selection = gCurrentSelection;\r
Context->ResetRequired = gResetRequired;\r
- Context->Direction = gDirection;\r
- Context->EnterString = gEnterString;\r
- Context->EnterCommitString = gEnterCommitString;\r
- Context->EnterEscapeString = gEnterEscapeString;\r
- Context->EscapeString = gEscapeString;\r
- Context->MoveHighlight = gMoveHighlight;\r
- Context->MakeSelection = gMakeSelection;\r
- Context->DecNumericInput = gDecNumericInput;\r
- Context->HexNumericInput = gHexNumericInput;\r
- Context->ToggleCheckBox = gToggleCheckBox;\r
- Context->PromptForData = gPromptForData;\r
- Context->PromptForPassword = gPromptForPassword;\r
- Context->PromptForNewPassword = gPromptForNewPassword;\r
- Context->ConfirmPassword = gConfirmPassword;\r
- Context->ConfirmError = gConfirmError;\r
- Context->PassowordInvalid = gPassowordInvalid;\r
- Context->PressEnter = gPressEnter;\r
- Context->EmptyString = gEmptyString;\r
- Context->AreYouSure = gAreYouSure;\r
- Context->YesResponse = gYesResponse;\r
- Context->NoResponse = gNoResponse;\r
- Context->MiniString = gMiniString;\r
- Context->PlusString = gPlusString;\r
- Context->MinusString = gMinusString;\r
- Context->AdjustNumber = gAdjustNumber;\r
- Context->SaveChanges = gSaveChanges;\r
- Context->OptionMismatch = gOptionMismatch;\r
- Context->FormSuppress = gFormSuppress;\r
- Context->PromptBlockWidth = gPromptBlockWidth;\r
- Context->OptionBlockWidth = gOptionBlockWidth;\r
- Context->HelpBlockWidth = gHelpBlockWidth;\r
- Context->OldFormSet = gOldFormSet;\r
- Context->MenuRefreshHead = gMenuRefreshHead;\r
- Context->ProtocolNotFound = gProtocolNotFound;\r
-\r
- CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));\r
- CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));\r
+ Context->ExitRequired = gExitRequired;\r
+ Context->HiiHandle = mCurrentHiiHandle;\r
+ Context->FormId = mCurrentFormId;\r
+ CopyGuid (&Context->FormSetGuid, &mCurrentFormSetGuid);\r
+\r
+ //\r
+ // Save the menu history data.\r
+ //\r
+ InitializeListHead(&Context->FormHistoryList);\r
+ while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
+ RemoveEntryList (&MenuList->Link);\r
+\r
+ InsertTailList(&Context->FormHistoryList, &MenuList->Link);\r
+ }\r
\r
//\r
// Insert to FormBrowser context list\r
{\r
LIST_ENTRY *Link;\r
BROWSER_CONTEXT *Context;\r
+ FORM_ENTRY_INFO *MenuList;\r
\r
ASSERT (gBrowserContextCount != 0);\r
gBrowserContextCount--;\r
//\r
// Restore FormBrowser context\r
//\r
- gBannerData = Context->BannerData;\r
- gClassOfVfr = Context->ClassOfVfr;\r
- gFunctionKeySetting = Context->FunctionKeySetting;\r
+ gCurrentSelection = Context->Selection;\r
gResetRequired = Context->ResetRequired;\r
- gDirection = Context->Direction;\r
- gEnterString = Context->EnterString;\r
- gEnterCommitString = Context->EnterCommitString;\r
- gEnterEscapeString = Context->EnterEscapeString;\r
- gEscapeString = Context->EscapeString;\r
- gMoveHighlight = Context->MoveHighlight;\r
- gMakeSelection = Context->MakeSelection;\r
- gDecNumericInput = Context->DecNumericInput;\r
- gHexNumericInput = Context->HexNumericInput;\r
- gToggleCheckBox = Context->ToggleCheckBox;\r
- gPromptForData = Context->PromptForData;\r
- gPromptForPassword = Context->PromptForPassword;\r
- gPromptForNewPassword = Context->PromptForNewPassword;\r
- gConfirmPassword = Context->ConfirmPassword;\r
- gConfirmError = Context->ConfirmError;\r
- gPassowordInvalid = Context->PassowordInvalid;\r
- gPressEnter = Context->PressEnter;\r
- gEmptyString = Context->EmptyString;\r
- gAreYouSure = Context->AreYouSure;\r
- gYesResponse = Context->YesResponse;\r
- gNoResponse = Context->NoResponse;\r
- gMiniString = Context->MiniString;\r
- gPlusString = Context->PlusString;\r
- gMinusString = Context->MinusString;\r
- gAdjustNumber = Context->AdjustNumber;\r
- gSaveChanges = Context->SaveChanges;\r
- gOptionMismatch = Context->OptionMismatch;\r
- gFormSuppress = Context->FormSuppress;\r
- gPromptBlockWidth = Context->PromptBlockWidth;\r
- gOptionBlockWidth = Context->OptionBlockWidth;\r
- gHelpBlockWidth = Context->HelpBlockWidth;\r
- gOldFormSet = Context->OldFormSet;\r
- gMenuRefreshHead = Context->MenuRefreshHead;\r
- gProtocolNotFound = Context->ProtocolNotFound;\r
-\r
- CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));\r
- CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));\r
+ gExitRequired = Context->ExitRequired;\r
+ mCurrentHiiHandle = Context->HiiHandle;\r
+ mCurrentFormId = Context->FormId;\r
+ CopyGuid (&mCurrentFormSetGuid, &Context->FormSetGuid);\r
+\r
+ //\r
+ // Restore the menu history data.\r
+ //\r
+ while (!IsListEmpty (&Context->FormHistoryList)) {\r
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (Context->FormHistoryList.ForwardLink);\r
+ RemoveEntryList (&MenuList->Link);\r
+\r
+ InsertTailList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
+ }\r
\r
//\r
// Remove from FormBrowser context list\r
//\r
// HiiHandle is Current FormSet.\r
//\r
- if ((gOldFormSet != NULL) && (gOldFormSet->HiiHandle == Handle)) {\r
+ if (mCurrentHiiHandle == Handle) {\r
return TRUE;\r
}\r
\r
Link = GetFirstNode (&gBrowserContextList);\r
while (!IsNull (&gBrowserContextList, Link)) {\r
Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
- if (Context->OldFormSet->HiiHandle == Handle) {\r
+ if (Context->HiiHandle == Handle) {\r
//\r
// HiiHandle is in BrowserContext\r
//\r
return FALSE;\r
}\r
\r
+/**\r
+ Perform Password check. \r
+ Passwork may be encrypted by driver that requires the specific check.\r
+ \r
+ @param Form Form where Password Statement is in.\r
+ @param Statement Password statement\r
+ @param PasswordString Password string to be checked. It may be NULL.\r
+ NULL means to restore password.\r
+ "" string can be used to checked whether old password does exist.\r
+ \r
+ @return Status Status of Password check.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PasswordCheck (\r
+ IN FORM_DISPLAY_ENGINE_FORM *Form,\r
+ IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
+ IN EFI_STRING PasswordString OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ EFI_IFR_TYPE_VALUE IfrTypeValue;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ ConfigAccess = gCurrentSelection->FormSet->ConfigAccess;\r
+ Question = GetBrowserStatement(Statement);\r
+ ASSERT (Question != NULL);\r
+\r
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) {\r
+ if (ConfigAccess == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else {\r
+ if (PasswordString == NULL) {\r
+ return EFI_SUCCESS;\r
+ } \r
+ \r
+ if (StrnCmp (PasswordString, (CHAR16 *) Question->BufferValue, Question->StorageWidth/sizeof (CHAR16)) == 0) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_READY;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Prepare password string in HII database\r
+ //\r
+ if (PasswordString != NULL) {\r
+ IfrTypeValue.string = NewString (PasswordString, gCurrentSelection->FormSet->HiiHandle);\r
+ } else {\r
+ IfrTypeValue.string = 0;\r
+ }\r
+\r
+ //\r
+ // Send password to Configuration Driver for validation\r
+ //\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ EFI_BROWSER_ACTION_CHANGING,\r
+ Question->QuestionId,\r
+ Question->HiiValue.Type,\r
+ &IfrTypeValue,\r
+ &ActionRequest\r
+ );\r
+\r
+ //\r
+ // Remove password string from HII database\r
+ //\r
+ if (PasswordString != NULL) {\r
+ DeleteString (IfrTypeValue.string, gCurrentSelection->FormSet->HiiHandle);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Find the registered HotKey based on KeyData.\r
\r
if (Scope >= MaxLevel) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- \r
+\r
//\r
// When no hot key registered in system or on the first setting,\r
// Scope can be set.\r
return;\r
}\r
\r
+/**\r
+ Check whether the browser data has been modified.\r
+\r
+ @retval TRUE Browser data is modified.\r
+ @retval FALSE No browser data is modified.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsBrowserDataModified (\r
+ VOID\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+\r
+ if (gCurrentSelection == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ switch (gBrowserSettingScope) {\r
+ case FormLevel:\r
+ return IsNvUpdateRequiredForForm (gCurrentSelection->Form);\r
+\r
+ case FormSetLevel:\r
+ return IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet);\r
+\r
+ case SystemLevel:\r
+ Link = GetFirstNode (&gBrowserFormSetList);\r
+ while (!IsNull (&gBrowserFormSetList, Link)) {\r
+ FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+ if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
+ return TRUE;\r
+ }\r
+ Link = GetNextNode (&gBrowserFormSetList, Link);\r
+ }\r
+ return FALSE;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Execute the action requested by the Action parameter.\r
+\r
+ @param[in] Action Execute the request action.\r
+ @param[in] DefaultId The default Id info when need to load default value. Only used when Action is BROWSER_ACTION_DEFAULT.\r
+\r
+ @retval EFI_SUCCESS Execute the request action succss.\r
+ @retval EFI_INVALID_PARAMETER The input action value is invalid.\r
+\r
+**/\r
+EFI_STATUS \r
+EFIAPI\r
+ExecuteAction (\r
+ IN UINT32 Action,\r
+ IN UINT16 DefaultId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (gCurrentSelection == NULL) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Executet the discard action.\r
+ //\r
+ if ((Action & BROWSER_ACTION_DISCARD) != 0) {\r
+ Status = DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Executet the difault action.\r
+ //\r
+ if ((Action & BROWSER_ACTION_DEFAULT) != 0) {\r
+ Status = ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Executet the submit action.\r
+ //\r
+ if ((Action & BROWSER_ACTION_SUBMIT) != 0) {\r
+ Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Executet the reset action.\r
+ //\r
+ if ((Action & BROWSER_ACTION_RESET) != 0) {\r
+ gResetRequired = TRUE;\r
+ }\r
+\r
+ //\r
+ // Executet the exit action.\r
+ //\r
+ if ((Action & BROWSER_ACTION_EXIT) != 0) {\r
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ if (gBrowserSettingScope == SystemLevel) {\r
+ if (ExitHandlerFunction != NULL) {\r
+ ExitHandlerFunction ();\r
+ }\r
+ }\r
+\r
+ gExitRequired = TRUE;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Create reminder to let user to choose save or discard the changed browser data.\r
Caller can use it to actively check the changed browser data.\r
FORM_BROWSER_FORMSET *FormSet;\r
BOOLEAN IsDataChanged;\r
UINT32 DataSavedAction;\r
- CHAR16 *YesResponse;\r
- CHAR16 *NoResponse;\r
- CHAR16 *EmptyString;\r
- CHAR16 *ChangeReminderString;\r
- CHAR16 *SaveConfirmString;\r
- EFI_INPUT_KEY Key;\r
\r
DataSavedAction = BROWSER_NO_CHANGES;\r
IsDataChanged = FALSE;\r
if (!ValidateFormSet(FormSet)) {\r
continue;\r
}\r
- if (IsNvUpdateRequired (FormSet)) {\r
+ if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
IsDataChanged = TRUE;\r
break;\r
}\r
}\r
\r
//\r
- // If data is changed, prompt user\r
+ // If data is changed, prompt user to save or discard it. \r
//\r
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-\r
- YesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);\r
- ASSERT (YesResponse != NULL);\r
- NoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);\r
- ASSERT (NoResponse != NULL);\r
- EmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- ChangeReminderString = GetToken (STRING_TOKEN (CHANGE_REMINDER), gHiiHandle);\r
- SaveConfirmString = GetToken (STRING_TOKEN (SAVE_CONFIRM), gHiiHandle);\r
-\r
do {\r
- CreateDialog (4, TRUE, 0, NULL, &Key, EmptyString, ChangeReminderString, SaveConfirmString, EmptyString);\r
- } while\r
- (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse[0] | UPPER_LOWER_CASE_OFFSET))\r
- );\r
-\r
- //\r
- // If the user hits the YesResponse key\r
- //\r
- if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse[0] | UPPER_LOWER_CASE_OFFSET)) {\r
- SubmitForm (NULL, NULL, SystemLevel);\r
- DataSavedAction = BROWSER_SAVE_CHANGES;\r
- } else {\r
- DiscardForm (NULL, NULL, SystemLevel);\r
- DataSavedAction = BROWSER_DISCARD_CHANGES;\r
- gResetRequired = FALSE;\r
- }\r
+ DataSavedAction = (UINT32) mFormDisplay->ConfirmDataChange();\r
\r
- FreePool (YesResponse);\r
- FreePool (NoResponse);\r
- FreePool (EmptyString);\r
- FreePool (SaveConfirmString);\r
- FreePool (ChangeReminderString);\r
+ if (DataSavedAction == BROWSER_SAVE_CHANGES) {\r
+ SubmitForm (NULL, NULL, SystemLevel);\r
+ break;\r
+ } else if (DataSavedAction == BROWSER_DISCARD_CHANGES) {\r
+ DiscardForm (NULL, NULL, SystemLevel);\r
+ break;\r
+ } else if (DataSavedAction == BROWSER_NO_CHANGES) {\r
+ break;\r
+ }\r
+ } while (1);\r
\r
return DataSavedAction;\r
}\r