396 lines
14 KiB
C
396 lines
14 KiB
C
/** @file
|
|
For IFR Import Op Codes
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2019 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "InternalH2OFormBrowser.h"
|
|
#include "FBProcessVfcf.h"
|
|
|
|
|
|
EFI_STATUS
|
|
GetImportInfoListFromVfrFormSet (
|
|
IN FORM_BROWSER_FORMSET *FormSet,
|
|
OUT IMPORT_INFO **ImportInfoList,
|
|
OUT UINT16 *ImportInfoCount
|
|
)
|
|
{
|
|
LIST_ENTRY *LinkForm;
|
|
LIST_ENTRY *LinkStatement;
|
|
FORM_BROWSER_FORM *Form;
|
|
FORM_BROWSER_STATEMENT *Statement;
|
|
UINT16 Count;
|
|
IMPORT_INFO *NewImportInfoList;
|
|
IMPORT_INFO *ImportInfo;
|
|
|
|
if (FormSet == NULL || ImportInfoList == NULL || ImportInfoCount == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Count = 0;
|
|
LinkForm = GetFirstNode (&FormSet->FormListHead);
|
|
while (!IsNull (&FormSet->FormListHead, LinkForm)) {
|
|
Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);
|
|
LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);
|
|
|
|
LinkStatement = GetFirstNode (&Form->StatementListHead);
|
|
while (!IsNull (&Form->StatementListHead, LinkStatement)) {
|
|
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (LinkStatement);
|
|
LinkStatement = GetNextNode (&Form->StatementListHead, LinkStatement);
|
|
if (IS_VFR_IMPORT_FAKE_STATEMENT(Statement) && Statement->VfrImportInfo->ImportInfo.Type == VFR_IMPORT) {
|
|
Count++;
|
|
}
|
|
}
|
|
}
|
|
if (Count == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Update ImportInfoList
|
|
//
|
|
NewImportInfoList = ReallocatePool (
|
|
sizeof (IMPORT_INFO) * (*ImportInfoCount),
|
|
sizeof (IMPORT_INFO) * (*ImportInfoCount + Count),
|
|
*ImportInfoList
|
|
);
|
|
if (NewImportInfoList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Count = *ImportInfoCount;
|
|
LinkForm = GetFirstNode (&FormSet->FormListHead);
|
|
while (!IsNull (&FormSet->FormListHead, LinkForm)) {
|
|
Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);
|
|
LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);
|
|
|
|
LinkStatement = GetFirstNode (&Form->StatementListHead);
|
|
while (!IsNull (&Form->StatementListHead, LinkStatement)) {
|
|
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (LinkStatement);
|
|
LinkStatement = GetNextNode (&Form->StatementListHead, LinkStatement);
|
|
if (IS_VFR_IMPORT_FAKE_STATEMENT(Statement) && Statement->VfrImportInfo->ImportInfo.Type == VFR_IMPORT) {
|
|
//
|
|
// Update the ImportInfo which from CurrentQ
|
|
//
|
|
if (((Statement->VfrImportInfo->ImportInfo.Flags & H2O_HII_IMPORT_CURRENT_SELECTION) == H2O_HII_IMPORT_CURRENT_SELECTION) &&
|
|
(mFBPrivate.FB.CurrentQ != NULL)) {
|
|
CopyGuid (&Statement->VfrImportInfo->ImportInfo.SrcFormSetGuid, &mFBPrivate.FB.CurrentQ->FormsetGuid);
|
|
Statement->VfrImportInfo->ImportInfo.SrcFormId = mFBPrivate.FB.CurrentQ->FormId;
|
|
Statement->VfrImportInfo->ImportInfo.SrcId = mFBPrivate.FB.CurrentQ->QuestionId;
|
|
}
|
|
|
|
ImportInfo = &NewImportInfoList[Count++];
|
|
CopyMem (
|
|
ImportInfo,
|
|
&Statement->VfrImportInfo->ImportInfo,
|
|
sizeof (IMPORT_INFO)
|
|
);
|
|
ImportInfo->VfrFakeStatement = (VOID *)Statement;
|
|
}
|
|
}
|
|
}
|
|
*ImportInfoList = NewImportInfoList;
|
|
*ImportInfoCount = Count;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
CopyStatementProperties (
|
|
IN FORM_BROWSER_STATEMENT *SrcStatement,
|
|
IN OUT FORM_BROWSER_STATEMENT *DstStatement
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
H2O_PROPERTY_INFO *SrcProperty;
|
|
H2O_PROPERTY_INFO *DstProperty;
|
|
|
|
if (DstStatement->PropertyListHead.ForwardLink == NULL) {
|
|
InitializeListHead (&DstStatement->PropertyListHead);
|
|
}
|
|
|
|
Link = GetFirstNode (&SrcStatement->PropertyListHead);
|
|
while (!IsNull (&SrcStatement->PropertyListHead, Link)) {
|
|
SrcProperty = H2O_PROPERTY_INFO_NODE_FROM_LINK (Link);
|
|
Link = GetNextNode (&SrcStatement->PropertyListHead, Link);
|
|
|
|
DstProperty = AllocateCopyPool (sizeof (H2O_PROPERTY_INFO), SrcProperty);
|
|
if (DstProperty == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
InsertTailList (&DstStatement->PropertyListHead, &DstProperty->Link);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
CopyStatementExpression (
|
|
IN FORM_BROWSER_FORMSET *FormSet,
|
|
IN FORM_BROWSER_FORM *Form,
|
|
IN FORM_BROWSER_STATEMENT *SrcStatement,
|
|
IN OUT FORM_BROWSER_STATEMENT *DstStatement
|
|
)
|
|
{
|
|
UINTN Index;
|
|
FORM_EXPRESSION_LIST *NewExpression;
|
|
|
|
if (SrcStatement->Expression == NULL || SrcStatement->Expression->Count == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (DstStatement->Expression == NULL) {
|
|
NewExpression = AllocateZeroPool ((UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((SrcStatement->Expression->Count - 1) * sizeof(FORM_EXPRESSION *))));
|
|
if (NewExpression == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
NewExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
|
|
NewExpression->Count = 0;
|
|
} else {
|
|
NewExpression = AllocateZeroPool ((UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((SrcStatement->Expression->Count + DstStatement->Expression->Count - 1) * sizeof(FORM_EXPRESSION *))));
|
|
if (NewExpression == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
NewExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
|
|
NewExpression->Count = DstStatement->Expression->Count;
|
|
if (DstStatement->Expression->Count > 0) {
|
|
CopyMem (
|
|
NewExpression->Expression,
|
|
DstStatement->Expression->Expression,
|
|
DstStatement->Expression->Count * sizeof(FORM_EXPRESSION *)
|
|
);
|
|
}
|
|
FreePool (DstStatement->Expression);
|
|
}
|
|
DstStatement->Expression = NewExpression;
|
|
|
|
for (Index = 0; Index < SrcStatement->Expression->Count; Index++) {
|
|
CopyExpression (
|
|
FormSet,
|
|
SrcStatement->Expression->Expression[Index],
|
|
FormSet,
|
|
Form,
|
|
&DstStatement->Expression->Expression[DstStatement->Expression->Count]
|
|
);
|
|
InsertTailList (&Form->ExpressionListHead, &DstStatement->Expression->Expression[DstStatement->Expression->Count]->Link);
|
|
DstStatement->Expression->Count++;
|
|
}
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
InsertNewStatementAfterFakeStatement (
|
|
IN FORM_BROWSER_FORMSET *FormSet,
|
|
IN FORM_BROWSER_FORM *Form,
|
|
IN FORM_BROWSER_STATEMENT *FakeStatement,
|
|
IN FORM_BROWSER_STATEMENT *NewStatement
|
|
)
|
|
{
|
|
if (FormSet == NULL || FakeStatement == NULL || NewStatement == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
CopyStatementProperties (FakeStatement, NewStatement);
|
|
CopyStatementExpression (FormSet, Form, FakeStatement, NewStatement);
|
|
|
|
InsertTailList (&FakeStatement->Link, &NewStatement->Link);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
DeleteAllVfrImportNewStatements (
|
|
IN FORM_BROWSER_FORMSET *FormSet
|
|
)
|
|
{
|
|
LIST_ENTRY *LinkForm;
|
|
LIST_ENTRY *LinkStatement;
|
|
FORM_BROWSER_FORM *Form;
|
|
FORM_BROWSER_STATEMENT *Statement;
|
|
FORM_BROWSER_STATEMENT *FakeStatement;
|
|
|
|
if (FormSet == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
LinkForm = GetFirstNode (&FormSet->FormListHead);
|
|
while (!IsNull (&FormSet->FormListHead, LinkForm)) {
|
|
Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);
|
|
LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);
|
|
|
|
FakeStatement = NULL;
|
|
LinkStatement = GetFirstNode (&Form->StatementListHead);
|
|
while (!IsNull (&Form->StatementListHead, LinkStatement)) {
|
|
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (LinkStatement);
|
|
LinkStatement = GetNextNode (&Form->StatementListHead, LinkStatement);
|
|
|
|
//
|
|
// Delete the import statement which is created by previous VFR import fake statement.
|
|
//
|
|
if (IS_VFR_IMPORT_FAKE_STATEMENT(Statement)) {
|
|
FakeStatement = Statement;
|
|
continue;
|
|
}
|
|
if (FakeStatement != NULL) {
|
|
if (IS_IMPORT_STATEMENT(Statement) &&
|
|
CompareGuid (&Statement->ImportInfo->SrcFormSet->Guid, &FakeStatement->VfrImportInfo->ImportInfo.SrcFormSetGuid) &&
|
|
Statement->ImportInfo->SrcForm->FormId == FakeStatement->VfrImportInfo->ImportInfo.SrcFormId &&
|
|
((IMPORT_INFO_FLAG_IS_QUESTION(FakeStatement->VfrImportInfo->ImportInfo.Flags) && Statement->ImportInfo->SrcStatement->QuestionId == FakeStatement->VfrImportInfo->ImportInfo.SrcId) ||
|
|
(!IMPORT_INFO_FLAG_IS_QUESTION(FakeStatement->VfrImportInfo->ImportInfo.Flags) && Statement->ImportInfo->SrcStatement->StatementId == FakeStatement->VfrImportInfo->ImportInfo.SrcId))) {
|
|
RemoveEntryList (&Statement->Link);
|
|
DestroyStatement (FormSet, Statement);
|
|
}
|
|
|
|
FakeStatement = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
FB_VFR_IMPORT_INFO *
|
|
CreateVfrImportInfo (
|
|
IN FORM_BROWSER_FORMSET *FormSet,
|
|
IN FORM_BROWSER_FORM *Form,
|
|
IN H2O_IFR_GUID_IMPORT *ImportOpcode
|
|
)
|
|
{
|
|
FB_VFR_IMPORT_INFO *VfrImportInfo;
|
|
EFI_IFR_SUBTITLE *Subtitle;
|
|
IMPORT_INFO *ImportInfo;
|
|
|
|
VfrImportInfo = AllocateZeroPool (sizeof (FB_VFR_IMPORT_INFO));
|
|
if (VfrImportInfo == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize IFR subtitle opcode
|
|
//
|
|
Subtitle = &VfrImportInfo->IfrSubtitleOpcode;
|
|
Subtitle->Header.OpCode = EFI_IFR_SUBTITLE_OP;
|
|
Subtitle->Header.Length = sizeof(EFI_IFR_SUBTITLE);
|
|
Subtitle->Header.Scope = ImportOpcode->Header.Scope;
|
|
|
|
//
|
|
// Initialize ImportInfo
|
|
//
|
|
ImportInfo = &VfrImportInfo->ImportInfo;
|
|
ImportInfo->Type = VFR_IMPORT;
|
|
ImportInfo->Flags = ImportOpcode->Flags;
|
|
if ((ImportOpcode->Flags & H2O_HII_IMPORT_CURRENT_SELECTION) == H2O_HII_IMPORT_CURRENT_SELECTION) {
|
|
ImportInfo->Flags |= H2O_HII_IMPORT_QUESTION;
|
|
//
|
|
// The SrcFormSetId and Src FormId will be assigned when processing this ImportInfo
|
|
//
|
|
ImportInfo->DstFormId = Form->FormId;
|
|
ImportInfo->DstId = H2O_IFR_GUID_IMPORT_LOCAL_ID_NON_CONFLICTING;
|
|
} else {
|
|
CopyGuid (&ImportInfo->SrcFormSetGuid, (EFI_GUID *)(UINT8 *)&ImportOpcode->TargetFormsetGuid);
|
|
ImportInfo->SrcFormId = ImportOpcode->TargetFormId;
|
|
ImportInfo->SrcId = ImportOpcode->TargetId;
|
|
|
|
ImportInfo->DstFormId = Form->FormId;
|
|
ImportInfo->DstId = ImportOpcode->LocalId;
|
|
}
|
|
ImportInfo->ExpressionQId = 0;
|
|
|
|
return VfrImportInfo;
|
|
}
|
|
|
|
FORM_BROWSER_STATEMENT *
|
|
CreateFakeStatementByVfrImport (
|
|
IN H2O_IFR_GUID_IMPORT *ImportOpcode,
|
|
IN OUT FORM_BROWSER_FORMSET *FormSet,
|
|
IN OUT FORM_BROWSER_FORM *Form
|
|
)
|
|
{
|
|
FB_VFR_IMPORT_INFO *VfrImportInfo;
|
|
FORM_BROWSER_STATEMENT *Statement;
|
|
|
|
if (ImportOpcode == NULL || FormSet == NULL || Form == NULL) {
|
|
return NULL;
|
|
}
|
|
if (ImportOpcode->Header.OpCode != EFI_IFR_GUID_OP ||
|
|
ImportOpcode->Function != H2O_IFR_EXT_IMPORT) {
|
|
return NULL;
|
|
}
|
|
|
|
VfrImportInfo = CreateVfrImportInfo (FormSet, Form, ImportOpcode);
|
|
if (VfrImportInfo == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
Statement = CreateStatement ((UINT8 *) &VfrImportInfo->IfrSubtitleOpcode, FormSet, Form);
|
|
if (Statement == NULL) {
|
|
FreePool (VfrImportInfo);
|
|
return NULL;
|
|
}
|
|
Statement->VfrImportInfo = VfrImportInfo;
|
|
|
|
return Statement;
|
|
}
|
|
|
|
/**
|
|
Create a fake statement for VFR label.
|
|
|
|
@param[in] Label Pointer to VFR label opcode
|
|
@param[in, out] FormSet Pointer to formset data
|
|
@param[in, out] Form Pointer to form data
|
|
|
|
@return The pointer of statement data or NULL if input parameter is NULL or allocate memory failed.
|
|
**/
|
|
FORM_BROWSER_STATEMENT *
|
|
CreateFakeStatementByVfrLabel (
|
|
IN EFI_IFR_GUID_LABEL *Label,
|
|
IN OUT FORM_BROWSER_FORMSET *FormSet,
|
|
IN OUT FORM_BROWSER_FORM *Form
|
|
)
|
|
{
|
|
FB_VFR_IMPORT_INFO *VfrImportInfo;
|
|
EFI_IFR_SUBTITLE *Subtitle;
|
|
FORM_BROWSER_STATEMENT *Statement;
|
|
|
|
if (Label == NULL || FormSet == NULL || Form == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
VfrImportInfo = AllocateZeroPool (sizeof (FB_VFR_IMPORT_INFO));
|
|
if (VfrImportInfo == NULL) {
|
|
return NULL;
|
|
}
|
|
VfrImportInfo->ImportInfo.Type = VFR_LABEL;
|
|
VfrImportInfo->ImportInfo.SrcId = Label->Number;
|
|
|
|
//
|
|
// Initialize IFR subtitle opcode
|
|
//
|
|
Subtitle = &VfrImportInfo->IfrSubtitleOpcode;
|
|
Subtitle->Header.OpCode = EFI_IFR_SUBTITLE_OP;
|
|
Subtitle->Header.Length = sizeof(EFI_IFR_SUBTITLE);
|
|
Subtitle->Header.Scope = Label->Header.Scope;
|
|
|
|
Statement = CreateStatement ((UINT8 *) &VfrImportInfo->IfrSubtitleOpcode, FormSet, Form);
|
|
if (Statement == NULL) {
|
|
FreePool (VfrImportInfo);
|
|
return NULL;
|
|
}
|
|
Statement->VfrImportInfo = VfrImportInfo;
|
|
|
|
return Statement;
|
|
}
|
|
|