diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c index 589b98b2e4..66bd438469 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c @@ -1,8 +1,7 @@ - /**@file - This file contains functions related to Config Access Protocols installed by - by HII Thunk Modules which is used to thunk UEFI Config Access Callback to - Framework HII Callback. + This file implements functions related to Config Access Protocols installed by + by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config + Access Callback to Framework HII Callback and EFI Variable Set/Get operations. Copyright (c) 2008, Intel Corporation All rights reserved. This program and the accompanying materials @@ -16,8 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "HiiDatabase.h" +#include "UefiIfrParser.h" -BOOLEAN mHiiPackageListUpdated; +BOOLEAN mHiiPackageListUpdated = FALSE; CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = { CONFIG_ACCESS_PRIVATE_SIGNATURE, @@ -27,154 +27,157 @@ CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = { ThunkCallback }, //ConfigAccessProtocol NULL, //FormCallbackProtocol - {NULL, NULL}, //ConfigAccessStorageListHead NULL }; /** - Find and return the pointer to Package Header of the Form package - in the Framework Package List. The Framework Package List is created - by a module calling the Framework HII interface. - The Framwork Package List contains package data - generated by Intel's UEFI VFR Compiler and String gather tool. The data format - of the package data is defined by TIANO_AUTOGEN_PACKAGES_HEADER. - - If the package list contains other type of packages such as KEYBOARD_LAYOUT, - FONTS and IMAGES, the ASSERT. This is to make sure the caller is a - Framework Module which does not include packages introduced by UEFI Specification - or packages that is not supported by Thunk layer. + Get the first EFI_IFR_VARSTORE from the FormSet. - @param Packages The Framework Package List + @param FormSet The Form Set. - @retval EFI_HII_PACKAGE_HEADER* Return the Package Header of Form Package. - @retval NULL If no Form Package is found. + @retval FORMSET_STORAGE * Return the first EFI_IFR_VARSTORE. + @retval NULL If the Form Set does not have EFI_IFR_VARSTORE. **/ -EFI_HII_PACKAGE_HEADER * -GetIfrFormSet ( - IN CONST EFI_HII_PACKAGES *Packages - ) +FORMSET_STORAGE * +GetFirstStorageOfFormSet ( + IN CONST FORM_BROWSER_FORMSET * FormSet + ) { - TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray; - EFI_HII_PACKAGE_HEADER *IfrPackage; - UINTN Index; + LIST_ENTRY *StorageList; + FORMSET_STORAGE *Storage; - ASSERT (Packages != NULL); + StorageList = GetFirstNode (&FormSet->StorageListHead); - IfrPackage = NULL; - - TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId)); - for (Index = 0; Index < Packages->NumberOfPackages; Index++) { - // - // BugBug: The current UEFI HII build tool generate a binary in the format defined in: - // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in - // this binary is with same package type. So the returned IfrPackNum and StringPackNum - // may not be the exact number of valid package number in the binary generated - // by HII Build tool. - // - switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) { - case EFI_HII_PACKAGE_FORMS: - return &TianoAutogenPackageHdrArray[Index]->PackageHeader; - break; - - case EFI_HII_PACKAGE_STRINGS: - case EFI_HII_PACKAGE_SIMPLE_FONTS: - break; - - // - // The following fonts are invalid for a module that using Framework to UEFI thunk layer. - // - case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: - case EFI_HII_PACKAGE_FONTS: - case EFI_HII_PACKAGE_IMAGES: - default: - ASSERT (FALSE); - break; - } + if (!IsNull (&FormSet->StorageListHead, StorageList)) { + Storage = FORMSET_STORAGE_FROM_LINK (StorageList); + return Storage; } - - return (EFI_HII_PACKAGE_HEADER *) NULL; + + return NULL; } /** - This function scan EFI_IFR_VARSTORE_OP in the Form Package. - It create entries for these VARSTORE found and append the entry - to a Link List. - - If FormSetPackage is not EFI_HII_PACKAGE_FORM, then ASSERT. - If there is no linear buffer storage in this formset, then ASSERT. - - @param FormSetPackage The Form Package header. - @param BufferStorageListHead The link list for the VARSTORE found in the form package. + Get the EFI_IFR_VARSTORE where the Question's value is stored. + + @param FormSet The Form Set. - @retval EFI_SUCCESS The function scan the form set and find one or more VARSTOREs. - @retval EFI_OUT_OF_RESOURCES There is not enough memory to complete the function. + @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored. + @retval NULL If the Form Set does not have EFI_IFR_VARSTORE. **/ -EFI_STATUS -GetBufferStorage ( - IN CONST EFI_HII_PACKAGE_HEADER *FormSetPackage, - OUT LIST_ENTRY *BufferStorageListHead +FORMSET_STORAGE * +GetStorageFromQuestionId ( + IN CONST FORM_BROWSER_FORMSET * FormSet, + IN EFI_QUESTION_ID QuestionId ) { - UINTN OpCodeOffset; - UINTN OpCodeLength; - UINT8 *OpCodeData; - UINT8 Operand; - EFI_IFR_VARSTORE *VarStoreOpCode; - BUFFER_STORAGE_ENTRY *BufferStorage; + LIST_ENTRY *FormList; + LIST_ENTRY *StatementList; + FORM_BROWSER_FORM *Form; + FORM_BROWSER_STATEMENT *Statement; - ASSERT (FormSetPackage->Type == EFI_HII_PACKAGE_FORMS); + FormList = GetFirstNode (&FormSet->FormListHead); - OpCodeOffset = sizeof (EFI_HII_PACKAGE_HEADER); - // - // Scan all opcode for the FormSet Package for - // EFI_IFR_VARSTORE_OP opcode. - // - while (OpCodeOffset < FormSetPackage->Length) { - OpCodeData = (UINT8 *) FormSetPackage + OpCodeOffset; + while (!IsNull (&FormSet->FormListHead, FormList)) { + Form = FORM_BROWSER_FORM_FROM_LINK (FormList); - OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; - OpCodeOffset += OpCodeLength; - Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; + StatementList = GetFirstNode (&Form->StatementListHead); - if (Operand == EFI_IFR_VARSTORE_OP) { - VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData; - BufferStorage = AllocateZeroPool (sizeof (*BufferStorage)); - if (BufferStorage == NULL) { - return EFI_OUT_OF_RESOURCES; + while (!IsNull (&Form->StatementListHead, StatementList)) { + Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList); + if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) { + // + // UEFI Question ID is unique in a FormSet. + // + ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER); + return Statement->Storage; } - // - // Record the attributes: GUID, Name, VarStoreId and Size. - // - CopyMem (&BufferStorage->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID)); - - BufferStorage->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2); - AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorage->Name); - - BufferStorage->VarStoreId = VarStoreOpCode->VarStoreId; - - BufferStorage->Size = VarStoreOpCode->Size; - BufferStorage->Signature = BUFFER_STORAGE_ENTRY_SIGNATURE; - - InsertTailList (BufferStorageListHead, &BufferStorage->Link); + StatementList = GetNextNode (&Form->StatementListHead, StatementList); } - } - return EFI_SUCCESS; + FormList = GetNextNode (&FormSet->FormListHead, FormList); + } + + return NULL; } +/** + Get the EFI_IFR_VARSTORE based the ID. + + @param FormSet The Form Set. + + @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE with the ID. + @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID. +**/ +FORMSET_STORAGE * +GetStorageFromVarStoreId ( + IN CONST FORM_BROWSER_FORMSET * FormSet, + IN EFI_VARSTORE_ID VarStoreId + ) +{ + LIST_ENTRY *StorageList; + FORMSET_STORAGE *Storage; + + StorageList = GetFirstNode (&FormSet->StorageListHead); + + while (!IsNull (&FormSet->StorageListHead, StorageList)) { + Storage = FORMSET_STORAGE_FROM_LINK (StorageList); + + if (VarStoreId == Storage->VarStoreId) { + return Storage; + } + + StorageList = GetNextNode (&FormSet->StorageListHead, StorageList); + } + + return NULL; +} + +/** + Get the EFI_IFR_VARSTORE based the string in a + or a string. + + @param FormSet The Form Set. + @param ConfigString The Configuration String which is defined by UEFI HII. + + @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored. + @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID. +**/ +FORMSET_STORAGE * +GetStorageFromConfigString ( + IN CONST FORM_BROWSER_FORMSET *FormSet, + IN CONST EFI_STRING ConfigString + ) +{ + LIST_ENTRY *StorageList; + FORMSET_STORAGE *Storage; + + StorageList = GetFirstNode (&FormSet->StorageListHead); + + while (!IsNull (&FormSet->StorageListHead, StorageList)) { + Storage = FORMSET_STORAGE_FROM_LINK (StorageList); + + if (IsConfigHdrMatch (ConfigString, &Storage->Guid, Storage->Name)) { + return Storage; + } + + StorageList = GetNextNode (&FormSet->StorageListHead, StorageList); + } + + return NULL; +} /** This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered by a module using Framework HII Protocol Interfaces. - UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so - that Setup Utility can load the Buffer Storage using this protocol. + UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so + that Setup Utility can load the Buffer Storage using this protocol. - @param Packages The framework package list. - @param ThunkContext The Thunk Layer Handle Mapping Database Entry. + @param Packages The Package List. + @param ThunkContext The Thunk Context. - @retval EFI_SUCCESS The Config Access Protocol is installed successfully. - @retval EFI_OUT_RESOURCE There is not enough memory. + @retval EFI_SUCCESS The Config Access Protocol is installed successfully. + @retval EFI_OUT_RESOURCE There is not enough memory. **/ EFI_STATUS @@ -183,73 +186,42 @@ InstallDefaultConfigAccessProtocol ( IN OUT HII_THUNK_CONTEXT *ThunkContext ) { - EFI_HII_PACKAGE_HEADER *FormSetPackage; EFI_STATUS Status; CONFIG_ACCESS_PRIVATE *ConfigAccessInstance; + ASSERT (ThunkContext->IfrPackageCount != 0); + Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle); + ASSERT_EFI_ERROR (Status); + ConfigAccessInstance = AllocateCopyPool ( sizeof (CONFIG_ACCESS_PRIVATE), &gConfigAccessPrivateTempate ); ASSERT (ConfigAccessInstance != NULL); - InitializeListHead (&ConfigAccessInstance->BufferStorageListHead); - - // - // We assume there is only one formset package in each Forms Package - // - FormSetPackage = GetIfrFormSet (Packages); - ASSERT (FormSetPackage != NULL); - - Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->BufferStorageListHead); - if (EFI_ERROR (Status)) { - FreePool (ConfigAccessInstance); - ASSERT (FALSE); - return Status; - } - Status = gBS->InstallMultipleProtocolInterfaces ( &ThunkContext->UefiHiiDriverHandle, &gEfiHiiConfigAccessProtocolGuid, &ConfigAccessInstance->ConfigAccessProtocol, NULL ); - // - //BUGBUG: Remove when done. - // ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - FreePool (ConfigAccessInstance); - return Status; - } - ConfigAccessInstance->ThunkContext = ThunkContext; return EFI_SUCCESS; } -VOID -DestroyBufferStorageList ( - IN LIST_ENTRY *ListHead - ) -{ - LIST_ENTRY *Link; - BUFFER_STORAGE_ENTRY *Entry; +/** + This function un-installs the EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered + by a module using Framework HII Protocol Interfaces. - while (!IsListEmpty (ListHead)) { - Link = GetFirstNode (ListHead); - - Entry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link); - - FreePool (Entry->Name); - Link = RemoveEntryList (Link); - - FreePool (Entry); - } -} + ASSERT if no Config Access is found for such pakcage list or failed to uninstall the protocol. + @param ThunkContext The Thunk Context. + +**/ VOID UninstallDefaultConfigAccessProtocol ( IN HII_THUNK_CONTEXT *ThunkContext @@ -266,7 +238,6 @@ UninstallDefaultConfigAccessProtocol ( &gEfiHiiConfigAccessProtocolGuid, (VOID **) &ConfigAccess ); - ASSERT_EFI_ERROR (Status); Status = gBS->UninstallProtocolInterface ( @@ -278,8 +249,6 @@ UninstallDefaultConfigAccessProtocol ( ConfigAccessInstance = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccess); - DestroyBufferStorageList (&ConfigAccessInstance->BufferStorageListHead); - } @@ -297,7 +266,7 @@ UninstallDefaultConfigAccessProtocol ( **/ EFI_STATUS CallFormCallBack ( - IN BUFFER_STORAGE_ENTRY *BufferStorage, + IN FORMSET_STORAGE *BufferStorage, IN EFI_FORM_CALLBACK_PROTOCOL *FwFormCallBack, OUT VOID **Data, OUT UINTN *DataSize @@ -359,7 +328,7 @@ CallFormCallBack ( EFI_STATUS GetUefiVariable ( - IN BUFFER_STORAGE_ENTRY *BufferStorage, + IN FORMSET_STORAGE *BufferStorage, OUT VOID **Data, OUT UINTN *DataSize ) @@ -399,31 +368,6 @@ GetUefiVariable ( return Status; } -BUFFER_STORAGE_ENTRY * -GetBufferStorageEntry ( - IN CONFIG_ACCESS_PRIVATE *ConfigAccess, - IN UINT16 VarStoreId - ) -{ - LIST_ENTRY *Link; - BUFFER_STORAGE_ENTRY *BufferStorage; - - Link = GetFirstNode (&ConfigAccess->BufferStorageListHead); - - while (!IsNull (&ConfigAccess->BufferStorageListHead, Link)) { - BufferStorage = BUFFER_STORAGE_ENTRY_FROM_LINK (Link); - - if (BufferStorage->VarStoreId == VarStoreId) { - return BufferStorage; - } - - Link = GetNextNode (&ConfigAccess->BufferStorageListHead, Link); - } - - return NULL; -} - - /** This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig @@ -458,19 +402,19 @@ ThunkExtractConfig ( { EFI_STATUS Status; CONFIG_ACCESS_PRIVATE *ConfigAccess; - BUFFER_STORAGE_ENTRY *BufferStorage; + FORMSET_STORAGE *BufferStorage; VOID *Data; UINTN DataSize; Data = NULL; ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); - // - // For now, only one var varstore is supported so that we don't need to parse the Configuration string. - // - BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID); + BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request); if (ConfigAccess->ThunkContext->NvMapOverride == NULL) { + // + // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback. + // if (ConfigAccess->FormCallbackProtocol == NULL || ConfigAccess->FormCallbackProtocol->NvRead == NULL) { Status = GetUefiVariable ( @@ -487,6 +431,9 @@ ThunkExtractConfig ( ); } } else { + // + // Use the NvMapOverride. + // DataSize = BufferStorage->Size; Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride); @@ -515,7 +462,6 @@ ThunkExtractConfig ( } /** - This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig so that data can be written to the data storage such as UEFI Variable or module's customized storage exposed by EFI_FRAMEWORK_CALLBACK. @@ -540,7 +486,7 @@ ThunkRouteConfig ( { EFI_STATUS Status; CONFIG_ACCESS_PRIVATE *ConfigAccess; - BUFFER_STORAGE_ENTRY *BufferStorage; + FORMSET_STORAGE *BufferStorage; UINT8 *Data; UINTN DataSize; UINTN DataSize2; @@ -551,10 +497,7 @@ ThunkRouteConfig ( Data = NULL; ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); - // - // For now, only one var varstore is supported so that we don't need to parse the Configuration string. - // - BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID); + BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Configuration); DataSize2 = BufferStorage->Size; if (ConfigAccess->ThunkContext->NvMapOverride == NULL) { @@ -632,6 +575,21 @@ Done: return Status; } +/** + Build the FRAMEWORK_EFI_IFR_DATA_ARRAY which will be used to pass to + EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of FRAMEWORK_EFI_IFR_DATA_ARRAY + for details. + + ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL + @param QuestionId The Question ID. + @param Type The Question Type. + @param Value The Question Value. + @param NvMapAllocated On output indicates if a buffer is allocated for NvMap. + + @return A pointer to FRAMEWORK_EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated. +**/ FRAMEWORK_EFI_IFR_DATA_ARRAY * CreateIfrDataArray ( IN CONFIG_ACCESS_PRIVATE *ConfigAccess, @@ -644,19 +602,15 @@ CreateIfrDataArray ( FRAMEWORK_EFI_IFR_DATA_ARRAY *IfrDataArray; FRAMEWORK_EFI_IFR_DATA_ENTRY *IfrDataEntry; UINTN BrowserDataSize; - BUFFER_STORAGE_ENTRY *BufferStorageEntry; - LIST_ENTRY *Link; + FORMSET_STORAGE *BufferStorage; EFI_STATUS Status; UINTN Size; UINTN StringSize; EFI_STRING String; - String = NULL; + *NvMapAllocated = FALSE; - Link = GetFirstNode (&ConfigAccess->BufferStorageListHead); - if (IsNull (&ConfigAccess->BufferStorageListHead, Link)) { - return NULL; - } + String = NULL; switch (Type) { case EFI_IFR_TYPE_NUM_SIZE_8: @@ -690,68 +644,121 @@ CreateIfrDataArray ( IfrDataArray = AllocateZeroPool (sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY) + sizeof (FRAMEWORK_EFI_IFR_DATA_ENTRY) + Size); ASSERT (IfrDataArray != NULL); - BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link); - BrowserDataSize = BufferStorageEntry->Size; + BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId); - if (ConfigAccess->ThunkContext->NvMapOverride == NULL) { - *NvMapAllocated = TRUE; - IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize); - } else { - *NvMapAllocated = FALSE; - IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride; + if (BufferStorage == NULL) { + // + // The QuestionId is not associated with a Buffer Storage. + // Try to get the first Buffer Storage then. + // + BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet); } - Status = GetBrowserData (NULL, NULL, &BrowserDataSize, IfrDataArray->NvRamMap); - ASSERT_EFI_ERROR (Status); + if (BufferStorage != NULL) { + BrowserDataSize = BufferStorage->Size; - IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1); + if (ConfigAccess->ThunkContext->NvMapOverride == NULL) { + *NvMapAllocated = TRUE; + IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize); + } else { + *NvMapAllocated = FALSE; + IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride; + } + + Status = GetBrowserData (&BufferStorage->Guid, BufferStorage->Name, &BrowserDataSize, IfrDataArray->NvRamMap); + ASSERT_EFI_ERROR (Status); - switch (Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - case EFI_IFR_TYPE_NUM_SIZE_16: - case EFI_IFR_TYPE_NUM_SIZE_32: - case EFI_IFR_TYPE_NUM_SIZE_64: - case EFI_IFR_TYPE_BOOLEAN: - CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value)); - break; + IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1); - case EFI_IFR_TYPE_STRING: - ASSERT (String != NULL); - StrCpy ((CHAR16 *) &IfrDataEntry->Data, String); - FreePool (String); - break; - default: - ASSERT (FALSE); - break; + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + case EFI_IFR_TYPE_NUM_SIZE_16: + case EFI_IFR_TYPE_NUM_SIZE_32: + case EFI_IFR_TYPE_NUM_SIZE_64: + case EFI_IFR_TYPE_BOOLEAN: + CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value)); + break; + + case EFI_IFR_TYPE_STRING: + ASSERT (String != NULL); + StrCpy ((CHAR16 *) &IfrDataEntry->Data, String); + FreePool (String); + break; + default: + ASSERT (FALSE); + break; + } + + // + // Need to fiil in the information for the rest of field for FRAMEWORK_EFI_IFR_DATA_ENTRY. + // It seems that no implementation is found to use other fields. Leave them uninitialized for now. + // + //UINT8 OpCode; // Likely a string, numeric, or one-of + //UINT8 Length; // Length of the FRAMEWORK_EFI_IFR_DATA_ENTRY packet + //UINT16 Flags; // Flags settings to determine what behavior is desired from the browser after the callback + //VOID *Data; // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately + // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value + // If the OpCode is a String type - Data is a CHAR16[x] type + // If the OpCode is a Checkbox type - Data is a UINT8 value + // If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure } return IfrDataArray; } +/** + If a NvMapOverride is passed in to EFI_FORM_BROWSER_PROTOCOL.SendForm, the Form Browser + needs to be informed when data changed in NvMapOverride. This function will invoke + SetBrowserData () to set internal data of Form Browser. + + @param ConfigAccess The Config Access Private Context. + @param QuestionId The Question Id that invokes the callback. + + +**/ VOID SyncBrowserDataForNvMapOverride ( - IN CONFIG_ACCESS_PRIVATE *ConfigAccess + IN CONST CONFIG_ACCESS_PRIVATE *ConfigAccess, + IN EFI_QUESTION_ID QuestionId ) { - BUFFER_STORAGE_ENTRY *BufferStorageEntry; - LIST_ENTRY *Link; + FORMSET_STORAGE *BufferStorage; EFI_STATUS Status; UINTN BrowserDataSize; if (ConfigAccess->ThunkContext->NvMapOverride != NULL) { - - Link = GetFirstNode (&ConfigAccess->BufferStorageListHead); - ASSERT (!IsNull (&ConfigAccess->BufferStorageListHead, Link)); - - BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link); - BrowserDataSize = BufferStorageEntry->Size; - Status = SetBrowserData (NULL, NULL, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL); + BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId); + + if (BufferStorage == NULL) { + // + // QuestionId is a statement without Storage. + // 1) It is a Goto. + // + // + BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet); + } + + // + // If NvMapOverride is not NULL, this Form must have at least one Buffer Type Variable Storage. + // + ASSERT (BufferStorage != NULL); + + BrowserDataSize = BufferStorage->Size; + + Status = SetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL); ASSERT_EFI_ERROR (Status); } } +/** + Free up resource allocated for a FRAMEWORK_EFI_IFR_DATA_ARRAY by CreateIfrDataArray (). + + @param Array The FRAMEWORK_EFI_IFR_DATA_ARRAY allocated. + @param NvMapAllocated If the NvRamMap is allocated for FRAMEWORK_EFI_IFR_DATA_ARRAY. + +**/ VOID DestroyIfrDataArray ( IN FRAMEWORK_EFI_IFR_DATA_ARRAY *Array, @@ -767,7 +774,21 @@ DestroyIfrDataArray ( } } +/** + Get the ONE_OF_OPTION_MAP_ENTRY for a QuestionId that invokes the + EFI_FORM_CALLBACK_PROTOCOL.Callback. The information is needed as + the callback mechanism for EFI_IFR_ONE_OF_OPTION is changed from + EFI_IFR_ONE_OF_OPTION in Framework IFR. Check EFI_IFR_GUID_OPTIONKEY + for detailed information. + @param ThunkContext The Thunk Context. + @param QuestionId The Question Id. + @param Type The Question Type. + @param Value The One Of Option's value. + + @return The ONE_OF_OPTION_MAP_ENTRY found. + @retval NULL If no entry is found. +**/ ONE_OF_OPTION_MAP_ENTRY * GetOneOfOptionMapEntry ( IN HII_THUNK_CONTEXT *ThunkContext, @@ -780,10 +801,13 @@ GetOneOfOptionMapEntry ( LIST_ENTRY *Link2; ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry; ONE_OF_OPTION_MAP *OneOfOptionMap; + FORM_BROWSER_FORMSET *FormSet; - Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead); + FormSet = ThunkContext->FormSet; - while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) { + Link = GetFirstNode (&FormSet->OneOfOptionMapListHead); + + while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) { OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link); if (OneOfOptionMap->QuestionId == QuestionId) { ASSERT (OneOfOptionMap->ValueType == Type); @@ -801,7 +825,7 @@ GetOneOfOptionMapEntry ( } } - Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link); + Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link); } @@ -815,6 +839,18 @@ GetOneOfOptionMapEntry ( PackageGuid, Handle, and Package are used for each of the notification types. + If any Pakcage List in database is updated, mHiiPackageListUpdated + will be set. If mHiiPackageListUpdated is set, Framework ThunkCallback() + will force the UEFI Setup Browser to save the uncommitted data. This + is needed as Framework's Callback function may dynamically update + opcode in a Package List. UEFI Setup Browser will quit itself and reparse + the Package List's IFR and display it. UEFI Config Access's implementation + is required to save the modified (SetBrowserData or directly save the data + to NV storage). But Framework HII Modules is not aware of this rule. Therefore, + we will enforce the rule in ThunkCallback (). The side effect of force saving + of NV data is the NV flag in browser may not flag a update as data has already + been saved to NV storage. + @param PackageType Package type of the notification. @param PackageGuid If PackageType is @@ -851,8 +887,7 @@ FormUpdateNotify ( /** Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor, - the framework HII module willl do no porting (except some porting works needed for callback for EFI_ONE_OF_OPTION opcode) - and still work with a UEFI HII SetupBrowser. + the framework HII module willl do no porting and work with a UEFI HII SetupBrowser. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x. @@ -922,6 +957,9 @@ ThunkCallback ( // KeyValue = QuestionId; } else { + // + // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax. + // KeyValue = OneOfOptionMapEntry->FwKey; } @@ -939,7 +977,7 @@ ThunkCallback ( &NotifyHandle ); // - // + //Call the Framework Callback function. // Packet = NULL; Status = FormCallbackProtocol->Callback ( @@ -948,7 +986,7 @@ ThunkCallback ( Data, &Packet ); - SyncBrowserDataForNvMapOverride (ConfigAccess); + SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId); // // Callback require browser to perform action @@ -998,15 +1036,19 @@ ThunkCallback ( // the form and load all the variable storages. // if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) { + mHiiPackageListUpdated= FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; } else { - if (ConfigAccess->ThunkContext->FormSetSubClass == EFI_FRONT_PAGE_SUBCLASS || - ConfigAccess->ThunkContext->FormSetSubClass == EFI_SINGLE_USE_SUBCLASS) { + if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS || + ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } } + // + // Clean up. + // DestroyIfrDataArray (Data, NvMapAllocated); return Status; diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Fonts.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Fonts.c index 236029671b..46cb76f06b 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Fonts.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Fonts.c @@ -22,20 +22,31 @@ EFI_GRAPHICS_OUTPUT_BLT_PIXEL mSysFGColor = {0}; /** - This function is only called by Graphics Console module and GraphicsLib. - EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib - complying to UEFI HII. + Translates a Unicode character into the corresponding font glyph. - This function will ASSERT and return EFI_UNSUPPORTED. + Notes: + This function is only called by Graphics Console module and GraphicsLib. + Wrap the Framework HII GetGlyph function to UEFI Font Protocol. + + EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib + complying to UEFI HII. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + @param Source A pointer to a Unicode string. + @param Index On input, the offset into the string from which to fetch the character. On successful completion, the + index is updated to the first character past the character(s) making up the just extracted glyph. + @param GlyphBuffer Pointer to an array where the glyphs corresponding to the characters in the source may be stored. + GlyphBuffer is assumed to be wide enough to accept a wide glyph character. + @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by this value is filled with the length of the glyph in pixels. + It is unchanged if the call was unsuccessful. + @param InternalStatus To save the time required to read the string from the beginning on each glyph extraction + (for example, to ensure that the narrow versus wide glyph mode is correct), this value is + updated each time the function is called with the status that is local to the call. The cell pointed + to by this parameter must be initialized to zero prior to invoking the call the first time for any string. - @param This N.A. - @param Source N.A. - @param Index N.A. - @param GlyphBuffer N.A. - @param BitWidth N.A. - @param InternalStatus N.A. - - @return EFI_UNSUPPORTED N.A. + @retval EFI_SUCCESS It worked. + @retval EFI_NOT_FOUND A glyph for a character was not found. + **/ EFI_STATUS @@ -122,22 +133,25 @@ HiiGetGlyph ( } /** + Translates a glyph into the format required for input to the Universal Graphics Adapter (UGA) Block Transfer (BLT) routines. + + Notes: This function is only called by Graphics Console module and GraphicsLib. EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib complying to UEFI HII. - This function will ASSERT and return EFI_UNSUPPORTED. + @param This A pointer to the EFI_HII_PROTOCOL instance. + @param GlyphBuffer A pointer to the buffer that contains glyph data. + @param Foreground The foreground setting requested to be used for the generated BltBuffer data. Type EFI_UGA_PIXEL is defined in "Related Definitions" below. + @param Background The background setting requested to be used for the generated BltBuffer data. + @param Count The entry in the BltBuffer upon which to act. + @param Width The width in bits of the glyph being converted. + @param Height The height in bits of the glyph being converted + @param BltBuffer A pointer to the buffer that contains the data that is ready to be used by the UGA BLT routines. - @param This N.A. - @param GlyphBuffer N.A. - @param Foreground N.A. - @param Background N.A. - @param Count N.A. - @param Width N.A. - @param Height N.A. - @param BltBuffer N.A. - - @return EFI_UNSUPPORTED N.A. + @retval EFI_SUCCESS It worked. + @retval EFI_NOT_FOUND A glyph for a character was not found. + **/ EFI_STATUS diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c index fb0a6900b8..c302cf56f0 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c @@ -55,6 +55,8 @@ FW_HII_FORMSET_TEMPLATE FormSetTemplate = { }; +EFI_GUID mTianoHiiIfrGuid = EFI_IFR_TIANO_GUID; + /** This thunk module only handles UEFI HII packages. The caller of this function @@ -144,10 +146,12 @@ HiiGetForms ( CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE)); CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID)); - OutputFormSet->FormSet.Class = ThunkContext->FormSetClass; - OutputFormSet->FormSet.SubClass = ThunkContext->FormSetSubClass; - OutputFormSet->FormSet.Help = ThunkContext->FormSetHelp; - OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSetTitle; + if (ThunkContext->FormSet != NULL) { + OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class; + OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass; + OutputFormSet->FormSet.Help = ThunkContext->FormSet->Help; + OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle; + } return EFI_SUCCESS; } @@ -182,25 +186,25 @@ HiiGetDefaultImage ( ) { LIST_ENTRY *UefiDefaults; - EFI_HII_HANDLE UefiHiiHandle; EFI_STATUS Status; HII_THUNK_PRIVATE_DATA *Private; + HII_THUNK_CONTEXT *ThunkContext; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); - UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle); - if (UefiHiiHandle == NULL) { + ThunkContext = FwHiiHandleToThunkContext (Private, Handle); + if (ThunkContext == NULL) { ASSERT (FALSE); return EFI_INVALID_PARAMETER; } UefiDefaults = NULL; - Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults); + Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults); if (EFI_ERROR (Status)) { goto Done; } - Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, VariablePackList); + Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList); Done: FreeDefaultList (UefiDefaults); @@ -209,12 +213,15 @@ Done: } /** - EDES_TODO: Add function description. + This function update the FormCallbackProtocol cached in Config Access + private context data. - @param CallbackHandle EDES_TODO: Add parameter description - @param ThunkContext EDES_TODO: Add parameter description + @param CallbackHandle The EFI Handle on which the Framework FormCallbackProtocol is + installed. + @param ThunkContext The Thunk Context. - @return EDES_TODO: Add description for return value + @retval EFI_SUCCESS The update is successful. + @retval EFI_INVALID_PARAMETER If no Framework FormCallbackProtocol is located on CallbackHandle. **/ EFI_STATUS @@ -260,17 +267,17 @@ UpdateFormCallBack ( /** - EDES_TODO: Add function description. + Get the package data from the Package List. - @param HiiPackageList EDES_TODO: Add parameter description - @param PackageIndex EDES_TODO: Add parameter description - @param BufferLen EDES_TODO: Add parameter description - @param Buffer EDES_TODO: Add parameter description + @param HiiPackageList Package List. + @param PackageIndex The index of the Package in the Package List. + @param BufferLen The Length of the Pacage data. + @param Buffer On output, the Package data. - @return EDES_TODO: Add description for return value + @return EFI_NOT_FOUND No Package is found for PackageIndex. + @return EFI_SUCCESS The package data is returned. **/ -STATIC EFI_STATUS GetPackageData ( IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList, @@ -317,10 +324,16 @@ GetPackageData ( } /** - Check if Label exist in the IFR form package. + Check if Label exist in the IFR form package and return the FormSet GUID + and Form ID. - @param + @param Package The Package Header. + @param Label The Label ID. + @param FormsetGuid Returns the FormSet GUID. + @param FormId Returns the Form ID. + @retval EFI_SUCCESS The FORM ID is found. + @retval EFI_NOT_FOUND The FORM ID is not found. **/ EFI_STATUS LocateLabel ( @@ -332,12 +345,11 @@ LocateLabel ( { UINTN Offset; EFI_IFR_OP_HEADER *IfrOpHdr; - UINT8 ExtendOpCode; - UINT16 LabelNumber; EFI_GUID InternalFormSetGuid; EFI_FORM_ID InternalFormId; BOOLEAN GetFormSet; BOOLEAN GetForm; + EFI_IFR_GUID_LABEL *LabelOpcode; IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER)); Offset = sizeof (EFI_HII_PACKAGE_HEADER); @@ -360,26 +372,18 @@ LocateLabel ( break; case EFI_IFR_GUID_OP : - ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode; - - if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) { - // - // Go to the next Op-Code - // - Offset += IfrOpHdr->Length; - IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length); - continue; + LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr; + // + // If it is an Label opcode. + // + if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) { + if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) { + ASSERT (GetForm && GetFormSet); + CopyGuid (FormsetGuid, &InternalFormSetGuid); + *FormId = InternalFormId; + return EFI_SUCCESS; + } } - - CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16)); - if (LabelNumber == Label) { - ASSERT (GetForm && GetFormSet); - CopyGuid (FormsetGuid, &InternalFormSetGuid); - *FormId = InternalFormId; - return EFI_SUCCESS; - } - - break; default : break; @@ -462,6 +466,7 @@ Done: return Status; } + /** This function allows the caller to update a form that has previously been registered with the EFI HII database. @@ -539,10 +544,10 @@ HiiUpdateForm ( if (Data->DataCount != 0) { ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle); - Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, AddData, &UefiHiiUpdateData); + Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, &UefiHiiUpdateData); ASSERT_EFI_ERROR (Status); - Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData); + Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, TRUE, UefiHiiUpdateData); ASSERT_EFI_ERROR (Status); } diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf index 2fed1569d1..fcdcabfc56 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf @@ -43,13 +43,10 @@ ConfigAccess.h OpcodeCreation.c OpcodeCreation.h - UefiIfrParserInternal.h - UefiIfrParserCommon.c - UefiIfrParserCommon.h UefiIfrParser.c UefiIfrParser.h UefiIfrParserExpression.c - UefiIfrParserExpressionInternal.h + UefiIfrParserExpression.h UefiIfrDefault.c UefiIfrDefault.h Keyboard.c @@ -104,3 +101,4 @@ gEfiFormBrowser2ProtocolGuid + diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h index 2fc2be81a4..0ea1b5a359 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h @@ -51,6 +51,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include "UefiIfrParser.h" + // // VARSTORE ID of 0 for Buffer Storage Type Storage is reserved in UEFI IFR form. But VARSTORE ID @@ -59,7 +61,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Framework VFR has to be ported or pre-processed to change the default VARSTORE to a VARSTORE // with ID equal to 0x0001. // -#define RESERVED_VARSTORE_ID 0x0001 +#define FRAMEWORK_RESERVED_VARSTORE_ID 0x0001 #pragma pack (push, 1) @@ -87,32 +89,6 @@ typedef struct { -#define ONE_OF_OPTION_MAP_ENTRY_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP_ENTRY, Link, ONE_OF_OPTION_MAP_ENTRY_SIGNATURE) -#define ONE_OF_OPTION_MAP_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'M', 'E') -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - UINT16 FwKey; - EFI_IFR_TYPE_VALUE Value; - -} ONE_OF_OPTION_MAP_ENTRY; - - - -#define ONE_OF_OPTION_MAP_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP, Link, ONE_OF_OPTION_MAP_SIGNATURE) -#define ONE_OF_OPTION_MAP_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'O', 'M') -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - UINT8 ValueType; //EFI_IFR_TYPE_NUM_* - - EFI_QUESTION_ID QuestionId; - - LIST_ENTRY OneOfOptionMapEntryListHead; //ONE_OF_OPTION_MAP_ENTRY -} ONE_OF_OPTION_MAP; - #define QUESTION_ID_MAP_ENTRY_FROM_LINK(Record) CR(Record, QUESTION_ID_MAP_ENTRY, Link, QUESTION_ID_MAP_ENTRY_SIGNATURE) @@ -161,17 +137,10 @@ typedef struct { // TagGuid is the used to record this GuidId. EFI_GUID TagGuid; - LIST_ENTRY QuestionIdMapListHead; //QUESTION_ID_MAP - - LIST_ENTRY OneOfOptionMapListHead; //ONE_OF_OPTION_MAP - UINT8 *NvMapOverride; - UINT16 FormSetClass; - UINT16 FormSetSubClass; - STRING_REF FormSetTitle; - STRING_REF FormSetHelp; - + FORM_BROWSER_FORMSET *FormSet; + } HII_THUNK_CONTEXT; @@ -199,8 +168,6 @@ typedef struct { // EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol; - LIST_ENTRY BufferStorageListHead; - HII_THUNK_CONTEXT *ThunkContext; } CONFIG_ACCESS_PRIVATE; diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Keyboard.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Keyboard.c index 9a49ee5761..087cd7aedb 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Keyboard.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Keyboard.c @@ -16,6 +16,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HiiDatabase.h" +/** + Retrieves the current keyboard layout. + This function is not implemented by HII Thunk Module. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + @param DescriptorCount A pointer to the number of Descriptor entries being described in the keyboard layout being retrieved. + @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR entries. Each entry will reflect the definition of a specific physical key. Type EFI_KEY_DESCRIPTOR is defined in "Related Definitions" below. + + @retval EFI_SUCCESS The keyboard layout was retrieved successfully. + +**/ EFI_STATUS EFIAPI HiiGetKeyboardLayout ( @@ -23,15 +34,6 @@ HiiGetKeyboardLayout ( OUT UINT16 *DescriptorCount, OUT FRAMEWORK_EFI_KEY_DESCRIPTOR *Descriptor ) -/*++ - -Routine Description: - -Arguments: - -Returns: - ---*/ { ASSERT (FALSE); // diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c index 0fbe943165..60b2d25c71 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c @@ -18,6 +18,108 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID; + +EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = { + {EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0}, + EFI_IFR_FRAMEWORK_GUID, + EFI_IFR_EXTEND_OP_OPTIONKEY, + 0, + 0, + 0 +}; + +typedef struct { + UINT8 FrameworkIfrOp; + UINT8 UefiIfrOp; +} IFR_OPCODE_MAP; + +IFR_OPCODE_MAP mQuestionOpcodeMap [] = { + { FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP}, + { FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP}, + { FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP}, + { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP}, + { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP} +}; + +EFI_STATUS +QuestionOpFwToUefi ( + IN UINT8 FwOp, + OUT UINT8 *UefiOp + ) +{ + UINTN Index; + + for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) { + if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) { + *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + + +EFI_STATUS +FwQIdToUefiQId ( + IN CONST FORM_BROWSER_FORMSET *FormSet, + IN UINT16 VarStoreId, + IN UINT8 FwOpCode, + IN UINT16 FwQId, + OUT UINT16 *UefiQId + ) +{ + LIST_ENTRY *FormList; + LIST_ENTRY *StatementList; + FORM_BROWSER_FORM *Form; + FORM_BROWSER_STATEMENT *Statement; + EFI_STATUS Status; + UINT8 UefiOp; + + *UefiQId = 0; + + FormList = GetFirstNode (&FormSet->FormListHead); + + while (!IsNull (&FormSet->FormListHead, FormList)) { + Form = FORM_BROWSER_FORM_FROM_LINK (FormList); + + StatementList = GetFirstNode (&Form->StatementListHead); + + while (!IsNull (&Form->StatementListHead, StatementList)) { + Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList); + if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) { + if (FwQId == Statement->VarStoreInfo.VarOffset) { + Status = QuestionOpFwToUefi (FwOpCode, &UefiOp); + ASSERT_EFI_ERROR (Status); + + if (UefiOp == Statement->Operand) { + // + // If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the + // same field in NvMap. This is ambigurity, we don't handle it for now. + // + // + // UEFI Question ID is unique in a FormSet. + // + ASSERT (VarStoreId == Statement->VarStoreId); + *UefiQId = Statement->QuestionId; + + return EFI_SUCCESS; + + } + } + } + + StatementList = GetNextNode (&Form->StatementListHead, StatementList); + } + + FormList = GetNextNode (&FormSet->FormListHead, FormList); + } + + return EFI_NOT_FOUND; +} + + + #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000 EFI_STATUS AppendToUpdateBuffer ( @@ -46,54 +148,18 @@ AppendToUpdateBuffer ( EFI_QUESTION_ID AssignQuestionId ( - IN UINT16 FwQuestionId + IN UINT16 FwQuestionId, + IN FORM_BROWSER_FORMSET *FormSet ) { if (FwQuestionId == 0) { - // - // In UEFI IFR, the Question ID can't be zero. Zero means no storage. - // So use 0xABBA as a Question ID. - // - return 0xABBA; + FormSet->MaxQuestionId++; + return FormSet->MaxQuestionId; } else { return FwQuestionId; } } - -EFI_STATUS -FwQuestionIdToUefiQuestionId ( - IN HII_THUNK_CONTEXT *ThunkContext, - IN UINT16 VarStoreId, - IN UINT16 FwId, - OUT EFI_QUESTION_ID *UefiQId - ) -{ - LIST_ENTRY *MapEntryListHead; - LIST_ENTRY *Link; - QUESTION_ID_MAP_ENTRY *MapEntry; - - MapEntryListHead = GetMapEntryListHead (ThunkContext, VarStoreId); - ASSERT (MapEntryListHead != NULL); - - Link = GetFirstNode (MapEntryListHead); - - while (!IsNull (MapEntryListHead, Link)) { - MapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link); - - if (MapEntry->FwQId == FwId) { - *UefiQId = MapEntry->UefiQid; - return EFI_SUCCESS; - } - - Link = GetNextNode (MapEntryListHead, Link); - } - - return EFI_NOT_FOUND; -} - - - EFI_STATUS UCreateEndOfOpcode ( OUT EFI_HII_UPDATE_DATA *UefiData @@ -281,6 +347,24 @@ F2UCreateOneOfOptionOpCode ( return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData); } +EFI_STATUS +CreateGuidOptionKeyOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN UINT16 OptionValue, + IN EFI_QUESTION_ID KeyValue, + OUT EFI_HII_UPDATE_DATA *UefiData + ) +{ + EFI_IFR_GUID_OPTIONKEY UOpcode; + + CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY)); + + UOpcode.QuestionId = QuestionId; + CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue)); + UOpcode.KeyValue = KeyValue; + + return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData); +} /* typedef struct _EFI_IFR_QUESTION_HEADER { @@ -349,14 +433,10 @@ F2UCreateOneOfOpCode ( EFI_IFR_ONE_OF UOpcode; FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader; FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp; - ONE_OF_OPTION_MAP *OneOfOptionMap; - ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry; ASSERT (NextFwOpcode != NULL); ASSERT (DataCount != NULL); - OneOfOptionMap = NULL; - ZeroMem (&UOpcode, sizeof(UOpcode)); *DataCount = 0; @@ -381,41 +461,12 @@ F2UCreateOneOfOpCode ( UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK; if (UOpcode.Question.QuestionId == 0) { - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { - UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key); + UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet); } - - OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP)); - ASSERT (OneOfOptionMap != NULL); - OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE; - OneOfOptionMap->QuestionId = UOpcode.Question.QuestionId; - InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead); - switch (FwOpcode->Width) { - case 1: - OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8; - break; - case 2: - OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_16; - break; - default: - ASSERT (FALSE); - break; - } - - InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link); } - - OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY)); - ASSERT (OneOfOptionMapEntry != NULL); - OneOfOptionMapEntry->FwKey = FwOneOfOp->Key; - OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE; - - CopyMem (&OneOfOptionMapEntry->Value, &FwOneOfOp->Value, FwOpcode->Width); - - ASSERT (OneOfOptionMap != NULL); - InsertTailList (&OneOfOptionMap->OneOfOptionMapEntryListHead, &OneOfOptionMapEntry->Link); } if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) { @@ -430,9 +481,9 @@ F2UCreateOneOfOpCode ( // // Assign QuestionId if still not assigned. // - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { - UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId); + UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet); } } @@ -447,10 +498,18 @@ F2UCreateOneOfOpCode ( // FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length); while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) { + + FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader; + Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData); if (EFI_ERROR (Status)) { return Status; } + + Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiData); + if (EFI_ERROR (Status)) { + return Status; + } FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length); *DataCount += 1; } @@ -533,9 +592,9 @@ F2UCreateOrderedListOpCode ( UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK; if (UOpcode.Question.QuestionId == 0) { - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { - UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key); + UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet); } } @@ -549,9 +608,9 @@ F2UCreateOrderedListOpCode ( } if (UOpcode.Question.QuestionId == 0) { - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { - UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId); + UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet); } } @@ -637,18 +696,18 @@ F2UCreateCheckBoxOpCode ( UOpcode.Question.Header.Help = FwOpcode->Help; if (FwOpcode->Key == 0) { - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { // // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId. // - UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId); + UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet); } } else { UOpcode.Question.QuestionId = FwOpcode->Key; } - UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID; + UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID; UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId; // @@ -746,12 +805,12 @@ F2UCreateNumericOpCode ( ZeroMem (&UOpcode, sizeof(UOpcode)); if (FwOpcode->Key == 0) { - Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); if (EFI_ERROR (Status)) { // // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId. // - UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId); + UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet); } } else { UOpcode.Question.QuestionId = FwOpcode->Key; @@ -887,7 +946,7 @@ F2UCreateStringOpCode ( ZeroMem (&UOpcode, sizeof(UOpcode)); if (FwOpcode->Key == 0) { - FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); + FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId); } else { UOpcode.Question.QuestionId = FwOpcode->Key; } @@ -899,7 +958,7 @@ F2UCreateStringOpCode ( UOpcode.Question.Header.Help = FwOpcode->Help; UOpcode.Question.QuestionId = FwOpcode->Key; - UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID; + UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID; UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId; UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED)); @@ -957,7 +1016,6 @@ EFI_STATUS FwUpdateDataToUefiUpdateData ( IN HII_THUNK_CONTEXT *ThunkContext, IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data, - IN BOOLEAN AddData, OUT EFI_HII_UPDATE_DATA **UefiData ) { diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.h index c56947539d..3cdc33a365 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.h @@ -105,7 +105,6 @@ EFI_STATUS FwUpdateDataToUefiUpdateData ( IN HII_THUNK_CONTEXT *ThunkContext, IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data, - IN BOOLEAN AddData, OUT EFI_HII_UPDATE_DATA **UefiData ); #endif diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c index 154b9cfa58..c88ad767b9 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c @@ -362,7 +362,7 @@ UefiRegisterPackageList ( // // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is - // not used as the name of the package list. A GUID is generated as a Package List + // not used as the name of the package list. Formset GUID is used as the Package List // GUID. // ASSERT (StringPackageCount >=1 && IfrPackageCount == 1); @@ -383,7 +383,9 @@ UefiRegisterPackageList ( // // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so - // that Setup Utility can load the Buffer Storage using this protocol. + // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only + // produce IFR package generated with Buffer Storage type and EFI Variable Storage. + // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage. // if (IfrPackageCount != 0) { InstallDefaultConfigAccessProtocol (Packages, ThunkContext); @@ -425,8 +427,10 @@ UefiRegisterPackageList ( if (IfrPackageCount == 0) { if (StringPackageCount != 0) { // - // Look for a Package List with only IFR Package with the same GUID name. - // If found one, add the String Packages to it. + // Look for a Package List with only IFR Package with the same TAG GUID name. + // If found one, add the String Packages to the found Package List. + // This is needed because Framework HII Module may not register the String Package + // and IFR Package in one NewPack () call. // UpdatePackListWithOnlyIfrPack ( Private, @@ -435,11 +439,12 @@ UefiRegisterPackageList ( ); } } else { - CreateQuestionIdMap (ThunkContext); - if (StringPackageCount == 0) { // - // Register the Package List to UEFI HII first. + // Look for the String Package with the same TAG GUID name and add + // the found String Package to this Package List. + // This is needed because Framework HII Module may not register the String Package + // and IFR Package in one NewPack () call. // Status = FindStringPackAndUpdatePackListWithOnlyIfrPack ( Private, @@ -450,6 +455,14 @@ UefiRegisterPackageList ( goto Done; } } + + // + // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so + // that String Package is ready. + // + ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle); + ASSERT (ThunkContext->FormSet != NULL); + } Done: @@ -468,6 +481,18 @@ Done: } +/** + + Registers the various packages that are passed in a Package List. + + @param This Pointer of Frameowk HII protocol instance. + @param Packages Pointer of HII packages. + @param Handle Handle value to be returned. + + @retval EFI_SUCCESS Pacakges has added to HII database successfully. + @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL. + +**/ EFI_STATUS EFIAPI HiiNewPack ( @@ -475,24 +500,6 @@ HiiNewPack ( IN EFI_HII_PACKAGES *Packages, OUT FRAMEWORK_EFI_HII_HANDLE *Handle ) -/*++ - -Routine Description: - - Extracts the various packs from a package list. - -Arguments: - - This - Pointer of HII protocol. - Packages - Pointer of HII packages. - Handle - Handle value to be returned. - -Returns: - - EFI_SUCCESS - Pacakges has added to HII database successfully. - EFI_INVALID_PARAMETER - Invalid parameter. - ---*/ { EFI_STATUS Status; HII_THUNK_PRIVATE_DATA *Private; @@ -509,10 +516,10 @@ Returns: OldTpl = gBS->RaiseTPL (TPL_NOTIFY); // - // We use a simple Global variable to inform NewPackNotify + // We use a simple Global variable to inform NewOrAddPackNotify() // that the package list registered here is already registered - // in the HII Thunk Layer. So NewPackNotify does not need to - // call RegisterUefiHiiHandle () to registered it. + // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to + // call registered the Package List again. // mInFrameworkHiiNewPack = TRUE; @@ -532,26 +539,27 @@ Returns: return Status; } +/** + + Remove a package from the HII database. + + @param This Pointer of Frameowk HII protocol instance. + @param Handle Handle value to be removed. + + @retval EFI_SUCCESS Pacakges has added to HII database successfully. + @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL. + +**/ EFI_STATUS EFIAPI HiiRemovePack ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle ) -/*++ - -Routine Description: - Removes the various packs from a Handle - -Arguments: - -Returns: - ---*/ { EFI_STATUS Status; - HII_THUNK_PRIVATE_DATA *Private; - HII_THUNK_CONTEXT *ThunkContext; + HII_THUNK_PRIVATE_DATA *Private; + HII_THUNK_CONTEXT *ThunkContext; EFI_TPL OldTpl; OldTpl = gBS->RaiseTPL (TPL_NOTIFY); @@ -584,6 +592,25 @@ Returns: return Status; } +/** + This notification function will be called when a Package List is registered + using UEFI HII interface. The Package List registered need to be recorded in + Framework Thunk module as Thunk Module may need to look for String Package in + the package registered. + + If the Package List registered is not either Sting Package or IFR package, + then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT. + Both cases means UEFI HII Database itself is buggy. + + @param PackageType The Package Type. + @param PackageGuid The Package GUID. + @param Package The Package Header. + @param Handle The HII Handle of this Package List. + @param NotifyType The reason of the notification. + + @retval EFI_SUCCESS The notification function is successful. + +**/ EFI_STATUS EFIAPI NewOrAddPackNotify ( @@ -609,8 +636,8 @@ NewOrAddPackNotify ( } // - // We only create a ThunkContext if the Uefi Hii Handle is only already registered - // by the HII Thunk Layer. + // We will create a ThunkContext to log the package list only if the + // package is not registered with by Framework HII Thunk module yet. // ThunkContext = UefiHiiHandleToThunkContext (Private, Handle); if (ThunkContext == NULL) { @@ -621,17 +648,38 @@ NewOrAddPackNotify ( } if (PackageType == EFI_HII_PACKAGE_FORMS) { - GetAttributesOfFirstFormSet (ThunkContext); + if (ThunkContext->FormSet != NULL) { + DestroyFormSet (ThunkContext->FormSet); + } + + // + // Reparse the FormSet. + // + ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle); + ASSERT (ThunkContext->FormSet != NULL); } return Status; } -// -// Framework HII module may cache a GUID as the name of the package list. -// Then search for the Framework HII handle database for the handle matching -// this GUID +/** + This notification function will be called when a Package List is removed + using UEFI HII interface. The Package List removed need to be removed from + Framework Thunk module too. + If the Package List registered is not Sting Package, + then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT. + Both cases means UEFI HII Database itself is buggy. + + @param PackageType The Package Type. + @param PackageGuid The Package GUID. + @param Package The Package Header. + @param Handle The HII Handle of this Package List. + @param NotifyType The reason of the notification. + + @retval EFI_SUCCESS The notification function is successful. + +**/ EFI_STATUS EFIAPI RemovePackNotify ( diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c index 5e391127cf..ebfbdeceb1 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c @@ -15,6 +15,26 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HiiDatabase.h" +/** + This is the Framework Setup Browser interface which displays a FormSet. + + @param This The EFI_FORM_BROWSER_PROTOCOL context. + @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation + only support UseDatabase is TRUE. + @param Handle The Handle buffer. + @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation. + @param Packet The pointer to data buffer containing IFR and String package. Not supported. + @param CallbackHandle Not supported. + @param NvMapOverride The buffer is used only when there is no NV variable to define the + current settings and the caller needs to provide to the browser the + current settings for the the "fake" NV variable. If used, no saving of + an NV variable is possbile. This parameter is also ignored if Handle is NULL. + + @retval EFI_SUCCESS If the Formset is displayed correctly. + @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1. + @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database. +**/ + EFI_STATUS EFIAPI ThunkSendForm ( @@ -75,6 +95,26 @@ ThunkSendForm ( return Status; } +/** + + Rountine used to display a generic dialog interface and return + the Key or Input from user input. + + @param NumberOfLines The number of lines for the dialog box. + @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue + or if a string is returned in StringBuffer. + @param MaximumStringSize The maximum size in bytes of a typed-in string. + @param StringBuffer On return contains the typed-in string if HotKey + is FALSE. + @param KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE. + @param String The pointer to the first string in the list of strings + that comprise the dialog box. + @param ... A series of NumberOfLines text strings that will be used + to construct the dialog box. + @retval EFI_SUCCESS The dialog is created successfully and user interaction was received. + @retval EFI_DEVICE_ERROR The user typed in an ESC. + @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE). +**/ EFI_STATUS EFIAPI ThunkCreatePopUp ( diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c index b46a31e37b..d89b8155e0 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c @@ -24,9 +24,9 @@ #include #include +#include "HiiDatabase.h" #include "UefiIfrParser.h" #include "UefiIfrDefault.h" -#include "HiiDatabase.h" // // Extern Variables @@ -36,216 +36,6 @@ extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol; extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol; extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol; -extern EFI_GUID gZeroGuid; - -/** - Fetch the Ifr binary data of a FormSet. - - @param Handle PackageList Handle - @param FormSetGuid GUID of a formset. If not specified (NULL or zero - GUID), take the first FormSet found in package - list. - @param BinaryLength The length of the FormSet IFR binary. - @param BinaryData The buffer designed to receive the FormSet. - - @retval EFI_SUCCESS Buffer filled with the requested FormSet. - BufferLength was updated. - @retval EFI_INVALID_PARAMETER The handle is unknown. - @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot - be found with the requested FormId. - -**/ -EFI_STATUS -GetIfrBinaryData ( - IN EFI_HII_HANDLE Handle, - IN OUT EFI_GUID *FormSetGuid, - OUT UINTN *BinaryLength, - OUT UINT8 **BinaryData - ) -{ - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; - UINTN BufferSize; - UINT8 *Package; - UINT8 *OpCodeData; - UINT32 Offset; - UINT32 Offset2; - BOOLEAN ReturnDefault; - UINT32 PackageListLength; - EFI_HII_PACKAGE_HEADER PackageHeader; - - OpCodeData = NULL; - Package = NULL; - ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));; - - // - // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list - // - if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) { - ReturnDefault = TRUE; - } else { - ReturnDefault = FALSE; - } - - // - // Get HII PackageList - // - BufferSize = 0; - HiiPackageList = NULL; - Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList); - if (Status == EFI_BUFFER_TOO_SMALL) { - HiiPackageList = AllocatePool (BufferSize); - ASSERT (HiiPackageList != NULL); - - Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList); - } - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get Form package from this HII package List - // - Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); - Offset2 = 0; - CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); - - while (Offset < PackageListLength) { - Package = ((UINT8 *) HiiPackageList) + Offset; - CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); - - if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) { - // - // Search FormSet in this Form Package - // - Offset2 = sizeof (EFI_HII_PACKAGE_HEADER); - while (Offset2 < PackageHeader.Length) { - OpCodeData = Package + Offset2; - - if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) { - // - // Check whether return default FormSet - // - if (ReturnDefault) { - break; - } - - // - // FormSet GUID is specified, check it - // - if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) { - break; - } - } - - Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; - } - - if (Offset2 < PackageHeader.Length) { - // - // Target formset found - // - break; - } - } - - Offset += PackageHeader.Length; - } - - if (Offset >= PackageListLength) { - // - // Form package not found in this Package List - // - gBS->FreePool (HiiPackageList); - return EFI_NOT_FOUND; - } - - if (ReturnDefault && FormSetGuid != NULL) { - // - // Return the default FormSet GUID - // - CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)); - } - - // - // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes - // in this FormSet; So, here just simply copy the data from start of a FormSet to the end - // of the Form Package. - // - *BinaryLength = PackageHeader.Length - Offset2; - *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData); - - gBS->FreePool (HiiPackageList); - - if (*BinaryData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - -/** - Initialize the internal data structure of a FormSet. - - @param Handle PackageList Handle - @param FormSetGuid GUID of a formset. If not specified (NULL or zero - GUID), take the first FormSet found in package - list. - @param FormSet FormSet data structure. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_FOUND The specified FormSet could not be found. - -**/ -EFI_STATUS -InitializeFormSet ( - IN EFI_HII_HANDLE Handle, - IN OUT EFI_GUID *FormSetGuid, - OUT FORM_BROWSER_FORMSET *FormSet - ) -{ - EFI_STATUS Status; - EFI_HANDLE DriverHandle; - - Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData); - if (EFI_ERROR (Status)) { - return Status; - } - - FormSet->HiiHandle = Handle; - CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID)); - - // - // Retrieve ConfigAccess Protocol associated with this HiiPackageList - // - Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle); - if (EFI_ERROR (Status)) { - return Status; - } - FormSet->DriverHandle = DriverHandle; - Status = gBS->HandleProtocol ( - DriverHandle, - &gEfiHiiConfigAccessProtocolGuid, - (VOID **) &FormSet->ConfigAccess - ); - if (EFI_ERROR (Status)) { - // - // Configuration Driver don't attach ConfigAccess protocol to its HII package - // list, then there will be no configuration action required - // - FormSet->ConfigAccess = NULL; - } - - // - // Parse the IFR binary OpCodes - // - Status = ParseOpCodes (FormSet); - if (EFI_ERROR (Status)) { - return Status; - } - return Status; -} - /** Set the data position at Offset with Width in Node->Buffer based the value passed in. @@ -276,6 +66,11 @@ SetNodeBuffer ( /** Reset Question to its default value. + Note Framework 0.92's HII Implementation does not support for default value for these opcodes: + EFI_IFR_ORDERED_LIST_OP: + EFI_IFR_PASSWORD_OP: + EFI_IFR_STRING_OP: + @param FormSet FormSet data structure. @param DefaultId The Class of the default. @@ -330,22 +125,10 @@ GetQuestionDefault ( Default = QUESTION_DEFAULT_FROM_LINK (Link); if (Default->DefaultId == DefaultId) { - if (Default->ValueExpression != NULL) { - // - // Default is provided by an Expression, evaluate it - // - Status = EvaluateExpression (FormSet, Form, Default->ValueExpression); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE)); - } else { - // - // Default value is embedded in EFI_IFR_DEFAULT - // - CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE)); - } + // + // Default value is embedded in EFI_IFR_DEFAULT + // + CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE)); SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth); return EFI_SUCCESS; @@ -580,41 +363,30 @@ GetBufferTypeDefaultId ( **/ EFI_STATUS UefiIfrGetBufferTypeDefaults ( - IN EFI_HII_HANDLE UefiHiiHandle, + IN HII_THUNK_CONTEXT *ThunkContext, OUT LIST_ENTRY **UefiDefaults ) { - FORM_BROWSER_FORMSET *FormSet; - EFI_GUID FormSetGuid; LIST_ENTRY *DefaultLink; FORMSET_DEFAULTSTORE *DefaultStore; EFI_STATUS Status; ASSERT (UefiDefaults != NULL); - FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); - ASSERT (FormSet != NULL); - - CopyGuid (&FormSetGuid, &gZeroGuid); - Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet); - ASSERT_EFI_ERROR (Status); - *UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY)); ASSERT (UefiDefaults != NULL); InitializeListHead (*UefiDefaults); - DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead); - while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) { + DefaultLink = GetFirstNode (&ThunkContext->FormSet->DefaultStoreListHead); + while (!IsNull (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink)) { DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink); - Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults); + Status = GetBufferTypeDefaultId (DefaultStore, ThunkContext->FormSet, *UefiDefaults); ASSERT_EFI_ERROR (Status); - DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink); + DefaultLink = GetNextNode (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink); } - DestroyFormSet (FormSet); - return EFI_SUCCESS; } @@ -642,6 +414,7 @@ EFI_STATUS UefiDefaultsToFwDefaults ( IN LIST_ENTRY *ListHead, IN UINTN DefaultMask, + IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId, OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList ) { @@ -713,9 +486,9 @@ UefiDefaultsToFwDefaults ( // // In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId. // So the default storage of Var Store in VFR from a Framework module - // should be translated to 0x0001 (RESERVED_VARSTORE_ID). + // should be translated to 0x0001 (FRAMEWORK_RESERVED_VARSTORE_ID). // - if (Node->StoreId == RESERVED_VARSTORE_ID) { + if (Node->StoreId == UefiFormSetDefaultVarStoreId) { Pack->VariableId = 0; } else { Pack->VariableId = Node->StoreId; diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h index 020c5e5cbc..4b0c61e5fb 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h @@ -45,8 +45,8 @@ typedef struct { **/ EFI_STATUS UefiIfrGetBufferTypeDefaults ( - EFI_HII_HANDLE UefiHiiHandle, - LIST_ENTRY **UefiDefaults + IN HII_THUNK_CONTEXT *ThunkContext, + OUT LIST_ENTRY **UefiDefaults ); /** @@ -73,6 +73,7 @@ EFI_STATUS UefiDefaultsToFwDefaults ( IN LIST_ENTRY *UefiIfrDefaults, IN UINTN DefaultMask, + IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId, OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList ); diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c index 8b130af45f..aacba8d416 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c @@ -12,22 +12,90 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#include "UefiIfrParser.h" -#include "UefiIfrParserExpression.h" -#include "UefiIfrParserInternal.h" -#include "UefiIfrParserCommon.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "UefiIfrParser.h" + +#include "UefiIfrParserExpression.h" UINT16 mStatementIndex; -UINT16 mExpressionOpCodeIndex; BOOLEAN mInScopeSubtitle; BOOLEAN mInScopeSuppress; BOOLEAN mInScopeGrayOut; -FORM_EXPRESSION *mSuppressExpression; -FORM_EXPRESSION *mGrayOutExpression; -EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; +EFI_GUID mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID; +extern EFI_GUID mTianoHiiIfrGuid; + +LIST_ENTRY * +GetOneOfOptionMapEntryListHead ( + IN CONST FORM_BROWSER_FORMSET *FormSet, + IN UINT16 QuestionId + ) +{ + LIST_ENTRY *Link; + ONE_OF_OPTION_MAP *Map; + + Link = GetFirstNode (&FormSet->OneOfOptionMapListHead); + + while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) { + Map = ONE_OF_OPTION_MAP_FROM_LINK (Link); + if (QuestionId == Map->QuestionId) { + return &Map->OneOfOptionMapEntryListHead; + } + Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link); + } + + return NULL; +} + +VOID +DestoryOneOfOptionMap ( + IN LIST_ENTRY *OneOfOptionMapListHead + ) +{ + ONE_OF_OPTION_MAP *Map; + ONE_OF_OPTION_MAP_ENTRY *MapEntry; + LIST_ENTRY *Link; + LIST_ENTRY *Link2; + + while (!IsListEmpty (OneOfOptionMapListHead)) { + Link = GetFirstNode (OneOfOptionMapListHead); + + Map = ONE_OF_OPTION_MAP_FROM_LINK (Link); + + while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) { + Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead); + + MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2); + + RemoveEntryList (Link2); + + FreePool (MapEntry); + } + + RemoveEntryList (Link); + FreePool (Map); + } +} + /** Initialize Statement header members. @@ -61,8 +129,6 @@ CreateStatement ( InitializeListHead (&Statement->DefaultListHead); InitializeListHead (&Statement->OptionListHead); - InitializeListHead (&Statement->InconsistentListHead); - InitializeListHead (&Statement->NoSubmitListHead); Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE; @@ -72,14 +138,6 @@ CreateStatement ( CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID)); CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID)); - if (mInScopeSuppress) { - Statement->SuppressExpression = mSuppressExpression; - } - - if (mInScopeGrayOut) { - Statement->GrayOutExpression = mGrayOutExpression; - } - Statement->InSubtitle = mInScopeSubtitle; // @@ -90,7 +148,6 @@ CreateStatement ( return Statement; } - /** Initialize Question's members. @@ -112,7 +169,6 @@ CreateQuestion ( EFI_IFR_QUESTION_HEADER *QuestionHdr; LIST_ENTRY *Link; FORMSET_STORAGE *Storage; - NAME_VALUE_NODE *NameValueNode; Statement = CreateStatement (OpCodeData, FormSet, Form); if (Statement == NULL) { @@ -124,6 +180,10 @@ CreateQuestion ( CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID)); CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16)); + if (FormSet->MaxQuestionId < QuestionHdr->QuestionId) { + FormSet->MaxQuestionId = QuestionHdr->QuestionId; + } + Statement->QuestionFlags = QuestionHdr->Flags; if (Statement->VarStoreId == 0) { @@ -149,59 +209,9 @@ CreateQuestion ( } ASSERT (Statement->Storage != NULL); - // - // Initialilze varname for Name/Value or EFI Variable - // - if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) || - (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) { - Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle); - ASSERT (Statement->VariableName != NULL); - - if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { - // - // Insert to Name/Value varstore list - // - NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE)); - ASSERT (NameValueNode != NULL); - NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE; - NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName); - ASSERT (NameValueNode->Name != NULL); - NameValueNode->Value = AllocateZeroPool (0x10); - ASSERT (NameValueNode->Value != NULL); - NameValueNode->EditValue = AllocateZeroPool (0x10); - ASSERT (NameValueNode->EditValue != NULL); - - InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link); - } - } - return Statement; } - -/** - Allocate a FORM_EXPRESSION node. - - @param Form The Form associated with this Expression - - @return Pointer to a FORM_EXPRESSION data structure. - -**/ -FORM_EXPRESSION * -CreateExpression ( - IN OUT FORM_BROWSER_FORM *Form - ) -{ - FORM_EXPRESSION *Expression; - - Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION)); - Expression->Signature = FORM_EXPRESSION_SIGNATURE; - InitializeListHead (&Expression->OpCodeListHead); - - return Expression; -} - - /** Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List. @@ -219,185 +229,11 @@ CreateStorage ( Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE)); Storage->Signature = FORMSET_STORAGE_SIGNATURE; - InitializeListHead (&Storage->NameValueListHead); InsertTailList (&FormSet->StorageListHead, &Storage->Link); return Storage; } - -/** - Create ConfigHdr string for a storage. - - @param FormSet Pointer of the current FormSet - @param Storage Pointer of the storage - - @retval EFI_SUCCESS Initialize ConfigHdr success - -**/ -EFI_STATUS -InitializeConfigHdr ( - IN FORM_BROWSER_FORMSET *FormSet, - IN OUT FORMSET_STORAGE *Storage - ) -{ - EFI_STATUS Status; - UINTN StrBufferLen; - CHAR16 *Name; - - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { - Name = Storage->Name; - } else { - Name = NULL; - } - - StrBufferLen = 0; - Status = ConstructConfigHdr ( - Storage->ConfigHdr, - &StrBufferLen, - &Storage->Guid, - Name, - FormSet->DriverHandle - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - Storage->ConfigHdr = AllocateZeroPool (StrBufferLen); - Status = ConstructConfigHdr ( - Storage->ConfigHdr, - &StrBufferLen, - &Storage->Guid, - Name, - FormSet->DriverHandle - ); - } - - if (EFI_ERROR (Status)) { - return Status; - } - - Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr); - Storage->SpareStrLen = 0; - - return EFI_SUCCESS; -} - - -/** - Initialize Request Element of a Question. ::= '&' | '&'