// Find the same FromSet.\r
//\r
if (MenuList->HiiHandle == HiiHandle) {\r
- if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {\r
+ if (IsZeroGuid (&MenuList->FormSetGuid)) {\r
//\r
// FormSetGuid is not specified.\r
//\r
\r
Status = gBS->InstallProtocolInterface (\r
&mPrivateData.Handle,\r
- &gEfiFormBrowserExProtocolGuid,\r
+ &gEdkiiFormBrowserExProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
&mPrivateData.FormBrowserEx\r
);\r
*StringPtr = L'\0';\r
\r
LengthStr = StrLen (Value);\r
+\r
+ //\r
+ // Value points to a Unicode hexadecimal string, we need to convert the string to the value with CHAR16/UINT8...type.\r
+ // When generating the Value string, we follow this rule: 1 byte -> 2 Unicode characters (for string: 2 byte(CHAR16) ->4 Unicode characters).\r
+ // So the maximum value string length of a question is : Question->StorageWidth * 2.\r
+ // If the value string length > Question->StorageWidth * 2, only set the string length as Question->StorageWidth * 2, then convert.\r
+ //\r
+ if (LengthStr > (UINTN) Question->StorageWidth * 2) {\r
+ Length = (UINTN) Question->StorageWidth * 2;\r
+ } else {\r
+ Length = LengthStr;\r
+ }\r
+\r
Status = EFI_SUCCESS;\r
if (!IsBufferStorage && IsString) {\r
//\r
// Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
// Add string tail char L'\0' into Length\r
//\r
- Length = Question->StorageWidth + sizeof (CHAR16);\r
- if (Length < ((LengthStr / 4 + 1) * 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- } else {\r
- DstBuf = (CHAR16 *) Dst;\r
- ZeroMem (TemStr, sizeof (TemStr));\r
- for (Index = 0; Index < LengthStr; Index += 4) {\r
- StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);\r
- DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
- }\r
- //\r
- // Add tailing L'\0' character\r
- //\r
- DstBuf[Index/4] = L'\0';\r
+ DstBuf = (CHAR16 *) Dst;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < Length; Index += 4) {\r
+ StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);\r
+ DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
}\r
+ //\r
+ // Add tailing L'\0' character\r
+ //\r
+ DstBuf[Index/4] = L'\0';\r
} else {\r
- if (Question->StorageWidth < ((LengthStr + 1) / 2)) {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- } else {\r
- ZeroMem (TemStr, sizeof (TemStr));\r
- for (Index = 0; Index < LengthStr; Index ++) {\r
- TemStr[0] = Value[LengthStr - Index - 1];\r
- DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
- if ((Index & 1) == 0) {\r
- Dst [Index/2] = DigitUint8;\r
- } else {\r
- Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
- }\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < Length; 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
EFI_STRING Progress;\r
BROWSER_STORAGE *Storage;\r
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+ BOOLEAN SubmitFormFail;\r
+\r
+ SubmitFormFail = FALSE;\r
\r
if (!IsNvUpdateRequiredForForm (Form)) {\r
return EFI_SUCCESS;\r
ConfigResp,\r
&Progress\r
);\r
- FreePool (ConfigResp);\r
\r
if (EFI_ERROR (Status)) {\r
//\r
// Submit fail, to get the RestoreConfigRequest and SyncConfigRequest.\r
//\r
+ SubmitFormFail = TRUE;\r
GetSyncRestoreConfigRequest (ConfigInfo->Storage, ConfigInfo->ConfigRequest, Progress, &ConfigInfo->RestoreConfigRequest, &ConfigInfo->SyncConfigRequest);\r
InsertTailList (&gBrowserSaveFailFormSetList, &ConfigInfo->SaveFailLink);\r
+ FreePool (ConfigResp);\r
continue;\r
}\r
\r
+ FreePool (ConfigResp);\r
//\r
// 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
//\r
\r
Status = EFI_SUCCESS;\r
}\r
+ SendDiscardInfoToDriver (FormSet,Form);\r
} else {\r
Status = EFI_UNSUPPORTED;\r
}\r
//\r
// 6 Call callback with Submitted type to inform the driver.\r
//\r
- SubmitCallback (FormSet, Form);\r
+ if (!SubmitFormFail) {\r
+ SubmitCallback (FormSet, Form);\r
+ }\r
\r
return Status;\r
}\r
FORM_BROWSER_FORM *Form;\r
BOOLEAN HasInserted;\r
FORM_BROWSER_STATEMENT *Question;\r
+ BOOLEAN SubmitFormSetFail;\r
+ BOOLEAN DiscardChange;\r
\r
HasInserted = FALSE;\r
+ SubmitFormSetFail = FALSE;\r
+ DiscardChange = FALSE;\r
\r
if (!IsNvUpdateRequiredForFormSet (FormSet)) {\r
return EFI_SUCCESS;\r
//\r
// Submit fail, to get the RestoreConfigRequest and SyncConfigRequest.\r
//\r
+ SubmitFormSetFail = TRUE;\r
GetSyncRestoreConfigRequest (FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, Progress, &FormSetStorage->RestoreConfigRequest, &FormSetStorage->SyncConfigRequest);\r
InsertTailList (&FormSet->SaveFailStorageListHead, &FormSetStorage->SaveFailLink);\r
if (!HasInserted) {\r
// If not in system level, just handl the save failed storage here.\r
//\r
if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
+ DiscardChange = TRUE;\r
Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
while (!IsNull (&FormSet->SaveFailStorageListHead, Link)) {\r
FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
}\r
}\r
\r
+ //\r
+ // If user discard the change, send the discard info to driver.\r
+ //\r
+ if (DiscardChange) {\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ //\r
+ // Call callback with Changed type to inform the driver.\r
+ //\r
+ SendDiscardInfoToDriver (FormSet, Form);\r
+ }\r
+ }\r
+\r
//\r
// 5. Update the NV flag.\r
// \r
//\r
// 6. Call callback with Submitted type to inform the driver.\r
//\r
- SubmitCallback (FormSet, NULL);\r
+ if (!SubmitFormSetFail) {\r
+ SubmitCallback (FormSet, NULL);\r
+ }\r
\r
return Status;\r
}\r
}\r
}\r
\r
+ Link = GetFirstNode (&LocalFormSet->FormListHead);\r
+ while (!IsNull (&LocalFormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ Link = GetNextNode (&LocalFormSet->FormListHead, Link);\r
+ //\r
+ // Call callback with Changed type to inform the driver.\r
+ //\r
+ SendDiscardInfoToDriver (LocalFormSet, Form);\r
+ }\r
+\r
if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
CleanBrowserStorage(LocalFormSet);\r
RemoveEntryList (&LocalFormSet->Link);\r
// Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\r
//\r
\r
+ //\r
+ // Convert all hex digits in ConfigResp to lower case before searching.\r
+ //\r
+ HiiToLower (ConfigResp);\r
+\r
//\r
// 1. Directly use Question->BlockName to find.\r
//\r
INTN Action;\r
CHAR16 *NewString;\r
EFI_IFR_TYPE_VALUE *TypeValue;\r
+ UINT16 OriginalDefaultId;\r
+ FORMSET_DEFAULTSTORE *DefaultStore;\r
+ LIST_ENTRY *DefaultLink;\r
\r
Status = EFI_NOT_FOUND;\r
StrValue = NULL;\r
+ OriginalDefaultId = DefaultId;\r
+ DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
\r
//\r
// Statement don't have storage, skip them\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
+ReGetDefault:\r
HiiValue = &Question->HiiValue;\r
TypeValue = &HiiValue->Value;\r
if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
\r
ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth);\r
if (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth) {\r
+ ZeroMem (Question->BufferValue, Question->StorageWidth);\r
CopyMem (Question->BufferValue, NewString, StrSize (NewString));\r
} else {\r
CopyMem (Question->BufferValue, NewString, Question->StorageWidth);\r
return EFI_NOT_FOUND;\r
}\r
if (Question->StorageWidth > StrSize (StrValue)) {\r
+ ZeroMem (Question->BufferValue, Question->StorageWidth);\r
CopyMem (Question->BufferValue, StrValue, StrSize (StrValue));\r
} else {\r
CopyMem (Question->BufferValue, StrValue, Question->StorageWidth);\r
((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
) {\r
HiiValue->Value.b = TRUE;\r
- } else {\r
- HiiValue->Value.b = FALSE;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
//\r
- // For Questions without default\r
+ // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r
+ // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r
+ // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r
+ //\r
+ while (!IsNull(&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+ DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
+ DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead,DefaultLink);\r
+ DefaultId = DefaultStore->DefaultId;\r
+ if (DefaultId == OriginalDefaultId) {\r
+ continue;\r
+ }\r
+ goto ReGetDefault;\r
+ }\r
+\r
+ //\r
+ // For Questions without default value for all the default id in the DefaultStoreList.\r
//\r
Status = EFI_NOT_FOUND;\r
switch (Question->Operand) {\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ HiiValue->Value.b = FALSE;\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+\r
case EFI_IFR_NUMERIC_OP:\r
//\r
// Take minimum value as numeric default value\r
//\r
// Try to compare against formset GUID\r
//\r
- if (CompareGuid (FormSetGuid, &gZeroGuid) || \r
+ if (IsZeroGuid (FormSetGuid) ||\r
CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
break;\r
}\r