/** @file\r
Entry and initialization module for the browser.\r
\r
-Copyright (c) 2007 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
**/\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
UINTN gFunctionKeySetting;\r
BOOLEAN gResetRequired;\r
-BOOLEAN gNvUpdateRequired;\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
//\r
-CHAR16 *gFunctionOneString;\r
CHAR16 *gFunctionNineString;\r
CHAR16 *gFunctionTenString;\r
CHAR16 *gEnterString;\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
\r
gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
- gHelpBlockWidth = gOptionBlockWidth;\r
- gPromptBlockWidth = gOptionBlockWidth;\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
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
- gNvUpdateRequired = FALSE;\r
+ gOldFormSet = NULL;\r
\r
do {\r
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\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
//\r
// Generate <ConfigResp>\r
//\r
- Status = StorageToConfigResp (Storage, &ConfigResp);\r
+ Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
{\r
EFI_STRING String;\r
\r
+ if (HiiHandle == NULL) {\r
+ return NULL;\r
+ }\r
+\r
String = HiiGetString (HiiHandle, Token, NULL);\r
if (String == NULL) {\r
String = AllocateCopyPool (sizeof (mUnknownString), mUnknownString);\r
@param Storage The NameValue Storage.\r
@param Name The Name.\r
@param Value The Value to set.\r
+ @param Edit Whether update editValue or Value.\r
\r
@retval EFI_SUCCESS Value found for given Name.\r
@retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
SetValueByName (\r
IN FORMSET_STORAGE *Storage,\r
IN CHAR16 *Name,\r
- IN CHAR16 *Value\r
+ IN CHAR16 *Value,\r
+ IN BOOLEAN Edit\r
)\r
{\r
LIST_ENTRY *Link;\r
NAME_VALUE_NODE *Node;\r
+ CHAR16 *Buffer;\r
\r
Link = GetFirstNode (&Storage->NameValueListHead);\r
while (!IsNull (&Storage->NameValueListHead, Link)) {\r
Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
\r
if (StrCmp (Name, Node->Name) == 0) {\r
- if (Node->EditValue != NULL) {\r
- FreePool (Node->EditValue);\r
+ if (Edit) {\r
+ Buffer = Node->EditValue;\r
+ } else {\r
+ Buffer = Node->Value;\r
+ }\r
+ if (Buffer != NULL) {\r
+ FreePool (Buffer);\r
+ }\r
+ Buffer = AllocateCopyPool (StrSize (Value), Value);\r
+ ASSERT (Buffer != NULL);\r
+ if (Edit) {\r
+ Node->EditValue = Buffer;\r
+ } else {\r
+ Node->Value = Buffer;\r
}\r
- Node->EditValue = AllocateCopyPool (StrSize (Value), Value);\r
- ASSERT (Node->EditValue != NULL);\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
\r
- @param Storage The Storage to be conveted.\r
+ @param Buffer The Storage to be conveted.\r
@param ConfigResp The returned <ConfigResp>.\r
+ @param SingleForm Whether update data for single form or formset level.\r
\r
@retval EFI_SUCCESS Convert success.\r
@retval EFI_INVALID_PARAMETER Incorrect storage type.\r
**/\r
EFI_STATUS\r
StorageToConfigResp (\r
- IN FORMSET_STORAGE *Storage,\r
- IN CHAR16 **ConfigResp\r
+ IN VOID *Buffer,\r
+ IN CHAR16 **ConfigResp,\r
+ IN BOOLEAN SingleForm\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STRING Progress;\r
LIST_ENTRY *Link;\r
NAME_VALUE_NODE *Node;\r
+ CHAR16 *ConfigRequest;\r
+ FORMSET_STORAGE *Storage;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
\r
Status = EFI_SUCCESS;\r
+ if (SingleForm) {\r
+ ConfigInfo = (FORM_BROWSER_CONFIG_REQUEST *) Buffer;\r
+ Storage = ConfigInfo->Storage;\r
+ ConfigRequest = ConfigInfo->ConfigRequest;\r
+ } else {\r
+ Storage = (FORMSET_STORAGE *) Buffer;\r
+ ConfigRequest = Storage->ConfigRequest;\r
+ }\r
\r
switch (Storage->Type) {\r
case EFI_HII_VARSTORE_BUFFER:\r
Status = mHiiConfigRouting->BlockToConfig (\r
mHiiConfigRouting,\r
- Storage->ConfigRequest,\r
+ ConfigRequest,\r
Storage->EditBuffer,\r
Storage->Size,\r
ConfigResp,\r
while (!IsNull (&Storage->NameValueListHead, Link)) {\r
Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
\r
- NewStringCat (ConfigResp, L"&");\r
- NewStringCat (ConfigResp, Node->Name);\r
- NewStringCat (ConfigResp, L"=");\r
- NewStringCat (ConfigResp, Node->EditValue);\r
-\r
+ if (StrStr (ConfigRequest, Node->Name) != NULL) {\r
+ NewStringCat (ConfigResp, L"&");\r
+ NewStringCat (ConfigResp, Node->Name);\r
+ NewStringCat (ConfigResp, L"=");\r
+ NewStringCat (ConfigResp, Node->EditValue);\r
+ }\r
Link = GetNextNode (&Storage->NameValueListHead, Link);\r
}\r
break;\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
if (StrPtr != NULL) {\r
*StrPtr = 0;\r
}\r
- SetValueByName (Storage, Name, Value);\r
+ SetValueByName (Storage, Name, Value, TRUE);\r
}\r
break;\r
\r
}\r
return Status;\r
}\r
+ \r
+ //\r
+ // Get question value by read expression.\r
+ //\r
+ if (Question->ReadExpression != NULL && Form->FormType == STANDARD_MAP_FORM_TYPE) {\r
+ Status = EvaluateExpression (FormSet, Form, Question->ReadExpression);\r
+ if (!EFI_ERROR (Status) && (Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER)) {\r
+ //\r
+ // Only update question value to the valid result.\r
+ //\r
+ CopyMem (&Question->HiiValue, &Question->ReadExpression->Result, sizeof (EFI_HII_VALUE));\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
\r
//\r
// Question value is provided by RTC\r
//\r
CopyMem (Dst, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
} else {\r
+ Value = NULL;\r
Status = GetValueByName (Storage, Question->VariableName, &Value);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ ASSERT (Value != NULL);\r
LengthStr = StrLen (Value);\r
Status = EFI_SUCCESS;\r
if (IsString) {\r
if (IsBufferStorage) {\r
CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
} else {\r
- SetValueByName (Storage, Question->VariableName, Value);\r
+ SetValueByName (Storage, Question->VariableName, Value, TRUE);\r
}\r
\r
FreePool (Result);\r
if (Question->ValueExpression != NULL) {\r
return Status;\r
}\r
+ \r
+ //\r
+ // Before set question value, evaluate its write expression.\r
+ //\r
+ if (Question->WriteExpression != NULL && Form->FormType == STANDARD_MAP_FORM_TYPE) {\r
+ Status = EvaluateExpression (FormSet, Form, Question->WriteExpression);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
\r
//\r
// Question value is provided by RTC\r
}\r
}\r
\r
- Status = SetValueByName (Storage, Question->VariableName, Value);\r
+ Status = SetValueByName (Storage, Question->VariableName, Value, TRUE);\r
FreePool (Value);\r
}\r
\r
\r
\r
/**\r
- Perform NoSubmit check for a Form.\r
+ Perform NoSubmit check for each Form in FormSet.\r
\r
@param FormSet FormSet data structure.\r
- @param Form Form data structure.\r
+ @param CurrentForm Current input form data structure.\r
\r
@retval EFI_SUCCESS Form validation pass.\r
@retval other Form validation failed.\r
EFI_STATUS\r
NoSubmitCheck (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
+ IN FORM_BROWSER_FORM *CurrentForm\r
)\r
{\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
+ FORM_BROWSER_FORM *Form;\r
+ LIST_ENTRY *LinkForm;\r
\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- while (!IsNull (&Form->StatementListHead, Link)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ LinkForm = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, LinkForm)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);\r
+ LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
+\r
+ if (CurrentForm != NULL && CurrentForm != Form) {\r
+ continue;\r
+ }\r
+\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+ Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Restore Storage's Edit copy to Shadow copy.\r
+\r
+ @param Storage The Storage to be synchronized.\r
+\r
+**/\r
+VOID\r
+RestoreStorage (\r
+ IN FORMSET_STORAGE *Storage\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ NAME_VALUE_NODE *Node;\r
+\r
+ switch (Storage->Type) {\r
+ case EFI_HII_VARSTORE_BUFFER:\r
+ CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);\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 (Node->EditValue != NULL) {\r
+ FreePool (Node->EditValue);\r
+ }\r
+ Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);\r
+ ASSERT (Node->EditValue != NULL);\r
+ Link = GetNextNode (&Storage->NameValueListHead, Link);\r
+ }\r
+ break;\r
+\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+ default:\r
+ break;\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 ConfigInfo The config info related to this form.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+FormRestoreStorage (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING Progress;\r
+ EFI_STRING Result;\r
+ UINTN BufferSize;\r
+ LIST_ENTRY *Link;\r
+ NAME_VALUE_NODE *Node;\r
+\r
+ Status = EFI_SUCCESS;\r
+ Result = NULL;\r
+ if (FormSet->ConfigAccess == NULL) {\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
- Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+ BufferSize = ConfigInfo->Storage->Size;\r
+ Status = mHiiConfigRouting->BlockToConfig(\r
+ mHiiConfigRouting,\r
+ ConfigInfo->ConfigRequest,\r
+ ConfigInfo->Storage->Buffer,\r
+ BufferSize,\r
+ &Result,\r
+ &Progress\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
+ Status = mHiiConfigRouting->ConfigToBlock (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ ConfigInfo->Storage->EditBuffer,\r
+ &BufferSize,\r
+ &Progress\r
+ );\r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\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
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+\r
+ if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {\r
+ if (Node->EditValue != NULL) {\r
+ FreePool (Node->EditValue);\r
+ }\r
+ Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);\r
+ ASSERT (Node->EditValue != NULL);\r
+ }\r
+\r
+ Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);\r
+ }\r
}\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
\r
/**\r
- Submit a Form.\r
+ Discard data for form level or formset level.\r
\r
@param FormSet FormSet data structure.\r
@param Form Form data structure.\r
+ @param SingleForm Only discard single form or formset.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+DiscardForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BOOLEAN SingleForm\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *Storage;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+\r
+ if (SingleForm) {\r
+ if (Form->NvUpdateRequired) {\r
+ ConfigInfo = NULL;\r
+ Link = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (ConfigInfo->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Prepare <ConfigResp>\r
+ //\r
+ FormRestoreStorage(FormSet, ConfigInfo);\r
+ }\r
+\r
+ Form->NvUpdateRequired = FALSE;\r
+ }\r
+ } else {\r
+ if (IsNvUpdateRequired(FormSet)) {\r
+ //\r
+ // Discard Buffer storage or Name/Value storage\r
+ //\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (Storage->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ RestoreStorage(Storage);\r
+ }\r
+\r
+ UpdateNvInfoInForm(FormSet, FALSE); \r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS; \r
+}\r
+\r
+/**\r
+ Submit data for form level or formset level.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param SingleForm whether submit for the single form or all form set.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
\r
EFI_STATUS\r
SubmitForm (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BOOLEAN SingleForm\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STRING ConfigResp;\r
EFI_STRING Progress;\r
FORMSET_STORAGE *Storage;\r
+ FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
\r
//\r
// Validate the Form by NoSubmit check\r
//\r
- Status = NoSubmitCheck (FormSet, Form);\r
+ if (SingleForm) {\r
+ Status = NoSubmitCheck (FormSet, Form);\r
+ } else {\r
+ Status = NoSubmitCheck (FormSet, NULL);\r
+ }\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- //\r
- // Submit Buffer storage or Name/Value storage\r
- //\r
- Link = GetFirstNode (&FormSet->StorageListHead);\r
- while (!IsNull (&FormSet->StorageListHead, Link)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
- Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+ if (SingleForm) {\r
+ ConfigInfo = NULL;\r
+ Link = GetFirstNode (&Form->ConfigRequestHead);\r
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
\r
- if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- continue;\r
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (ConfigInfo->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Prepare <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\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
+ FreePool (ConfigResp);\r
+\r
+ //\r
+ // Config success, update storage shadow Buffer\r
+ //\r
+ SynchronizeStorage (ConfigInfo->Storage);\r
}\r
\r
+ Form->NvUpdateRequired = FALSE;\r
+ } else {\r
//\r
- // Skip if there is no RequestElement\r
+ // Submit Buffer storage or Name/Value storage\r
//\r
- if (Storage->ElementCount == 0) {\r
- continue;\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->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Skip if there is no RequestElement\r
+ //\r
+ if (Storage->ElementCount == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Prepare <ConfigResp>\r
+ //\r
+ Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\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
+ FreePool (ConfigResp);\r
+\r
+ //\r
+ // Config success, update storage shadow Buffer\r
+ //\r
+ SynchronizeStorage (Storage);\r
}\r
\r
+ UpdateNvInfoInForm(FormSet, FALSE);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Get Question default value from AltCfg string.\r
+\r
+ @param FormSet The form set.\r
+ @param Question The question.\r
+ @param DefaultId The default Id.\r
+\r
+ @retval EFI_SUCCESS Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetDefaultValueFromAltCfg (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN OUT FORM_BROWSER_STATEMENT *Question,\r
+ IN UINT16 DefaultId\r
+ )\r
+{\r
+ BOOLEAN IsBufferStorage;\r
+ BOOLEAN IsString; \r
+ UINTN Length;\r
+ FORMSET_STORAGE *Storage;\r
+ CHAR16 *ConfigRequest;\r
+ CHAR16 *Progress;\r
+ CHAR16 *Result;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Value;\r
+ CHAR16 *StringPtr;\r
+ UINTN LengthStr;\r
+ UINT8 *Dst;\r
+ CHAR16 TemStr[5];\r
+ UINTN Index;\r
+ UINT8 DigitUint8;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ Length = 0;\r
+ Dst = NULL;\r
+ ConfigRequest = NULL;\r
+ Result = NULL;\r
+ ConfigResp = NULL;\r
+ Storage = Question->Storage;\r
+\r
+ if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Question Value is provided by Buffer Storage or NameValue Storage\r
+ //\r
+ if (Question->BufferValue != NULL) {\r
//\r
- // Prepare <ConfigResp>\r
+ // This Question is password or orderedlist\r
//\r
- Status = StorageToConfigResp (Storage, &ConfigResp);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ Dst = Question->BufferValue;\r
+ } else {\r
+ //\r
+ // Other type of Questions\r
+ //\r
+ Dst = (UINT8 *) &Question->HiiValue.Value;\r
+ }\r
+\r
+ IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\r
+ IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
+\r
+ //\r
+ // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
+ // <ConfigHdr> + "&" + <VariableName>\r
+ //\r
+ if (IsBufferStorage) {\r
+ Length = StrLen (Storage->ConfigHdr);\r
+ Length += StrLen (Question->BlockName);\r
+ } else {\r
+ Length = StrLen (Storage->ConfigHdr);\r
+ Length += StrLen (Question->VariableName) + 1;\r
+ }\r
+ ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
+ ASSERT (ConfigRequest != NULL);\r
+\r
+ StrCpy (ConfigRequest, Storage->ConfigHdr);\r
+ if (IsBufferStorage) {\r
+ StrCat (ConfigRequest, Question->BlockName);\r
+ } else {\r
+ StrCat (ConfigRequest, L"&");\r
+ StrCat (ConfigRequest, Question->VariableName);\r
+ }\r
\r
+ Status = FormSet->ConfigAccess->ExtractConfig (\r
+ FormSet->ConfigAccess,\r
+ ConfigRequest,\r
+ &Progress,\r
+ &Result\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+ // Get the default configuration string according to the default ID.\r
+ //\r
+ Status = mHiiConfigRouting->GetAltConfig (\r
+ mHiiConfigRouting,\r
+ Result,\r
+ &Storage->Guid,\r
+ Storage->Name,\r
+ NULL,\r
+ &DefaultId, // it can be NULL to get the current setting.\r
+ &ConfigResp\r
+ );\r
+ \r
+ //\r
+ // The required setting can't be found. So, it is not required to be validated and set.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Skip <ConfigRequest>\r
+ //\r
+ Value = StrStr (ConfigResp, L"&VALUE");\r
+ if (IsBufferStorage) {\r
//\r
- // Send <ConfigResp> to Configuration Driver\r
+ // Skip "&VALUE"\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
+ Value = Value + 6;\r
+ }\r
+ if (*Value != '=') {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Skip '=', point to value\r
+ //\r
+ Value = Value + 1;\r
+\r
+ //\r
+ // Suppress <AltResp> if any\r
+ //\r
+ StringPtr = Value;\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr++;\r
+ }\r
+ *StringPtr = L'\0';\r
\r
+ LengthStr = StrLen (Value);\r
+ if (!IsBufferStorage && IsString) {\r
+ StringPtr = (CHAR16 *) Dst;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < LengthStr; Index += 4) {\r
+ StrnCpy (TemStr, Value + Index, 4);\r
+ StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+ }\r
//\r
- // Config success, update storage shadow Buffer\r
+ // Add tailing L'\0' character\r
//\r
- SynchronizeStorage (Storage);\r
+ StringPtr[Index/4] = L'\0';\r
+ } else {\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < LengthStr; Index ++) {\r
+ TemStr[0] = Value[LengthStr - Index - 1];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+ if ((Index & 1) == 0) {\r
+ Dst [Index/2] = DigitUint8;\r
+ } else {\r
+ Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+ }\r
+ }\r
}\r
\r
- gNvUpdateRequired = FALSE;\r
+Done:\r
+ if (ConfigRequest != NULL){\r
+ FreePool (ConfigRequest);\r
+ }\r
\r
- return EFI_SUCCESS;\r
+ if (ConfigResp != NULL) {\r
+ FreePool (ConfigResp);\r
+ }\r
+ \r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
+/**\r
+ Get default Id value used for browser.\r
+\r
+ @param DefaultId The default id value used by hii.\r
+\r
+ @retval Browser used default value.\r
+\r
+**/\r
+INTN\r
+GetDefaultIdForCallBack (\r
+ UINTN DefaultId\r
+ )\r
+{ \r
+ if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
+ } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
+ } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
+ } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
+ } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
+ } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000) {\r
+ return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
+ } else {\r
+ return -1;\r
+ }\r
+}\r
\r
/**\r
Reset Question to its default value.\r
EFI_HII_VALUE *HiiValue;\r
UINT8 Index;\r
EFI_STRING StrValue;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ INTN Action;\r
\r
Status = EFI_SUCCESS;\r
StrValue = NULL;\r
}\r
\r
//\r
- // There are three ways to specify default value for a Question:\r
- // 1, use nested EFI_IFR_DEFAULT (highest priority)\r
- // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
- // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
+ // There are Five ways to specify default value for a Question:\r
+ // 1, use call back function (highest priority)\r
+ // 2, use ExtractConfig function\r
+ // 3, use nested EFI_IFR_DEFAULT \r
+ // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
+ // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
//\r
HiiValue = &Question->HiiValue;\r
\r
+ //\r
+ // Get Question defaut value from call back function.\r
+ //\r
+ ConfigAccess = FormSet->ConfigAccess;\r
+ Action = GetDefaultIdForCallBack (DefaultId);\r
+ if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ Action,\r
+ Question->QuestionId,\r
+ HiiValue->Type,\r
+ &HiiValue->Value,\r
+ &ActionRequest\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get default value from altcfg string.\r
+ //\r
+ if (ConfigAccess != NULL) { \r
+ Status = GetDefaultValueFromAltCfg(FormSet, Question, DefaultId);\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
//\r
// EFI_IFR_DEFAULT has highest priority\r
//\r
// For Questions without default\r
//\r
switch (Question->Operand) {\r
+ case EFI_IFR_NUMERIC_OP:\r
+ //\r
+ // Take minimum value as numeric default value\r
+ //\r
+ if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r
+ HiiValue->Value.u64 = Question->Minimum;\r
+ }\r
+ break;\r
+\r
case EFI_IFR_ONE_OF_OP:\r
//\r
// Take first oneof option as oneof's default value\r
while (!IsNull (&Question->OptionListHead, Link)) {\r
Option = QUESTION_OPTION_FROM_LINK (Link);\r
\r
- Question->BufferValue[Index] = Option->Value.Value.u8;\r
+ SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r
\r
Index++;\r
if (Index >= Question->MaxContainers) {\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
+ \r
Link = GetFirstNode (&Form->StatementListHead);\r
while (!IsNull (&Form->StatementListHead, Link)) {\r
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
return Status;\r
}\r
\r
+ if ((Question->Operand == EFI_IFR_STRING_OP) || (Question->Operand == EFI_IFR_PASSWORD_OP)) {\r
+ HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);\r
+ }\r
+\r
+ //\r
+ // Check whether EfiVarstore with CallBack can be got.\r
+ //\r
+ if ((FormSet->ConfigAccess != NULL) &&\r
+ (Selection->Action != UI_ACTION_REFRESH_FORMSET) &&\r
+ (Question->QuestionId != 0) && \r
+ (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
+ //\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
+ Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
+ }\r
+ }\r
+\r
Link = GetNextNode (&Form->StatementListHead, Link);\r
}\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
switch (Src->Type) {\r
case EFI_HII_VARSTORE_BUFFER:\r
CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);\r
+ CopyMem (Dst->Buffer, Src->Buffer, Src->Size);\r
break;\r
\r
case EFI_HII_VARSTORE_NAME_VALUE:\r
while (!IsNull (&Src->NameValueListHead, Link)) {\r
Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
\r
- SetValueByName (Dst, Node->Name, Node->EditValue);\r
+ SetValueByName (Dst, Node->Name, Node->EditValue, TRUE);\r
+ SetValueByName (Dst, Node->Name, Node->Value, FALSE);\r
\r
Link = GetNextNode (&Src->NameValueListHead, Link);\r
}\r
// Storage is not found in backup formset, request it from ConfigDriver\r
//\r
Status = LoadStorage (FormSet, Storage);\r
+ //\r
+ // Now Edit Buffer is filled with default values(lower priority) and current\r
+ // settings(higher priority), sychronize it to shadow Buffer\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ SynchronizeStorage (Storage);\r
+ }\r
} else {\r
//\r
// Storage found in backup formset, use it\r
Status = CopyStorage (Storage, OldStorage);\r
}\r
\r
- //\r
- // Now Edit Buffer is filled with default values(lower priority) and current\r
- // settings(higher priority), sychronize it to shadow Buffer\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- SynchronizeStorage (Storage);\r
- }\r
-\r
Link = GetNextNode (&FormSet->StorageListHead, Link);\r
}\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
+ if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ break;\r
+ }\r
+\r
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
//\r
- // Check ClassGuid of formset OpCode\r
+ // Try to compare against formset class GUID\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
+ if (CompareGuid (ComparingGuid, ClassGuid + Index)) {\r
+ ClassGuidMatch = TRUE;\r
break;\r
}\r
}\r
- if (IsSetupClassGuid) {\r
+ if (ClassGuidMatch) {\r
break;\r
}\r
- }\r
-\r
- //\r
- // FormSet GUID is specified, check it\r
- //\r
- if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ } else if (ComparingGuid == &gEfiHiiPlatformSetupFormsetGuid) {\r
+ ClassGuidMatch = TRUE;\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
// Function key prompt can not be displayed if the function key has been disabled.\r
//\r
- if ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE) {\r
- gFunctionOneString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- }\r
-\r
if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {\r
gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\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->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
+ 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