-\r
/**@file\r
- This file contains functions related to Config Access Protocols installed by\r
- by HII Thunk Modules which is used to thunk UEFI Config Access Callback to \r
- Framework HII Callback.\r
+ This file implements functions related to Config Access Protocols installed by\r
+ by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config \r
+ Access Callback to Framework HII Callback and EFI Variable Set/Get operations.\r
\r
Copyright (c) 2008, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
**/\r
\r
#include "HiiDatabase.h"\r
+#include "UefiIfrParser.h"\r
\r
-BOOLEAN mHiiPackageListUpdated;\r
+BOOLEAN mHiiPackageListUpdated = FALSE;\r
\r
CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {\r
CONFIG_ACCESS_PRIVATE_SIGNATURE,\r
ThunkCallback\r
}, //ConfigAccessProtocol\r
NULL, //FormCallbackProtocol\r
- {NULL, NULL}, //ConfigAccessStorageListHead\r
NULL \r
};\r
\r
/**\r
- Find and return the pointer to Package Header of the Form package\r
- in the Framework Package List. The Framework Package List is created\r
- by a module calling the Framework HII interface.\r
- The Framwork Package List contains package data \r
- generated by Intel's UEFI VFR Compiler and String gather tool. The data format\r
- of the package data is defined by TIANO_AUTOGEN_PACKAGES_HEADER.\r
-\r
- If the package list contains other type of packages such as KEYBOARD_LAYOUT,\r
- FONTS and IMAGES, the ASSERT. This is to make sure the caller is a \r
- Framework Module which does not include packages introduced by UEFI Specification\r
- or packages that is not supported by Thunk layer.\r
+ Get the first EFI_IFR_VARSTORE from the FormSet. \r
+ \r
+ @param FormSet The Form Set.\r
+ \r
+ @retval FORMSET_STORAGE * Return the first EFI_IFR_VARSTORE.\r
+ @retval NULL If the Form Set does not have EFI_IFR_VARSTORE.\r
+**/\r
+FORMSET_STORAGE *\r
+GetFirstStorageOfFormSet (\r
+ IN CONST FORM_BROWSER_FORMSET * FormSet\r
+ ) \r
+{\r
+ LIST_ENTRY *StorageList;\r
+ FORMSET_STORAGE *Storage;\r
+\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
+\r
+ if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
+ return Storage;\r
+ }\r
+ \r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Get the EFI_IFR_VARSTORE where the Question's value is stored.\r
\r
- @param Packages The Framework Package List\r
+ @param FormSet The Form Set.\r
\r
- @retval EFI_HII_PACKAGE_HEADER* Return the Package Header of Form Package.\r
- @retval NULL If no Form Package is found.\r
+ @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.\r
+ @retval NULL If the Form Set does not have EFI_IFR_VARSTORE.\r
**/\r
-EFI_HII_PACKAGE_HEADER *\r
-GetIfrFormSet (\r
- IN CONST EFI_HII_PACKAGES *Packages\r
+FORMSET_STORAGE *\r
+GetStorageFromQuestionId (\r
+ IN CONST FORM_BROWSER_FORMSET * FormSet,\r
+ IN EFI_QUESTION_ID QuestionId\r
)\r
{\r
- TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
- EFI_HII_PACKAGE_HEADER *IfrPackage;\r
- UINTN Index;\r
+ LIST_ENTRY *FormList;\r
+ LIST_ENTRY *StatementList;\r
+ FORM_BROWSER_FORM *Form;\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+\r
+ FormList = GetFirstNode (&FormSet->FormListHead);\r
+\r
+ while (!IsNull (&FormSet->FormListHead, FormList)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
+\r
+ StatementList = GetFirstNode (&Form->StatementListHead);\r
+\r
+ while (!IsNull (&Form->StatementListHead, StatementList)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
+ if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) {\r
+ //\r
+ // UEFI Question ID is unique in a FormSet.\r
+ //\r
+ ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
+ return Statement->Storage;\r
+ }\r
+ StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
+ }\r
\r
- ASSERT (Packages != NULL);\r
+ FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
+ }\r
+ \r
+ return NULL;\r
+}\r
\r
- IfrPackage = NULL;\r
+/**\r
+ Get the EFI_IFR_VARSTORE based the ID.\r
+ \r
+ @param FormSet The Form Set.\r
+ \r
+ @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE with the ID.\r
+ @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.\r
+**/\r
+FORMSET_STORAGE *\r
+GetStorageFromVarStoreId (\r
+ IN CONST FORM_BROWSER_FORMSET * FormSet,\r
+ IN EFI_VARSTORE_ID VarStoreId\r
+ )\r
+{\r
+ LIST_ENTRY *StorageList;\r
+ FORMSET_STORAGE *Storage;\r
\r
- TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
- for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
- //\r
- // BugBug: The current UEFI HII build tool generate a binary in the format defined in: \r
- // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
- // this binary is with same package type. So the returned IfrPackNum and StringPackNum\r
- // may not be the exact number of valid package number in the binary generated \r
- // by HII Build tool.\r
- //\r
- switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
- case EFI_HII_PACKAGE_FORMS:\r
- return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
- break;\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
\r
- case EFI_HII_PACKAGE_STRINGS:\r
- case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
- break;\r
+ while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
\r
- //\r
- // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
- //\r
- case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
- case EFI_HII_PACKAGE_FONTS:\r
- case EFI_HII_PACKAGE_IMAGES:\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
+ if (VarStoreId == Storage->VarStoreId) {\r
+ return Storage;\r
}\r
- }\r
\r
- return (EFI_HII_PACKAGE_HEADER *) NULL;\r
+ StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
+ }\r
+ \r
+ return NULL;\r
}\r
\r
/**\r
- This function scan EFI_IFR_VARSTORE_OP in the Form Package.\r
- It create entries for these VARSTORE found and append the entry\r
- to a Link List.\r
-\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 BufferStorageListHead The link list for the VARSTORE found in the form package.\r
+ Get the EFI_IFR_VARSTORE based the <ConfigHdr> string in a <ConfigRequest>\r
+ or a <ConfigResp> string.\r
+ \r
+ @param FormSet The Form Set.\r
+ @param ConfigString The Configuration String which is defined by UEFI HII.\r
\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
+ @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.\r
+ @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.\r
**/\r
-EFI_STATUS\r
-GetBufferStorage (\r
- IN CONST EFI_HII_PACKAGE_HEADER *FormSetPackage,\r
- OUT LIST_ENTRY *BufferStorageListHead\r
+FORMSET_STORAGE *\r
+GetStorageFromConfigString (\r
+ IN CONST FORM_BROWSER_FORMSET *FormSet,\r
+ IN CONST EFI_STRING ConfigString\r
)\r
{\r
- UINTN OpCodeOffset;\r
- UINTN OpCodeLength;\r
- UINT8 *OpCodeData;\r
- UINT8 Operand;\r
- EFI_IFR_VARSTORE *VarStoreOpCode;\r
- BUFFER_STORAGE_ENTRY *BufferStorage;\r
-\r
- ASSERT (FormSetPackage->Type == EFI_HII_PACKAGE_FORMS);\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
- OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
- OpCodeOffset += OpCodeLength;\r
- Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
-\r
- if (Operand == EFI_IFR_VARSTORE_OP) {\r
- VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData;\r
- BufferStorage = AllocateZeroPool (sizeof (*BufferStorage));\r
- if (BufferStorage == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Record the attributes: GUID, Name, VarStoreId and Size.\r
- //\r
- CopyMem (&BufferStorage->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));\r
- \r
- BufferStorage->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);\r
- AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorage->Name);\r
+ LIST_ENTRY *StorageList;\r
+ FORMSET_STORAGE *Storage;\r
\r
- BufferStorage->VarStoreId = VarStoreOpCode->VarStoreId;\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
\r
- BufferStorage->Size = VarStoreOpCode->Size;\r
- BufferStorage->Signature = BUFFER_STORAGE_ENTRY_SIGNATURE;\r
+ while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
\r
- InsertTailList (BufferStorageListHead, &BufferStorage->Link);\r
+ if (IsConfigHdrMatch (ConfigString, &Storage->Guid, Storage->Name)) {\r
+ return Storage;\r
}\r
+\r
+ StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
}\r
\r
- return EFI_SUCCESS;\r
+ return NULL;\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
\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
+ 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 ThunkContext The Thunk Layer Handle Mapping Database Entry.\r
+ @param Packages The Package List.\r
+ @param ThunkContext The Thunk Context.\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
IN OUT HII_THUNK_CONTEXT *ThunkContext\r
)\r
{\r
- EFI_HII_PACKAGE_HEADER *FormSetPackage;\r
EFI_STATUS Status;\r
CONFIG_ACCESS_PRIVATE *ConfigAccessInstance;\r
\r
+ ASSERT (ThunkContext->IfrPackageCount != 0);\r
+\r
Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
ConfigAccessInstance = AllocateCopyPool (\r
sizeof (CONFIG_ACCESS_PRIVATE), \r
&gConfigAccessPrivateTempate\r
);\r
ASSERT (ConfigAccessInstance != NULL);\r
\r
- InitializeListHead (&ConfigAccessInstance->BufferStorageListHead);\r
-\r
- //\r
- // We assume there is only one formset package in each Forms Package\r
- //\r
- FormSetPackage = GetIfrFormSet (Packages);\r
- ASSERT (FormSetPackage != NULL);\r
- \r
- Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->BufferStorageListHead);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (ConfigAccessInstance);\r
- ASSERT (FALSE);\r
- return Status;\r
- }\r
-\r
Status = gBS->InstallMultipleProtocolInterfaces (\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
-VOID\r
-DestroyBufferStorageList (\r
- IN LIST_ENTRY *ListHead\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- BUFFER_STORAGE_ENTRY *Entry;\r
-\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
+ This function un-installs the EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered\r
+ by a module using Framework HII Protocol Interfaces.\r
\r
- FreePool (Entry);\r
- }\r
-}\r
+ ASSERT if no Config Access is found for such pakcage list or failed to uninstall the protocol.\r
\r
+ @param ThunkContext The Thunk Context.\r
+ \r
+**/\r
VOID\r
UninstallDefaultConfigAccessProtocol (\r
IN HII_THUNK_CONTEXT *ThunkContext\r
&gEfiHiiConfigAccessProtocolGuid,\r
(VOID **) &ConfigAccess\r
);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->UninstallProtocolInterface (\r
\r
ConfigAccessInstance = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccess);\r
\r
- DestroyBufferStorageList (&ConfigAccessInstance->BufferStorageListHead);\r
-\r
}\r
\r
\r
**/\r
EFI_STATUS\r
CallFormCallBack (\r
- IN BUFFER_STORAGE_ENTRY *BufferStorage,\r
+ IN FORMSET_STORAGE *BufferStorage,\r
IN EFI_FORM_CALLBACK_PROTOCOL *FwFormCallBack,\r
OUT VOID **Data,\r
OUT UINTN *DataSize\r
\r
EFI_STATUS\r
GetUefiVariable (\r
- IN BUFFER_STORAGE_ENTRY *BufferStorage,\r
+ IN FORMSET_STORAGE *BufferStorage,\r
OUT VOID **Data,\r
OUT UINTN *DataSize\r
)\r
return Status;\r
}\r
\r
-BUFFER_STORAGE_ENTRY *\r
-GetBufferStorageEntry (\r
- IN CONFIG_ACCESS_PRIVATE *ConfigAccess,\r
- IN UINT16 VarStoreId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- BUFFER_STORAGE_ENTRY *BufferStorage;\r
-\r
- Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
-\r
- while (!IsNull (&ConfigAccess->BufferStorageListHead, Link)) {\r
- BufferStorage = BUFFER_STORAGE_ENTRY_FROM_LINK (Link);\r
-\r
- if (BufferStorage->VarStoreId == VarStoreId) {\r
- return BufferStorage;\r
- }\r
-\r
- Link = GetNextNode (&ConfigAccess->BufferStorageListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
/**\r
\r
This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig\r
{\r
EFI_STATUS Status;\r
CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
- BUFFER_STORAGE_ENTRY *BufferStorage;\r
+ FORMSET_STORAGE *BufferStorage;\r
VOID *Data;\r
UINTN DataSize;\r
\r
Data = NULL;\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
- BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID);\r
+ BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request);\r
\r
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
+ //\r
+ // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback.\r
+ //\r
if (ConfigAccess->FormCallbackProtocol == NULL ||\r
ConfigAccess->FormCallbackProtocol->NvRead == NULL) {\r
Status = GetUefiVariable (\r
);\r
}\r
} else {\r
+ //\r
+ // Use the NvMapOverride.\r
+ //\r
DataSize = BufferStorage->Size;\r
Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride);\r
\r
}\r
\r
/**\r
-\r
This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig\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
EFI_STATUS Status;\r
CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
- BUFFER_STORAGE_ENTRY *BufferStorage;\r
+ FORMSET_STORAGE *BufferStorage;\r
UINT8 *Data;\r
UINTN DataSize;\r
UINTN DataSize2;\r
Data = NULL;\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
- BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID);\r
+ BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Configuration);\r
\r
DataSize2 = BufferStorage->Size;\r
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
return Status;\r
}\r
\r
+/**\r
+ Build the FRAMEWORK_EFI_IFR_DATA_ARRAY which will be used to pass to \r
+ EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of FRAMEWORK_EFI_IFR_DATA_ARRAY\r
+ for details.\r
+\r
+ ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.\r
+ \r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
+ @param QuestionId The Question ID.\r
+ @param Type The Question Type.\r
+ @param Value The Question Value.\r
+ @param NvMapAllocated On output indicates if a buffer is allocated for NvMap.\r
+ \r
+ @return A pointer to FRAMEWORK_EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.\r
+**/ \r
FRAMEWORK_EFI_IFR_DATA_ARRAY *\r
CreateIfrDataArray (\r
IN CONFIG_ACCESS_PRIVATE *ConfigAccess,\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
+ FORMSET_STORAGE *BufferStorage;\r
EFI_STATUS Status;\r
UINTN Size;\r
UINTN StringSize;\r
EFI_STRING String;\r
\r
- String = NULL;\r
+ *NvMapAllocated = FALSE;\r
\r
- Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
- if (IsNull (&ConfigAccess->BufferStorageListHead, Link)) {\r
- return NULL;\r
- }\r
+ String = NULL;\r
\r
switch (Type) {\r
case EFI_IFR_TYPE_NUM_SIZE_8:\r
IfrDataArray = AllocateZeroPool (sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY) + sizeof (FRAMEWORK_EFI_IFR_DATA_ENTRY) + Size);\r
ASSERT (IfrDataArray != NULL);\r
\r
- BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);\r
- BrowserDataSize = BufferStorageEntry->Size;\r
+ BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
\r
- if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
- *NvMapAllocated = TRUE;\r
- IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);\r
- } else {\r
- *NvMapAllocated = FALSE;\r
- IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;\r
+ if (BufferStorage == NULL) {\r
+ //\r
+ // The QuestionId is not associated with a Buffer Storage.\r
+ // Try to get the first Buffer Storage then.\r
+ //\r
+ BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
}\r
\r
- Status = GetBrowserData (NULL, NULL, &BrowserDataSize, IfrDataArray->NvRamMap);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (BufferStorage != NULL) {\r
+ BrowserDataSize = BufferStorage->Size;\r
\r
- IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
+ if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
+ *NvMapAllocated = TRUE;\r
+ IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);\r
+ } else {\r
+ *NvMapAllocated = FALSE;\r
+ IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;\r
+ }\r
+ \r
+ Status = GetBrowserData (&BufferStorage->Guid, BufferStorage->Name, &BrowserDataSize, IfrDataArray->NvRamMap);\r
+ ASSERT_EFI_ERROR (Status);\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
+ IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
\r
- case EFI_IFR_TYPE_STRING:\r
- ASSERT (String != NULL);\r
- StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);\r
- FreePool (String);\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\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
+ case EFI_IFR_TYPE_STRING:\r
+ ASSERT (String != NULL);\r
+ StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);\r
+ FreePool (String);\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Need to fiil in the information for the rest of field for FRAMEWORK_EFI_IFR_DATA_ENTRY.\r
+ // It seems that no implementation is found to use other fields. Leave them uninitialized for now.\r
+ //\r
+ //UINT8 OpCode; // Likely a string, numeric, or one-of\r
+ //UINT8 Length; // Length of the FRAMEWORK_EFI_IFR_DATA_ENTRY packet\r
+ //UINT16 Flags; // Flags settings to determine what behavior is desired from the browser after the callback\r
+ //VOID *Data; // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately\r
+ // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value\r
+ // If the OpCode is a String type - Data is a CHAR16[x] type\r
+ // If the OpCode is a Checkbox type - Data is a UINT8 value\r
+ // If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure\r
}\r
\r
return IfrDataArray;\r
}\r
\r
+/**\r
+ If a NvMapOverride is passed in to EFI_FORM_BROWSER_PROTOCOL.SendForm, the Form Browser\r
+ needs to be informed when data changed in NvMapOverride. This function will invoke\r
+ SetBrowserData () to set internal data of Form Browser.\r
+\r
+ @param ConfigAccess The Config Access Private Context.\r
+ @param QuestionId The Question Id that invokes the callback.\r
+ \r
+\r
+**/\r
VOID\r
SyncBrowserDataForNvMapOverride (\r
- IN CONFIG_ACCESS_PRIVATE *ConfigAccess\r
+ IN CONST CONFIG_ACCESS_PRIVATE *ConfigAccess,\r
+ IN EFI_QUESTION_ID QuestionId\r
)\r
{\r
- BUFFER_STORAGE_ENTRY *BufferStorageEntry;\r
- LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *BufferStorage;\r
EFI_STATUS Status;\r
UINTN BrowserDataSize;\r
\r
if (ConfigAccess->ThunkContext->NvMapOverride != NULL) {\r
+\r
+ BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
+\r
+ if (BufferStorage == NULL) {\r
+ //\r
+ // QuestionId is a statement without Storage.\r
+ // 1) It is a Goto. \r
+ // \r
+ //\r
+ BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
+ }\r
+\r
+ //\r
+ // If NvMapOverride is not NULL, this Form must have at least one Buffer Type Variable Storage.\r
+ //\r
+ ASSERT (BufferStorage != NULL);\r
\r
- Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);\r
- ASSERT (!IsNull (&ConfigAccess->BufferStorageListHead, Link));\r
- \r
- BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);\r
- BrowserDataSize = BufferStorageEntry->Size;\r
+ BrowserDataSize = BufferStorage->Size;\r
\r
- Status = SetBrowserData (NULL, NULL, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);\r
+ Status = SetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);\r
ASSERT_EFI_ERROR (Status);\r
}\r
\r
}\r
\r
+/**\r
+ Free up resource allocated for a FRAMEWORK_EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().\r
+\r
+ @param Array The FRAMEWORK_EFI_IFR_DATA_ARRAY allocated.\r
+ @param NvMapAllocated If the NvRamMap is allocated for FRAMEWORK_EFI_IFR_DATA_ARRAY.\r
+\r
+**/\r
VOID\r
DestroyIfrDataArray (\r
IN FRAMEWORK_EFI_IFR_DATA_ARRAY *Array,\r
}\r
}\r
\r
-\r
+/**\r
+ Get the ONE_OF_OPTION_MAP_ENTRY for a QuestionId that invokes the \r
+ EFI_FORM_CALLBACK_PROTOCOL.Callback. The information is needed as\r
+ the callback mechanism for EFI_IFR_ONE_OF_OPTION is changed from \r
+ EFI_IFR_ONE_OF_OPTION in Framework IFR. Check EFI_IFR_GUID_OPTIONKEY\r
+ for detailed information.\r
+\r
+ @param ThunkContext The Thunk Context.\r
+ @param QuestionId The Question Id.\r
+ @param Type The Question Type.\r
+ @param Value The One Of Option's value.\r
+\r
+ @return The ONE_OF_OPTION_MAP_ENTRY found.\r
+ @retval NULL If no entry is found.\r
+**/\r
ONE_OF_OPTION_MAP_ENTRY *\r
GetOneOfOptionMapEntry (\r
IN HII_THUNK_CONTEXT *ThunkContext,\r
LIST_ENTRY *Link2;\r
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
ONE_OF_OPTION_MAP *OneOfOptionMap;\r
+ FORM_BROWSER_FORMSET *FormSet;\r
\r
- Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
+ FormSet = ThunkContext->FormSet;\r
\r
- while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {\r
+ Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);\r
+\r
+ while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {\r
OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link);\r
if (OneOfOptionMap->QuestionId == QuestionId) {\r
ASSERT (OneOfOptionMap->ValueType == Type);\r
}\r
}\r
\r
- Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
+ Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);\r
}\r
\r
\r
PackageGuid, Handle, and Package are used for each of the\r
notification types.\r
\r
+ If any Pakcage List in database is updated, mHiiPackageListUpdated\r
+ will be set. If mHiiPackageListUpdated is set, Framework ThunkCallback()\r
+ will force the UEFI Setup Browser to save the uncommitted data. This\r
+ is needed as Framework's Callback function may dynamically update\r
+ opcode in a Package List. UEFI Setup Browser will quit itself and reparse\r
+ the Package List's IFR and display it. UEFI Config Access's implementation\r
+ is required to save the modified (SetBrowserData or directly save the data\r
+ to NV storage). But Framework HII Modules is not aware of this rule. Therefore,\r
+ we will enforce the rule in ThunkCallback (). The side effect of force saving\r
+ of NV data is the NV flag in browser may not flag a update as data has already\r
+ been saved to NV storage.\r
+\r
@param PackageType Package type of the notification.\r
\r
@param PackageGuid If PackageType is\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
+ the framework HII module willl do no porting and 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
//\r
KeyValue = QuestionId;\r
} else {\r
+ //\r
+ // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax.\r
+ //\r
KeyValue = OneOfOptionMapEntry->FwKey;\r
}\r
\r
&NotifyHandle\r
);\r
//\r
- //\r
+ //Call the Framework Callback function.\r
//\r
Packet = NULL;\r
Status = FormCallbackProtocol->Callback (\r
Data,\r
&Packet\r
);\r
- SyncBrowserDataForNvMapOverride (ConfigAccess);\r
+ SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId);\r
\r
//\r
// Callback require browser to perform action\r
// the form and load all the variable storages.\r
//\r
if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) {\r
+ mHiiPackageListUpdated= FALSE;\r
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
} else {\r
- if (ConfigAccess->ThunkContext->FormSetSubClass == EFI_FRONT_PAGE_SUBCLASS ||\r
- ConfigAccess->ThunkContext->FormSetSubClass == EFI_SINGLE_USE_SUBCLASS) {\r
+ if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS ||\r
+ ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) {\r
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
}\r
}\r
\r
\r
+ //\r
+ // Clean up.\r
+ //\r
DestroyIfrDataArray (Data, NvMapAllocated);\r
\r
return Status;\r
\r
\r
/**\r
- This function is only called by Graphics Console module and GraphicsLib. \r
- EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib \r
- complying to UEFI HII.\r
+ Translates a Unicode character into the corresponding font glyph.\r
\r
- This function will ASSERT and return EFI_UNSUPPORTED.\r
-\r
- @param This N.A.\r
- @param Source N.A.\r
- @param Index N.A.\r
- @param GlyphBuffer N.A.\r
- @param BitWidth N.A.\r
- @param InternalStatus N.A.\r
-\r
- @return EFI_UNSUPPORTED N.A.\r
+ Notes:\r
+ This function is only called by Graphics Console module and GraphicsLib. \r
+ Wrap the Framework HII GetGlyph function to UEFI Font Protocol.\r
+ \r
+ EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib \r
+ complying to UEFI HII.\r
+ \r
+ @param This A pointer to the EFI_HII_PROTOCOL instance.\r
+ @param Source A pointer to a Unicode string.\r
+ @param Index On input, the offset into the string from which to fetch the character. On successful completion, the \r
+ index is updated to the first character past the character(s) making up the just extracted glyph. \r
+ @param GlyphBuffer Pointer to an array where the glyphs corresponding to the characters in the source may be stored. \r
+ GlyphBuffer is assumed to be wide enough to accept a wide glyph character.\r
+ @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by this value is filled with the length of the glyph in pixels. \r
+ It is unchanged if the call was unsuccessful.\r
+ @param InternalStatus To save the time required to read the string from the beginning on each glyph extraction \r
+ (for example, to ensure that the narrow versus wide glyph mode is correct), this value is \r
+ updated each time the function is called with the status that is local to the call. The cell pointed \r
+ to by this parameter must be initialized to zero prior to invoking the call the first time for any string.\r
+\r
+ @retval EFI_SUCCESS It worked.\r
+ @retval EFI_NOT_FOUND A glyph for a character was not found.\r
+ \r
\r
**/\r
EFI_STATUS\r
}\r
\r
/**\r
+ Translates a glyph into the format required for input to the Universal Graphics Adapter (UGA) Block Transfer (BLT) routines.\r
+ \r
+ Notes:\r
This function is only called by Graphics Console module and GraphicsLib. \r
EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib \r
complying to UEFI HII.\r
\r
- This function will ASSERT and return EFI_UNSUPPORTED.\r
-\r
- @param This N.A.\r
- @param GlyphBuffer N.A.\r
- @param Foreground N.A.\r
- @param Background N.A.\r
- @param Count N.A.\r
- @param Width N.A.\r
- @param Height N.A.\r
- @param BltBuffer N.A.\r
-\r
- @return EFI_UNSUPPORTED N.A.\r
+ @param This A pointer to the EFI_HII_PROTOCOL instance.\r
+ @param GlyphBuffer A pointer to the buffer that contains glyph data. \r
+ @param Foreground The foreground setting requested to be used for the generated BltBuffer data. Type EFI_UGA_PIXEL is defined in "Related Definitions" below.\r
+ @param Background The background setting requested to be used for the generated BltBuffer data. \r
+ @param Count The entry in the BltBuffer upon which to act.\r
+ @param Width The width in bits of the glyph being converted.\r
+ @param Height The height in bits of the glyph being converted\r
+ @param BltBuffer A pointer to the buffer that contains the data that is ready to be used by the UGA BLT routines. \r
+\r
+ @retval EFI_SUCCESS It worked.\r
+ @retval EFI_NOT_FOUND A glyph for a character was not found.\r
+ \r
\r
**/\r
EFI_STATUS\r
};\r
\r
\r
+EFI_GUID mTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+\r
/**\r
\r
This thunk module only handles UEFI HII packages. The caller of this function \r
CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));\r
CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID)); \r
\r
- OutputFormSet->FormSet.Class = ThunkContext->FormSetClass;\r
- OutputFormSet->FormSet.SubClass = ThunkContext->FormSetSubClass;\r
- OutputFormSet->FormSet.Help = ThunkContext->FormSetHelp;\r
- OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSetTitle;\r
+ if (ThunkContext->FormSet != NULL) {\r
+ OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class;\r
+ OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass;\r
+ OutputFormSet->FormSet.Help = ThunkContext->FormSet->Help;\r
+ OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle;\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
)\r
{\r
LIST_ENTRY *UefiDefaults;\r
- EFI_HII_HANDLE UefiHiiHandle;\r
EFI_STATUS Status;\r
HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
\r
- UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
- if (UefiHiiHandle == NULL) {\r
+ ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
+ if (ThunkContext == NULL) {\r
ASSERT (FALSE);\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
UefiDefaults = NULL;\r
- Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);\r
+ Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, VariablePackList);\r
+ Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);\r
\r
Done:\r
FreeDefaultList (UefiDefaults);\r
}\r
\r
/**\r
- EDES_TODO: Add function description.\r
+ This function update the FormCallbackProtocol cached in Config Access\r
+ private context data.\r
\r
- @param CallbackHandle EDES_TODO: Add parameter description\r
- @param ThunkContext EDES_TODO: Add parameter description\r
+ @param CallbackHandle The EFI Handle on which the Framework FormCallbackProtocol is \r
+ installed.\r
+ @param ThunkContext The Thunk Context.\r
\r
- @return EDES_TODO: Add description for return value\r
+ @retval EFI_SUCCESS The update is successful.\r
+ @retval EFI_INVALID_PARAMETER If no Framework FormCallbackProtocol is located on CallbackHandle.\r
\r
**/\r
EFI_STATUS\r
\r
\r
/**\r
- EDES_TODO: Add function description.\r
+ Get the package data from the Package List.\r
\r
- @param HiiPackageList EDES_TODO: Add parameter description\r
- @param PackageIndex EDES_TODO: Add parameter description\r
- @param BufferLen EDES_TODO: Add parameter description\r
- @param Buffer EDES_TODO: Add parameter description\r
+ @param HiiPackageList Package List.\r
+ @param PackageIndex The index of the Package in the Package List.\r
+ @param BufferLen The Length of the Pacage data.\r
+ @param Buffer On output, the Package data.\r
\r
- @return EDES_TODO: Add description for return value\r
+ @return EFI_NOT_FOUND No Package is found for PackageIndex.\r
+ @return EFI_SUCCESS The package data is returned.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
GetPackageData (\r
IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
}\r
\r
/**\r
- Check if Label exist in the IFR form package.\r
+ Check if Label exist in the IFR form package and return the FormSet GUID\r
+ and Form ID.\r
\r
- @param \r
+ @param Package The Package Header.\r
+ @param Label The Label ID.\r
+ @param FormsetGuid Returns the FormSet GUID.\r
+ @param FormId Returns the Form ID.\r
\r
+ @retval EFI_SUCCESS The FORM ID is found.\r
+ @retval EFI_NOT_FOUND The FORM ID is not found.\r
**/\r
EFI_STATUS\r
LocateLabel (\r
{\r
UINTN Offset;\r
EFI_IFR_OP_HEADER *IfrOpHdr;\r
- UINT8 ExtendOpCode;\r
- UINT16 LabelNumber;\r
EFI_GUID InternalFormSetGuid;\r
EFI_FORM_ID InternalFormId;\r
BOOLEAN GetFormSet;\r
BOOLEAN GetForm;\r
+ EFI_IFR_GUID_LABEL *LabelOpcode;\r
\r
IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
break;\r
\r
case EFI_IFR_GUID_OP :\r
- ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
- \r
- if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) {\r
- //\r
- // Go to the next Op-Code\r
- //\r
- Offset += IfrOpHdr->Length;\r
- IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
- continue;\r
- }\r
- \r
- CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));\r
- if (LabelNumber == Label) {\r
- ASSERT (GetForm && GetFormSet);\r
- CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
- *FormId = InternalFormId;\r
- return EFI_SUCCESS;\r
+ LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr;\r
+ //\r
+ // If it is an Label opcode.\r
+ //\r
+ if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) {\r
+ if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) {\r
+ ASSERT (GetForm && GetFormSet);\r
+ CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
+ *FormId = InternalFormId;\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
- \r
-\r
break;\r
default :\r
break;\r
\r
return Status;\r
}\r
+\r
/**\r
This function allows the caller to update a form that has\r
previously been registered with the EFI HII database.\r
if (Data->DataCount != 0) {\r
\r
ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
- Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, AddData, &UefiHiiUpdateData);\r
+ Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, &UefiHiiUpdateData);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);\r
+ Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, TRUE, UefiHiiUpdateData);\r
ASSERT_EFI_ERROR (Status);\r
\r
} \r
ConfigAccess.h\r
OpcodeCreation.c\r
OpcodeCreation.h\r
- UefiIfrParserInternal.h\r
- UefiIfrParserCommon.c\r
- UefiIfrParserCommon.h\r
UefiIfrParser.c\r
UefiIfrParser.h\r
UefiIfrParserExpression.c\r
- UefiIfrParserExpressionInternal.h\r
+ UefiIfrParserExpression.h\r
UefiIfrDefault.c\r
UefiIfrDefault.h\r
Keyboard.c\r
gEfiFormBrowser2ProtocolGuid\r
\r
\r
+\r
\r
#include <MdeModuleHii.h>\r
\r
+#include "UefiIfrParser.h"\r
+\r
\r
//\r
// VARSTORE ID of 0 for Buffer Storage Type Storage is reserved in UEFI IFR form. But VARSTORE ID\r
// Framework VFR has to be ported or pre-processed to change the default VARSTORE to a VARSTORE\r
// with ID equal to 0x0001.\r
//\r
-#define RESERVED_VARSTORE_ID 0x0001\r
+#define FRAMEWORK_RESERVED_VARSTORE_ID 0x0001\r
\r
\r
#pragma pack (push, 1)\r
\r
\r
\r
-#define ONE_OF_OPTION_MAP_ENTRY_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP_ENTRY, Link, ONE_OF_OPTION_MAP_ENTRY_SIGNATURE)\r
-#define ONE_OF_OPTION_MAP_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'M', 'E')\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
-\r
- UINT16 FwKey;\r
- EFI_IFR_TYPE_VALUE Value;\r
- \r
-} ONE_OF_OPTION_MAP_ENTRY;\r
-\r
-\r
-\r
-#define ONE_OF_OPTION_MAP_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP, Link, ONE_OF_OPTION_MAP_SIGNATURE)\r
-#define ONE_OF_OPTION_MAP_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'O', 'M')\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link; \r
-\r
- UINT8 ValueType; //EFI_IFR_TYPE_NUM_* \r
-\r
- EFI_QUESTION_ID QuestionId;\r
-\r
- LIST_ENTRY OneOfOptionMapEntryListHead; //ONE_OF_OPTION_MAP_ENTRY\r
-} ONE_OF_OPTION_MAP;\r
-\r
\r
\r
#define QUESTION_ID_MAP_ENTRY_FROM_LINK(Record) CR(Record, QUESTION_ID_MAP_ENTRY, Link, QUESTION_ID_MAP_ENTRY_SIGNATURE)\r
// TagGuid is the used to record this GuidId.\r
EFI_GUID TagGuid;\r
\r
- LIST_ENTRY QuestionIdMapListHead; //QUESTION_ID_MAP\r
-\r
- LIST_ENTRY OneOfOptionMapListHead; //ONE_OF_OPTION_MAP\r
-\r
UINT8 *NvMapOverride;\r
\r
- UINT16 FormSetClass;\r
- UINT16 FormSetSubClass;\r
- STRING_REF FormSetTitle;\r
- STRING_REF FormSetHelp;\r
- \r
+ FORM_BROWSER_FORMSET *FormSet;\r
+\r
} HII_THUNK_CONTEXT;\r
\r
\r
//\r
EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;\r
\r
- LIST_ENTRY BufferStorageListHead;\r
-\r
HII_THUNK_CONTEXT *ThunkContext;\r
} CONFIG_ACCESS_PRIVATE;\r
\r
\r
#include "HiiDatabase.h"\r
\r
+/**\r
+ Retrieves the current keyboard layout. \r
+ This function is not implemented by HII Thunk Module.\r
+\r
+ @param This A pointer to the EFI_HII_PROTOCOL instance. \r
+ @param DescriptorCount A pointer to the number of Descriptor entries being described in the keyboard layout being retrieved.\r
+ @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR entries. Each entry will reflect the definition of a specific physical key. Type EFI_KEY_DESCRIPTOR is defined in "Related Definitions" below.\r
+\r
+ @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
+ \r
+**/\r
EFI_STATUS\r
EFIAPI\r
HiiGetKeyboardLayout (\r
OUT UINT16 *DescriptorCount,\r
OUT FRAMEWORK_EFI_KEY_DESCRIPTOR *Descriptor\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
{\r
ASSERT (FALSE);\r
//\r
\r
EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;\r
\r
+\r
+EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = {\r
+ {EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0},\r
+ EFI_IFR_FRAMEWORK_GUID,\r
+ EFI_IFR_EXTEND_OP_OPTIONKEY,\r
+ 0,\r
+ 0,\r
+ 0\r
+};\r
+\r
+typedef struct { \r
+ UINT8 FrameworkIfrOp;\r
+ UINT8 UefiIfrOp;\r
+} IFR_OPCODE_MAP;\r
+\r
+IFR_OPCODE_MAP mQuestionOpcodeMap [] = {\r
+ { FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP},\r
+ { FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP},\r
+ { FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP},\r
+ { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
+ { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP}\r
+};\r
+\r
+EFI_STATUS\r
+QuestionOpFwToUefi (\r
+ IN UINT8 FwOp,\r
+ OUT UINT8 *UefiOp\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {\r
+ if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {\r
+ *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+FwQIdToUefiQId (\r
+ IN CONST FORM_BROWSER_FORMSET *FormSet,\r
+ IN UINT16 VarStoreId,\r
+ IN UINT8 FwOpCode,\r
+ IN UINT16 FwQId,\r
+ OUT UINT16 *UefiQId\r
+ )\r
+{\r
+ LIST_ENTRY *FormList;\r
+ LIST_ENTRY *StatementList;\r
+ FORM_BROWSER_FORM *Form;\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ EFI_STATUS Status;\r
+ UINT8 UefiOp;\r
+\r
+ *UefiQId = 0;\r
+\r
+ FormList = GetFirstNode (&FormSet->FormListHead);\r
+\r
+ while (!IsNull (&FormSet->FormListHead, FormList)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
+\r
+ StatementList = GetFirstNode (&Form->StatementListHead);\r
+\r
+ while (!IsNull (&Form->StatementListHead, StatementList)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
+ if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+ if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
+ Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (UefiOp == Statement->Operand) {\r
+ //\r
+ // If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the \r
+ // same field in NvMap. This is ambigurity, we don't handle it for now.\r
+ //\r
+ //\r
+ // UEFI Question ID is unique in a FormSet.\r
+ //\r
+ ASSERT (VarStoreId == Statement->VarStoreId);\r
+ *UefiQId = Statement->QuestionId;\r
+\r
+ return EFI_SUCCESS;\r
+ \r
+ }\r
+ }\r
+ }\r
+\r
+ StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
+ }\r
+\r
+ FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
+ }\r
+ \r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+\r
#define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000\r
EFI_STATUS\r
AppendToUpdateBuffer (\r
\r
EFI_QUESTION_ID\r
AssignQuestionId (\r
- IN UINT16 FwQuestionId\r
+ IN UINT16 FwQuestionId,\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
if (FwQuestionId == 0) {\r
- //\r
- // In UEFI IFR, the Question ID can't be zero. Zero means no storage.\r
- // So use 0xABBA as a Question ID.\r
- //\r
- return 0xABBA;\r
+ FormSet->MaxQuestionId++;\r
+ return FormSet->MaxQuestionId;\r
} else {\r
return FwQuestionId;\r
}\r
}\r
\r
-\r
-EFI_STATUS\r
-FwQuestionIdToUefiQuestionId (\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN UINT16 VarStoreId,\r
- IN UINT16 FwId,\r
- OUT EFI_QUESTION_ID *UefiQId\r
- )\r
-{\r
- LIST_ENTRY *MapEntryListHead;\r
- LIST_ENTRY *Link;\r
- QUESTION_ID_MAP_ENTRY *MapEntry;\r
-\r
- MapEntryListHead = GetMapEntryListHead (ThunkContext, VarStoreId);\r
- ASSERT (MapEntryListHead != NULL);\r
-\r
- Link = GetFirstNode (MapEntryListHead);\r
-\r
- while (!IsNull (MapEntryListHead, Link)) {\r
- MapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
-\r
- if (MapEntry->FwQId == FwId) {\r
- *UefiQId = MapEntry->UefiQid;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Link = GetNextNode (MapEntryListHead, Link);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-\r
EFI_STATUS\r
UCreateEndOfOpcode (\r
OUT EFI_HII_UPDATE_DATA *UefiData\r
return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
}\r
\r
+EFI_STATUS\r
+CreateGuidOptionKeyOpCode (\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT16 OptionValue,\r
+ IN EFI_QUESTION_ID KeyValue,\r
+ OUT EFI_HII_UPDATE_DATA *UefiData\r
+ )\r
+{\r
+ EFI_IFR_GUID_OPTIONKEY UOpcode;\r
+\r
+ CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY));\r
+\r
+ UOpcode.QuestionId = QuestionId;\r
+ CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue)); \r
+ UOpcode.KeyValue = KeyValue;\r
+ \r
+ return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+}\r
\r
/*\r
typedef struct _EFI_IFR_QUESTION_HEADER {\r
EFI_IFR_ONE_OF UOpcode;\r
FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
- ONE_OF_OPTION_MAP *OneOfOptionMap;\r
- ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
\r
ASSERT (NextFwOpcode != NULL);\r
ASSERT (DataCount != NULL);\r
\r
- OneOfOptionMap = NULL;\r
-\r
ZeroMem (&UOpcode, sizeof(UOpcode));\r
*DataCount = 0;\r
\r
UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
\r
if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
}\r
-\r
- OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
- ASSERT (OneOfOptionMap != NULL);\r
- OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
- OneOfOptionMap->QuestionId = UOpcode.Question.QuestionId;\r
- InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
- switch (FwOpcode->Width) {\r
- case 1:\r
- OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
- case 2:\r
- OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
-\r
- InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
}\r
- \r
- OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
- ASSERT (OneOfOptionMapEntry != NULL);\r
\r
- OneOfOptionMapEntry->FwKey = FwOneOfOp->Key;\r
- OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
- \r
- CopyMem (&OneOfOptionMapEntry->Value, &FwOneOfOp->Value, FwOpcode->Width);\r
-\r
- ASSERT (OneOfOptionMap != NULL);\r
- InsertTailList (&OneOfOptionMap->OneOfOptionMapEntryListHead, &OneOfOptionMapEntry->Link);\r
}\r
\r
if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
//\r
// Assign QuestionId if still not assigned.\r
//\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
}\r
}\r
\r
//\r
FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
+\r
+ FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
+ \r
Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
+ Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
*DataCount += 1;\r
}\r
UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
\r
if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
}\r
\r
}\r
}\r
\r
if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
}\r
}\r
\r
UOpcode.Question.Header.Help = FwOpcode->Help;\r
\r
if (FwOpcode->Key == 0) {\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
//\r
// Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
//\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
}\r
} else {\r
UOpcode.Question.QuestionId = FwOpcode->Key;\r
}\r
\r
- UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;\r
+ UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
\r
//\r
ZeroMem (&UOpcode, sizeof(UOpcode));\r
\r
if (FwOpcode->Key == 0) {\r
- Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
if (EFI_ERROR (Status)) {\r
//\r
// Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
//\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
+ UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
}\r
} else {\r
UOpcode.Question.QuestionId = FwOpcode->Key;\r
ZeroMem (&UOpcode, sizeof(UOpcode));\r
\r
if (FwOpcode->Key == 0) {\r
- FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+ FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
} else {\r
UOpcode.Question.QuestionId = FwOpcode->Key;\r
}\r
UOpcode.Question.Header.Help = FwOpcode->Help;\r
\r
UOpcode.Question.QuestionId = FwOpcode->Key;\r
- UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;\r
+ UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
\r
UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
FwUpdateDataToUefiUpdateData (\r
IN HII_THUNK_CONTEXT *ThunkContext,\r
IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,\r
- IN BOOLEAN AddData,\r
OUT EFI_HII_UPDATE_DATA **UefiData\r
)\r
{\r
FwUpdateDataToUefiUpdateData (\r
IN HII_THUNK_CONTEXT *ThunkContext,\r
IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,\r
- IN BOOLEAN AddData,\r
OUT EFI_HII_UPDATE_DATA **UefiData\r
);\r
#endif\r
//\r
// If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
// packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
- // not used as the name of the package list. A GUID is generated as a Package List\r
+ // not used as the name of the package list. Formset GUID is used as the Package List\r
// GUID.\r
//\r
ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);\r
\r
//\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
+ // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only\r
+ // produce IFR package generated with Buffer Storage type and EFI Variable Storage.\r
+ // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.\r
//\r
if (IfrPackageCount != 0) {\r
InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
if (IfrPackageCount == 0) {\r
if (StringPackageCount != 0) {\r
//\r
- // Look for a Package List with only IFR Package with the same GUID name.\r
- // If found one, add the String Packages to it.\r
+ // Look for a Package List with only IFR Package with the same TAG GUID name.\r
+ // If found one, add the String Packages to the found Package List.\r
+ // This is needed because Framework HII Module may not register the String Package\r
+ // and IFR Package in one NewPack () call.\r
//\r
UpdatePackListWithOnlyIfrPack (\r
Private,\r
);\r
}\r
} else {\r
- CreateQuestionIdMap (ThunkContext);\r
- \r
if (StringPackageCount == 0) {\r
//\r
- // Register the Package List to UEFI HII first.\r
+ // Look for the String Package with the same TAG GUID name and add\r
+ // the found String Package to this Package List.\r
+ // This is needed because Framework HII Module may not register the String Package\r
+ // and IFR Package in one NewPack () call.\r
//\r
Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
Private,\r
goto Done;\r
}\r
}\r
+ \r
+ //\r
+ // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so\r
+ // that String Package is ready.\r
+ //\r
+ ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
+ ASSERT (ThunkContext->FormSet != NULL);\r
+ \r
}\r
\r
Done:\r
}\r
\r
\r
+/**\r
+\r
+ Registers the various packages that are passed in a Package List.\r
+\r
+ @param This Pointer of Frameowk HII protocol instance.\r
+ @param Packages Pointer of HII packages.\r
+ @param Handle Handle value to be returned.\r
+\r
+ @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
+ @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
HiiNewPack (\r
IN EFI_HII_PACKAGES *Packages,\r
OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Extracts the various packs from a package list.\r
-\r
-Arguments:\r
-\r
- This - Pointer of HII protocol.\r
- Packages - Pointer of HII packages.\r
- Handle - Handle value to be returned.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Pacakges has added to HII database successfully.\r
- EFI_INVALID_PARAMETER - Invalid parameter.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
HII_THUNK_PRIVATE_DATA *Private;\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
\r
//\r
- // We use a simple Global variable to inform NewPackNotify\r
+ // We use a simple Global variable to inform NewOrAddPackNotify()\r
// that the package list registered here is already registered\r
- // in the HII Thunk Layer. So NewPackNotify does not need to\r
- // call RegisterUefiHiiHandle () to registered it.\r
+ // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to\r
+ // call registered the Package List again.\r
//\r
mInFrameworkHiiNewPack = TRUE;\r
\r
return Status;\r
}\r
\r
+/**\r
+\r
+ Remove a package from the HII database.\r
+\r
+ @param This Pointer of Frameowk HII protocol instance.\r
+ @param Handle Handle value to be removed.\r
+\r
+ @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
+ @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
HiiRemovePack (\r
IN EFI_HII_PROTOCOL *This,\r
IN FRAMEWORK_EFI_HII_HANDLE Handle\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Removes the various packs from a Handle\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
- HII_THUNK_PRIVATE_DATA *Private;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
EFI_TPL OldTpl;\r
\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
return Status;\r
}\r
\r
+/**\r
+ This notification function will be called when a Package List is registered\r
+ using UEFI HII interface. The Package List registered need to be recorded in\r
+ Framework Thunk module as Thunk Module may need to look for String Package in\r
+ the package registered.\r
+\r
+ If the Package List registered is not either Sting Package or IFR package, \r
+ then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.\r
+ Both cases means UEFI HII Database itself is buggy. \r
+\r
+ @param PackageType The Package Type.\r
+ @param PackageGuid The Package GUID.\r
+ @param Package The Package Header.\r
+ @param Handle The HII Handle of this Package List.\r
+ @param NotifyType The reason of the notification. \r
+\r
+ @retval EFI_SUCCESS The notification function is successful.\r
+ \r
+**/\r
EFI_STATUS\r
EFIAPI\r
NewOrAddPackNotify (\r
}\r
\r
//\r
- // We only create a ThunkContext if the Uefi Hii Handle is only already registered\r
- // by the HII Thunk Layer.\r
+ // We will create a ThunkContext to log the package list only if the\r
+ // package is not registered with by Framework HII Thunk module yet.\r
//\r
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
if (ThunkContext == NULL) {\r
} \r
\r
if (PackageType == EFI_HII_PACKAGE_FORMS) {\r
- GetAttributesOfFirstFormSet (ThunkContext);\r
+ if (ThunkContext->FormSet != NULL) {\r
+ DestroyFormSet (ThunkContext->FormSet);\r
+ }\r
+\r
+ //\r
+ // Reparse the FormSet.\r
+ //\r
+ ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
+ ASSERT (ThunkContext->FormSet != NULL);\r
}\r
\r
return Status; \r
}\r
\r
-//\r
-// Framework HII module may cache a GUID as the name of the package list.\r
-// Then search for the Framework HII handle database for the handle matching\r
-// this GUID\r
+/**\r
+ This notification function will be called when a Package List is removed\r
+ using UEFI HII interface. The Package List removed need to be removed from\r
+ Framework Thunk module too.\r
+\r
+ If the Package List registered is not Sting Package, \r
+ then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.\r
+ Both cases means UEFI HII Database itself is buggy. \r
+\r
+ @param PackageType The Package Type.\r
+ @param PackageGuid The Package GUID.\r
+ @param Package The Package Header.\r
+ @param Handle The HII Handle of this Package List.\r
+ @param NotifyType The reason of the notification. \r
\r
+ @retval EFI_SUCCESS The notification function is successful.\r
+ \r
+**/\r
EFI_STATUS\r
EFIAPI\r
RemovePackNotify (\r
\r
#include "HiiDatabase.h"\r
\r
+/**\r
+ This is the Framework Setup Browser interface which displays a FormSet.\r
+\r
+ @param This The EFI_FORM_BROWSER_PROTOCOL context.\r
+ @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation\r
+ only support UseDatabase is TRUE.\r
+ @param Handle The Handle buffer.\r
+ @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.\r
+ @param Packet The pointer to data buffer containing IFR and String package. Not supported.\r
+ @param CallbackHandle Not supported.\r
+ @param NvMapOverride The buffer is used only when there is no NV variable to define the \r
+ current settings and the caller needs to provide to the browser the\r
+ current settings for the the "fake" NV variable. If used, no saving of\r
+ an NV variable is possbile. This parameter is also ignored if Handle is NULL.\r
+\r
+ @retval EFI_SUCCESS If the Formset is displayed correctly.\r
+ @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.\r
+ @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.\r
+**/\r
+\r
EFI_STATUS\r
EFIAPI \r
ThunkSendForm (\r
return Status;\r
}\r
\r
+/** \r
+\r
+ Rountine used to display a generic dialog interface and return \r
+ the Key or Input from user input.\r
+\r
+ @param NumberOfLines The number of lines for the dialog box.\r
+ @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue\r
+ or if a string is returned in StringBuffer.\r
+ @param MaximumStringSize The maximum size in bytes of a typed-in string.\r
+ @param StringBuffer On return contains the typed-in string if HotKey\r
+ is FALSE.\r
+ @param KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE.\r
+ @param String The pointer to the first string in the list of strings\r
+ that comprise the dialog box.\r
+ @param ... A series of NumberOfLines text strings that will be used\r
+ to construct the dialog box.\r
+ @retval EFI_SUCCESS The dialog is created successfully and user interaction was received.\r
+ @retval EFI_DEVICE_ERROR The user typed in an ESC.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).\r
+**/\r
EFI_STATUS\r
EFIAPI \r
ThunkCreatePopUp (\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
\r
+#include "HiiDatabase.h"\r
#include "UefiIfrParser.h"\r
#include "UefiIfrDefault.h"\r
-#include "HiiDatabase.h"\r
\r
//\r
// Extern Variables\r
extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
\r
-extern EFI_GUID gZeroGuid;\r
-\r
-/**\r
- Fetch the Ifr binary data of a FormSet.\r
-\r
- @param Handle PackageList Handle\r
- @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
- GUID), take the first FormSet found in package\r
- list.\r
- @param BinaryLength The length of the FormSet IFR binary.\r
- @param BinaryData The buffer designed to receive the FormSet.\r
-\r
- @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
- BufferLength was updated.\r
- @retval EFI_INVALID_PARAMETER The handle is unknown.\r
- @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
- be found with the requested FormId.\r
-\r
-**/\r
-EFI_STATUS\r
-GetIfrBinaryData (\r
- IN EFI_HII_HANDLE Handle,\r
- IN OUT EFI_GUID *FormSetGuid,\r
- OUT UINTN *BinaryLength,\r
- OUT UINT8 **BinaryData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
- UINTN BufferSize;\r
- UINT8 *Package;\r
- UINT8 *OpCodeData;\r
- UINT32 Offset;\r
- UINT32 Offset2;\r
- BOOLEAN ReturnDefault;\r
- UINT32 PackageListLength;\r
- EFI_HII_PACKAGE_HEADER PackageHeader;\r
-\r
- OpCodeData = NULL;\r
- Package = NULL;\r
- ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
-\r
- //\r
- // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
- //\r
- if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
- ReturnDefault = TRUE;\r
- } else {\r
- ReturnDefault = FALSE;\r
- }\r
-\r
- //\r
- // Get HII PackageList\r
- //\r
- BufferSize = 0;\r
- HiiPackageList = NULL;\r
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- HiiPackageList = AllocatePool (BufferSize);\r
- ASSERT (HiiPackageList != NULL);\r
-\r
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get Form package from this HII package List\r
- //\r
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
- Offset2 = 0;\r
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
-\r
- while (Offset < PackageListLength) {\r
- Package = ((UINT8 *) HiiPackageList) + Offset;\r
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
- //\r
- // Search FormSet in this Form Package\r
- //\r
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
- while (Offset2 < PackageHeader.Length) {\r
- OpCodeData = Package + Offset2;\r
-\r
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
- //\r
- // Check whether return default FormSet\r
- //\r
- if (ReturnDefault) {\r
- break;\r
- }\r
-\r
- //\r
- // FormSet GUID is specified, check it\r
- //\r
- if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
- break;\r
- }\r
- }\r
-\r
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
- }\r
-\r
- if (Offset2 < PackageHeader.Length) {\r
- //\r
- // Target formset found\r
- //\r
- break;\r
- }\r
- }\r
-\r
- Offset += PackageHeader.Length;\r
- }\r
-\r
- if (Offset >= PackageListLength) {\r
- //\r
- // Form package not found in this Package List\r
- //\r
- gBS->FreePool (HiiPackageList);\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (ReturnDefault && FormSetGuid != NULL) {\r
- //\r
- // Return the default FormSet GUID\r
- //\r
- CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- }\r
-\r
- //\r
- // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
- // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
- // of the Form Package.\r
- //\r
- *BinaryLength = PackageHeader.Length - Offset2;\r
- *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
-\r
- gBS->FreePool (HiiPackageList);\r
-\r
- if (*BinaryData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Initialize the internal data structure of a FormSet.\r
-\r
- @param Handle PackageList Handle\r
- @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
- GUID), take the first FormSet found in package\r
- list.\r
- @param FormSet FormSet data structure.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeFormSet (\r
- IN EFI_HII_HANDLE Handle,\r
- IN OUT EFI_GUID *FormSetGuid,\r
- OUT FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE DriverHandle;\r
-\r
- Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- FormSet->HiiHandle = Handle;\r
- CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
-\r
- //\r
- // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
- //\r
- Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- FormSet->DriverHandle = DriverHandle;\r
- Status = gBS->HandleProtocol (\r
- DriverHandle,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- (VOID **) &FormSet->ConfigAccess\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
- // list, then there will be no configuration action required\r
- //\r
- FormSet->ConfigAccess = NULL;\r
- }\r
-\r
- //\r
- // Parse the IFR binary OpCodes\r
- //\r
- Status = ParseOpCodes (FormSet);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- return Status;\r
-}\r
-\r
/**\r
Set the data position at Offset with Width in Node->Buffer based \r
the value passed in.\r
/**\r
Reset Question to its default value.\r
\r
+ Note Framework 0.92's HII Implementation does not support for default value for these opcodes:\r
+ EFI_IFR_ORDERED_LIST_OP:\r
+ EFI_IFR_PASSWORD_OP:\r
+ EFI_IFR_STRING_OP:\r
+\r
@param FormSet FormSet data structure.\r
@param DefaultId The Class of the default.\r
\r
Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
\r
if (Default->DefaultId == DefaultId) {\r
- if (Default->ValueExpression != NULL) {\r
- //\r
- // Default is provided by an Expression, evaluate it\r
- //\r
- Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
- } else {\r
- //\r
- // Default value is embedded in EFI_IFR_DEFAULT\r
- //\r
- CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
- }\r
+ //\r
+ // Default value is embedded in EFI_IFR_DEFAULT\r
+ //\r
+ CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
\r
SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
return EFI_SUCCESS;\r
**/\r
EFI_STATUS\r
UefiIfrGetBufferTypeDefaults (\r
- IN EFI_HII_HANDLE UefiHiiHandle,\r
+ IN HII_THUNK_CONTEXT *ThunkContext,\r
OUT LIST_ENTRY **UefiDefaults\r
)\r
{\r
- FORM_BROWSER_FORMSET *FormSet;\r
- EFI_GUID FormSetGuid;\r
LIST_ENTRY *DefaultLink;\r
FORMSET_DEFAULTSTORE *DefaultStore;\r
EFI_STATUS Status;\r
\r
ASSERT (UefiDefaults != NULL);\r
\r
- FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
- ASSERT (FormSet != NULL);\r
-\r
- CopyGuid (&FormSetGuid, &gZeroGuid);\r
- Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
*UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));\r
ASSERT (UefiDefaults != NULL);\r
InitializeListHead (*UefiDefaults);\r
\r
- DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
- while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+ DefaultLink = GetFirstNode (&ThunkContext->FormSet->DefaultStoreListHead);\r
+ while (!IsNull (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink)) {\r
DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
\r
- Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults);\r
+ Status = GetBufferTypeDefaultId (DefaultStore, ThunkContext->FormSet, *UefiDefaults);\r
ASSERT_EFI_ERROR (Status);\r
\r
- DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink); \r
+ DefaultLink = GetNextNode (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink); \r
}\r
\r
- DestroyFormSet (FormSet);\r
- \r
return EFI_SUCCESS;\r
}\r
\r
UefiDefaultsToFwDefaults (\r
IN LIST_ENTRY *ListHead,\r
IN UINTN DefaultMask,\r
+ IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,\r
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
)\r
{\r
//\r
// In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId.\r
// So the default storage of Var Store in VFR from a Framework module \r
- // should be translated to 0x0001 (RESERVED_VARSTORE_ID).\r
+ // should be translated to 0x0001 (FRAMEWORK_RESERVED_VARSTORE_ID).\r
//\r
- if (Node->StoreId == RESERVED_VARSTORE_ID) {\r
+ if (Node->StoreId == UefiFormSetDefaultVarStoreId) {\r
Pack->VariableId = 0;\r
} else {\r
Pack->VariableId = Node->StoreId;\r
**/\r
EFI_STATUS\r
UefiIfrGetBufferTypeDefaults (\r
- EFI_HII_HANDLE UefiHiiHandle,\r
- LIST_ENTRY **UefiDefaults\r
+ IN HII_THUNK_CONTEXT *ThunkContext,\r
+ OUT LIST_ENTRY **UefiDefaults\r
);\r
\r
/**\r
UefiDefaultsToFwDefaults (\r
IN LIST_ENTRY *UefiIfrDefaults,\r
IN UINTN DefaultMask,\r
+ IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,\r
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
);\r
\r
\r
**/\r
\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Print.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/HiiString.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/IfrSupportLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <MdeModuleHii.h>\r
+\r
#include "UefiIfrParser.h"\r
-#include "UefiIfrParserExpression.h"\r
-#include "UefiIfrParserInternal.h"\r
-#include "UefiIfrParserCommon.h"\r
\r
+#include "UefiIfrParserExpression.h"\r
\r
UINT16 mStatementIndex;\r
-UINT16 mExpressionOpCodeIndex;\r
\r
BOOLEAN mInScopeSubtitle;\r
BOOLEAN mInScopeSuppress;\r
BOOLEAN mInScopeGrayOut;\r
-FORM_EXPRESSION *mSuppressExpression;\r
-FORM_EXPRESSION *mGrayOutExpression;\r
\r
-EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+EFI_GUID mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
+extern EFI_GUID mTianoHiiIfrGuid;\r
+\r
+LIST_ENTRY *\r
+GetOneOfOptionMapEntryListHead (\r
+ IN CONST FORM_BROWSER_FORMSET *FormSet,\r
+ IN UINT16 QuestionId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ ONE_OF_OPTION_MAP *Map;\r
+\r
+ Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);\r
+\r
+ while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {\r
+ Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+ if (QuestionId == Map->QuestionId) {\r
+ return &Map->OneOfOptionMapEntryListHead;\r
+ }\r
+ Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);\r
+ }\r
+ \r
+ return NULL;\r
+}\r
+\r
+VOID\r
+DestoryOneOfOptionMap (\r
+ IN LIST_ENTRY *OneOfOptionMapListHead\r
+ )\r
+{\r
+ ONE_OF_OPTION_MAP *Map;\r
+ ONE_OF_OPTION_MAP_ENTRY *MapEntry;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *Link2;\r
+\r
+ while (!IsListEmpty (OneOfOptionMapListHead)) {\r
+ Link = GetFirstNode (OneOfOptionMapListHead);\r
+ \r
+ Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+\r
+ while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
+ Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
+ \r
+ MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
+\r
+ RemoveEntryList (Link2);\r
+\r
+ FreePool (MapEntry);\r
+ }\r
+\r
+ RemoveEntryList (Link);\r
+ FreePool (Map);\r
+ }\r
+}\r
+\r
\r
/**\r
Initialize Statement header members.\r
\r
InitializeListHead (&Statement->DefaultListHead);\r
InitializeListHead (&Statement->OptionListHead);\r
- InitializeListHead (&Statement->InconsistentListHead);\r
- InitializeListHead (&Statement->NoSubmitListHead);\r
\r
Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
\r
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
\r
- if (mInScopeSuppress) {\r
- Statement->SuppressExpression = mSuppressExpression;\r
- }\r
-\r
- if (mInScopeGrayOut) {\r
- Statement->GrayOutExpression = mGrayOutExpression;\r
- }\r
-\r
Statement->InSubtitle = mInScopeSubtitle;\r
\r
//\r
return Statement;\r
}\r
\r
-\r
/**\r
Initialize Question's members.\r
\r
EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
LIST_ENTRY *Link;\r
FORMSET_STORAGE *Storage;\r
- NAME_VALUE_NODE *NameValueNode;\r
\r
Statement = CreateStatement (OpCodeData, FormSet, Form);\r
if (Statement == NULL) {\r
CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
\r
+ if (FormSet->MaxQuestionId < QuestionHdr->QuestionId) {\r
+ FormSet->MaxQuestionId = QuestionHdr->QuestionId;\r
+ }\r
+\r
Statement->QuestionFlags = QuestionHdr->Flags;\r
\r
if (Statement->VarStoreId == 0) {\r
}\r
ASSERT (Statement->Storage != NULL);\r
\r
- //\r
- // Initialilze varname for Name/Value or EFI Variable\r
- //\r
- if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
- (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
- Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
- ASSERT (Statement->VariableName != NULL);\r
-\r
- if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
- //\r
- // Insert to Name/Value varstore list\r
- //\r
- NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
- ASSERT (NameValueNode != NULL);\r
- NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
- NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
- ASSERT (NameValueNode->Name != NULL);\r
- NameValueNode->Value = AllocateZeroPool (0x10);\r
- ASSERT (NameValueNode->Value != NULL);\r
- NameValueNode->EditValue = AllocateZeroPool (0x10);\r
- ASSERT (NameValueNode->EditValue != NULL);\r
-\r
- InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
- }\r
- }\r
-\r
return Statement;\r
}\r
\r
-\r
-/**\r
- Allocate a FORM_EXPRESSION node.\r
-\r
- @param Form The Form associated with this Expression\r
-\r
- @return Pointer to a FORM_EXPRESSION data structure.\r
-\r
-**/\r
-FORM_EXPRESSION *\r
-CreateExpression (\r
- IN OUT FORM_BROWSER_FORM *Form\r
- )\r
-{\r
- FORM_EXPRESSION *Expression;\r
-\r
- Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
- Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
- InitializeListHead (&Expression->OpCodeListHead);\r
-\r
- return Expression;\r
-}\r
-\r
-\r
/**\r
Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
\r
\r
Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
- InitializeListHead (&Storage->NameValueListHead);\r
InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
\r
return Storage;\r
}\r
\r
-\r
-/**\r
- Create ConfigHdr string for a storage.\r
-\r
- @param FormSet Pointer of the current FormSet\r
- @param Storage Pointer of the storage\r
-\r
- @retval EFI_SUCCESS Initialize ConfigHdr success\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeConfigHdr (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORMSET_STORAGE *Storage\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN StrBufferLen;\r
- CHAR16 *Name;\r
-\r
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
- Name = Storage->Name;\r
- } else {\r
- Name = NULL;\r
- }\r
-\r
- StrBufferLen = 0;\r
- Status = ConstructConfigHdr (\r
- Storage->ConfigHdr,\r
- &StrBufferLen,\r
- &Storage->Guid,\r
- Name,\r
- FormSet->DriverHandle\r
- );\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- Storage->ConfigHdr = AllocateZeroPool (StrBufferLen);\r
- Status = ConstructConfigHdr (\r
- Storage->ConfigHdr,\r
- &StrBufferLen,\r
- &Storage->Guid,\r
- Name,\r
- FormSet->DriverHandle\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr);\r
- Storage->SpareStrLen = 0;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
-\r
- @param FormSet Pointer of the current FormSet.\r
- @param Question The Question to be initialized.\r
-\r
- @retval EFI_SUCCESS Function success.\r
- @retval EFI_INVALID_PARAMETER No storage associated with the Question.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeRequestElement (\r
- IN OUT FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT FORM_BROWSER_STATEMENT *Question\r
- )\r
-{\r
- FORMSET_STORAGE *Storage;\r
- UINTN StrLen;\r
- UINTN StringSize;\r
- CHAR16 *NewStr;\r
- CHAR16 RequestElement[30];\r
-\r
- Storage = Question->Storage;\r
- if (Storage == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- //\r
- // <ConfigRequest> is unnecessary for EFI variable storage,\r
- // GetVariable()/SetVariable() will be used to retrieve/save values\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Prepare <RequestElement>\r
- //\r
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
- StrLen = UnicodeSPrint (\r
- RequestElement,\r
- 30 * sizeof (CHAR16),\r
- L"&OFFSET=%x&WIDTH=%x",\r
- Question->VarStoreInfo.VarOffset,\r
- Question->StorageWidth\r
- );\r
- Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
- } else {\r
- StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
- }\r
-\r
- if ((Question->Operand == EFI_IFR_PASSWORD_OP) && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)) {\r
- //\r
- // Password with CALLBACK flag is stored in encoded format,\r
- // so don't need to append it to <ConfigRequest>\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Append <RequestElement> to <ConfigRequest>\r
- //\r
- if (StrLen > Storage->SpareStrLen) {\r
- //\r
- // Old String buffer is not sufficient for RequestElement, allocate a new one\r
- //\r
- StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
- NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
- if (Storage->ConfigRequest != NULL) {\r
- CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
- gBS->FreePool (Storage->ConfigRequest);\r
- }\r
- Storage->ConfigRequest = NewStr;\r
- Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
- }\r
-\r
- StrCat (Storage->ConfigRequest, RequestElement);\r
- Storage->ElementCount++;\r
- Storage->SpareStrLen -= StrLen;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Free resources of a Expression\r
-\r
- @param FormSet Pointer of the Expression\r
-\r
- @return None.\r
-\r
-**/\r
-VOID\r
-DestroyExpression (\r
- IN FORM_EXPRESSION *Expression\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- EXPRESSION_OPCODE *OpCode;\r
-\r
- while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
- Link = GetFirstNode (&Expression->OpCodeListHead);\r
- OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
- RemoveEntryList (&OpCode->Link);\r
-\r
- if (OpCode->ValueList != NULL) {\r
- FreePool (OpCode->ValueList);\r
- }\r
- }\r
-\r
- //\r
- // Free this Expression\r
- //\r
- gBS->FreePool (Expression);\r
-}\r
-\r
-\r
/**\r
Free resources of a storage\r
\r
IN FORMSET_STORAGE *Storage\r
)\r
{\r
- LIST_ENTRY *Link;\r
- NAME_VALUE_NODE *NameValueNode;\r
-\r
if (Storage == NULL) {\r
return;\r
}\r
\r
- FreePool (Storage->Name);\r
- FreePool (Storage->Buffer);\r
- FreePool (Storage->EditBuffer);\r
-\r
- while (!IsListEmpty (&Storage->NameValueListHead)) {\r
- Link = GetFirstNode (&Storage->NameValueListHead);\r
- NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
- RemoveEntryList (&NameValueNode->Link);\r
-\r
- FreePool (NameValueNode->Name);\r
- FreePool (NameValueNode->Value);\r
- FreePool (NameValueNode->EditValue);\r
- FreePool (NameValueNode);\r
+ if (Storage->Name!= NULL) {\r
+ FreePool (Storage->Name);\r
}\r
\r
- FreePool (Storage->ConfigHdr);\r
- FreePool (Storage->ConfigRequest);\r
-\r
FreePool (Storage);\r
}\r
\r
LIST_ENTRY *Link;\r
QUESTION_DEFAULT *Default;\r
QUESTION_OPTION *Option;\r
- FORM_EXPRESSION *Expression;\r
\r
//\r
// Free Default value List\r
gBS->FreePool (Option);\r
}\r
\r
- //\r
- // Free Inconsistent List\r
- //\r
- while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
- Link = GetFirstNode (&Statement->InconsistentListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- //\r
- // Free NoSubmit List\r
- //\r
- while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
- Link = GetFirstNode (&Statement->NoSubmitListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
- if (Statement->VariableName != NULL) {\r
- FreePool (Statement->VariableName);\r
- }\r
- if (Statement->BlockName != NULL) {\r
- FreePool (Statement->BlockName);\r
- }\r
}\r
\r
\r
)\r
{\r
LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
FORM_BROWSER_STATEMENT *Statement;\r
\r
- //\r
- // Free Form Expressions\r
- //\r
- while (!IsListEmpty (&Form->ExpressionListHead)) {\r
- Link = GetFirstNode (&Form->ExpressionListHead);\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- RemoveEntryList (&Expression->Link);\r
-\r
- DestroyExpression (Expression);\r
- }\r
-\r
//\r
// Free Statements/Questions\r
//\r
if (FormSet->StatementBuffer != NULL) {\r
FreePool (FormSet->StatementBuffer);\r
}\r
- if (FormSet->ExpressionBuffer != NULL) {\r
- FreePool (FormSet->ExpressionBuffer);\r
- }\r
\r
+ DestoryOneOfOptionMap (&FormSet->OneOfOptionMapListHead);\r
+ \r
FreePool (FormSet);\r
}\r
\r
UINT16 Index;\r
FORM_BROWSER_FORM *CurrentForm;\r
FORM_BROWSER_STATEMENT *CurrentStatement;\r
- EXPRESSION_OPCODE *ExpressionOpCode;\r
- FORM_EXPRESSION *CurrentExpression;\r
UINT8 Operand;\r
UINT8 Scope;\r
UINTN OpCodeOffset;\r
EFI_IMAGE_ID *ImageId;\r
BOOLEAN SuppressForOption;\r
BOOLEAN InScopeOptionSuppress;\r
- FORM_EXPRESSION *OptionSuppressExpression;\r
BOOLEAN InScopeDisable;\r
UINT16 DepthOfDisable;\r
BOOLEAN OpCodeDisabled;\r
BOOLEAN SingleOpCodeExpression;\r
BOOLEAN InScopeDefault;\r
EFI_HII_VALUE *Value;\r
+ LIST_ENTRY *OneOfOptinMapEntryListHead;\r
+ EFI_IFR_GUID_OPTIONKEY *OptionMap;\r
+ ONE_OF_OPTION_MAP *OneOfOptionMap;\r
+ ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
+ UINT8 OneOfType;\r
+ EFI_IFR_ONE_OF *OneOfOpcode;\r
\r
mInScopeSubtitle = FALSE;\r
SuppressForOption = FALSE;\r
OpCodeDisabled = FALSE;\r
SingleOpCodeExpression = FALSE;\r
InScopeDefault = FALSE;\r
- CurrentExpression = NULL;\r
CurrentDefault = NULL;\r
CurrentOption = NULL;\r
- OptionSuppressExpression = NULL;\r
+\r
+ //\r
+ // Set to a invalid value.\r
+ //\r
+ OneOfType = (UINT8) -1;\r
\r
//\r
// Get the number of Statements and Expressions\r
//\r
CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
+ FormSet->NumberOfStatement = NumberOfStatement;\r
\r
mStatementIndex = 0;\r
FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- mExpressionOpCodeIndex = 0;\r
- FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
- if (FormSet->ExpressionBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
InitializeListHead (&FormSet->StorageListHead);\r
InitializeListHead (&FormSet->DefaultStoreListHead);\r
InitializeListHead (&FormSet->FormListHead);\r
+ InitializeListHead (&FormSet->OneOfOptionMapListHead);\r
\r
CurrentForm = NULL;\r
CurrentStatement = NULL;\r
}\r
\r
if (IsExpressionOpCode (Operand)) {\r
- ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
- mExpressionOpCodeIndex++;\r
-\r
- ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
- ExpressionOpCode->Operand = Operand;\r
- Value = &ExpressionOpCode->Value;\r
-\r
- switch (Operand) {\r
- case EFI_IFR_EQ_ID_VAL_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_ID_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
- CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_LIST_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
- CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
- ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);\r
- break;\r
-\r
- case EFI_IFR_TO_STRING_OP:\r
- case EFI_IFR_FIND_OP:\r
- ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF1_OP:\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
- break;\r
-\r
- case EFI_IFR_RULE_REF_OP:\r
- ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
- break;\r
-\r
- case EFI_IFR_SPAN_OP:\r
- ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
- break;\r
-\r
- case EFI_IFR_THIS_OP:\r
- ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF1_OP:\r
- CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
- CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
-\r
- if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
- CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- }\r
- }\r
- break;\r
-\r
- //\r
- // constant\r
- //\r
- case EFI_IFR_TRUE_OP:\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Value->Value.b = TRUE;\r
- break;\r
-\r
- case EFI_IFR_FALSE_OP:\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Value->Value.b = FALSE;\r
- break;\r
-\r
- case EFI_IFR_ONE_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = 1;\r
- break;\r
-\r
- case EFI_IFR_ZERO_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = 0;\r
- break;\r
-\r
- case EFI_IFR_ONES_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = 0xffffffffffffffffULL;\r
- break;\r
-\r
- case EFI_IFR_UINT8_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
- break;\r
-\r
- case EFI_IFR_UINT16_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
- break;\r
-\r
- case EFI_IFR_UINT32_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
- CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
- break;\r
-\r
- case EFI_IFR_UINT64_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
- break;\r
-\r
- case EFI_IFR_UNDEFINED_OP:\r
- Value->Type = EFI_IFR_TYPE_OTHER;\r
- break;\r
-\r
- case EFI_IFR_VERSION_OP:\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
-\r
- if (SingleOpCodeExpression) {\r
- //\r
- // There are two cases to indicate the end of an Expression:\r
- // for single OpCode expression: one Expression OpCode\r
- // for expression consists of more than one OpCode: EFI_IFR_END\r
- //\r
- SingleOpCodeExpression = FALSE;\r
-\r
- if (InScopeDisable) {\r
- //\r
- // Evaluate DisableIf expression\r
- //\r
- Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
- }\r
-\r
- CurrentExpression = NULL;\r
- }\r
-\r
continue;\r
}\r
\r
//\r
CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
- InitializeListHead (&CurrentForm->ExpressionListHead);\r
+\r
InitializeListHead (&CurrentForm->StatementListHead);\r
\r
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
\r
- Storage->Buffer = AllocateZeroPool (Storage->Size);\r
- Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
-\r
AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
ASSERT (Storage->Name != NULL);\r
Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
}\r
\r
- //\r
- // Initialize <ConfigHdr>\r
- //\r
- InitializeConfigHdr (FormSet, Storage);\r
break;\r
\r
case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
- //\r
- // Create a name/value Storage for this FormSet\r
- //\r
- Storage = CreateStorage (FormSet);\r
- Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+ ASSERT (FALSE);\r
\r
- CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-\r
- //\r
- // Initialize <ConfigHdr>\r
- //\r
- InitializeConfigHdr (FormSet, Storage);\r
break;\r
\r
case EFI_IFR_VARSTORE_EFI_OP:\r
break;\r
}\r
\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
-\r
if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {\r
SuppressForOption = TRUE;\r
}\r
+\r
+ if (Operand == EFI_IFR_ONE_OF_OP) {\r
+ OneOfOpcode = (EFI_IFR_ONE_OF *) OpCodeData;\r
+ OneOfType = OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE;\r
+ }\r
break;\r
\r
case EFI_IFR_ORDERED_LIST_OP:\r
CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
\r
//\r
// No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver\r
CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
break;\r
\r
case EFI_IFR_STRING_OP:\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
break;\r
\r
case EFI_IFR_PASSWORD_OP:\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
break;\r
\r
case EFI_IFR_DATE_OP:\r
CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
\r
- if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
- CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
-\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
- } else {\r
- //\r
- // Don't assign storage for RTC type of date/time\r
- //\r
- CurrentStatement->Storage = NULL;\r
- CurrentStatement->StorageWidth = 0;\r
- }\r
break;\r
\r
case EFI_IFR_TIME_OP:\r
CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
\r
- if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
- CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
-\r
- InitializeRequestElement (FormSet, CurrentStatement);\r
- } else {\r
- //\r
- // Don't assign storage for RTC type of date/time\r
- //\r
- CurrentStatement->Storage = NULL;\r
- CurrentStatement->StorageWidth = 0;\r
- }\r
break;\r
\r
//\r
CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
ExtendValueToU64 (&CurrentOption->Value);\r
\r
- if (InScopeOptionSuppress) {\r
- CurrentOption->SuppressExpression = OptionSuppressExpression;\r
- }\r
-\r
//\r
// Insert to Option list of current Question\r
//\r
//\r
case EFI_IFR_NO_SUBMIT_IF_OP:\r
case EFI_IFR_INCONSISTENT_IF_OP:\r
- //\r
- // Create an Expression node\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
-\r
- if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
- InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
- } else {\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
- InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
- }\r
break;\r
\r
case EFI_IFR_SUPPRESS_IF_OP:\r
- //\r
- // Question and Option will appear in scope of this OpCode\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- if (SuppressForOption) {\r
- InScopeOptionSuppress = TRUE;\r
- OptionSuppressExpression = CurrentExpression;\r
- } else {\r
- mInScopeSuppress = TRUE;\r
- mSuppressExpression = CurrentExpression;\r
- }\r
break;\r
\r
case EFI_IFR_GRAY_OUT_IF_OP:\r
- //\r
- // Questions will appear in scope of this OpCode\r
- //\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- mInScopeGrayOut = TRUE;\r
- mGrayOutExpression = CurrentExpression;\r
break;\r
\r
case EFI_IFR_DISABLE_IF_OP:\r
- //\r
- // The DisableIf expression should only rely on constant, so it could be\r
- // evaluated at initialization and it will not be queued\r
- //\r
- CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
- CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
- InitializeListHead (&CurrentExpression->OpCodeListHead);\r
-\r
- InScopeDisable = TRUE;\r
- OpCodeDisabled = FALSE;\r
+ ASSERT (FALSE);\r
\r
- //\r
- // Take a look at next OpCode to see whether current expression consists\r
- // of single OpCode\r
- //\r
- if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
- SingleOpCodeExpression = TRUE;\r
- }\r
- break;\r
\r
//\r
// Expression\r
//\r
case EFI_IFR_VALUE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
-\r
- if (InScopeDefault) {\r
- //\r
- // Used for default (EFI_IFR_DEFAULT)\r
- //\r
- CurrentDefault->ValueExpression = CurrentExpression;\r
- } else {\r
- //\r
- // If used for a question, then the question will be read-only\r
- //\r
- CurrentStatement->ValueExpression = CurrentExpression;\r
- }\r
break;\r
\r
case EFI_IFR_RULE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
- CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
-\r
- CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
- InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
break;\r
\r
//\r
// Vendor specific\r
//\r
case EFI_IFR_GUID_OP:\r
- if (CompareGuid (&gTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCodeData;\r
+ \r
+ if (CompareGuid (&mTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
//\r
// Tiano specific GUIDed opcodes\r
//\r
//\r
break;\r
\r
-#if 0\r
- case EFI_IFR_EXTEND_OP_BANNER:\r
- if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
- CopyMem (\r
- &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
- ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
- &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
- sizeof (EFI_STRING_ID)\r
- );\r
- }\r
- break;\r
-#endif\r
\r
case EFI_IFR_EXTEND_OP_CLASS:\r
CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
default:\r
break;\r
}\r
- }\r
+ } \r
+ else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {\r
+ if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {\r
+ OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId);\r
+ if (OneOfOptinMapEntryListHead == NULL) {\r
+ OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
+ ASSERT (OneOfOptionMap != NULL);\r
+\r
+ OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
+ OneOfOptionMap->QuestionId = OptionMap->QuestionId;\r
+\r
+ //\r
+ // Make sure OneOfType is initialized.\r
+ //\r
+ ASSERT (OneOfType != (UINT8) -1);\r
+ OneOfOptionMap->ValueType = OneOfType;\r
+ InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
+ OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;\r
+ InsertTailList (&FormSet->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
+ }\r
+ OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
+ ASSERT (OneOfOptionMapEntry != NULL);\r
+\r
+ OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
+ OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;\r
+ CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));\r
+ \r
+ InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);\r
+ }\r
+ }\r
break;\r
\r
//\r
\r
default:\r
if (IsExpressionOpCode (ScopeOpCode)) {\r
- if (InScopeDisable) {\r
- //\r
- // Evaluate DisableIf expression\r
- //\r
- Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
- //\r
- // DisableIf Expression is only used once and not quequed, free it\r
- //\r
- DestroyExpression (CurrentExpression);\r
- }\r
-\r
- //\r
- // End of current Expression\r
- //\r
- CurrentExpression = NULL;\r
}\r
break;\r
}\r
/** @file\r
Function and Macro defintions for IFR parsing. To get the default value from IFR package, the IFR\r
opcode needs to be parsed. Most of code is taken from MdeModulePkg\Universal\SetupBrowserDxe\IfrParse.c.\r
+ This parser is simplified from the origianl IfrParser.c in the following way:\r
+\r
+ 1) All data structure definition that have nothing to do with IFR Default value scanning (\r
+ required to implement Framework HII's GetDefaultImage ()) is removed.\r
+ 2) Ignore the IFR opcode which is invalid for Form Package\r
+ generated using Framework VFR file.\r
\r
Copyright (c) 2008, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
#ifndef _HII_THUNK_UEFI_IFR_PARSER_\r
#define _HII_THUNK_UEFI_IFR_PARSER_\r
\r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/Print.h>\r
-#include <Protocol/HiiConfigAccess.h>\r
-#include <Protocol/HiiConfigRouting.h>\r
-#include <Protocol/HiiDatabase.h>\r
-#include <Protocol/HiiString.h>\r
\r
//\r
// IFR relative definition\r
\r
extern EFI_GUID gTianoHiiIfrGuid;\r
\r
+#define ONE_OF_OPTION_MAP_ENTRY_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP_ENTRY, Link, ONE_OF_OPTION_MAP_ENTRY_SIGNATURE)\r
+#define ONE_OF_OPTION_MAP_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'M', 'E')\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT16 FwKey;\r
+ EFI_IFR_TYPE_VALUE Value;\r
+ \r
+} ONE_OF_OPTION_MAP_ENTRY;\r
+\r
+\r
+\r
+#define ONE_OF_OPTION_MAP_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP, Link, ONE_OF_OPTION_MAP_SIGNATURE)\r
+#define ONE_OF_OPTION_MAP_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'O', 'M')\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link; \r
+\r
+ UINT16 VarStoreId;\r
+\r
+ UINT8 ValueType; //EFI_IFR_TYPE_NUM_* \r
+\r
+ EFI_QUESTION_ID QuestionId;\r
+\r
+ LIST_ENTRY OneOfOptionMapEntryListHead; //ONE_OF_OPTION_MAP_ENTRY\r
+} ONE_OF_OPTION_MAP;\r
+\r
\r
typedef struct {\r
UINT8 Type;\r
\r
#define NAME_VALUE_NODE_SIGNATURE EFI_SIGNATURE_32 ('N', 'V', 'S', 'T')\r
\r
-typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- CHAR16 *Name;\r
- CHAR16 *Value;\r
- CHAR16 *EditValue;\r
-} NAME_VALUE_NODE;\r
-\r
-#define NAME_VALUE_NODE_FROM_LINK(a) CR (a, NAME_VALUE_NODE, Link, NAME_VALUE_NODE_SIGNATURE)\r
-\r
#define FORMSET_STORAGE_SIGNATURE EFI_SIGNATURE_32 ('F', 'S', 'T', 'G')\r
\r
typedef struct {\r
\r
CHAR16 *Name; // For EFI_IFR_VARSTORE\r
UINT16 Size;\r
- UINT8 *Buffer;\r
- UINT8 *EditBuffer; // Edit copy for Buffer Storage\r
-\r
- LIST_ENTRY NameValueListHead; // List of NAME_VALUE_NODE\r
\r
UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute\r
\r
- CHAR16 *ConfigHdr; // <ConfigHdr>\r
- CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>\r
- UINTN ElementCount; // Number of <RequestElement> in the <ConfigRequest>\r
- UINTN SpareStrLen; // Spare length of ConfigRequest string buffer\r
} FORMSET_STORAGE;\r
\r
#define FORMSET_STORAGE_FROM_LINK(a) CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)\r
\r
+#if 0\r
+\r
#define EXPRESSION_OPCODE_SIGNATURE EFI_SIGNATURE_32 ('E', 'X', 'O', 'P')\r
\r
typedef struct {\r
} FORM_EXPRESSION;\r
\r
#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)\r
+#endif\r
\r
#define QUESTION_DEFAULT_SIGNATURE EFI_SIGNATURE_32 ('Q', 'D', 'F', 'T')\r
\r
UINT16 DefaultId;\r
EFI_HII_VALUE Value; // Default value\r
\r
- FORM_EXPRESSION *ValueExpression; // Not-NULL indicates default value is provided by EFI_IFR_VALUE\r
} QUESTION_DEFAULT;\r
\r
#define QUESTION_DEFAULT_FROM_LINK(a) CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)\r
EFI_HII_VALUE Value;\r
EFI_IMAGE_ID ImageId;\r
\r
+#if 0\r
FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf\r
+#endif\r
} QUESTION_OPTION;\r
\r
#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)\r
EFI_STRING_ID VarName;\r
UINT16 VarOffset;\r
} VarStoreInfo;\r
+#if 0\r
+ CHAR16 *UnicodeVarName;\r
+#endif\r
+ \r
UINT16 StorageWidth;\r
UINT8 QuestionFlags;\r
+\r
+#if 0\r
CHAR16 *VariableName; // Name/Value or EFI Variable name\r
CHAR16 *BlockName; // Buffer storage block name: "OFFSET=...WIDTH=..."\r
+#endif\r
\r
EFI_HII_VALUE HiiValue; // Edit copy for checkbox, numberic, oneof\r
UINT8 *BufferValue; // Edit copy for string, password, orderedlist\r
//\r
// Get from IFR parsing\r
//\r
+#if 0\r
FORM_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly\r
+#endif\r
LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT list (QUESTION_DEFAULT), provide default values\r
LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)\r
\r
UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh\r
BOOLEAN InSubtitle; // nesting inside of EFI_IFR_SUBTITLE\r
\r
+#if 0\r
LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)\r
LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)\r
FORM_EXPRESSION *GrayOutExpression; // nesting inside of GrayOutIf\r
FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf\r
+#endif\r
\r
} FORM_BROWSER_STATEMENT;\r
\r
\r
EFI_IMAGE_ID ImageId;\r
\r
+#if 0\r
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)\r
+#endif\r
LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
} FORM_BROWSER_FORM;\r
\r
\r
typedef struct {\r
EFI_HII_HANDLE HiiHandle;\r
- EFI_HANDLE DriverHandle;\r
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
UINTN IfrBinaryLength;\r
UINT8 *IfrBinaryData;\r
EFI_IMAGE_ID ImageId;\r
\r
FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions\r
+#if 0\r
EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode\r
+#endif\r
\r
LIST_ENTRY StorageListHead; // Storage list (FORMSET_STORAGE)\r
LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)\r
LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)\r
-} FORM_BROWSER_FORMSET;\r
\r
+ LIST_ENTRY OneOfOptionMapListHead; //ONE_OF_OPTION_MAP\r
+\r
+ UINT16 MaxQuestionId;\r
+\r
+ EFI_VARSTORE_ID DefaultVarStoreId;\r
+\r
+ UINTN NumberOfStatement;\r
+ \r
+} FORM_BROWSER_FORMSET;\r
\r
-EFI_STATUS\r
-EvaluateExpression (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN OUT FORM_EXPRESSION *Expression\r
- );\r
\r
EFI_STATUS\r
ParseOpCodes (\r
\r
#include "UefiIfrParser.h"\r
#include "UefiIfrParserExpressionInternal.h"\r
-#include "UefiIfrParserCommon.h"\r
\r
//\r
// Global stack used to evaluate boolean expresions\r
EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
\r
-//\r
-// Unicode collation protocol interface\r
-//\r
-EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
+#define EXPRESSION_STACK_SIZE_INCREMENT 0x100\r
\r
\r
/**\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Reset stack pointer to begin of the stack.\r
\r
);\r
}\r
\r
-\r
-/**\r
- Get Form given its FormId.\r
-\r
- @param FormSet The formset which contains this form.\r
- @param FormId Id of this form.\r
-\r
- @retval Pointer The form.\r
- @retval NULL Specified Form is not found in the formset.\r
-\r
-**/\r
-FORM_BROWSER_FORM *\r
-IdToForm (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT16 FormId\r
-)\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_FORM *Form;\r
-\r
- Link = GetFirstNode (&FormSet->FormListHead);\r
- while (!IsNull (&FormSet->FormListHead, Link)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
- if (Form->FormId == FormId) {\r
- return Form;\r
- }\r
-\r
- Link = GetNextNode (&FormSet->FormListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Search a Question in Form scope using its QuestionId.\r
-\r
- @param Form The form which contains this Question.\r
- @param QuestionId Id of this Question.\r
-\r
- @retval Pointer The Question.\r
- @retval NULL Specified Question not found in the form.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-IdToQuestion2 (\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 QuestionId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Question;\r
-\r
- if (QuestionId == 0) {\r
- //\r
- // The value of zero is reserved\r
- //\r
- return NULL;\r
- }\r
-\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- while (!IsNull (&Form->StatementListHead, Link)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-\r
- if (Question->QuestionId == QuestionId) {\r
- return Question;\r
- }\r
-\r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Search a Question in Formset scope using its QuestionId.\r
-\r
- @param FormSet The formset which contains this form.\r
- @param Form The form which contains this Question.\r
- @param QuestionId Id of this Question.\r
-\r
- @retval Pointer The Question.\r
- @retval NULL Specified Question not found in the form.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-IdToQuestion (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT16 QuestionId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Question;\r
-\r
- //\r
- // Search in the form scope first\r
- //\r
- Question = IdToQuestion2 (Form, QuestionId);\r
- if (Question != NULL) {\r
- return Question;\r
- }\r
-\r
- //\r
- // Search in the formset scope\r
- //\r
- Link = GetFirstNode (&FormSet->FormListHead);\r
- while (!IsNull (&FormSet->FormListHead, Link)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
- Question = IdToQuestion2 (Form, QuestionId);\r
- if (Question != NULL) {\r
- return Question;\r
- }\r
-\r
- Link = GetNextNode (&FormSet->FormListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Get Expression given its RuleId.\r
-\r
- @param Form The form which contains this Expression.\r
- @param RuleId Id of this Expression.\r
-\r
- @retval Pointer The Expression.\r
- @retval NULL Specified Expression not found in the form.\r
-\r
-**/\r
-FORM_EXPRESSION *\r
-RuleIdToExpression (\r
- IN FORM_BROWSER_FORM *Form,\r
- IN UINT8 RuleId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
-\r
- Link = GetFirstNode (&Form->ExpressionListHead);\r
- while (!IsNull (&Form->ExpressionListHead, Link)) {\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
-\r
- if (Expression->Type == EFI_HII_EXPRESSION_RULE && Expression->RuleId == RuleId) {\r
- return Expression;\r
- }\r
-\r
- Link = GetNextNode (&Form->ExpressionListHead, Link);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Locate the Unicode Collation Protocol interface for later use.\r
-\r
- None.\r
-\r
- @retval EFI_SUCCESS Protocol interface initialize success.\r
- @retval Other Protocol interface initialize failed.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeUnicodeCollationProtocol (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (mUnicodeCollation != NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol\r
- // instances first and then select one which support English language.\r
- // Current implementation just pick the first instance.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiUnicodeCollation2ProtocolGuid,\r
- NULL,\r
- (VOID **) &mUnicodeCollation\r
- );\r
- return Status;\r
-}\r
-\r
-VOID\r
-IfrStrToUpper (\r
- CHAR16 *String\r
- )\r
-{\r
- while (*String != 0) {\r
- if ((*String >= 'a') && (*String <= 'z')) {\r
- *String = (UINT16) ((*String) & ((UINT16) ~0x20));\r
- }\r
- String++;\r
- }\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TO_STRING.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Format String format in EFI_IFR_TO_STRING.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToString (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Format,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String;\r
- CHAR16 *PrintFormat;\r
- CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
- UINTN BufferSize;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- switch (Value.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
- BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);\r
- switch (Format) {\r
- case EFI_IFR_STRING_UNSIGNED_DEC:\r
- case EFI_IFR_STRING_SIGNED_DEC:\r
- PrintFormat = L"%ld";\r
- break;\r
-\r
- case EFI_IFR_STRING_LOWERCASE_HEX:\r
- PrintFormat = L"%lx";\r
- break;\r
-\r
- case EFI_IFR_STRING_UPPERCASE_HEX:\r
- PrintFormat = L"%lX";\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
- UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);\r
- String = Buffer;\r
- break;\r
-\r
- case EFI_IFR_TYPE_STRING:\r
- CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
- return EFI_SUCCESS;\r
-\r
- case EFI_IFR_TYPE_BOOLEAN:\r
- String = (Value.Value.b) ? L"True" : L"False";\r
- break;\r
-\r
- default:\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (String, FormSet->HiiHandle);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TO_UINT.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToUint (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String;\r
- CHAR16 *StringPtr;\r
- UINTN BufferSize;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- if (Value.Type == EFI_IFR_TYPE_STRING) {\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- IfrStrToUpper (String);\r
- StringPtr = StrStr (String, L"0X");\r
- if (StringPtr != NULL) {\r
- //\r
- // Hex string\r
- //\r
- BufferSize = sizeof (UINT64);\r
- Status = HexStringToBuf ((UINT8 *) &Result->Value.u64, &BufferSize, StringPtr + 2, NULL);\r
- } else {\r
- //\r
- // BUGBUG: Need handle decimal string\r
- //\r
- }\r
- gBS->FreePool (String);\r
- } else {\r
- CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_CATENATE.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrCatenate (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Index;\r
- CHAR16 *StringPtr;\r
- UINTN Size;\r
-\r
- //\r
- // String[0] - The second string\r
- // String[1] - The first string\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- StringPtr = NULL;\r
- Status = EFI_SUCCESS;\r
-\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Size = StrSize (String[0]);\r
- StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
- ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- } \r
- if (StringPtr != NULL) {\r
- FreePool (StringPtr);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_MATCH.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrMatch (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Index;\r
-\r
- //\r
- // String[0] - The string to search\r
- // String[1] - pattern\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- Status = EFI_SUCCESS;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- } \r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_FIND.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Format Case sensitive or insensitive.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrFind (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Format,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Base;\r
- CHAR16 *StringPtr;\r
- UINTN Index;\r
-\r
- if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - sub-string\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
-\r
- if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {\r
- //\r
- // Case insensitive, convert both string to upper case\r
- //\r
- IfrStrToUpper (String[Index]);\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- if (Base >= StrLen (String[1])) {\r
- Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;\r
- } else {\r
- StringPtr = StrStr (String[1] + Base, String[0]);\r
- Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);\r
- }\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- } \r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_MID.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrMid (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String;\r
- UINTN Base;\r
- UINTN Length;\r
- CHAR16 *SubString;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Length = (UINTN) Value.Value.u64;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (Length == 0 || Base >= StrLen (String)) {\r
- SubString = gEmptyString;\r
- } else {\r
- SubString = String + Base;\r
- if ((Base + Length) < StrLen (String)) {\r
- SubString[Length] = L'\0';\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
-\r
- gBS->FreePool (String);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_TOKEN.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrToken (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- UINTN Count;\r
- CHAR16 *Delimiter;\r
- CHAR16 *SubString;\r
- CHAR16 *StringPtr;\r
- UINTN Index;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Count = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - Delimiter\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- Delimiter = String[0];\r
- SubString = String[1];\r
- while (Count > 0) {\r
- SubString = StrStr (SubString, Delimiter);\r
- if (SubString != NULL) {\r
- //\r
- // Skip over the delimiter\r
- //\r
- SubString = SubString + StrLen (Delimiter);\r
- } else {\r
- break;\r
- }\r
- Count--;\r
- }\r
-\r
- if (SubString == NULL) {\r
- //\r
- // nth delimited sub-string not found, push an empty string\r
- //\r
- SubString = gEmptyString;\r
- } else {\r
- //\r
- // Put a NULL terminator for nth delimited sub-string\r
- //\r
- StringPtr = StrStr (SubString, Delimiter);\r
- if (StringPtr != NULL) {\r
- *StringPtr = L'\0';\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- } \r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Evaluate opcode EFI_IFR_SPAN.\r
-\r
- @param FormSet Formset which contains this opcode.\r
- @param Flags FIRST_MATCHING or FIRST_NON_MATCHING.\r
- @param Result Evaluation result for this opcode.\r
-\r
- @retval EFI_SUCCESS Opcode evaluation success.\r
- @retval Other Opcode evaluation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IfrSpan (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 Flags,\r
- OUT EFI_HII_VALUE *Result\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
- CHAR16 *String[2];\r
- CHAR16 *Charset;\r
- UINTN Base;\r
- UINTN Index;\r
- CHAR16 *StringPtr;\r
- BOOLEAN Found;\r
-\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
-\r
- //\r
- // String[0] - Charset\r
- // String[1] - The string to search\r
- //\r
- String[0] = NULL;\r
- String[1] = NULL;\r
- for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- }\r
-\r
- if (Base >= StrLen (String[1])) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- Found = FALSE;\r
- StringPtr = String[1] + Base;\r
- Charset = String[0];\r
- while (*StringPtr != 0 && !Found) {\r
- Index = 0;\r
- while (Charset[Index] != 0) {\r
- if (*StringPtr >= Charset[Index] && *StringPtr <= Charset[Index + 1]) {\r
- if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {\r
- Found = TRUE;\r
- break;\r
- }\r
- } else {\r
- if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- //\r
- // Skip characters pair representing low-end of a range and high-end of a range\r
- //\r
- Index += 2;\r
- }\r
-\r
- if (!Found) {\r
- StringPtr++;\r
- }\r
- }\r
-\r
- Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Result->Value.u64 = StringPtr - String[1];\r
-\r
-Done:\r
- if (String[0] != NULL) {\r
- FreePool (String[0]);\r
- }\r
- if (String[1] != NULL) {\r
- FreePool (String[1]);\r
- } \r
-\r
- return Status;\r
-}\r
-\r
-\r
/**\r
Zero extend integer/boolean/date/time to UINT64 for comparing.\r
\r
\r
Value->Value.u64 = Temp;\r
}\r
-\r
-\r
-/**\r
- Compare two Hii value.\r
-\r
- @param Value1 Expression value to compare on left-hand\r
- @param Value2 Expression value to compare on right-hand\r
- @param HiiHandle Only required for string compare\r
-\r
- @retval EFI_INVALID_PARAMETER Could not perform comparation on two values\r
- @retval 0 Two operators equeal\r
- @retval 0 Value1 is greater than Value2\r
- @retval 0 Value1 is less than Value2\r
-\r
-**/\r
-INTN\r
-CompareHiiValue (\r
- IN EFI_HII_VALUE *Value1,\r
- IN EFI_HII_VALUE *Value2,\r
- IN EFI_HII_HANDLE HiiHandle OPTIONAL\r
- )\r
-{\r
- INTN Result;\r
- INT64 Temp64;\r
- CHAR16 *Str1;\r
- CHAR16 *Str2;\r
-\r
- if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
- if (Value1->Type != Value2->Type) {\r
- //\r
- // Both Operator should be type of String\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
- //\r
- // StringId 0 is reserved\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Value1->Value.string == Value2->Value.string) {\r
- return 0;\r
- }\r
-\r
- Str1 = GetToken (Value1->Value.string, HiiHandle);\r
- if (Str1 == NULL) {\r
- //\r
- // String not found\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Str2 = GetToken (Value2->Value.string, HiiHandle);\r
- if (Str2 == NULL) {\r
- gBS->FreePool (Str1);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Result = StrCmp (Str1, Str2);\r
-\r
- gBS->FreePool (Str1);\r
- gBS->FreePool (Str2);\r
-\r
- return Result;\r
- }\r
-\r
- //\r
- // Take remain types(integer, boolean, date/time) as integer\r
- //\r
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
- if (Temp64 > 0) {\r
- Result = 1;\r
- } else if (Temp64 < 0) {\r
- Result = -1;\r
- } else {\r
- Result = 0;\r
- }\r
-\r
- return Result;\r
-}\r
-\r
-\r
-/**\r
- Evaluate the result of a HII expression\r
-\r
- @param FormSet FormSet associated with this expression.\r
- @param Form Form associated with this expression.\r
- @param Expression Expression to be evaluated.\r
-\r
- @retval EFI_SUCCESS The expression evaluated successfuly\r
- @retval EFI_NOT_FOUND The Question which referenced by a QuestionId\r
- could not be found.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
- stack.\r
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
- @retval EFI_INVALID_PARAMETER Syntax error with the Expression\r
-\r
-**/\r
-EFI_STATUS\r
-EvaluateExpression (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form,\r
- IN OUT FORM_EXPRESSION *Expression\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- EXPRESSION_OPCODE *OpCode;\r
- FORM_BROWSER_STATEMENT *Question;\r
- FORM_BROWSER_STATEMENT *Question2;\r
- UINT16 Index;\r
- EFI_HII_VALUE Data1;\r
- EFI_HII_VALUE Data2;\r
- EFI_HII_VALUE Data3;\r
- FORM_EXPRESSION *RuleExpression;\r
- EFI_HII_VALUE *Value;\r
- INTN Result;\r
- CHAR16 *StrPtr;\r
- UINT32 TempValue;\r
-\r
- //\r
- // Always reset the stack before evaluating an Expression\r
- //\r
- ResetExpressionStack ();\r
-\r
- Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
-\r
- Link = GetFirstNode (&Expression->OpCodeListHead);\r
- while (!IsNull (&Expression->OpCodeListHead, Link)) {\r
- OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
-\r
- Link = GetNextNode (&Expression->OpCodeListHead, Link);\r
-\r
- ZeroMem (&Data1, sizeof (EFI_HII_VALUE));\r
- ZeroMem (&Data2, sizeof (EFI_HII_VALUE));\r
- ZeroMem (&Data3, sizeof (EFI_HII_VALUE));\r
-\r
- Value = &Data3;\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Status = EFI_SUCCESS;\r
-\r
- switch (OpCode->Operand) {\r
- //\r
- // Built-in functions\r
- //\r
- case EFI_IFR_EQ_ID_VAL_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_ID_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
- if (Question2 == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_LIST_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Value->Value.b = FALSE;\r
- for (Index =0; Index < OpCode->ListLength; Index++) {\r
- if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {\r
- Value->Value.b = TRUE;\r
- break;\r
- }\r
- }\r
- break;\r
-\r
- case EFI_IFR_DUP_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PushExpression (Value);\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF1_OP:\r
- case EFI_IFR_THIS_OP:\r
- Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Value = &Question->HiiValue;\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCode->DevicePath == 0) {\r
- //\r
- // EFI_IFR_QUESTION_REF3\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // push the questions' value on to the expression stack\r
- //\r
- Value = &Question->HiiValue;\r
- } else {\r
- //\r
- // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,\r
- // since it is impractical to evaluate the value of a Question in another\r
- // Hii Package list.\r
- //\r
- ZeroMem (Value, sizeof (EFI_HII_VALUE));\r
- }\r
- break;\r
-\r
- case EFI_IFR_RULE_REF_OP:\r
- //\r
- // Find expression for this rule\r
- //\r
- RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);\r
- if (RuleExpression == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Evaluate this rule expression\r
- //\r
- Status = EvaluateExpression (FormSet, Form, RuleExpression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Value = &RuleExpression->Result;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF1_OP:\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- Value->Value.string = OpCode->Value.Value.string;\r
- break;\r
-\r
- //\r
- // Constant\r
- //\r
- case EFI_IFR_TRUE_OP:\r
- case EFI_IFR_FALSE_OP:\r
- case EFI_IFR_ONE_OP:\r
- case EFI_IFR_ONES_OP:\r
- case EFI_IFR_UINT8_OP:\r
- case EFI_IFR_UINT16_OP:\r
- case EFI_IFR_UINT32_OP:\r
- case EFI_IFR_UINT64_OP:\r
- case EFI_IFR_UNDEFINED_OP:\r
- case EFI_IFR_VERSION_OP:\r
- case EFI_IFR_ZERO_OP:\r
- Value = &OpCode->Value;\r
- break;\r
-\r
- //\r
- // unary-op\r
- //\r
- case EFI_IFR_LENGTH_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = StrLen (StrPtr);\r
- gBS->FreePool (StrPtr);\r
- break;\r
-\r
- case EFI_IFR_NOT_OP:\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- Value->Value.b = (BOOLEAN) (!Value->Value.b);\r
- break;\r
-\r
- case EFI_IFR_QUESTION_REF2_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
- if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Value = &Question->HiiValue;\r
- break;\r
-\r
- case EFI_IFR_STRING_REF2_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_STRING;\r
- StrPtr = GetToken (Value->Value.u16, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- //\r
- // If String not exit, push an empty string\r
- //\r
- Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);\r
- } else {\r
- Index = (UINT16) Value->Value.u64;\r
- Value->Value.string = Index;\r
- gBS->FreePool (StrPtr);\r
- }\r
- break;\r
-\r
- case EFI_IFR_TO_BOOLEAN_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Convert an expression to a Boolean\r
- //\r
- if (Value->Type <= EFI_IFR_TYPE_DATE) {\r
- //\r
- // When converting from an unsigned integer, zero will be converted to\r
- // FALSE and any other value will be converted to TRUE.\r
- //\r
- Value->Value.b = (BOOLEAN) ((Value->Value.u64) ? TRUE : FALSE);\r
-\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- } else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
- //\r
- // When converting from a string, if case-insensitive compare\r
- // with "true" is True, then push True. If a case-insensitive compare\r
- // with "false" is True, then push False.\r
- //\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((StrCmp (StrPtr, L"true") == 0) || (StrCmp (StrPtr, L"false") == 0)){\r
- Value->Value.b = TRUE;\r
- } else {\r
- Value->Value.b = FALSE;\r
- }\r
- gBS->FreePool (StrPtr);\r
- Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
- }\r
- break;\r
-\r
- case EFI_IFR_TO_STRING_OP:\r
- Status = IfrToString (FormSet, OpCode->Format, Value);\r
- break;\r
-\r
- case EFI_IFR_TO_UINT_OP:\r
- Status = IfrToUint (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_TO_LOWER_OP:\r
- case EFI_IFR_TO_UPPER_OP:\r
- Status = InitializeUnicodeCollationProtocol ();\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {\r
- mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);\r
- } else {\r
- mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);\r
- }\r
- Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);\r
- gBS->FreePool (StrPtr);\r
- break;\r
-\r
- case EFI_IFR_BITWISE_NOT_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Value->Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = ~Value->Value.u64;\r
- break;\r
-\r
- //\r
- // binary-op\r
- //\r
- case EFI_IFR_ADD_OP:\r
- case EFI_IFR_SUBTRACT_OP:\r
- case EFI_IFR_MULTIPLY_OP:\r
- case EFI_IFR_DIVIDE_OP:\r
- case EFI_IFR_MODULO_OP:\r
- case EFI_IFR_BITWISE_AND_OP:\r
- case EFI_IFR_BITWISE_OR_OP:\r
- case EFI_IFR_SHIFT_LEFT_OP:\r
- case EFI_IFR_SHIFT_RIGHT_OP:\r
- //\r
- // Pop an expression from the expression stack\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
-\r
- switch (OpCode->Operand) {\r
- case EFI_IFR_ADD_OP:\r
- Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_SUBTRACT_OP:\r
- Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_MULTIPLY_OP:\r
- Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_DIVIDE_OP:\r
- Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_MODULO_OP:\r
- DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
- Value->Value.u64 = TempValue;\r
- break;\r
-\r
- case EFI_IFR_BITWISE_AND_OP:\r
- Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_BITWISE_OR_OP:\r
- Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
- break;\r
-\r
- case EFI_IFR_SHIFT_LEFT_OP:\r
- Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
- break;\r
-\r
- case EFI_IFR_SHIFT_RIGHT_OP:\r
- Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- break;\r
-\r
- case EFI_IFR_AND_OP:\r
- case EFI_IFR_OR_OP:\r
- //\r
- // Two Boolean operator\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (OpCode->Operand == EFI_IFR_AND_OP) {\r
- Value->Value.b = (BOOLEAN) (Data1.Value.b && Data2.Value.b);\r
- } else {\r
- Value->Value.b = (BOOLEAN) (Data1.Value.b || Data2.Value.b);\r
- }\r
- break;\r
-\r
- case EFI_IFR_EQUAL_OP:\r
- case EFI_IFR_NOT_EQUAL_OP:\r
- case EFI_IFR_GREATER_EQUAL_OP:\r
- case EFI_IFR_GREATER_THAN_OP:\r
- case EFI_IFR_LESS_EQUAL_OP:\r
- case EFI_IFR_LESS_THAN_OP:\r
- //\r
- // Compare two integer, string, boolean or date/time\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Pop another expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- switch (OpCode->Operand) {\r
- case EFI_IFR_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_NOT_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_GREATER_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result >= 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_GREATER_THAN_OP:\r
- Value->Value.b = (BOOLEAN) ((Result > 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_LESS_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result <= 0) ? TRUE : FALSE);\r
- break;\r
-\r
- case EFI_IFR_LESS_THAN_OP:\r
- Value->Value.b = (BOOLEAN) ((Result < 0) ? TRUE : FALSE);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- break;\r
-\r
- case EFI_IFR_MATCH_OP:\r
- Status = IfrMatch (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_CATENATE_OP:\r
- Status = IfrCatenate (FormSet, Value);\r
- break;\r
-\r
- //\r
- // ternary-op\r
- //\r
- case EFI_IFR_CONDITIONAL_OP:\r
- //\r
- // Pop third expression from the expression stack\r
- //\r
- Status = PopExpression (&Data3);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Pop second expression from the expression stack\r
- //\r
- Status = PopExpression (&Data2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Pop first expression from the expression stack\r
- //\r
- Status = PopExpression (&Data1);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Data1.Value.b) {\r
- Value = &Data3;\r
- } else {\r
- Value = &Data2;\r
- }\r
- break;\r
-\r
- case EFI_IFR_FIND_OP:\r
- Status = IfrFind (FormSet, OpCode->Format, Value);\r
- break;\r
-\r
- case EFI_IFR_MID_OP:\r
- Status = IfrMid (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_TOKEN_OP:\r
- Status = IfrToken (FormSet, Value);\r
- break;\r
-\r
- case EFI_IFR_SPAN_OP:\r
- Status = IfrSpan (FormSet, OpCode->Flags, Value);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = PushExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Pop the final result from expression stack\r
- //\r
- Value = &Data1;\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // After evaluating an expression, there should be only one value left on the expression stack\r
- //\r
- if (PopExpression (Value) != EFI_ACCESS_DENIED) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
-\r
- return EFI_SUCCESS;\r
-}\r
\r
#include "HiiDatabase.h"\r
#include "HiiHandle.h"\r
+#include <Library/DebugLib.h>\r
\r
-EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
-EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
\r
+/**\r
+ Find the corressponding UEFI HII Handle from a Framework HII Handle given.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param FwHiiHandle The Framemwork HII Handle.\r
\r
+ @return NULL If Framework HII Handle is invalid.\r
+ @return The corresponding UEFI HII Handle.\r
+**/\r
EFI_HII_HANDLE\r
FwHiiHandleToUefiHiiHandle (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
}\r
\r
\r
+/**\r
+ Find the corressponding HII Thunk Context from a Framework HII Handle given.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param FwHiiHandle The Framemwork HII Handle.\r
+\r
+ @return NULL If Framework HII Handle is invalid.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
FwHiiHandleToThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
+/**\r
+ Find the corressponding HII Thunk Context from a UEFI HII Handle given.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param UEFIHiiHandle The UEFI HII Handle.\r
+\r
+ @return NULL If UEFI HII Handle is invalid.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
UefiHiiHandleToThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
+/**\r
+ Find the corressponding HII Thunk Context from a Tag GUID.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param Guid The Tag GUID.\r
+\r
+ @return NULL No HII Thunk Context matched the Tag GUID.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
TagGuidToIfrPackThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
\r
}\r
\r
+/**\r
+ Clean up the HII Thunk Context for a UEFI HII Handle.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param UEFIHiiHandle The UEFI HII Handle.\r
\r
+**/\r
VOID\r
DestroyThunkContextForUefiHiiHandle (\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
\r
CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
\r
- InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
- InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
- \r
return ThunkContext;\r
}\r
\r
\r
+/**\r
+ Get the number of HII Package for a Package type.\r
+\r
+ @param PackageListHeader The Package List.\r
+ @param PackageType The Package Type.\r
+\r
+ @return The number of Package for given type.\r
+**/\r
UINTN\r
GetPackageCountByType (\r
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
return Count;\r
}\r
\r
-LIST_ENTRY *\r
-GetOneOfOptionMapEntryListHead (\r
- IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
- IN UINT16 QuestionId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- ONE_OF_OPTION_MAP *Map;\r
+/**\r
+ Get the Form Package from a Framework Package List.\r
\r
- Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
-\r
- while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {\r
- Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
- if (QuestionId == Map->QuestionId) {\r
- return &Map->OneOfOptionMapEntryListHead;\r
- }\r
- Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
- }\r
- \r
- return NULL;\r
-}\r
+ @param Packages Framework Package List.\r
\r
+ @return The Form Package Header found.\r
+**/\r
EFI_HII_PACKAGE_HEADER *\r
GetIfrPackage (\r
IN CONST EFI_HII_PACKAGES *Packages\r
return NULL;\r
}\r
\r
+/**\r
+ Get FormSet GUID.\r
+\r
+ ASSERT if no FormSet Opcode is found.\r
+\r
+ @param Packages Form Framework Package.\r
+ @param FormSetGuid Return the FormSet Guid.\r
+\r
+**/\r
VOID\r
GetFormSetGuid (\r
IN EFI_HII_PACKAGE_HEADER *Package,\r
\r
}\r
\r
+/**\r
+ Creat a Thunk Context.\r
+\r
+ ASSERT if no FormSet Opcode is found.\r
+\r
+ @param Private The HII Thunk Private Context.\r
+ @param StringPackageCount The String package count.\r
+ @param FormSetGuid The IFR Package count.\r
+\r
+ @return A newly created Thunk Context.\r
+ @retval NULL No resource to create a new Thunk Context.\r
+**/\r
+HII_THUNK_CONTEXT *\r
+CreateThunkContext (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN UINTN StringPackageCount,\r
+ IN UINTN IfrPackageCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
+ ASSERT (ThunkContext != NULL);\r
+ \r
+ ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
+ ThunkContext->IfrPackageCount = IfrPackageCount;\r
+ ThunkContext->StringPackageCount = StringPackageCount;\r
+ Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ return ThunkContext;\r
+ \r
+}\r
+\r
+/**\r
+ Destroy the Thunk Context and free up all resource.\r
\r
+ @param ThunkContext The HII Thunk Private Context to be freed.\r
+\r
+**/\r
VOID\r
-GetAttributesOfFirstFormSet (\r
- IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+DestroyThunkContext (\r
+ IN HII_THUNK_CONTEXT *ThunkContext\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGE_LIST_HEADER *List;\r
- EFI_HII_PACKAGE_HEADER *Package;\r
- UINTN Size;\r
- EFI_IFR_OP_HEADER *OpCode;\r
- UINTN Offset;\r
- EFI_IFR_GUID_CLASS *Class;\r
- EFI_IFR_FORM_SET *FormSet;\r
- EFI_IFR_GUID_SUBCLASS *SubClass;\r
+ ASSERT (ThunkContext != NULL);\r
\r
- Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
- ASSERT_EFI_ERROR (Status);\r
+ FreeHiiHandle (ThunkContext->FwHiiHandle);\r
\r
- //\r
- // There must be at least one EFI_HII_PACKAGE_FORMS in the package list.\r
- //\r
- ASSERT (GetPackageCountByType (List, EFI_HII_PACKAGE_FORMS) >= 1);\r
+ RemoveEntryList (&ThunkContext->Link);\r
+\r
+ if (ThunkContext->FormSet != NULL) {\r
+ DestroyFormSet (ThunkContext->FormSet);\r
+ }\r
+\r
+ FreePool (ThunkContext);\r
+}\r
+\r
+/**\r
+ Get the FormSet's Default Varstore ID based on the rule (Descending Priority):\r
+\r
+ 1) Var Store ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01).\r
+ 2) First Var Store ID.\r
+\r
+ @param FormSet The Form Set.\r
+ \r
+**/\r
+VOID\r
+GetFormsetDefaultVarstoreId (\r
+ IN OUT FORM_BROWSER_FORMSET * FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *StorageList;\r
+ FORMSET_STORAGE *Storage;\r
+ EFI_VARSTORE_ID FirstVarStoreId;\r
\r
//\r
- // Skip the package list header.\r
+ // VarStoreId 0 is invalid in UEFI IFR.\r
//\r
- Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
-\r
- while (Package->Type != EFI_HII_PACKAGE_END) {\r
+ FormSet->DefaultVarStoreId = 0;\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
\r
- if (Package->Type == EFI_HII_PACKAGE_FORMS) {\r
+ while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
\r
- //\r
- // Skip the package header\r
- //\r
- Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
- while (Offset < Package->Length) {\r
- OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
-\r
- switch (OpCode->OpCode) {\r
- case EFI_IFR_FORM_SET_OP:\r
- FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
- ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
- ThunkContext->FormSetHelp = FormSet->Help;\r
- break;\r
- \r
-\r
- case EFI_IFR_GUID_OP:\r
- Class = (EFI_IFR_GUID_CLASS*) OpCode;\r
- if (CompareGuid ((EFI_GUID *)(VOID *)&Class->Guid, &gTianoHiiIfrGuid)) {\r
- Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
-\r
- switch (Class->ExtendOpCode) {\r
- case EFI_IFR_EXTEND_OP_CLASS:\r
- ThunkContext->FormSetClass = Class->Class;\r
- break;\r
- case EFI_IFR_EXTEND_OP_SUBCLASS:\r
- SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
- ThunkContext->FormSetSubClass = SubClass->SubClass;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- break;\r
- \r
- default:\r
- break;\r
- \r
- }\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x\n", &FormSet->Guid, Storage->VarStoreId));\r
\r
- Offset += OpCode->Length;\r
- }\r
- //\r
- // The attributes of first FormSet is ready now.\r
- //\r
- FreePool (List);\r
- return;\r
- \r
+ if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {\r
+ FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
break;\r
}\r
\r
- Package = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) Package + Package->Length);\r
+ StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
+ }\r
+\r
+ if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
+ if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
+ FirstVarStoreId = Storage->VarStoreId;\r
+ }\r
+ \r
}\r
\r
+ DEBUG_CODE_BEGIN ();\r
+ if (FormSet->DefaultVarStoreId == 0) {\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: Default Varstore ID is %x\n", &FormSet->Guid, FormSet->DefaultVarStoreId));\r
+ }\r
+ DEBUG_CODE_END ();\r
+ \r
+ return;\r
}\r
\r
+/**\r
+ Fetch the Ifr binary data of a FormSet.\r
+\r
+ @param Handle PackageList Handle\r
+ @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
+ GUID), take the first FormSet found in package\r
+ list.\r
+ @param BinaryLength The length of the FormSet IFR binary.\r
+ @param BinaryData The buffer designed to receive the FormSet.\r
\r
+ @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
+ BufferLength was updated.\r
+ @retval EFI_INVALID_PARAMETER The handle is unknown.\r
+ @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
+ be found with the requested FormId.\r
+\r
+**/\r
EFI_STATUS\r
-CreateQuestionIdMap (\r
- IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+GetIfrBinaryData (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN OUT EFI_GUID *FormSetGuid,\r
+ OUT UINTN *BinaryLength,\r
+ OUT UINT8 **BinaryData\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGE_LIST_HEADER *List;\r
- EFI_HII_PACKAGE_HEADER *Package;\r
- UINTN Size;\r
- EFI_IFR_OP_HEADER *OpCode;\r
- UINTN Offset;\r
- QUESTION_ID_MAP *IdMap;\r
- EFI_IFR_VARSTORE *VarStore;\r
- EFI_IFR_FORM_SET *FormSet;\r
- EFI_IFR_QUESTION_HEADER *Question;\r
- LIST_ENTRY *QuestionIdMapEntryListHead;\r
- LIST_ENTRY *OneOfOptinMapEntryListHead;\r
- QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
- EFI_IFR_GUID_OPTIONKEY *OptionMap;\r
- ONE_OF_OPTION_MAP *OneOfOptionMap;\r
- ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
- EFI_IFR_GUID_CLASS *Class;\r
- EFI_IFR_GUID_SUBCLASS *SubClass;\r
- UINT8 OneOfType;\r
- EFI_IFR_ONE_OF *OneOfOpcode;\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ UINT8 *Package;\r
+ UINT8 *OpCodeData;\r
+ UINT32 Offset;\r
+ UINT32 Offset2;\r
+ BOOLEAN ReturnDefault;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+\r
+ OpCodeData = NULL;\r
+ Package = NULL;\r
+ ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
\r
//\r
- // Set to a invalid value.\r
+ // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
//\r
- OneOfType = (UINT8) -1;\r
- \r
-\r
- Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
+ ReturnDefault = TRUE;\r
+ } else {\r
+ ReturnDefault = FALSE;\r
}\r
\r
//\r
- // Get all VarStoreId and build the the QuestionId map.\r
- // EFI_IFR_QUESTION_HEADER.VarStoreInfo.VarOffset -> Framework Question ID\r
- // EFI_IFR_QUESTION_HEADER.QuestionId -> UEFI Question ID\r
+ // Get HII PackageList\r
//\r
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
//\r
- // Skip the package list header.\r
+ // Get Form package from this HII package List\r
//\r
- Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
-\r
- while (Package->Type != EFI_HII_PACKAGE_END) {\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
\r
- if (Package->Type == EFI_HII_PACKAGE_FORMS) {\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *) HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
//\r
- // Skip the package header\r
+ // Search FormSet in this Form Package\r
//\r
- Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
- while (Offset < Package->Length) {\r
- OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
-\r
- switch (OpCode->OpCode) {\r
- case EFI_IFR_FORM_SET_OP:\r
- FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
- ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
- ThunkContext->FormSetHelp = FormSet->Help;\r
- break;\r
- \r
- case EFI_IFR_VARSTORE_OP:\r
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset2 < PackageHeader.Length) {\r
+ OpCodeData = Package + Offset2;\r
+\r
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
//\r
- // IFR built from Framework VFR only has UEFI Buffer Type Storage\r
+ // Check whether return default FormSet\r
//\r
- VarStore = (EFI_IFR_VARSTORE *) OpCode;\r
- IdMap = AllocateZeroPool (sizeof (QUESTION_ID_MAP));\r
- ASSERT (IdMap != NULL);\r
- \r
- IdMap->Signature = QUESTION_ID_MAP_SIGNATURE;\r
- IdMap->VarStoreId = VarStore->VarStoreId;\r
- IdMap->VarSize = VarStore->Size;\r
- InitializeListHead (&IdMap->MapEntryListHead);\r
- InsertTailList (&ThunkContext->QuestionIdMapListHead, &IdMap->Link);\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
- case EFI_IFR_CHECKBOX_OP:\r
- case EFI_IFR_ONE_OF_OP:\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- case EFI_IFR_STRING_OP:\r
- //case EFI_IFR_PASSWORD_OP:\r
- Question = (EFI_IFR_QUESTION_HEADER *)(OpCode + 1);\r
- QuestionIdMapEntryListHead = GetMapEntryListHead (ThunkContext, Question->VarStoreId);\r
-\r
- if (QuestionIdMapEntryListHead != NULL) {\r
- //\r
- // If the Question is using Buffer (EFI_IFR_VARSTORE_OP) type VarStore.\r
- //\r
- IdMapEntry = AllocateZeroPool (sizeof (QUESTION_ID_MAP_ENTRY));\r
- ASSERT (IdMapEntry != NULL);\r
-\r
- IdMapEntry->FwQId = Question->VarStoreInfo.VarOffset;\r
- IdMapEntry->UefiQid = Question->QuestionId;\r
- IdMapEntry->Signature = QUESTION_ID_MAP_ENTRY_SIGNATURE;\r
-\r
- InsertTailList (QuestionIdMapEntryListHead, &IdMapEntry->Link);\r
- }\r
-\r
- if (OpCode->OpCode == EFI_IFR_ONE_OF_OP) {\r
- OneOfOpcode = (EFI_IFR_ONE_OF *) OpCode;\r
- OneOfType = OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE;\r
+ if (ReturnDefault) {\r
+ break;\r
}\r
\r
- break;\r
- \r
- case EFI_IFR_GUID_OP:\r
- OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCode;\r
- if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gFrameworkHiiCompatbilityGuid)) {\r
- if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {\r
- OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (ThunkContext, OptionMap->QuestionId);\r
- if (OneOfOptinMapEntryListHead == NULL) {\r
- OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
- ASSERT (OneOfOptionMap != NULL);\r
-\r
- OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
- OneOfOptionMap->QuestionId = OptionMap->QuestionId;\r
-\r
- //\r
- // Make sure OneOfType is initialized.\r
- //\r
- ASSERT (OneOfType != (UINT8) -1);\r
- OneOfOptionMap->ValueType = OneOfType;\r
- InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
- OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;\r
- InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
- }\r
- OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
- ASSERT (OneOfOptionMapEntry != NULL);\r
-\r
- OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
- OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;\r
- CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));\r
- \r
- InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);\r
- }\r
- } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gTianoHiiIfrGuid)) {\r
- Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
-\r
- switch (Class->ExtendOpCode) {\r
- case EFI_IFR_EXTEND_OP_CLASS:\r
- ThunkContext->FormSetClass = Class->Class;\r
- break;\r
- case EFI_IFR_EXTEND_OP_SUBCLASS:\r
- SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
- ThunkContext->FormSetSubClass = SubClass->SubClass;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
+ //\r
+ // FormSet GUID is specified, check it\r
+ //\r
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ break;\r
}\r
- break;\r
- \r
- default:\r
- break;\r
- \r
}\r
\r
- Offset += OpCode->Length;\r
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ }\r
+\r
+ if (Offset2 < PackageHeader.Length) {\r
+ //\r
+ // Target formset found\r
+ //\r
+ break;\r
}\r
- //\r
- // Only Form Package is in a Package List.\r
- //\r
- break;\r
}\r
\r
- Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;\r
+ Offset += PackageHeader.Length;\r
}\r
\r
- FreePool (List);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-LIST_ENTRY *\r
-GetMapEntryListHead (\r
- IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
- IN UINT16 VarStoreId\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- QUESTION_ID_MAP *Map;\r
-\r
- Link = GetFirstNode (&ThunkContext->QuestionIdMapListHead);\r
+ if (Offset >= PackageListLength) {\r
+ //\r
+ // Form package not found in this Package List\r
+ //\r
+ gBS->FreePool (HiiPackageList);\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- while (!IsNull (&ThunkContext->QuestionIdMapListHead, Link)) {\r
- Map = QUESTION_ID_MAP_FROM_LINK (Link);\r
- if (VarStoreId == Map->VarStoreId) {\r
- return &Map->MapEntryListHead;\r
- }\r
- Link = GetNextNode (&ThunkContext->QuestionIdMapListHead, Link);\r
+ if (ReturnDefault && FormSetGuid != NULL) {\r
+ //\r
+ // Return the default FormSet GUID\r
+ //\r
+ CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
}\r
- return NULL;\r
-}\r
\r
+ //\r
+ // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
+ // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
+ // of the Form Package.\r
+ //\r
+ *BinaryLength = PackageHeader.Length - Offset2;\r
+ *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
\r
-HII_THUNK_CONTEXT *\r
-CreateThunkContext (\r
- IN HII_THUNK_PRIVATE_DATA *Private,\r
- IN UINTN StringPackageCount,\r
- IN UINTN IfrPackageCount\r
- )\r
-{\r
- EFI_STATUS Status;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
+ gBS->FreePool (HiiPackageList);\r
\r
- ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
- ASSERT (ThunkContext != NULL);\r
- \r
- ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
- ThunkContext->IfrPackageCount = IfrPackageCount;\r
- ThunkContext->StringPackageCount = StringPackageCount;\r
- Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
+ if (*BinaryData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
- InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
-\r
-\r
- return ThunkContext;\r
- \r
+ return EFI_SUCCESS;\r
}\r
\r
-VOID\r
-DestroyThunkContext (\r
- IN HII_THUNK_CONTEXT *ThunkContext\r
- )\r
-{\r
- ASSERT (ThunkContext != NULL);\r
-\r
- FreeHiiHandle (ThunkContext->FwHiiHandle);\r
-\r
- DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
-\r
- DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
-\r
- RemoveEntryList (&ThunkContext->Link);\r
+/**\r
+ Initialize the internal data structure of a FormSet.\r
\r
- FreePool (ThunkContext);\r
-}\r
+ @param Handle PackageList Handle\r
+ @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
+ GUID), take the first FormSet found in package\r
+ list.\r
+ @param FormSet FormSet data structure.\r
\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
\r
-VOID\r
-DestroyQuestionIdMap (\r
- IN LIST_ENTRY *QuestionIdMapListHead\r
+**/\r
+EFI_STATUS\r
+InitializeFormSet (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN OUT EFI_GUID *FormSetGuid,\r
+ OUT FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
- QUESTION_ID_MAP *IdMap;\r
- QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *Link2;\r
-\r
- while (!IsListEmpty (QuestionIdMapListHead)) {\r
- Link = GetFirstNode (QuestionIdMapListHead);\r
- \r
- IdMap = QUESTION_ID_MAP_FROM_LINK (Link);\r
+ EFI_STATUS Status;\r
\r
- while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
- Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
- \r
- IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link2);\r
-\r
- RemoveEntryList (Link2);\r
+ Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- FreePool (IdMapEntry);\r
- }\r
+ FormSet->HiiHandle = Handle;\r
+ CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
\r
- RemoveEntryList (Link);\r
- FreePool (IdMap);\r
+ //\r
+ // Parse the IFR binary OpCodes\r
+ //\r
+ Status = ParseOpCodes (FormSet);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
+\r
+ GetFormsetDefaultVarstoreId (FormSet);\r
+ return Status;\r
}\r
\r
-VOID\r
-DestoryOneOfOptionMap (\r
- IN LIST_ENTRY *OneOfOptionMapListHead\r
- )\r
-{\r
- ONE_OF_OPTION_MAP *Map;\r
- ONE_OF_OPTION_MAP_ENTRY *MapEntry;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *Link2;\r
+/**\r
+ Parse the Form Package and build a FORM_BROWSER_FORMSET structure.\r
\r
- while (!IsListEmpty (OneOfOptionMapListHead)) {\r
- Link = GetFirstNode (OneOfOptionMapListHead);\r
- \r
- Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+ @param UefiHiiHandle PackageList Handle\r
\r
- while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
- Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
- \r
- MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
+ @return A pointer to FORM_BROWSER_FORMSET.\r
\r
- RemoveEntryList (Link2);\r
+**/\r
+FORM_BROWSER_FORMSET *\r
+ParseFormSet (\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+ EFI_GUID FormSetGuid;\r
+ EFI_STATUS Status;\r
+ \r
+ FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
+ ASSERT (FormSet != NULL);\r
\r
- FreePool (MapEntry);\r
- }\r
+ CopyGuid (&FormSetGuid, &gZeroGuid);\r
+ Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- RemoveEntryList (Link);\r
- FreePool (Map);\r
- }\r
+ return FormSet;\r
}\r
\r
-\r
-\r
-\r
IN HII_THUNK_CONTEXT *ThunkContext\r
);\r
\r
-VOID\r
-DestroyQuestionIdMap (\r
- IN LIST_ENTRY *QuestionIdMapListHead\r
- );\r
-\r
-\r
VOID\r
DestoryOneOfOptionMap (\r
IN LIST_ENTRY *OneOfOptionMapListHead\r
)\r
;\r
\r
+FORM_BROWSER_FORMSET *\r
+ParseFormSet (\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+;\r
+\r
#endif\r