}\r
\r
if (!EFI_ERROR (Status)) {\r
- Status = mUefiConfigRoutingProtocol->BlockToConfig (\r
- mUefiConfigRoutingProtocol,\r
+ Status = mHiiConfigRoutingProtocol->BlockToConfig (\r
+ mHiiConfigRoutingProtocol,\r
Request,\r
Data,\r
DataSize,\r
if (Data == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- Status = mUefiConfigRoutingProtocol->ConfigToBlock (\r
- mUefiConfigRoutingProtocol,\r
+ Status = mHiiConfigRoutingProtocol->ConfigToBlock (\r
+ mHiiConfigRoutingProtocol,\r
Configuration,\r
Data,\r
&LastModifiedByteIndex,\r
\r
#include "HiiDatabase.h"\r
\r
+\r
+UINT8 mGlyphBuffer[EFI_GLYPH_WIDTH * 2 * EFI_GLYPH_HEIGHT];\r
+\r
EFI_STATUS\r
EFIAPI\r
HiiGetGlyph (\r
--*/\r
{\r
ASSERT (FALSE);\r
- return EFI_SUCCESS;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
EFI_STATUS\r
)\r
{\r
ASSERT (FALSE);\r
- return EFI_SUCCESS;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
\r
#include "HiiDatabase.h"\r
+#include "UefiIfrDefault.h"\r
\r
EFI_STATUS\r
EFIAPI\r
return EFI_UNSUPPORTED;\r
}\r
\r
+\r
EFI_STATUS\r
EFIAPI\r
HiiGetDefaultImage (\r
\r
--*/\r
{\r
- return EFI_SUCCESS;\r
+ LIST_ENTRY *UefiDefaults;\r
+ EFI_HII_HANDLE UefiHiiHandle;\r
+ EFI_STATUS Status;\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+\r
+ Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+\r
+ UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
+ if (UefiHiiHandle == NULL) {\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ UefiDefaults = NULL;\r
+ Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = UefiDefaultsToFrameworkDefaults (UefiDefaults, DefaultMask, VariablePackList);\r
+\r
+Done:\r
+ FreeDefaultList (UefiDefaults);\r
+ \r
+ return Status;\r
}\r
\r
EFI_STATUS\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Status = mUefiHiiDatabaseProtocol->GetPackageListHandle (\r
- mUefiHiiDatabaseProtocol,\r
+ Status = mHiiDatabase->GetPackageListHandle (\r
+ mHiiDatabase,\r
HandleMapEntry->UefiHiiHandle,\r
&UefiDriverHandle\r
);\r
}\r
\r
EFI_STATUS\r
-Framework2UefiCreateSubtitleOpCode (\r
+F2UCreateSubtitleOpCode (\r
IN CONST FRAMEWORK_EFI_IFR_SUBTITLE *FwSubTitle,\r
OUT EFI_HII_UPDATE_DATA *UefiData\r
)\r
}\r
\r
EFI_STATUS\r
-Framework2UefiCreateTextOpCode (\r
+F2UCreateTextOpCode (\r
IN CONST FRAMEWORK_EFI_IFR_TEXT *FwText,\r
OUT EFI_HII_UPDATE_DATA *UefiData\r
)\r
for (Index = 0; Index < Data->DataCount; Index++) {\r
switch (FrameworkOpcodeBuffer->OpCode) {\r
case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
- Status = Framework2UefiCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);\r
+ Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);\r
break;\r
\r
case FRAMEWORK_EFI_IFR_TEXT_OP:\r
- Status = Framework2UefiCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer); \r
+ Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer); \r
break;\r
\r
default:\r
\r
return EFI_SUCCESS;\r
}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetPackageDataFromPackageList (\r
+ IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
+ IN UINT32 PackageIndex,\r
+ OUT UINT32 *BufferLen,\r
+ OUT EFI_HII_PACKAGE_HEADER **Buffer\r
+ )\r
+{\r
+ UINT32 Index;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINT32 Offset;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};\r
+\r
+ ASSERT(HiiPackageList != NULL);\r
+\r
+ if ((BufferLen == NULL) || (Buffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Package = NULL;\r
+ Index = 0;\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+ while (Offset < PackageListLength) {\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ if (Index == PackageIndex) {\r
+ break;\r
+ }\r
+ Offset += PackageHeader.Length;\r
+ Index++;\r
+ }\r
+ if (Offset >= PackageListLength) {\r
+ //\r
+ // no package found in this Package List\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *BufferLen = PackageHeader.Length;\r
+ *Buffer = Package;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Check if Label exist in the IFR form package.\r
+\r
+ @param \r
+\r
+**/\r
+EFI_STATUS\r
+LocateLabel (\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_FORM_LABEL Label,\r
+ OUT EFI_GUID *FormsetGuid,\r
+ OUT EFI_FORM_ID *FormId\r
+ )\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
+\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+ InternalFormId= 0;\r
+ ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));\r
+ GetFormSet = FALSE;\r
+ GetForm = FALSE;\r
+\r
+ while (Offset < Package->Length) {\r
+ switch (IfrOpHdr->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP :\r
+ CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));\r
+ GetFormSet = TRUE;\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));\r
+ GetForm = TRUE;\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
+ }\r
+ \r
+\r
+ break;\r
+ default :\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Go to the next Op-Code\r
+ //\r
+ Offset += IfrOpHdr->Length;\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.\r
+ \r
+ EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation\r
+ does not restrict labels with same label value to be duplicated in either FormSet \r
+ scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL\r
+ with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID \r
+ and Form ID is returned if such Label is found.\r
+\r
+ \r
+ @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.\r
+ @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or\r
+ There is no Form ID with value Label found in all Form Sets in the pacakge\r
+ list.\r
+ \r
+ @retval EFI_SUCCESS The first found Form ID is returned in FormId.\r
+**/\r
+EFI_STATUS\r
+ThunkLocateFormId (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_FORM_LABEL Label,\r
+ OUT EFI_GUID *FormsetGuid,\r
+ OUT EFI_FORM_ID *FormId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINT32 Index;\r
+ UINTN BufferSize;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINT32 PackageLength;\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
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ for (Index = 0; ; Index++) {\r
+ Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);\r
+ if (!EFI_ERROR (Status)) {\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
+ Status = LocateLabel (Package, Label, FormsetGuid, FormId);\r
+ if (!EFI_ERROR(Status)) {\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+\r
+ \r
+Done:\r
+ FreePool (HiiPackageList);\r
+ \r
+ return Status;\r
+}\r
EFI_STATUS\r
EFIAPI\r
HiiUpdateForm (\r
HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
EFI_HII_UPDATE_DATA *UefiHiiUpdateData;\r
EFI_HII_HANDLE UefiHiiHandle;\r
+ EFI_GUID FormsetGuid;\r
+ EFI_FORM_ID FormId;\r
\r
Status = EFI_SUCCESS;\r
\r
\r
ThunkFrameworkUpdateDataToUefiUpdateData (Data, AddData, &UefiHiiUpdateData);\r
\r
- Status = IfrLibUpdateForm (UefiHiiHandle, NULL, 0, Label, AddData, UefiHiiUpdateData);\r
+ Status = ThunkLocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);\r
ASSERT_EFI_ERROR (Status);\r
\r
if (UefiHiiUpdateData != NULL) {\r
#\r
\r
[Sources.common]\r
+ UefiIfrParserInternal.h\r
+ UefiIfrParserCommon.c\r
+ UefiIfrParserCommon.h\r
+ UefiIfrParser.c\r
+ UefiIfrParser.h\r
+ UefiIfrParserExpression.c\r
+ UefiIfrParserExpressionInternal.h\r
+ UefiIfrDefault.c\r
+ UefiIfrDefault.h\r
Keyboard.c\r
Fonts.c\r
Package.c\r
ConfigAccess.h\r
Utility.c\r
Utility.h\r
+ R8Lib.c\r
+ R8Lib.h\r
\r
\r
[Packages]\r
ExtendedHiiLib\r
IfrSupportLib\r
ExtendedIfrSupportLib\r
+ PrintLib\r
\r
[Protocols]\r
gEfiHiiProtocolGuid\r
gEfiHiiConfigRoutingProtocolGuid\r
gEfiHiiConfigAccessProtocolGuid\r
gEfiFormCallbackProtocolGuid\r
+ gEfiUnicodeCollation2ProtocolGuid\r
\r
[Depex]\r
gEfiHiiImageProtocolGuid AND\r
},\r
};\r
\r
-CONST EFI_HII_DATABASE_PROTOCOL *mUefiHiiDatabaseProtocol;\r
-CONST EFI_HII_FONT_PROTOCOL *mUefiHiiFontProtocol;\r
-CONST EFI_HII_IMAGE_PROTOCOL *mUefiHiiImageProtocol;\r
-CONST EFI_HII_STRING_PROTOCOL *mUefiStringProtocol;\r
-CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mUefiConfigRoutingProtocol;\r
+CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
+CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;\r
+CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
+CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
+CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
\r
\r
EFI_STATUS\r
Status = gBS->LocateProtocol (\r
&gEfiHiiDatabaseProtocolGuid,\r
NULL,\r
- (VOID **) &mUefiHiiDatabaseProtocol\r
+ (VOID **) &mHiiDatabase\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->LocateProtocol (\r
&gEfiHiiFontProtocolGuid,\r
NULL,\r
- (VOID **) &mUefiHiiFontProtocol\r
+ (VOID **) &mHiiFontProtocol\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->LocateProtocol (\r
&gEfiHiiImageProtocolGuid,\r
NULL,\r
- (VOID **) &mUefiHiiImageProtocol\r
+ (VOID **) &mHiiImageProtocol\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->LocateProtocol (\r
&gEfiHiiStringProtocolGuid,\r
NULL,\r
- (VOID **) &mUefiStringProtocol\r
+ (VOID **) &mHiiStringProtocol\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = gBS->LocateProtocol (\r
&gEfiHiiConfigRoutingProtocolGuid,\r
NULL,\r
- (VOID **) &mUefiConfigRoutingProtocol\r
+ (VOID **) &mHiiConfigRoutingProtocol\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
#include <Library/HiiLib.h>\r
#include <Library/ExtendedHiiLib.h>\r
\r
-//\r
-// There are some type redefinitions between Framework Ifr Support Library and \r
-// UEFI HII Ifr Support Library. We undefine the duplicated Framework definition here \r
-// so that the duplicated definitions in UEFI HII Ifr can be defined.\r
-// In this Thunk Module, we will access all Framework definition with "FRAMEWORK_" prefix.\r
-//\r
-#undef IFR_OPTION\r
-#undef EFI_HII_UPDATE_DATA\r
-\r
#include <Library/IfrSupportLib.h>\r
#include <Library/ExtendedIfrSupportLib.h>\r
\r
+#include <MdeModuleHii.h>\r
+\r
//\r
// Macros\r
//\r
//\r
// Extern Variables\r
//\r
-extern CONST EFI_HII_DATABASE_PROTOCOL *mUefiHiiDatabaseProtocol;\r
-extern CONST EFI_HII_FONT_PROTOCOL *mUefiHiiFontProtocol;\r
-extern CONST EFI_HII_IMAGE_PROTOCOL *mUefiHiiImageProtocol;\r
-extern CONST EFI_HII_STRING_PROTOCOL *mUefiStringProtocol;\r
-extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mUefiConfigRoutingProtocol;\r
+extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
+extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
+extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
\r
//\r
// Prototypes\r
\r
Size = 0;\r
PackageListHdr = NULL;\r
- Status = mUefiHiiDatabaseProtocol->ExportPackageLists (\r
- mUefiHiiDatabaseProtocol,\r
+ Status = mHiiDatabase->ExportPackageLists (\r
+ mHiiDatabase,\r
UefiHiiHandle,\r
&Size,\r
PackageListHdr\r
if (PackageListHeader == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
} else {\r
- Status = mUefiHiiDatabaseProtocol->ExportPackageLists (\r
- mUefiHiiDatabaseProtocol,\r
+ Status = mHiiDatabase->ExportPackageLists (\r
+ mHiiDatabase,\r
UefiHiiHandle,\r
&Size,\r
PackageListHdr\r
)\r
{\r
EFI_STATUS Status;\r
- Status = mUefiHiiDatabaseProtocol->UpdatePackageList (\r
- mUefiHiiDatabaseProtocol,\r
+ Status = mHiiDatabase->UpdatePackageList (\r
+ mHiiDatabase,\r
UefiHiiHandle,\r
StringPackageListHeader\r
);\r
return PackageListHeader; \r
}\r
\r
-EFI_GUID *\r
-UefiGeneratePackageListGuidId (\r
- IN CONST EFI_HII_PACKAGES * Packages\r
+VOID\r
+GenerateGuidId (\r
+ IN CONST EFI_GUID * InGuid,\r
+ OUT EFI_GUID * OutGuid\r
)\r
{\r
- EFI_GUID *Guid;\r
UINT64 MonotonicCount;\r
\r
- Guid = AllocateCopyPool (sizeof (EFI_GUID), Packages->GuidId);\r
+ CopyMem (OutGuid, InGuid, sizeof (EFI_GUID));\r
\r
gBS->GetNextMonotonicCount (&MonotonicCount);\r
//\r
// Use Monotonic Count as a psedo random number generator.\r
//\r
- *((UINT64 *) Guid) = *((UINT64 *) Guid) + MonotonicCount;\r
- \r
- return Guid;\r
+ *((UINT64 *) OutGuid) = *((UINT64 *) OutGuid) + MonotonicCount;\r
}\r
\r
EFI_STATUS\r
\r
}\r
\r
+CONST EFI_GUID mAGuid = \r
+ { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };\r
+\r
EFI_STATUS\r
UefiRegisterPackageList(\r
EFI_HII_THUNK_PRIVATE_DATA *Private,\r
UINTN IfrPackNum;\r
EFI_HII_PACKAGE_LIST_HEADER *UefiPackageListHeader;\r
HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
- EFI_GUID *GuidId;\r
+ EFI_GUID GuidId;\r
EFI_HANDLE UefiHiiDriverHandle;\r
\r
- GuidId = NULL;\r
UefiHiiDriverHandle = NULL;\r
\r
Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum);\r
ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack\r
+ //\r
+ if (IfrPackNum > 1) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
\r
HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
ASSERT (HandleMappingEntry != NULL);\r
\r
HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
HandleMappingEntry->FrameworkHiiHandle = Private->StaticHiiHandle++;\r
+\r
+ //\r
+ // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering\r
+ // package with StringPack and IfrPack.\r
+ //\r
+ if (Packages->GuidId == NULL) {\r
+ Packages->GuidId = &GuidId;\r
+ GenerateGuidId (&mAGuid, Packages->GuidId);\r
+ }\r
+ \r
CopyGuid (&HandleMappingEntry->TagGuid, Packages->GuidId);\r
\r
if ((StringPackNum == 0) && (IfrPackNum != 0)) {\r
// In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
// a PackageList with only IFR to a Package list the with String package.\r
//\r
- GuidId = UefiGeneratePackageListGuidId (Packages);\r
+ GenerateGuidId (Packages->GuidId, &GuidId);\r
}\r
\r
//\r
if (IfrPackNum != 0) {\r
InstallDefaultUefiConfigAccessProtocol (Packages, &UefiHiiDriverHandle, HandleMappingEntry);\r
}\r
- UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, GuidId);\r
- Status = mUefiHiiDatabaseProtocol->NewPackageList (\r
- mUefiHiiDatabaseProtocol,\r
+ UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
+ Status = mHiiDatabase->NewPackageList (\r
+ mHiiDatabase,\r
UefiPackageListHeader, \r
UefiHiiDriverHandle,\r
&HandleMappingEntry->UefiHiiHandle\r
}\r
\r
FreePool (UefiPackageListHeader);\r
- SafeFreePool (GuidId);\r
\r
return Status;\r
}\r
HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
\r
if (HandleMapEntry->UefiHiiHandle != NULL) {\r
- Status = mUefiHiiDatabaseProtocol->RemovePackageList (\r
- mUefiHiiDatabaseProtocol,\r
+ Status = mHiiDatabase->RemovePackageList (\r
+ mHiiDatabase,\r
HandleMapEntry->UefiHiiHandle\r
);\r
ASSERT_EFI_ERROR (Status);\r
--- /dev/null
+/**@file
+ Copyright (c) 2007, Intel Corporation
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include <PiDxe.h>
+#include "R8Lib.h"
+
+CHAR16
+NibbleToHexChar (
+ IN UINT8 Nibble
+ )
+/*++
+
+ Routine Description:
+ Converts the low nibble of a byte to hex unicode character.
+
+ Arguments:
+ Nibble - lower nibble of a byte.
+
+ Returns:
+ Hex unicode character.
+
+--*/
+{
+ Nibble &= 0x0F;
+ if (Nibble <= 0x9) {
+ return (CHAR16)(Nibble + L'0');
+ }
+
+ return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+
+
+/**
+ Converts binary buffer to Unicode string.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ @param Str Pointer to the string.
+ @param HexStringBufferLength Length in bytes of buffer to hold the hex string.
+ Includes tailing '\0' character. If routine return
+ with EFI_SUCCESS, containing length of hex string
+ buffer. If routine return with
+ EFI_BUFFER_TOO_SMALL, containg length of hex
+ string buffer desired.
+ @param Buf Buffer to be converted from.
+ @param Len Length in bytes of the buffer to be converted.
+
+ @retval EFI_SUCCESS Routine success.
+ @retval EFI_BUFFER_TOO_SMALL The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ )
+{
+ //
+ // Porting Guide:
+ // This library interface is simply obsolete.
+ // Include the source code to user code.
+ //
+ UINTN Idx;
+ UINT8 Byte;
+ UINTN StrLen;
+
+ //
+ // Make sure string is either passed or allocate enough.
+ // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+ // Plus the Unicode termination character.
+ //
+ StrLen = Len * 2;
+ if (StrLen > ((*HexStringBufferLength) - 1)) {
+ *HexStringBufferLength = StrLen + 1;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *HexStringBufferLength = StrLen + 1;
+ //
+ // Ends the string.
+ //
+ Str[StrLen] = L'\0';
+
+ for (Idx = 0; Idx < Len; Idx++) {
+
+ Byte = Buf[Idx];
+ Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+ Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+/**
+ Converts Unicode string to binary buffer.
+ The conversion may be partial.
+ The first character in the string that is not hex digit stops the conversion.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ @param Buf Pointer to buffer that receives the data.
+ @param Len Length in bytes of the buffer to hold converted
+ data. If routine return with EFI_SUCCESS,
+ containing length of converted data. If routine
+ return with EFI_BUFFER_TOO_SMALL, containg length
+ of buffer desired.
+ @param Str String to be converted from.
+ @param ConvertedStrLen Length of the Hex String consumed.
+
+ @retval EFI_SUCCESS Routine Success.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ )
+{
+ //
+ // Porting Guide:
+ // This library interface is simply obsolete.
+ // Include the source code to user code.
+ //
+
+ UINTN HexCnt;
+ UINTN Idx;
+ UINTN BufferLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Find out how many hex characters the string has.
+ //
+ for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+ if (HexCnt == 0) {
+ *Len = 0;
+ return EFI_SUCCESS;
+ }
+ //
+ // Two Unicode characters make up 1 buffer byte. Round up.
+ //
+ BufferLength = (HexCnt + 1) / 2;
+
+ //
+ // Test if buffer is passed enough.
+ //
+ if (BufferLength > (*Len)) {
+ *Len = BufferLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Len = BufferLength;
+
+ for (Idx = 0; Idx < HexCnt; Idx++) {
+
+ R8_IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+ //
+ // For odd charaters, write the lower nibble for each buffer byte,
+ // and for even characters, the upper nibble.
+ //
+ if ((Idx & 1) == 0) {
+ Byte = Digit;
+ } else {
+ Byte = Buf[Idx / 2];
+ Byte &= 0x0F;
+ Byte = (UINT8) (Byte | Digit << 4);
+ }
+
+ Buf[Idx / 2] = Byte;
+ }
+
+ if (ConvertedStrLen != NULL) {
+ *ConvertedStrLen = HexCnt;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+/**
+ Determines if a Unicode character is a hexadecimal digit.
+ The test is case insensitive.
+
+ @param Digit Pointer to byte that receives the value of the hex
+ character.
+ @param Char Unicode character to test.
+
+ @retval TRUE If the character is a hexadecimal digit.
+ @retval FALSE Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+ OUT UINT8 *Digit,
+ IN CHAR16 Char
+ )
+{
+ //
+ // Porting Guide:
+ // This library interface is simply obsolete.
+ // Include the source code to user code.
+ //
+
+ if ((Char >= L'0') && (Char <= L'9')) {
+ *Digit = (UINT8) (Char - L'0');
+ return TRUE;
+ }
+
+ if ((Char >= L'A') && (Char <= L'F')) {
+ *Digit = (UINT8) (Char - L'A' + 0x0A);
+ return TRUE;
+ }
+
+ if ((Char >= L'a') && (Char <= L'f')) {
+ *Digit = (UINT8) (Char - L'a' + 0x0A);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
--- /dev/null
+/**@file
+ Copyright (c) 2007, Intel Corporation
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+
+/**
+ Converts binary buffer to Unicode string.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ @param Str Pointer to the string.
+ @param HexStringBufferLength Length in bytes of buffer to hold the hex string.
+ Includes tailing '\0' character. If routine return
+ with EFI_SUCCESS, containing length of hex string
+ buffer. If routine return with
+ EFI_BUFFER_TOO_SMALL, containg length of hex
+ string buffer desired.
+ @param Buf Buffer to be converted from.
+ @param Len Length in bytes of the buffer to be converted.
+
+ @retval EFI_SUCCESS Routine success.
+ @retval EFI_BUFFER_TOO_SMALL The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ )
+;
+
+
+
+
+/**
+ Converts Unicode string to binary buffer.
+ The conversion may be partial.
+ The first character in the string that is not hex digit stops the conversion.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ @param Buf Pointer to buffer that receives the data.
+ @param Len Length in bytes of the buffer to hold converted
+ data. If routine return with EFI_SUCCESS,
+ containing length of converted data. If routine
+ return with EFI_BUFFER_TOO_SMALL, containg length
+ of buffer desired.
+ @param Str String to be converted from.
+ @param ConvertedStrLen Length of the Hex String consumed.
+
+ @retval EFI_SUCCESS Routine Success.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ )
+;
+
+
+
+
+/**
+ Determines if a Unicode character is a hexadecimal digit.
+ The test is case insensitive.
+
+ @param Digit Pointer to byte that receives the value of the hex
+ character.
+ @param Char Unicode character to test.
+
+ @retval TRUE If the character is a hexadecimal digit.
+ @retval FALSE Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+ OUT UINT8 *Digit,
+ IN CHAR16 Char
+ )
+;
+
+
if (AsciiLanguage == NULL) {\r
return HiiLibGetString (HandleMapEntry->UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);\r
} else {\r
- return mUefiStringProtocol->GetString (\r
- mUefiStringProtocol,\r
+ return mHiiStringProtocol->GetString (\r
+ mHiiStringProtocol,\r
AsciiLanguage,\r
HandleMapEntry->UefiHiiHandle,\r
Token,\r
--- /dev/null
+/** @file\r
+ Function and Macro defintions for to extract default values from UEFI Form package.\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include <FrameworkDxe.h>\r
+\r
+#include <Protocol/FrameworkHii.h>\r
+#include <Protocol/HiiDatabase.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrDefault.h"\r
+\r
+//\r
+// Extern Variables\r
+//\r
+extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\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_FORM) {\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
+ @param Node The Buffer Storage Node.\r
+ @param Value The input value.\r
+ @param Offset The offset in Node->Buffer for the update.\r
+ @param Width The length of the Value.\r
+ \r
+ @retval VOID\r
+\r
+**/\r
+VOID\r
+SetNodeBuffer (\r
+ OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node,\r
+ IN CONST EFI_HII_VALUE *Value,\r
+ IN UINTN Offset,\r
+ IN UINTN Width\r
+ )\r
+{\r
+ ASSERT (Node->Signature == UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE);\r
+ ASSERT (Offset + Width <= Node->Size);\r
+\r
+ CopyMem (Node->Buffer + Offset, &Value->Value.u8, Width);\r
+}\r
+\r
+\r
+/**\r
+ Reset Question to its default value.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param DefaultId The Class of the default.\r
+\r
+ @retval EFI_SUCCESS Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetQuestionDefault (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN UINT16 DefaultId,\r
+ IN UINT16 VarStoreId,\r
+ OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ QUESTION_DEFAULT *Default;\r
+ QUESTION_OPTION *Option;\r
+ EFI_HII_VALUE *HiiValue;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Statement don't have storage, skip them\r
+ //\r
+ if (Question->QuestionId == 0) {\r
+ return Status;\r
+ }\r
+\r
+ if (Question->VarStoreId != VarStoreId) {\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
+\r
+ //\r
+ // There are three ways to specify default value for a Question:\r
+ // 1, use nested EFI_IFR_DEFAULT (highest priority)\r
+ // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
+ // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
+ //\r
+ HiiValue = &Question->HiiValue;\r
+\r
+ //\r
+ // EFI_IFR_DEFAULT has highest priority\r
+ //\r
+ if (!IsListEmpty (&Question->DefaultListHead)) {\r
+ Link = GetFirstNode (&Question->DefaultListHead);\r
+ while (!IsNull (&Question->DefaultListHead, Link)) {\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
+ SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Link = GetNextNode (&Question->DefaultListHead, Link);\r
+ }\r
+ }\r
+\r
+ //\r
+ // EFI_ONE_OF_OPTION\r
+ //\r
+ if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
+ if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // OneOfOption could only provide Standard and Manufacturing default\r
+ //\r
+ Link = GetFirstNode (&Question->OptionListHead);\r
+ while (!IsNull (&Question->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+ if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Option->Flags & EFI_IFR_OPTION_DEFAULT)) ||\r
+ ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG))\r
+ ) {\r
+ CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
+\r
+ SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Link = GetNextNode (&Question->OptionListHead, Link);\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // EFI_IFR_CHECKBOX - lowest priority\r
+ //\r
+ if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
+ if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // Checkbox could only provide Standard and Manufacturing default\r
+ //\r
+ if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT)) ||\r
+ ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG))\r
+ ) {\r
+ HiiValue->Value.b = TRUE;\r
+ } else {\r
+ HiiValue->Value.b = FALSE;\r
+ }\r
+\r
+ SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Reset Questions in a Form to their default value.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form The Form which to be reset.\r
+ @param DefaultId The Class of the default.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ExtractFormDefault (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN UINT16 DefaultId,\r
+ IN UINT16 VarStoreId,\r
+ OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+\r
+ //\r
+ // Reset Question to its default value\r
+ //\r
+ Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, VarStoreId, Node);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Destroy all the buffer allocated for the fileds of\r
+ UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself\r
+ will be freed too.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param DefaultId The Class of the default.\r
+\r
+ @retval VOID\r
+\r
+**/\r
+VOID\r
+DestroyDefaultNode (\r
+ IN UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
+ )\r
+{\r
+ SafeFreePool (Node->Buffer);\r
+ SafeFreePool (Node->Name);\r
+ SafeFreePool (Node);\r
+}\r
+\r
+\r
+/**\r
+ Get the default value for Buffer Type storage named by\r
+ a Default Store and a Storage Store from a FormSet.\r
+ The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ allocated by this function. It is inserted to the link list.\r
+ \r
+ @param DefaultStore The Default Store.\r
+ @param Storage The Storage.\r
+ @param FormSet The Form Set.\r
+ @param UefiDefaultsListHead The head of link list for the output.\r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ \r
+**/\r
+EFI_STATUS\r
+GetBufferTypeDefaultIdAndStorageId (\r
+ IN FORMSET_DEFAULTSTORE *DefaultStore,\r
+ IN FORMSET_STORAGE *Storage,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ OUT LIST_ENTRY *UefiDefaultsListHead\r
+ )\r
+{\r
+ UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+ EFI_STATUS Status;\r
+\r
+ Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE));\r
+ ASSERT (Node != NULL);\r
+\r
+ Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE;\r
+ Node->Name = AllocateCopyPool (StrSize (Storage->Name), Storage->Name);\r
+ Node->DefaultId = DefaultStore->DefaultId;\r
+ CopyGuid (&Node->Guid, &Storage->Guid);\r
+ Node->Size = Storage->Size;\r
+ Node->Buffer = AllocateZeroPool (Node->Size);\r
+ //\r
+ // Extract default from IFR binary\r
+ //\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ Status = ExtractFormDefault (FormSet, Form, DefaultStore->DefaultId, Storage->VarStoreId, Node);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ }\r
+\r
+ InsertTailList (UefiDefaultsListHead, &Node->List);\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Get the default value for Buffer Type storage named by\r
+ a Default Store from a FormSet.\r
+ The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ allocated by this function. The output can be multiple instances\r
+ of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.\r
+ \r
+ @param DefaultStore The Default Store.\r
+ @param FormSet The Form Set.\r
+ @param UefiDefaultsListHead The head of link list for the output.\r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ \r
+**/\r
+EFI_STATUS\r
+GetBufferTypeDefaultId (\r
+ IN FORMSET_DEFAULTSTORE *DefaultStore,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ OUT LIST_ENTRY *UefiDefaultsListHead\r
+ )\r
+{\r
+ LIST_ENTRY *StorageListEntry;\r
+ FORMSET_STORAGE *Storage;\r
+ EFI_STATUS Status;\r
+\r
+ StorageListEntry = GetFirstNode (&FormSet->StorageListHead);\r
+\r
+ while (!IsNull (&FormSet->StorageListHead, StorageListEntry)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK(StorageListEntry);\r
+\r
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+ Status = GetBufferTypeDefaultIdAndStorageId (DefaultStore, Storage, FormSet, UefiDefaultsListHead);\r
+ }\r
+\r
+ StorageListEntry = GetNextNode (&FormSet->StorageListHead, StorageListEntry);\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Get the default value for Buffer Type storage from the first FormSet\r
+ in the Package List specified by a EFI_HII_HANDLE.\r
+ \r
+ The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
+ They are inserted to the link list.\r
+ \r
+ @param UefiHiiHandle The handle for the package list.\r
+ @param UefiDefaultsListHead The head of link list for the output.\r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ \r
+**/\r
+EFI_STATUS\r
+UefiIfrGetBufferTypeDefaults (\r
+ IN EFI_HII_HANDLE UefiHiiHandle,\r
+ OUT LIST_ENTRY **UefiDefaults\r
+ )\r
+{\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+ EFI_GUID FormSetGuid;\r
+ LIST_ENTRY *DefaultListEntry;\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
+ DefaultListEntry = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+ while (!IsNull (&FormSet->DefaultStoreListHead, DefaultListEntry)) {\r
+ DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultListEntry);\r
+\r
+ Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ DefaultListEntry = GetNextNode (&FormSet->DefaultStoreListHead, DefaultListEntry); \r
+ }\r
+\r
+ DestroyFormSet (FormSet);\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Convert the UEFI Buffer Type default values to a Framework HII default\r
+ values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
+ \r
+ @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ which contains the default values retrived from\r
+ a UEFI form set.\r
+ @param DefaultMask The default mask.\r
+ The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+ and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+ UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+ from specification to valid default class.\r
+ @param VariablePackList The output default value in a format defined in Framework.\r
+ \r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+ FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+EFI_STATUS\r
+UefiDefaultsToFrameworkDefaults (\r
+ IN LIST_ENTRY *ListHead,\r
+ IN UINTN DefaultMask,\r
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
+ )\r
+{\r
+ LIST_ENTRY *List;\r
+ UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
+ UINTN Size;\r
+ UINTN Count;\r
+ UINT16 DefaultId;\r
+ EFI_HII_VARIABLE_PACK *Pack;\r
+ EFI_HII_VARIABLE_PACK_LIST *PackList;\r
+\r
+ if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_DEFAULT) {\r
+ DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ } else if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING) {\r
+ DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ } else {\r
+ //\r
+ // UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+ // from specification to valid default class.\r
+ //\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ //\r
+ // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure\r
+ //\r
+ Size = 0;\r
+ Count = 0;\r
+ List = GetFirstNode (ListHead);\r
+ while (!IsNull (ListHead, List)) {\r
+ Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
+\r
+ if (Node->DefaultId == DefaultId) {\r
+ Size += Node->Size;\r
+ Size += StrSize (Node->Name);\r
+\r
+ Count++;\r
+ }\r
+ \r
+ List = GetNextNode (ListHead, List); \r
+ }\r
+\r
+ Size = Size + Count * (sizeof (EFI_HII_VARIABLE_PACK_LIST) + sizeof (EFI_HII_VARIABLE_PACK));\r
+ \r
+ *VariablePackList = AllocateZeroPool (Size);\r
+ ASSERT (*VariablePackList != NULL);\r
+\r
+ List = GetFirstNode (ListHead);\r
+\r
+ PackList = (EFI_HII_VARIABLE_PACK_LIST *) *VariablePackList;\r
+ Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);\r
+ while (!IsNull (ListHead, List)) {\r
+ Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
+\r
+ Size = 0; \r
+ if (Node->DefaultId == DefaultId) {\r
+ Size += Node->Size;\r
+ Size += StrSize (Node->Name);\r
+ Size += sizeof (EFI_HII_VARIABLE_PACK); \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 0xFFEE.\r
+ //\r
+ if (Node->StoreId == 0xFFEE) {\r
+ Pack->VariableId = 0;\r
+ }\r
+ //\r
+ // Initialize EFI_HII_VARIABLE_PACK\r
+ //\r
+ Pack->Header.Type = 0;\r
+ Pack->Header.Length = Size;\r
+ Pack->VariableId = Node->StoreId;\r
+ Pack->VariableNameLength = StrSize (Node->Name);\r
+ CopyMem (&Pack->VariableGuid, &Node->Guid, sizeof (EFI_GUID));\r
+ \r
+ CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK), Node->Name, StrSize (Node->Name));\r
+ CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK) + Pack->VariableNameLength, Node->Buffer, Node->Size);\r
+\r
+ Size += sizeof (EFI_HII_VARIABLE_PACK_LIST);\r
+\r
+ //\r
+ // initialize EFI_HII_VARIABLE_PACK_LIST\r
+ //\r
+ PackList->VariablePack = Pack;\r
+ PackList->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *)((UINT8 *) PackList + Size);\r
+ \r
+ }\r
+ \r
+ List = GetNextNode (ListHead, List); \r
+ }\r
+ \r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
+ \r
+ @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ which contains the default values retrived from\r
+ a UEFI form set.\r
+ \r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+ FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+VOID\r
+FreeDefaultList (\r
+ IN LIST_ENTRY *ListHead\r
+ )\r
+{\r
+ LIST_ENTRY *Node;\r
+ UEFI_IFR_BUFFER_STORAGE_NODE *Default;\r
+\r
+ Node = GetFirstNode (ListHead);\r
+ \r
+ while (!IsNull (ListHead, Node)) {\r
+ Default = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Node);\r
+\r
+ RemoveEntryList (Node);\r
+ \r
+ DestroyDefaultNode (Default);\r
+ \r
+ Node = GetFirstNode (ListHead);\r
+ }\r
+\r
+ FreePool (ListHead);\r
+}\r
+\r
--- /dev/null
+/** @file\r
+ Header file for Function and Macro defintions for to extract default values from UEFI Form package.\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_DEFAULT_\r
+#define _HII_THUNK_UEFI_IFR_DEFAULT_\r
+\r
+\r
+#define UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(a) CR(a, UEFI_IFR_BUFFER_STORAGE_NODE, List, UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE)\r
+#define UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE EFI_SIGNATURE_32 ('I', 'b', 'S', 'n')\r
+typedef struct {\r
+ LIST_ENTRY List;\r
+ UINT32 Signature;\r
+\r
+ EFI_GUID Guid;\r
+ CHAR16 *Name;\r
+ UINT16 DefaultId;\r
+ UINT16 StoreId;\r
+ UINTN Size;\r
+ UINT8 *Buffer;\r
+ \r
+} UEFI_IFR_BUFFER_STORAGE_NODE;\r
+\r
+/**\r
+ Get the default value for Buffer Type storage from the first FormSet\r
+ in the Package List specified by a EFI_HII_HANDLE.\r
+ \r
+ The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
+ They are inserted to the link list.\r
+ \r
+ @param UefiHiiHandle The handle for the package list.\r
+ @param UefiDefaultsListHead The head of link list for the output.\r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ \r
+**/\r
+EFI_STATUS\r
+UefiIfrGetBufferTypeDefaults (\r
+ EFI_HII_HANDLE UefiHiiHandle,\r
+ LIST_ENTRY **UefiDefaults\r
+);\r
+\r
+/**\r
+ Convert the UEFI Buffer Type default values to a Framework HII default\r
+ values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
+ \r
+ @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ which contains the default values retrived from\r
+ a UEFI form set.\r
+ @param DefaultMask The default mask.\r
+ The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+ and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+ UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+ from specification to valid default class.\r
+ @param VariablePackList The output default value in a format defined in Framework.\r
+ \r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+ FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+\r
+EFI_STATUS\r
+UefiDefaultsToFrameworkDefaults (\r
+ IN LIST_ENTRY *UefiIfrDefaults,\r
+ IN UINTN DefaultMask,\r
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
+ )\r
+;\r
+\r
+/**\r
+ Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
+ \r
+ @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+ which contains the default values retrived from\r
+ a UEFI form set.\r
+ \r
+\r
+ @retval EFI_SUCCESS Successful.\r
+ @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+ FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+VOID\r
+FreeDefaultList (\r
+ IN LIST_ENTRY *UefiIfrDefaults\r
+ )\r
+;\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+/** @file\r
+Parser for IFR binary encoding.\r
+\r
+Copyright (c) 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrParserExpression.h"\r
+#include "UefiIfrParserInternal.h"\r
+#include "UefiIfrParserCommon.h"\r
+\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 gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+\r
+/**\r
+ Initialize Statement header members.\r
+\r
+ @param OpCodeData Pointer of the raw OpCode data.\r
+ @param FormSet Pointer of the current FormSe.\r
+ @param Form Pointer of the current Form.\r
+\r
+ @return The Statement.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+CreateStatement (\r
+ IN UINT8 *OpCodeData,\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet,\r
+ IN OUT FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
+\r
+ if (Form == NULL) {\r
+ //\r
+ // We are currently not in a Form Scope, so just skip this Statement\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ Statement = &FormSet->StatementBuffer[mStatementIndex];\r
+ mStatementIndex++;\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
+ Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
+\r
+ StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\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
+ // Insert this Statement into current Form\r
+ //\r
+ InsertTailList (&Form->StatementListHead, &Statement->Link);\r
+\r
+ return Statement;\r
+}\r
+\r
+\r
+/**\r
+ Initialize Question's members.\r
+\r
+ @param OpCodeData Pointer of the raw OpCode data.\r
+ @param FormSet Pointer of the current FormSet.\r
+ @param Form Pointer of the current Form.\r
+\r
+ @return The Question.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+CreateQuestion (\r
+ IN UINT8 *OpCodeData,\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet,\r
+ IN OUT FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ FORM_BROWSER_STATEMENT *Statement;\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
+ return NULL;\r
+ }\r
+\r
+ QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
+ CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
+ CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+ CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
+\r
+ Statement->QuestionFlags = QuestionHdr->Flags;\r
+\r
+ if (Statement->VarStoreId == 0) {\r
+ //\r
+ // VarStoreId of zero indicates no variable storage\r
+ //\r
+ return Statement;\r
+ }\r
+\r
+ //\r
+ // Find Storage for this Question\r
+ //\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+\r
+ if (Storage->VarStoreId == Statement->VarStoreId) {\r
+ Statement->Storage = Storage;\r
+ break;\r
+ }\r
+\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\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
+ @param FormSet Pointer of the current FormSet\r
+\r
+ @return Pointer to a FORMSET_STORAGE data structure.\r
+\r
+**/\r
+FORMSET_STORAGE *\r
+CreateStorage (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ FORMSET_STORAGE *Storage;\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
+ SafeFreePool (OpCode->ValueList);\r
+ }\r
+\r
+ //\r
+ // Free this Expression\r
+ //\r
+ gBS->FreePool (Expression);\r
+}\r
+\r
+\r
+/**\r
+ Free resources of a storage\r
+\r
+ @param Storage Pointer of the storage\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+DestroyStorage (\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
+ SafeFreePool (Storage->Name);\r
+ SafeFreePool (Storage->Buffer);\r
+ SafeFreePool (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
+ SafeFreePool (NameValueNode->Name);\r
+ SafeFreePool (NameValueNode->Value);\r
+ SafeFreePool (NameValueNode->EditValue);\r
+ SafeFreePool (NameValueNode);\r
+ }\r
+\r
+ SafeFreePool (Storage->ConfigHdr);\r
+ SafeFreePool (Storage->ConfigRequest);\r
+\r
+ gBS->FreePool (Storage);\r
+}\r
+\r
+\r
+/**\r
+ Free resources of a Statement\r
+\r
+ @param Statement Pointer of the Statement\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+DestroyStatement (\r
+ IN OUT FORM_BROWSER_STATEMENT *Statement\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
+ //\r
+ while (!IsListEmpty (&Statement->DefaultListHead)) {\r
+ Link = GetFirstNode (&Statement->DefaultListHead);\r
+ Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
+ RemoveEntryList (&Default->Link);\r
+\r
+ gBS->FreePool (Default);\r
+ }\r
+\r
+ //\r
+ // Free Options List\r
+ //\r
+ while (!IsListEmpty (&Statement->OptionListHead)) {\r
+ Link = GetFirstNode (&Statement->OptionListHead);\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ RemoveEntryList (&Option->Link);\r
+\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
+ SafeFreePool (Statement->VariableName);\r
+ SafeFreePool (Statement->BlockName);\r
+}\r
+\r
+\r
+/**\r
+ Free resources of a Form\r
+\r
+ @param Form Pointer of the Form\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+DestroyForm (\r
+ IN OUT FORM_BROWSER_FORM *Form\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
+ while (!IsListEmpty (&Form->StatementListHead)) {\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ RemoveEntryList (&Statement->Link);\r
+\r
+ DestroyStatement (Statement);\r
+ }\r
+\r
+ //\r
+ // Free this Form\r
+ //\r
+ gBS->FreePool (Form);\r
+}\r
+\r
+\r
+/**\r
+ Free resources allocated for a FormSet\r
+\r
+ @param FormSet Pointer of the FormSet\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+DestroyFormSet (\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORMSET_STORAGE *Storage;\r
+ FORMSET_DEFAULTSTORE *DefaultStore;\r
+ FORM_BROWSER_FORM *Form;\r
+\r
+ //\r
+ // Free IFR binary buffer\r
+ //\r
+ SafeFreePool (FormSet->IfrBinaryData);\r
+\r
+ //\r
+ // Free FormSet Storage\r
+ //\r
+ if (FormSet->StorageListHead.ForwardLink != NULL) {\r
+ while (!IsListEmpty (&FormSet->StorageListHead)) {\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ RemoveEntryList (&Storage->Link);\r
+\r
+ DestroyStorage (Storage);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Free FormSet Default Store\r
+ //\r
+ if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
+ while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
+ Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+ DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
+ RemoveEntryList (&DefaultStore->Link);\r
+\r
+ gBS->FreePool (DefaultStore);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Free Forms\r
+ //\r
+ if (FormSet->FormListHead.ForwardLink != NULL) {\r
+ while (!IsListEmpty (&FormSet->FormListHead)) {\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ RemoveEntryList (&Form->Link);\r
+\r
+ DestroyForm (Form);\r
+ }\r
+ }\r
+\r
+ SafeFreePool (FormSet->StatementBuffer);\r
+ SafeFreePool (FormSet->ExpressionBuffer);\r
+\r
+ SafeFreePool (FormSet);\r
+}\r
+\r
+\r
+/**\r
+ Tell whether this Operand is an Expression OpCode or not\r
+\r
+ @param Operand Operand of an IFR OpCode.\r
+\r
+ @retval TRUE This is an Expression OpCode.\r
+ @retval FALSE Not an Expression OpCode.\r
+\r
+**/\r
+BOOLEAN\r
+IsExpressionOpCode (\r
+ IN UINT8 Operand\r
+ )\r
+{\r
+ if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
+ ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
+ (Operand == EFI_IFR_CATENATE_OP)\r
+ ) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Calculate number of Statemens(Questions) and Expression OpCodes.\r
+\r
+ @param FormSet The FormSet to be counted.\r
+ @param NumberOfStatement Number of Statemens(Questions)\r
+ @param NumberOfExpression Number of Expression OpCodes\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+CountOpCodes (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN OUT UINT16 *NumberOfStatement,\r
+ IN OUT UINT16 *NumberOfExpression\r
+ )\r
+{\r
+ UINT16 StatementCount;\r
+ UINT16 ExpressionCount;\r
+ UINT8 *OpCodeData;\r
+ UINTN Offset;\r
+ UINTN OpCodeLen;\r
+\r
+ Offset = 0;\r
+ StatementCount = 0;\r
+ ExpressionCount = 0;\r
+\r
+ while (Offset < FormSet->IfrBinaryLength) {\r
+ OpCodeData = FormSet->IfrBinaryData + Offset;\r
+ OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ Offset += OpCodeLen;\r
+\r
+ if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
+ ExpressionCount++;\r
+ } else {\r
+ StatementCount++;\r
+ }\r
+ }\r
+\r
+ *NumberOfStatement = StatementCount;\r
+ *NumberOfExpression = ExpressionCount;\r
+}\r
+\r
+\r
+/**\r
+ Parse opcodes in the formset IFR binary.\r
+\r
+ @param FormSet Pointer of the FormSet data structure.\r
+\r
+ @retval EFI_SUCCESS Opcode parse success.\r
+ @retval Other Opcode parse fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ParseOpCodes (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ EFI_STATUS Status;\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
+ UINTN OpCodeLength;\r
+ UINT8 *OpCodeData;\r
+ UINT8 ScopeOpCode;\r
+ FORMSET_STORAGE *Storage;\r
+ FORMSET_DEFAULTSTORE *DefaultStore;\r
+ QUESTION_DEFAULT *CurrentDefault;\r
+ QUESTION_OPTION *CurrentOption;\r
+ CHAR8 *AsciiString;\r
+ UINT16 NumberOfStatement;\r
+ UINT16 NumberOfExpression;\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
+\r
+ mInScopeSubtitle = FALSE;\r
+ SuppressForOption = FALSE;\r
+ mInScopeSuppress = FALSE;\r
+ InScopeOptionSuppress = FALSE;\r
+ mInScopeGrayOut = FALSE;\r
+ InScopeDisable = FALSE;\r
+ DepthOfDisable = 0;\r
+ OpCodeDisabled = FALSE;\r
+ SingleOpCodeExpression = FALSE;\r
+ InScopeDefault = FALSE;\r
+ CurrentExpression = NULL;\r
+ CurrentDefault = NULL;\r
+ CurrentOption = NULL;\r
+ OptionSuppressExpression = NULL;\r
+\r
+ //\r
+ // Get the number of Statements and Expressions\r
+ //\r
+ CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
+\r
+ mStatementIndex = 0;\r
+ FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
+ if (FormSet->StatementBuffer == NULL) {\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
+\r
+ CurrentForm = NULL;\r
+ CurrentStatement = NULL;\r
+\r
+ ResetScopeStack ();\r
+\r
+ OpCodeOffset = 0;\r
+ while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
+ OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
+\r
+ OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ OpCodeOffset += OpCodeLength;\r
+ Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
+ Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
+\r
+ //\r
+ // If scope bit set, push onto scope stack\r
+ //\r
+ if (Scope) {\r
+ PushScope (Operand);\r
+ }\r
+\r
+ if (OpCodeDisabled) {\r
+ //\r
+ // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
+ // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
+ //\r
+ if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
+ DepthOfDisable++;\r
+ } else if (Operand == EFI_IFR_END_OP) {\r
+ Status = PopScope (&ScopeOpCode);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
+ if (DepthOfDisable == 0) {\r
+ InScopeDisable = FALSE;\r
+ OpCodeDisabled = FALSE;\r
+ } else {\r
+ DepthOfDisable--;\r
+ }\r
+ }\r
+ }\r
+ continue;\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
+ // Parse the Opcode\r
+ //\r
+ switch (Operand) {\r
+\r
+ case EFI_IFR_FORM_SET_OP:\r
+ //\r
+ // check the formset GUID\r
+ //\r
+ if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
+ CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ //\r
+ // Create a new Form for this FormSet\r
+ //\r
+ CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+ CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+ InitializeListHead (&CurrentForm->ExpressionListHead);\r
+ InitializeListHead (&CurrentForm->StatementListHead);\r
+\r
+ CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
+ CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
+\r
+ //\r
+ // Insert into Form list of this FormSet\r
+ //\r
+ InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
+ break;\r
+\r
+ //\r
+ // Storage\r
+ //\r
+ case EFI_IFR_VARSTORE_OP:\r
+ //\r
+ // Create a buffer Storage for this FormSet\r
+ //\r
+ Storage = CreateStorage (FormSet);\r
+ Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
+\r
+ CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\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
+ for (Index = 0; AsciiString[Index] != 0; Index++) {\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
+\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
+ //\r
+ // Create a EFI variable Storage for this FormSet\r
+ //\r
+ Storage = CreateStorage (FormSet);\r
+ Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
+\r
+ CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+ CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
+ CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
+ break;\r
+\r
+ //\r
+ // DefaultStore\r
+ //\r
+ case EFI_IFR_DEFAULTSTORE_OP:\r
+ DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
+ DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
+\r
+ CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
+ CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
+\r
+ //\r
+ // Insert to DefaultStore list of this Formset\r
+ //\r
+ InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+ break;\r
+\r
+ //\r
+ // Statements\r
+ //\r
+ case EFI_IFR_SUBTITLE_OP:\r
+ CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+ CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
+\r
+ if (Scope) {\r
+ mInScopeSubtitle = TRUE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_TEXT_OP:\r
+ CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+\r
+ CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
+ break;\r
+\r
+ //\r
+ // Questions\r
+ //\r
+ case EFI_IFR_ACTION_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
+ //\r
+ // No QuestionConfig present, so no configuration string will be processed\r
+ //\r
+ CurrentStatement->QuestionConfig = 0;\r
+ } else {\r
+ CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_RESET_BUTTON_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
+ break;\r
+\r
+ case EFI_IFR_REF_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
+ if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
+ CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+\r
+ if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
+ CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
+\r
+ if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
+ CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_NUMERIC_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
+ Value = &CurrentStatement->HiiValue;\r
+\r
+ switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
+ CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
+ CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
+ CurrentStatement->StorageWidth = sizeof (UINT8);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
+ CurrentStatement->StorageWidth = sizeof (UINT16);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
+ CurrentStatement->StorageWidth = sizeof (UINT32);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
+ CurrentStatement->StorageWidth = sizeof (UINT64);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ InitializeRequestElement (FormSet, CurrentStatement);\r
+\r
+ if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {\r
+ SuppressForOption = TRUE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\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
+ // has to use FormBrowser2.Callback() to retrieve the uncommited data for\r
+ // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).\r
+ //\r
+ CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;\r
+ CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+\r
+ if (Scope) {\r
+ SuppressForOption = TRUE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\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 = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ //\r
+ // MinSize is the minimum number of characters that can be accepted for this opcode,\r
+ // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
+ // The characters are stored as Unicode, so the storage width should multiply 2.\r
+ //\r
+ CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
+ CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
+ CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
+ CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
+\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 = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+ //\r
+ // MinSize is the minimum number of characters that can be accepted for this opcode,\r
+ // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
+ // The characters are stored as Unicode, so the storage width should multiply 2.\r
+ //\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
+ CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
+\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 = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\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 = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\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
+ // Default\r
+ //\r
+ case EFI_IFR_DEFAULT_OP:\r
+ //\r
+ // EFI_IFR_DEFAULT appear in scope of a Question,\r
+ // It creates a default value for the current question.\r
+ // A Question may have more than one Default value which have different default types.\r
+ //\r
+ CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+ CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
+\r
+ CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
+ CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
+ CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+ ExtendValueToU64 (&CurrentDefault->Value);\r
+\r
+ //\r
+ // Insert to Default Value list of current Question\r
+ //\r
+ InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
+\r
+ if (Scope) {\r
+ InScopeDefault = TRUE;\r
+ }\r
+ break;\r
+\r
+ //\r
+ // Option\r
+ //\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ //\r
+ // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
+ // It create a selection for use in current Question.\r
+ //\r
+ CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
+ CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
+\r
+ CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
+ CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
+ CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\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
+ InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
+ break;\r
+\r
+ //\r
+ // Conditional\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
+\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
+ // Image\r
+ //\r
+ case EFI_IFR_IMAGE_OP:\r
+ //\r
+ // Get ScopeOpcode from top of stack\r
+ //\r
+ PopScope (&ScopeOpCode);\r
+ PushScope (ScopeOpCode);\r
+\r
+ switch (ScopeOpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ ImageId = &FormSet->ImageId;\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ ImageId = &CurrentForm->ImageId;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ ImageId = &CurrentOption->ImageId;\r
+ break;\r
+\r
+ default:\r
+ ImageId = &CurrentStatement->ImageId;\r
+ break;\r
+ }\r
+\r
+ CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
+ break;\r
+\r
+ //\r
+ // Refresh\r
+ //\r
+ case EFI_IFR_REFRESH_OP:\r
+ CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\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
+ //\r
+ // Tiano specific GUIDed opcodes\r
+ //\r
+ switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
+ case EFI_IFR_EXTEND_OP_LABEL:\r
+ //\r
+ // just ignore label\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
+ break;\r
+\r
+ case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+ CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+\r
+ //\r
+ // Scope End\r
+ //\r
+ case EFI_IFR_END_OP:\r
+ Status = PopScope (&ScopeOpCode);\r
+ if (EFI_ERROR (Status)) {\r
+ ResetScopeStack ();\r
+ return Status;\r
+ }\r
+\r
+ switch (ScopeOpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ //\r
+ // End of FormSet, update FormSet IFR binary length\r
+ // to stop parsing substantial OpCodes\r
+ //\r
+ FormSet->IfrBinaryLength = OpCodeOffset;\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ //\r
+ // End of Form\r
+ //\r
+ CurrentForm = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ //\r
+ // End of Option\r
+ //\r
+ CurrentOption = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_SUBTITLE_OP:\r
+ mInScopeSubtitle = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_NO_SUBMIT_IF_OP:\r
+ case EFI_IFR_INCONSISTENT_IF_OP:\r
+ //\r
+ // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
+ //\r
+ break;\r
+\r
+ case EFI_IFR_SUPPRESS_IF_OP:\r
+ if (SuppressForOption) {\r
+ InScopeOptionSuppress = FALSE;\r
+ } else {\r
+ mInScopeSuppress = FALSE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_GRAY_OUT_IF_OP:\r
+ mInScopeGrayOut = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_DISABLE_IF_OP:\r
+ InScopeDisable = FALSE;\r
+ OpCodeDisabled = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ SuppressForOption = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_DEFAULT_OP:\r
+ InScopeDefault = FALSE;\r
+ break;\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
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/** @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
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\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/SimpleTextOut.h>\r
+//#include <Protocol/SimpleTextIn.h>\r
+//#include <Protocol/FormBrowser2.h>\r
+//#include <Protocol/DevicePath.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
+#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0\r
+#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1\r
+#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2\r
+#define EFI_HII_EXPRESSION_SUPPRESS_IF 3\r
+#define EFI_HII_EXPRESSION_DISABLE_IF 4\r
+#define EFI_HII_EXPRESSION_VALUE 5\r
+#define EFI_HII_EXPRESSION_RULE 6\r
+\r
+#define EFI_HII_VARSTORE_BUFFER 0\r
+#define EFI_HII_VARSTORE_NAME_VALUE 1\r
+#define EFI_HII_VARSTORE_EFI_VARIABLE 2\r
+\r
+#define FORM_INCONSISTENT_VALIDATION 0\r
+#define FORM_NO_SUBMIT_VALIDATION 1\r
+\r
+\r
+typedef struct {\r
+ UINT8 Type;\r
+ EFI_IFR_TYPE_VALUE Value;\r
+} EFI_HII_VALUE;\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
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT8 Type; // Storage type\r
+\r
+ UINT16 VarStoreId;\r
+ EFI_GUID Guid;\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
+#define EXPRESSION_OPCODE_SIGNATURE EFI_SIGNATURE_32 ('E', 'X', 'O', 'P')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT8 Operand;\r
+\r
+ UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND\r
+ UINT8 Flags; // For EFI_IFR_SPAN\r
+ UINT8 RuleId; // For EFI_IFR_RULE_REF\r
+\r
+ EFI_HII_VALUE Value; // For EFI_IFR_EQ_ID_VAL, EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_IFR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1\r
+\r
+ EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_ID, EFI_IFR_EQ_ID_LIST, EFI_IFR_QUESTION_REF1\r
+ EFI_QUESTION_ID QuestionId2;\r
+\r
+ UINT16 ListLength; // For EFI_IFR_EQ_ID_LIST\r
+ UINT16 *ValueList;\r
+\r
+ EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_2, EFI_IFR_QUESTION_REF3_3\r
+ EFI_GUID Guid;\r
+} EXPRESSION_OPCODE;\r
+\r
+#define EXPRESSION_OPCODE_FROM_LINK(a) CR (a, EXPRESSION_OPCODE, Link, EXPRESSION_OPCODE_SIGNATURE)\r
+\r
+#define FORM_EXPRESSION_SIGNATURE EFI_SIGNATURE_32 ('F', 'E', 'X', 'P')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT8 Type; // Type for this expression\r
+\r
+ UINT8 RuleId; // For EFI_IFR_RULE only\r
+ EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR_INCONSISTENT_IF only\r
+\r
+ EFI_HII_VALUE Result; // Expression evaluation result\r
+\r
+ LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE)\r
+} FORM_EXPRESSION;\r
+\r
+#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)\r
+\r
+#define QUESTION_DEFAULT_SIGNATURE EFI_SIGNATURE_32 ('Q', 'D', 'F', 'T')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\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
+\r
+#define QUESTION_OPTION_SIGNATURE EFI_SIGNATURE_32 ('Q', 'O', 'P', 'T')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_STRING_ID Text;\r
+ UINT8 Flags;\r
+ EFI_HII_VALUE Value;\r
+ EFI_IMAGE_ID ImageId;\r
+\r
+ FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf\r
+} QUESTION_OPTION;\r
+\r
+#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)\r
+\r
+#define FORM_BROWSER_STATEMENT_SIGNATURE EFI_SIGNATURE_32 ('F', 'S', 'T', 'A')\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT8 Operand; // The operand (first byte) of this Statement or Question\r
+\r
+ //\r
+ // Statement Header\r
+ //\r
+ EFI_STRING_ID Prompt;\r
+ EFI_STRING_ID Help;\r
+ EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT\r
+\r
+ //\r
+ // Question Header\r
+ //\r
+ EFI_QUESTION_ID QuestionId; // The value of zero is reserved\r
+ EFI_VARSTORE_ID VarStoreId; // A value of zero indicates no variable storage\r
+ FORMSET_STORAGE *Storage;\r
+ union {\r
+ EFI_STRING_ID VarName;\r
+ UINT16 VarOffset;\r
+ } VarStoreInfo;\r
+ UINT16 StorageWidth;\r
+ UINT8 QuestionFlags;\r
+ CHAR16 *VariableName; // Name/Value or EFI Variable name\r
+ CHAR16 *BlockName; // Buffer storage block name: "OFFSET=...WIDTH=..."\r
+\r
+ EFI_HII_VALUE HiiValue; // Edit copy for checkbox, numberic, oneof\r
+ UINT8 *BufferValue; // Edit copy for string, password, orderedlist\r
+\r
+ //\r
+ // OpCode specific members\r
+ //\r
+ UINT8 Flags; // for EFI_IFR_CHECKBOX, EFI_IFR_DATE, EFI_IFR_NUMERIC, EFI_IFR_ONE_OF,\r
+ // EFI_IFR_ORDERED_LIST, EFI_IFR_STRING,EFI_IFR_SUBTITLE,EFI_IFR_TIME, EFI_IFR_BANNER\r
+ UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST\r
+\r
+ UINT16 BannerLineNumber; // for EFI_IFR_BANNER, 1-based line number\r
+ EFI_STRING_ID QuestionConfig; // for EFI_IFR_ACTION, if 0 then no configuration string will be processed\r
+\r
+ UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC, it's Min/Max value\r
+ UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD, it's Min/Max length\r
+ UINT64 Step;\r
+\r
+ EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON\r
+ EFI_FORM_ID RefFormId; // for EFI_IFR_REF\r
+ EFI_QUESTION_ID RefQuestionId; // for EFI_IFR_REF2\r
+ EFI_GUID RefFormSetId; // for EFI_IFR_REF3\r
+ EFI_STRING_ID RefDevicePath; // for EFI_IFR_REF4\r
+\r
+ //\r
+ // Get from IFR parsing\r
+ //\r
+ FORM_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly\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
+ EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE\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
+ 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
+\r
+} FORM_BROWSER_STATEMENT;\r
+\r
+#define FORM_BROWSER_STATEMENT_FROM_LINK(a) CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)\r
+\r
+#define FORM_BROWSER_FORM_SIGNATURE EFI_SIGNATURE_32 ('F', 'F', 'R', 'M')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT16 FormId;\r
+ EFI_STRING_ID FormTitle;\r
+\r
+ EFI_IMAGE_ID ImageId;\r
+\r
+ LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)\r
+ LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
+} FORM_BROWSER_FORM;\r
+\r
+#define FORM_BROWSER_FORM_FROM_LINK(a) CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)\r
+\r
+#define FORMSET_DEFAULTSTORE_SIGNATURE EFI_SIGNATURE_32 ('F', 'D', 'F', 'S')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT16 DefaultId;\r
+ EFI_STRING_ID DefaultName;\r
+} FORMSET_DEFAULTSTORE;\r
+\r
+#define FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)\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
+\r
+ EFI_GUID Guid;\r
+ EFI_STRING_ID FormSetTitle;\r
+ EFI_STRING_ID Help;\r
+ UINT16 Class;\r
+ UINT16 SubClass;\r
+ EFI_IMAGE_ID ImageId;\r
+\r
+ FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions\r
+ EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode\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
+\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
+\r
+EFI_STATUS\r
+ParseOpCodes (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+;\r
+\r
+VOID\r
+DestroyFormSet (\r
+ IN OUT FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+;\r
+\r
+#endif\r
+\r
--- /dev/null
+#include <PiDxe.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+\r
+CHAR16 *gEmptyString = L" ";\r
+\r
+/**\r
+ Get the string based on the StringId and HII Package List Handle.\r
+\r
+ @param Token The String's ID.\r
+ @param HiiHandle The package list in the HII database to search for\r
+ the specified string.\r
+\r
+ @return The output string.\r
+\r
+**/\r
+CHAR16 *\r
+GetToken (\r
+ IN EFI_STRING_ID Token,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *String;\r
+ UINTN BufferLength;\r
+\r
+ //\r
+ // Set default string size assumption at no more than 256 bytes\r
+ //\r
+ BufferLength = 0x100;\r
+ String = AllocateZeroPool (BufferLength);\r
+ ASSERT (String != NULL);\r
+\r
+ Status = HiiLibGetString (HiiHandle, Token, String, &BufferLength);\r
+\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ gBS->FreePool (String);\r
+ String = AllocateZeroPool (BufferLength);\r
+ ASSERT (String != NULL);\r
+\r
+ Status = HiiLibGetString (HiiHandle, Token, String, &BufferLength);\r
+ }\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return String;\r
+}\r
+\r
+/**\r
+ Create a new string in HII Package List.\r
+\r
+ @param String The String to be added\r
+ @param HiiHandle The package list in the HII database to insert the\r
+ specified string.\r
+\r
+ @return The output string.\r
+\r
+**/\r
+EFI_STRING_ID\r
+NewString (\r
+ IN CHAR16 *String,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ EFI_STRING_ID StringId;\r
+ EFI_STATUS Status;\r
+\r
+ StringId = 0;\r
+ Status = HiiLibNewString (HiiHandle, &StringId, String);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return StringId;\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/** @file\r
+ Common Function and Macro defintions used for both for IFR Parser and Expression evaluation. \r
+ This header file should only be included by UefiIfrParserExpression.c and UefiIfrParser.c\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_COMMON_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_COMMON_INTERNAL_\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+\r
+extern CHAR16 *gEmptyString;\r
+\r
+/**\r
+ Get the string based on the StringId and HII Package List Handle.\r
+\r
+ @param Token The String's ID.\r
+ @param HiiHandle The package list in the HII database to search for\r
+ the specified string.\r
+\r
+ @return The output string.\r
+\r
+**/\r
+CHAR16 *\r
+GetToken (\r
+ IN EFI_STRING_ID Token,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+;\r
+\r
+/**\r
+ Create a new string in HII Package List.\r
+\r
+ @param String The String to be added\r
+ @param HiiHandle The package list in the HII database to insert the\r
+ specified string.\r
+\r
+ @return The output string.\r
+\r
+**/\r
+EFI_STRING_ID\r
+NewString (\r
+ IN CHAR16 *String,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+;\r
+\r
+#endif\r
+\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ Expression.c\r
+\r
+Abstract:\r
+\r
+ Expression evaluation.\r
+\r
+\r
+**/\r
+#include <PiDxe.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+ \r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrParserExpressionInternal.h"\r
+#include "UefiIfrParserCommon.h"\r
+#include "R8Lib.h"\r
+\r
+//\r
+// Global stack used to evaluate boolean expresions\r
+//\r
+EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
+EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
+EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
+\r
+EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\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
+\r
+\r
+/**\r
+ Grow size of the stack\r
+\r
+ @param Stack On input: old stack; On output: new stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack\r
+ pointer\r
+ @param StackPtr On input: old stack end; On output: new stack end\r
+\r
+ @retval EFI_SUCCESS Grow stack success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GrowStack (\r
+ IN OUT EFI_HII_VALUE **Stack,\r
+ IN OUT EFI_HII_VALUE **StackPtr,\r
+ IN OUT EFI_HII_VALUE **StackEnd\r
+ )\r
+{\r
+ UINTN Size;\r
+ EFI_HII_VALUE *NewStack;\r
+\r
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
+ if (*StackPtr != NULL) {\r
+ Size = Size + (*StackEnd - *Stack);\r
+ }\r
+\r
+ NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\r
+ if (NewStack == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (*StackPtr != NULL) {\r
+ //\r
+ // Copy from Old Stack to the New Stack\r
+ //\r
+ CopyMem (\r
+ NewStack,\r
+ *Stack,\r
+ (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)\r
+ );\r
+\r
+ //\r
+ // Free The Old Stack\r
+ //\r
+ gBS->FreePool (*Stack);\r
+ }\r
+\r
+ //\r
+ // Make the Stack pointer point to the old data in the new stack\r
+ //\r
+ *StackPtr = NewStack + (*StackPtr - *Stack);\r
+ *Stack = NewStack;\r
+ *StackEnd = NewStack + Size;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Push an element onto the Boolean Stack\r
+\r
+ @param Stack On input: old stack; On output: new stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack\r
+ pointer\r
+ @param StackPtr On input: old stack end; On output: new stack end\r
+ @param Data Data to push.\r
+\r
+ @retval EFI_SUCCESS Push stack success.\r
+\r
+**/\r
+EFI_STATUS\r
+PushStack (\r
+ IN OUT EFI_HII_VALUE **Stack,\r
+ IN OUT EFI_HII_VALUE **StackPtr,\r
+ IN OUT EFI_HII_VALUE **StackEnd,\r
+ IN EFI_HII_VALUE *Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check for a stack overflow condition\r
+ //\r
+ if (*StackPtr >= *StackEnd) {\r
+ //\r
+ // Grow the stack\r
+ //\r
+ Status = GrowStack (Stack, StackPtr, StackEnd);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Push the item onto the stack\r
+ //\r
+ CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
+ *StackPtr = *StackPtr + 1;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Pop an element from the stack.\r
+\r
+ @param Stack On input: old stack; On output: new stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack\r
+ pointer\r
+ @param StackPtr On input: old stack end; On output: new stack end\r
+ @param Data Data to pop.\r
+\r
+ @retval EFI_SUCCESS The value was popped onto the stack.\r
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopStack (\r
+ IN OUT EFI_HII_VALUE **Stack,\r
+ IN OUT EFI_HII_VALUE **StackPtr,\r
+ IN OUT EFI_HII_VALUE **StackEnd,\r
+ OUT EFI_HII_VALUE *Data\r
+ )\r
+{\r
+ //\r
+ // Check for a stack underflow condition\r
+ //\r
+ if (*StackPtr == *Stack) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ //\r
+ // Pop the item off the stack\r
+ //\r
+ *StackPtr = *StackPtr - 1;\r
+ CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Reset stack pointer to begin of the stack.\r
+\r
+ None.\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+ResetScopeStack (\r
+ VOID\r
+ )\r
+{\r
+ mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
+}\r
+\r
+\r
+/**\r
+ Push an Operand onto the Stack\r
+\r
+ @param Operand Operand to push.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
+ stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushScope (\r
+ IN UINT8 Operand\r
+ )\r
+{\r
+ EFI_HII_VALUE Data;\r
+\r
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Data.Value.u8 = Operand;\r
+\r
+ return PushStack (\r
+ &mOpCodeScopeStack,\r
+ &mOpCodeScopeStackPointer,\r
+ &mOpCodeScopeStackEnd,\r
+ &Data\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Pop an Operand from the Stack\r
+\r
+ @param Operand Operand to pop.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
+ stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopScope (\r
+ OUT UINT8 *Operand\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Data;\r
+\r
+ Status = PopStack (\r
+ &mOpCodeScopeStack,\r
+ &mOpCodeScopeStackPointer,\r
+ &mOpCodeScopeStackEnd,\r
+ &Data\r
+ );\r
+\r
+ *Operand = Data.Value.u8;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Reset stack pointer to begin of the stack.\r
+\r
+ None.\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+ResetExpressionStack (\r
+ VOID\r
+ )\r
+{\r
+ mExpressionEvaluationStackPointer = mExpressionEvaluationStack;\r
+}\r
+\r
+\r
+/**\r
+ Push an Expression value onto the Stack\r
+\r
+ @param Value Expression value to push.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
+ stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushExpression (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ return PushStack (\r
+ &mExpressionEvaluationStack,\r
+ &mExpressionEvaluationStackPointer,\r
+ &mExpressionEvaluationStackEnd,\r
+ Value\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Pop an Expression value from the stack.\r
+\r
+ @param Value Expression value to pop.\r
+\r
+ @retval EFI_SUCCESS The value was popped onto the stack.\r
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopExpression (\r
+ OUT EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ return PopStack (\r
+ &mExpressionEvaluationStack,\r
+ &mExpressionEvaluationStackPointer,\r
+ &mExpressionEvaluationStackEnd,\r
+ Value\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 = R8_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
+ SafeFreePool (String[0]);\r
+ SafeFreePool (String[1]);\r
+ SafeFreePool (StringPtr);\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
+ SafeFreePool (String[0]);\r
+ SafeFreePool (String[1]);\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
+ SafeFreePool (String[0]);\r
+ SafeFreePool (String[1]);\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
+ SafeFreePool (String[0]);\r
+ SafeFreePool (String[1]);\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
+ SafeFreePool (String[0]);\r
+ SafeFreePool (String[1]);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Zero extend integer/boolean/date/time to UINT64 for comparing.\r
+\r
+ @param Value HII Value to be converted.\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+ExtendValueToU64 (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ UINT64 Temp;\r
+\r
+ Temp = 0;\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ Temp = Value->Value.u8;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ Temp = Value->Value.u16;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ Temp = Value->Value.u32;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ Temp = Value->Value.b;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ Temp = Value->Value.u32 & 0xffffff;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ Temp = Value->Value.u32;\r
+ break;\r
+\r
+ default:\r
+ return;\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
--- /dev/null
+/** @file\r
+ Internal Function and Macro defintions for IFR Expression evaluation used in Ifr Parsing. This header file should only\r
+ be included by UefiIfrParserExpression.c and UefiIfrParser.c\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_\r
+\r
+/**\r
+ Reset stack pointer to begin of the stack.\r
+\r
+ None.\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+ResetScopeStack (\r
+ VOID\r
+ )\r
+;\r
+\r
+/**\r
+ Push an Operand onto the Stack\r
+\r
+ @param Operand Operand to push.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
+ stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushScope (\r
+ IN UINT8 Operand\r
+ )\r
+;\r
+\r
+\r
+/**\r
+ Pop an Operand from the Stack\r
+\r
+ @param Operand Operand to pop.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
+ stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopScope (\r
+ OUT UINT8 *Operand\r
+ )\r
+;\r
+\r
+/**\r
+ Zero extend integer/boolean/date/time to UINT64 for comparing.\r
+\r
+ @param Value HII Value to be converted.\r
+\r
+ @return None.\r
+\r
+**/\r
+VOID\r
+ExtendValueToU64 (\r
+ IN EFI_HII_VALUE *Value\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
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Internal Function and Macro defintions for IFR Expression evaluation used in Ifr Parsing. This header file should only\r
+ be included by UefiIfrParserExpression.c\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_INTERNAL_\r
+\r
+//\r
+// Incremental size of stack for expression\r
+//\r
+#define EXPRESSION_STACK_SIZE_INCREMENT 0x100\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
+\r
+\r
+FORM_EXPRESSION *\r
+IdToExpression (\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN UINT8 RuleId\r
+ )\r
+;\r
+\r
+ \r
+#endif\r
--- /dev/null
+/** @file\r
+ Internal Function and Macro defintions for IFR parsing. This header file should only\r
+ be included by UefiIfrParser.c\r
+\r
+ Copyright (c) 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_INTERNAL_\r
+\r
+#include <Protocol/UnicodeCollation.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
+//\r
+// Extern Variables\r
+//\r
+extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
+extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
+extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
+\r
+//\r
+// Incremental string lenght of ConfigRequest\r
+//\r
+#define CONFIG_REQUEST_STRING_INCREMENTAL 1024\r
+\r
+\r
+#define EFI_SPECIFICATION_ERRATA_VERSION 0\r
+\r
+#define EFI_IFR_SPECIFICATION_VERSION \\r
+ ((((EFI_SPECIFICATION_VERSION) >> 8) & 0xff00) | \\r
+ (((EFI_SPECIFICATION_VERSION) & 0xf) << 4) | \\r
+ ((EFI_SPECIFICATION_ERRATA_VERSION) & 0xf))\r
+\r
+extern EFI_GUID gZeroGuid;\r
+\r
+#endif\r