From db40504eaeaf1f005755305cf8c48fcfd281360b Mon Sep 17 00:00:00 2001 From: ydong10 Date: Tue, 22 Nov 2011 07:46:35 +0000 Subject: [PATCH] Add support for EFI_IFR_QUESTION_REF3 opcode for browser when this opcode has the device path info. Signed-off-by: ydong10 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12759 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/SetupBrowserDxe/Expression.c | 200 ++++++++++++++++-- .../Universal/SetupBrowserDxe/Setup.c | 29 ++- .../Universal/SetupBrowserDxe/Setup.h | 4 +- 3 files changed, 202 insertions(+), 31 deletions(-) diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c index 883693fde5..b6028cb31f 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c @@ -522,7 +522,7 @@ IdToQuestion2 ( LIST_ENTRY *Link; FORM_BROWSER_STATEMENT *Question; - if (QuestionId == 0) { + if (QuestionId == 0 || Form == NULL) { // // The value of zero is reserved // @@ -757,6 +757,7 @@ IfrToString ( // so need 1 byte to align, also need 2 bytes for L'\0'. // TmpBuf = AllocateZeroPool (Value.BufferLen + 3); + ASSERT (TmpBuf != NULL); if (Format == EFI_IFR_STRING_ASCII) { CopyMem (TmpBuf, Value.Buffer, Value.BufferLen); PrintFormat = L"%a"; @@ -1651,6 +1652,151 @@ CheckUserPrivilege ( return FALSE; } +/** + Get question value from the predefined formset. + + @param DevicePath The driver's device path which produece the formset data. + @param InputHiiHandle The hii handle associate with the formset data. + @param FormSetGuid The formset guid which include the question. + @param QuestionId The question id which need to get value from. + @param Value The return data about question's value. + + @retval TRUE Get the question value success. + @retval FALSE Get the question value failed. +**/ +BOOLEAN +GetQuestionValueFromForm ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_HII_HANDLE InputHiiHandle, + IN EFI_GUID *FormSetGuid, + IN EFI_QUESTION_ID QuestionId, + OUT EFI_HII_VALUE *Value + ) +{ + EFI_STATUS Status; + EFI_HANDLE DriverHandle; + EFI_HANDLE Handle; + EFI_HII_HANDLE *HiiHandles; + EFI_HII_HANDLE HiiHandle; + UINTN Index; + FORM_BROWSER_STATEMENT *Question; + FORM_BROWSER_FORMSET *FormSet; + FORM_BROWSER_FORM *Form; + BOOLEAN GetTheVal; + LIST_ENTRY *Link; + + // + // The input parameter DevicePath or InputHiiHandle must have one valid input. + // + ASSERT ((DevicePath != NULL && InputHiiHandle == NULL) || + (DevicePath == NULL && InputHiiHandle != NULL) ); + + GetTheVal = TRUE; + DriverHandle = NULL; + HiiHandle = NULL; + Question = NULL; + Form = NULL; + + // + // Get HiiHandle. + // + if (DevicePath != NULL) { + // + // 1. Get Driver handle. + // + Status = gBS->LocateDevicePath ( + &gEfiDevicePathProtocolGuid, + &DevicePath, + &DriverHandle + ); + if (EFI_ERROR (Status) || (DriverHandle == NULL)) { + return FALSE; + } + + // + // 2. Get Hii handle + // + HiiHandles = HiiGetHiiHandles (NULL); + if (HiiHandles == NULL) { + return FALSE; + } + + for (Index = 0; HiiHandles[Index] != NULL; Index++) { + Status = mHiiDatabase->GetPackageListHandle ( + mHiiDatabase, + HiiHandles[Index], + &Handle + ); + if (!EFI_ERROR (Status) && (Handle == DriverHandle)) { + HiiHandle = HiiHandles[Index]; + break; + } + } + FreePool (HiiHandles); + } else { + HiiHandle = InputHiiHandle; + } + ASSERT (HiiHandle != NULL); + + // + // Get the formset data include this question. + // + FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); + ASSERT (FormSet != NULL); + Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE); + if (EFI_ERROR (Status)) { + GetTheVal = FALSE; + goto Done; + } + + // + // Base on the Question Id to get the question info. + // + Question = IdToQuestion(FormSet, NULL, QuestionId); + if (Question == NULL) { + GetTheVal = FALSE; + goto Done; + } + + // + // Search form in the formset scope + // + Link = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, Link)) { + Form = FORM_BROWSER_FORM_FROM_LINK (Link); + + Question = IdToQuestion2 (Form, QuestionId); + if (Question != NULL) { + break; + } + + Link = GetNextNode (&FormSet->FormListHead, Link); + Form = NULL; + } + ASSERT (Form != NULL); + + // + // Get the question value. + // + Status = GetQuestionValue(FormSet, Form, Question, FALSE); + if (EFI_ERROR (Status)) { + GetTheVal = FALSE; + goto Done; + } + + CopyMem (Value, &Question->HiiValue, sizeof (EFI_HII_VALUE)); + +Done: + // + // Clean the formset structure and restore the global parameter. + // + if (FormSet != NULL) { + DestroyFormSet (FormSet); + } + + return GetTheVal; +} + /** Evaluate the result of a HII expression. @@ -1699,6 +1845,7 @@ EvaluateExpression ( UINT8 DigitUint8; UINT8 *TempBuffer; EFI_TIME EfiTime; + EFI_HII_VALUE QuestionVal; // // Save current stack offset. @@ -1931,24 +2078,42 @@ EvaluateExpression ( break; case EFI_IFR_QUESTION_REF3_OP: - if (OpCode->DevicePath == 0) { - // - // EFI_IFR_QUESTION_REF3 - // Pop an expression from the expression stack - // - Status = PopExpression (Value); - if (EFI_ERROR (Status)) { - goto Done; - } + // + // EFI_IFR_QUESTION_REF3 + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Validate the expression value + // + if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { + Status = EFI_NOT_FOUND; + goto Done; + } - // - // Validate the expression value - // - if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { + if (OpCode->DevicePath != 0) { + StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle); + if (StrPtr == NULL) { Status = EFI_NOT_FOUND; goto Done; } + if (!GetQuestionValueFromForm((EFI_DEVICE_PATH_PROTOCOL*)StrPtr, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)){ + Status = EFI_NOT_FOUND; + goto Done; + } + Value = &QuestionVal; + } else if (CompareGuid (&OpCode->Guid, &gZeroGuid) != 0) { + if (!GetQuestionValueFromForm(NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)){ + Status = EFI_NOT_FOUND; + goto Done; + } + Value = &QuestionVal; + } else { Question = IdToQuestion (FormSet, Form, Value->Value.u16); if (Question == NULL) { Status = EFI_NOT_FOUND; @@ -1959,13 +2124,6 @@ EvaluateExpression ( // push the questions' value on to the expression stack // Value = &Question->HiiValue; - } else { - // - // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3, - // since it is impractical to evaluate the value of a Question in another - // Hii Package list. - // - ZeroMem (Value, sizeof (EFI_HII_VALUE)); } break; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index 92582f35d8..6b169cd0a1 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -329,7 +329,7 @@ SendForm ( // // Initialize internal data structures of FormSet // - Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet); + Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet, TRUE); if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) { DestroyFormSet (FormSet); break; @@ -1220,6 +1220,7 @@ GetQuestionValue ( Status = EFI_SUCCESS; Value = NULL; + Result = NULL; // // Statement don't have storage, skip them @@ -1428,7 +1429,7 @@ GetQuestionValue ( FreePool (Value); } } else { - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { + if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { // // Request current settings from Configuration Driver // @@ -1541,9 +1542,9 @@ GetQuestionValue ( } } } - FreePool (Result); if (EFI_ERROR (Status)) { + FreePool (Result); return Status; } } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { @@ -1579,6 +1580,10 @@ GetQuestionValue ( } else { SetValueByName (Storage, Question->VariableName, Value, TRUE); } + + if (Result != NULL) { + FreePool (Result); + } } return Status; @@ -1783,7 +1788,7 @@ SetQuestionValue ( } if (!Cached) { - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { + if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { // // ::= + + "&VALUE=" + "StorageWidth * 2" || // + "&" + + "=" + "" @@ -2991,7 +2996,6 @@ ExtractDefault ( EFI_HII_HANDLE *HiiHandles; UINTN Index; EFI_GUID ZeroGuid; - UINTN BackUpClassOfVfr; // // Check the supported setting level. @@ -3051,7 +3055,6 @@ ExtractDefault ( // Open all FormSet by locate HII packages. // Initiliaze the maintain FormSet to store default data as back up data. // - BackUpClassOfVfr = gClassOfVfr; BackUpFormSet = gOldFormSet; gOldFormSet = NULL; @@ -3078,7 +3081,7 @@ ExtractDefault ( LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); ASSERT (LocalFormSet != NULL); ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); - Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet); + Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet, FALSE); if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) { DestroyFormSet (LocalFormSet); continue; @@ -3108,7 +3111,6 @@ ExtractDefault ( // FreePool (HiiHandles); gOldFormSet = BackUpFormSet; - gClassOfVfr = BackUpClassOfVfr; // // Set Default Value for each FormSet in the maintain list. @@ -3660,6 +3662,7 @@ GetIfrBinaryData ( found in package list. On output, GUID of the formset found(if not NULL). @param FormSet FormSet data structure. + @param UpdateGlobalVar Whether need to update the global variable. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND The specified FormSet could not be found. @@ -3669,7 +3672,8 @@ EFI_STATUS InitializeFormSet ( IN EFI_HII_HANDLE Handle, IN OUT EFI_GUID *FormSetGuid, - OUT FORM_BROWSER_FORMSET *FormSet + OUT FORM_BROWSER_FORMSET *FormSet, + IN BOOLEAN UpdateGlobalVar ) { EFI_STATUS Status; @@ -3714,6 +3718,13 @@ InitializeFormSet ( return Status; } + // + // If not need to update the global variable, just return. + // + if (!UpdateGlobalVar) { + return Status; + } + // // Set VFR type by FormSet SubClass field // diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index 168979a52a..214102c213 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -1026,6 +1026,7 @@ InitializeCurrentSetting ( GUID), take the first FormSet found in package list. @param FormSet FormSet data structure. + @param UpdateGlobalVar Whether need to update the global variable. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND The specified FormSet could not be found. @@ -1035,7 +1036,8 @@ EFI_STATUS InitializeFormSet ( IN EFI_HII_HANDLE Handle, IN OUT EFI_GUID *FormSetGuid, - OUT FORM_BROWSER_FORMSET *FormSet + OUT FORM_BROWSER_FORMSET *FormSet, + IN BOOLEAN UpdateGlobalVar ); /**