From 7e3bcccb0eed449e95c18b01ae8cbace1a759d01 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Mon, 13 Apr 2009 06:05:15 +0000 Subject: Update UefiHiiLib to support new defined IFR related HII APIs. Apply new defined IFR related HII APIs in PlatOverMngr, DriverSample, IScsiDxe and Setup drivers. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8066 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Application/PlatOverMngr/PlatOverMngr.c | 309 ++- .../Application/PlatOverMngr/PlatOverMngr.h | 2 + .../Application/PlatOverMngr/PlatOverMngr.inf | 3 +- MdeModulePkg/Application/PlatOverMngr/Vfr.vfr | 1 - MdeModulePkg/Include/Library/HiiLib.h | 939 ++++++++ MdeModulePkg/Include/Library/NewHiiLib.h | 28 + MdeModulePkg/Library/NewHiiLib/HiiLib.c | 76 +- MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c | 8 +- MdeModulePkg/Library/UefiHiiLib/HiiLib.c | 2330 +++++++++++++++++++- MdeModulePkg/Library/UefiHiiLib/HiiString.c | 12 +- MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h | 3 + MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf | 15 +- .../Universal/DriverSampleDxe/DriverSample.c | 433 ++-- .../Universal/DriverSampleDxe/DriverSample.h | 2 - .../Universal/DriverSampleDxe/DriverSampleDxe.inf | 5 +- .../Universal/DriverSampleDxe/NVDataStruc.h | 6 + MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr | 5 +- .../Universal/Network/IScsiDxe/IScsiConfig.c | 74 +- .../Universal/Network/IScsiDxe/IScsiConfig.h | 3 +- .../Universal/Network/IScsiDxe/IScsiConfigDxe.vfr | 2 - .../Network/IScsiDxe/IScsiConfigNVDataStruc.h | 1 + .../Universal/Network/IScsiDxe/IScsiDxe.inf | 3 +- MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c | 37 +- MdeModulePkg/Universal/SetupBrowserDxe/Setup.h | 1 - .../Universal/SetupBrowserDxe/SetupBrowserDxe.inf | 4 +- 25 files changed, 3839 insertions(+), 463 deletions(-) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.c b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.c index d9a5302..64a26c6 100644 --- a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.c +++ b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.c @@ -38,6 +38,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -46,12 +47,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include -#include -#include #include #include #include +#include + #include "PlatOverMngr.h" #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k') @@ -88,6 +88,7 @@ extern UINT8 PlatOverMngrStrings[]; // module global data // EFI_GUID mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID; +CHAR16 mVariableName[] = L"Data"; LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase); EFI_HANDLE *mDevicePathHandleBuffer; @@ -103,6 +104,7 @@ EFI_DEVICE_PATH_PROTOCOL *mControllerDevicePathProtocol[MAX_CHOICE_NUM]; UINTN mSelectedDriverImageNum; UINTN mLastSavedDriverImageNum; UINT16 mCurrentPage; +EFI_CALLBACK_INFO *mCallbackInfo; HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = { { @@ -114,10 +116,7 @@ HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = { (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) } }, - // - // {99936717-BF3D-4b04-9787-76CEE324D76F} - // - { 0x99936717, 0xbf3d, 0x4b04, { 0x97, 0x87, 0x76, 0xce, 0xe3, 0x24, 0xd7, 0x6f } } + EFI_CALLER_ID_GUID }, { END_DEVICE_PATH_TYPE, @@ -345,7 +344,6 @@ UpdateDeviceSelectPage ( IN PLAT_OVER_MNGR_DATA *FakeNvData ) { - EFI_HII_UPDATE_DATA UpdateData; EFI_STATUS Status; UINTN Index; UINTN DevicePathHandleCount; @@ -356,9 +354,13 @@ UpdateDeviceSelectPage ( EFI_PCI_IO_PROTOCOL *PciIo; EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; UINTN Len; - + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + // - // set current page form ID. + // Set current page form ID. // mCurrentPage = FORM_ID_DEVICE; @@ -366,25 +368,40 @@ UpdateDeviceSelectPage ( // Initial the mapping database in memory // FreeMappingDatabase (&mMappingDataBase); - Status = InitOverridesMapping (&mMappingDataBase); + InitOverridesMapping (&mMappingDataBase); + + // + // Init OpCode Handle + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode // - // Clear all the content in the first page + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = FORM_ID_DEVICE; + // - UpdateData.BufferSize = UPDATE_DATA_SIZE; - UpdateData.Offset = 0; - UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE); - ASSERT (UpdateData.Data != NULL); + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + // // Clear first page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_DEVICE, - FORM_ID_DEVICE, - FALSE, - &UpdateData + StartOpCodeHandle, // Label FORM_ID_DEVICE + EndOpCodeHandle // LABEL_END ); // @@ -499,30 +516,31 @@ UpdateDeviceSelectPage ( // Save the device path string toke for next access use // mControllerToken[Index] = NewStringToken; - - CreateGotoOpCode ( + + HiiCreateGotoOpCode ( + StartOpCodeHandle, FORM_ID_DRIVER, NewStringToken, STRING_TOKEN (STR_GOTO_HELP_DRIVER), EFI_IFR_FLAG_CALLBACK, - (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET), - &UpdateData + (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET) ); } // // Update first page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_DEVICE, - FORM_ID_DEVICE, - FALSE, - &UpdateData + StartOpCodeHandle, // Label FORM_ID_DEVICE + EndOpCodeHandle // LABEL_END ); - FreePool (UpdateData.Data); + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + return EFI_SUCCESS; } @@ -613,7 +631,6 @@ UpdateBindingDriverSelectPage ( IN PLAT_OVER_MNGR_DATA *FakeNvData ) { - EFI_HII_UPDATE_DATA UpdateData; EFI_STATUS Status; UINTN Index; CHAR16 *NewString; @@ -626,6 +643,10 @@ UpdateBindingDriverSelectPage ( EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; EFI_HANDLE DriverBindingHandle; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; // // If user select a controller item in the first page the following code will be run. @@ -641,26 +662,42 @@ UpdateBindingDriverSelectPage ( // Switch the item callback key value to its NO. in mDevicePathHandleBuffer // mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET; - ASSERT (mSelectedCtrIndex > 0 && mSelectedCtrIndex < MAX_CHOICE_NUM); + ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM); mLastSavedDriverImageNum = 0; + // - // Clear all the content in dynamic page + // Init OpCode Handle // - UpdateData.BufferSize = UPDATE_DATA_SIZE; - UpdateData.Offset = 0; - UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE); - ASSERT (UpdateData.Data != NULL); + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = FORM_ID_DRIVER; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + // // Clear second page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_DRIVER, - FORM_ID_DRIVER, - FALSE, - &UpdateData + StartOpCodeHandle, + EndOpCodeHandle ); // @@ -816,7 +853,8 @@ UpdateBindingDriverSelectPage ( FreePool (NewString); FreePool (DriverName); - CreateCheckBoxOpCode ( + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index), VARSTORE_ID_PLAT_OVER_MNGR, (UINT16) (DRIVER_SELECTION_VAR_OFFSET + Index), @@ -824,23 +862,23 @@ UpdateBindingDriverSelectPage ( NewStringHelpToken, 0, 0, - &UpdateData + NULL ); } // // Update second page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_DRIVER, - FORM_ID_DRIVER, - FALSE, - &UpdateData + StartOpCodeHandle, // Label FORM_ID_DRIVER + EndOpCodeHandle // LABEL_END ); - FreePool (UpdateData.Data); + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); return EFI_SUCCESS; } @@ -862,15 +900,19 @@ UpdatePrioritySelectPage ( IN PLAT_OVER_MNGR_DATA *FakeNvData ) { - EFI_HII_UPDATE_DATA UpdateData; UINTN Index; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; - IFR_OPTION *IfrOptionList; UINTN SelectedDriverImageNum; UINT32 DriverImageNO; UINTN MinNO; UINTN Index1; UINTN TempNO[100]; + UINTN OrderNO[100]; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + VOID *OptionsOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; // // Following code will be run if user select 'order ... priority' item in second page @@ -878,20 +920,38 @@ UpdatePrioritySelectPage ( // mCurrentPage = FORM_ID_ORDER; - UpdateData.BufferSize = UPDATE_DATA_SIZE; - UpdateData.Offset = 0; - UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE); - ASSERT (UpdateData.Data != NULL); + // + // Init OpCode Handle + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = FORM_ID_ORDER; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + // // Clear third page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_ORDER, - FORM_ID_ORDER, - FALSE, - &UpdateData + StartOpCodeHandle, + EndOpCodeHandle ); // @@ -908,21 +968,26 @@ UpdatePrioritySelectPage ( if (SelectedDriverImageNum == 0) { return EFI_SUCCESS; } - - IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * mSelectedDriverImageNum); - ASSERT (IfrOptionList != NULL); + + OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle != NULL); + // // Create order list for those selected drivers // SelectedDriverImageNum = 0; for (Index = 0; Index < mDriverImageHandleCount; Index++) { if (FakeNvData->DriSelection[Index] != 0) { - IfrOptionList[SelectedDriverImageNum].StringToken = mDriverImageToken[Index]; // // Use the NO. in driver binding buffer as value, will use it later // - IfrOptionList[SelectedDriverImageNum].Value.u8 = (UINT8) (Index + 1); - IfrOptionList[SelectedDriverImageNum].Flags = 0; + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + mDriverImageToken[Index], + 0, + EFI_IFR_NUMERIC_SIZE_1, + Index + 1 + ); // // Get the EFI Loaded Image Device Path Protocol @@ -951,6 +1016,7 @@ UpdatePrioritySelectPage ( mLastSavedDriverImageNum++; } TempNO[SelectedDriverImageNum] = DriverImageNO; + OrderNO[SelectedDriverImageNum] = Index + 1; SelectedDriverImageNum ++; } } @@ -978,11 +1044,15 @@ UpdatePrioritySelectPage ( // // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer // - FakeNvData->DriOrder[Index] =IfrOptionList[MinNO].Value.u8; + FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO]; TempNO[MinNO] = MAX_CHOICE_NUM + 1; } - - CreateOrderedListOpCode ( + + // + // Create Order List OpCode + // + HiiCreateOrderedListOpCode ( + StartOpCodeHandle, (UINT16) DRIVER_ORDER_QUESTION_ID, VARSTORE_ID_PLAT_OVER_MNGR, (UINT16) DRIVER_ORDER_VAR_OFFSET, @@ -992,25 +1062,25 @@ UpdatePrioritySelectPage ( 0, EFI_IFR_NUMERIC_SIZE_1, (UINT8) MAX_CHOICE_NUM, - IfrOptionList, - SelectedDriverImageNum, - &UpdateData + OptionsOpCodeHandle, + NULL ); // // Update third page form // - IfrLibUpdateForm ( + HiiUpdateForm ( Private->RegisteredHandle, &mPlatformOverridesManagerGuid, FORM_ID_ORDER, - FORM_ID_ORDER, - FALSE, - &UpdateData + StartOpCodeHandle, // Label FORM_ID_ORDER + EndOpCodeHandle // LABEL_END ); - FreePool (IfrOptionList); - FreePool (UpdateData.Data); + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + HiiFreeOpCodeHandle (OptionsOpCodeHandle); + return EFI_SUCCESS; } @@ -1102,7 +1172,7 @@ PlatOverMngrExtractConfig ( EFI_STATUS Status; EFI_CALLBACK_INFO *Private; EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; - + if (Request == NULL) { return EFI_NOT_FOUND; } @@ -1148,18 +1218,13 @@ PlatOverMngrRouteConfig ( ) { EFI_CALLBACK_INFO *Private; - EFI_STATUS Status; UINT16 KeyValue; - UINTN BufferSize; PLAT_OVER_MNGR_DATA *FakeNvData; - Private = EFI_CALLBACK_INFO_FROM_THIS (This); - - FakeNvData = &Private->FakeNvData; - BufferSize = sizeof (PLAT_OVER_MNGR_DATA); - Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) FakeNvData); - if (EFI_ERROR (Status)) { - return Status; + Private = EFI_CALLBACK_INFO_FROM_THIS (This); + FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA)); + if (FakeNvData == NULL) { + return EFI_NOT_FOUND; } if (mCurrentPage == FORM_ID_DRIVER) { @@ -1178,6 +1243,11 @@ PlatOverMngrRouteConfig ( KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT; CommintChanges (Private, KeyValue, FakeNvData); } + + if (FakeNvData != NULL) { + FreePool (FakeNvData); + } + return EFI_SUCCESS; } @@ -1216,17 +1286,13 @@ PlatOverMngrCallback ( EFI_CALLBACK_INFO *Private; EFI_STATUS Status; EFI_STRING_ID NewStringToken; - UINTN BufferSize; - PLAT_OVER_MNGR_DATA *FakeNvData; EFI_INPUT_KEY Key; - + PLAT_OVER_MNGR_DATA *FakeNvData; + Private = EFI_CALLBACK_INFO_FROM_THIS (This); - - FakeNvData = &Private->FakeNvData; - BufferSize = sizeof (PLAT_OVER_MNGR_DATA); - Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) FakeNvData); - if (EFI_ERROR (Status)) { - return Status; + FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA)); + if (FakeNvData == NULL) { + return EFI_NOT_FOUND; } if (KeyValue == KEY_VALUE_DEVICE_REFRESH || @@ -1285,8 +1351,15 @@ PlatOverMngrCallback ( // // Pass changed uncommitted data back to Form Browser // - BufferSize = sizeof (PLAT_OVER_MNGR_DATA); - Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) FakeNvData, NULL); + HiiSetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL); + + // + // Update local configuration buffer. + // + CopyMem (&Private->FakeNvData, FakeNvData, sizeof (PLAT_OVER_MNGR_DATA)); + if (FakeNvData != NULL) { + FreePool (FakeNvData); + } return EFI_SUCCESS; } @@ -1312,7 +1385,6 @@ PlatOverMngrInit ( EFI_STATUS Status; EFI_HII_DATABASE_PROTOCOL *HiiDatabase; EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_CALLBACK_INFO *CallbackInfo; EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; // @@ -1339,25 +1411,25 @@ PlatOverMngrInit ( return Status; } - CallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO)); - if (CallbackInfo == NULL) { + mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO)); + if (mCallbackInfo == NULL) { return EFI_BAD_BUFFER_SIZE; } - CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE; - CallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig; - CallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig; - CallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback; + mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE; + mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig; + mCallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig; + mCallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback; // // Install Device Path Protocol and Config Access protocol to driver handle // Status = gBS->InstallMultipleProtocolInterfaces ( - &CallbackInfo->DriverHandle, + &mCallbackInfo->DriverHandle, &gEfiDevicePathProtocolGuid, &mHiiVendorDevicePath, &gEfiHiiConfigAccessProtocolGuid, - &CallbackInfo->ConfigAccess, + &mCallbackInfo->ConfigAccess, NULL ); if (EFI_ERROR (Status)) { @@ -1378,8 +1450,8 @@ PlatOverMngrInit ( Status = HiiDatabase->NewPackageList ( HiiDatabase, PackageList, - CallbackInfo->DriverHandle, - &CallbackInfo->RegisteredHandle + mCallbackInfo->DriverHandle, + &mCallbackInfo->RegisteredHandle ); FreePool (PackageList); @@ -1393,7 +1465,7 @@ PlatOverMngrInit ( Status = gBS->LocateProtocol ( &gEfiHiiConfigRoutingProtocolGuid, NULL, - (VOID **) &CallbackInfo->HiiConfigRouting + (VOID **) &mCallbackInfo->HiiConfigRouting ); if (EFI_ERROR (Status)) { goto Finish; @@ -1414,37 +1486,34 @@ PlatOverMngrInit ( // Status = FormBrowser2->SendForm ( FormBrowser2, - &CallbackInfo->RegisteredHandle, + &mCallbackInfo->RegisteredHandle, 1, NULL, 0, NULL, NULL ); - if (EFI_ERROR (Status)) { - goto Finish; - } - Status = HiiDatabase->RemovePackageList (HiiDatabase, CallbackInfo->RegisteredHandle); + HiiDatabase->RemovePackageList (HiiDatabase, mCallbackInfo->RegisteredHandle); + if (EFI_ERROR (Status)) { goto Finish; } - - return EFI_SUCCESS; Finish: - if (CallbackInfo->DriverHandle != NULL) { + if (mCallbackInfo->DriverHandle != NULL) { gBS->UninstallMultipleProtocolInterfaces ( - CallbackInfo->DriverHandle, + mCallbackInfo->DriverHandle, &gEfiDevicePathProtocolGuid, &mHiiVendorDevicePath, &gEfiHiiConfigAccessProtocolGuid, - &CallbackInfo->ConfigAccess, + &mCallbackInfo->ConfigAccess, NULL ); } - if (CallbackInfo != NULL) { - FreePool (CallbackInfo); + + if (mCallbackInfo != NULL) { + FreePool (mCallbackInfo); } return Status; diff --git a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.h b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.h index 12bbf6a..2d73d0e 100644 --- a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.h +++ b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.h @@ -47,6 +47,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define VARSTORE_ID_PLAT_OVER_MNGR 0x1000 +#define LABEL_END 0xffff + typedef struct { UINT8 DriSelection[MAX_CHOICE_NUM]; UINT8 DriOrder[MAX_CHOICE_NUM]; diff --git a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf index 6b42f05..0d5ea88 100644 --- a/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf +++ b/MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf @@ -57,8 +57,6 @@ UefiBootServicesTableLib PlatformDriverOverrideLib HiiLib - IfrSupportLib - ExtendedIfrSupportLib BaseMemoryLib MemoryAllocationLib DevicePathLib @@ -67,6 +65,7 @@ ## This GUID C Name is not required for build since it is from UefiLib and not directly used by this module source. ## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"PlatformLang" this variable specifies the platform supported language string (RFC 4646 format) ## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"Lang" this variable specifies the platform supported language string (ISO 639-2 format) + gEfiIfrTianoGuid ## CONSUMES ## Guid [Protocols] gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name if ComponentName2Protocol exists) diff --git a/MdeModulePkg/Application/PlatOverMngr/Vfr.vfr b/MdeModulePkg/Application/PlatOverMngr/Vfr.vfr index b3cd038..a68073f 100644 --- a/MdeModulePkg/Application/PlatOverMngr/Vfr.vfr +++ b/MdeModulePkg/Application/PlatOverMngr/Vfr.vfr @@ -23,7 +23,6 @@ #include "PlatOverMngr.h" #define EFI_DISK_DEVICE_CLASS 0x01 -#define LABEL_END 0xffff formset guid = PLAT_OVER_MNGR_GUID, diff --git a/MdeModulePkg/Include/Library/HiiLib.h b/MdeModulePkg/Include/Library/HiiLib.h index e5c33d8..fa1963b 100644 --- a/MdeModulePkg/Include/Library/HiiLib.h +++ b/MdeModulePkg/Include/Library/HiiLib.h @@ -512,4 +512,943 @@ Rfc3066ToIso639 ( ) ; + +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +// HiiLib Functions +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// + +/** + Registers a list of packages in the HII Database and returns the HII Handle + associated with that registration. If an HII Handle has already been registered + with the same PackageListGuid, then NULL is returned. If there are not enough + resources to perform the registration, then NULL is returned. If an empty list + of packages is passed in, then NULL is returned. If the size of the list of + package is 0, then NULL is returned. + + @param[in] PackageListGuid An optional parameter that is used to identify + the GUID of the package list. If this parameter + is NULL, then gEfiCallerIdGuid is used. + @param[in] DeviceHandle Optional. If not NULL, the Device Handle on which + an instance of DEVICE_PATH_PROTOCOL is installed. + This Device Handle uniquely defines the device that + the added packages are associated with. + @param[in] ... The variable argument list that contains pointers + to packages terminated by a NULL. + + @retval NULL A HII Handle has already been registered in the HII Database with + the same PackageListGuid. + @retval NULL The HII Handle could not be created. + @retval Other The HII Handle associated with the newly registered package list. + +**/ +EFI_HII_HANDLE +EFIAPI +HiiAddPackages ( + IN CONST EFI_GUID *PackageListGuid, OPTIONAL + IN EFI_HANDLE DeviceHandle, OPTIONAL + ... + ); + +/** + Removes a package list from the HII Database. + + If HiiHandle is NULL, then ASSERT(). + If HiiHandle is not a valid EFI_HII_HANDLE in the HII Database, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + +**/ +VOID +EFIAPI +HiiRemovePackages ( + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Retrieves the array of all the HII Handles in the HII Database. + This array is terminated with a NULL HII Handle. + This function allocates the returned array using AllocatePool(). + The caller is responsible for freeing the array with FreePool(). + + @param[in] PackageListGuid An optional parameter that is used to request + an HII Handle that is associatd with a specific + Package List GUID. If this parameter is NULL + then all the HII Handles in the HII Database + are returned. If this parameter is not NULL + then at most 1 HII Handle is returned. + + @retval NULL There are no HII handles in the HII database + @retval NULL The array of HII Handles could not be retrieved + @retval Other A pointer to the NULL terminated array of HII Handles + +**/ +EFI_HII_HANDLE * +EFIAPI +HiiGetHiiHandles ( + IN CONST EFI_GUID *PackageListGuid OPTIONAL + ); + +/** + Retrieves a pointer to the a Null-terminated ASCII string containing the list + of languages that an HII handle in the HII Database supports. The returned + string is allocated using AllocatePool(). The caller is responsible for freeing + the returned string using FreePool(). The format of the returned string follows + the language format assumed the HII Database. + + If HiiHandle is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + + @retval NULL HiiHandle is not registered in the HII database + @retval NULL There are not enough resources available to retrieve the suported + languages. + @retval NULL The list of suported languages could not be retrieved. + @retval Other A pointer to the Null-terminated ASCII string of supported languages. + +**/ +CHAR8 * +EFIAPI +HiiGetSupportedLanguages ( + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Retrieves a string from a string package in a specific language. If the language + is not specified, then a string from a string package in the current platform + language is retrieved. If the string can not be retrieved using the specified + language or the current platform language, then the string is retrieved from + the string package in the first language the string package supports. The + returned string is allocated using AllocatePool(). The caller is responsible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + @param[in] StringId The identifier of the string to retrieved from the string + package associated with HiiHandle. + @param[in] Language The language of the string to retrieve. If this parameter + is NULL, then the current platform language is used. The + format of Language must follow the language format assumed + the HII Database. + + @retval NULL The string specified by StringId is not present in the string package. + @retval Other The string was returned. + +**/ +EFI_STRING +EFIAPI +HiiGetString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language OPTIONAL + ); + +/** + Retrieves a string from a string package names by GUID in a specific language. + If the language is not specified, then a string from a string package in the + current platform language is retrieved. If the string can not be retrieved + using the specified language or the current platform language, then the string + is retrieved from the string package in the first language the string package + supports. The returned string is allocated using AllocatePool(). The caller + is responsible for freeing the allocated buffer using FreePool(). + + If PackageListGuid is NULL, then ASSERT(). + If StringId is 0, then ASSET. + + @param[in] PackageListGuid The GUID of a package list that was previously + registered in the HII Database. + @param[in] StringId The identifier of the string to retrieved from the + string package associated with PackageListGuid. + @param[in] Language The language of the string to retrieve. If this + parameter is NULL, then the current platform + language is used. The format of Language must + follow the language format assumed the HII Database. + + @retval NULL The package list specified by PackageListGuid is not present in the + HII Database. + @retval NULL The string specified by StringId is not present in the string package. + @retval Other The string was returned. + +**/ +EFI_STRING +EFIAPI +HiiGetPackageString ( + IN CONST EFI_GUID *PackageListGuid, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language OPTIONAL + ); + +/** + This function create a new string in String Package or updates an existing + string in a String Package. If StringId is 0, then a new string is added to + a String Package. If StringId is not zero, then a string in String Package is + updated. If SupportedLanguages is NULL, then the string is added or updated + for all the languages that the String Package supports. If SupportedLanguages + is not NULL, then the string is added or updated for the set of languages + specified by SupportedLanguages. + + If HiiHandle is NULL, then ASSERT(). + If String is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the + HII Database. + @param[in] StringId If zero, then a new string is created in the + String Package associated with HiiHandle. If + non-zero, then the string specified by StringId + is updated in the String Package associated + with HiiHandle. + @param[in] String A pointer to the Null-terminated Unicode string + to add or update in the String Package associated + with HiiHandle. + @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of + language codes. If this parameter is NULL, then + String is added or updated in the String Package + associated with HiiHandle for all the languages + that the String Package supports. If this + parameter is not NULL, then then String is added + or updated in the String Package associated with + HiiHandle for the set oflanguages specified by + SupportedLanguages. The format of + SupportedLanguages must follow the language + format assumed the HII Database. + + @retval 0 The string could not be added or updated in the String Package. + @retval Other The EFI_STRING_ID of the newly added or updated string. + +**/ +EFI_STRING_ID +EFIAPI +HiiSetString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId, OPTIONAL + IN CONST EFI_STRING String, + IN CONST CHAR8 *SupportedLanguages OPTIONAL + ); + +/** + Validates the config data associated with an HII handle in the HII Database. + + If HiiHandle is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + + @retval TRUE The config data associated with HiiHandle passes all validation + checks. + @retval FALSE The config data associated with HiiHandle failed one or more + validation checks. + +**/ +BOOLEAN +EFIAPI +HiiValidateDataFromHiiHandle ( + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Allocates and returns a Null-terminated Unicode string using routing + information that includes a GUID, an optional Unicode string name, and a device + path. The string returned is allocated with AllocatePool(). The caller is + responsible for freeing the allocated string with FreePool(). + + The format of a is as follows: + + GUID=32&NAME=NameLength&PATH=DevicePathSize + + @param[in] Guid Pointer to an EFI_GUID that is the routing information + GUID. Each of the 16 bytes in Guid is converted to + a 2 Unicode character hexidecimal string. This is + an optional parameter that may be NULL. + @param[in] Name Pointer to a Null-terminated Unicode string that is + the routing information NAME. This is an optional + parameter that may be NULL. Each 16-bit Unicode + character in Name is converted to a 4 character Unicode + hexidecimal string. + @param[in] DriverHandle The driver handle which supports a Device Path Protocol + that is the routing information PATH. Each byte of + the Device Path associated with DriverHandle is converted + to a 2 Unicode character hexidecimal string. + + @retval NULL DriverHandle does not support the Device Path Protocol. + @retval NULL DriverHandle does not support the Device Path Protocol. + @retval Other A pointer to the Null-terminate Unicode string + +**/ +EFI_STRING +EFIAPI +HiiConstructConfigHdr ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN CONST CHAR16 *Name, OPTIONAL + IN EFI_HANDLE DriverHandle + ); + +/** + Allocates and returns a Null-terminated Unicode string. + + If Guid is NULL, then ASSERT(). + If Name is NULL, then ASSERT(). + If BlockNameArray is NULL, then ASSERT(). + + @param[in] Guid GUID of the buffer storage. + @param[in] Name Name of the buffer storage. + @param[in] DriverHandle The DriverHandle that support a Device Path + Protocol. + @param[in] BufferStorage Content of the buffer storage. + @param[in] BufferStorageSize Length in bytes of the buffer storage. + @param[in] BlockNameArray Array generated by VFR compiler. This array + contains a UINT32 value that is the length + of BlockNameArray in bytes, followed by pairs + of 16-bit values that are the offset and length + values used to contruct a string. + @param[in] ... A variable argument list that contains pairs of 16-bit + ALTCFG identifiers and pointers to DefaultValueArrays. + The variable argument list is terminated by a NULL + DefaultValueArray pointer. A DefaultValueArray + contains a UINT32 value that is the length, in bytes, + of the DefaultValueArray. The UINT32 length value + is followed by a series of records that contain + a 16-bit WIDTH value followed by a byte array with + WIDTH entries. The records must be parsed from + beginning to end until the UINT32 length limit + is reached. + + @retval NULL There are not enough resources to process the request. + @retval NULL A could not be retrieved from the Config + Routing Protocol. + @retval Other A pointer to the Null-terminate Unicode + string. + +**/ +EFI_STRING +EFIAPI +HiiConstructConfigAltResp ( + IN CONST EFI_GUID *Guid, + IN CONST CHAR16 *Name, + IN EFI_HANDLE DriverHandle, + IN CONST VOID *BufferStorage, + IN UINTN BufferStorageSize, + IN CONST VOID *BlockNameArray, + ... + ); + +/** + Determines if the routing data specified by GUID and NAME match a . + + If ConfigHdr is NULL, then ASSERT(). + + @param[in] ConfigHdr Either or . + @param[in] Guid GUID of the storage. + @param[in] Name NAME of the storage. + + @retval TRUE Routing information matches . + @retval FALSE Routing information does not match . + +**/ +BOOLEAN +EFIAPI +HiiIsConfigHdrMatch ( + IN CONST EFI_STRING ConfigHdr, + IN CONST EFI_GUID *Guid, OPTIONAL + IN CONST CHAR16 *Name OPTIONAL + ); + +/** + Retrieves uncommited data from the Form Browser and converts it to a binary + buffer. The returned buffer is allocated using AllocatePool(). The caller + is responsible for freeing the returned buffer using FreePool(). + + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] BufferSize Length in bytes of buffer to hold retrived data. + + @retval NULL The uncommitted data could not be retrieved. + @retval Other A pointer to a buffer containing the uncommitted data. + +**/ +UINT8 * +EFIAPI +HiiGetBrowserData ( + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName, OPTIONAL + IN UINTN BlockSize + ); + +/** + Updates uncommitted data in the Form Browser. + + If Buffer is NULL, then ASSERT(). + + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] BufferSize Length, in bytes, of Buffer. + @param[in] Buffer Buffer of data to commit. + @param[in] RequestElement An optional field to specify which part of the + buffer data will be send back to Browser. If NULL, + the whole buffer of data will be committed to + Browser. + ::= &OFFSET=&WIDTH=* + + @retval FALSE The uncommitted data could not be updated. + @retval TRUE The uncommitted data was updated. + +**/ +BOOLEAN +EFIAPI +HiiSetBrowserData ( + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName, OPTIONAL + IN UINTN BufferSize, + IN CONST UINT8 *Buffer, + IN CONST CHAR16 *RequestElement OPTIONAL + ); + +///////////////////////////////////////// +///////////////////////////////////////// +/// IFR Functions +///////////////////////////////////////// +///////////////////////////////////////// + +/** + Returns a UINT64 value that contains bitfields for Hour, Minute, and Second. + The lower 8-bits of Hour are placed in bits 0..7. The lower 8-bits of Minute + are placed in bits 8..15, and the lower 8-bits of Second are placed in bits + 16..23. This format is selected because it can be easily translated to + an EFI_HII_TIME structure in an EFI_IFR_TYPE_VALUE union. + + @param Hour The hour value to be encoded. + @param Minute The miniute value to be encoded. + @param Second The second value to be encoded. + + @return A 64-bit containing Hour, Minute, and Second. +**/ +#define EFI_HII_TIME_UINT64(Hour, Minute, Second) \ + (UINT64)((Hour & 0xff) | ((Minute & 0xff) << 8) | ((Second & 0xff) << 16)) + +/** + Returns a UINT64 value that contains bitfields for Year, Month, and Day. + The lower 16-bits of Year are placed in bits 0..15. The lower 8-bits of Month + are placed in bits 16..23, and the lower 8-bits of Day are placed in bits + 24..31. This format is selected because it can be easily translated to + an EFI_HII_DATE structure in an EFI_IFR_TYPE_VALUE union. + + @param Year The year value to be encoded. + @param Month The month value to be encoded. + @param Day The day value to be encoded. + + @return A 64-bit containing Year, Month, and Day. +**/ +#define EFI_HII_DATE_UINT64(Year, Month, Day) \ + (UINT64)((Year & 0xffff) | ((Month & 0xff) << 16) | ((Day & 0xff) << 24)) + +/** + Allocates and returns a new OpCode Handle. OpCode Handles must be freed with + HiiFreeOpCodeHandle(). + + @retval NULL There are not enough resources to allocate a new OpCode Handle. + @retval Other A new OpCode handle. + +**/ +VOID * +EFIAPI +HiiAllocateOpCodeHandle ( + VOID + ); + +/** + Frees an OpCode Handle that was peviously allocated with HiiAllocateOpCodeHandle(). + When an OpCode Handle is freed, all of the opcodes associated with the OpCode + Handle are also freed. + + If OpCodeHandle is NULL, then ASSERT(). + +**/ +VOID +EFIAPI +HiiFreeOpCodeHandle ( + VOID *OpCodeHandle + ); + +/** + Create EFI_IFR_END_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateEndOpCode ( + IN VOID *OpCodeHandle + ); + +/** + Create EFI_IFR_ONE_OF_OPTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + If Flags is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] StringId StringId for the option + @param[in] Flags Flags for the option + @param[in] Type Type for the option + @param[in] Value Value for the option + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOptionOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 StringId, + IN UINT8 Flags, + IN UINT8 Type, + IN UINT64 Value + ); + +/** + Create EFI_IFR_DEFAULT_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] DefaultId DefaultId for the default + @param[in] Type Type for the default + @param[in] Value Value for the default + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateDefaultOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 DefaultId, + IN UINT8 Type, + IN UINT64 Value + ); + +/** + Create EFI_IFR_GUID opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Guid is NULL, then ASSERT(). + If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Guid Pointer to EFI_GUID of this guided opcode. + @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an + optional parameter that may be NULL. If this + parameter is NULL, then the GUID extension + region of the created opcode is filled with zeros. + If this parameter is not NULL, then the GUID + extension region of GuidData will be copied to + the GUID extension region of the created opcode. + @param[in] OpCodeSize The size, in bytes, of created opcode. This value + must be >= sizeof(EFI_IFR_GUID). + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGuidOpCode ( + IN VOID *OpCodeHandle, + IN CONST EFI_GUID *Guid, + IN CONST VOID *GuidOpCode, OPTIONAL + IN UINTN OpCodeSize + ); + +/** + Create EFI_IFR_ACTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionConfig String ID for configuration + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateActionOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_STRING_ID QuestionConfig + ); + +/** + Create EFI_IFR_SUBTITLE_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in Flags, then ASSERT(). + If Scope > 1, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] Flags Subtitle opcode flags + @param[in] Scope 1 if this opcpde is the beginning of a new scope. + 0 if this opcode is within the current scope. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateSubTitleOpCode ( + IN VOID *OpCodeHandle, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 Flags, + IN UINT8 Scope + ); + +/** + Create EFI_IFR_REF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] FormId Destination Form ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionId Question ID + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGotoOpCode ( + IN VOID *OpCodeHandle, + IN EFI_FORM_ID FormId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_QUESTION_ID QuestionId + ); + +/** + Create EFI_IFR_CHECKBOX_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in CheckBoxFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] CheckBoxFlags Flags for checkbox opcode + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateCheckBoxOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 CheckBoxFlags, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ); + +/** + Create EFI_IFR_NUMERIC_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in NumericFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] NumericFlags Flags for numeric opcode + @param[in] Minimum Numeric minimum value + @param[in] Maximum Numeric maximum value + @param[in] Step Numeric step for edit + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateNumericOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 NumericFlags, + IN UINT64 Minimum, + IN UINT64 Maximum, + IN UINT64 Step, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ); + +/** + Create EFI_IFR_STRING_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in StringFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] StringFlags Flags for string opcode + @param[in] MinSize String minimum length + @param[in] MaxSize String maximum length + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateStringOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 StringFlags, + IN UINT8 MinSize, + IN UINT8 MaxSize, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ); + +/** + Create EFI_IFR_ONE_OF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OneOfFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OneOfFlags Flags for oneof opcode + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OneOfFlags, + IN VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ); + +/** + Create EFI_IFR_ORDERED_LIST_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OrderedListFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OrderedListFlags Flags for ordered list opcode + @param[in] DataType Type for option value + @param[in] MaxContainers Maximum count for options in this ordered list + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOrderedListOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OrderedListFlags, + IN UINT8 DataType, + IN UINT8 MaxContainers, + IN VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ); + +/** + This function updates a form that has previously been registered with the HII + Database. This function will perform at most one update operation. + + The form to update is specified by Handle, FormSetGuid, and FormId. Binary + comparisons of IFR opcodes are performed from the beginning of the form being + updated until an IFR opcode is found that exactly matches the first IFR opcode + specifed by StartOpCodeHandle. The following rules are used to determine if + an insert, replace, or delete operation is performed. + + 1) If no matches are found, then NULL is returned. + 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes + from StartOpcodeHandle except the first opcode are inserted immediately after + the matching IFR opcode in the form beng updated. + 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made + from the matching IFR opcode until an IFR opcode exatly matches the first + IFR opcode specified by EndOpCodeHandle. If no match is found for the first + IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match + is found, then all of the IFR opcodes between the start match and the end + match are deleted from the form being updated and all of the IFR opcodes + from StartOpcodeHandle except the first opcode are inserted immediately after + the matching start IFR opcode. If StartOpCcodeHandle only contains one + IFR instruction, then the result of ths operation will delete all of the IFR + opcodes between the start end matches. + + If HiiHandle is NULL, then ASSERT(). + If StartOpCodeHandle is NULL, then ASSERT(). + + @param[in] HiiHandle The HII Handle of the form to update. + @param[in] FormSetGuid The Formset GUID of the form to update. This + is an optional parameter that may be NULL. + If it is NULL, all FormSet will be updated. + @param[in] FormId The ID of the form to update. + @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR + opcodes to be inserted or replaced in the form. + The first IFR instruction in StartOpCodeHandle + is used to find matching IFR opcode in the + form. + @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode + that marks the end of a replace operation in + the form. This is an optional parameter that + may be NULL. If it is NULL, then an the IFR + opcodes specified by StartOpCodeHandle are + inserted into the form. + + @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated. + @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND. + 1) The form specified by HiiHandle, FormSetGuid, + and FormId could not be found in the HII Database. + 2) No IFR opcodes in the target form match the first + IFR opcode in StartOpCodeHandle. + 3) EndOpCOde is not NULL, and no IFR opcodes in the + target form following a matching start opcode match + the first IFR opcode in EndOpCodeHandle. + @retval EFI_SUCCESS The matched form is updated by StartOpcode. + +**/ +EFI_STATUS +EFIAPI +HiiUpdateForm ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_GUID *FormSetGuid, OPTIONAL + IN EFI_FORM_ID FormId, + IN VOID *StartOpcodeHandle, + IN VOID *EndOpcodeHandle OPTIONAL + ); + +/** + Configure the buffer accrording to ConfigBody strings in the format of + , , , . + This ConfigBody strings is generated by EDKII UEFI VfrCompiler for the default + values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000 + constructed following this rule: + "Vfr" + varstore.name + "Default" + defaultstore.attributes. + Check the generated C file in Output for details. + + @param Buffer the start address of buffer. + @param BufferSize the size of buffer. + @param Number the number of the ConfigBody strings. + @param ... the ConfigBody strings + + @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate. + @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0. + @retval EFI_SUCCESS Operation successful. + +**/ +EFI_STATUS +EFIAPI +IfrLibExtractDefault( + IN VOID *Buffer, + IN UINTN *BufferSize, + UINTN Number, + ... + ); + #endif diff --git a/MdeModulePkg/Include/Library/NewHiiLib.h b/MdeModulePkg/Include/Library/NewHiiLib.h index 388a951..1983a65 100644 --- a/MdeModulePkg/Include/Library/NewHiiLib.h +++ b/MdeModulePkg/Include/Library/NewHiiLib.h @@ -925,4 +925,32 @@ HiiUpdateForm ( IN VOID *EndOpcodeHandle OPTIONAL ); +/** + Configure the buffer accrording to ConfigBody strings in the format of + , , , . + This ConfigBody strings is generated by EDKII UEFI VfrCompiler for the default + values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000 + constructed following this rule: + "Vfr" + varstore.name + "Default" + defaultstore.attributes. + Check the generated C file in Output for details. + + @param Buffer the start address of buffer. + @param BufferSize the size of buffer. + @param Number the number of the ConfigBody strings. + @param ... the ConfigBody strings + + @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate. + @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0. + @retval EFI_SUCCESS Operation successful. + +**/ +EFI_STATUS +EFIAPI +IfrLibExtractDefault( + IN VOID *Buffer, + IN UINTN *BufferSize, + UINTN Number, + ... + ); + #endif diff --git a/MdeModulePkg/Library/NewHiiLib/HiiLib.c b/MdeModulePkg/Library/NewHiiLib/HiiLib.c index 099ef54..06d51fa 100644 --- a/MdeModulePkg/Library/NewHiiLib/HiiLib.c +++ b/MdeModulePkg/Library/NewHiiLib/HiiLib.c @@ -794,7 +794,7 @@ InternalHiiLowerConfigString ( EFI_STRING String; BOOLEAN Lower; - ASSERT (String != NULL); + ASSERT (ConfigString != NULL); // // Convert all hex digits in range [A-F] in the configuration header to [a-f] @@ -2938,3 +2938,77 @@ Finish: return Status; } + +/** + Configure the buffer accrording to ConfigBody strings in the format of + , , , . + This ConfigBody strings is generated by UEFI VfrCompiler for the default + values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000 + constructed following this rule: + "Vfr" + varstore.name + "Default" + defaultstore.attributes. + Check the generated C file in Output for details. + + @param Buffer The start address of buffer. + @param BufferSize The size of buffer. + @param Number The number of the strings. + @param ... Variable argument list for default value in format + generated by the tool. + + @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate. + @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0. + @retval EFI_SUCCESS Operation successful. + +**/ +EFI_STATUS +EFIAPI +IfrLibExtractDefault( + IN VOID *Buffer, + IN UINTN *BufferSize, + UINTN Number, + ... + ) +{ + VA_LIST Args; + UINTN Index; + UINT32 TotalLen; + UINT8 *BufCfgArray; + UINT8 *BufferPos; + UINT16 Offset; + UINT16 Width; + UINT8 *Value; + + if ((Buffer == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Offset = 0; + Width = 0; + Value = NULL; + + VA_START (Args, Number); + for (Index = 0; Index < Number; Index++) { + BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *); + TotalLen = ReadUnaligned32 ((UINT32 *)BufCfgArray); + BufferPos = BufCfgArray + sizeof (UINT32); + + while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) { + Offset = ReadUnaligned16 ((UINT16 *)BufferPos); + BufferPos += sizeof (UINT16); + Width = ReadUnaligned16 ((UINT16 *)BufferPos); + BufferPos += sizeof (UINT16); + Value = BufferPos; + BufferPos += Width; + + if ((UINTN)(Offset + Width) > *BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + CopyMem ((UINT8 *)Buffer + Offset, Value, Width); + } + } + VA_END (Args); + + *BufferSize = (UINTN)Offset; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c b/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c index 3aef712..2117329 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c @@ -90,7 +90,7 @@ HiiLibGetSupportedLanguages ( return NULL; } - Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize); + Status = gHiiString->GetLanguages (gHiiString, HiiHandle, LanguageString, &BufferSize); if (Status == EFI_BUFFER_TOO_SMALL) { FreePool (LanguageString); @@ -99,7 +99,7 @@ HiiLibGetSupportedLanguages ( return NULL; } - Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize); + Status = gHiiString->GetLanguages (gHiiString, HiiHandle, LanguageString, &BufferSize); } if (EFI_ERROR (Status)) { @@ -189,7 +189,7 @@ HiiLibGetSupportedSecondaryLanguages ( return NULL; } - Status = mHiiStringProt->GetSecondaryLanguages (mHiiStringProt, HiiHandle, FirstLanguage, LanguageString, &BufferSize); + Status = gHiiString->GetSecondaryLanguages (gHiiString, HiiHandle, FirstLanguage, LanguageString, &BufferSize); if (Status == EFI_BUFFER_TOO_SMALL) { FreePool (LanguageString); @@ -198,7 +198,7 @@ HiiLibGetSupportedSecondaryLanguages ( return NULL; } - Status = mHiiStringProt->GetSecondaryLanguages (mHiiStringProt, HiiHandle, FirstLanguage, LanguageString, &BufferSize); + Status = gHiiString->GetSecondaryLanguages (gHiiString, HiiHandle, FirstLanguage, LanguageString, &BufferSize); } if (EFI_ERROR (Status)) { diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c index 83e33d2..a3e2498 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c @@ -14,42 +14,15 @@ #include "InternalHiiLib.h" -CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabaseProt = NULL; -CONST EFI_HII_STRING_PROTOCOL *mHiiStringProt = NULL; - -/** - This function locate Hii relative protocols for later usage. - - The constructor function caches the protocol pointer of HII Database Protocol - and Hii String Protocol. - - It will ASSERT() if either of the protocol can't be located. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -HiiLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabaseProt); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &mHiiStringProt); - ASSERT_EFI_ERROR (Status); - - return EFI_SUCCESS; -} - +// +// Template +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 mConfigHdrTemplate[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=00"; +// +// Form Browser2 Protocol +// +EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2 = NULL; /** This funciton build the package list based on the package number, @@ -222,7 +195,7 @@ HiiLibAddPackages ( VA_START (Args, HiiHandle); PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args); - Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle); + Status = gHiiDatabase->NewPackageList (gHiiDatabase, PackageListHeader, DriverHandle, HiiHandle); if (HiiHandle != NULL) { if (EFI_ERROR (Status)) { *HiiHandle = NULL; @@ -254,7 +227,7 @@ HiiLibRemovePackages ( EFI_STATUS Status; ASSERT (IsHiiHandleRegistered (HiiHandle)); - Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle); + Status = gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle); ASSERT_EFI_ERROR (Status); } @@ -292,8 +265,8 @@ HiiLibGetHiiHandles ( // // Try to find the actual buffer size for HiiHandle Buffer. // - Status = mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL, HandleBufferLength, @@ -303,8 +276,8 @@ HiiLibGetHiiHandles ( if (Status == EFI_BUFFER_TOO_SMALL) { *HiiHandleBuffer = AllocateZeroPool (*HandleBufferLength); ASSERT (*HiiHandleBuffer != NULL); - Status = mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL, HandleBufferLength, @@ -352,14 +325,14 @@ HiiLibExtractGuidFromHiiHandle ( BufferSize = 0; HiiPackageList = NULL; - Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList); + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList); ASSERT (Status != EFI_NOT_FOUND); if (Status == EFI_BUFFER_TOO_SMALL) { HiiPackageList = AllocatePool (BufferSize); ASSERT (HiiPackageList != NULL); - Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList); + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList); } if (EFI_ERROR (Status)) { FreePool (HiiPackageList); @@ -453,8 +426,8 @@ HiiLibDevicePathToHiiHandle ( BufferSize = 0x1000; HiiHandles = AllocatePool (BufferSize); ASSERT (HiiHandles != NULL); - Status = mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL, &BufferSize, @@ -465,8 +438,8 @@ HiiLibDevicePathToHiiHandle ( HiiHandles = AllocatePool (BufferSize); ASSERT (HiiHandles != NULL); - Status = mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL, &BufferSize, @@ -485,8 +458,8 @@ HiiLibDevicePathToHiiHandle ( HiiHandle = NULL; HandleCount = BufferSize / sizeof (EFI_HII_HANDLE); for (Index = 0; Index < HandleCount; Index++) { - Status = mHiiDatabaseProt->GetPackageListHandle ( - mHiiDatabaseProt, + Status = gHiiDatabase->GetPackageListHandle ( + gHiiDatabase, HiiHandles[Index], &Handle ); @@ -539,8 +512,8 @@ HiiLibExportPackageLists ( Size = 0; PackageListHdr = NULL; - Status = mHiiDatabaseProt->ExportPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ExportPackageLists ( + gHiiDatabase, Handle, &Size, PackageListHdr @@ -553,8 +526,8 @@ HiiLibExportPackageLists ( if (PackageListHeader == NULL) { return EFI_OUT_OF_RESOURCES; } else { - Status = mHiiDatabaseProt->ExportPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ExportPackageLists ( + gHiiDatabase, Handle, &Size, PackageListHdr @@ -632,8 +605,8 @@ HiiLibListPackageLists ( ASSERT (PackageGuid == NULL); } - Status = mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, PackageType, PackageGuid, HandleBufferLength, @@ -653,8 +626,8 @@ HiiLibListPackageLists ( return EFI_OUT_OF_RESOURCES; } - return mHiiDatabaseProt->ListPackageLists ( - mHiiDatabaseProt, + return gHiiDatabase->ListPackageLists ( + gHiiDatabase, PackageType, PackageGuid, HandleBufferLength, @@ -685,8 +658,8 @@ IsHiiHandleRegistered ( HiiPackageList = NULL; BufferSize = 0; - Status = mHiiDatabaseProt->ExportPackageLists ( - mHiiDatabaseProt, + Status = gHiiDatabase->ExportPackageLists ( + gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList @@ -695,3 +668,2242 @@ IsHiiHandleRegistered ( return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL); } + +/** + Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for + hex digits that appear between a '=' and a '&' in a config string. + + If String is NULL, then ASSERT(). + + @param[in] String Pointer to a Null-terminated Unicode string. + + @return Pointer to the Null-terminated Unicode result string. + +**/ +EFI_STRING +EFIAPI +InternalHiiLowerConfigString ( + IN EFI_STRING ConfigString + ) +{ + EFI_STRING String; + BOOLEAN Lower; + + ASSERT (ConfigString != NULL); + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) { + if (*String == L'=') { + Lower = TRUE; + } else if (*String == L'&') { + Lower = FALSE; + } else if (Lower && *String > L'A' && *String <= L'F') { + *String = *String - L'A' + L'a'; + } + } + + return ConfigString; +} + +/** + Uses the BlockToConfig() service of the Config Routing Protocol to + convert and a buffer to a + + If ConfigRequest is NULL, then ASSERT(). + If Block is NULL, then ASSERT(). + + @param[in] ConfigRequest Pointer to a Null-terminated Unicode string. + @param[in] Block Pointer to a block of data. + @param[in] BlockSize The zie, in bytes, of Block. + + @retval NULL The string could not be generated. + @retval Other Pointer to the Null-terminated Unicode string. + +**/ +EFI_STRING +EFIAPI +InternalHiiBlockToConfig ( + IN CONST EFI_STRING ConfigRequest, + IN CONST UINT8 *Block, + IN UINTN BlockSize + ) +{ + EFI_STATUS Status; + EFI_STRING ConfigResp; + CHAR16 *Progress; + + ASSERT (ConfigRequest != NULL); + ASSERT (Block != NULL); + + // + // Convert to + // + Status = gHiiConfigRouting->BlockToConfig ( + gHiiConfigRouting, + ConfigRequest, + Block, + BlockSize, + &ConfigResp, + &Progress + ); + if (EFI_ERROR (Status)) { + return NULL; + } + return ConfigResp; +} + +/** + Uses the ConfigToBlock() service of the Config Routing Protocol to + convert to a block. The block is allocated using + AllocatePool(). The caller is responsible for freeing the block + using FreePool(). + + If ConfigResp is NULL, then ASSERT(). + + @param[in] ConfigResp Pointer to a Null-terminated Unicode string. + @param[in] BufferSize Length in bytes of buffer to hold retrived data. + + @retval NULL The block could not be generated.. + @retval Other Pointer to the allocated block. + +**/ +UINT8 * +EFIAPI +InternalHiiConfigToBlock ( + IN EFI_STRING ConfigResp, + IN UINTN BlockSize + ) +{ + EFI_STATUS Status; + CHAR16 *Progress; + UINT8 *Block; + + ASSERT (ConfigResp != NULL); + + // + // Allocate a buffer to hold the conversion + // + Block = AllocateZeroPool (BlockSize); + if (Block == NULL) { + return NULL; + } + + // + // Convert to a buffer + // + Status = gHiiConfigRouting->ConfigToBlock ( + gHiiConfigRouting, + ConfigResp, + Block, + &BlockSize, + &Progress + ); + if (EFI_ERROR (Status)) { + FreePool (Block); + return NULL; + } + + // + // Return converted buffer + // + return Block; +} + +/** + Uses the BrowserCallback() service of the Form Browser Protocol to retrieve + or set uncommitted data. If sata i being retrieved, then the buffer is + allocated using AllocatePool(). The caller is then responsible for freeing + the buffer using FreePool(). + + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] SetResultsData If not NULL, then this parameter specified the buffer + of uncommited data to set. If this parameter is NULL, + then the caller is requesting to get the uncommited data + from the Form Browser. + + @retval NULL The uncommitted data could not be retrieved. + @retval Other A pointer to a buffer containing the uncommitted data. + +**/ +EFI_STRING +EFIAPI +InternalHiiBrowserCallback ( + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName, OPTIONAL + IN CONST EFI_STRING SetResultsData OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN ResultsDataSize; + EFI_STRING ResultsData; + CHAR16 TempResultsData; + + // + // Locate protocols + // + if (mFormBrowser2 == NULL) { + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2); + if (EFI_ERROR (Status) || mFormBrowser2 == NULL) { + return NULL; + } + } + + ResultsDataSize = 0; + + if (SetResultsData != NULL) { + // + // Request to to set data in the uncommitted browser state information + // + ResultsData = SetResultsData; + } else { + // + // Retrieve the length of the buffer required ResultsData from the Browser Callback + // + Status = mFormBrowser2->BrowserCallback ( + mFormBrowser2, + &ResultsDataSize, + &TempResultsData, + TRUE, + VariableGuid, + VariableName + ); + if (Status != EFI_BUFFER_TOO_SMALL) { + return NULL; + } + + // + // Allocate the ResultsData buffer + // + ResultsData = AllocateZeroPool (ResultsDataSize); + if (ResultsData == NULL) { + return NULL; + } + } + + // + // Retrieve or set the ResultsData from the Browser Callback + // + Status = mFormBrowser2->BrowserCallback ( + mFormBrowser2, + &ResultsDataSize, + ResultsData, + (BOOLEAN)(SetResultsData == NULL), + VariableGuid, + VariableName + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + return ResultsData; +} + +/** + Allocates and returns a Null-terminated Unicode string using routing + information that includes a GUID, an optional Unicode string name, and a device + path. The string returned is allocated with AllocatePool(). The caller is + responsible for freeing the allocated string with FreePool(). + + The format of a is as follows: + + GUID=32&NAME=NameLength&PATH=DevicePathSize + + @param[in] Guid Pointer to an EFI_GUID that is the routing information + GUID. Each of the 16 bytes in Guid is converted to + a 2 Unicode character hexidecimal string. This is + an optional parameter that may be NULL. + @param[in] Name Pointer to a Null-terminated Unicode string that is + the routing information NAME. This is an optional + parameter that may be NULL. Each 16-bit Unicode + character in Name is converted to a 4 character Unicode + hexidecimal string. + @param[in] DriverHandle The driver handle which supports a Device Path Protocol + that is the routing information PATH. Each byte of + the Device Path associated with DriverHandle is converted + to a 2 Unicode character hexidecimal string. + + @retval NULL DriverHandle does not support the Device Path Protocol. + @retval NULL DriverHandle does not support the Device Path Protocol. + @retval Other A pointer to the Null-terminate Unicode string + +**/ +EFI_STRING +EFIAPI +HiiConstructConfigHdr ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN CONST CHAR16 *Name, OPTIONAL + IN EFI_HANDLE DriverHandle + ) +{ + UINTN NameLength; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN DevicePathSize; + CHAR16 *String; + CHAR16 *ReturnString; + UINTN Index; + UINT8 *Buffer; + + // + // Compute the length of Name in Unicode characters. + // If Name is NULL, then the length is 0. + // + NameLength = 0; + if (Name != NULL) { + NameLength = StrLen (Name); + } + + // + // Retrieve DevicePath Protocol associated with DriverHandle + // + DevicePath = DevicePathFromHandle (DriverHandle); + if (DevicePath == NULL) { + return NULL; + } + + // + // Compute the size of the device path in bytes + // + DevicePathSize = GetDevicePathSize (DevicePath); + + // + // GUID=32&NAME=NameLength&PATH=DevicePathSize + // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 | + // + String = AllocateZeroPool ((5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16)); + if (String == NULL) { + return NULL; + } + + // + // Start with L"GUID=" + // + ReturnString = StrCpy (String, L"GUID="); + String += StrLen (String); + + if (Guid != NULL) { + // + // Append Guid converted to 32 + // + for (Index = 0, Buffer = (UINT8 *)Guid; Index < sizeof (EFI_GUID); Index++) { + String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *(Buffer++), 2); + } + } + + // + // Append L"&NAME=" + // + StrCpy (String, L"&NAME="); + String += StrLen (String); + + if (Name != NULL) { + // + // Append Name converted to NameLength + // + for (; *Name != L'\0'; Name++) { + String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *Name, 4); + } + } + + // + // Append L"&PATH=" + // + StrCpy (String, L"&PATH="); + String += StrLen (String); + + // + // Append the device path associated with DriverHandle converted to DevicePathSize + // + for (Index = 0, Buffer = (UINT8 *)DevicePath; Index < DevicePathSize; Index++) { + String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *(Buffer++), 2); + } + + // + // Null terminate the Unicode string + // + *String = L'\0'; + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + return InternalHiiLowerConfigString (ReturnString); +} + +/** + Allocates and returns a Null-terminated Unicode string. + + If Guid is NULL, then ASSERT(). + If Name is NULL, then ASSERT(). + If BlockNameArray is NULL, then ASSERT(). + + @param[in] Guid GUID of the buffer storage. + @param[in] Name Name of the buffer storage. + @param[in] DriverHandle The DriverHandle that support a Device Path + Protocol. + @param[in] BufferStorage Content of the buffer storage. + @param[in] BufferStorageSize Length in bytes of the buffer storage. + @param[in] BlockNameArray Array generated by VFR compiler. This array + contains a UINT32 value that is the length + of BlockNameArray in bytes, followed by pairs + of 16-bit values that are the offset and length + values used to contruct a string. + @param[in] ... A variable argument list that contains pairs of 16-bit + ALTCFG identifiers and pointers to DefaultValueArrays. + The variable argument list is terminated by a NULL + DefaultValueArray pointer. A DefaultValueArray + contains a UINT32 value that is the length, in bytes, + of the DefaultValueArray. The UINT32 length value + is followed by a series of records that contain + a 16-bit WIDTH value followed by a byte array with + WIDTH entries. The records must be parsed from + beginning to end until the UINT32 length limit + is reached. + + @retval NULL There are not enough resources to process the request. + @retval NULL A could not be retrieved from the Config + Routing Protocol. + @retval Other A pointer to the Null-terminate Unicode + string. + +**/ +EFI_STRING +EFIAPI +HiiConstructConfigAltResp ( + IN CONST EFI_GUID *Guid, + IN CONST CHAR16 *Name, + IN EFI_HANDLE DriverHandle, + IN CONST VOID *BufferStorage, + IN UINTN BufferStorageSize, + IN CONST VOID *BlockNameArray, + ... + ) +{ + UINTN Length; + CHAR16 *String; + CHAR16 *ConfigHdr; + UINT8 *Buffer; + UINT8 *BufferEnd; + CHAR16 *ConfigRequest; + EFI_STRING ConfigResp; + EFI_STRING ConfigAltResp; + VA_LIST Args; + UINTN AltCfgId; + UINT16 Width; + + ASSERT (Guid != NULL); + ASSERT (Name != NULL); + ASSERT (BlockNameArray != NULL); + + // + // Initialize local variables + // + ConfigHdr = NULL; + ConfigRequest = NULL; + ConfigResp = NULL; + + // + // Construct : "GUID=...&NAME=...&PATH=..." + // + ConfigHdr = HiiConstructConfigHdr (Guid, Name, DriverHandle); + if (ConfigHdr == NULL) { + goto Exit; + } + + // + // Compute the length of the entire request starting with and a + // Null-terminator + // + Length = StrLen (ConfigHdr) + 1; + + // + // Determine the size Offset/Width pairs + // + Buffer = (UINT8 *)BlockNameArray; + BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer); + Buffer += sizeof (UINT32); + + // + // Add length that is composed of one or more Offset/Width pairs + // + // ::= &OFFSET=1234&WIDTH=1234 + // | 8 | 4 | 7 | 4 | + // + Length += (((BufferEnd - Buffer) / (sizeof (UINT16) + sizeof (UINT16))) * (8 + 4 + 7 + 4)); + + // + // Allocate buffer for the entire + // + ConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16)); + if (ConfigRequest == NULL) { + goto Exit; + } + String = ConfigRequest; + + // + // Start with + // + StrCpy (String, ConfigHdr); + String += StrLen (String); + + // + // Loop through all the Offset/Width pairs and append them to ConfigRequest + // + while (Buffer < BufferEnd) { + // + // Append &OFFSET=XXXX&WIDTH=YYYY + // + UnicodeSPrint ( + String, + (8 + 4 + 7 + 4) * sizeof (CHAR16), + L"&OFFSET=%04X&WIDTH=%04X", + ReadUnaligned16 ((UINT16 *)Buffer), + ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16))) + ); + String += StrLen (String); + Buffer += (sizeof (UINT16) + sizeof (UINT16)); + } + + // + // Get the + // + ConfigResp = InternalHiiBlockToConfig (ConfigRequest, BufferStorage, BufferStorageSize); + if (ConfigResp == NULL) { + goto Exit; + } + + // + // Compute the length of the entire response starting with and a + // Null-terminator + // + Length = StrLen (ConfigResp) + 1; + + // + // Add the length associated with each pair of variable argument parameters + // + VA_START (Args, BlockNameArray); + while (TRUE) { + AltCfgId = VA_ARG (Args, UINT16); + Buffer = VA_ARG (Args, UINT8 *); + if (Buffer == NULL) { + break; + } + + // + // Add length for "&&ALTCFG=XXXX" + // |1| StrLen (ConfigHdr) | 8 | 4 | + // + Length += (1 + StrLen (ConfigHdr) + 8 + 4); + + BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer); + Buffer += sizeof (UINT32); + while (Buffer < BufferEnd) { + // + // Extract Width field + // + Width = ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16))); + + // + // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz" + // | 8 | 4 | 7 | 4 | 7 | Width * 2 | + // + Length += (8 + 4 + 7 + 4 + 7 + Width * 2); + + // + // Update Buffer to the next record + // + Buffer += (sizeof (UINT16) + sizeof (UINT16) + Width); + } + } + VA_END (Args); + + // + // Allocate a buffer for the entire response + // + ConfigAltResp = AllocateZeroPool (Length * sizeof (CHAR16)); + if (ConfigAltResp == NULL) { + goto Exit; + } + String = ConfigAltResp; + + // + // Add + // + StrCpy (String, ConfigResp); + String += StrLen (String); + + // + // Add for each pair of variable argument parameters + // + VA_START (Args, BlockNameArray); + while (TRUE) { + AltCfgId = VA_ARG (Args, UINT16); + Buffer = VA_ARG (Args, UINT8 *); + if (Buffer == NULL) { + break; + } + + // + // Add of the form "&&ALTCFG=XXXX" + // |1| StrLen (ConfigHdr) | 8 | 4 | + // + UnicodeSPrint ( + String, + (1 + StrLen (ConfigHdr) + 8 + 4) * sizeof (CHAR16), + L"&%s&ALTCFG=%04X", + ConfigHdr, + AltCfgId + ); + String += StrLen (String); + + // + // Add ::= * + // + BufferEnd = Buffer + ReadUnaligned32 ((UINT32 *)Buffer); + Buffer += sizeof (UINT32); + while (Buffer < BufferEnd) { + // + // Extract Width field + // + Width = ReadUnaligned16 ((UINT16 *)(Buffer + sizeof (UINT16))); + + // + // Add + // + UnicodeSPrint ( + String, + (8 + 4 + 7 + 4 + 7 + Width * 2) * sizeof (CHAR16), + L"&OFFSET=%04X&WIDTH=%04X&VALUE=", + ReadUnaligned16 ((UINT16 *)Buffer), + Width + ); + String += StrLen (String); + + // + // Update Buffer to point to the value in the current record + // + Buffer += (sizeof (UINT16) + sizeof (UINT16)); + + // + // Convert Value to a hex string in "%x" format + // NOTE: This is in the opposite byte that GUID and PATH use + // + for (; Width > 0; Width--) { + String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, Buffer[Width - 1], 2); + } + // + // Update Buffer to the next record + // + Buffer += Width; + } + } + VA_END (Args); + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + return InternalHiiLowerConfigString (ConfigAltResp); + +Exit: + if (ConfigHdr != NULL) { + FreePool (ConfigHdr); + } + if (ConfigRequest != NULL) { + FreePool (ConfigRequest); + } + if (ConfigResp != NULL) { + FreePool (ConfigResp); + } + + return NULL; +} + +/** + Determines if two values in config strings match. + + Compares the substring between StartSearchString and StopSearchString in + FirstString to the substring between StartSearchString and StopSearchString + in SecondString. If the two substrings match, then TRUE is returned. If the + two substrings do not match, then FALSE is returned. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + If StartSearchString is NULL, then ASSERT(). + If StopSearchString is NULL, then ASSERT(). + + @param FirstString Pointer to the first Null-terminated Unicode string. + @param SecondString Pointer to the second Null-terminated Unicode string. + @param StartSearchString Pointer to the Null-terminated Unicode string that + marks the start of the value string to compare. + @param StopSearchString Pointer to the Null-terminated Unicode string that + marks the end of the vakue string to compare. + + @retval FALSE StartSearchString is not present in FirstString. + @retval FALSE StartSearchString is not present in SecondString. + @retval FALSE StopSearchString is not present in FirstString. + @retval FALSE StopSearchString is not present in SecondString. + @retval FALSE The length of the substring in FirstString is not the + same length as the substring in SecondString. + @retval FALSE The value string in FirstString does not matche the + value string in SecondString. + @retval TRUE The value string in FirstString matches the value + string in SecondString. + +**/ +BOOLEAN +EFIAPI +InternalHiiCompareSubString ( + IN CHAR16 *FirstString, + IN CHAR16 *SecondString, + IN CHAR16 *StartSearchString, + IN CHAR16 *StopSearchString + ) +{ + CHAR16 *EndFirstString; + CHAR16 *EndSecondString; + + ASSERT (FirstString != NULL); + ASSERT (SecondString != NULL); + ASSERT (StartSearchString != NULL); + ASSERT (StopSearchString != NULL); + + FirstString = StrStr (FirstString, StartSearchString); + if (FirstString == NULL) { + return FALSE; + } + + SecondString = StrStr (SecondString, StartSearchString); + if (SecondString == NULL) { + return FALSE; + } + + EndFirstString = StrStr (FirstString, StopSearchString); + if (EndFirstString == NULL) { + return FALSE; + } + + EndSecondString = StrStr (SecondString, StopSearchString); + if (EndSecondString == NULL) { + return FALSE; + } + + if ((EndFirstString - FirstString) != (EndSecondString - SecondString)) { + return FALSE; + } + + return (BOOLEAN)(StrnCmp (FirstString, SecondString, EndFirstString - FirstString) == 0); +} + +/** + Determines if the routing data specified by GUID and NAME match a . + + If ConfigHdr is NULL, then ASSERT(). + + @param[in] ConfigHdr Either or . + @param[in] Guid GUID of the storage. + @param[in] Name NAME of the storage. + + @retval TRUE Routing information matches . + @retval FALSE Routing information does not match . + +**/ +BOOLEAN +EFIAPI +HiiIsConfigHdrMatch ( + IN CONST EFI_STRING ConfigHdr, + IN CONST EFI_GUID *Guid, OPTIONAL + IN CONST CHAR16 *Name OPTIONAL + ) +{ + EFI_STRING CompareConfigHdr; + BOOLEAN Result; + + ASSERT (ConfigHdr != NULL); + + // + // Use Guid and Name to generate a string + // + CompareConfigHdr = HiiConstructConfigHdr (Guid, Name, NULL); + if (CompareConfigHdr == NULL) { + return FALSE; + } + + Result = TRUE; + if (Guid != NULL) { + // + // Compare GUID value strings + // + Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"GUID=", L"&NAME="); + } + + if (Result && Name != NULL) { + // + // Compare NAME value strings + // + Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"&NAME=", L"&PATH="); + } + + // + // Free the string + // + FreePool (CompareConfigHdr); + + return Result; +} + +/** + Retrieves uncommited data from the Form Browser and converts it to a binary + buffer. The returned buffer is allocated using AllocatePool(). The caller + is responsible for freeing the returned buffer using FreePool(). + + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] BufferSize Length in bytes of buffer to hold retrived data. + + @retval NULL The uncommitted data could not be retrieved. + @retval Other A pointer to a buffer containing the uncommitted data. + +**/ +UINT8 * +EFIAPI +HiiGetBrowserData ( + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName, OPTIONAL + IN UINTN BlockSize + ) +{ + EFI_STRING ResultsData; + UINTN Size; + EFI_STRING ConfigResp; + UINT8 *Block; + + // + // Retrieve the results data from the Browser Callback + // + ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, NULL); + if (ResultsData == NULL) { + return NULL; + } + + // + // Construct + // + Size = (StrLen (mConfigHdrTemplate) + 1 + StrLen (ResultsData) + 1) * sizeof (CHAR16); + ConfigResp = AllocateZeroPool (Size); + UnicodeSPrint (ConfigResp, Size, L"%s&%s", mConfigHdrTemplate, ResultsData); + + // + // Free the allocated buffer + // + FreePool (ResultsData); + if (ConfigResp == NULL) { + return NULL; + } + + // + // Convert to a buffer + // + Block = InternalHiiConfigToBlock (ConfigResp, BlockSize); + FreePool (ConfigResp); + + return Block; +} + +/** + Updates uncommitted data in the Form Browser. + + If Buffer is NULL, then ASSERT(). + + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] BufferSize Length, in bytes, of Buffer. + @param[in] Buffer Buffer of data to commit. + @param[in] RequestElement An optional field to specify which part of the + buffer data will be send back to Browser. If NULL, + the whole buffer of data will be committed to + Browser. + ::= &OFFSET=&WIDTH=* + + @retval FALSE The uncommitted data could not be updated. + @retval TRUE The uncommitted data was updated. + +**/ +BOOLEAN +EFIAPI +HiiSetBrowserData ( + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName, OPTIONAL + IN UINTN BufferSize, + IN CONST UINT8 *Buffer, + IN CONST CHAR16 *RequestElement OPTIONAL + ) +{ + UINTN Size; + EFI_STRING ConfigRequest; + EFI_STRING ConfigResp; + EFI_STRING ResultsData; + + ASSERT (Buffer != NULL); + + // + // Construct + // + if (RequestElement == NULL) { + // + // Allocate and fill a buffer large enough to hold the template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator + // + Size = (StrLen (mConfigHdrTemplate) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate, (UINT64)BufferSize); + } else { + // + // Allocate and fill a buffer large enough to hold the template + // followed by followed by a Null-terminator + // + Size = (StrLen (mConfigHdrTemplate) + StrLen (RequestElement) + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + UnicodeSPrint (ConfigRequest, Size, L"%s%s", mConfigHdrTemplate, RequestElement); + } + if (ConfigRequest == NULL) { + return FALSE; + } + + // + // Convert to + // + ConfigResp = InternalHiiBlockToConfig (ConfigRequest, Buffer, BufferSize); + FreePool (ConfigRequest); + if (ConfigResp == NULL) { + return FALSE; + } + + // + // Set data in the uncommitted browser state information + // + ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, ConfigResp + StrLen(mConfigHdrTemplate) + 1); + FreePool (ConfigResp); + + return (BOOLEAN)(ResultsData != NULL); +} + +///////////////////////////////////////// +///////////////////////////////////////// +/// IFR Functions +///////////////////////////////////////// +///////////////////////////////////////// + +#define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200 + +typedef struct { + UINT8 *Buffer; + UINTN BufferSize; + UINTN Position; +} HII_LIB_OPCODE_BUFFER; + +/// +/// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes +/// +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth[] = { + 1, // EFI_IFR_TYPE_NUM_SIZE_8 + 2, // EFI_IFR_TYPE_NUM_SIZE_16 + 4, // EFI_IFR_TYPE_NUM_SIZE_32 + 8, // EFI_IFR_TYPE_NUM_SIZE_64 + 1, // EFI_IFR_TYPE_BOOLEAN + 3, // EFI_IFR_TYPE_TIME + 4, // EFI_IFR_TYPE_DATE + 2 // EFI_IFR_TYPE_STRING +}; + +/** + Allocates and returns a new OpCode Handle. OpCode Handles must be freed with + HiiFreeOpCodeHandle(). + + @retval NULL There are not enough resources to allocate a new OpCode Handle. + @retval Other A new OpCode handle. + +**/ +VOID * +EFIAPI +HiiAllocateOpCodeHandle ( + VOID + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER)); + if (OpCodeBuffer == NULL) { + return NULL; + } + OpCodeBuffer->Buffer = (UINT8 *)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE); + if (OpCodeBuffer->Buffer == NULL) { + FreePool (OpCodeBuffer); + return NULL; + } + OpCodeBuffer->BufferSize = HII_LIB_OPCODE_ALLOCATION_SIZE; + OpCodeBuffer->Position = 0; + return (VOID *)OpCodeBuffer; +} + +/** + Frees an OpCode Handle that was peviously allocated with HiiAllocateOpCodeHandle(). + When an OpCode Handle is freed, all of the opcodes associated with the OpCode + Handle are also freed. + + If OpCodeHandle is NULL, then ASSERT(). + +**/ +VOID +EFIAPI +HiiFreeOpCodeHandle ( + VOID *OpCodeHandle + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + + ASSERT (OpCodeHandle != NULL); + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle; + if (OpCodeBuffer->Buffer != NULL) { + FreePool (OpCodeBuffer->Buffer); + } + FreePool (OpCodeBuffer); +} + +UINTN +EFIAPI +InternalHiiOpCodeHandlePosition ( + IN VOID *OpCodeHandle + ) +{ + return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Position; +} + +UINT8 * +EFIAPI +InternalHiiOpCodeHandleBuffer ( + IN VOID *OpCodeHandle + ) +{ + return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Buffer; +} + +UINT8 * +EFIAPI +InternalHiiGrowOpCodeHandle ( + VOID *OpCodeHandle, + UINTN Size + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + UINT8 *Buffer; + + ASSERT (OpCodeHandle != NULL); + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle; + if (OpCodeBuffer->Position + Size > OpCodeBuffer->BufferSize) { + Buffer = ReallocatePool ( + OpCodeBuffer->BufferSize, + OpCodeBuffer->BufferSize + (Size + HII_LIB_OPCODE_ALLOCATION_SIZE), + OpCodeBuffer->Buffer + ); + if (Buffer == NULL) { + return NULL; + } + OpCodeBuffer->Buffer = Buffer; + OpCodeBuffer->BufferSize += (Size + HII_LIB_OPCODE_ALLOCATION_SIZE); + } + Buffer = OpCodeBuffer->Buffer + OpCodeBuffer->Position; + OpCodeBuffer->Position += Size; + return Buffer; +} + +UINT8 * +EFIAPI +InternalHiiCreateOpCodeExtended ( + IN VOID *OpCodeHandle, + IN VOID *OpCodeTemplate, + IN UINT8 OpCode, + IN UINTN OpCodeSize, + IN UINTN ExtensionSize, + IN UINT8 Scope + ) +{ + EFI_IFR_OP_HEADER *Header; + UINT8 *Buffer; + + ASSERT (OpCodeTemplate != NULL); + ASSERT ((OpCodeSize + ExtensionSize) <= 0x7F); + + Header = (EFI_IFR_OP_HEADER *)OpCodeTemplate; + Header->OpCode = OpCode; + Header->Scope = Scope; + Header->Length = (UINT8)(OpCodeSize + ExtensionSize); + Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, Header->Length); + return (UINT8 *)CopyMem (Buffer, Header, OpCodeSize); +} + +UINT8 * +EFIAPI +InternalHiiCreateOpCode ( + IN VOID *OpCodeHandle, + IN VOID *OpCodeTemplate, + IN UINT8 OpCode, + IN UINTN OpCodeSize + ) +{ + return InternalHiiCreateOpCodeExtended (OpCodeHandle, OpCodeTemplate, OpCode, OpCodeSize, 0, 0); +} + +/** + Append raw opcodes to an OpCodeHandle. + + If OpCodeHandle is NULL, then ASSERT(). + If RawBuffer is NULL, then ASSERT(); + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] RawBuffer Buffer of opcodes to append. + @param[in] RawBufferSize The size, in bytes, of Buffer. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the appended opcodes. + +**/ +UINT8 * +EFIAPI +InternalHiiCreateRawOpCodes ( + IN VOID *OpCodeHandle, + IN UINT8 *RawBuffer, + IN UINTN RawBufferSize + ) +{ + UINT8 *Buffer; + + ASSERT (RawBuffer != NULL); + + Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, RawBufferSize); + return (UINT8 *)CopyMem (Buffer, RawBuffer, RawBufferSize); +} + +/** + Append opcodes from one OpCode Handle to another OpCode handle. + + If OpCodeHandle is NULL, then ASSERT(). + If RawOpCodeHandle is NULL, then ASSERT(); + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] RawOpCodeHandle Handle to the buffer of opcodes. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the appended opcodes. + +**/ +UINT8 * +EFIAPI +InternalHiiAppendOpCodes ( + IN VOID *OpCodeHandle, + IN VOID *RawOpCodeHandle + ) +{ + HII_LIB_OPCODE_BUFFER *RawOpCodeBuffer; + + ASSERT (RawOpCodeHandle != NULL); + + RawOpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)RawOpCodeHandle; + return InternalHiiCreateRawOpCodes (OpCodeHandle, RawOpCodeBuffer->Buffer, RawOpCodeBuffer->Position); +} + +/** + Create EFI_IFR_END_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateEndOpCode ( + IN VOID *OpCodeHandle + ) +{ + EFI_IFR_END OpCode; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_END_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_ONE_OF_OPTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + If Flags is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] StringId StringId for the option + @param[in] Flags Flags for the option + @param[in] Type Type for the option + @param[in] Value Value for the option + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOptionOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 StringId, + IN UINT8 Flags, + IN UINT8 Type, + IN UINT64 Value + ) +{ + EFI_IFR_ONE_OF_OPTION OpCode; + + ASSERT (Type < EFI_IFR_TYPE_OTHER); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Option = StringId; + OpCode.Flags = (UINT8) (Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)); + OpCode.Type = Type; + CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]); + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_DEFAULT_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] DefaultId DefaultId for the default + @param[in] Type Type for the default + @param[in] Value Value for the default + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateDefaultOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 DefaultId, + IN UINT8 Type, + IN UINT64 Value + ) +{ + EFI_IFR_DEFAULT OpCode; + + ASSERT (Type < EFI_IFR_TYPE_OTHER); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Type = Type; + OpCode.DefaultId = DefaultId; + CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]); + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_GUID opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Guid is NULL, then ASSERT(). + If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Guid Pointer to EFI_GUID of this guided opcode. + @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an + optional parameter that may be NULL. If this + parameter is NULL, then the GUID extension + region of the created opcode is filled with zeros. + If this parameter is not NULL, then the GUID + extension region of GuidData will be copied to + the GUID extension region of the created opcode. + @param[in] OpCodeSize The size, in bytes, of created opcode. This value + must be >= sizeof(EFI_IFR_GUID). + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGuidOpCode ( + IN VOID *OpCodeHandle, + IN CONST EFI_GUID *Guid, + IN CONST VOID *GuidOpCode, OPTIONAL + IN UINTN OpCodeSize + ) +{ + EFI_IFR_GUID OpCode; + EFI_IFR_GUID *OpCodePointer; + + ASSERT (Guid != NULL); + ASSERT (OpCodeSize >= sizeof (OpCode)); + + ZeroMem (&OpCode, sizeof (OpCode)); + CopyGuid (&OpCode.Guid, Guid); + + OpCodePointer = (EFI_IFR_GUID *)InternalHiiCreateOpCodeExtended ( + OpCodeHandle, + &OpCode, + EFI_IFR_GUID_OP, + sizeof (OpCode), + OpCodeSize - sizeof (OpCode), + 0 + ); + if (OpCodePointer != NULL && GuidOpCode != NULL) { + CopyMem (OpCodePointer + 1, (EFI_IFR_GUID *)GuidOpCode + 1, OpCodeSize - sizeof (OpCode)); + } + return (UINT8 *)OpCodePointer; +} + +/** + Create EFI_IFR_ACTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionConfig String ID for configuration + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateActionOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_STRING_ID QuestionConfig + ) +{ + EFI_IFR_ACTION OpCode; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.QuestionConfig = QuestionConfig; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ACTION_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_SUBTITLE_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in Flags, then ASSERT(). + If Scope > 1, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] Flags Subtitle opcode flags + @param[in] Scope 1 if this opcpde is the beginning of a new scope. + 0 if this opcode is within the current scope. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateSubTitleOpCode ( + IN VOID *OpCodeHandle, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 Flags, + IN UINT8 Scope + ) +{ + EFI_IFR_SUBTITLE OpCode; + + ASSERT (Scope <= 1); + ASSERT ((Flags & (~(EFI_IFR_FLAGS_HORIZONTAL))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Statement.Prompt = Prompt; + OpCode.Statement.Help = Help; + OpCode.Flags = Flags; + + return InternalHiiCreateOpCodeExtended ( + OpCodeHandle, + &OpCode, + EFI_IFR_SUBTITLE_OP, + sizeof (OpCode), + 0, + Scope + ); +} + +/** + Create EFI_IFR_REF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] FormId Destination Form ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionId Question ID + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGotoOpCode ( + IN VOID *OpCodeHandle, + IN EFI_FORM_ID FormId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_QUESTION_ID QuestionId + ) +{ + EFI_IFR_REF OpCode; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.Flags = QuestionFlags; + OpCode.FormId = FormId; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_CHECKBOX_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in CheckBoxFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] CheckBoxFlags Flags for checkbox opcode + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateCheckBoxOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 CheckBoxFlags, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_CHECKBOX OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = CheckBoxFlags; + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_NUMERIC_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in NumericFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] NumericFlags Flags for numeric opcode + @param[in] Minimum Numeric minimum value + @param[in] Maximum Numeric maximum value + @param[in] Step Numeric step for edit + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateNumericOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 NumericFlags, + IN UINT64 Minimum, + IN UINT64 Maximum, + IN UINT64 Step, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_NUMERIC OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = NumericFlags; + + switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + OpCode.data.u8.MinValue = (UINT8)Minimum; + OpCode.data.u8.MaxValue = (UINT8)Maximum; + OpCode.data.u8.Step = (UINT8)Step; + break; + + case EFI_IFR_NUMERIC_SIZE_2: + OpCode.data.u16.MinValue = (UINT16)Minimum; + OpCode.data.u16.MaxValue = (UINT16)Maximum; + OpCode.data.u16.Step = (UINT16)Step; + break; + + case EFI_IFR_NUMERIC_SIZE_4: + OpCode.data.u32.MinValue = (UINT32)Minimum; + OpCode.data.u32.MaxValue = (UINT32)Maximum; + OpCode.data.u32.Step = (UINT32)Step; + break; + + case EFI_IFR_NUMERIC_SIZE_8: + OpCode.data.u64.MinValue = Minimum; + OpCode.data.u64.MaxValue = Maximum; + OpCode.data.u64.Step = Step; + break; + } + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_STRING_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in StringFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] StringFlags Flags for string opcode + @param[in] MinSize String minimum length + @param[in] MaxSize String maximum length + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateStringOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 StringFlags, + IN UINT8 MinSize, + IN UINT8 MaxSize, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_STRING OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.MinSize = MinSize; + OpCode.MaxSize = MaxSize; + OpCode.Flags = (UINT8) (StringFlags & EFI_IFR_STRING_MULTI_LINE); + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_ONE_OF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OneOfFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OneOfFlags Flags for oneof opcode + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OneOfFlags, + IN VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_ONE_OF OpCode; + UINTN Position; + + ASSERT (OptionsOpCodeHandle != NULL); + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = OneOfFlags; + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle); + if (DefaultsOpCodeHandle != NULL) { + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + } + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_ORDERED_LIST_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OrderedListFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OrderedListFlags Flags for ordered list opcode + @param[in] DataType Type for option value + @param[in] MaxContainers Maximum count for options in this ordered list + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOrderedListOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OrderedListFlags, + IN UINT8 DataType, + IN UINT8 MaxContainers, + IN VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_ORDERED_LIST OpCode; + UINTN Position; + + ASSERT (OptionsOpCodeHandle != NULL); + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.MaxContainers = MaxContainers; + OpCode.Flags = OrderedListFlags; + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ORDERED_LIST_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle); + if (DefaultsOpCodeHandle != NULL) { + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + } + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + This is the internal worker function to update the data in + a form specified by FormSetGuid, FormId and Label. + + @param FormSetGuid The optional Formset GUID. + @param FormId The Form ID. + @param Package The package header. + + @param TempPacakge The resultant package. + + @retval EFI_SUCCESS The function completes successfully. + +**/ +EFI_STATUS +EFIAPI +InternalHiiUpdateFormPackageData ( + IN EFI_GUID *FormSetGuid, OPTIONAL + IN EFI_FORM_ID FormId, + IN EFI_HII_PACKAGE_HEADER *Package, + IN HII_LIB_OPCODE_BUFFER *OpCodeBufferStart, + IN HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd, OPTIONAL + OUT EFI_HII_PACKAGE_HEADER *TempPackage + ) +{ + UINTN AddSize; + UINT8 *BufferPos; + EFI_HII_PACKAGE_HEADER PackageHeader; + UINTN Offset; + EFI_IFR_OP_HEADER *IfrOpHdr; + EFI_IFR_OP_HEADER *UpdateIfrOpHdr; + BOOLEAN GetFormSet; + BOOLEAN GetForm; + BOOLEAN Updated; + EFI_IFR_OP_HEADER *AddOpCode; + UINT32 UpdatePackageLength; + + CopyMem (TempPackage, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + UpdatePackageLength = sizeof (EFI_HII_PACKAGE_HEADER); + BufferPos = (UINT8 *) (TempPackage + 1); + + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER)); + Offset = sizeof (EFI_HII_PACKAGE_HEADER); + GetFormSet = (BOOLEAN) ((FormSetGuid == NULL) ? TRUE : FALSE); + GetForm = FALSE; + Updated = FALSE; + + while (Offset < PackageHeader.Length) { + CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length); + BufferPos += IfrOpHdr->Length; + UpdatePackageLength += IfrOpHdr->Length; + + // + // Find the matched FormSet and Form + // + if ((IfrOpHdr->OpCode == EFI_IFR_FORM_SET_OP) && (FormSetGuid != NULL)) { + if (CompareGuid((GUID *)(VOID *)&((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, FormSetGuid)) { + GetFormSet = TRUE; + } else { + GetFormSet = FALSE; + } + } else if (IfrOpHdr->OpCode == EFI_IFR_FORM_OP) { + if (CompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) { + GetForm = TRUE; + } else { + GetForm = FALSE; + } + } + + // + // The matched Form is found, and Update data in this form + // + if (GetFormSet && GetForm && !Updated) { + UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *) OpCodeBufferStart->Buffer; + if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \ + (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) { + // + // Remove the original data when End OpCode buffer exist. + // + if (OpCodeBufferEnd != NULL) { + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *) ((UINT8 *) (IfrOpHdr) + IfrOpHdr->Length); + UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *) OpCodeBufferEnd->Buffer; + while (Offset < PackageHeader.Length) { + // + // Search the matched end opcode + // + if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \ + (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) { + break; + } + // + // Go to the next Op-Code + // + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *) ((UINT8 *) (IfrOpHdr) + IfrOpHdr->Length); + } + + if (Offset >= PackageHeader.Length) { + // + // The end opcode is not found. + // + return EFI_NOT_FOUND; + } + } + // + // Insert the updated data + // + UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *) OpCodeBufferStart->Buffer; + AddOpCode = (EFI_IFR_OP_HEADER *) (OpCodeBufferStart->Buffer + UpdateIfrOpHdr->Length); + AddSize = UpdateIfrOpHdr->Length; + while (AddSize < OpCodeBufferStart->Position) { + CopyMem (BufferPos, AddOpCode, AddOpCode->Length); + BufferPos += AddOpCode->Length; + UpdatePackageLength += AddOpCode->Length; + + AddOpCode = (EFI_IFR_OP_HEADER *) ((UINT8 *) (AddOpCode) + AddOpCode->Length); + AddSize += AddOpCode->Length; + } + + if (OpCodeBufferEnd != NULL) { + // + // Add the end opcode + // + CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length); + BufferPos += IfrOpHdr->Length; + UpdatePackageLength += IfrOpHdr->Length; + } + // + // Set update flag + // + Updated = TRUE; + } + } + + // + // Go to the next Op-Code + // + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length); + } + + if (!Updated) { + // + // The updated opcode buffer is not found. + // + return EFI_NOT_FOUND; + } + // + // Update the package length. + // + PackageHeader.Length = UpdatePackageLength; + CopyMem (TempPackage, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER)); + + return EFI_SUCCESS; +} + +/** + This function updates a form that has previously been registered with the HII + Database. This function will perform at most one update operation. + + The form to update is specified by Handle, FormSetGuid, and FormId. Binary + comparisons of IFR opcodes are performed from the beginning of the form being + updated until an IFR opcode is found that exactly matches the first IFR opcode + specifed by StartOpCodeHandle. The following rules are used to determine if + an insert, replace, or delete operation is performed. + + 1) If no matches are found, then NULL is returned. + 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes + from StartOpcodeHandle except the first opcode are inserted immediately after + the matching IFR opcode in the form beng updated. + 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made + from the matching IFR opcode until an IFR opcode exatly matches the first + IFR opcode specified by EndOpCodeHandle. If no match is found for the first + IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match + is found, then all of the IFR opcodes between the start match and the end + match are deleted from the form being updated and all of the IFR opcodes + from StartOpcodeHandle except the first opcode are inserted immediately after + the matching start IFR opcode. If StartOpCcodeHandle only contains one + IFR instruction, then the result of ths operation will delete all of the IFR + opcodes between the start end matches. + + If HiiHandle is NULL, then ASSERT(). + If StartOpCodeHandle is NULL, then ASSERT(). + + @param[in] HiiHandle The HII Handle of the form to update. + @param[in] FormSetGuid The Formset GUID of the form to update. This + is an optional parameter that may be NULL. + If it is NULL, all FormSet will be updated. + @param[in] FormId The ID of the form to update. + @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR + opcodes to be inserted or replaced in the form. + The first IFR instruction in StartOpCodeHandle + is used to find matching IFR opcode in the + form. + @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode + that marks the end of a replace operation in + the form. This is an optional parameter that + may be NULL. If it is NULL, then an the IFR + opcodes specified by StartOpCodeHandle are + inserted into the form. + + @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated. + @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND. + 1) The form specified by HiiHandle, FormSetGuid, + and FormId could not be found in the HII Database. + 2) No IFR opcodes in the target form match the first + IFR opcode in StartOpCodeHandle. + 3) EndOpCOde is not NULL, and no IFR opcodes in the + target form following a matching start opcode match + the first IFR opcode in EndOpCodeHandle. + @retval EFI_SUCCESS The matched form is updated by StartOpcode. + +**/ +EFI_STATUS +EFIAPI +HiiUpdateForm ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_GUID *FormSetGuid, OPTIONAL + IN EFI_FORM_ID FormId, + IN VOID *StartOpcodeHandle, + IN VOID *EndOpcodeHandle OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINT32 PackageListLength; + UINT32 Offset; + EFI_HII_PACKAGE_LIST_HEADER *UpdatePackageList; + UINTN BufferSize; + UINT8 *UpdateBufferPos; + EFI_HII_PACKAGE_HEADER *Package; + EFI_HII_PACKAGE_HEADER *TempPacakge; + EFI_HII_PACKAGE_HEADER PackageHeader; + BOOLEAN Updated; + HII_LIB_OPCODE_BUFFER *OpCodeBufferStart; + HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd; + + // + // Input update data can't be NULL. + // + ASSERT (HiiHandle != NULL); + ASSERT (StartOpcodeHandle != NULL); + UpdatePackageList = NULL; + TempPacakge = NULL; + HiiPackageList = NULL; + + // + // Restrive buffer data from Opcode Handle + // + OpCodeBufferStart = (HII_LIB_OPCODE_BUFFER *) StartOpcodeHandle; + OpCodeBufferEnd = (HII_LIB_OPCODE_BUFFER *) EndOpcodeHandle; + + // + // Get the orginal package list + // + BufferSize = 0; + HiiPackageList = NULL; + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList); + // + // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0. + // + if (Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + + HiiPackageList = AllocatePool (BufferSize); + if (HiiPackageList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList); + if (EFI_ERROR (Status)) { + goto Finish; + } + + // + // Calculate and allocate space for retrieval of IFR data + // + BufferSize += OpCodeBufferStart->Position; + UpdatePackageList = AllocateZeroPool (BufferSize); + if (UpdatePackageList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + // + // Allocate temp buffer to store the temp updated package buffer + // + TempPacakge = AllocateZeroPool (BufferSize); + if (TempPacakge == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + UpdateBufferPos = (UINT8 *) UpdatePackageList; + + // + // Copy the package list header + // + CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER)); + UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER); + + // + // Go through each package to find the matched pacakge and update one by one + // + Updated = FALSE; + Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength); + while (Offset < PackageListLength) { + Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset); + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + Offset += Package->Length; + + if (Package->Type == EFI_HII_PACKAGE_FORMS) { + // + // Check this package is the matched package. + // + Status = InternalHiiUpdateFormPackageData (FormSetGuid, FormId, Package, OpCodeBufferStart, OpCodeBufferEnd, TempPacakge); + // + // The matched package is found. Its pacakge buffer will be updated by the input new data. + // + if (!EFI_ERROR(Status)) { + // + // Set Update Flag + // + Updated = TRUE; + // + // Add updated package buffer + // + Package = TempPacakge; + } + } + + // + // Add pacakge buffer + // + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + CopyMem (UpdateBufferPos, Package, PackageHeader.Length); + UpdateBufferPos += PackageHeader.Length; + } + + if (Updated) { + // + // Update package list length + // + BufferSize = UpdateBufferPos - (UINT8 *) UpdatePackageList; + WriteUnaligned32 (&UpdatePackageList->PackageLength, (UINT32) BufferSize); + + // + // Update Pacakge to show form + // + Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, HiiHandle, UpdatePackageList); + } else { + // + // Not matched form is found and updated. + // + Status = EFI_NOT_FOUND; + } + +Finish: + if (HiiPackageList != NULL) { + FreePool (HiiPackageList); + } + + if (UpdatePackageList != NULL) { + FreePool (UpdatePackageList); + } + + if (TempPacakge != NULL) { + FreePool (TempPacakge); + } + + return Status; +} + +/** + Configure the buffer accrording to ConfigBody strings in the format of + , , , . + This ConfigBody strings is generated by UEFI VfrCompiler for the default + values in a Form Set. The name of the ConfigBody strings is VfrMyIfrNVDataDefault0000 + constructed following this rule: + "Vfr" + varstore.name + "Default" + defaultstore.attributes. + Check the generated C file in Output for details. + + @param Buffer The start address of buffer. + @param BufferSize The size of buffer. + @param Number The number of the strings. + @param ... Variable argument list for default value in format + generated by the tool. + + @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate. + @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0. + @retval EFI_SUCCESS Operation successful. + +**/ +EFI_STATUS +EFIAPI +IfrLibExtractDefault( + IN VOID *Buffer, + IN UINTN *BufferSize, + UINTN Number, + ... + ) +{ + VA_LIST Args; + UINTN Index; + UINT32 TotalLen; + UINT8 *BufCfgArray; + UINT8 *BufferPos; + UINT16 Offset; + UINT16 Width; + UINT8 *Value; + + if ((Buffer == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Offset = 0; + Width = 0; + Value = NULL; + + VA_START (Args, Number); + for (Index = 0; Index < Number; Index++) { + BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *); + TotalLen = ReadUnaligned32 ((UINT32 *)BufCfgArray); + BufferPos = BufCfgArray + sizeof (UINT32); + + while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) { + Offset = ReadUnaligned16 ((UINT16 *)BufferPos); + BufferPos += sizeof (UINT16); + Width = ReadUnaligned16 ((UINT16 *)BufferPos); + BufferPos += sizeof (UINT16); + Value = BufferPos; + BufferPos += Width; + + if ((UINTN)(Offset + Width) > *BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + CopyMem ((UINT8 *)Buffer + Offset, Value, Width); + } + } + VA_END (Args); + + *BufferSize = (UINTN)Offset; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiString.c b/MdeModulePkg/Library/UefiHiiLib/HiiString.c index 333c29f..7d8ca5e 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiString.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiString.c @@ -214,8 +214,8 @@ HiiLibNewString ( // For each language supported by the package, // a string token is created. // - Status = mHiiStringProt->NewString ( - mHiiStringProt, + Status = gHiiString->NewString ( + gHiiString, PackageList, StringId, Lang, @@ -287,8 +287,8 @@ HiiLibSetString ( // For each language supported by the package, // the string is updated. // - Status = mHiiStringProt->SetString ( - mHiiStringProt, + Status = gHiiString->SetString ( + gHiiString, PackageList, StringId, Lang, @@ -425,8 +425,8 @@ HiiLibGetString ( NULL ); if (BestLanguage != NULL ) { - Status = mHiiStringProt->GetString ( - mHiiStringProt, + Status = gHiiString->GetString ( + gHiiString, BestLanguage, PackageList, StringId, diff --git a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h index 8f2aeb4..e144635 100644 --- a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h +++ b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -30,7 +31,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf index 8c8a2f2..1a03ff1 100644 --- a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +++ b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf @@ -25,7 +25,6 @@ VERSION_STRING = 1.0 LIBRARY_CLASS = HiiLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER EFI_SPECIFICATION_VERSION = 0x0002000A - CONSTRUCTOR = HiiLibConstructor # # VALID_ARCHITECTURES = IA32 X64 IPF EBC @@ -49,21 +48,13 @@ UefiBootServicesTableLib DevicePathLib UefiLib + UefiHiiServicesLib + PrintLib PcdLib - UefiRuntimeServicesTableLib [Protocols] - gEfiHiiDatabaseProtocolGuid ## CONSUMES - gEfiHiiStringProtocolGuid ## CONSUMES + gEfiFormBrowser2ProtocolGuid ## CONSUMES gEfiDevicePathProtocolGuid ## CONSUMES [Pcd] gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang - -[Guids] - gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"PlatformLang" - -[Depex] - gEfiHiiDatabaseProtocolGuid AND - gEfiHiiStringProtocolGuid - diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c index 8351a32..9ef7c3b 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c @@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "DriverSample.h" -#define DISPLAY_ONLY_MY_ITEM 0x0000 +#define DISPLAY_ONLY_MY_ITEM 0x0002 EFI_GUID mFormSetGuid = FORMSET_GUID; EFI_GUID mInventoryGuid = INVENTORY_GUID; @@ -218,10 +218,10 @@ SetPassword ( ) { EFI_STATUS Status; - UINTN BufferSize; CHAR16 *Password; UINTN PasswordSize; DRIVER_SAMPLE_CONFIGURATION *Configuration; + UINTN BufferSize; // // Get Buffer Storage data from EFI variable @@ -253,11 +253,8 @@ SetPassword ( // // Retrive uncommitted data from Browser // - BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); - Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA)); - ASSERT (Configuration != NULL); - Status = GetBrowserData (&mFormSetGuid, VariableName, &BufferSize, (UINT8 *) Configuration); - if (!EFI_ERROR (Status)) { + Configuration = (DRIVER_SAMPLE_CONFIGURATION *) HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION)); + if (Configuration != NULL) { // // Update password's clear text in the screen // @@ -266,16 +263,17 @@ SetPassword ( // // Update uncommitted data of Browser // - BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); - Status = SetBrowserData ( - &mFormSetGuid, - VariableName, - BufferSize, - (UINT8 *) Configuration, - NULL - ); + HiiSetBrowserData ( + &mFormSetGuid, + VariableName, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + (UINT8 *) Configuration, + NULL + ); + + FreePool (Configuration); } - FreePool (Configuration); + // // Set password @@ -355,31 +353,36 @@ ExtractConfig ( // // Request is set to NULL, return all configurable elements together with ALTCFG // - Status = ConstructConfigAltResp ( - NULL, - NULL, - Results, - &mFormSetGuid, - VariableName, - PrivateData->DriverHandle[0], - &PrivateData->Configuration, - BufferSize, - VfrMyIfrNVDataBlockName, - 2, - STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT), - VfrMyIfrNVDataDefault0000, - STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT), - VfrMyIfrNVDataDefault0001 + *Results = HiiConstructConfigAltResp ( + &mFormSetGuid, + VariableName, + PrivateData->DriverHandle[0], + &PrivateData->Configuration, + BufferSize, + VfrMyIfrNVDataBlockName, + STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT), + VfrMyIfrNVDataDefault0000, + STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT), + VfrMyIfrNVDataDefault0001, + 0, + NULL ); + + // + // No matched storage is found. + // + if (*Results == NULL) { + return EFI_NOT_FOUND; + } - return Status; + return EFI_SUCCESS; } // // Check routing data in . // Note: if only one Storage is used, then this checking could be skipped. // - if (!IsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) { + if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) { *Progress = Request; return EFI_NOT_FOUND; } @@ -440,7 +443,7 @@ RouteConfig ( // Check routing data in . // Note: if only one Storage is used, then this checking could be skipped. // - if (!IsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) { + if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) { *Progress = Configuration; return EFI_NOT_FOUND; } @@ -525,9 +528,12 @@ DriverCallback ( { DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; EFI_STATUS Status; - EFI_HII_UPDATE_DATA UpdateData; - IFR_OPTION *IfrOptionList; UINT8 MyVar; + VOID *StartOpCodeHandle; + VOID *OptionsOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; if ((Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; @@ -541,139 +547,179 @@ DriverCallback ( // // Initialize the container for dynamic opcodes // - IfrLibInitUpdateData (&UpdateData, 0x1000); - - IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION)); - ASSERT (IfrOptionList != NULL); - - IfrOptionList[0].Flags = 0; - IfrOptionList[0].StringToken = STRING_TOKEN (STR_BOOT_OPTION1); - IfrOptionList[0].Value.u8 = 1; - IfrOptionList[1].Flags = EFI_IFR_OPTION_DEFAULT; - IfrOptionList[1].StringToken = STRING_TOKEN (STR_BOOT_OPTION2); - IfrOptionList[1].Value.u8 = 2; - - CreateActionOpCode ( - 0x1237, // Question ID - STRING_TOKEN(STR_EXIT_TEXT), // Prompt text - STRING_TOKEN(STR_EXIT_TEXT), // Help text - EFI_IFR_FLAG_CALLBACK, // Question flag - 0, // Action String ID - &UpdateData // Container for dynamic created opcodes - ); - - // - // Prepare initial value for the dynamic created oneof Question - // - PrivateData->Configuration.DynamicOneof = 2; - Status = gRT->SetVariable( - VariableName, - &mFormSetGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (DRIVER_SAMPLE_CONFIGURATION), - &PrivateData->Configuration - ); - CreateOneOfOpCode ( - 0x8001, // Question ID (or call it "key") - CONFIGURATION_VARSTORE_ID, // VarStore ID - (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage - STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text - STRING_TOKEN (STR_ONE_OF_HELP), // Question help text - EFI_IFR_FLAG_CALLBACK, // Question flag - EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value - IfrOptionList, // Option list - 2, // Number of options in Option list - &UpdateData // Container for dynamic created opcodes - ); - - CreateOrderedListOpCode ( - 0x8002, // Question ID - CONFIGURATION_VARSTORE_ID, // VarStore ID - (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage - STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text - STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text - EFI_IFR_FLAG_RESET_REQUIRED, // Question flag - 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET - EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value - 5, // Maximum container - IfrOptionList, // Option list - 2, // Number of options in Option list - &UpdateData // Container for dynamic created opcodes - ); - - CreateGotoOpCode ( - 1, // Target Form ID - STRING_TOKEN (STR_GOTO_FORM1), // Prompt text - STRING_TOKEN (STR_GOTO_HELP), // Help text - 0, // Question flag - 0x8003, // Question ID - &UpdateData // Container for dynamic created opcodes - ); - - Status = IfrLibUpdateForm ( - PrivateData->HiiHandle[0], // HII handle - &mFormSetGuid, // Formset GUID - 0x1234, // Form ID - 0x1234, // Label for where to insert opcodes - TRUE, // Append or replace - &UpdateData // Dynamic created opcodes - ); - FreePool (IfrOptionList); - IfrLibFreeUpdateData (&UpdateData); - break; - - case 0x5678: - // - // We will reach here once the Question is refreshed - // - IfrLibInitUpdateData (&UpdateData, 0x1000); - - IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION)); - ASSERT (IfrOptionList != NULL); - - CreateActionOpCode ( - 0x1237, // Question ID - STRING_TOKEN(STR_EXIT_TEXT), // Prompt text - STRING_TOKEN(STR_EXIT_TEXT), // Help text - EFI_IFR_FLAG_CALLBACK, // Question flag - 0, // Action String ID - &UpdateData // Container for dynamic created opcodes - ); - - Status = IfrLibUpdateForm ( - PrivateData->HiiHandle[0], // HII handle - &mFormSetGuid, // Formset GUID - 3, // Form ID - 0x2234, // Label for where to insert opcodes - TRUE, // Append or replace - &UpdateData // Dynamic created opcodes - ); - IfrLibFreeUpdateData (&UpdateData); + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LABEL_UPDATE1; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1237, // Question ID + STRING_TOKEN(STR_EXIT_TEXT), // Prompt text + STRING_TOKEN(STR_EXIT_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + + // + // Create Option OpCode + // + OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle != NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_BOOT_OPTION1), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_BOOT_OPTION2), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 + ); + + // + // Prepare initial value for the dynamic created oneof Question + // + PrivateData->Configuration.DynamicOneof = 2; + Status = gRT->SetVariable( + VariableName, + &mFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8001, // Question ID (or call it "key") + CONFIGURATION_VARSTORE_ID, // VarStore ID + (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text + STRING_TOKEN (STR_ONE_OF_HELP), // Question help text + EFI_IFR_FLAG_CALLBACK, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + HiiCreateOrderedListOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8002, // Question ID + CONFIGURATION_VARSTORE_ID, // VarStore ID + (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text + STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text + EFI_IFR_FLAG_RESET_REQUIRED, // Question flag + 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value + 5, // Maximum container + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + HiiCreateGotoOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 1, // Target Form ID + STRING_TOKEN (STR_GOTO_FORM1), // Prompt text + STRING_TOKEN (STR_GOTO_HELP), // Help text + 0, // Question flag + 0x8003 // Question ID + ); + + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &mFormSetGuid, // Formset GUID + 0x1234, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (OptionsOpCodeHandle); + break; - // - // Refresh the Question value - // - PrivateData->Configuration.DynamicRefresh++; - Status = gRT->SetVariable( - VariableName, - &mFormSetGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (DRIVER_SAMPLE_CONFIGURATION), - &PrivateData->Configuration - ); + case 0x5678: + // + // We will reach here once the Question is refreshed + // + + // + // Initialize the container for dynamic opcodes + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LABEL_UPDATE2; + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1237, // Question ID + STRING_TOKEN(STR_EXIT_TEXT), // Prompt text + STRING_TOKEN(STR_EXIT_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); - // - // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause - // the first statement in Form 3 be suppressed - // - MyVar = 111; - Status = gRT->SetVariable( - L"MyVar", - &mFormSetGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - 1, - &MyVar - ); + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &mFormSetGuid, // Formset GUID + 0x3, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + NULL // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + + // + // Refresh the Question value + // + PrivateData->Configuration.DynamicRefresh++; + Status = gRT->SetVariable( + VariableName, + &mFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + // + // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause + // the first statement in Form 3 be suppressed + // + MyVar = 111; + Status = gRT->SetVariable( + L"MyVar", + &mFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + 1, + &MyVar + ); break; case 0x1237: @@ -934,32 +980,43 @@ DriverSampleInit ( ); } } + + SavedStatus = EFI_SUCCESS; // - // Example of how to display only the item we sent to HII + // Default this driver is built into Flash device image, + // the following code doesn't run. // + // - // Have the browser pull out our copy of the data, and only display our data + // Example of how to display only the item we sent to HII + // When this driver is not built into Flash device image, + // it need to call SendForm to show front page by itself. // - Status = FormBrowser2->SendForm ( - FormBrowser2, - &(HiiHandle[DISPLAY_ONLY_MY_ITEM]), - 1, - NULL, - 0, - NULL, - NULL - ); - SavedStatus = Status; - - Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]); - if (EFI_ERROR (Status)) { - return Status; + if (DISPLAY_ONLY_MY_ITEM <= 1) { + // + // Have the browser pull out our copy of the data, and only display our data + // + Status = FormBrowser2->SendForm ( + FormBrowser2, + &(HiiHandle[DISPLAY_ONLY_MY_ITEM]), + 1, + NULL, + 0, + NULL, + NULL + ); + SavedStatus = Status; + + Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]); + if (EFI_ERROR (Status)) { + return Status; + } } return SavedStatus; diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h index cdecddb..3317e4f 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h @@ -39,8 +39,6 @@ Revision History #include #include #include -#include -#include #include #include diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf b/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf index 9e5ff99..3ed56e9 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf @@ -53,8 +53,9 @@ BaseMemoryLib DebugLib HiiLib - IfrSupportLib - ExtendedIfrSupportLib + +[Guids] + gEfiIfrTianoGuid ## CONSUMES ## Guid [Protocols] gEfiHiiStringProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h b/MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h index 4fbd6a5..162c5ec 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h +++ b/MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h @@ -71,6 +71,12 @@ typedef struct { UINT8 OrderedList[3]; } MY_DATA2; +// +// Labels definition +// +#define LABEL_UPDATE1 0x1234 +#define LABEL_UPDATE2 0x2234 +#define LABEL_END 0x2223 #pragma pack() diff --git a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr index 01c7634..fc6b5da 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr +++ b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr @@ -49,7 +49,6 @@ #define LABEL_1_VALUE 0x01 #define LABEL_2_VALUE 0x1000 #define LABEL_UPDATE_BBS 0x2222 -#define LABEL_END 0x2223 formset guid = FORMSET_GUID, @@ -519,7 +518,7 @@ formset refresh interval = 3 // Refresh interval in seconds endnumeric; - label 0x2234; + label LABEL_UPDATE2; label LABEL_END; endform; @@ -531,7 +530,7 @@ formset form formid = 0x1234, // Dynamically created page, title = STRING_TOKEN(STR_DYNAMIC_TITLE); // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code - label 0x1234; + label LABEL_UPDATE1; // // This is where we will insert dynamic created opcodes // diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c index 34942f7..76068e5 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c @@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "IScsiImpl.h" EFI_GUID mVendorGuid = ISCSI_CONFIG_GUID; +CHAR16 mVendorStorageName[] = L"ISCSI_CONFIG_IFR_NVDATA"; BOOLEAN mIScsiDeviceListUpdated = FALSE; UINTN mNumberOfIScsiDevices = 0; ISCSI_FORM_CALLBACK_INFO *mCallbackInfo = NULL; @@ -504,14 +505,12 @@ IScsiFormCallback ( // // Retrive uncommitted data from Browser // - BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA); - IfrNvData = AllocateZeroPool (BufferSize); - ASSERT (IfrNvData != NULL); - Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) IfrNvData); - if (EFI_ERROR (Status)) { - gBS->FreePool (IfrNvData); - return Status; + IfrNvData = (ISCSI_CONFIG_IFR_NVDATA *) HiiGetBrowserData (&mVendorGuid, mVendorStorageName, sizeof (ISCSI_CONFIG_IFR_NVDATA)); + if (IfrNvData == NULL) { + return EFI_NOT_FOUND; } + + Status = EFI_SUCCESS; switch (QuestionId) { case KEY_INITIATOR_NAME: @@ -730,11 +729,10 @@ IScsiFormCallback ( // // Pass changed uncommitted data back to Form Browser // - BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA); - Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL); + HiiSetBrowserData (&mVendorGuid, mVendorStorageName, sizeof (ISCSI_CONFIG_IFR_NVDATA), (UINT8 *) IfrNvData, NULL); } - gBS->FreePool (IfrNvData); + FreePool (IfrNvData); return Status; } @@ -761,12 +759,14 @@ IScsiConfigUpdateForm ( ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry; BOOLEAN EntryExisted; EFI_STATUS Status; - EFI_HII_UPDATE_DATA UpdateData; EFI_SIMPLE_NETWORK_PROTOCOL *Snp; CHAR16 PortString[128]; UINT16 FormIndex; UINTN BufferSize; - + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; ConfigFormEntry = NULL; EntryExisted = FALSE; @@ -861,36 +861,56 @@ IScsiConfigUpdateForm ( // // Allocate space for creation of Buffer // - UpdateData.BufferSize = 0x1000; - UpdateData.Data = AllocateZeroPool (0x1000); - UpdateData.Offset = 0; + + // + // Init OpCode Handle + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = DEVICE_ENTRY_LABEL; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; FormIndex = 0; NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) { ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link); - CreateGotoOpCode ( - FORMID_DEVICE_FORM, - ConfigFormEntry->PortTitleToken, - ConfigFormEntry->PortTitleHelpToken, - EFI_IFR_FLAG_CALLBACK, - (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex), - &UpdateData + HiiCreateGotoOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + FORMID_DEVICE_FORM, // Target Form ID + ConfigFormEntry->PortTitleToken, // Prompt text + ConfigFormEntry->PortTitleHelpToken, // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex) // Question ID ); FormIndex++; } - IfrLibUpdateForm ( + HiiUpdateForm ( mCallbackInfo->RegisteredHandle, &mVendorGuid, FORMID_MAIN_FORM, - DEVICE_ENTRY_LABEL, - FALSE, - &UpdateData + StartOpCodeHandle, // Label DEVICE_ENTRY_LABEL + EndOpCodeHandle // LABEL_END ); - gBS->FreePool (UpdateData.Data); + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.h b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.h index fd6a2c4..b0a748a 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.h +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.h @@ -15,11 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _ISCSI_CONFIG_H_ #define _ISCSI_CONFIG_H_ +#include #include #include #include -#include -#include #include #include #include diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigDxe.vfr b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigDxe.vfr index 10f1c4e..666fa04 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigDxe.vfr +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigDxe.vfr @@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "IScsiConfigNVDataStruc.h" #define EFI_NETWORK_DEVICE_CLASS 0x04 -#define LABEL_END 0xffff - formset guid = ISCSI_CONFIG_GUID, title = STRING_TOKEN(STR_ISCSI_CONFIG_FORM_TITLE), diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigNVDataStruc.h b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigNVDataStruc.h index eb9e7dc..7b77a19 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigNVDataStruc.h +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfigNVDataStruc.h @@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define TARGET_PORT_MAX_NUM 65535 #define DEVICE_ENTRY_LABEL 0x1234 +#define LABEL_END 0xffff #define KEY_INITIATOR_NAME 0x101 #define KEY_DHCP_ENABLE 0x102 diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf index 2950991..3587c30 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf @@ -78,8 +78,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. DebugLib PrintLib HiiLib - IfrSupportLib - ExtendedIfrSupportLib NetLib [Protocols] @@ -97,3 +95,4 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. [Guids] gEfiEventExitBootServicesGuid + gEfiIfrTianoGuid ## CONSUMES ## Guid diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 90ab529..e612d4f 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -323,40 +323,25 @@ InitializeConfigHdr ( 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->ConfigHdr = HiiConstructConfigHdr ( + &Storage->Guid, + Name, + FormSet->DriverHandle + ); + + if (Storage->ConfigHdr == NULL) { + return EFI_NOT_FOUND; } - Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr); + Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr); Storage->SpareStrLen = 0; return EFI_SUCCESS; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index 699b2c4..b19d1ba 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -39,7 +39,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include #include #include diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf index d531d7b..bd4ba10 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf @@ -49,7 +49,6 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - [LibraryClasses] MemoryAllocationLib BaseLib @@ -59,9 +58,8 @@ BaseMemoryLib DebugLib PrintLib - IfrSupportLib HiiLib - + [Guids] gEfiIfrTianoGuid ## CONSUMES ## GUID gEfiIfrFrameworkGuid ## CONSUMES ## GUID -- cgit v1.1