X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=EdkCompatibilityPkg%2FCompatibility%2FFrameworkHiiOnUefiHiiThunk%2FConfigAccess.c;h=86820ca5dadb6f4094e43ae5a87efc594dc60ab8;hb=d664f8a25c2966326a5e153516395dd1925be806;hp=4701a31457a14acdb81c99673401165eebce192f;hpb=995c594047fcc85dabb58addd28486c5df04deaa;p=mirror_edk2.git diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/ConfigAccess.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/ConfigAccess.c index 4701a31457..86820ca5da 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/ConfigAccess.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/ConfigAccess.c @@ -1,10 +1,10 @@ -/**@file +/** @file This file implements functions related to Config Access Protocols installed by by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config Access Callback to Framework HII Callback and EFI Variable Set/Get operations. -Copyright (c) 2008 - 2010, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -127,38 +127,6 @@ GetStorageFromQuestionId ( return NULL; } -/** - Get the EFI_IFR_VARSTORE based the ID. - - @param FormSet The Form Set. - - @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE with the ID. - @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID. -**/ -FORMSET_STORAGE * -GetStorageFromVarStoreId ( - IN CONST FORM_BROWSER_FORMSET * FormSet, - IN EFI_VARSTORE_ID VarStoreId - ) -{ - LIST_ENTRY *StorageList; - FORMSET_STORAGE *Storage; - - StorageList = GetFirstNode (&FormSet->StorageListHead); - - while (!IsNull (&FormSet->StorageListHead, StorageList)) { - Storage = FORMSET_STORAGE_FROM_LINK (StorageList); - - if (VarStoreId == Storage->VarStoreId) { - return Storage; - } - - StorageList = GetNextNode (&FormSet->StorageListHead, StorageList); - } - - return NULL; -} - /** Get the EFI_IFR_VARSTORE based the string in a or a string. @@ -179,6 +147,10 @@ GetStorageFromConfigString ( FORMSET_STORAGE *Storage; CHAR16 *Name; + if (ConfigString == NULL) { + return NULL; + } + StorageList = GetFirstNode (&FormSet->StorageListHead); while (!IsNull (&FormSet->StorageListHead, StorageList)) { @@ -197,7 +169,7 @@ GetStorageFromConfigString ( StorageList = GetNextNode (&FormSet->StorageListHead, StorageList); } - return NULL; + return NULL; } /** @@ -377,7 +349,6 @@ CallFormCallBack ( @retval EFI_INVALID_PARAMETER If the UEFI Variable Get Service return the size information of the data does not match what has been recorded early in he BUFFER_STORAGE_ENTRY. **/ - EFI_STATUS GetUefiVariable ( IN FORMSET_STORAGE *BufferStorage, @@ -452,73 +423,194 @@ ThunkExtractConfig ( OUT EFI_STRING *Results ) { - EFI_STATUS Status; - CONFIG_ACCESS_PRIVATE *ConfigAccess; - FORMSET_STORAGE *BufferStorage; - VOID *Data; - UINTN DataSize; - - if (Request == NULL) { + EFI_STATUS Status; + CONFIG_ACCESS_PRIVATE *ConfigAccess; + FORMSET_STORAGE *BufferStorage; + VOID *Data; + UINTN DataSize; + FORM_BROWSER_FORMSET *FormSetContext; + CHAR16 *VarStoreName; + EFI_STRING ConfigRequestHdr; + EFI_STRING ConfigRequest; + UINTN Size; + BOOLEAN AllocatedRequest; + LIST_ENTRY *StorageList; + EFI_STRING SingleResult; + EFI_STRING FinalResults; + EFI_STRING StrPointer; + + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress = Request; + + Status = EFI_SUCCESS; + Data = NULL; + StrPointer = NULL; + SingleResult = NULL; + FinalResults = NULL; + ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); + FormSetContext = ConfigAccess->ThunkContext->FormSet; + if (IsListEmpty (&FormSetContext->StorageListHead)) { + // + // No VarStorage does exist in this form. + // return EFI_NOT_FOUND; } + StorageList = GetFirstNode (&FormSetContext->StorageListHead); - Data = NULL; - ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); + do { + if (Request != NULL) { + BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request); + if (BufferStorage == NULL) { + return EFI_NOT_FOUND; + } + } else { + if (IsNull (&FormSetContext->StorageListHead, StorageList)) { + // + // No Storage to be extracted into the results. + // + break; + } + BufferStorage = FORMSET_STORAGE_FROM_LINK (StorageList); + StorageList = GetNextNode (&FormSetContext->StorageListHead, StorageList); + } + + VarStoreName = NULL; + ConfigRequestHdr = NULL; + ConfigRequest = NULL; + Size = 0; + AllocatedRequest = FALSE; + + if (ConfigAccess->ThunkContext->NvMapOverride == NULL) { + // + // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback. + // + if (ConfigAccess->FormCallbackProtocol == NULL || + ConfigAccess->FormCallbackProtocol->NvRead == NULL) { + Status = GetUefiVariable ( + BufferStorage, + &Data, + &DataSize + ); + } else { + Status = CallFormCallBack ( + BufferStorage, + ConfigAccess->FormCallbackProtocol, + &Data, + &DataSize + ); + } + } else { + // + // Use the NvMapOverride. + // + DataSize = BufferStorage->Size; + Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride); + + if (Data != NULL) { + Status = EFI_SUCCESS; + } else { + Status = EFI_OUT_OF_RESOURCES; + } + } + + if (!EFI_ERROR (Status)) { + ConfigRequest = Request; + if (Request == NULL || (StrStr (Request, L"OFFSET") == NULL)) { + // + // Request is without any request element, construct full request string. + // - BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request); + if ((BufferStorage->VarStoreId == FormSetContext->DefaultVarStoreId) && (FormSetContext->OriginalDefaultVarStoreName != NULL)) { + VarStoreName = FormSetContext->OriginalDefaultVarStoreName; + } else { + VarStoreName = BufferStorage->Name; + } - if (BufferStorage == NULL) { - *Progress = (EFI_STRING) Request; - return EFI_NOT_FOUND; - } + // + // First Set ConfigRequestHdr string. + // + ConfigRequestHdr = HiiConstructConfigHdr (&BufferStorage->Guid, VarStoreName, ConfigAccess->ThunkContext->UefiHiiDriverHandle); + ASSERT (ConfigRequestHdr != NULL); - if (ConfigAccess->ThunkContext->NvMapOverride == 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 (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + ASSERT (ConfigRequest != NULL); + AllocatedRequest = TRUE; + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)DataSize); + FreePool (ConfigRequestHdr); + } + Status = mHiiConfigRoutingProtocol->BlockToConfig ( + mHiiConfigRoutingProtocol, + ConfigRequest, + Data, + DataSize, + &SingleResult, + Progress + ); + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + ConfigRequest = NULL; + } + } // - // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback. + // Free the allocated Data // - if (ConfigAccess->FormCallbackProtocol == NULL || - ConfigAccess->FormCallbackProtocol->NvRead == NULL) { - Status = GetUefiVariable ( - BufferStorage, - &Data, - &DataSize - ); - } else { - Status = CallFormCallBack ( - BufferStorage, - ConfigAccess->FormCallbackProtocol, - &Data, - &DataSize - ); + if (Data != NULL) { + FreePool (Data); } - } else { // - // Use the NvMapOverride. + // Directly return when meet with error // - DataSize = BufferStorage->Size; - Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride); - - if (Data != NULL) { - Status = EFI_SUCCESS; + if (EFI_ERROR (Status)) { + break; + } + // + // Merge result into the final results. + // + if (FinalResults == NULL) { + FinalResults = SingleResult; + SingleResult = NULL; } else { - Status = EFI_OUT_OF_RESOURCES; + Size = StrLen (FinalResults); + Size = Size + 1; + Size = Size + StrLen (SingleResult) + 1; + StrPointer = AllocateZeroPool (Size * sizeof (CHAR16)); + ASSERT (StrPointer != NULL); + StrCpy (StrPointer, FinalResults); + FreePool (FinalResults); + FinalResults = StrPointer; + StrPointer = StrPointer + StrLen (StrPointer); + *StrPointer = L'&'; + StrCpy (StrPointer + 1, SingleResult); + FreePool (SingleResult); } - } - + } while (Request == NULL); + if (!EFI_ERROR (Status)) { - Status = mHiiConfigRoutingProtocol->BlockToConfig ( - mHiiConfigRoutingProtocol, - Request, - Data, - DataSize, - Results, - Progress - ); + *Results = FinalResults; + } else { + if (FinalResults != NULL) { + FreePool (FinalResults); + } } - - if (Data != NULL) { - FreePool (Data); + // + // Set Progress string to the original request string. + // + if (Request == NULL) { + *Progress = NULL; + } else if (StrStr (Request, L"OFFSET") == NULL) { + *Progress = Request + StrLen (Request); } + return Status; } @@ -651,7 +743,7 @@ Done: ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING. - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL + @param ConfigAccess Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL @param QuestionId The Question ID. @param Type The Question Type. @param Value The Question Value. @@ -701,6 +793,7 @@ CreateIfrDataArray ( break; case EFI_IFR_TYPE_ACTION: + case EFI_IFR_TYPE_UNDEFINED: Size = 0; break; @@ -760,6 +853,7 @@ CreateIfrDataArray ( break; case EFI_IFR_TYPE_ACTION: + case EFI_IFR_TYPE_UNDEFINED: break; default: @@ -1013,132 +1107,131 @@ ThunkCallback ( EFI_INPUT_KEY Key; BOOLEAN NvMapAllocated; - if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) { - // - // Ignore UEFI OPEN/CLOSE Action for FrameworkCallback - // - return EFI_SUCCESS; - } + if (Action == EFI_BROWSER_ACTION_CHANGING) { + ASSERT (This != NULL); + ASSERT (Value != NULL); + ASSERT (ActionRequest != NULL); - ASSERT (This != NULL); - ASSERT (Value != NULL); - ASSERT (ActionRequest != NULL); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); - ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This); + FormCallbackProtocol = ConfigAccess->FormCallbackProtocol; + if (FormCallbackProtocol == NULL) { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } - FormCallbackProtocol = ConfigAccess->FormCallbackProtocol; - if (FormCallbackProtocol == NULL) { - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } + // + // Check if the QuestionId match a OneOfOption. + // + OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value); - // - // Check if the QuestionId match a OneOfOption. - // - OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value); + if (OneOfOptionMapEntry == NULL) { + // + // This is not a One-Of-Option opcode. QuestionId is the KeyValue + // + KeyValue = QuestionId; + } else { + // + // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax. + // + KeyValue = OneOfOptionMapEntry->FwKey; + } - if (OneOfOptionMapEntry == NULL) { // - // This is not a One-Of-Option opcode. QuestionId is the KeyValue + // Build the EFI_IFR_DATA_ARRAY // - KeyValue = QuestionId; - } else { + Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated); + + Status = mHiiDatabase->RegisterPackageNotify ( + mHiiDatabase, + EFI_HII_PACKAGE_FORMS, + NULL, + FormUpdateNotify, + EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, + &NotifyHandle + ); // - // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax. + //Call the Framework Callback function. // - KeyValue = OneOfOptionMapEntry->FwKey; - } - - // - // Build the EFI_IFR_DATA_ARRAY - // - Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated); - - Status = mHiiDatabase->RegisterPackageNotify ( - mHiiDatabase, - EFI_HII_PACKAGE_FORMS, - NULL, - FormUpdateNotify, - EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, - &NotifyHandle - ); - // - //Call the Framework Callback function. - // - Packet = NULL; - Status = FormCallbackProtocol->Callback ( - FormCallbackProtocol, - KeyValue, - Data, - &Packet - ); - SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId); + Packet = NULL; + Status = FormCallbackProtocol->Callback ( + FormCallbackProtocol, + KeyValue, + Data, + &Packet + ); + SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId); - // - // Callback require browser to perform action - // - if (EFI_ERROR (Status)) { - if (Packet != NULL) { - do { - CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, Packet->String, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - } // - // Error Code in Status is discarded. + // Callback require browser to perform action // - } else { - if (Packet != NULL) { - if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) { - DataEntry = (EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (EFI_IFR_DATA_ARRAY)); - if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) { - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; - } - - if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) { - Status = ConfigAccess->ConfigAccessProtocol.RouteConfig ( - &ConfigAccess->ConfigAccessProtocol, - NULL, - NULL - ); + if (EFI_ERROR (Status)) { + if (Packet != NULL) { + do { + CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, Packet->String, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + } + // + // Error Code in Status is discarded. + // + } else { + if (Packet != NULL) { + if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) { + DataEntry = (EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (EFI_IFR_DATA_ARRAY)); + if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } + + if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) { + Status = ConfigAccess->ConfigAccessProtocol.RouteConfig ( + &ConfigAccess->ConfigAccessProtocol, + NULL, + NULL + ); + } } - } - FreePool (Packet); + FreePool (Packet); + } } - } - // - // Unregister notify for Form package update - // - Status = mHiiDatabase->UnregisterPackageNotify ( - mHiiDatabase, - NotifyHandle - ); - // - // UEFI SetupBrowser behaves differently with Framework SetupBrowser when call back function - // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load - // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages. - // To make sure customer's previous changes is saved and the changing question behaves as expected, we - // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse - // the form and load all the variable storages. - // - if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) { - mHiiPackageListUpdated= FALSE; - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; - } else { - if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS || - ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) { - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + // + // Unregister notify for Form package update + // + Status = mHiiDatabase->UnregisterPackageNotify ( + mHiiDatabase, + NotifyHandle + ); + // + // UEFI SetupBrowser behaves differently with Framework SetupBrowser when call back function + // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load + // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages. + // To make sure customer's previous changes is saved and the changing question behaves as expected, we + // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse + // the form and load all the variable storages. + // + if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) { + mHiiPackageListUpdated= FALSE; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + } else { + if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS || + ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } } - } + // + // Clean up. + // + DestroyIfrDataArray (Data, NvMapAllocated); + + return Status; + } // - // Clean up. + // All other action return unsupported. // - DestroyIfrDataArray (Data, NvMapAllocated); - - return Status; + return EFI_UNSUPPORTED; }