return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Check whether current element in the ConfigReqeust string.\r
+\r
+ @param BrowserStorage Storage which includes ConfigReqeust.\r
+ @param RequestElement New element need to check.\r
+\r
+ @retval TRUE The Element is in the ConfigReqeust string.\r
+ @retval FALSE The Element not in the configReqeust String.\r
+\r
+**/\r
+BOOLEAN \r
+ElementValidation (\r
+ BROWSER_STORAGE *BrowserStorage,\r
+ CHAR16 *RequestElement\r
+ )\r
+{\r
+ return StrStr (BrowserStorage->ConfigRequest, RequestElement) != NULL ? TRUE : FALSE;\r
+}\r
+\r
+/**\r
+ Append the Request element to the Config Request.\r
+\r
+ @param ConfigRequest Current ConfigRequest info.\r
+ @param SpareStrLen Current remain free buffer for config reqeust.\r
+ @param RequestElement New Request element.\r
+\r
+**/\r
+VOID\r
+AppendConfigRequest (\r
+ IN OUT CHAR16 **ConfigRequest,\r
+ IN OUT UINTN *SpareStrLen,\r
+ IN CHAR16 *RequestElement\r
+ )\r
+{\r
+ CHAR16 *NewStr;\r
+ UINTN StringSize;\r
+ UINTN StrLength;\r
+\r
+ StrLength = StrLen (RequestElement) * sizeof (CHAR16);\r
+\r
+ //\r
+ // Append <RequestElement> to <ConfigRequest>\r
+ //\r
+ if (StrLength > *SpareStrLen) {\r
+ //\r
+ // Old String buffer is not sufficient for RequestElement, allocate a new one\r
+ //\r
+ StringSize = (*ConfigRequest != NULL) ? StrSize (*ConfigRequest) : sizeof (CHAR16);\r
+ NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+ ASSERT (NewStr != NULL);\r
+\r
+ if (*ConfigRequest != NULL) {\r
+ CopyMem (NewStr, *ConfigRequest, StringSize);\r
+ FreePool (*ConfigRequest);\r
+ }\r
+ *ConfigRequest = NewStr;\r
+ *SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
+ }\r
+\r
+ StrCat (*ConfigRequest, RequestElement);\r
+ *SpareStrLen -= StrLength;\r
+}\r
+\r
+/**\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
+**/\r
+BOOLEAN \r
+ConfigRequestAdjust (\r
+ IN FORMSET_STORAGE *Storage,\r
+ OUT CHAR16 **ConfigRequest\r
+ )\r
+{\r
+ CHAR16 *RequestElement;\r
+ CHAR16 *NextRequestElement;\r
+ CHAR16 *RetBuf;\r
+ UINTN SpareBufLen;\r
+ CHAR16 *SearchKey;\r
+ BOOLEAN RetVal;\r
+\r
+ SpareBufLen = 0;\r
+ RetBuf = NULL;\r
+ RetVal = FALSE;\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
+ return TRUE;\r
+ }\r
+\r
+ if (Storage->BrowserStorage->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
+ // Prepare the config header.\r
+ // \r
+ RetBuf = AllocateCopyPool(StrSize (Storage->BrowserStorage->ConfigHdr), Storage->BrowserStorage->ConfigHdr);\r
+ ASSERT (RetBuf != NULL);\r
+\r
+ //\r
+ // Find SearchKey storage\r
+ //\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ RequestElement = StrStr (Storage->ConfigRequest, L"PATH");\r
+ ASSERT (RequestElement != NULL);\r
+ RequestElement = StrStr (RequestElement, SearchKey); \r
+ } else {\r
+ RequestElement = StrStr (Storage->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
+ if (!ElementValidation (Storage->BrowserStorage, RequestElement)) {\r
+ //\r
+ // Add this element to the Storage->BrowserStorage->AllRequestElement.\r
+ //\r
+ AppendConfigRequest(&Storage->BrowserStorage->ConfigRequest, &Storage->BrowserStorage->SpareStrLen, RequestElement);\r
+ AppendConfigRequest (&RetBuf, &SpareBufLen, RequestElement);\r
+ RetVal = TRUE;\r
+ }\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
+ if (RetVal) {\r
+ *ConfigRequest = RetBuf;\r
+ } else {\r
+ FreePool (RetBuf);\r
+ }\r
+\r
+ return RetVal;\r
+}\r
+\r
/**\r
Fill storage's edit copy with settings requested from Configuration Driver.\r
\r
EFI_STRING Progress;\r
EFI_STRING Result;\r
CHAR16 *StrPtr;\r
+ CHAR16 *ConfigRequest;\r
\r
if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
return EFI_SUCCESS;\r
}\r
\r
if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\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
+ 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
\r
return EFI_SUCCESS;\r
}\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
+ }\r
+\r
//\r
// Request current settings from Configuration Driver\r
//\r
Status = FormSet->ConfigAccess->ExtractConfig (\r
FormSet->ConfigAccess,\r
- Storage->ConfigRequest,\r
+ ConfigRequest,\r
&Progress,\r
&Result\r
);\r
+ FreePool (ConfigRequest);\r
+\r
if (EFI_ERROR (Status)) {\r
return Status;\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 && Storage->BrowserStorage->ReferenceCount == 1) {\r
+ if (OldStorage == NULL) {\r
Status = LoadStorage (FormSet, Storage);\r
\r
if (EFI_ERROR (Status)) {\r