//\r
// Question value may be changed, need invoke its Callback()\r
//\r
- ProcessCallBackFunction (gCurrentSelection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+ ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
\r
if (mHiiPackageListUpdated) {\r
//\r
}\r
}\r
\r
+/**\r
+\r
+ Get the extra question attribute from override question list.\r
+\r
+ @param QuestionId The question id for this request question.\r
+\r
+ @retval The attribute for this question or NULL if not found this \r
+ question in the list.\r
+\r
+**/\r
+UINT32 \r
+ProcessQuestionExtraAttr (\r
+ IN EFI_QUESTION_ID QuestionId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_ATTRIBUTE_OVERRIDE *QuestionDesc;\r
+\r
+ //\r
+ // Return HII_DISPLAY_NONE if input a invalid question id.\r
+ //\r
+ if (QuestionId == 0) {\r
+ return HII_DISPLAY_NONE;\r
+ }\r
+\r
+ Link = GetFirstNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
+ while (!IsNull (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link)) {\r
+ QuestionDesc = FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link);\r
+ Link = GetNextNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link);\r
+\r
+ if ((QuestionDesc->QuestionId == QuestionId) &&\r
+ (QuestionDesc->FormId == gCurrentSelection->FormId) &&\r
+ (QuestionDesc->HiiHandle == gCurrentSelection->Handle) &&\r
+ CompareGuid (&QuestionDesc->FormSetGuid, &gCurrentSelection->FormSetGuid)) {\r
+ return QuestionDesc->Attribute;\r
+ }\r
+ }\r
+\r
+ return HII_DISPLAY_NONE;\r
+}\r
+\r
/**\r
\r
Enum all statement in current form, find all the statement can be display and\r
EFI_EVENT RefreshIntervalEvent;\r
FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
BOOLEAN FormEditable;\r
+ UINT32 ExtraAttribute;\r
\r
HostDisplayStatement = NULL;\r
MinRefreshInterval = 0;\r
continue;\r
}\r
\r
+ //\r
+ // Check the extra attribute.\r
+ //\r
+ ExtraAttribute = ProcessQuestionExtraAttr (Statement->QuestionId);\r
+ if ((ExtraAttribute & HII_DISPLAY_SUPPRESS) != 0) {\r
+ continue;\r
+ }\r
+\r
DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
ASSERT (DisplayStatement != NULL);\r
\r
//\r
InitializeDisplayStatement(DisplayStatement, Statement, HostDisplayStatement);\r
\r
+ //\r
+ // Set the extra attribute.\r
+ //\r
+ DisplayStatement->Attribute |= ExtraAttribute;\r
+\r
//\r
// Save the Host statement info.\r
// Host statement may has nest statement follow it.\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Check whether the formset guid is in this Hii package list.\r
+\r
+ @param HiiHandle The HiiHandle for this HII package list.\r
+ @param FormSetGuid The formset guid for the request formset.\r
+\r
+ @retval TRUE Find the formset guid.\r
+ @retval FALSE Not found the formset guid.\r
+\r
+**/\r
+BOOLEAN\r
+GetFormsetGuidFromHiiHandle (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *FormSetGuid\r
+ )\r
+{\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ UINT32 Offset;\r
+ UINT32 Offset2;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ UINT8 *Package;\r
+ UINT8 *OpCodeData;\r
+ EFI_STATUS Status;\r
+ BOOLEAN FindGuid;\r
+\r
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ FindGuid = FALSE;\r
+ \r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+ }\r
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Get Form package from this HII package List\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *) HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ Offset += PackageHeader.Length;\r
+\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+ //\r
+ // Search FormSet in this Form Package\r
+ //\r
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset2 < PackageHeader.Length) {\r
+ OpCodeData = Package + Offset2;\r
+\r
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))){\r
+ FindGuid = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ }\r
+ }\r
+ if (FindGuid) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (HiiPackageList);\r
+\r
+ return FindGuid;\r
+}\r
\r
/**\r
Find HII Handle in the HII database associated with given Device Path.\r
\r
@param DevicePath Device Path associated with the HII package list\r
handle.\r
+ @param FormsetGuid The formset guid for this formset.\r
\r
@retval Handle HII package list Handle associated with the Device\r
Path.\r
\r
**/\r
EFI_HII_HANDLE\r
-EFIAPI\r
DevicePathToHiiHandle (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN EFI_GUID *FormsetGuid\r
)\r
{\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
- UINTN BufferSize;\r
- UINTN HandleCount;\r
UINTN Index;\r
EFI_HANDLE Handle;\r
EFI_HANDLE DriverHandle;\r
//\r
// Retrieve all HII Handles from HII database\r
//\r
- BufferSize = 0x1000;\r
- HiiHandles = AllocatePool (BufferSize);\r
- ASSERT (HiiHandles != NULL);\r
- Status = mHiiDatabase->ListPackageLists (\r
- mHiiDatabase,\r
- EFI_HII_PACKAGE_TYPE_ALL,\r
- NULL,\r
- &BufferSize,\r
- HiiHandles\r
- );\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- FreePool (HiiHandles);\r
- HiiHandles = AllocatePool (BufferSize);\r
- ASSERT (HiiHandles != NULL);\r
-\r
- Status = mHiiDatabase->ListPackageLists (\r
- mHiiDatabase,\r
- EFI_HII_PACKAGE_TYPE_ALL,\r
- NULL,\r
- &BufferSize,\r
- HiiHandles\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (HiiHandles);\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ if (HiiHandles == NULL) {\r
return NULL;\r
}\r
\r
// Search Hii Handle by Driver Handle\r
//\r
HiiHandle = NULL;\r
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
- for (Index = 0; Index < HandleCount; Index++) {\r
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
Status = mHiiDatabase->GetPackageListHandle (\r
mHiiDatabase,\r
HiiHandles[Index],\r
&Handle\r
);\r
if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
- HiiHandle = HiiHandles[Index];\r
- break;\r
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], FormsetGuid)) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
+ }\r
+\r
+ if (HiiHandle != NULL) {\r
+ break;\r
+ }\r
}\r
}\r
\r
)\r
{\r
EFI_HII_HANDLE *HiiHandles;\r
- UINTN Index;\r
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
- UINTN BufferSize;\r
- UINT32 Offset;\r
- UINT32 Offset2;\r
- UINT32 PackageListLength;\r
- EFI_HII_PACKAGE_HEADER PackageHeader;\r
- UINT8 *Package;\r
- UINT8 *OpCodeData;\r
- EFI_STATUS Status;\r
EFI_HII_HANDLE HiiHandle;\r
+ UINTN Index;\r
\r
ASSERT (ComparingGuid != NULL);\r
\r
// Search for formset of each class type\r
//\r
for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
- BufferSize = 0;\r
- HiiPackageList = NULL;\r
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- HiiPackageList = AllocatePool (BufferSize);\r
- ASSERT (HiiPackageList != NULL);\r
-\r
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
- }\r
- if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
- return NULL;\r
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], ComparingGuid)) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
}\r
\r
- //\r
- // Get Form package from this HII package List\r
- //\r
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
- Offset2 = 0;\r
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
-\r
- while (Offset < PackageListLength) {\r
- Package = ((UINT8 *) HiiPackageList) + Offset;\r
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
- //\r
- // Search FormSet in this Form Package\r
- //\r
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
- while (Offset2 < PackageHeader.Length) {\r
- OpCodeData = Package + Offset2;\r
-\r
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
- //\r
- // Try to compare against formset GUID\r
- //\r
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
- HiiHandle = HiiHandles[Index];\r
- break;\r
- }\r
- }\r
-\r
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
- }\r
- }\r
- if (HiiHandle != NULL) {\r
- break;\r
- }\r
- Offset += PackageHeader.Length;\r
+ if (HiiHandle != NULL) {\r
+ break;\r
}\r
- \r
- FreePool (HiiPackageList);\r
- if (HiiHandle != NULL) {\r
- break;\r
- }\r
}\r
\r
FreePool (HiiHandles);\r
//\r
// Check whether the device path string is a valid string.\r
//\r
- if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {\r
+ if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL && StringPtr[0] != L'\0') {\r
if (Selection->Form->ModalForm) {\r
return Status;\r
}\r
if (mPathFromText != NULL) {\r
DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);\r
if (DevicePath != NULL) {\r
- HiiHandle = DevicePathToHiiHandle (DevicePath);\r
+ HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);\r
FreePool (DevicePath);\r
}\r
FreePool (StringPtr);\r
EFI_STATUS Status;\r
CHAR16 *ConfigResp;\r
CHAR16 *Progress;\r
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
\r
if (Question->QuestionConfig == 0) {\r
return EFI_SUCCESS;\r
//\r
// Send config to Configuration Driver\r
//\r
- ConfigAccess = Selection->FormSet->ConfigAccess;\r
- if (ConfigAccess == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Status = ConfigAccess->RouteConfig (\r
- ConfigAccess,\r
+ Status = mHiiConfigRouting->RouteConfig (\r
+ mHiiConfigRouting,\r
ConfigResp,\r
&Progress\r
);\r
CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));\r
break;\r
}\r
- if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
- SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
- }\r
break;\r
}\r
}\r
about the Selection, form and formset to be displayed.\r
On output, Selection return the screen item that is selected\r
by user.\r
+ @param FormSet The formset this question belong to.\r
+ @param Form The form this question belong to.\r
@param Question The Question which need to call.\r
@param Action The action request.\r
@param SkipSaveOrDiscard Whether skip save or discard action.\r
EFI_STATUS \r
ProcessCallBackFunction (\r
IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
IN FORM_BROWSER_STATEMENT *Question,\r
IN EFI_BROWSER_ACTION Action,\r
IN BOOLEAN SkipSaveOrDiscard\r
BOOLEAN NeedExit;\r
LIST_ENTRY *Link;\r
BROWSER_SETTING_SCOPE SettingLevel;\r
+ EFI_IFR_TYPE_VALUE BackUpValue;\r
+ UINT8 *BackUpBuffer;\r
\r
- ConfigAccess = Selection->FormSet->ConfigAccess;\r
+ ConfigAccess = FormSet->ConfigAccess;\r
SubmitFormIsRequired = FALSE;\r
SettingLevel = FormSetLevel;\r
DiscardFormIsRequired = FALSE;\r
NeedExit = FALSE;\r
Status = EFI_SUCCESS;\r
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ BackUpBuffer = NULL;\r
\r
if (ConfigAccess == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
- Link = GetFirstNode (&Selection->Form->StatementListHead);\r
- while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
- Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
\r
//\r
// if Question != NULL, only process the question. Else, process all question in this form.\r
// Check whether Statement is disabled.\r
//\r
if (Statement->Expression != NULL) {\r
- if (EvaluateExpressionList(Statement->Expression, TRUE, Selection->FormSet, Selection->Form) == ExpressDisable) {\r
+ if (EvaluateExpressionList(Statement->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
continue;\r
}\r
}\r
//\r
TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
}\r
- \r
+\r
+ //\r
+ // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.\r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ BackUpBuffer = AllocateCopyPool(Statement->StorageWidth + sizeof(CHAR16), Statement->BufferValue);\r
+ } else {\r
+ CopyMem (&BackUpValue, &HiiValue->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+ }\r
+ }\r
+\r
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
Status = ConfigAccess->Callback (\r
ConfigAccess,\r
// "retrieve" should update to the question's temp buffer.\r
//\r
if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
- SetQuestionValue(Selection->FormSet, Selection->Form, Statement, GetSetValueWithEditBuffer);\r
+ SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
}\r
} else {\r
+ //\r
+ // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING, \r
+ // then the browser will use the value passed to Callback() and ignore the \r
+ // value returned by Callback(). \r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING && Status == EFI_UNSUPPORTED) {\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth + sizeof(CHAR16));\r
+ } else {\r
+ CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
+ }\r
+\r
+ SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
+ }\r
+\r
//\r
// According the spec, return fail from call back of "changing" and \r
// "retrieve", should restore the question's value.\r
//\r
- if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
- GetQuestionValue(Selection->FormSet, Selection->Form, Statement, GetSetValueWithEditBuffer);\r
+ if ((Action == EFI_BROWSER_ACTION_CHANGING && Status != EFI_UNSUPPORTED) || \r
+ Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ GetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
}\r
\r
if (Status == EFI_UNSUPPORTED) {\r
Status = EFI_SUCCESS;\r
}\r
}\r
+\r
+ if (BackUpBuffer != NULL) {\r
+ FreePool (BackUpBuffer);\r
+ }\r
}\r
\r
if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
- SubmitForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ SubmitForm (FormSet, Form, SettingLevel);\r
}\r
\r
if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
- DiscardForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ DiscardForm (FormSet, Form, SettingLevel);\r
}\r
\r
if (NeedExit) {\r
return Status;\r
}\r
\r
+ if ((Selection->Handle != mCurrentHiiHandle) ||\r
+ (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid))) {\r
+ gFinishRetrieveCall = FALSE;\r
+ }\r
+\r
//\r
// Initialize current settings of Questions in this FormSet\r
//\r
CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
mCurrentFormId = Selection->FormId;\r
\r
- Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
+ Status = ProcessCallBackFunction (Selection, gCurrentSelection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
goto Done;\r
}\r
\r
+ //\r
+ // Finish call RETRIEVE callback for this formset.\r
+ //\r
+ gFinishRetrieveCall = TRUE;\r
+\r
//\r
// IFR is updated during callback of read value, force to reparse the IFR binary\r
//\r
if ((ConfigAccess != NULL) && \r
((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
(Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
- Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+ Status = ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
if (Statement->Operand == EFI_IFR_REF_OP) {\r
//\r
// Process dynamic update ref opcode.\r
}\r
\r
if (!EFI_ERROR (Status) && Statement->Operand != EFI_IFR_REF_OP) {\r
- ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+ ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
}\r
+ } else if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
+ SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
}\r
}\r
\r
(!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
(Selection->FormId != mCurrentFormId))) {\r
\r
- Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
+ Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r