summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2011-07-12 07:24:36 +0000
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2011-07-12 07:24:36 +0000
commitcce6230ffb5981caab05cfcb500c9217db2a6963 (patch)
tree8b149ec0c2de6fbbc0e712eadafebe7c45dc4735
parentd23610ebbc91a1eff5dbb2cbf1921ad41e925279 (diff)
downloadedk2-platforms-cce6230ffb5981caab05cfcb500c9217db2a6963.tar.xz
Change the HiiDataBase and browser codes to support new efi varstore data structure.
Signed-off-by:ydong10 Reviewed-by:lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12009 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c544
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.c3
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c29
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c675
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.h1
5 files changed, 939 insertions, 313 deletions
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
index 29576ba477..ffaa33472a 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
@@ -781,6 +781,187 @@ BlockArrayCheck (
}
/**
+ Get form package data from data base.
+
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.
+ @param HiiFormPackage The buffer saves the package data.
+ @param PackageSize The buffer size of the package data.
+
+**/
+EFI_STATUS
+GetFormPackageData (
+ IN HII_DATABASE_RECORD *DataBaseRecord,
+ IN OUT UINT8 **HiiFormPackage,
+ OUT UINTN *PackageSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN ResultSize;
+
+ if (DataBaseRecord == NULL || HiiFormPackage == NULL || PackageSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Size = 0;
+ ResultSize = 0;
+ //
+ // 0. Get Hii Form Package by HiiHandle
+ //
+ Status = ExportFormPackages (
+ &mPrivate,
+ DataBaseRecord->Handle,
+ DataBaseRecord->PackageList,
+ 0,
+ Size,
+ HiiFormPackage,
+ &ResultSize
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ (*HiiFormPackage) = AllocatePool (ResultSize);
+ if (*HiiFormPackage == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ //
+ // Get HiiFormPackage by HiiHandle
+ //
+ Size = ResultSize;
+ ResultSize = 0;
+ Status = ExportFormPackages (
+ &mPrivate,
+ DataBaseRecord->Handle,
+ DataBaseRecord->PackageList,
+ 0,
+ Size,
+ *HiiFormPackage,
+ &ResultSize
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (*HiiFormPackage);
+ }
+
+ *PackageSize = Size;
+
+ return Status;
+}
+
+
+/**
+ This function parses Form Package to get the efi varstore info according to the request ConfigHdr.
+
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.
+ @param ConfigHdr Request string ConfigHdr. If it is NULL,
+ the first found varstore will be as ConfigHdr.
+ @param IsEfiVarstore Whether the request storage type is efi varstore type.
+ @param EfiVarStore The efi varstore info which will return.
+**/
+EFI_STATUS
+GetVarStoreType (
+ IN HII_DATABASE_RECORD *DataBaseRecord,
+ IN EFI_STRING ConfigHdr,
+ OUT BOOLEAN *IsEfiVarstore,
+ OUT EFI_IFR_VARSTORE_EFI **EfiVarStore
+
+ )
+{
+ EFI_STATUS Status;
+ UINTN IfrOffset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ CHAR16 *VarStoreName;
+ EFI_STRING GuidStr;
+ EFI_STRING NameStr;
+ EFI_STRING TempStr;
+ UINTN LengthString;
+ UINT8 *HiiFormPackage;
+ UINTN PackageSize;
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
+
+ HiiFormPackage = NULL;
+ LengthString = 0;
+ Status = EFI_SUCCESS;
+ GuidStr = NULL;
+ NameStr = NULL;
+ TempStr = NULL;
+
+ Status = GetFormPackageData(DataBaseRecord, &HiiFormPackage, &PackageSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (IfrOffset < PackageSize) {
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (HiiFormPackage + IfrOffset);
+ IfrOffset += IfrOpHdr->Length;
+
+ if (IfrOpHdr->OpCode == EFI_IFR_VARSTORE_EFI_OP ) {
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;
+ //
+ // If the length is small than the structure, this is from old efi
+ // varstore definition. Old efi varstore get config directly from
+ // GetVariable function.
+ //
+ if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
+ continue;
+ }
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName);
+
+ GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrEfiVarStore->Guid, 1, &GuidStr);
+ GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);
+ LengthString = StrLen (GuidStr);
+ LengthString = LengthString + StrLen (NameStr) + 1;
+ TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
+ if (TempStr == NULL) {
+ FreePool (GuidStr);
+ FreePool (NameStr);
+ FreePool (VarStoreName);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ StrCpy (TempStr, GuidStr);
+ StrCat (TempStr, NameStr);
+ if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {
+ *EfiVarStore = (EFI_IFR_VARSTORE_EFI *) AllocateZeroPool (IfrOpHdr->Length);
+ if (*EfiVarStore == NULL) {
+ FreePool (VarStoreName);
+ FreePool (GuidStr);
+ FreePool (NameStr);
+ FreePool (TempStr);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ *IsEfiVarstore = TRUE;
+ CopyMem (*EfiVarStore, IfrEfiVarStore, IfrOpHdr->Length);
+ }
+
+ //
+ // Free alllocated temp string.
+ //
+ FreePool (VarStoreName);
+ FreePool (GuidStr);
+ FreePool (NameStr);
+ FreePool (TempStr);
+ }
+ }
+Done:
+ if (HiiFormPackage != NULL) {
+ FreePool (HiiFormPackage);
+ }
+
+ return Status;
+}
+
+/**
This function parses Form Package to get the block array and the default
value array according to the request ConfigHdr.
@@ -811,6 +992,7 @@ ParseIfrData (
EFI_STATUS Status;
UINTN IfrOffset;
EFI_IFR_VARSTORE *IfrVarStore;
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
EFI_IFR_OP_HEADER *IfrOpHdr;
EFI_IFR_ONE_OF *IfrOneOf;
EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
@@ -876,7 +1058,7 @@ ParseIfrData (
LengthString = StrLen (GuidStr);
LengthString = LengthString + StrLen (NameStr) + 1;
TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
- if (TempStr == NULL) {
+ if (TempStr == NULL) {
FreePool (GuidStr);
FreePool (NameStr);
FreePool (VarStoreName);
@@ -907,6 +1089,73 @@ ParseIfrData (
FreePool (TempStr);
break;
+ case EFI_IFR_VARSTORE_EFI_OP:
+ //
+ // VarStore is found. Don't need to search any more.
+ //
+ if (VarStorageData->Size != 0) {
+ break;
+ }
+
+ //
+ // Get the requied varstore information
+ // Add varstore by Guid and Name in ConfigHdr
+ // Make sure Offset is in varstore size and varstoreid
+ //
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;
+
+ //
+ // If the length is small than the structure, this is from old efi
+ // varstore definition. Old efi varstore get config directly from
+ // GetVariable function.
+ //
+ if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
+ break;
+ }
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName);
+
+ GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrEfiVarStore->Guid, 1, &GuidStr);
+ GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);
+ LengthString = StrLen (GuidStr);
+ LengthString = LengthString + StrLen (NameStr) + 1;
+ TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
+ if (TempStr == NULL) {
+ FreePool (GuidStr);
+ FreePool (NameStr);
+ FreePool (VarStoreName);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ StrCpy (TempStr, GuidStr);
+ StrCat (TempStr, NameStr);
+ if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {
+ //
+ // Find the matched VarStore
+ //
+ CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrEfiVarStore->Guid);
+ VarStorageData->VarStoreId = IfrEfiVarStore->VarStoreId;
+ VarStorageData->Size = IfrEfiVarStore->Size;
+ VarStorageData->Name = VarStoreName;
+ } else {
+ //
+ // No found, free the allocated memory
+ //
+ FreePool (VarStoreName);
+ }
+ //
+ // Free alllocated temp string.
+ //
+ FreePool (GuidStr);
+ FreePool (NameStr);
+ FreePool (TempStr);
+ break;
+
case EFI_IFR_DEFAULTSTORE_OP:
//
// Add new the map between default id and default name.
@@ -1637,45 +1886,10 @@ GetFullStringFromHiiFormPackages (
PackageSize = 0;
DataExist = FALSE;
Progress = *Request;
-
- //
- // 0. Get Hii Form Package by HiiHandle
- //
- Status = ExportFormPackages (
- &mPrivate,
- DataBaseRecord->Handle,
- DataBaseRecord->PackageList,
- 0,
- PackageSize,
- HiiFormPackage,
- &ResultSize
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HiiFormPackage = AllocatePool (ResultSize);
- if (HiiFormPackage == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- //
- // Get HiiFormPackage by HiiHandle
- //
- PackageSize = ResultSize;
- ResultSize = 0;
- Status = ExportFormPackages (
- &mPrivate,
- DataBaseRecord->Handle,
- DataBaseRecord->PackageList,
- 0,
- PackageSize,
- HiiFormPackage,
- &ResultSize
- );
+ Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
if (EFI_ERROR (Status)) {
- goto Done;
+ return Status;
}
//
@@ -2209,6 +2423,168 @@ Done:
}
/**
+ This function gets the full request resp string by
+ parsing IFR data in HII form packages.
+
+ @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
+ instance.
+ @param EfiVarStoreInfo The efi varstore info which is save in the EFI
+ varstore data structure.
+ @param Request Pointer to a null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param RequestResp Pointer to a null-terminated Unicode string in
+ <ConfigResp> format.
+ @param AccessProgress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ & before the first failing name / value pair (or
+ the beginning of the string if the failure is in
+ the first name / value pair) if the request was
+ not successful.
+
+ @retval EFI_SUCCESS The Results string is set to the full request string.
+ And AltCfgResp contains all default value string.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.
+ @retval EFI_INVALID_PARAMETER Request points to NULL.
+
+**/
+EFI_STATUS
+GetConfigRespFromEfiVarStore (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo,
+ IN EFI_STRING Request,
+ OUT EFI_STRING *RequestResp,
+ OUT EFI_STRING *AccessProgress
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING VarStoreName;
+ UINT8 *VarStore;
+ UINTN BufferSize;
+
+ Status = EFI_SUCCESS;
+ BufferSize = 0;
+ VarStore = NULL;
+ VarStoreName = NULL;
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);
+
+
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ goto Done;
+ }
+
+ VarStore = AllocateZeroPool (BufferSize);
+ ASSERT (VarStore != NULL);
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = HiiBlockToConfig(This, Request, VarStore, BufferSize, RequestResp, AccessProgress);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+Done:
+ if (VarStoreName != NULL) {
+ FreePool (VarStoreName);
+ }
+
+ if (VarStore != NULL) {
+ FreePool (VarStore);
+ }
+
+ return Status;
+}
+
+
+/**
+ This function route the full request resp string for efi varstore.
+
+ @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
+ instance.
+ @param EfiVarStoreInfo The efi varstore info which is save in the EFI
+ varstore data structure.
+ @param RequestResp Pointer to a null-terminated Unicode string in
+ <ConfigResp> format.
+ @param Result Pointer to a null-terminated Unicode string in
+ <ConfigResp> format.
+
+ @retval EFI_SUCCESS The Results string is set to the full request string.
+ And AltCfgResp contains all default value string.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.
+ @retval EFI_INVALID_PARAMETER Request points to NULL.
+
+**/
+EFI_STATUS
+RouteConfigRespForEfiVarStore (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo,
+ IN EFI_STRING RequestResp,
+ OUT EFI_STRING *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING VarStoreName;
+ CHAR8 *VarStore;
+ UINTN BufferSize;
+ UINTN BlockSize;
+
+ Status = EFI_SUCCESS;
+ BufferSize = 0;
+ VarStore = NULL;
+ VarStoreName = NULL;
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);
+
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ goto Done;
+ }
+
+ BlockSize = BufferSize;
+ VarStore = AllocateZeroPool (BufferSize);
+ ASSERT (VarStore != NULL);
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = HiiConfigToBlock(This, RequestResp, VarStore, &BlockSize, Result);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+Done:
+ if (VarStoreName != NULL) {
+ FreePool (VarStoreName);
+ }
+
+ if (VarStore != NULL) {
+ FreePool (VarStore);
+ }
+
+ return Status;
+}
+
+/**
This function allows a caller to extract the current configuration
for one or more named elements from one or more drivers.
@@ -2275,6 +2651,8 @@ HiiConfigRoutingExtractConfig (
EFI_STRING DefaultResults;
BOOLEAN FirstElement;
BOOLEAN IfrDataParsedFlag;
+ BOOLEAN IsEfiVarStore;
+ EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
if (This == NULL || Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
@@ -2292,8 +2670,11 @@ HiiConfigRoutingExtractConfig (
ConfigRequest = NULL;
Status = EFI_SUCCESS;
AccessResults = NULL;
+ AccessProgress = NULL;
DevicePath = NULL;
IfrDataParsedFlag = FALSE;
+ IsEfiVarStore = FALSE;
+ EfiVarStoreInfo = NULL;
//
// The first element of <MultiConfigRequest> should be
@@ -2418,21 +2799,37 @@ HiiConfigRoutingExtractConfig (
}
//
- // Call corresponding ConfigAccess protocol to extract settings
+ // Check whether this ConfigRequest is search from Efi varstore type storage.
//
- Status = gBS->HandleProtocol (
- DriverHandle,
- &gEfiHiiConfigAccessProtocolGuid,
- (VOID **) &ConfigAccess
- );
- ASSERT_EFI_ERROR (Status);
+ Status = GetVarStoreType(Database, ConfigRequest, &IsEfiVarStore, &EfiVarStoreInfo);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ if (IsEfiVarStore) {
+ //
+ // Call the GetVariable function to extract settings.
+ //
+ Status = GetConfigRespFromEfiVarStore(This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);
+ FreePool (EfiVarStoreInfo);
+ } else {
+ //
+ // Call corresponding ConfigAccess protocol to extract settings
+ //
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ (VOID **) &ConfigAccess
+ );
+ ASSERT_EFI_ERROR (Status);
- Status = ConfigAccess->ExtractConfig (
- ConfigAccess,
- ConfigRequest,
- &AccessProgress,
- &AccessResults
- );
+ Status = ConfigAccess->ExtractConfig (
+ ConfigAccess,
+ ConfigRequest,
+ &AccessProgress,
+ &AccessResults
+ );
+ }
if (EFI_ERROR (Status)) {
//
// AccessProgress indicates the parsing progress on <ConfigRequest>.
@@ -2766,6 +3163,8 @@ HiiConfigRoutingRouteConfig (
EFI_HANDLE DriverHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
EFI_STRING AccessProgress;
+ EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
+ BOOLEAN IsEfiVarstore;
if (This == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
@@ -2779,6 +3178,10 @@ HiiConfigRoutingRouteConfig (
Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
StringPtr = Configuration;
*Progress = StringPtr;
+ Database = NULL;
+ AccessProgress = NULL;
+ EfiVarStoreInfo= NULL;
+ IsEfiVarstore = FALSE;
//
// The first element of <MultiConfigResp> should be
@@ -2869,21 +3272,36 @@ HiiConfigRoutingRouteConfig (
FreePool (DevicePath);
//
- // Call corresponding ConfigAccess protocol to route settings
+ // Check whether this ConfigRequest is search from Efi varstore type storage.
//
- Status = gBS->HandleProtocol (
- DriverHandle,
- &gEfiHiiConfigAccessProtocolGuid,
- (VOID **) &ConfigAccess
- );
- ASSERT_EFI_ERROR (Status);
+ Status = GetVarStoreType(Database, ConfigResp, &IsEfiVarstore, &EfiVarStoreInfo);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- Status = ConfigAccess->RouteConfig (
- ConfigAccess,
- ConfigResp,
- &AccessProgress
- );
+ if (IsEfiVarstore) {
+ //
+ // Call the SetVariable function to route settings.
+ //
+ Status = RouteConfigRespForEfiVarStore(This, EfiVarStoreInfo, ConfigResp, &AccessProgress);
+ FreePool (EfiVarStoreInfo);
+ } else {
+ //
+ // Call corresponding ConfigAccess protocol to route settings
+ //
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ (VOID **) &ConfigAccess
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = ConfigAccess->RouteConfig (
+ ConfigAccess,
+ ConfigResp,
+ &AccessProgress
+ );
+ }
if (EFI_ERROR (Status)) {
//
// AccessProgress indicates the parsing progress on <ConfigResp>.
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index 5d0339a040..cbbb20dc9f 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -1716,6 +1716,7 @@ EvaluateExpression (
if (OpCode->VarStorage != NULL) {
switch (OpCode->VarStorage->Type) {
case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
//
// Get value from Edit Buffer
//
@@ -1765,6 +1766,7 @@ EvaluateExpression (
Value->Type = EFI_IFR_TYPE_UNDEFINED;
Value->Value.u8 = 0;
}
+ break;
default:
//
// Not recognize storage.
@@ -2123,6 +2125,7 @@ EvaluateExpression (
if (OpCode->VarStorage != NULL) {
switch (OpCode->VarStorage->Type) {
case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);
Data1.Value.b = TRUE;
break;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index ba805560ef..d8fb8c963e 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -329,7 +329,8 @@ InitializeConfigHdr (
{
CHAR16 *Name;
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
Name = Storage->Name;
} else {
Name = NULL;
@@ -395,7 +396,8 @@ InitializeRequestElement (
//
// Prepare <RequestElement>
//
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
StrLen = UnicodeSPrint (
RequestElement,
30 * sizeof (CHAR16),
@@ -1480,11 +1482,32 @@ ParseOpCodes (
// Create a EFI variable Storage for this FormSet
//
Storage = CreateStorage (FormSet);
- Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
+ CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));
+
+ if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
+ Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
+ break;
+ }
+
+ Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;
+ Storage->Buffer = AllocateZeroPool (Storage->Size);
+ Storage->EditBuffer = AllocateZeroPool (Storage->Size);
+
+ AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;
+ Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
+ ASSERT (Storage->Name != NULL);
+ for (Index = 0; AsciiString[Index] != 0; Index++) {
+ Storage->Name[Index] = (CHAR16) AsciiString[Index];
+ }
+
+ //
+ // Initialize <ConfigHdr>
+ //
+ InitializeConfigHdr (FormSet, Storage);
break;
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index f4081679c6..65ce5bddce 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -431,7 +431,8 @@ BrowserCallback (
Link = GetNextNode (&FormSet->StorageListHead, Link);
if (CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
//
// Buffer storage require both GUID and Name
//
@@ -727,14 +728,19 @@ NewStringCat (
/**
- Synchronize Storage's Edit copy to Shadow copy.
+ Synchronize or restore Storage's Edit copy and Shadow copy.
- @param Storage The Storage to be synchronized.
+ @param Storage The Storage to be synchronized.
+ @param SyncOrRestore Sync the buffer to editbuffer or Restore the
+ editbuffer to buffer
+ if TRUE, copy the editbuffer to the buffer.
+ if FALSE, copy the buffer to the editbuffer.
**/
VOID
SynchronizeStorage (
- IN FORMSET_STORAGE *Storage
+ IN FORMSET_STORAGE *Storage,
+ IN BOOLEAN SyncOrRestore
)
{
LIST_ENTRY *Link;
@@ -742,7 +748,12 @@ SynchronizeStorage (
switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER:
- CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
+ if (SyncOrRestore) {
+ CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);
+ } else {
+ CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);
+ }
break;
case EFI_HII_VARSTORE_NAME_VALUE:
@@ -750,7 +761,11 @@ SynchronizeStorage (
while (!IsNull (&Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (Link);
- NewStringCpy (&Node->Value, Node->EditValue);
+ if (SyncOrRestore) {
+ NewStringCpy (&Node->Value, Node->EditValue);
+ } else {
+ NewStringCpy (&Node->EditValue, Node->Value);
+ }
Link = GetNextNode (&Storage->NameValueListHead, Link);
}
@@ -894,6 +909,7 @@ StorageToConfigResp (
switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
Status = mHiiConfigRouting->BlockToConfig (
mHiiConfigRouting,
ConfigRequest,
@@ -959,6 +975,7 @@ ConfigRespToStorage (
switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
BufferSize = Storage->Size;
Status = mHiiConfigRouting->ConfigToBlock (
mHiiConfigRouting,
@@ -1050,8 +1067,10 @@ GetQuestionValue (
BOOLEAN IsString;
CHAR16 TemStr[5];
UINT8 DigitUint8;
+ UINT8 *TemBuffer;
Status = EFI_SUCCESS;
+ Value = NULL;
//
// Statement don't have storage, skip them
@@ -1172,7 +1191,12 @@ GetQuestionValue (
Dst = (UINT8 *) &Question->HiiValue.Value;
}
- IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ IsBufferStorage = TRUE;
+ } else {
+ IsBufferStorage = FALSE;
+ }
IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
if (Cached) {
if (IsBufferStorage) {
@@ -1230,115 +1254,141 @@ GetQuestionValue (
FreePool (Value);
}
} else {
- //
- // Request current settings from Configuration Driver
- //
- if (FormSet->ConfigAccess == NULL) {
- return EFI_NOT_FOUND;
- }
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ //
+ // Request current settings from Configuration Driver
+ //
+ if (FormSet->ConfigAccess == NULL) {
+ return EFI_NOT_FOUND;
+ }
- //
- // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
- // <ConfigHdr> + "&" + <VariableName>
- //
- if (IsBufferStorage) {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->BlockName);
- } else {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->VariableName) + 1;
- }
- ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigRequest != NULL);
+ //
+ // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
+ // <ConfigHdr> + "&" + <VariableName>
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->BlockName);
+ } else {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->VariableName) + 1;
+ }
+ ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigRequest != NULL);
- StrCpy (ConfigRequest, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigRequest, Question->BlockName);
- } else {
- StrCat (ConfigRequest, L"&");
- StrCat (ConfigRequest, Question->VariableName);
- }
+ StrCpy (ConfigRequest, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigRequest, Question->BlockName);
+ } else {
+ StrCat (ConfigRequest, L"&");
+ StrCat (ConfigRequest, Question->VariableName);
+ }
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- ConfigRequest,
- &Progress,
- &Result
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ Status = FormSet->ConfigAccess->ExtractConfig (
+ FormSet->ConfigAccess,
+ ConfigRequest,
+ &Progress,
+ &Result
+ );
+ FreePool (ConfigRequest);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- //
- // Skip <ConfigRequest>
- //
- Value = Result + Length;
- if (IsBufferStorage) {
//
- // Skip "&VALUE"
+ // Skip <ConfigRequest>
//
- Value = Value + 6;
- }
- if (*Value != '=') {
- FreePool (Result);
- return EFI_NOT_FOUND;
- }
- //
- // Skip '=', point to value
- //
- Value = Value + 1;
-
- //
- // Suppress <AltResp> if any
- //
- StringPtr = Value;
- while (*StringPtr != L'\0' && *StringPtr != L'&') {
- StringPtr++;
- }
- *StringPtr = L'\0';
+ Value = Result + Length;
+ if (IsBufferStorage) {
+ //
+ // Skip "&VALUE"
+ //
+ Value = Value + 6;
+ }
+ if (*Value != '=') {
+ FreePool (Result);
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Skip '=', point to value
+ //
+ Value = Value + 1;
- LengthStr = StrLen (Value);
- Status = EFI_SUCCESS;
- if (!IsBufferStorage && IsString) {
//
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
- // Add string tail char L'\0' into Length
+ // Suppress <AltResp> if any
//
- Length = StorageWidth + sizeof (CHAR16);
- if (Length < ((LengthStr / 4 + 1) * 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
- } else {
- StringPtr = (CHAR16 *) Dst;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index += 4) {
- StrnCpy (TemStr, Value + Index, 4);
- StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
- }
+ StringPtr = Value;
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {
+ StringPtr++;
+ }
+ *StringPtr = L'\0';
+
+ LengthStr = StrLen (Value);
+ Status = EFI_SUCCESS;
+ if (!IsBufferStorage && IsString) {
//
- // Add tailing L'\0' character
+ // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
+ // Add string tail char L'\0' into Length
//
- StringPtr[Index/4] = L'\0';
- }
- } else {
- if (StorageWidth < ((LengthStr + 1) / 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
+ Length = StorageWidth + sizeof (CHAR16);
+ if (Length < ((LengthStr / 4 + 1) * 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ StringPtr = (CHAR16 *) Dst;
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index += 4) {
+ StrnCpy (TemStr, Value + Index, 4);
+ StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
+ }
+ //
+ // Add tailing L'\0' character
+ //
+ StringPtr[Index/4] = L'\0';
+ }
} else {
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index ++) {
- TemStr[0] = Value[LengthStr - Index - 1];
- DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- Dst [Index/2] = DigitUint8;
- } else {
- Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
+ if (StorageWidth < ((LengthStr + 1) / 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index ++) {
+ TemStr[0] = Value[LengthStr - Index - 1];
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
+ if ((Index & 1) == 0) {
+ Dst [Index/2] = DigitUint8;
+ } else {
+ Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
+ }
}
}
}
- }
-
- if (EFI_ERROR (Status)) {
FreePool (Result);
- return Status;
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ TemBuffer = NULL;
+ TemBuffer = AllocateZeroPool (Storage->Size);
+ if (TemBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ Length = Storage->Size;
+ Status = gRT->GetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ NULL,
+ &Length,
+ TemBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (TemBuffer);
+ return Status;
+ }
+
+ CopyMem (Dst, TemBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);
+
+ FreePool (TemBuffer);
}
//
@@ -1349,8 +1399,6 @@ GetQuestionValue (
} else {
SetValueByName (Storage, Question->VariableName, Value, TRUE);
}
-
- FreePool (Result);
}
return Status;
@@ -1507,7 +1555,12 @@ SetQuestionValue (
Src = (UINT8 *) &Question->HiiValue.Value;
}
- IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ IsBufferStorage = TRUE;
+ } else {
+ IsBufferStorage = FALSE;
+ }
IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
if (IsBufferStorage) {
//
@@ -1550,84 +1603,115 @@ SetQuestionValue (
}
if (!Cached) {
- //
- // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
- // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
- //
- if (IsBufferStorage) {
- Length = StrLen (Question->BlockName) + 7;
- } else {
- Length = StrLen (Question->VariableName) + 2;
- }
- if (!IsBufferStorage && IsString) {
- Length += (StrLen ((CHAR16 *) Src) * 4);
- } else {
- Length += (StorageWidth * 2);
- }
- ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigResp != NULL);
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ //
+ // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
+ // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Question->BlockName) + 7;
+ } else {
+ Length = StrLen (Question->VariableName) + 2;
+ }
+ if (!IsBufferStorage && IsString) {
+ Length += (StrLen ((CHAR16 *) Src) * 4);
+ } else {
+ Length += (StorageWidth * 2);
+ }
+ ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigResp != NULL);
- StrCpy (ConfigResp, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigResp, Question->BlockName);
- StrCat (ConfigResp, L"&VALUE=");
- } else {
- StrCat (ConfigResp, L"&");
- StrCat (ConfigResp, Question->VariableName);
- StrCat (ConfigResp, L"=");
- }
+ StrCpy (ConfigResp, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigResp, Question->BlockName);
+ StrCat (ConfigResp, L"&VALUE=");
+ } else {
+ StrCat (ConfigResp, L"&");
+ StrCat (ConfigResp, Question->VariableName);
+ StrCat (ConfigResp, L"=");
+ }
+
+ Value = ConfigResp + StrLen (ConfigResp);
- Value = ConfigResp + StrLen (ConfigResp);
+ if (!IsBufferStorage && IsString) {
+ //
+ // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
+ //
+ TemName = (CHAR16 *) Src;
+ TemString = Value;
+ for (; *TemName != L'\0'; TemName++) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
+ }
+ } else {
+ //
+ // Convert Buffer to Hex String
+ //
+ TemBuffer = Src + StorageWidth - 1;
+ TemString = Value;
+ for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
+ }
+ }
- if (!IsBufferStorage && IsString) {
//
- // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
+ // Convert to lower char.
//
- TemName = (CHAR16 *) Src;
- TemString = Value;
- for (; *TemName != L'\0'; TemName++) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
+ for (TemString = Value; *Value != L'\0'; Value++) {
+ if (*Value >= L'A' && *Value <= L'Z') {
+ *Value = (CHAR16) (*Value - L'A' + L'a');
+ }
}
- } else {
+
//
- // Convert Buffer to Hex String
+ // Submit Question Value to Configuration Driver
//
- TemBuffer = Src + StorageWidth - 1;
- TemString = Value;
- for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
+ if (FormSet->ConfigAccess != NULL) {
+ Status = FormSet->ConfigAccess->RouteConfig (
+ FormSet->ConfigAccess,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
}
- }
-
- //
- // Convert to lower char.
- //
- for (TemString = Value; *Value != L'\0'; Value++) {
- if (*Value >= L'A' && *Value <= L'Z') {
- *Value = (CHAR16) (*Value - L'A' + L'a');
+ FreePool (ConfigResp);
+
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ TemBuffer = NULL;
+ TemBuffer = AllocateZeroPool(Storage->Size);
+ if (TemBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
}
- }
+ Length = Storage->Size;
+ Status = gRT->GetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ NULL,
+ &Length,
+ TemBuffer
+ );
- //
- // Submit Question Value to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
+ CopyMem (TemBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
+
+ Status = gRT->SetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ Storage->Attributes,
+ Storage->Size,
+ TemBuffer
+ );
+ FreePool (TemBuffer);
+ if (EFI_ERROR (Status)){
return Status;
}
}
- FreePool (ConfigResp);
-
//
- // Synchronize shadow Buffer
+ // Sync storage, from editbuffer to buffer.
//
- SynchronizeStorage (Storage);
+ CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
}
return Status;
@@ -1751,57 +1835,23 @@ NoSubmitCheck (
}
/**
- Restore Storage's Edit copy to Shadow copy.
-
- @param Storage The Storage to be synchronized.
-
-**/
-VOID
-RestoreStorage (
- IN FORMSET_STORAGE *Storage
- )
-{
- LIST_ENTRY *Link;
- NAME_VALUE_NODE *Node;
-
- switch (Storage->Type) {
- case EFI_HII_VARSTORE_BUFFER:
- CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);
- break;
-
- case EFI_HII_VARSTORE_NAME_VALUE:
- Link = GetFirstNode (&Storage->NameValueListHead);
- while (!IsNull (&Storage->NameValueListHead, Link)) {
- Node = NAME_VALUE_NODE_FROM_LINK (Link);
-
- if (Node->EditValue != NULL) {
- FreePool (Node->EditValue);
- }
- Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);
- ASSERT (Node->EditValue != NULL);
- Link = GetNextNode (&Storage->NameValueListHead, Link);
- }
- break;
-
- case EFI_HII_VARSTORE_EFI_VARIABLE:
- default:
- break;
- }
-}
-
-/**
Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure.
@param ConfigInfo The config info related to this form.
+ @param SyncOrRestore Sync the buffer to editbuffer or Restore the
+ editbuffer to buffer
+ if TRUE, copy the editbuffer to the buffer.
+ if FALSE, copy the buffer to the editbuffer.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS
-FormRestoreStorage (
+SynchronizeStorageForForm (
IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo
+ IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,
+ IN BOOLEAN SyncOrRestore
)
{
EFI_STATUS Status;
@@ -1810,10 +1860,12 @@ FormRestoreStorage (
UINTN BufferSize;
LIST_ENTRY *Link;
NAME_VALUE_NODE *Node;
+ UINT8 *Src;
+ UINT8 *Dst;
Status = EFI_SUCCESS;
Result = NULL;
- if (FormSet->ConfigAccess == NULL) {
+ if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
return EFI_NOT_FOUND;
}
@@ -1824,12 +1876,22 @@ FormRestoreStorage (
return EFI_SUCCESS;
}
- if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
BufferSize = ConfigInfo->Storage->Size;
+
+ if (SyncOrRestore) {
+ Src = ConfigInfo->Storage->EditBuffer;
+ Dst = ConfigInfo->Storage->Buffer;
+ } else {
+ Src = ConfigInfo->Storage->Buffer;
+ Dst = ConfigInfo->Storage->EditBuffer;
+ }
+
Status = mHiiConfigRouting->BlockToConfig(
mHiiConfigRouting,
ConfigInfo->ConfigRequest,
- ConfigInfo->Storage->Buffer,
+ Src,
BufferSize,
&Result,
&Progress
@@ -1841,28 +1903,24 @@ FormRestoreStorage (
Status = mHiiConfigRouting->ConfigToBlock (
mHiiConfigRouting,
Result,
- ConfigInfo->Storage->EditBuffer,
+ Dst,
&BufferSize,
&Progress
);
if (Result != NULL) {
FreePool (Result);
}
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
} else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);
while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (Link);
if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {
- if (Node->EditValue != NULL) {
- FreePool (Node->EditValue);
+ if (SyncOrRestore) {
+ NewStringCpy (&Node->Value, Node->EditValue);
+ } else {
+ NewStringCpy (&Node->EditValue, Node->Value);
}
- Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);
- ASSERT (Node->EditValue != NULL);
}
Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);
@@ -1916,7 +1974,7 @@ DiscardForm (
//
// Prepare <ConfigResp>
//
- FormRestoreStorage(FormSet, ConfigInfo);
+ SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
}
Form->NvUpdateRequired = FALSE;
@@ -1942,7 +2000,7 @@ DiscardForm (
continue;
}
- RestoreStorage(Storage);
+ SynchronizeStorage(Storage, FALSE);
}
UpdateNvInfoInForm(FormSet, FALSE);
@@ -1974,6 +2032,8 @@ SubmitForm (
EFI_STRING ConfigResp;
EFI_STRING Progress;
FORMSET_STORAGE *Storage;
+ UINTN BufferSize;
+ UINT8 *TmpBuf;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
//
@@ -1995,7 +2055,8 @@ SubmitForm (
ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
Link = GetNextNode (&Form->ConfigRequestHead, Link);
- if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
+ Storage = ConfigInfo->Storage;
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
continue;
}
@@ -2007,7 +2068,7 @@ SubmitForm (
}
//
- // Prepare <ConfigResp>
+ // 1. Prepare <ConfigResp>
//
Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);
if (EFI_ERROR (Status)) {
@@ -2015,27 +2076,82 @@ SubmitForm (
}
//
- // Send <ConfigResp> to Configuration Driver
+ // 2. Set value to hii driver or efi variable.
//
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ //
+ // Send <ConfigResp> to Configuration Driver
+ //
+ if (FormSet->ConfigAccess != NULL) {
+ Status = FormSet->ConfigAccess->RouteConfig (
+ FormSet->ConfigAccess,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
+ }
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ TmpBuf = NULL;
+ TmpBuf = AllocateZeroPool(Storage->Size);
+ if (TmpBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ BufferSize = Storage->Size;
+ Status = gRT->GetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ NULL,
+ &BufferSize,
+ TmpBuf
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (TmpBuf);
+ FreePool (ConfigResp);
+ return Status;
+ }
+ ASSERT (BufferSize == Storage->Size);
+ Status = mHiiConfigRouting->ConfigToBlock (
+ mHiiConfigRouting,
+ ConfigResp,
+ TmpBuf,
+ &BufferSize,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (TmpBuf);
+ FreePool (ConfigResp);
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ Storage->Attributes,
+ Storage->Size,
+ TmpBuf
+ );
+ FreePool (TmpBuf);
if (EFI_ERROR (Status)) {
FreePool (ConfigResp);
return Status;
}
}
FreePool (ConfigResp);
-
//
- // Config success, update storage shadow Buffer
+ // 3. Config success, update storage shadow Buffer, only update the data belong to this form.
//
- SynchronizeStorage (ConfigInfo->Storage);
+ SynchronizeStorageForForm(FormSet, ConfigInfo, TRUE);
}
+ //
+ // 4. Update the NV flag.
+ //
Form->NvUpdateRequired = FALSE;
} else {
//
@@ -2058,35 +2174,86 @@ SubmitForm (
}
//
- // Prepare <ConfigResp>
+ // 1. Prepare <ConfigResp>
//
Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);
if (EFI_ERROR (Status)) {
return Status;
}
- //
- // Send <ConfigResp> to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+
+ //
+ // 2. Send <ConfigResp> to Configuration Driver
+ //
+ if (FormSet->ConfigAccess != NULL) {
+ Status = FormSet->ConfigAccess->RouteConfig (
+ FormSet->ConfigAccess,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
+ }
+ } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ //
+ // 1&2. Set the edit data to the variable.
+ //
+ TmpBuf = NULL;
+ TmpBuf = AllocateZeroPool (Storage->Size);
+ if (TmpBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ BufferSize = Storage->Size;
+ Status = gRT->GetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ NULL,
+ &BufferSize,
+ TmpBuf
+ );
+ ASSERT (BufferSize == Storage->Size);
+ Status = mHiiConfigRouting->ConfigToBlock (
+ mHiiConfigRouting,
+ ConfigResp,
+ TmpBuf,
+ &BufferSize,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (TmpBuf);
+ FreePool (ConfigResp);
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ Storage->Attributes,
+ Storage->Size,
+ TmpBuf
+ );
if (EFI_ERROR (Status)) {
+ FreePool (TmpBuf);
FreePool (ConfigResp);
return Status;
}
+ FreePool (TmpBuf);
}
FreePool (ConfigResp);
-
//
- // Config success, update storage shadow Buffer
+ // 3. Config success, update storage shadow Buffer
//
- SynchronizeStorage (Storage);
+ SynchronizeStorage (Storage, TRUE);
}
+ //
+ // 4. Update the NV flag.
+ //
UpdateNvInfoInForm(FormSet, FALSE);
}
@@ -2136,7 +2303,9 @@ GetDefaultValueFromAltCfg (
Value = NULL;
Storage = Question->Storage;
- if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
+ if ((Storage == NULL) ||
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) ||
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
return Status;
}
@@ -2754,6 +2923,17 @@ LoadStorage (
return EFI_SUCCESS;
}
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ Status = gRT->GetVariable (
+ Storage->Name,
+ &Storage->Guid,
+ NULL,
+ (UINTN*)&Storage->Size,
+ Storage->EditBuffer
+ );
+ return Status;
+ }
+
if (FormSet->ConfigAccess == NULL) {
return EFI_NOT_FOUND;
}
@@ -2817,6 +2997,7 @@ CopyStorage (
switch (Src->Type) {
case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);
CopyMem (Dst->Buffer, Src->Buffer, Src->Size);
break;
@@ -2907,7 +3088,7 @@ InitializeCurrentSetting (
// settings(higher priority), sychronize it to shadow Buffer
//
if (!EFI_ERROR (Status)) {
- SynchronizeStorage (Storage);
+ SynchronizeStorage (Storage, TRUE);
}
} else {
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 4740731edf..27a1ad1c3c 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -188,6 +188,7 @@ typedef struct {
#define EFI_HII_VARSTORE_BUFFER 0
#define EFI_HII_VARSTORE_NAME_VALUE 1
#define EFI_HII_VARSTORE_EFI_VARIABLE 2
+#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3
#define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1