\r
#include "HiiDatabase.h"\r
\r
-HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE ConfigAccessProtocolInstanceTempate = {\r
- HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_SIGNATURE,\r
+BOOLEAN mHiiPackageListUpdated;\r
+\r
+CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {\r
+ CONFIG_ACCESS_PRIVATE_SIGNATURE,\r
{\r
ThunkExtractConfig,\r
ThunkRouteConfig,\r
ThunkCallback\r
}, //ConfigAccessProtocol\r
- NULL, //FrameworkFormCallbackProtocol\r
- {NULL, NULL} //ConfigAccessStorageListHead\r
+ NULL, //FormCallbackProtocol\r
+ {NULL, NULL}, //ConfigAccessStorageListHead\r
+ NULL \r
};\r
\r
/**\r
Framework Module which does not include packages introduced by UEFI Specification\r
or packages that is not supported by Thunk layer.\r
\r
- @param Packages The Framework Package List\r
+ @param Packages The Framework Package List\r
\r
- @retval EFI_HII_PACKAGE_HEADER* Return the Package Header of\r
- Form Package.\r
- @retval NULL If no Form Package is found.\r
+ @retval EFI_HII_PACKAGE_HEADER* Return the Package Header of Form Package.\r
+ @retval NULL If no Form Package is found.\r
**/\r
EFI_HII_PACKAGE_HEADER *\r
GetIfrFormSet (\r
If FormSetPackage is not EFI_HII_PACKAGE_FORM, then ASSERT.\r
If there is no linear buffer storage in this formset, then ASSERT.\r
\r
- @param FormSetPackage The Form Package header.\r
+ @param FormSetPackage The Form Package header.\r
@param BufferStorageListHead The link list for the VARSTORE found in the form package.\r
\r
- @retval EFI_SUCCESS The function scan the form set and find one or more \r
- VARSTOREs.\r
+ @retval EFI_SUCCESS The function scan the form set and find one or more VARSTOREs.\r
@retval EFI_OUT_OF_RESOURCES There is not enough memory to complete the function.\r
**/\r
EFI_STATUS\r
UINT8 *OpCodeData;\r
UINT8 Operand;\r
EFI_IFR_VARSTORE *VarStoreOpCode;\r
- HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
+ BUFFER_STORAGE_ENTRY *BufferStorage;\r
\r
ASSERT (FormSetPackage->Type == EFI_HII_PACKAGE_FORM);\r
\r
OpCodeOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ //\r
+ // Scan all opcode for the FormSet Package for \r
+ // EFI_IFR_VARSTORE_OP opcode.\r
+ //\r
while (OpCodeOffset < FormSetPackage->Length) {\r
OpCodeData = (UINT8 *) FormSetPackage + OpCodeOffset;\r
\r
\r
if (Operand == EFI_IFR_VARSTORE_OP) {\r
VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData;\r
- BufferStorageKey = AllocateZeroPool (sizeof (*BufferStorageKey));\r
- if (BufferStorageKey == NULL) {\r
+ BufferStorage = AllocateZeroPool (sizeof (*BufferStorage));\r
+ if (BufferStorage == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- CopyMem (&BufferStorageKey->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));\r
+ //\r
+ // Record the attributes: GUID, Name, VarStoreId and Size.\r
+ //\r
+ CopyMem (&BufferStorage->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));\r
\r
- BufferStorageKey->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);\r
- AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorageKey->Name);\r
+ BufferStorage->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);\r
+ AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorage->Name);\r
\r
- BufferStorageKey->VarStoreId = VarStoreOpCode->VarStoreId;\r
+ BufferStorage->VarStoreId = VarStoreOpCode->VarStoreId;\r
\r
- BufferStorageKey->Size = VarStoreOpCode->Size;\r
- BufferStorageKey->Signature = HII_TRHUNK_BUFFER_STORAGE_KEY_SIGNATURE;\r
+ BufferStorage->Size = VarStoreOpCode->Size;\r
+ BufferStorage->Signature = BUFFER_STORAGE_ENTRY_SIGNATURE;\r
\r
- InsertTailList (BufferStorageListHead, &BufferStorageKey->List);\r
+ InsertTailList (BufferStorageListHead, &BufferStorage->Link);\r
}\r
}\r
\r
return EFI_SUCCESS;\r
}\r
- \r
+\r
+\r
/**\r
This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered\r
by a module using Framework HII Protocol Interfaces.\r
UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
that Setup Utility can load the Buffer Storage using this protocol.\r
\r
- @param Packages The framework package list.\r
- @param MapEntry The Thunk Layer Handle Mapping Database Entry.\r
+ @param Packages The framework package list.\r
+ @param ThunkContext The Thunk Layer Handle Mapping Database Entry.\r
\r
- @retval EFI_SUCCESS The Config Access Protocol is installed successfully.\r
- @retval EFI_OUT_RESOURCE There is not enough memory.\r
+ @retval EFI_SUCCESS The Config Access Protocol is installed successfully.\r
+ @retval EFI_OUT_RESOURCE There is not enough memory.\r
\r
**/\r
EFI_STATUS\r
-InstallDefaultUefiConfigAccessProtocol (\r
- IN CONST EFI_HII_PACKAGES *Packages,\r
- IN OUT HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry\r
+InstallDefaultConfigAccessProtocol (\r
+ IN CONST EFI_HII_PACKAGES *Packages,\r
+ IN OUT HII_THUNK_CONTEXT *ThunkContext\r
)\r
{\r
EFI_HII_PACKAGE_HEADER *FormSetPackage;\r
EFI_STATUS Status;\r
- HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessInstance;\r
+ CONFIG_ACCESS_PRIVATE *ConfigAccessInstance;\r
\r
- Status = HiiLibCreateHiiDriverHandle (&MapEntry->UefiHiiDriverHandle);\r
+ Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle);\r
ConfigAccessInstance = AllocateCopyPool (\r
- sizeof (HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE), \r
- &ConfigAccessProtocolInstanceTempate\r
+ sizeof (CONFIG_ACCESS_PRIVATE), \r
+ &gConfigAccessPrivateTempate\r
);\r
ASSERT (ConfigAccessInstance != NULL);\r
- InitializeListHead (&ConfigAccessInstance->ConfigAccessBufferStorageListHead);\r
+ \r
+ InitializeListHead (&ConfigAccessInstance->BufferStorageListHead);\r
\r
//\r
// We assume there is only one formset package in each Forms Package\r
FormSetPackage = GetIfrFormSet (Packages);\r
ASSERT (FormSetPackage != NULL);\r
\r
- Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->ConfigAccessBufferStorageListHead);\r
+ Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->BufferStorageListHead);\r
if (EFI_ERROR (Status)) {\r
FreePool (ConfigAccessInstance);\r
ASSERT (FALSE);\r
}\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
- &MapEntry->UefiHiiDriverHandle,\r
+ &ThunkContext->UefiHiiDriverHandle,\r
&gEfiHiiConfigAccessProtocolGuid,\r
&ConfigAccessInstance->ConfigAccessProtocol,\r
NULL\r
);\r
+ //\r
+ //BUGBUG: Remove when done.\r
+ //\r
ASSERT_EFI_ERROR (Status);\r
+ \r
if (EFI_ERROR (Status)) {\r
FreePool (ConfigAccessInstance);\r
return Status;\r
}\r
+\r
+ ConfigAccessInstance->ThunkContext = ThunkContext;\r
\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
+VOID\r
+DestroyBufferStorageList (\r
+ IN LIST_ENTRY *ListHead\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ BUFFER_STORAGE_ENTRY *Entry;\r
\r
- Wrap EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
- \r
- @param BufferStorageKey The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
- @param FrameworkFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.\r
- @param Data The data to be saved.\r
- @param DataSize The size of data.\r
- \r
- @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
- **/\r
-EFI_STATUS\r
-RouteConfigToFrameworkFormCallBack (\r
- IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
- IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,\r
- IN VOID *Data,\r
- IN UINTN DataSize\r
+ while (!IsListEmpty (ListHead)) {\r
+ Link = GetFirstNode (ListHead);\r
+ \r
+ Entry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);\r
+\r
+ FreePool (Entry->Name);\r
+ Link = RemoveEntryList (Link);\r
+\r
+ FreePool (Entry);\r
+ }\r
+}\r
+\r
+VOID\r
+UninstallDefaultConfigAccessProtocol (\r
+ IN HII_THUNK_CONTEXT *ThunkContext\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN ResetRequired;\r
+ EFI_STATUS Status;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ CONFIG_ACCESS_PRIVATE *ConfigAccessInstance;\r
+ \r
+ HiiLibDestroyHiiDriverHandle (ThunkContext->UefiHiiDriverHandle);\r
+\r
+ Status = gBS->HandleProtocol (\r
+ ThunkContext->UefiHiiDriverHandle,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ (VOID **) &ConfigAccess\r
+ );\r
+\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gBS->UninstallProtocolInterface (\r
+ ThunkContext->UefiHiiDriverHandle,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ ConfigAccess\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ ConfigAccessInstance = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccess);\r
+\r
+ DestroyBufferStorageList (&ConfigAccessInstance->BufferStorageListHead);\r
\r
- Status = FrameworkFormCallBack->NvWrite (\r
- FrameworkFormCallBack, \r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- DataSize,\r
- Data,\r
- &ResetRequired\r
- );\r
- return Status;\r
}\r
+ \r
\r
/**\r
Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvRead.\r
\r
- @param BufferStorageKey The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvRead.\r
- @param FrameworkFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.\r
- @param Data The data read.\r
- @param DataSize The size of data.\r
+ @param BufferStorage The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvRead.\r
+ @param FwFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.\r
+ @param Data The data read.\r
+ @param DataSize The size of data.\r
\r
- @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
+ @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
@retval EFI_INVALID_PARAMETER If the EFI_FORM_CALLBACK_PROTOCOL.NvRead return the size information of the data\r
- does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.\r
+ does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
**/\r
EFI_STATUS\r
-ExtractConfigFromFrameworkFormCallBack (\r
- IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
- IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,\r
+CallFormCallBack (\r
+ IN BUFFER_STORAGE_ENTRY *BufferStorage,\r
+ IN EFI_FORM_CALLBACK_PROTOCOL *FwFormCallBack,\r
OUT VOID **Data,\r
OUT UINTN *DataSize\r
)\r
*DataSize = 0;\r
*Data = NULL;\r
\r
- Status = FrameworkFormCallBack->NvRead (\r
- FrameworkFormCallBack, \r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
+ Status = FwFormCallBack->NvRead (\r
+ FwFormCallBack, \r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
NULL,\r
DataSize,\r
*Data\r
);\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
- if (BufferStorageKey->Size != *DataSize) {\r
+ if (BufferStorage->Size != *DataSize) {\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
}\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- FrameworkFormCallBack->NvRead (\r
- FrameworkFormCallBack, \r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
+ FwFormCallBack->NvRead (\r
+ FwFormCallBack, \r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
NULL,\r
DataSize,\r
*Data\r
return Status;\r
}\r
\r
-/**\r
- Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Set Service.\r
- \r
- @param BufferStorageKey The key with all attributes needed to call a UEFI Variable Get Service.\r
- @param Data The data read.\r
- @param DataSize The size of data.\r
-\r
- @retval EFI_STATUS The status returned by the UEFI Variable Set Service.\r
- \r
- **/\r
-EFI_STATUS\r
-RouteConfigToUefiVariable (\r
- IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
- IN VOID *Data,\r
- IN UINTN DataSize\r
- )\r
-{\r
- return gRT->SetVariable (\r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- DataSize,\r
- Data\r
- );\r
- \r
-}\r
\r
/**\r
Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Get Service.\r
\r
- @param BufferStorageKey The key with all attributes needed to call a UEFI Variable Get Service.\r
- @param Data The data read.\r
- @param DataSize The size of data.\r
+ @param BufferStorage The key with all attributes needed to call a UEFI Variable Get Service.\r
+ @param Data The data read.\r
+ @param DataSize The size of data.\r
\r
If the UEFI Variable Get Service return the size information of the data\r
- does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.\r
+ does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
then ASSERT.\r
\r
- @retval EFI_STATUS The status returned by the UEFI Variable Get Service.\r
+ @retval EFI_STATUS The status returned by the UEFI Variable Get Service.\r
@retval EFI_INVALID_PARAMETER If the UEFI Variable Get Service return the size information of the data\r
- does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.\r
+ does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
**/\r
\r
EFI_STATUS\r
-ExtractConfigFromUefiVariable (\r
- IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
+GetUefiVariable (\r
+ IN BUFFER_STORAGE_ENTRY *BufferStorage,\r
OUT VOID **Data,\r
OUT UINTN *DataSize\r
)\r
*DataSize = 0;\r
*Data = NULL;\r
Status = gRT->GetVariable (\r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
NULL,\r
DataSize,\r
*Data\r
);\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
\r
- if (BufferStorageKey->Size != *DataSize) {\r
+ if (BufferStorage->Size != *DataSize) {\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
\r
Status = gRT->GetVariable (\r
- BufferStorageKey->Name,\r
- &BufferStorageKey->Guid,\r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
NULL,\r
DataSize,\r
*Data\r
so that data can be read from the data storage such as UEFI Variable or module's\r
customized storage exposed by EFI_FRAMEWORK_CALLBACK.\r
\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
@param Request A null-terminated Unicode string in <ConfigRequest> format. Note that this\r
- includes the routing information as well as the configurable name / value pairs. It is\r
- invalid for this string to be in <MultiConfigRequest> format.\r
+ includes the routing information as well as the configurable name / value pairs. It is\r
+ invalid for this string to be in <MultiConfigRequest> format.\r
\r
- @param Progress On return, points to a character in the Request string. Points to the string's null\r
- terminator if request was successful. Points to the most recent '&' before the first\r
- failing name / value pair (or the beginning of the string if the failure is in the first\r
- name / value pair) if the request was not successful\r
+ @param Progress On return, points to a character in the Request string. Points to the string's null\r
+ terminator if request was successful. Points to the most recent '&' before the first\r
+ failing name / value pair (or the beginning of the string if the failure is in the first\r
+ name / value pair) if the request was not successful\r
@param Results A null-terminated Unicode string in <ConfigAltResp> format which has all\r
- values filled in for the names in the Request string. String to be allocated by the called\r
- function.\r
+ values filled in for the names in the Request string. String to be allocated by the called\r
+ function.\r
\r
@retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.\r
- @retval EFI_SUCCESS The setting is retrived successfully.\r
- @retval !EFI_SUCCESS The error returned by UEFI Get Variable or Framework Form Callback Nvread.\r
+ @retval EFI_SUCCESS The setting is retrived successfully.\r
+ @retval !EFI_SUCCESS The error returned by UEFI Get Variable or Framework Form Callback Nvread.\r
**/\r
EFI_STATUS\r
EFIAPI\r
)\r
{\r
EFI_STATUS Status;\r
- HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
- LIST_ENTRY *ListEntry;\r
- HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
+ CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
+ LIST_ENTRY *Link;\r
+ BUFFER_STORAGE_ENTRY *BufferStorage;\r
VOID *Data;\r
UINTN DataSize;\r
\r
Data = NULL;\r
- ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
+ ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
\r
//\r
// For now, only one var varstore is supported so that we don't need to parse the Configuration string.\r
//\r
- ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);\r
- if (ListEntry == NULL) {\r
+ Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
+ if (Link == NULL) {\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);\r
+ BufferStorage = BUFFER_STORAGE_ENTRY_FROM_LINK (Link);\r
\r
- if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||\r
- ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {\r
- Status = ExtractConfigFromUefiVariable (\r
- BufferStorageKey,\r
+ if (ConfigAccess->FormCallbackProtocol == NULL ||\r
+ ConfigAccess->FormCallbackProtocol->NvRead == NULL) {\r
+ Status = GetUefiVariable (\r
+ BufferStorage,\r
&Data,\r
&DataSize\r
);\r
} else {\r
- Status = ExtractConfigFromFrameworkFormCallBack (\r
- BufferStorageKey,\r
- ConfigaAccessInstance->FrameworkFormCallbackProtocol,\r
+ Status = CallFormCallBack (\r
+ BufferStorage,\r
+ ConfigAccess->FormCallbackProtocol,\r
&Data,\r
&DataSize\r
);\r
so that data can be written to the data storage such as UEFI Variable or module's\r
customized storage exposed by EFI_FRAMEWORK_CALLBACK.\r
\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
- @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
+ @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
@param Progress A pointer to a string filled in with the offset of the most recent '&' before the first\r
- failing name / value pair (or the beginning of the string if the failure is in the first\r
- name / value pair) or the terminating NULL if all was successful.\r
+ failing name / value pair (or the beginning of the string if the failure is in the first\r
+ name / value pair) or the terminating NULL if all was successful.\r
\r
@retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.\r
- @retval EFI_SUCCESS The setting is saved successfully.\r
- @retval !EFI_SUCCESS The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.\r
+ @retval EFI_SUCCESS The setting is saved successfully.\r
+ @retval !EFI_SUCCESS The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.\r
**/ \r
EFI_STATUS\r
EFIAPI\r
)\r
{\r
EFI_STATUS Status;\r
- HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
- LIST_ENTRY *ListEntry;\r
- HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
- VOID *Data;\r
+ CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
+ LIST_ENTRY *Link;\r
+ BUFFER_STORAGE_ENTRY *BufferStorage;\r
+ UINT8 *Data;\r
UINTN DataSize;\r
+ UINTN DataSize2;\r
UINTN LastModifiedByteIndex;\r
+ BOOLEAN ResetRequired;\r
+ BOOLEAN DataAllocated;\r
\r
Data = NULL;\r
- ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
+ DataAllocated = TRUE;\r
+ ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
\r
//\r
// For now, only one var varstore is supported so that we don't need to parse the Configuration string.\r
//\r
- ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);\r
- if (ListEntry == NULL) {\r
+ Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
+ if (Link == NULL) {\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);\r
-\r
- Data = AllocateZeroPool (BufferStorageKey->Size);\r
- if (Data == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ BufferStorage = BUFFER_STORAGE_ENTRY_FROM_LINK (Link);\r
+ DataSize2 = BufferStorage->Size;\r
+ if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
+ if (ConfigAccess->FormCallbackProtocol == NULL ||\r
+ ConfigAccess->FormCallbackProtocol->NvRead == NULL) {\r
+ Status = GetUefiVariable (\r
+ BufferStorage,\r
+ &Data,\r
+ &DataSize\r
+ );\r
+ ASSERT (DataSize == DataSize2);\r
+ \r
+ } else {\r
+ Status = CallFormCallBack (\r
+ BufferStorage,\r
+ ConfigAccess->FormCallbackProtocol,\r
+ &Data,\r
+ &DataSize\r
+ );\r
+ ASSERT (DataSize == DataSize2);\r
+ \r
+ }\r
+ } else {\r
+ Status = EFI_SUCCESS;\r
+ Data = ConfigAccess->ThunkContext->NvMapOverride;\r
+ DataSize = DataSize2;\r
+ DataAllocated = FALSE;\r
+ } \r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
}\r
+\r
Status = mHiiConfigRoutingProtocol->ConfigToBlock (\r
mHiiConfigRoutingProtocol,\r
Configuration,\r
&LastModifiedByteIndex,\r
Progress\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- DataSize = BufferStorageKey->Size;\r
- if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||\r
- ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {\r
- Status = RouteConfigToUefiVariable (\r
- BufferStorageKey,\r
- Data,\r
- DataSize\r
- );\r
+ if (ConfigAccess->FormCallbackProtocol == NULL ||\r
+ ConfigAccess->FormCallbackProtocol->NvWrite == NULL) {\r
+ Status = gRT->SetVariable (\r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ DataSize,\r
+ Data\r
+ );\r
} else {\r
- Status = RouteConfigToFrameworkFormCallBack (\r
- BufferStorageKey,\r
- ConfigaAccessInstance->FrameworkFormCallbackProtocol,\r
- Data,\r
- DataSize\r
- );\r
+ Status = ConfigAccess->FormCallbackProtocol->NvWrite (\r
+ ConfigAccess->FormCallbackProtocol, \r
+ BufferStorage->Name,\r
+ &BufferStorage->Guid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ DataSize,\r
+ Data,\r
+ &ResetRequired\r
+ );\r
+ \r
}\r
\r
-Done: \r
- SafeFreePool (Data);\r
+Done: \r
+ if (DataAllocated && (Data != NULL)) {\r
+ FreePool (Data);\r
+ }\r
+ \r
return Status;\r
}\r
\r
+FRAMEWORK_EFI_IFR_DATA_ARRAY *\r
+CreateIfrDataArray (\r
+ IN CONFIG_ACCESS_PRIVATE *ConfigAccess,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value,\r
+ OUT BOOLEAN *NvMapAllocated\r
+ )\r
+{\r
+ FRAMEWORK_EFI_IFR_DATA_ARRAY *IfrDataArray;\r
+ FRAMEWORK_EFI_IFR_DATA_ENTRY *IfrDataEntry;\r
+ UINTN BrowserDataSize;\r
+ BUFFER_STORAGE_ENTRY *BufferStorageEntry;\r
+ LIST_ENTRY *Link;\r
+\r
+ IfrDataArray = AllocateZeroPool (0x100);\r
+ ASSERT (IfrDataArray != NULL);\r
+\r
+ if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
+ Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
+\r
+ ASSERT (!IsNull (&ConfigAccess->BufferStorageListHead, Link));\r
+\r
+ BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);\r
+\r
+ BrowserDataSize = BufferStorageEntry->Size;\r
+ *NvMapAllocated = TRUE;\r
+ IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);\r
+ GetBrowserData (NULL, NULL, &BrowserDataSize, IfrDataArray->NvRamMap);\r
+ } else {\r
+ *NvMapAllocated = FALSE;\r
+ IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;\r
+ }\r
+\r
+ IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
+\r
+ switch (Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+\r
+ return IfrDataArray;\r
+}\r
+\r
+VOID\r
+DestroyIfrDataArray (\r
+ IN FRAMEWORK_EFI_IFR_DATA_ARRAY *Array,\r
+ IN BOOLEAN NvMapAllocated\r
+ )\r
+{\r
+ if (NvMapAllocated) {\r
+ FreePool (Array->NvRamMap);\r
+ }\r
+\r
+ FreePool (Array);\r
+}\r
+\r
+\r
+ONE_OF_OPTION_MAP_ENTRY *\r
+GetOneOfOptionMapEntry (\r
+ IN HII_THUNK_CONTEXT *ThunkContext,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *Link2;\r
+ ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
+ ONE_OF_OPTION_MAP *OneOfOptionMap;\r
+\r
+ Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+ while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {\r
+ OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link);\r
+ if (OneOfOptionMap->QuestionId == QuestionId) {\r
+ ASSERT (OneOfOptionMap->ValueType == Type);\r
+\r
+ Link2 = GetFirstNode (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
+\r
+ while (!IsNull (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2)) {\r
+ OneOfOptionMapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
+\r
+ if (CompareMem (Value, &OneOfOptionMapEntry->Value, sizeof (EFI_IFR_TYPE_VALUE)) == 0) {\r
+ return OneOfOptionMapEntry;\r
+ }\r
+\r
+ Link2 = GetNextNode (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2);\r
+ }\r
+ }\r
+\r
+ Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
+ }\r
+\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Functions which are registered to receive notification of\r
+ database events have this prototype. The actual event is encoded\r
+ in NotifyType. The following table describes how PackageType,\r
+ PackageGuid, Handle, and Package are used for each of the\r
+ notification types.\r
+\r
+ @param PackageType Package type of the notification.\r
+\r
+ @param PackageGuid If PackageType is\r
+ EFI_HII_PACKAGE_TYPE_GUID, then this is\r
+ the pointer to the GUID from the Guid\r
+ field of EFI_HII_PACKAGE_GUID_HEADER.\r
+ Otherwise, it must be NULL.\r
+\r
+ @param Package Points to the package referred to by the\r
+ notification Handle The handle of the package\r
+ list which contains the specified package.\r
+\r
+ @param Handle The HII handle.\r
+\r
+ @param NotifyType The type of change concerning the\r
+ database. See\r
+ EFI_HII_DATABASE_NOTIFY_TYPE.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FormUpdateNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ mHiiPackageListUpdated = TRUE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor,\r
the framework HII module willl do no porting (except some porting works needed for callback for EFI_ONE_OF_OPTION opcode)\r
and still work with a UEFI HII SetupBrowser.\r
\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.\r
@param QuestionId A unique value which is sent to the original exporting driver so that it can identify the\r
- type of data to expect. The format of the data tends to vary based on the opcode that\r
- generated the callback.\r
- @param Type The type of value for the question. See EFI_IFR_TYPE_x in\r
- EFI_IFR_ONE_OF_OPTION.\r
- @param Value A pointer to the data being sent to the original exporting driver. The type is specified\r
- by Type. Type EFI_IFR_TYPE_VALUE is defined in\r
- EFI_IFR_ONE_OF_OPTION.\r
+ type of data to expect. The format of the data tends to vary based on the opcode that\r
+ generated the callback.\r
+ @param Type The type of value for the question. See EFI_IFR_TYPE_x in\r
+ EFI_IFR_ONE_OF_OPTION.\r
+ @param Value A pointer to the data being sent to the original exporting driver. The type is specified\r
+ by Type. Type EFI_IFR_TYPE_VALUE is defined in\r
+ EFI_IFR_ONE_OF_OPTION.\r
@param ActionRequest On return, points to the action requested by the callback function. Type\r
- EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form\r
- Browser Protocol.\r
+ EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form\r
+ Browser Protocol.\r
\r
- @retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under\r
- focuse to be INTERRACTIVE.\r
+ @retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under\r
+ focuse to be INTERRACTIVE.\r
@retval EFI_SUCCESS The callback complete successfully.\r
@retval !EFI_SUCCESS The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
- EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallbackProtocol;\r
+ CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
+ EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;\r
EFI_HII_CALLBACK_PACKET *Packet;\r
- FRAMEWORK_EFI_IFR_DATA_ARRAY Data;\r
+ FRAMEWORK_EFI_IFR_DATA_ARRAY *Data;\r
FRAMEWORK_EFI_IFR_DATA_ENTRY *DataEntry;\r
- EFI_FORM_CALLBACK Callback; \r
+ UINT16 KeyValue;\r
+ ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
+ EFI_HANDLE NotifyHandle;\r
+ EFI_INPUT_KEY Key; \r
+ BOOLEAN NvMapAllocated;\r
\r
ASSERT (This != NULL);\r
ASSERT (Value != NULL);\r
\r
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
\r
- ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
+ ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
\r
- FrameworkFormCallbackProtocol = ConfigaAccessInstance->FrameworkFormCallbackProtocol;\r
- if (FrameworkFormCallbackProtocol == NULL) {\r
+ FormCallbackProtocol = ConfigAccess->FormCallbackProtocol;\r
+ if (FormCallbackProtocol == NULL) {\r
+ ASSERT (FALSE);\r
return EFI_UNSUPPORTED;\r
}\r
- Callback = FrameworkFormCallbackProtocol->Callback;\r
\r
- Status = Callback (\r
- FrameworkFormCallbackProtocol,\r
- QuestionId,\r
- &Data,\r
+ //\r
+ // Check if the QuestionId match a OneOfOption.\r
+ //\r
+ OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value);\r
+\r
+ if (OneOfOptionMapEntry == NULL) {\r
+ //\r
+ // This is not a One-Of-Option opcode. QuestionId is the KeyValue\r
+ //\r
+ KeyValue = QuestionId;\r
+ } else {\r
+ KeyValue = OneOfOptionMapEntry->FwKey;\r
+ }\r
+\r
+ //\r
+ // Build the FRAMEWORK_EFI_IFR_DATA_ARRAY\r
+ //\r
+ Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated);\r
+\r
+ Status = mHiiDatabase->RegisterPackageNotify (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_FORM,\r
+ NULL,\r
+ FormUpdateNotify,\r
+ EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
+ &NotifyHandle\r
+ );\r
+ //\r
+ //\r
+ //\r
+ Packet = NULL;\r
+ Status = FormCallbackProtocol->Callback (\r
+ FormCallbackProtocol,\r
+ KeyValue,\r
+ Data,\r
&Packet\r
);\r
\r
//\r
// Callback require browser to perform action\r
//\r
- if (Packet != NULL) {\r
- if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) {\r
- DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));\r
- switch (DataEntry->Flags) {\r
- case EXIT_REQUIRED:\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- break;\r
- case SAVE_REQUIRED:\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
- break;\r
- case RESET_REQUIRED:\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
- break;\r
- default:\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- break; \r
- }\r
+ if (EFI_ERROR (Status)) {\r
+ if (Packet != NULL) {\r
+ //\r
+ // BUGBUG: need to restore the changing question to default value\r
+ //\r
+\r
+ do {\r
+ IfrLibCreatePopUp (1, &Key, Packet->String);\r
+\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ \r
}\r
+\r
+ //\r
+ // Error Code in Status is discarded.\r
+ //\r
+ } else {\r
+ if (Packet != NULL) {\r
+ if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) {\r
+ DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));\r
+ if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) {\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+ }\r
+\r
+ if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) {\r
+ Status = ConfigAccess->ConfigAccessProtocol.RouteConfig (\r
+ &ConfigAccess->ConfigAccessProtocol,\r
+ NULL,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ FreePool (Packet);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Unregister notify for Form package update\r
+ //\r
+ Status = mHiiDatabase->UnregisterPackageNotify (\r
+ mHiiDatabase,\r
+ NotifyHandle\r
+ );\r
+ //\r
+ // UEFI SetupBrowser handles scenario differently with Framework SetupBrowser when call back function \r
+ // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load\r
+ // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages.\r
+ // To make sure customer's previous changes is saved and the changing question behaves as expected, we\r
+ // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse\r
+ // the form and load all the variable storages.\r
+ //\r
+ if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) {\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
}\r
+\r
+ DestroyIfrDataArray (Data, NvMapAllocated);\r
\r
return Status;\r
}\r