return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Removes a node from a doubly linked list, and returns the node that follows\r
- the removed node.\r
-\r
- Removes the node Entry from a doubly linked list. It is up to the caller of\r
- this function to release the memory used by this node if that is required. On\r
- exit, the node following Entry in the doubly linked list is returned. If\r
- Entry is the only node in the linked list, then the head node of the linked\r
- list is returned.\r
-\r
- If Entry is NULL, then ASSERT().\r
- If Entry is the head node of an empty list, then ASSERT().\r
- If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
- linked list containing Entry, including the Entry node, is greater than\r
- or equal to PcdMaximumLinkedListLength, then ASSERT().\r
-\r
- @param Entry A pointer to a node in a linked list\r
-\r
- @return Entry\r
-\r
-**/\r
-EFI_STATUS\r
-FindPackListWithOnlyIfrPackAndAddStringPack (\r
+VOID\r
+UpdatePackListWithOnlyIfrPack (\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
IN HII_THUNK_CONTEXT *StringPackageThunkContext,\r
IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
ThunkContext->UefiHiiHandle,\r
StringPackageListHeader\r
);\r
- ASSERT (Status != EFI_NOT_FOUND);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
}\r
}\r
\r
Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
-\r
- return EFI_NOT_FOUND;\r
}\r
\r
\r
}\r
\r
VOID\r
-GenerateGuidId (\r
- IN CONST EFI_GUID * InGuid,\r
- OUT EFI_GUID * OutGuid\r
+GenerateRandomGuid (\r
+ OUT EFI_GUID * Guid\r
)\r
{\r
- UINT64 MonotonicCount;\r
+ EFI_STATUS Status;\r
+ static EFI_GUID GuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
+ UINT64 MonotonicCount;\r
\r
- CopyMem (OutGuid, InGuid, sizeof (EFI_GUID));\r
+ CopyGuid (Guid, &GuidBase);\r
+ \r
+ Status = gBS->GetNextMonotonicCount (&MonotonicCount);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- gBS->GetNextMonotonicCount (&MonotonicCount);\r
//\r
// Use Monotonic Count as a psedo random number generator.\r
//\r
- *((UINT64 *) OutGuid) = *((UINT64 *) OutGuid) + MonotonicCount;\r
+ *((UINT64 *) Guid) = *((UINT64 *) Guid) + MonotonicCount;\r
}\r
\r
EFI_STATUS\r
-FindStringPackAndAddToPackListWithOnlyIfrPack(\r
+FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
IN HII_THUNK_CONTEXT *IfrThunkContext\r
)\r
\r
FreePool (StringPackageListHeader);\r
return EFI_SUCCESS;\r
+\r
}\r
}\r
\r
Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
+ ASSERT (FALSE);\r
return EFI_NOT_FOUND;\r
-\r
+ \r
}\r
\r
\r
-\r
-CONST EFI_GUID mAGuid = \r
- { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };\r
-\r
+//\r
+// \r
+//\r
EFI_STATUS\r
UefiRegisterPackageList(\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
UINTN StringPackageCount;\r
UINTN IfrPackageCount;\r
EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
EFI_GUID GuidId;\r
\r
PackageListHeader = NULL;\r
//\r
// HII Thunk only handle package with 0 or 1 IFR package. \r
//\r
+ ASSERT (FALSE);\r
return EFI_UNSUPPORTED;\r
}\r
\r
// GUID.\r
//\r
ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);\r
- Packages->GuidId = &GuidId;\r
- GenerateGuidId (&mAGuid, Packages->GuidId);\r
+ GenerateRandomGuid (&GuidId);\r
} else {\r
- //BugBug We need fix this.\r
- //ASSERT (StringPackageCount == 0 || IfrPackageCount == 0);\r
CopyGuid (&GuidId, Packages->GuidId);\r
}\r
\r
//\r
// Record the Package List GUID, it is used as a name for the package list by Framework HII.\r
//\r
- CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
+ CopyGuid (&ThunkContext->TagGuid, &GuidId);\r
\r
if ((StringPackageCount == 0) && (IfrPackageCount != 0)) {\r
//\r
// In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
// a PackageList with only IFR to a Package list the with String package.\r
//\r
- GenerateGuidId (Packages->GuidId, &GuidId);\r
+ GenerateRandomGuid (&GuidId);\r
}\r
\r
//\r
if (IfrPackageCount == 0) {\r
if (StringPackageCount != 0) {\r
//\r
- // Find if there is Package List with only IFR Package in the databasee with the same\r
- // tag. If found, add the String Package to this Package List.\r
+ // Look for a Package List with only IFR Package with the same GUID name.\r
+ // If found one, add the String Packages to it.\r
//\r
- Status = FindPackListWithOnlyIfrPackAndAddStringPack (\r
- Private,\r
- ThunkContext,\r
- PackageListHeader\r
- );\r
-\r
- if (Status == EFI_NOT_FOUND) {\r
- Status = EFI_SUCCESS;\r
- }\r
+ UpdatePackListWithOnlyIfrPack (\r
+ Private,\r
+ ThunkContext,\r
+ PackageListHeader\r
+ );\r
}\r
} else {\r
CreateQuestionIdMap (ThunkContext);\r
//\r
// Register the Package List to UEFI HII first.\r
//\r
- Status = FindStringPackAndAddToPackListWithOnlyIfrPack (\r
+ Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
Private,\r
ThunkContext\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
}\r
}\r
\r
}\r
\r
RemoveEntryList (&ThunkContext->Link);\r
-\r
DestroyThunkContext (ThunkContext);\r
}else {\r
Status = EFI_NOT_FOUND;\r
}\r
\r
mInFrameworkHiiRemovePack = FALSE;\r
- \r
gBS->RestoreTPL (OldTpl);\r
\r
return Status;\r
InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
} \r
\r
-\r
if (PackageType == EFI_HII_PACKAGE_FORM) {\r
- Status = CreateQuestionIdMap (ThunkContext);\r
+ GetAttributesOfFirstFormSet (ThunkContext);\r
}\r
\r
return Status; \r
}\r
\r
-\r
-BOOLEAN\r
-IsRemovingLastStringPack (\r
- IN EFI_HII_HANDLE Handle\r
- )\r
-{\r
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
- UINTN BufferSize;\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGE_HEADER *PackageHeader;\r
- UINTN StringPackageCount;\r
-\r
- HiiPackageList = NULL;\r
- BufferSize = 0;\r
- StringPackageCount = 0;\r
-\r
- Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
-\r
- while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
- switch (PackageHeader->Type) {\r
- case EFI_HII_PACKAGE_STRINGS:\r
- StringPackageCount++;\r
-\r
- if (StringPackageCount > 1) {\r
- //\r
- // More than one String Pack in the package list\r
- //\r
- FreePool (HiiPackageList);\r
- return FALSE;\r
- }\r
- break; \r
-\r
- default:\r
- break;\r
- }\r
- //\r
- // goto header of next package\r
- //\r
- PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
- }\r
-\r
-\r
- //\r
- // We will always be notified for the removal of String Pack from a package list.\r
- // So StringPackageCount must be one at this point.\r
- //\r
- ASSERT (StringPackageCount == 1);\r
- \r
- FreePool (HiiPackageList);\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
+//\r
// Framework HII module may cache a GUID as the name of the package list.\r
// Then search for the Framework HII handle database for the handle matching\r
// this GUID\r
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
)\r
{\r
- EFI_STATUS Status;\r
- HII_THUNK_PRIVATE_DATA *Private;\r
- HII_THUNK_CONTEXT * ThunkContext;\r
+ EFI_STATUS Status;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
\r
Status = EFI_SUCCESS;\r
\r
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
\r
if (!ThunkContext->ByFrameworkHiiNewPack) {\r
- if (IsRemovingLastStringPack (Handle)) {\r
+ Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {\r
//\r
// If the string package will be removed is the last string package\r
// in the package list, we will remove the HII Thunk entry from the\r
//\r
DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
}\r
+\r
+ FreePool (HiiPackageList);\r
}\r
\r
return Status;\r
EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
\r
\r
-EFI_GUID *\r
-GetGuidOfFirstFormset (\r
- CONST EFI_HII_FORM_PACKAGE * FormPackage\r
-) \r
-{\r
- UINT8 *StartOfNextPackage;\r
- EFI_IFR_OP_HEADER *OpCodeData;\r
-\r
- StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;\r
- OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);\r
-\r
- while ((UINT8 *) OpCodeData < StartOfNextPackage) {\r
- if (OpCodeData->OpCode == EFI_IFR_FORM_SET_OP) {\r
- return AllocateCopyPool (sizeof(EFI_GUID), &(((EFI_IFR_FORM_SET *) OpCodeData)->Guid));\r
- }\r
- OpCodeData = (EFI_IFR_OP_HEADER *) ((UINT8 *) OpCodeData + OpCodeData->Length);\r
- }\r
-\r
- ASSERT (FALSE);\r
-\r
- return NULL;\r
-}\r
-\r
EFI_HII_HANDLE\r
FwHiiHandleToUefiHiiHandle (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
+VOID\r
+GetAttributesOfFirstFormSet (\r
+ IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *List;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINTN Size;\r
+ EFI_IFR_OP_HEADER *OpCode;\r
+ UINTN Offset;\r
+ EFI_IFR_GUID_CLASS *Class;\r
+ EFI_IFR_FORM_SET *FormSet;\r
+ EFI_IFR_GUID_SUBCLASS *SubClass;\r
+\r
+ Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // There must be at least one EFI_HII_PACKAGE_FORM in the package list.\r
+ //\r
+ ASSERT (GetPackageCountByType (List, EFI_HII_PACKAGE_FORM) >= 1);\r
+\r
+ //\r
+ // Skip the package list header.\r
+ //\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
+\r
+ while (Package->Type != EFI_HII_PACKAGE_END) {\r
+\r
+ if (Package->Type == EFI_HII_PACKAGE_FORM) {\r
+\r
+ //\r
+ // Skip the package header\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset < Package->Length) {\r
+ OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
+\r
+ switch (OpCode->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
+ ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
+ ThunkContext->FormSetHelp = FormSet->Help;\r
+ break;\r
+ \r
+\r
+ case EFI_IFR_GUID_OP:\r
+ Class = (EFI_IFR_GUID_CLASS*) OpCode;\r
+ if (CompareGuid (&Class->Guid, &gTianoHiiIfrGuid)) {\r
+ Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
+\r
+ switch (Class->ExtendOpCode) {\r
+ case EFI_IFR_EXTEND_OP_CLASS:\r
+ ThunkContext->FormSetClass = Class->Class;\r
+ break;\r
+ case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+ SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
+ ThunkContext->FormSetSubClass = SubClass->SubClass;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ \r
+ default:\r
+ break;\r
+ \r
+ }\r
+\r
+ Offset += OpCode->Length;\r
+ }\r
+ //\r
+ // The attributes of first FormSet is ready now.\r
+ //\r
+ FreePool (List);\r
+ return;\r
+ \r
+ break;\r
+ }\r
+\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;\r
+ }\r
+\r
+}\r
+\r
\r
EFI_STATUS\r
CreateQuestionIdMap (\r
ONE_OF_OPTION_MAP *OneOfOptionMap;\r
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
EFI_IFR_GUID_CLASS *Class;\r
+ EFI_IFR_GUID_SUBCLASS *SubClass;\r
\r
\r
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
ThunkContext->FormSetClass = Class->Class;\r
break;\r
case EFI_IFR_EXTEND_OP_SUBCLASS:\r
- ThunkContext->FormSetSubClass = ((EFI_IFR_GUID_SUBCLASS *) Class)->SubClass;\r
+ SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
+ ThunkContext->FormSetSubClass = SubClass->SubClass;\r
break;\r
\r
default:\r
while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
\r
- IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
+ IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link2);\r
\r
RemoveEntryList (Link2);\r
\r
while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
\r
- MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link);\r
+ MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
\r
RemoveEntryList (Link2);\r
\r