From cce6230ffb5981caab05cfcb500c9217db2a6963 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Tue, 12 Jul 2011 07:24:36 +0000 Subject: [PATCH] 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 --- .../Universal/HiiDatabaseDxe/ConfigRouting.c | 544 ++++++++++++-- .../Universal/SetupBrowserDxe/Expression.c | 3 + .../Universal/SetupBrowserDxe/IfrParse.c | 29 +- .../Universal/SetupBrowserDxe/Setup.c | 675 +++++++++++------- .../Universal/SetupBrowserDxe/Setup.h | 1 + 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 @@ -780,6 +780,187 @@ BlockArrayCheck ( return FALSE; } +/** + 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; } // @@ -2208,6 +2422,168 @@ Done: return Status; } +/** + 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 + format. + @param RequestResp Pointer to a null-terminated Unicode string in + 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 + format. + @param Result Pointer to a null-terminated Unicode string in + 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 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 . @@ -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 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 . 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 // - 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 + // + 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; + } - // - // ::= + || - // + "&" + - // - 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); + // + // ::= + || + // + "&" + + // + 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 - // - Value = Result + Length; - if (IsBufferStorage) { // - // Skip "&VALUE" + // Skip // - Value = Value + 6; - } - if (*Value != '=') { - FreePool (Result); - return EFI_NOT_FOUND; - } - // - // Skip '=', point to value - // - Value = Value + 1; - - // - // Suppress 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 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) { - // - // ::= + + "&VALUE=" + "StorageWidth * 2" || - // + "&" + + "=" + "" - // - 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) { + // + // ::= + + "&VALUE=" + "StorageWidth * 2" || + // + "&" + + "=" + "" + // + 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; @@ -1750,58 +1834,24 @@ NoSubmitCheck ( return EFI_SUCCESS; } -/** - 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 // - 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 + // 1. Prepare // Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE); if (EFI_ERROR (Status)) { @@ -2015,27 +2076,82 @@ SubmitForm ( } // - // Send 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 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 + // 1. Prepare // Status = StorageToConfigResp (Storage, &ConfigResp, FALSE); if (EFI_ERROR (Status)) { return Status; } - // - // Send 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 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 -- 2.39.2