alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/H2OFormBrowserDxe/FBTargetInfo.c

683 lines
25 KiB
C

/** @file
Target info related functions for VFR/VFCF linktarget and importtarget opcodes.
;******************************************************************************
;* Copyright (c) 2020, 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 "FBTargetInfo.h"
#include "FBProcessVfcf.h"
/**
Create VFR target info for VFR linktarget opcode
@param[in] LinkTargetOpcode Pointer to VFR linktarget opcode.
@param[in, out] Form Pointer to form.
@return The pointer of VFR target info or NULL if input parameter is NULL or allocate memory failed.
**/
H2O_VFR_TARGET_INFO *
CreateVfrTargetInfoByVfrLinkTarget (
IN H2O_IFR_GUID_LINK_TARGET *LinkTargetOpcode,
IN OUT FORM_BROWSER_FORM *Form
)
{
H2O_VFR_TARGET_INFO *VfrTargetInfo;
if (LinkTargetOpcode == NULL || Form == NULL) {
return NULL;
}
VfrTargetInfo = AllocateZeroPool (sizeof(H2O_VFR_TARGET_INFO));
if (VfrTargetInfo == NULL) {
return NULL;
}
VfrTargetInfo->Signature = H2O_VFR_TARGET_INFO_SIGNATURE;
VfrTargetInfo->TargetType = VFR_LINK_TARGET;
VfrTargetInfo->TargetLabelId = LinkTargetOpcode->TargetLabelId;
VfrTargetInfo->TargetFormId = LinkTargetOpcode->TargetFormId;
CopyGuid (&VfrTargetInfo->TargetFormsetGuid, &LinkTargetOpcode->TargetFormsetGuid);
InitializeListHead (&VfrTargetInfo->PropertyListHead);
InsertTailList (&Form->TargetInfoListHead, &VfrTargetInfo->Link);
return VfrTargetInfo;
}
/**
Create VFR target info for VFR importtarget opcode
@param[in] ImportTargetOpcode Pointer to VFR importtarget opcode.
@param[in, out] Form Pointer to form.
@return The pointer of VFR target info or NULL if input parameter is NULL or allocate memory failed.
**/
H2O_VFR_TARGET_INFO *
CreateVfrTargetInfoByVfrImportTarget (
IN H2O_IFR_GUID_IMPORT_TARGET *ImportTargetOpcode,
IN OUT FORM_BROWSER_FORM *Form
)
{
H2O_VFR_TARGET_INFO *VfrTargetInfo;
if (ImportTargetOpcode == NULL) {
return NULL;
}
VfrTargetInfo = AllocateZeroPool (sizeof(H2O_VFR_TARGET_INFO));
if (VfrTargetInfo == NULL) {
return NULL;
}
VfrTargetInfo->Signature = H2O_VFR_TARGET_INFO_SIGNATURE;
VfrTargetInfo->TargetType = VFR_IMPORT_TARGET;
VfrTargetInfo->TargetLabelId = ImportTargetOpcode->TargetLabelId;
VfrTargetInfo->TargetFormId = ImportTargetOpcode->TargetFormId;
CopyGuid (&VfrTargetInfo->TargetFormsetGuid, &ImportTargetOpcode->TargetFormsetGuid);
InitializeListHead (&VfrTargetInfo->PropertyListHead);
InsertTailList (&Form->TargetInfoListHead, &VfrTargetInfo->Link);
return VfrTargetInfo;
}
/**
Destroy all VFR target info from form
@param[in, out] Form Pointer to form.
**/
VOID
DestroyAllVfrTargetInfo (
IN OUT FORM_BROWSER_FORM *Form
)
{
LIST_ENTRY *Link;
H2O_VFR_TARGET_INFO *VfrTargetInfo;
H2O_PROPERTY_INFO *Property;
if (Form == NULL) {
return;
}
while (!IsListEmpty (&Form->TargetInfoListHead)) {
Link = GetFirstNode (&Form->TargetInfoListHead);
VfrTargetInfo = H2O_VFR_TARGET_INFO_FROM_LINK (Link);
RemoveEntryList (&VfrTargetInfo->Link);
while (!IsListEmpty (&VfrTargetInfo->PropertyListHead)) {
Link = GetFirstNode (&VfrTargetInfo->PropertyListHead);
Property = H2O_PROPERTY_INFO_NODE_FROM_LINK (Link);
RemoveEntryList (&Property->Link);
FreePool (Property);
}
FreePool (VfrTargetInfo);
}
}
/**
Enumerate all target info from VFR formset
@param[in] FormSet Pointer to formset data.
@param[in, out] Private Pointer to form browser private data.
@retval EFI_SUCCESS Successfully enumerate all target info from VFR formset
@retval EFI_INVALID_PARAMETER Input parameter is NULL
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
**/
STATIC
EFI_STATUS
EnumerateAllTargetInfoFromVfrFormset (
IN FORM_BROWSER_FORMSET *FormSet,
IN OUT H2O_FORM_BROWSER_PRIVATE_DATA *Private
)
{
LIST_ENTRY *FormLink;
FORM_BROWSER_FORM *Form;
LIST_ENTRY *Link;
H2O_VFR_TARGET_INFO *VfrTargetInfo;
H2O_FORM_BROWSER_TARGET_INFO *TargetInfo;
H2O_PROPERTY_INFO *Property;
H2O_PROPERTY_VALUE PropValue;
EFI_STATUS Status;
if (FormSet == NULL || Private == NULL) {
return EFI_INVALID_PARAMETER;
}
for (FormLink = GetFirstNode (&FormSet->FormListHead); !IsNull (&FormSet->FormListHead, FormLink); FormLink = GetNextNode (&FormSet->FormListHead, FormLink)) {
Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);
if (IsListEmpty (&Form->TargetInfoListHead)) {
continue;
}
for (Link = GetFirstNode (&Form->TargetInfoListHead); !IsNull (&Form->TargetInfoListHead, Link); Link = GetNextNode (&Form->TargetInfoListHead, Link)) {
VfrTargetInfo = H2O_VFR_TARGET_INFO_FROM_LINK (Link);
TargetInfo = AllocateZeroPool (sizeof (H2O_FORM_BROWSER_TARGET_INFO));
if (TargetInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TargetInfo->Signature = H2O_FORM_BROWSER_TARGET_INFO_SIGNATURE;
TargetInfo->FormId = Form->FormId;
CopyGuid (&TargetInfo->FormsetGuid, &FormSet->Guid);
TargetInfo->TargetType = VfrTargetInfo->TargetType;
TargetInfo->TargetLabelId = VfrTargetInfo->TargetLabelId;
TargetInfo->TargetFormId = VfrTargetInfo->TargetFormId;
CopyGuid (&TargetInfo->TargetFormsetGuid, &VfrTargetInfo->TargetFormsetGuid);
Status = GetPropertyFromPropertyList (&VfrTargetInfo->PropertyListHead, H2O_HII_TARGET_PRIORITY_PROPERTY_NAME, NULL, &Property, &PropValue);
TargetInfo->TargetPriority = EFI_ERROR (Status) ? H2O_HII_TARGET_PRIORITY_PROPERTY_DEFAULT_VALUE : PropValue.H2OValue.Value.U16;
Status = GetPropertyFromPropertyList (&VfrTargetInfo->PropertyListHead, "enable", NULL, &Property, &PropValue);
TargetInfo->Enable = EFI_ERROR (Status) ? TRUE : PropValue.H2OValue.Value.Bool;
InsertTailList (&Private->TargetInfoList, &TargetInfo->Link);
}
}
return EFI_SUCCESS;
}
/**
Enumerate all target info from VFRs
@param[in, out] Private Pointer to form browser private data.
@retval EFI_SUCCESS Successfully enumerate all target info from VFRs
@retval EFI_INVALID_PARAMETER Input parameter is NULL
@retval EFI_NOT_FOUND There is no form package in HII database
**/
STATIC
EFI_STATUS
EnumerateAllTargetInfoFromVfr (
IN OUT H2O_FORM_BROWSER_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
EFI_HII_HANDLE *HiiHandles;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
EFI_HII_PACKAGE_HEADER *PackageHeader;
UINTN Index;
UINTN Size;
UINT32 Offset;
UINT32 FormPkgOffset;
UINT8 *OpCodeData;
UINT8 *Package;
FORM_BROWSER_FORMSET *FormSet;
HII_HANDLE_ENTRY *HiiHandleEntry;
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
HiiHandles = HiiGetHiiHandlesByPackageType (EFI_HII_PACKAGE_FORMS);
if (HiiHandles == NULL) {
return EFI_NOT_FOUND;
}
for (Index = 0; HiiHandles[Index] != NULL; Index++) {
Status = FBHiiExportPackageLists (HiiHandles[Index], &Size, &HiiPackageList);
if (EFI_ERROR (Status)) {
continue;
}
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
while (Offset < HiiPackageList->PackageLength) {
PackageHeader = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
Offset += PackageHeader->Length;
if (PackageHeader->Type != EFI_HII_PACKAGE_FORMS) {
continue;
}
Package = (UINT8 *) PackageHeader;
FormPkgOffset = sizeof (EFI_HII_PACKAGE_HEADER);
while (FormPkgOffset < PackageHeader->Length) {
OpCodeData = Package + FormPkgOffset;
if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode != EFI_IFR_FORM_SET_OP) {
FormPkgOffset += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
continue;
}
FormSet = AllocateZeroPool (sizeof(FORM_BROWSER_FORMSET));
if (FormSet == NULL) {
break;
}
Status = InitializeFormSet (HiiHandles[Index], (GUID *)(VOID *) &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, FormSet);
if (EFI_ERROR (Status)) {
FreePool (FormSet);
break;
}
FormPkgOffset += (UINT32) FormSet->IfrBinaryLength;
EnumerateAllTargetInfoFromVfrFormset (FormSet, Private);
DestroyFormSet (FormSet);
}
}
FreePool (HiiPackageList);
HiiPackageList = NULL;
}
while (!IsListEmpty (&Private->NeedAddHiiHandleList)) {
HiiHandleEntry = (HII_HANDLE_ENTRY *)GetFirstNode (&Private->NeedAddHiiHandleList);
RemoveEntryList (&HiiHandleEntry->Link);
FreePool (HiiHandleEntry);
}
FreePool (HiiHandles);
return EFI_SUCCESS;
}
/**
Enumerate all target info from VFCF
@param[in, out] Private Pointer to form browser private data.
@retval EFI_SUCCESS Successfully enumerate all target info from VFCF
@retval EFI_INVALID_PARAMETER Input parameter is NULL
@retval EFI_NOT_FOUND There is no formset data in VFCF
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
**/
STATIC
EFI_STATUS
EnumerateAllTargetInfoFromVfcf (
IN OUT H2O_FORM_BROWSER_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
LIST_ENTRY *LayoutListHead;
LIST_ENTRY *VfrListHead;
LIST_ENTRY *VfrLink;
H2O_VFR_INFO *VfrInfo;
LIST_ENTRY *FormsetLink;
H2O_FORMSET_INFO *FormsetInfo;
LIST_ENTRY *FormLink;
LIST_ENTRY *Link;
H2O_FORM_INFO *FormInfo;
H2O_TARGET_INFO *VfcfTargetInfo;
H2O_PROPERTY_INFO *Property;
H2O_PROPERTY_VALUE PropValue;
H2O_FORM_BROWSER_TARGET_INFO *TargetInfo;
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = GetLayoutTreeAndVfrTree (&LayoutListHead, &VfrListHead);
if (EFI_ERROR (Status) || VfrListHead == NULL || IsListEmpty (VfrListHead)) {
return EFI_NOT_FOUND;
}
for (VfrLink = GetFirstNode (VfrListHead); !IsNull (VfrListHead, VfrLink); VfrLink = GetNextNode (VfrListHead, VfrLink)) {
VfrInfo = H2O_VFR_INFO_NODE_FROM_LINK (VfrLink);
if (IsListEmpty (&VfrInfo->FormsetListHead)) {
continue;
}
for (FormsetLink = GetFirstNode (&VfrInfo->FormsetListHead); !IsNull (&VfrInfo->FormsetListHead, FormsetLink); FormsetLink = GetNextNode (&VfrInfo->FormsetListHead, FormsetLink)) {
FormsetInfo = H2O_FORMSET_INFO_NODE_FROM_LINK (FormsetLink);
if (IsListEmpty (&FormsetInfo->FormListHead)) {
continue;
}
for (FormLink = GetFirstNode (&FormsetInfo->FormListHead); !IsNull (&FormsetInfo->FormListHead, FormLink); FormLink = GetNextNode (&FormsetInfo->FormListHead, FormLink)) {
FormInfo = H2O_FORM_INFO_NODE_FROM_LINK (FormLink);
if (IsListEmpty (&FormInfo->TargetListHead)) {
continue;
}
for (Link = GetFirstNode (&FormInfo->TargetListHead); !IsNull (&FormInfo->TargetListHead, Link); Link = GetNextNode (&FormInfo->TargetListHead, Link)) {
VfcfTargetInfo = H2O_TARGET_INFO_NODE_FROM_LINK (Link);
TargetInfo = AllocateZeroPool (sizeof (H2O_FORM_BROWSER_TARGET_INFO));
if (TargetInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TargetInfo->Signature = H2O_FORM_BROWSER_TARGET_INFO_SIGNATURE;
TargetInfo->FormId = FormInfo->FormBlock->FormId;
CopyGuid (&TargetInfo->FormsetGuid, &FormsetInfo->FormsetId);
TargetInfo->TargetType = (VfcfTargetInfo->VfcfOpcode == H2O_HII_LIBT_IMPORT_TARGET_BEGIN) ? VFCF_IMPORT_TARGET : VFCF_LINK_TARGET;
TargetInfo->TargetLabelId = VfcfTargetInfo->TargetLabelId;
TargetInfo->TargetFormId = VfcfTargetInfo->TargetFormId;
CopyGuid (&TargetInfo->TargetFormsetGuid, &VfcfTargetInfo->TargetFormsetGuid);
Status = GetPropertyFromStyleList (&VfcfTargetInfo->StyleListHead, 0, H2O_STYLE_PSEUDO_CLASS_NORMAL, H2O_HII_TARGET_PRIORITY_PROPERTY_NAME, NULL, &Property, &PropValue);
TargetInfo->TargetPriority = EFI_ERROR (Status) ? H2O_HII_TARGET_PRIORITY_PROPERTY_DEFAULT_VALUE : PropValue.H2OValue.Value.U16;
Status = GetPropertyFromStyleList (&VfcfTargetInfo->StyleListHead, 0, H2O_STYLE_PSEUDO_CLASS_NORMAL, "enable", NULL, &Property, &PropValue);
TargetInfo->Enable = EFI_ERROR (Status) ? TRUE : PropValue.H2OValue.Value.Bool;
InsertTailList (&Private->TargetInfoList, &TargetInfo->Link);
}
}
}
}
return EFI_SUCCESS;
}
/**
Initialize target info list
@param[in, out] Private Pointer to form browser private data.
@retval EFI_SUCCESS Successfully initialize target info list
**/
EFI_STATUS
InitializeTargetInfoList (
IN OUT H2O_FORM_BROWSER_PRIVATE_DATA *Private
)
{
EnumerateAllTargetInfoFromVfr (Private);
EnumerateAllTargetInfoFromVfcf (Private);
return EFI_SUCCESS;
}
/**
Destroy all target info
@param[in, out] Private Pointer to form browser private data.
**/
VOID
DestroyTargetInfoList (
IN OUT H2O_FORM_BROWSER_PRIVATE_DATA *Private
)
{
LIST_ENTRY *Link;
H2O_FORM_BROWSER_TARGET_INFO *TargetInfo;
Link = GetFirstNode (&Private->TargetInfoList);
while (!IsNull (&Private->TargetInfoList, Link)) {
TargetInfo = H2O_FORM_BROWSER_TARGET_INFO_FROM_LINK (Link);
Link = GetNextNode (&Private->TargetInfoList, Link);
RemoveEntryList (&TargetInfo->Link);
FreePool (TargetInfo);
}
}
/**
Check if there is a target info for specifid (formset, form, label ID).
@param[in] FormSetGuid Pointer to formset GUID
@param[in] FormId Form ID in specified formset
@param[in] LabelId Label ID in specified formset
@retval TRUE There is a target info.
@retval FALSE There is no match target info.
**/
BOOLEAN
HaveTargetInfo (
IN EFI_GUID *FormSetGuid,
IN UINT16 FormId OPTIONAL,
IN UINT16 LabelId OPTIONAL
)
{
LIST_ENTRY *Link;
H2O_FORM_BROWSER_TARGET_INFO *TargetInfo;
for (Link = GetFirstNode (&mFBPrivate.TargetInfoList); !IsNull (&mFBPrivate.TargetInfoList, Link); Link = GetNextNode (&mFBPrivate.TargetInfoList, Link)) {
TargetInfo = H2O_FORM_BROWSER_TARGET_INFO_FROM_LINK (Link);
if (CompareGuid (&TargetInfo->TargetFormsetGuid, FormSetGuid) &&
(FormId == 0 || (TargetInfo->TargetFormId == FormId)) &&
(LabelId == 0 || (TargetInfo->TargetLabelId == LabelId))) {
return TRUE;
}
}
return FALSE;
}
/**
Internal function to get import info list by specified target (formset, form, fake statement).
@param[in] TargetFormSetGuid Pointer to targetformset GUID
@param[in] TargetFormId Target form ID
@param[in] TargetFakeStatement Pointer to target fake statement which is for VFR label
@param[in, out] ImportInfoList Double pointer to output import info list
@param[in, out] ImportInfoCount Pointer to the count of output import info list
@retval EFI_SUCCESS Successfully initialize target info list
@retval EFI_INVALID_PARAMETER TargetFakeStatement is invalid
@retval EFI_NOT_FOUND There is no valid import info for target
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
**/
STATIC
EFI_STATUS
InternalGetImportInfoListFromTargetInfo (
IN EFI_GUID *TargetFormSetGuid,
IN UINT16 TargetFormId,
IN FORM_BROWSER_STATEMENT *TargetFakeStatement OPTIONAL,
IN OUT IMPORT_INFO **ImportInfoList,
IN OUT UINT16 *ImportInfoCount
)
{
UINT16 TargetLabelId;
UINT16 FoundCount;
H2O_FORM_BROWSER_TARGET_INFO *FoundList;
H2O_FORM_BROWSER_TARGET_INFO *TargetInfo;
LIST_ENTRY *Link;
H2O_FORM_BROWSER_TARGET_INFO TempTargetInfo;
UINT16 Index;
UINT16 Index2;
IMPORT_INFO *NewImportInfoList;
UINT16 NewImportInfoCount;
FORM_BROWSER_FORMSET *FormSet;
FORM_BROWSER_FORM *Form;
if (TargetFakeStatement == NULL) {
TargetLabelId = 0;
} else {
if (!IS_VFR_IMPORT_FAKE_STATEMENT(TargetFakeStatement) || TargetFakeStatement->VfrImportInfo->ImportInfo.Type != VFR_LABEL) {
return EFI_INVALID_PARAMETER;
}
TargetLabelId = TargetFakeStatement->VfrImportInfo->ImportInfo.SrcId;
}
//
// Get all match target info
//
FoundList = NULL;
FoundCount = 0;
for (Link = GetFirstNode (&mFBPrivate.TargetInfoList); !IsNull (&mFBPrivate.TargetInfoList, Link); Link = GetNextNode (&mFBPrivate.TargetInfoList, Link)) {
TargetInfo = H2O_FORM_BROWSER_TARGET_INFO_FROM_LINK (Link);
if (TargetInfo->TargetLabelId != TargetLabelId ||
TargetInfo->TargetFormId != TargetFormId ||
!CompareGuid (&TargetInfo->TargetFormsetGuid, TargetFormSetGuid)) {
continue;
}
for (Index = 0; Index < FoundCount; Index++) {
if (((IS_LINK_TARGET (FoundList[Index].TargetType) && IS_LINK_TARGET(TargetInfo->TargetType)) ||
(IS_IMPORT_TARGET (FoundList[Index].TargetType) && IS_IMPORT_TARGET(TargetInfo->TargetType))) &&
FoundList[Index].FormId == TargetInfo->FormId &&
CompareGuid (&FoundList[Index].FormsetGuid, &TargetInfo->FormsetGuid)) {
//
// Found exiting target info, update later one which has higher priority.
//
FoundList[Index].TargetPriority = TargetInfo->TargetPriority;
FoundList[Index].Enable = TargetInfo->Enable;
break;
}
}
if (Index == FoundCount) {
FoundList = ReallocatePool (
sizeof(H2O_FORM_BROWSER_TARGET_INFO) * FoundCount,
sizeof(H2O_FORM_BROWSER_TARGET_INFO) * (FoundCount + 1),
FoundList
);
if (FoundList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (&FoundList[FoundCount], TargetInfo, sizeof (H2O_FORM_BROWSER_TARGET_INFO));
FoundCount++;
}
}
if (FoundList == NULL) {
return EFI_NOT_FOUND;
}
//
// Calculate required import info count.
//
NewImportInfoCount = 0;
for (Index = 0; Index < FoundCount; Index++) {
if (!FoundList[Index].Enable) {
continue;
}
if (IS_IMPORT_TARGET(FoundList[Index].TargetType)) {
FormSet = GetFormSetByFormSetGuid (&FoundList[Index].FormsetGuid, &mH2OBrowserImportFormSetList, NULL);
if (FormSet == NULL) {
FormSet = CreateImportFormSet (&FoundList[Index].FormsetGuid);
}
Form = (FormSet == NULL) ? NULL : IdToForm (FormSet, FoundList[Index].FormId);
if (Form == NULL || Form->NumberOfStatement == 0) {
continue;
}
NewImportInfoCount += Form->NumberOfStatement;
} else {
NewImportInfoCount++;
}
}
if (NewImportInfoCount == 0) {
FreePool (FoundList);
return EFI_NOT_FOUND;
}
//
// Sort by Priority. Higher priority value is located in front.
//
for (Index = 0; Index < FoundCount - 1; Index++) {
for (Index2 = 1; Index2 < FoundCount; Index2++) {
if (FoundList[Index2].TargetPriority > FoundList[Index2 - 1].TargetPriority) {
CopyMem (&TempTargetInfo , &FoundList[Index2 - 1], sizeof (H2O_FORM_BROWSER_TARGET_INFO));
CopyMem (&FoundList[Index2 - 1], &FoundList[Index2] , sizeof (H2O_FORM_BROWSER_TARGET_INFO));
CopyMem (&FoundList[Index2] , &TempTargetInfo , sizeof (H2O_FORM_BROWSER_TARGET_INFO));
}
}
}
//
// Create a new buffer and append new import info in the end.
//
NewImportInfoList = AllocateZeroPool ((*ImportInfoCount + NewImportInfoCount) * sizeof(IMPORT_INFO));
if (NewImportInfoList == NULL) {
FreePool (FoundList);
return EFI_OUT_OF_RESOURCES;
}
CopyMem (NewImportInfoList, *ImportInfoList, *ImportInfoCount * sizeof(IMPORT_INFO));
NewImportInfoCount = *ImportInfoCount;
for (Index = 0; Index < FoundCount; Index++) {
if (!FoundList[Index].Enable) {
continue;
}
NewImportInfoList[NewImportInfoCount].VfrFakeStatement = TargetFakeStatement;
NewImportInfoList[NewImportInfoCount].Type = FoundList[Index].TargetType;
NewImportInfoList[NewImportInfoCount].DstFormId = FoundList[Index].TargetFormId;
NewImportInfoList[NewImportInfoCount].SrcFormId = FoundList[Index].FormId;
CopyGuid (&NewImportInfoList[NewImportInfoCount].SrcFormSetGuid, &FoundList[Index].FormsetGuid);
if (IS_IMPORT_TARGET(FoundList[Index].TargetType)) {
FormSet = GetFormSetByFormSetGuid (&FoundList[Index].FormsetGuid, &mH2OBrowserImportFormSetList, NULL);
Form = (FormSet == NULL) ? NULL : IdToForm (FormSet, FoundList[Index].FormId);
if (Form == NULL || Form->NumberOfStatement == 0) {
continue;
}
for (Index2 = 1; Index2 < Form->NumberOfStatement; Index2++) {
CopyMem (
&NewImportInfoList[NewImportInfoCount + Index2],
&NewImportInfoList[NewImportInfoCount],
sizeof(IMPORT_INFO)
);
NewImportInfoList[NewImportInfoCount + Index2].SrcId = Index2;
}
NewImportInfoCount += Form->NumberOfStatement;
} else {
NewImportInfoCount++;
}
}
FreePool (FoundList);
if (*ImportInfoList != NULL) {
FreePool (*ImportInfoList);
}
*ImportInfoList = NewImportInfoList;
*ImportInfoCount = NewImportInfoCount;
return EFI_SUCCESS;
}
/**
Get import info list by specified target formset.
@param[in] FormSet Pointer to target formset
@param[in, out] ImportInfoList Double pointer to output import info list
@param[in, out] ImportInfoCount Pointer to the count of output import info list
@retval EFI_SUCCESS Successfully get import info list
@retval EFI_INVALID_PARAMETER Input parameter is NULL
**/
EFI_STATUS
GetImportInfoListFromTargetInfo (
IN FORM_BROWSER_FORMSET *FormSet,
IN OUT IMPORT_INFO **ImportInfoList,
IN OUT UINT16 *ImportInfoCount
)
{
LIST_ENTRY *LinkForm;
LIST_ENTRY *LinkStatement;
FORM_BROWSER_FORM *Form;
FORM_BROWSER_STATEMENT *Statement;
if (FormSet == NULL || ImportInfoList == NULL || ImportInfoCount == NULL) {
return EFI_INVALID_PARAMETER;
}
if (!HaveTargetInfo (&FormSet->Guid, 0, 0)) {
return EFI_SUCCESS;
}
//
// Check each VFR label and form to see if there is import info.
//
for (LinkForm = GetFirstNode (&FormSet->FormListHead); !IsNull (&FormSet->FormListHead, LinkForm); LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm)) {
Form = FORM_BROWSER_FORM_FROM_LINK (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_LABEL) {
InternalGetImportInfoListFromTargetInfo (
&FormSet->Guid,
Form->FormId,
Statement,
ImportInfoList,
ImportInfoCount
);
}
}
InternalGetImportInfoListFromTargetInfo (
&FormSet->Guid,
Form->FormId,
NULL,
ImportInfoList,
ImportInfoCount
);
}
return EFI_SUCCESS;
}