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
This commit is contained in:
ydong10 2011-07-12 07:24:36 +00:00
parent d23610ebbc
commit cce6230ffb
5 changed files with 951 additions and 325 deletions

View File

@ -780,6 +780,187 @@ BlockArrayCheck (
return FALSE; 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 This function parses Form Package to get the block array and the default
value array according to the request ConfigHdr. value array according to the request ConfigHdr.
@ -811,6 +992,7 @@ ParseIfrData (
EFI_STATUS Status; EFI_STATUS Status;
UINTN IfrOffset; UINTN IfrOffset;
EFI_IFR_VARSTORE *IfrVarStore; EFI_IFR_VARSTORE *IfrVarStore;
EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
EFI_IFR_OP_HEADER *IfrOpHdr; EFI_IFR_OP_HEADER *IfrOpHdr;
EFI_IFR_ONE_OF *IfrOneOf; EFI_IFR_ONE_OF *IfrOneOf;
EFI_IFR_ONE_OF_OPTION *IfrOneOfOption; EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
@ -876,7 +1058,7 @@ ParseIfrData (
LengthString = StrLen (GuidStr); LengthString = StrLen (GuidStr);
LengthString = LengthString + StrLen (NameStr) + 1; LengthString = LengthString + StrLen (NameStr) + 1;
TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16)); TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
if (TempStr == NULL) { if (TempStr == NULL) {
FreePool (GuidStr); FreePool (GuidStr);
FreePool (NameStr); FreePool (NameStr);
FreePool (VarStoreName); FreePool (VarStoreName);
@ -907,6 +1089,73 @@ ParseIfrData (
FreePool (TempStr); FreePool (TempStr);
break; 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: case EFI_IFR_DEFAULTSTORE_OP:
// //
// Add new the map between default id and default name. // Add new the map between default id and default name.
@ -1638,46 +1887,11 @@ GetFullStringFromHiiFormPackages (
DataExist = FALSE; DataExist = FALSE;
Progress = *Request; Progress = *Request;
// Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
// 0. Get Hii Form Package by HiiHandle
//
Status = ExportFormPackages (
&mPrivate,
DataBaseRecord->Handle,
DataBaseRecord->PackageList,
0,
PackageSize,
HiiFormPackage,
&ResultSize
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return 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
);
if (EFI_ERROR (Status)) {
goto Done;
}
// //
// 1. Get the request block array by Request String when Request string containts the block array. // 1. Get the request block array by Request String when Request string containts the block array.
// //
@ -2208,6 +2422,168 @@ Done:
return Status; 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
<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 This function allows a caller to extract the current configuration
for one or more named elements from one or more drivers. for one or more named elements from one or more drivers.
@ -2275,6 +2651,8 @@ HiiConfigRoutingExtractConfig (
EFI_STRING DefaultResults; EFI_STRING DefaultResults;
BOOLEAN FirstElement; BOOLEAN FirstElement;
BOOLEAN IfrDataParsedFlag; BOOLEAN IfrDataParsedFlag;
BOOLEAN IsEfiVarStore;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
if (This == NULL || Progress == NULL || Results == NULL) { if (This == NULL || Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -2292,8 +2670,11 @@ HiiConfigRoutingExtractConfig (
ConfigRequest = NULL; ConfigRequest = NULL;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
AccessResults = NULL; AccessResults = NULL;
AccessProgress = NULL;
DevicePath = NULL; DevicePath = NULL;
IfrDataParsedFlag = FALSE; IfrDataParsedFlag = FALSE;
IsEfiVarStore = FALSE;
EfiVarStoreInfo = NULL;
// //
// The first element of <MultiConfigRequest> should be // 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 ( Status = GetVarStoreType(Database, ConfigRequest, &IsEfiVarStore, &EfiVarStoreInfo);
DriverHandle, if (EFI_ERROR (Status)) {
&gEfiHiiConfigAccessProtocolGuid, goto Done;
(VOID **) &ConfigAccess }
);
ASSERT_EFI_ERROR (Status);
Status = ConfigAccess->ExtractConfig ( if (IsEfiVarStore) {
ConfigAccess, //
ConfigRequest, // Call the GetVariable function to extract settings.
&AccessProgress, //
&AccessResults 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
);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
// //
// AccessProgress indicates the parsing progress on <ConfigRequest>. // AccessProgress indicates the parsing progress on <ConfigRequest>.
@ -2766,6 +3163,8 @@ HiiConfigRoutingRouteConfig (
EFI_HANDLE DriverHandle; EFI_HANDLE DriverHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
EFI_STRING AccessProgress; EFI_STRING AccessProgress;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
BOOLEAN IsEfiVarstore;
if (This == NULL || Progress == NULL) { if (This == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -2779,6 +3178,10 @@ HiiConfigRoutingRouteConfig (
Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This); Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
StringPtr = Configuration; StringPtr = Configuration;
*Progress = StringPtr; *Progress = StringPtr;
Database = NULL;
AccessProgress = NULL;
EfiVarStoreInfo= NULL;
IsEfiVarstore = FALSE;
// //
// The first element of <MultiConfigResp> should be // The first element of <MultiConfigResp> should be
@ -2869,21 +3272,36 @@ HiiConfigRoutingRouteConfig (
FreePool (DevicePath); FreePool (DevicePath);
// //
// Call corresponding ConfigAccess protocol to route settings // Check whether this ConfigRequest is search from Efi varstore type storage.
// //
Status = gBS->HandleProtocol ( Status = GetVarStoreType(Database, ConfigResp, &IsEfiVarstore, &EfiVarStoreInfo);
DriverHandle, if (EFI_ERROR (Status)) {
&gEfiHiiConfigAccessProtocolGuid, return Status;
(VOID **) &ConfigAccess }
);
ASSERT_EFI_ERROR (Status);
Status = ConfigAccess->RouteConfig ( if (IsEfiVarstore) {
ConfigAccess, //
ConfigResp, // Call the SetVariable function to route settings.
&AccessProgress //
); 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)) { if (EFI_ERROR (Status)) {
// //
// AccessProgress indicates the parsing progress on <ConfigResp>. // AccessProgress indicates the parsing progress on <ConfigResp>.

View File

@ -1716,6 +1716,7 @@ EvaluateExpression (
if (OpCode->VarStorage != NULL) { if (OpCode->VarStorage != NULL) {
switch (OpCode->VarStorage->Type) { switch (OpCode->VarStorage->Type) {
case EFI_HII_VARSTORE_BUFFER: case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
// //
// Get value from Edit Buffer // Get value from Edit Buffer
// //
@ -1765,6 +1766,7 @@ EvaluateExpression (
Value->Type = EFI_IFR_TYPE_UNDEFINED; Value->Type = EFI_IFR_TYPE_UNDEFINED;
Value->Value.u8 = 0; Value->Value.u8 = 0;
} }
break;
default: default:
// //
// Not recognize storage. // Not recognize storage.
@ -2123,6 +2125,7 @@ EvaluateExpression (
if (OpCode->VarStorage != NULL) { if (OpCode->VarStorage != NULL) {
switch (OpCode->VarStorage->Type) { switch (OpCode->VarStorage->Type) {
case EFI_HII_VARSTORE_BUFFER: case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth); CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);
Data1.Value.b = TRUE; Data1.Value.b = TRUE;
break; break;

View File

@ -329,7 +329,8 @@ InitializeConfigHdr (
{ {
CHAR16 *Name; 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; Name = Storage->Name;
} else { } else {
Name = NULL; Name = NULL;
@ -395,7 +396,8 @@ InitializeRequestElement (
// //
// Prepare <RequestElement> // 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 ( StrLen = UnicodeSPrint (
RequestElement, RequestElement,
30 * sizeof (CHAR16), 30 * sizeof (CHAR16),
@ -1480,11 +1482,32 @@ ParseOpCodes (
// Create a EFI variable Storage for this FormSet // Create a EFI variable Storage for this FormSet
// //
Storage = CreateStorage (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->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->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32)); 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; break;
// //

View File

@ -431,7 +431,8 @@ BrowserCallback (
Link = GetNextNode (&FormSet->StorageListHead, Link); Link = GetNextNode (&FormSet->StorageListHead, Link);
if (CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) { 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 // 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 VOID
SynchronizeStorage ( SynchronizeStorage (
IN FORMSET_STORAGE *Storage IN FORMSET_STORAGE *Storage,
IN BOOLEAN SyncOrRestore
) )
{ {
LIST_ENTRY *Link; LIST_ENTRY *Link;
@ -742,7 +748,12 @@ SynchronizeStorage (
switch (Storage->Type) { switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER: 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; break;
case EFI_HII_VARSTORE_NAME_VALUE: case EFI_HII_VARSTORE_NAME_VALUE:
@ -750,7 +761,11 @@ SynchronizeStorage (
while (!IsNull (&Storage->NameValueListHead, Link)) { while (!IsNull (&Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (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); Link = GetNextNode (&Storage->NameValueListHead, Link);
} }
@ -894,6 +909,7 @@ StorageToConfigResp (
switch (Storage->Type) { switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER: case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
Status = mHiiConfigRouting->BlockToConfig ( Status = mHiiConfigRouting->BlockToConfig (
mHiiConfigRouting, mHiiConfigRouting,
ConfigRequest, ConfigRequest,
@ -959,6 +975,7 @@ ConfigRespToStorage (
switch (Storage->Type) { switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER: case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
BufferSize = Storage->Size; BufferSize = Storage->Size;
Status = mHiiConfigRouting->ConfigToBlock ( Status = mHiiConfigRouting->ConfigToBlock (
mHiiConfigRouting, mHiiConfigRouting,
@ -1050,8 +1067,10 @@ GetQuestionValue (
BOOLEAN IsString; BOOLEAN IsString;
CHAR16 TemStr[5]; CHAR16 TemStr[5];
UINT8 DigitUint8; UINT8 DigitUint8;
UINT8 *TemBuffer;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
Value = NULL;
// //
// Statement don't have storage, skip them // Statement don't have storage, skip them
@ -1172,7 +1191,12 @@ GetQuestionValue (
Dst = (UINT8 *) &Question->HiiValue.Value; 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); IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
if (Cached) { if (Cached) {
if (IsBufferStorage) { if (IsBufferStorage) {
@ -1230,115 +1254,141 @@ GetQuestionValue (
FreePool (Value); FreePool (Value);
} }
} else { } else {
// 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);
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;
}
//
// Skip <ConfigRequest>
//
Value = Result + Length;
if (IsBufferStorage) {
// //
// Skip "&VALUE" // Request current settings from Configuration Driver
// //
Value = Value + 6; if (FormSet->ConfigAccess == NULL) {
} return EFI_NOT_FOUND;
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';
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
//
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 {
if (StorageWidth < ((LengthStr + 1) / 2)) { //
Status = EFI_BUFFER_TOO_SMALL; // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
// <ConfigHdr> + "&" + <VariableName>
//
if (IsBufferStorage) {
Length = StrLen (Storage->ConfigHdr);
Length += StrLen (Question->BlockName);
} else { } else {
ZeroMem (TemStr, sizeof (TemStr)); Length = StrLen (Storage->ConfigHdr);
for (Index = 0; Index < LengthStr; Index ++) { Length += StrLen (Question->VariableName) + 1;
TemStr[0] = Value[LengthStr - Index - 1]; }
DigitUint8 = (UINT8) StrHexToUint64 (TemStr); ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
if ((Index & 1) == 0) { ASSERT (ConfigRequest != NULL);
Dst [Index/2] = DigitUint8;
} else { StrCpy (ConfigRequest, Storage->ConfigHdr);
Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]); if (IsBufferStorage) {
StrCat (ConfigRequest, Question->BlockName);
} else {
StrCat (ConfigRequest, L"&");
StrCat (ConfigRequest, Question->VariableName);
}
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"
//
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';
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
//
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 {
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); 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 { } else {
SetValueByName (Storage, Question->VariableName, Value, TRUE); SetValueByName (Storage, Question->VariableName, Value, TRUE);
} }
FreePool (Result);
} }
return Status; return Status;
@ -1507,7 +1555,12 @@ SetQuestionValue (
Src = (UINT8 *) &Question->HiiValue.Value; 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); IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
if (IsBufferStorage) { if (IsBufferStorage) {
// //
@ -1550,84 +1603,115 @@ SetQuestionValue (
} }
if (!Cached) { if (!Cached) {
// 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"=");
}
Value = ConfigResp + StrLen (ConfigResp);
if (!IsBufferStorage && IsString) {
// //
// Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044" // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
// <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
// //
TemName = (CHAR16 *) Src; if (IsBufferStorage) {
TemString = Value; Length = StrLen (Question->BlockName) + 7;
for (; *TemName != L'\0'; TemName++) { } else {
TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4); Length = StrLen (Question->VariableName) + 2;
} }
} else { if (!IsBufferStorage && IsString) {
// Length += (StrLen ((CHAR16 *) Src) * 4);
// Convert Buffer to Hex String } else {
// Length += (StorageWidth * 2);
TemBuffer = Src + StorageWidth - 1;
TemString = Value;
for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
} }
} ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
ASSERT (ConfigResp != NULL);
// StrCpy (ConfigResp, Storage->ConfigHdr);
// Convert to lower char. if (IsBufferStorage) {
// StrCat (ConfigResp, Question->BlockName);
for (TemString = Value; *Value != L'\0'; Value++) { StrCat (ConfigResp, L"&VALUE=");
if (*Value >= L'A' && *Value <= L'Z') { } else {
*Value = (CHAR16) (*Value - L'A' + L'a'); StrCat (ConfigResp, L"&");
StrCat (ConfigResp, Question->VariableName);
StrCat (ConfigResp, L"=");
} }
}
// Value = ConfigResp + StrLen (ConfigResp);
// Submit Question Value to Configuration Driver
// if (!IsBufferStorage && IsString) {
if (FormSet->ConfigAccess != NULL) { //
Status = FormSet->ConfigAccess->RouteConfig ( // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
FormSet->ConfigAccess, //
ConfigResp, TemName = (CHAR16 *) Src;
&Progress TemString = Value;
); for (; *TemName != L'\0'; TemName++) {
if (EFI_ERROR (Status)) { TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
FreePool (ConfigResp); }
} 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);
}
}
//
// 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');
}
}
//
// Submit Question Value to Configuration Driver
//
if (FormSet->ConfigAccess != NULL) {
Status = FormSet->ConfigAccess->RouteConfig (
FormSet->ConfigAccess,
ConfigResp,
&Progress
);
if (EFI_ERROR (Status)) {
FreePool (ConfigResp);
return Status;
}
}
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
);
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; 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; return Status;
@ -1750,58 +1834,24 @@ NoSubmitCheck (
return EFI_SUCCESS; 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. Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure. @param FormSet FormSet data structure.
@param ConfigInfo The config info related to this form. @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. @retval EFI_SUCCESS The function completed successfully.
**/ **/
EFI_STATUS EFI_STATUS
FormRestoreStorage ( SynchronizeStorageForForm (
IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,
IN BOOLEAN SyncOrRestore
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -1810,10 +1860,12 @@ FormRestoreStorage (
UINTN BufferSize; UINTN BufferSize;
LIST_ENTRY *Link; LIST_ENTRY *Link;
NAME_VALUE_NODE *Node; NAME_VALUE_NODE *Node;
UINT8 *Src;
UINT8 *Dst;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
Result = NULL; Result = NULL;
if (FormSet->ConfigAccess == NULL) { if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
@ -1824,12 +1876,22 @@ FormRestoreStorage (
return EFI_SUCCESS; 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; 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( Status = mHiiConfigRouting->BlockToConfig(
mHiiConfigRouting, mHiiConfigRouting,
ConfigInfo->ConfigRequest, ConfigInfo->ConfigRequest,
ConfigInfo->Storage->Buffer, Src,
BufferSize, BufferSize,
&Result, &Result,
&Progress &Progress
@ -1841,28 +1903,24 @@ FormRestoreStorage (
Status = mHiiConfigRouting->ConfigToBlock ( Status = mHiiConfigRouting->ConfigToBlock (
mHiiConfigRouting, mHiiConfigRouting,
Result, Result,
ConfigInfo->Storage->EditBuffer, Dst,
&BufferSize, &BufferSize,
&Progress &Progress
); );
if (Result != NULL) { if (Result != NULL) {
FreePool (Result); FreePool (Result);
} }
if (EFI_ERROR (Status)) {
return Status;
}
} else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead); Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);
while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) { while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (Link); Node = NAME_VALUE_NODE_FROM_LINK (Link);
if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) { if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {
if (Node->EditValue != NULL) { if (SyncOrRestore) {
FreePool (Node->EditValue); 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); Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);
@ -1916,7 +1974,7 @@ DiscardForm (
// //
// Prepare <ConfigResp> // Prepare <ConfigResp>
// //
FormRestoreStorage(FormSet, ConfigInfo); SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
} }
Form->NvUpdateRequired = FALSE; Form->NvUpdateRequired = FALSE;
@ -1942,7 +2000,7 @@ DiscardForm (
continue; continue;
} }
RestoreStorage(Storage); SynchronizeStorage(Storage, FALSE);
} }
UpdateNvInfoInForm(FormSet, FALSE); UpdateNvInfoInForm(FormSet, FALSE);
@ -1974,6 +2032,8 @@ SubmitForm (
EFI_STRING ConfigResp; EFI_STRING ConfigResp;
EFI_STRING Progress; EFI_STRING Progress;
FORMSET_STORAGE *Storage; FORMSET_STORAGE *Storage;
UINTN BufferSize;
UINT8 *TmpBuf;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
// //
@ -1995,7 +2055,8 @@ SubmitForm (
ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
Link = GetNextNode (&Form->ConfigRequestHead, 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; continue;
} }
@ -2007,7 +2068,7 @@ SubmitForm (
} }
// //
// Prepare <ConfigResp> // 1. Prepare <ConfigResp>
// //
Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE); Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);
if (EFI_ERROR (Status)) { 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) { if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
Status = FormSet->ConfigAccess->RouteConfig ( Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
FormSet->ConfigAccess, //
ConfigResp, // Send <ConfigResp> to Configuration Driver
&Progress //
); 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)) { if (EFI_ERROR (Status)) {
FreePool (ConfigResp); FreePool (ConfigResp);
return Status; return Status;
} }
} }
FreePool (ConfigResp); 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; Form->NvUpdateRequired = FALSE;
} else { } else {
// //
@ -2058,35 +2174,86 @@ SubmitForm (
} }
// //
// Prepare <ConfigResp> // 1. Prepare <ConfigResp>
// //
Status = StorageToConfigResp (Storage, &ConfigResp, FALSE); Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
// if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
// Send <ConfigResp> to Configuration Driver Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
//
if (FormSet->ConfigAccess != NULL) { //
Status = FormSet->ConfigAccess->RouteConfig ( // 2. Send <ConfigResp> to Configuration Driver
FormSet->ConfigAccess, //
ConfigResp, if (FormSet->ConfigAccess != NULL) {
&Progress 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)) { if (EFI_ERROR (Status)) {
FreePool (TmpBuf);
FreePool (ConfigResp); FreePool (ConfigResp);
return Status; 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); 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); UpdateNvInfoInForm(FormSet, FALSE);
} }
@ -2136,7 +2303,9 @@ GetDefaultValueFromAltCfg (
Value = NULL; Value = NULL;
Storage = Question->Storage; 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; return Status;
} }
@ -2754,6 +2923,17 @@ LoadStorage (
return EFI_SUCCESS; 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) { if (FormSet->ConfigAccess == NULL) {
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
@ -2817,6 +2997,7 @@ CopyStorage (
switch (Src->Type) { switch (Src->Type) {
case EFI_HII_VARSTORE_BUFFER: case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size); CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);
CopyMem (Dst->Buffer, Src->Buffer, Src->Size); CopyMem (Dst->Buffer, Src->Buffer, Src->Size);
break; break;
@ -2907,7 +3088,7 @@ InitializeCurrentSetting (
// settings(higher priority), sychronize it to shadow Buffer // settings(higher priority), sychronize it to shadow Buffer
// //
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
SynchronizeStorage (Storage); SynchronizeStorage (Storage, TRUE);
} }
} else { } else {
// //

View File

@ -188,6 +188,7 @@ typedef struct {
#define EFI_HII_VARSTORE_BUFFER 0 #define EFI_HII_VARSTORE_BUFFER 0
#define EFI_HII_VARSTORE_NAME_VALUE 1 #define EFI_HII_VARSTORE_NAME_VALUE 1
#define EFI_HII_VARSTORE_EFI_VARIABLE 2 #define EFI_HII_VARSTORE_EFI_VARIABLE 2
#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3
#define FORM_INCONSISTENT_VALIDATION 0 #define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1 #define FORM_NO_SUBMIT_VALIDATION 1