/** Get the FORM_BROWSER_STATEMENT that matches the Question's value. @param FormSet The Form Set. @param QuestionId QuestionId @retval FORM_BROWSER_STATEMENT* FORM_BROWSER_STATEMENT that match Question's value. @retval NULL If the Form Set does not have EFI_IFR_VARSTORE. **/ FORM_BROWSER_STATEMENT * GetStorageFromQuestionId ( IN CONST FORM_BROWSER_FORMSET * FormSet, IN EFI_QUESTION_ID QuestionId ) { LIST_ENTRY *FormList; LIST_ENTRY *StatementList; FORM_BROWSER_FORM *Form; FORM_BROWSER_STATEMENT *Statement; FormList = GetFirstNode (&FormSet->FormListHead); while (!IsNull (&FormSet->FormListHead, FormList)) { Form = FORM_BROWSER_FORM_FROM_LINK (FormList); StatementList = GetFirstNode (&Form->StatementListHead); while (!IsNull (&Form->StatementListHead, StatementList)) { Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList); if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) { // // UEFI Question ID is unique in a FormSet. // ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER); return Statement; } StatementList = GetNextNode (&Form->StatementListHead, StatementList); } FormList = GetNextNode (&FormSet->FormListHead, FormList); } return NULL; }
FORM_BROWSER_STATEMENT * IdToQuestion ( IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORM *Form, IN UINT16 QuestionId ) /*++ Routine Description: Search a Question in Formset scope using its QuestionId. Arguments: FormSet - The formset which contains this form. Form - The form which contains this Question. QuestionId - Id of this Question. Returns: Pointer - The Question. NULL - Specified Question not found in the form. --*/ { EFI_LIST_ENTRY *Link; FORM_BROWSER_STATEMENT *Question; // // Search in the form scope first // Question = IdToQuestion2 (Form, QuestionId); if (Question != NULL) { return Question; } // // Search 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) { // // EFI variable storage may be updated by Callback() asynchronous, // to keep synchronous, always reload the Question Value. // if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { GetQuestionValue (FormSet, Form, Question, FALSE); } return Question; } Link = GetNextNode (&FormSet->FormListHead, Link); } return NULL; }
/** Get the default value for Buffer Type storage named by a Default Store and a Storage Store from a FormSet. The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE allocated by this function. It is inserted to the link list. @param DefaultStore The Default Store. @param Storage The Storage. @param FormSet The Form Set. @param UefiDefaultsListHead The head of link list for the output. @retval EFI_SUCCESS Successful. **/ EFI_STATUS GetBufferTypeDefaultIdAndStorageId ( IN FORMSET_DEFAULTSTORE *DefaultStore, IN FORMSET_STORAGE *Storage, IN FORM_BROWSER_FORMSET *FormSet, OUT LIST_ENTRY *UefiDefaultsListHead ) { UEFI_IFR_BUFFER_STORAGE_NODE *Node; LIST_ENTRY *Link; FORM_BROWSER_FORM *Form; EFI_STATUS Status; Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE)); ASSERT (Node != NULL); Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE; Node->Name = AllocateCopyPool (StrSize (Storage->Name), Storage->Name); Node->DefaultId = DefaultStore->DefaultId; Node->StoreId = Storage->VarStoreId; CopyGuid (&Node->Guid, &Storage->Guid); Node->Size = Storage->Size; Node->Buffer = AllocateZeroPool (Node->Size); // // Extract default from IFR binary // Link = GetFirstNode (&FormSet->FormListHead); while (!IsNull (&FormSet->FormListHead, Link)) { Form = FORM_BROWSER_FORM_FROM_LINK (Link); Status = ExtractFormDefault (Form, DefaultStore->DefaultId, Storage->VarStoreId, Node); ASSERT_EFI_ERROR (Status); Link = GetNextNode (&FormSet->FormListHead, Link); } InsertTailList (UefiDefaultsListHead, &Node->List); return EFI_SUCCESS; }
FORM_BROWSER_FORM * IdToForm ( IN FORM_BROWSER_FORMSET *FormSet, IN UINT16 FormId ) /*++ Routine Description: Get Form given its FormId. Arguments: FormSet - The formset which contains this form. FormId - Id of this form. Returns: Pointer - The form. NULL - Specified Form is not found in the formset. --*/ { EFI_LIST_ENTRY *Link; FORM_BROWSER_FORM *Form; Link = GetFirstNode (&FormSet->FormListHead); while (!IsNull (&FormSet->FormListHead, Link)) { Form = FORM_BROWSER_FORM_FROM_LINK (Link); if (Form->FormId == FormId) { return Form; } Link = GetNextNode (&FormSet->FormListHead, Link); } return NULL; }
/** Translate a Framework Question ID to UEFI Question ID. @param FormSet FormSet context @param FwOpCode Framework Opcode @param FwQId Framework Question Id @param UefiQId UEFI Question ID. @retval EFI_SUCCESS The UEFI Question Id is found and returned. @retval EFI_NOT_FOUND The UEFI Question Id is not found. **/ EFI_STATUS FwQIdToUefiQId ( IN CONST FORM_BROWSER_FORMSET *FormSet, IN UINT8 FwOpCode, IN UINT16 FwQId, OUT UINT16 *UefiQId ) { LIST_ENTRY *FormList; LIST_ENTRY *StatementList; FORM_BROWSER_FORM *Form; FORM_BROWSER_STATEMENT *Statement; FORM_BROWSER_STATEMENT *StatementFound; EFI_STATUS Status; UINT8 UefiOp; *UefiQId = 0; StatementFound = NULL; FormList = GetFirstNode (&FormSet->FormListHead); while (!IsNull (&FormSet->FormListHead, FormList)) { Form = FORM_BROWSER_FORM_FROM_LINK (FormList); StatementList = GetFirstNode (&Form->StatementListHead); while (!IsNull (&Form->StatementListHead, StatementList)) { Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList); if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) { if (FwQId == Statement->VarStoreInfo.VarOffset) { Status = QuestionOpFwToUefi (FwOpCode, &UefiOp); ASSERT_EFI_ERROR (Status); if ((UefiOp == Statement->Operand) && (FormSet->DefaultVarStoreId == Statement->VarStoreId)) { // // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same: // 1) Same Question Type, // 2) Same Variable Storage // 3) Refering to the Same offset in Variable Map (NvMap). // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question // ID to return. // // One possible solution is to remove the one of the duplicated questions in this Form Set. // ASSERT (StatementFound == NULL); StatementFound= Statement; // // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes // with same value. // } } } StatementList = GetNextNode (&Form->StatementListHead, StatementList); } FormList = GetNextNode (&FormSet->FormListHead, FormList); } if (StatementFound != NULL) { *UefiQId = StatementFound->QuestionId; return EFI_SUCCESS; } return EFI_NOT_FOUND; }
/** Free resources allocated for a FormSet @param FormSet Pointer of the FormSet @return None. **/ VOID DestroyFormSet ( IN OUT FORM_BROWSER_FORMSET *FormSet ) { LIST_ENTRY *Link; FORMSET_STORAGE *Storage; FORMSET_DEFAULTSTORE *DefaultStore; FORM_BROWSER_FORM *Form; // // Free IFR binary buffer // FreePool (FormSet->IfrBinaryData); // // Free FormSet Storage // if (FormSet->StorageListHead.ForwardLink != NULL) { while (!IsListEmpty (&FormSet->StorageListHead)) { Link = GetFirstNode (&FormSet->StorageListHead); Storage = FORMSET_STORAGE_FROM_LINK (Link); RemoveEntryList (&Storage->Link); DestroyStorage (Storage); } } // // Free FormSet Default Store // if (FormSet->DefaultStoreListHead.ForwardLink != NULL) { while (!IsListEmpty (&FormSet->DefaultStoreListHead)) { Link = GetFirstNode (&FormSet->DefaultStoreListHead); DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link); RemoveEntryList (&DefaultStore->Link); gBS->FreePool (DefaultStore); } } // // Free Forms // if (FormSet->FormListHead.ForwardLink != NULL) { while (!IsListEmpty (&FormSet->FormListHead)) { Link = GetFirstNode (&FormSet->FormListHead); Form = FORM_BROWSER_FORM_FROM_LINK (Link); RemoveEntryList (&Form->Link); DestroyForm (Form); } } if (FormSet->StatementBuffer != NULL) { FreePool (FormSet->StatementBuffer); } DestoryOneOfOptionMap (&FormSet->OneOfOptionMapListHead); if (FormSet->OriginalDefaultVarStoreName != NULL) { FreePool (FormSet->OriginalDefaultVarStoreName); } FreePool (FormSet); }