**/\r
\r
#include "Setup.h"\r
-#include "Ui.h"\r
-\r
\r
SETUP_DRIVER_PRIVATE_DATA mPrivateData = {\r
SETUP_DRIVER_SIGNATURE,\r
EFI_HII_STRING_PROTOCOL *mHiiString;\r
EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;\r
\r
+UINTN gBrowserContextCount = 0;\r
+LIST_ENTRY gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\r
+\r
BANNER_DATA *gBannerData;\r
EFI_HII_HANDLE gFrontPageHandle;\r
UINTN gClassOfVfr;\r
EFI_HII_HANDLE gHiiHandle;\r
UINT16 gDirection;\r
EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
-BOOLEAN gUpArrow;\r
-BOOLEAN gDownArrow;\r
\r
//\r
// Browser Global Strings\r
CHAR16 *gAdjustNumber;\r
CHAR16 *gSaveChanges;\r
CHAR16 *gOptionMismatch;\r
+CHAR16 *gFormSuppress;\r
\r
CHAR16 *mUnknownString = L"!";\r
\r
0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}\r
};\r
\r
-FORM_BROWSER_FORMSET *gOldFormSet = NULL;\r
+FORM_BROWSER_FORMSET *gOldFormSet;\r
\r
FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {\r
//\r
UINTN Index;\r
FORM_BROWSER_FORMSET *FormSet;\r
\r
+ //\r
+ // Save globals used by SendForm()\r
+ //\r
+ SaveBrowserContext ();\r
+\r
Status = EFI_SUCCESS;\r
ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
\r
if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||\r
(gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)\r
) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
} else {\r
//\r
// Local dimension validation.\r
) {\r
CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
} else {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
}\r
}\r
InitializeBrowserStrings ();\r
\r
gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;\r
- gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
\r
//\r
// Ensure we are in Text mode\r
Selection->FormId = FormId;\r
}\r
\r
+ gOldFormSet = NULL;\r
gNvUpdateRequired = FALSE;\r
\r
do {\r
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
gST->ConOut->ClearScreen (gST->ConOut);\r
\r
+Done:\r
+ //\r
+ // Restore globals used by SendForm()\r
+ //\r
+ RestoreBrowserContext ();\r
+\r
return Status;\r
}\r
\r
break;\r
\r
case EFI_HII_VARSTORE_NAME_VALUE:\r
+ StrPtr = StrStr (ConfigResp, L"PATH");\r
+ if (StrPtr == NULL) {\r
+ break;\r
+ }\r
StrPtr = StrStr (ConfigResp, L"&");\r
while (StrPtr != NULL) {\r
//\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Initialize Question's Edit copy from Storage.\r
\r
+ @param Selection Selection contains the information about \r
+ the Selection, form and formset to be displayed.\r
+ Selection action may be updated in retrieve callback.\r
@param FormSet FormSet data structure.\r
@param Form Form data structure.\r
\r
**/\r
EFI_STATUS\r
LoadFormConfig (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Question;\r
-\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+ UINT8 *BufferValue;\r
+ UINTN StorageWidth;\r
+ EFI_HII_VALUE *HiiValue;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ \r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ \r
+ //\r
+ // Check whether EfiVarstore with CallBack can be got.\r
+ //\r
+ if ((Question->QuestionId != 0) && (Question->Storage != NULL) &&\r
+ (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) && \r
+ ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
+ //\r
+ // ConfigAccess can't be NULL.\r
+ //\r
+ if (FormSet->ConfigAccess == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Check QuestionValue does exist.\r
+ //\r
+ StorageWidth = Question->StorageWidth;\r
+ if (Question->BufferValue != NULL) {\r
+ BufferValue = Question->BufferValue;\r
+ } else {\r
+ BufferValue = (UINT8 *) &Question->HiiValue.Value;\r
+ }\r
+ Status = gRT->GetVariable (\r
+ Question->VariableName,\r
+ &Question->Storage->Guid,\r
+ NULL,\r
+ &StorageWidth,\r
+ BufferValue\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ HiiValue = &Question->HiiValue;\r
+ BufferValue = (UINT8 *) &Question->HiiValue.Value;\r
+ if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ //\r
+ // Create String in HII database for Configuration Driver to retrieve\r
+ //\r
+ HiiValue->Value.string = NewString ((CHAR16 *) Question->BufferValue, FormSet->HiiHandle);\r
+ } else if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ BufferValue = Question->BufferValue;\r
+ }\r
+\r
+ Status = FormSet->ConfigAccess->Callback (\r
+ FormSet->ConfigAccess,\r
+ EFI_BROWSER_ACTION_RETRIEVE,\r
+ Question->QuestionId,\r
+ HiiValue->Type,\r
+ (EFI_IFR_TYPE_VALUE *) BufferValue,\r
+ &ActionRequest\r
+ );\r
+\r
+ if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ //\r
+ // Clean the String in HII Database\r
+ //\r
+ DeleteString (HiiValue->Value.string, FormSet->HiiHandle);\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ switch (ActionRequest) {\r
+ case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+ gResetRequired = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+ //\r
+ // Till now there is no uncommitted data, so ignore this request\r
+ //\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
Link = GetNextNode (&Form->StatementListHead, Link);\r
}\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Initialize Question's Edit copy from Storage for the whole Formset.\r
\r
+ @param Selection Selection contains the information about \r
+ the Selection, form and formset to be displayed.\r
+ Selection action may be updated in retrieve callback.\r
@param FormSet FormSet data structure.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
**/\r
EFI_STATUS\r
LoadFormSetConfig (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_FORM *Form;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
\r
Link = GetFirstNode (&FormSet->FormListHead);\r
while (!IsNull (&FormSet->FormListHead, Link)) {\r
//\r
// Initialize local copy of Value for each Form\r
//\r
- Status = LoadFormConfig (FormSet, Form);\r
+ Status = LoadFormConfig (Selection, FormSet, Form);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Fill storage's edit copy with settings requested from Configuration Driver.\r
\r
Fetch the Ifr binary data of a FormSet.\r
\r
@param Handle PackageList Handle\r
- @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
- GUID), take the first FormSet found in package\r
- list.\r
+ @param FormSetGuid On input, GUID or class GUID of a formset. If not\r
+ specified (NULL or zero GUID), take the first\r
+ FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID\r
+ found in package list.\r
+ On output, GUID of the formset found(if not NULL).\r
@param BinaryLength The length of the FormSet IFR binary.\r
@param BinaryData The buffer designed to receive the FormSet.\r
\r
UINT8 *OpCodeData;\r
UINT32 Offset;\r
UINT32 Offset2;\r
- BOOLEAN ReturnDefault;\r
UINT32 PackageListLength;\r
EFI_HII_PACKAGE_HEADER PackageHeader;\r
UINT8 Index;\r
UINT8 NumberOfClassGuid;\r
- BOOLEAN IsSetupClassGuid;\r
+ BOOLEAN ClassGuidMatch;\r
EFI_GUID *ClassGuid;\r
+ EFI_GUID *ComparingGuid;\r
\r
OpCodeData = NULL;\r
Package = NULL;\r
- ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
+ ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
\r
//\r
- // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
+ // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list\r
//\r
if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
- ReturnDefault = TRUE;\r
+ ComparingGuid = &gEfiHiiPlatformSetupFormsetGuid;\r
} else {\r
- ReturnDefault = FALSE;\r
+ ComparingGuid = FormSetGuid;\r
}\r
\r
//\r
Offset2 = 0;\r
CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
\r
+ ClassGuidMatch = FALSE;\r
while (Offset < PackageListLength) {\r
Package = ((UINT8 *) HiiPackageList) + Offset;\r
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
\r
if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
//\r
- // Check whether return default FormSet\r
+ // Try to compare against formset GUID\r
//\r
- if (ReturnDefault) {\r
- //\r
- // Check ClassGuid of formset OpCode\r
- //\r
- IsSetupClassGuid = FALSE;\r
- NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
- ClassGuid = (EFI_GUID *) (OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
- for (Index = 0; Index < NumberOfClassGuid; Index++) {\r
- if (CompareGuid (ClassGuid + Index, &gEfiHiiPlatformSetupFormsetGuid)) {\r
- IsSetupClassGuid = TRUE;\r
- break;\r
- }\r
- }\r
- if (IsSetupClassGuid) {\r
- break;\r
- }\r
+ if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ break;\r
}\r
\r
//\r
- // FormSet GUID is specified, check it\r
+ // Try to compare against formset class GUID\r
//\r
- if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
+ ClassGuid = (EFI_GUID *) (OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
+ for (Index = 0; Index < NumberOfClassGuid; Index++) {\r
+ if (CompareGuid (ComparingGuid, ClassGuid + Index)) {\r
+ ClassGuidMatch = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ if (ClassGuidMatch) {\r
break;\r
}\r
}\r
return EFI_NOT_FOUND;\r
}\r
\r
- if (ReturnDefault && FormSetGuid != NULL) {\r
+ if (ClassGuidMatch && (FormSetGuid != NULL)) {\r
//\r
- // Return the default FormSet GUID\r
+ // Return the FormSet GUID\r
//\r
CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
}\r
Initialize the internal data structure of a FormSet.\r
\r
@param Handle PackageList Handle\r
- @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
- GUID), take the first FormSet found in package\r
- list.\r
+ @param FormSetGuid On input, GUID or class GUID of a formset. If not\r
+ specified (NULL or zero GUID), take the first\r
+ FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID\r
+ found in package list.\r
+ On output, GUID of the formset found(if not NULL).\r
@param FormSet FormSet data structure.\r
\r
@retval EFI_SUCCESS The function completed successfully.\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
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
gFrontPageHandle = FormSet->HiiHandle;\r
}\r
\r
\r
return Status;\r
}\r
+\r
+\r
+/**\r
+ Save globals used by previous call to SendForm(). SendForm() may be called from \r
+ HiiConfigAccess.Callback(), this will cause SendForm() be reentried.\r
+ So, save globals of previous call to SendForm() and restore them upon exit.\r
+\r
+**/\r
+VOID\r
+SaveBrowserContext (\r
+ VOID\r
+ )\r
+{\r
+ BROWSER_CONTEXT *Context;\r
+\r
+ gBrowserContextCount++;\r
+ if (gBrowserContextCount == 1) {\r
+ //\r
+ // This is not reentry of SendForm(), no context to save\r
+ //\r
+ return;\r
+ }\r
+\r
+ Context = AllocatePool (sizeof (BROWSER_CONTEXT));\r
+ ASSERT (Context != NULL);\r
+\r
+ Context->Signature = BROWSER_CONTEXT_SIGNATURE;\r
+\r
+ //\r
+ // Save FormBrowser context\r
+ //\r
+ Context->BannerData = gBannerData;\r
+ Context->ClassOfVfr = gClassOfVfr;\r
+ Context->FunctionKeySetting = gFunctionKeySetting;\r
+ Context->ResetRequired = gResetRequired;\r
+ Context->NvUpdateRequired = gNvUpdateRequired;\r
+ Context->Direction = gDirection;\r
+ Context->FunctionNineString = gFunctionNineString;\r
+ Context->FunctionTenString = gFunctionTenString;\r
+ Context->EnterString = gEnterString;\r
+ Context->EnterCommitString = gEnterCommitString;\r
+ Context->EnterEscapeString = gEnterEscapeString;\r
+ Context->EscapeString = gEscapeString;\r
+ Context->SaveFailed = gSaveFailed;\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
+\r
+ CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));\r
+ CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));\r
+\r
+ //\r
+ // Insert to FormBrowser context list\r
+ //\r
+ InsertHeadList (&gBrowserContextList, &Context->Link);\r
+}\r
+\r
+\r
+/**\r
+ Restore globals used by previous call to SendForm().\r
+\r
+**/\r
+VOID\r
+RestoreBrowserContext (\r
+ VOID\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ BROWSER_CONTEXT *Context;\r
+\r
+ ASSERT (gBrowserContextCount != 0);\r
+ gBrowserContextCount--;\r
+ if (gBrowserContextCount == 0) {\r
+ //\r
+ // This is not reentry of SendForm(), no context to restore\r
+ //\r
+ return;\r
+ }\r
+\r
+ ASSERT (!IsListEmpty (&gBrowserContextList));\r
+\r
+ Link = GetFirstNode (&gBrowserContextList);\r
+ Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
+\r
+ //\r
+ // Restore FormBrowser context\r
+ //\r
+ gBannerData = Context->BannerData;\r
+ gClassOfVfr = Context->ClassOfVfr;\r
+ gFunctionKeySetting = Context->FunctionKeySetting;\r
+ gResetRequired = Context->ResetRequired;\r
+ gNvUpdateRequired = Context->NvUpdateRequired;\r
+ gDirection = Context->Direction;\r
+ gFunctionNineString = Context->FunctionNineString;\r
+ gFunctionTenString = Context->FunctionTenString;\r
+ gEnterString = Context->EnterString;\r
+ gEnterCommitString = Context->EnterCommitString;\r
+ gEnterEscapeString = Context->EnterEscapeString;\r
+ gEscapeString = Context->EscapeString;\r
+ gSaveFailed = Context->SaveFailed;\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
+\r
+ CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));\r
+ CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));\r
+\r
+ //\r
+ // Remove from FormBrowser context list\r
+ //\r
+ RemoveEntryList (&Context->Link);\r
+ gBS->FreePool (Context);\r
+}\r