1) Add GetAttributesOfFirstFormSet to scan form package to read formset title, class info.

2) Clean up function related to package registration code.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5702 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12 2008-08-21 02:33:00 +00:00
parent 44f5e74f28
commit 5993016597
3 changed files with 149 additions and 166 deletions

View File

@ -76,29 +76,8 @@ GetPackageCount (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** VOID
Removes a node from a doubly linked list, and returns the node that follows UpdatePackListWithOnlyIfrPack (
the removed node.
Removes the node Entry from a doubly linked list. It is up to the caller of
this function to release the memory used by this node if that is required. On
exit, the node following Entry in the doubly linked list is returned. If
Entry is the only node in the linked list, then the head node of the linked
list is returned.
If Entry is NULL, then ASSERT().
If Entry is the head node of an empty list, then ASSERT().
If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
linked list containing Entry, including the Entry node, is greater than
or equal to PcdMaximumLinkedListLength, then ASSERT().
@param Entry A pointer to a node in a linked list
@return Entry
**/
EFI_STATUS
FindPackListWithOnlyIfrPackAndAddStringPack (
IN HII_THUNK_PRIVATE_DATA *Private, IN HII_THUNK_PRIVATE_DATA *Private,
IN HII_THUNK_CONTEXT *StringPackageThunkContext, IN HII_THUNK_CONTEXT *StringPackageThunkContext,
IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader
@ -129,19 +108,14 @@ FindPackListWithOnlyIfrPackAndAddStringPack (
ThunkContext->UefiHiiHandle, ThunkContext->UefiHiiHandle,
StringPackageListHeader StringPackageListHeader
); );
ASSERT (Status != EFI_NOT_FOUND); ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
} }
} }
Link = GetNextNode (&Private->ThunkContextListHead, Link); Link = GetNextNode (&Private->ThunkContextListHead, Link);
} }
return EFI_NOT_FOUND;
} }
@ -206,24 +180,27 @@ PrepareUefiPackageListFromFrameworkHiiPackages (
} }
VOID VOID
GenerateGuidId ( GenerateRandomGuid (
IN CONST EFI_GUID * InGuid, OUT EFI_GUID * Guid
OUT EFI_GUID * OutGuid
) )
{ {
UINT64 MonotonicCount; EFI_STATUS Status;
static EFI_GUID GuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};
UINT64 MonotonicCount;
CopyMem (OutGuid, InGuid, sizeof (EFI_GUID)); CopyGuid (Guid, &GuidBase);
Status = gBS->GetNextMonotonicCount (&MonotonicCount);
ASSERT_EFI_ERROR (Status);
gBS->GetNextMonotonicCount (&MonotonicCount);
// //
// Use Monotonic Count as a psedo random number generator. // Use Monotonic Count as a psedo random number generator.
// //
*((UINT64 *) OutGuid) = *((UINT64 *) OutGuid) + MonotonicCount; *((UINT64 *) Guid) = *((UINT64 *) Guid) + MonotonicCount;
} }
EFI_STATUS EFI_STATUS
FindStringPackAndAddToPackListWithOnlyIfrPack( FindStringPackAndUpdatePackListWithOnlyIfrPack (
IN HII_THUNK_PRIVATE_DATA *Private, IN HII_THUNK_PRIVATE_DATA *Private,
IN HII_THUNK_CONTEXT *IfrThunkContext IN HII_THUNK_CONTEXT *IfrThunkContext
) )
@ -259,21 +236,22 @@ FindStringPackAndAddToPackListWithOnlyIfrPack(
FreePool (StringPackageListHeader); FreePool (StringPackageListHeader);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
} }
Link = GetNextNode (&Private->ThunkContextListHead, Link); Link = GetNextNode (&Private->ThunkContextListHead, Link);
} }
ASSERT (FALSE);
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
//
CONST EFI_GUID mAGuid = //
{ 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } }; //
EFI_STATUS EFI_STATUS
UefiRegisterPackageList( UefiRegisterPackageList(
IN HII_THUNK_PRIVATE_DATA *Private, IN HII_THUNK_PRIVATE_DATA *Private,
@ -285,7 +263,7 @@ UefiRegisterPackageList(
UINTN StringPackageCount; UINTN StringPackageCount;
UINTN IfrPackageCount; UINTN IfrPackageCount;
EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
HII_THUNK_CONTEXT *ThunkContext; HII_THUNK_CONTEXT *ThunkContext;
EFI_GUID GuidId; EFI_GUID GuidId;
PackageListHeader = NULL; PackageListHeader = NULL;
@ -297,6 +275,7 @@ UefiRegisterPackageList(
// //
// HII Thunk only handle package with 0 or 1 IFR package. // HII Thunk only handle package with 0 or 1 IFR package.
// //
ASSERT (FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -316,18 +295,15 @@ UefiRegisterPackageList(
// GUID. // GUID.
// //
ASSERT (StringPackageCount >=1 && IfrPackageCount == 1); ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);
Packages->GuidId = &GuidId; GenerateRandomGuid (&GuidId);
GenerateGuidId (&mAGuid, Packages->GuidId);
} else { } else {
//BugBug We need fix this.
//ASSERT (StringPackageCount == 0 || IfrPackageCount == 0);
CopyGuid (&GuidId, Packages->GuidId); CopyGuid (&GuidId, Packages->GuidId);
} }
// //
// Record the Package List GUID, it is used as a name for the package list by Framework HII. // Record the Package List GUID, it is used as a name for the package list by Framework HII.
// //
CopyGuid (&ThunkContext->TagGuid, Packages->GuidId); CopyGuid (&ThunkContext->TagGuid, &GuidId);
if ((StringPackageCount == 0) && (IfrPackageCount != 0)) { if ((StringPackageCount == 0) && (IfrPackageCount != 0)) {
// //
@ -335,7 +311,7 @@ UefiRegisterPackageList(
// In Framework HII implementation, Packages->GuidId is used as an identifier to associate // In Framework HII implementation, Packages->GuidId is used as an identifier to associate
// a PackageList with only IFR to a Package list the with String package. // a PackageList with only IFR to a Package list the with String package.
// //
GenerateGuidId (Packages->GuidId, &GuidId); GenerateRandomGuid (&GuidId);
} }
// //
@ -364,18 +340,14 @@ UefiRegisterPackageList(
if (IfrPackageCount == 0) { if (IfrPackageCount == 0) {
if (StringPackageCount != 0) { if (StringPackageCount != 0) {
// //
// Find if there is Package List with only IFR Package in the databasee with the same // Look for a Package List with only IFR Package with the same GUID name.
// tag. If found, add the String Package to this Package List. // If found one, add the String Packages to it.
// //
Status = FindPackListWithOnlyIfrPackAndAddStringPack ( UpdatePackListWithOnlyIfrPack (
Private, Private,
ThunkContext, ThunkContext,
PackageListHeader PackageListHeader
); );
if (Status == EFI_NOT_FOUND) {
Status = EFI_SUCCESS;
}
} }
} else { } else {
CreateQuestionIdMap (ThunkContext); CreateQuestionIdMap (ThunkContext);
@ -384,11 +356,14 @@ UefiRegisterPackageList(
// //
// Register the Package List to UEFI HII first. // Register the Package List to UEFI HII first.
// //
Status = FindStringPackAndAddToPackListWithOnlyIfrPack ( Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (
Private, Private,
ThunkContext ThunkContext
); );
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
goto Done;
}
} }
} }
@ -511,14 +486,12 @@ Returns:
} }
RemoveEntryList (&ThunkContext->Link); RemoveEntryList (&ThunkContext->Link);
DestroyThunkContext (ThunkContext); DestroyThunkContext (ThunkContext);
}else { }else {
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
} }
mInFrameworkHiiRemovePack = FALSE; mInFrameworkHiiRemovePack = FALSE;
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
return Status; return Status;
@ -560,71 +533,14 @@ NewOrAddPackNotify (
InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link); InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);
} }
if (PackageType == EFI_HII_PACKAGE_FORM) { if (PackageType == EFI_HII_PACKAGE_FORM) {
Status = CreateQuestionIdMap (ThunkContext); GetAttributesOfFirstFormSet (ThunkContext);
} }
return Status; return Status;
} }
//
BOOLEAN
IsRemovingLastStringPack (
IN EFI_HII_HANDLE Handle
)
{
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINTN BufferSize;
EFI_STATUS Status;
EFI_HII_PACKAGE_HEADER *PackageHeader;
UINTN StringPackageCount;
HiiPackageList = NULL;
BufferSize = 0;
StringPackageCount = 0;
Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);
ASSERT_EFI_ERROR (Status);
PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
while (PackageHeader->Type != EFI_HII_PACKAGE_END) {
switch (PackageHeader->Type) {
case EFI_HII_PACKAGE_STRINGS:
StringPackageCount++;
if (StringPackageCount > 1) {
//
// More than one String Pack in the package list
//
FreePool (HiiPackageList);
return FALSE;
}
break;
default:
break;
}
//
// goto header of next package
//
PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);
}
//
// We will always be notified for the removal of String Pack from a package list.
// So StringPackageCount must be one at this point.
//
ASSERT (StringPackageCount == 1);
FreePool (HiiPackageList);
return TRUE;
}
// Framework HII module may cache a GUID as the name of the package list. // Framework HII module may cache a GUID as the name of the package list.
// Then search for the Framework HII handle database for the handle matching // Then search for the Framework HII handle database for the handle matching
// this GUID // this GUID
@ -639,9 +555,11 @@ RemovePackNotify (
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private; HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT * ThunkContext; HII_THUNK_CONTEXT *ThunkContext;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINTN BufferSize;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -657,7 +575,10 @@ RemovePackNotify (
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle); ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);
if (!ThunkContext->ByFrameworkHiiNewPack) { if (!ThunkContext->ByFrameworkHiiNewPack) {
if (IsRemovingLastStringPack (Handle)) { Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);
ASSERT_EFI_ERROR (Status);
if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {
// //
// If the string package will be removed is the last string package // If the string package will be removed is the last string package
// in the package list, we will remove the HII Thunk entry from the // in the package list, we will remove the HII Thunk entry from the
@ -665,6 +586,8 @@ RemovePackNotify (
// //
DestroyThunkContextForUefiHiiHandle (Private, Handle); DestroyThunkContextForUefiHiiHandle (Private, Handle);
} }
FreePool (HiiPackageList);
} }
return Status; return Status;

View File

@ -21,29 +21,6 @@ EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;
EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID; EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;
EFI_GUID *
GetGuidOfFirstFormset (
CONST EFI_HII_FORM_PACKAGE * FormPackage
)
{
UINT8 *StartOfNextPackage;
EFI_IFR_OP_HEADER *OpCodeData;
StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;
OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);
while ((UINT8 *) OpCodeData < StartOfNextPackage) {
if (OpCodeData->OpCode == EFI_IFR_FORM_SET_OP) {
return AllocateCopyPool (sizeof(EFI_GUID), &(((EFI_IFR_FORM_SET *) OpCodeData)->Guid));
}
OpCodeData = (EFI_IFR_OP_HEADER *) ((UINT8 *) OpCodeData + OpCodeData->Length);
}
ASSERT (FALSE);
return NULL;
}
EFI_HII_HANDLE EFI_HII_HANDLE
FwHiiHandleToUefiHiiHandle ( FwHiiHandleToUefiHiiHandle (
IN CONST HII_THUNK_PRIVATE_DATA *Private, IN CONST HII_THUNK_PRIVATE_DATA *Private,
@ -239,6 +216,94 @@ GetOneOfOptionMapEntryListHead (
return NULL; return NULL;
} }
VOID
GetAttributesOfFirstFormSet (
IN OUT HII_THUNK_CONTEXT *ThunkContext
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *List;
EFI_HII_PACKAGE_HEADER *Package;
UINTN Size;
EFI_IFR_OP_HEADER *OpCode;
UINTN Offset;
EFI_IFR_GUID_CLASS *Class;
EFI_IFR_FORM_SET *FormSet;
EFI_IFR_GUID_SUBCLASS *SubClass;
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);
ASSERT_EFI_ERROR (Status);
//
// There must be at least one EFI_HII_PACKAGE_FORM in the package list.
//
ASSERT (GetPackageCountByType (List, EFI_HII_PACKAGE_FORM) >= 1);
//
// Skip the package list header.
//
Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);
while (Package->Type != EFI_HII_PACKAGE_END) {
if (Package->Type == EFI_HII_PACKAGE_FORM) {
//
// Skip the package header
//
Offset = sizeof (EFI_HII_PACKAGE_HEADER);
while (Offset < Package->Length) {
OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);
switch (OpCode->OpCode) {
case EFI_IFR_FORM_SET_OP:
FormSet = (EFI_IFR_FORM_SET *) OpCode;
ThunkContext->FormSetTitle = FormSet->FormSetTitle;
ThunkContext->FormSetHelp = FormSet->Help;
break;
case EFI_IFR_GUID_OP:
Class = (EFI_IFR_GUID_CLASS*) OpCode;
if (CompareGuid (&Class->Guid, &gTianoHiiIfrGuid)) {
Class = (EFI_IFR_GUID_CLASS *) OpCode;
switch (Class->ExtendOpCode) {
case EFI_IFR_EXTEND_OP_CLASS:
ThunkContext->FormSetClass = Class->Class;
break;
case EFI_IFR_EXTEND_OP_SUBCLASS:
SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;
ThunkContext->FormSetSubClass = SubClass->SubClass;
break;
default:
break;
}
}
break;
default:
break;
}
Offset += OpCode->Length;
}
//
// The attributes of first FormSet is ready now.
//
FreePool (List);
return;
break;
}
Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;
}
}
EFI_STATUS EFI_STATUS
CreateQuestionIdMap ( CreateQuestionIdMap (
@ -262,6 +327,7 @@ CreateQuestionIdMap (
ONE_OF_OPTION_MAP *OneOfOptionMap; ONE_OF_OPTION_MAP *OneOfOptionMap;
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry; ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
EFI_IFR_GUID_CLASS *Class; EFI_IFR_GUID_CLASS *Class;
EFI_IFR_GUID_SUBCLASS *SubClass;
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size); Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);
@ -371,7 +437,8 @@ CreateQuestionIdMap (
ThunkContext->FormSetClass = Class->Class; ThunkContext->FormSetClass = Class->Class;
break; break;
case EFI_IFR_EXTEND_OP_SUBCLASS: case EFI_IFR_EXTEND_OP_SUBCLASS:
ThunkContext->FormSetSubClass = ((EFI_IFR_GUID_SUBCLASS *) Class)->SubClass; SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;
ThunkContext->FormSetSubClass = SubClass->SubClass;
break; break;
default: default:
@ -489,7 +556,7 @@ DestroyQuestionIdMap (
while (!IsListEmpty (&IdMap->MapEntryListHead)) { while (!IsListEmpty (&IdMap->MapEntryListHead)) {
Link2 = GetFirstNode (&IdMap->MapEntryListHead); Link2 = GetFirstNode (&IdMap->MapEntryListHead);
IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link); IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link2);
RemoveEntryList (Link2); RemoveEntryList (Link2);
@ -519,7 +586,7 @@ DestoryOneOfOptionMap (
while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) { while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {
Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead); Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);
MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link); MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);
RemoveEntryList (Link2); RemoveEntryList (Link2);

View File

@ -16,11 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef _HII_THUNK_UTILITY_H #ifndef _HII_THUNK_UTILITY_H
#define _HII_THUNK_UTILITY_H #define _HII_THUNK_UTILITY_H
EFI_GUID *
GetGuidOfFirstFormset (
CONST EFI_HII_FORM_PACKAGE * FormPackage
);
/** /**
Find the UefiHiiHandle based on a Framework HII Handle returned by Find the UefiHiiHandle based on a Framework HII Handle returned by
the HII Thunk to Framework HII code. the HII Thunk to Framework HII code.
@ -60,14 +55,6 @@ TagGuidToUefiHiiHandle (
) )
; ;
EFI_STATUS
AssignFrameworkHiiHandle (
IN OUT HII_THUNK_PRIVATE_DATA *Private,
IN BOOLEAN FromFwHiiNewPack,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
)
;
HII_THUNK_CONTEXT * HII_THUNK_CONTEXT *
CreateThunkContextForUefiHiiHandle ( CreateThunkContextForUefiHiiHandle (
IN EFI_HII_HANDLE UefiHiiHandle IN EFI_HII_HANDLE UefiHiiHandle
@ -94,6 +81,12 @@ CreateQuestionIdMap (
) )
; ;
VOID
GetAttributesOfFirstFormSet (
IN OUT HII_THUNK_CONTEXT *ThunkContext
)
;
LIST_ENTRY * LIST_ENTRY *
GetMapEntryListHead ( GetMapEntryListHead (
IN CONST HII_THUNK_CONTEXT *ThunkContext, IN CONST HII_THUNK_CONTEXT *ThunkContext,