683 lines
25 KiB
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;
|
|
}
|
|
|