]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/Package.c
Maintainers.txt: Remove EdkCompatibilityPkg information
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / Package.c
CommitLineData
26a76fbc 1/** @file\r
0368663f 2 Implement protocol interface related to package registrations.\r
4259256b 3\r
584d5652
HT
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
4259256b 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15\r
16#include "HiiDatabase.h"\r
d4775f2a 17#include "HiiHandle.h"\r
4259256b 18\r
19\r
a16d259b 20BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
21BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
0368663f 22BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
a16d259b 23UINT64 mGuidCount = 0;\r
63dd6a96 24\r
88b6bcec 25EFI_GUID mGuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
26\r
27\r
63dd6a96 28\r
a16d259b 29/**\r
26a76fbc 30 Get the number of Form, STRING and Font packages in the package list passed in.\r
a16d259b 31\r
32 @param Packages Package List.\r
33 @param IfrPackageCount Number of IFR Packages.\r
34 @param StringPackageCount Number of String Packages.\r
26a76fbc 35 @param FontPackageCount Number of Font Packages.\r
a16d259b 36\r
37 @retval EFI_INVALID_PARAMETER If the Package List has package with type of \r
38 EFI_HII_PACKAGE_KEYBOARD_LAYOUT, EFI_HII_PACKAGE_FONTS, EFI_HII_PACKAGE_IMAGES.\r
26a76fbc 39 @retval EFI_SUCCESS Successfully get the number of IFR and STRING package.\r
a16d259b 40 \r
41\r
42**/\r
4259256b 43EFI_STATUS\r
0368663f 44GetPackageCount (\r
4259256b 45 IN CONST EFI_HII_PACKAGES *Packages,\r
70d72ba9 46 OUT UINTN *IfrPackageCount,\r
47 OUT UINTN *StringPackageCount,\r
48 OUT UINTN *FontPackageCount\r
4259256b 49 )\r
50{\r
51 UINTN Index;\r
52 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
53\r
54 ASSERT (Packages != NULL);\r
0368663f 55 ASSERT (IfrPackageCount != NULL);\r
56 ASSERT (StringPackageCount != NULL);\r
70d72ba9 57 ASSERT (FontPackageCount != NULL);\r
4259256b 58\r
0368663f 59 *IfrPackageCount = 0;\r
60 *StringPackageCount = 0;\r
70d72ba9 61 *FontPackageCount = 0;\r
4259256b 62\r
63 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
0368663f 64 \r
4259256b 65 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
66 //\r
a3318eaf 67 // The current UEFI HII build tool generate a binary in the format defined by \r
4259256b 68 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
0368663f 69 // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
4259256b 70 // may not be the exact number of valid package number in the binary generated \r
71 // by HII Build tool.\r
72 //\r
70d72ba9 73 switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
74 case EFI_HII_IFR:\r
0368663f 75 *IfrPackageCount += 1;\r
4259256b 76 break;\r
70d72ba9 77 case EFI_HII_STRING:\r
0368663f 78 *StringPackageCount += 1;\r
4259256b 79 break;\r
80\r
70d72ba9 81 case EFI_HII_FONT:\r
82 *FontPackageCount += 1;\r
4259256b 83 break;\r
84\r
85 //\r
86 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
87 //\r
4259256b 88 default:\r
89 ASSERT (FALSE);\r
90 return EFI_INVALID_PARAMETER;\r
91 break;\r
92 }\r
93 }\r
94\r
95 return EFI_SUCCESS;\r
96}\r
97\r
a16d259b 98/**\r
99 Insert the String Package into the Package Lists which has the TAG GUID matching\r
100 the PackageListGuid of the String Package. \r
101\r
102 The Package List must have only IFR Package and no String Package. \r
103 Otherwise, ASSERT.\r
104\r
105 @param Private The HII THUNK driver context data.\r
106 @param StringPackageThunkContext The HII THUNK context data.\r
107 @param StringPackageListHeader The String Package List Header.\r
108 \r
109**/\r
59930165 110VOID\r
111UpdatePackListWithOnlyIfrPack (\r
0368663f 112 IN HII_THUNK_PRIVATE_DATA *Private,\r
113 IN HII_THUNK_CONTEXT *StringPackageThunkContext,\r
4259256b 114 IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
115 )\r
116{\r
117 EFI_STATUS Status;\r
0368663f 118 LIST_ENTRY *Link;\r
3321fa09 119 HII_THUNK_CONTEXT *ThunkContext;\r
0368663f 120\r
121 Link = GetFirstNode (&Private->ThunkContextListHead);\r
122 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
123\r
124 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
125\r
126 if (StringPackageThunkContext != ThunkContext) {\r
127 //\r
128 // Skip the String Package Thunk Entry itself.\r
129 //\r
130 \r
131 if (CompareGuid (&StringPackageListHeader->PackageListGuid, &ThunkContext->TagGuid)) {\r
132\r
133 ASSERT (ThunkContext->StringPackageCount == 0 && ThunkContext->IfrPackageCount == 1);\r
134\r
135 ThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
136 \r
137 Status = mHiiDatabase->UpdatePackageList (\r
138 mHiiDatabase,\r
139 ThunkContext->UefiHiiHandle,\r
140 StringPackageListHeader\r
141 );\r
59930165 142 ASSERT_EFI_ERROR (Status);\r
3321fa09 143\r
144 ThunkContext->SharingStringPack = TRUE;\r
145 StringPackageThunkContext->SharingStringPack = TRUE;\r
146\r
0368663f 147 }\r
4259256b 148 }\r
0368663f 149 \r
150 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
4259256b 151 }\r
3321fa09 152\r
4259256b 153}\r
0368663f 154\r
70d72ba9 155/**\r
156 Caculate the size of UEFI Simple Font Package that is needed to \r
157 convert all the font a Framework Font Paackage.\r
158\r
159 ONLY Narrow Font is supported. Wide Font is discarded. \r
160\r
161 If the Package Header is not of EFI_HII_FONT type, then ASSERT.\r
162\r
26a76fbc 163 @param PackHeader Pointer to Framework Font Package.\r
70d72ba9 164 \r
165 @return The size of the UEFI Simple Font Package.\r
166 \r
167**/\r
168UINTN\r
169GetUefiSimpleFontPackSize (\r
170 IN CONST EFI_HII_PACK_HEADER * PackHeader\r
171 )\r
172{\r
173 UINTN Size;\r
174 EFI_HII_FONT_PACK *FwFontPack;\r
175\r
176 FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
177\r
178 ASSERT (FwFontPack->Header.Type == EFI_HII_FONT);\r
179 \r
180 Size = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) \r
181 + (FwFontPack->NumberOfNarrowGlyphs * sizeof (EFI_NARROW_GLYPH));\r
182\r
183 return Size;\r
184}\r
185\r
186\r
187/**\r
188 Convert Font Package in Framework format to a newly allocated UEFI\r
189 Simple Font Package.\r
190\r
191 ONLY Narrow Font is supported. Wide Font is discarded. \r
192\r
193 If memory allocation fails, then ASSERT.\r
194\r
26a76fbc 195 @param PackHeader Pointer to Framework Font Package header.\r
70d72ba9 196\r
26a76fbc 197 @return UEFI Simple Font Package.\r
70d72ba9 198**/\r
199EFI_HII_SIMPLE_FONT_PACKAGE_HDR *\r
200FrameworkFontPackToUefiSimpliedFont (\r
201 IN CONST EFI_HII_PACK_HEADER * PackHeader\r
202 )\r
203{\r
204 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
205 UINTN Size;\r
206 EFI_NARROW_GLYPH *FwNarrowGlyph;\r
207 EFI_NARROW_GLYPH *NarrowGlyph;\r
208 UINTN Idx;\r
209 EFI_HII_FONT_PACK *FwFontPack;\r
210\r
211 Size = GetUefiSimpleFontPackSize (PackHeader);\r
212\r
213 FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
214\r
215 FontPack = AllocateZeroPool (Size);\r
216 ASSERT (FontPack != NULL);\r
217\r
218 //\r
219 // Prepare the Header information.\r
220 //\r
221 FontPack->Header.Length = (UINT32) Size;\r
222 FontPack->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
223\r
224 FontPack->NumberOfNarrowGlyphs = FwFontPack->NumberOfNarrowGlyphs;\r
225 \r
226 //\r
227 // ONLY Narrow Font is supported. Wide Font is discarded. \r
228 //\r
229 FontPack->NumberOfWideGlyphs = 0;\r
230 \r
231 //\r
232 // Copy Narrow Glyph\r
233 //\r
234 NarrowGlyph = (EFI_NARROW_GLYPH *) (FontPack + 1);\r
235 FwNarrowGlyph = (EFI_NARROW_GLYPH *) (FwFontPack + 1);\r
236 CopyMem (NarrowGlyph, FwNarrowGlyph, sizeof (EFI_NARROW_GLYPH) * FwFontPack->NumberOfNarrowGlyphs);\r
237 for (Idx = 0; Idx < FwFontPack->NumberOfNarrowGlyphs; Idx++) {\r
238 //\r
239 // Clear the GLYPH_NON_BREAKING (EFI_GLYPH_WIDE is used here as they are all 0x02)\r
240 // attribute which is not defined in UEFI EFI_NARROW_GLYPH\r
241 //\r
242 NarrowGlyph[Idx].Attributes = (UINT8) (NarrowGlyph[Idx].Attributes & ~(EFI_GLYPH_WIDE));\r
243 }\r
244\r
245 return FontPack;\r
246}\r
0368663f 247\r
a16d259b 248/**\r
249 Prepare a UEFI Package List from a Framework HII package list registered\r
250 from a Framework HII NewPack () function.\r
251\r
252 If either Packages or PackageListGuid is NULL, then ASSERT.\r
253 \r
254 @param Packages The Framework HII Package List.\r
255 @param PackageListGuid The Package List GUID.\r
256\r
257\r
258 @return The UEFI Package List. \r
259**/\r
4259256b 260EFI_HII_PACKAGE_LIST_HEADER *\r
261PrepareUefiPackageListFromFrameworkHiiPackages (\r
262 IN CONST EFI_HII_PACKAGES *Packages,\r
63dd6a96 263 IN CONST EFI_GUID *PackageListGuid\r
4259256b 264 )\r
265{\r
266 UINTN NumberOfPackages;\r
267 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
268 UINT8 *PackageListData;\r
269 UINT32 PackageListLength;\r
270 UINT32 PackageLength;\r
271 EFI_HII_PACKAGE_HEADER PackageHeader;\r
272 UINTN Index;\r
70d72ba9 273 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
274 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
275 \r
4259256b 276\r
63dd6a96 277 ASSERT (Packages != NULL);\r
278 ASSERT (PackageListGuid != NULL);\r
279\r
4259256b 280 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) ((UINT8 *) &Packages->GuidId + sizeof (Packages->GuidId));\r
281 NumberOfPackages = Packages->NumberOfPackages;\r
282\r
283 PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
284\r
285 for (Index = 0; Index < NumberOfPackages; Index++) {\r
70d72ba9 286 if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
287 //\r
288 // There is no tool to generate Font package in Framework HII's implementation.\r
289 // Therefore, Font Package be a C structure defined in Framework HII code. \r
290 // Therefore, Font Package will be in Framework HII format defined by EFI_HII_FONT_PACK.\r
291 // We need to create a UEFI Simple Font Package and copy over all data. Hence, EFI_HII_FONT\r
292 // is handled differently than EFI_HII_IFR and EFI_HII_STRING.\r
293 //\r
294 PackageListLength = (UINT32) (PackageListLength + GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader));\r
295 \r
296 } else {\r
297 //\r
298 // For EFI_HII_IFR and EFI_HII_STRING, EDK II's VFR Compiler and Build.exe will generate a binary in a format\r
299 // defined by TIANO_AUTOGEN_PACKAGES_HEADER. A Framework HII's EFI_HII_PACK_HEADER is inserted before\r
300 // the UEFI package data.\r
301 //\r
302 CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length, sizeof (UINT32));\r
303 //\r
304 // EFI_HII_PACK_HEADER.FrameworkPackageHeader.Length include the sizeof FrameworkPackageHeader itself.\r
305 //\r
306 PackageListLength += (PackageLength - sizeof(EFI_HII_PACK_HEADER));\r
307 \r
308 }\r
4259256b 309 }\r
310\r
311 //\r
312 // Include the lenght of EFI_HII_PACKAGE_END\r
313 //\r
314 PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
315 PackageListHeader = AllocateZeroPool (PackageListLength);\r
316 ASSERT (PackageListHeader != NULL);\r
63dd6a96 317\r
318 CopyMem (&PackageListHeader->PackageListGuid, PackageListGuid, sizeof (EFI_GUID));\r
4259256b 319 PackageListHeader->PackageLength = PackageListLength;\r
320\r
321 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
322\r
70d72ba9 323 //\r
324 // Build the UEFI Package List.\r
325 //\r
4259256b 326 for (Index = 0; Index < NumberOfPackages; Index++) {\r
70d72ba9 327 if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
328 PackageLength = (UINT32) GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
329 FontPack = FrameworkFontPackToUefiSimpliedFont (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
330 CopyMem (PackageListData, FontPack, PackageLength);\r
331 FreePool (FontPack);\r
332 \r
333 } else {\r
334 CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length), sizeof (UINT32));\r
335 PackageLength -= sizeof (EFI_HII_PACK_HEADER);\r
336 CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);\r
337 \r
338 }\r
4259256b 339 PackageListData += PackageLength;\r
340 }\r
341\r
342 //\r
343 // Append EFI_HII_PACKAGE_END\r
344 //\r
345 PackageHeader.Type = EFI_HII_PACKAGE_END;\r
346 PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
347 CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
348\r
349 return PackageListHeader; \r
350}\r
351\r
a16d259b 352\r
353/**\r
354 Generate a Random GUID.\r
355 \r
356 @param Guid On output, a Random GUID will be filled.\r
357\r
358**/\r
59336178 359VOID\r
59930165 360GenerateRandomGuid (\r
361 OUT EFI_GUID * Guid\r
4259256b 362 )\r
363{\r
88b6bcec 364 CopyGuid (Guid, &mGuidBase);\r
138f2f82 365\r
a16d259b 366 mGuidCount++; \r
367 *((UINT64 *) Guid) = *((UINT64 *) Guid) + mGuidCount;\r
4259256b 368}\r
369\r
a16d259b 370/**\r
371 Given a Package List with only a IFR package, find the Package List that only has a String Package based on\r
372 the TAG GUID. Then export the String Package from the Package List and insert it\r
373 to the given IFR package.\r
374\r
375 This is to handle the case of Framework HII interface which allow String Package\r
376 and IFR package to be registered using two different NewPack () calls.\r
377\r
378 @param Private The HII THUNK driver context data.\r
379 @param IfrThunkContext Package List with only a IFR package.\r
380\r
381 @retval EFI_SUCCESS If the String Package is found and inserted to the\r
382 Package List with only a IFR package.\r
383 @retval EFI_NOT_FOUND No String Package matching the TAG GUID is found.\r
384**/\r
4259256b 385EFI_STATUS\r
59930165 386FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
0368663f 387 IN HII_THUNK_PRIVATE_DATA *Private,\r
388 IN HII_THUNK_CONTEXT *IfrThunkContext\r
4259256b 389 )\r
390{\r
0368663f 391 EFI_STATUS Status;\r
392 LIST_ENTRY *Link;\r
393 EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
394 UINTN Size;\r
3321fa09 395 HII_THUNK_CONTEXT *ThunkContext;\r
0368663f 396 \r
397 Link = GetFirstNode (&Private->ThunkContextListHead);\r
398\r
399 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
400\r
401 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
402\r
403 if (ThunkContext != IfrThunkContext) {\r
404 if (CompareGuid (&IfrThunkContext->TagGuid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount == 0)) {\r
234980f6 405 StringPackageListHeader = NULL;\r
cb7d01c0 406 Status = ExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);\r
0368663f 407 ASSERT_EFI_ERROR (Status);\r
234980f6
LG
408 if (StringPackageListHeader == NULL) {\r
409 return EFI_NOT_FOUND;\r
410 }\r
0368663f 411\r
412 IfrThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
413 //\r
414 // Add Function to only get only String Packages from the Package List\r
415 //\r
416 Status = mHiiDatabase->UpdatePackageList (\r
417 mHiiDatabase,\r
418 IfrThunkContext->UefiHiiHandle,\r
419 StringPackageListHeader\r
420 );\r
421 ASSERT_EFI_ERROR (Status);\r
422 \r
423 FreePool (StringPackageListHeader);\r
3321fa09 424\r
425 IfrThunkContext->SharingStringPack = TRUE;\r
426 ThunkContext->SharingStringPack = TRUE;\r
427 \r
0368663f 428 return EFI_SUCCESS;\r
59930165 429\r
0368663f 430 }\r
431 }\r
4259256b 432\r
0368663f 433 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
434 }\r
435\r
3321fa09 436 //\r
437 // A Form Package must have a String Package to function.\r
438 // If ASSERT here, check the sequence of call to Hii->NewPack. \r
439 // String Pack must be registered before Ifr Package is registered.\r
440 //\r
59930165 441 ASSERT (FALSE);\r
0368663f 442 return EFI_NOT_FOUND;\r
59930165 443 \r
0368663f 444}\r
445\r
0368663f 446\r
a16d259b 447/**\r
448 Register the Package List passed from the Framework HII NewPack () interface.\r
449 The FRAMEWORK_EFI_HII_HANDLE will be returned.\r
450\r
451 @param This The EFI_HII_PROTOCOL context data. Only used\r
452 to call HiiRemovePack.\r
453 @param Private The HII THUNK driver context data.\r
26a76fbc 454 @param Packages Package List.\r
a16d259b 455 @param Handle On output, a FRAMEWORK_EFI_HII_HANDLE number is\r
456 returned.\r
457\r
4fc0be87 458 @retval EFI_SUCCESS The Package List is registered successfully in\r
a16d259b 459 the database.\r
460 @retval EFI_UNSUPPORTED The number of IFR package in the package list\r
461 is greater than 1.\r
462 @retval EFI_OUT_OF_RESOURCE Not enough resouce.\r
463 \r
464**/\r
4259256b 465EFI_STATUS\r
a16d259b 466UefiRegisterPackageList (\r
3032f549 467 IN EFI_HII_PROTOCOL *This,\r
0368663f 468 IN HII_THUNK_PRIVATE_DATA *Private,\r
469 IN EFI_HII_PACKAGES *Packages,\r
470 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
4259256b 471 )\r
472{\r
473 EFI_STATUS Status;\r
0368663f 474 UINTN StringPackageCount;\r
475 UINTN IfrPackageCount;\r
70d72ba9 476 UINTN FontPackageCount;\r
0368663f 477 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
59930165 478 HII_THUNK_CONTEXT *ThunkContext;\r
bc226416 479 HII_THUNK_CONTEXT *ThunkContextToRemove;\r
59336178 480 EFI_GUID GuidId;\r
bc226416 481 EFI_HII_PACKAGE_HEADER *IfrPackage;\r
4259256b 482\r
0368663f 483 PackageListHeader = NULL;\r
4259256b 484\r
70d72ba9 485 Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);\r
4259256b 486 ASSERT_EFI_ERROR (Status);\r
0368663f 487 \r
488 if (IfrPackageCount > 1) {\r
489 //\r
490 // HII Thunk only handle package with 0 or 1 IFR package. \r
491 //\r
59930165 492 ASSERT (FALSE);\r
59336178 493 return EFI_UNSUPPORTED;\r
494 }\r
4259256b 495\r
bc226416 496 ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);\r
497 if (ThunkContext == NULL) {\r
498 return EFI_OUT_OF_RESOURCES;\r
499 }\r
500 ThunkContext->ByFrameworkHiiNewPack = TRUE;\r
501 \r
59336178 502 if (Packages->GuidId == NULL) {\r
0368663f 503 //\r
504 // UEFI HII Database require Package List GUID must be unique.\r
505 //\r
506 // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
507 // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
a9d85320 508 // not used as the name of the package list. Formset GUID is used as the Package List\r
70d72ba9 509 // GUID instead.\r
0368663f 510 //\r
70d72ba9 511 ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));\r
512 if (IfrPackageCount > 0) {\r
513 IfrPackage = GetIfrPackage (Packages);\r
234980f6
LG
514 if (IfrPackage == NULL) {\r
515 Status = EFI_NOT_FOUND;\r
516 goto Done;\r
517 }\r
70d72ba9 518 GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);\r
519 } else {\r
520 ASSERT (FontPackageCount > 0);\r
521 GenerateRandomGuid (&ThunkContext->TagGuid);\r
522 }\r
523 \r
63dd6a96 524 } else {\r
bc226416 525 ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);\r
8ea58c07 526 \r
527 if (IfrPackageCount > 0 && \r
528 StringPackageCount > 0 && \r
70d72ba9 529 (ThunkContextToRemove != NULL)) {\r
8ea58c07 530 DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));\r
70d72ba9 531 DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));\r
bc226416 532 HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);\r
8ea58c07 533 }\r
bc226416 534 CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
70d72ba9 535 \r
59336178 536 }\r
4259256b 537\r
4259256b 538 //\r
539 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
a9d85320 540 // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only\r
541 // produce IFR package generated with Buffer Storage type and EFI Variable Storage.\r
542 // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.\r
4259256b 543 //\r
0368663f 544 if (IfrPackageCount != 0) {\r
545 InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
4259256b 546 }\r
70d72ba9 547 \r
b436ed89 548 PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);\r
59336178 549 Status = mHiiDatabase->NewPackageList (\r
550 mHiiDatabase,\r
0368663f 551 PackageListHeader, \r
552 ThunkContext->UefiHiiDriverHandle,\r
553 &ThunkContext->UefiHiiHandle\r
4259256b 554 );\r
b436ed89 555 if (Status == EFI_INVALID_PARAMETER) {\r
7001eaf8 556 FreePool (PackageListHeader);\r
b436ed89 557 \r
558 //\r
559 // UEFI HII database does not allow two package list with the same GUID.\r
560 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
561 // a PackageList with only IFR to a Package list the with String package.\r
562 //\r
563 GenerateRandomGuid (&GuidId);\r
564\r
565 PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
566 Status = mHiiDatabase->NewPackageList (\r
567 mHiiDatabase,\r
568 PackageListHeader, \r
569 ThunkContext->UefiHiiDriverHandle,\r
570 &ThunkContext->UefiHiiHandle\r
571 );\r
572 }\r
0368663f 573\r
574 //\r
575 // BUGBUG: Remove when development is done\r
576 //\r
4259256b 577 ASSERT_EFI_ERROR (Status);\r
578 if (EFI_ERROR (Status)) {\r
579 goto Done;\r
580 }\r
581 \r
0368663f 582 if (IfrPackageCount == 0) {\r
583 if (StringPackageCount != 0) {\r
4259256b 584 //\r
a9d85320 585 // Look for a Package List with only IFR Package with the same TAG GUID name.\r
586 // If found one, add the String Packages to the found Package List.\r
587 // This is needed because Framework HII Module may not register the String Package\r
588 // and IFR Package in one NewPack () call.\r
4259256b 589 //\r
59930165 590 UpdatePackListWithOnlyIfrPack (\r
591 Private,\r
592 ThunkContext,\r
593 PackageListHeader\r
594 );\r
4259256b 595 }\r
596 } else {\r
0368663f 597 if (StringPackageCount == 0) {\r
4259256b 598 //\r
a9d85320 599 // Look for the String Package with the same TAG GUID name and add\r
600 // the found String Package to this Package List.\r
601 // This is needed because Framework HII Module may not register the String Package\r
602 // and IFR Package in one NewPack () call.\r
4259256b 603 //\r
59930165 604 Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
4259256b 605 Private,\r
0368663f 606 ThunkContext\r
4259256b 607 );\r
59930165 608\r
609 if (EFI_ERROR (Status)) {\r
610 goto Done;\r
611 }\r
4259256b 612 }\r
a9d85320 613 \r
614 //\r
615 // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so\r
616 // that String Package is ready.\r
617 //\r
618 ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
619 ASSERT (ThunkContext->FormSet != NULL);\r
620 \r
4259256b 621 }\r
622\r
4259256b 623Done:\r
624 if (EFI_ERROR (Status)) {\r
d4775f2a 625 DestroyThunkContext (ThunkContext);\r
4259256b 626 } else {\r
0368663f 627 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
628 *Handle = ThunkContext->FwHiiHandle;\r
4259256b 629 }\r
630\r
7001eaf8 631 if (PackageListHeader != NULL) {\r
632 FreePool (PackageListHeader);\r
633 }\r
4259256b 634 \r
635 return Status;\r
636}\r
637\r
ea58467b 638\r
a9d85320 639/**\r
640\r
641 Registers the various packages that are passed in a Package List.\r
642\r
643 @param This Pointer of Frameowk HII protocol instance.\r
644 @param Packages Pointer of HII packages.\r
645 @param Handle Handle value to be returned.\r
646\r
4fc0be87 647 @retval EFI_SUCCESS Packages has added to HII database successfully.\r
a9d85320 648 @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
649\r
650**/\r
4259256b 651EFI_STATUS\r
652EFIAPI\r
653HiiNewPack (\r
654 IN EFI_HII_PROTOCOL *This,\r
655 IN EFI_HII_PACKAGES *Packages,\r
656 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
657 )\r
4259256b 658{\r
659 EFI_STATUS Status;\r
0368663f 660 HII_THUNK_PRIVATE_DATA *Private;\r
63dd6a96 661 EFI_TPL OldTpl;\r
4259256b 662\r
663 if (Handle == NULL) {\r
664 return EFI_INVALID_PARAMETER;\r
665 }\r
666\r
667 if (Packages == NULL) {\r
668 return EFI_INVALID_PARAMETER;\r
669 }\r
670\r
63dd6a96 671 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
672 \r
ea58467b 673 //\r
a9d85320 674 // We use a simple Global variable to inform NewOrAddPackNotify()\r
ea58467b 675 // that the package list registered here is already registered\r
a9d85320 676 // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to\r
677 // call registered the Package List again.\r
ea58467b 678 //\r
679 mInFrameworkHiiNewPack = TRUE;\r
680\r
0368663f 681 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
4259256b 682\r
683 Status = UefiRegisterPackageList (\r
8ea58c07 684 This,\r
4259256b 685 Private,\r
686 Packages,\r
687 Handle\r
688 );\r
689\r
ea58467b 690 mInFrameworkHiiNewPack = FALSE;\r
691\r
63dd6a96 692 gBS->RestoreTPL (OldTpl);\r
693\r
4259256b 694 return Status;\r
695}\r
696\r
a9d85320 697/**\r
698\r
699 Remove a package from the HII database.\r
700\r
701 @param This Pointer of Frameowk HII protocol instance.\r
702 @param Handle Handle value to be removed.\r
703\r
4fc0be87 704 @retval EFI_SUCCESS Packages has added to HII database successfully.\r
a9d85320 705 @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
706\r
707**/\r
4259256b 708EFI_STATUS\r
709EFIAPI\r
710HiiRemovePack (\r
a16d259b 711 IN EFI_HII_PROTOCOL *This,\r
4259256b 712 IN FRAMEWORK_EFI_HII_HANDLE Handle\r
713 )\r
4259256b 714{\r
715 EFI_STATUS Status;\r
a9d85320 716 HII_THUNK_PRIVATE_DATA *Private;\r
717 HII_THUNK_CONTEXT *ThunkContext;\r
63dd6a96 718 EFI_TPL OldTpl;\r
63dd6a96 719\r
720 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
721\r
722 mInFrameworkHiiRemovePack = TRUE;\r
4259256b 723\r
0368663f 724 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
4259256b 725\r
0368663f 726 ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
4259256b 727\r
0368663f 728 if (ThunkContext != NULL) {\r
59336178 729 Status = mHiiDatabase->RemovePackageList (\r
730 mHiiDatabase,\r
0368663f 731 ThunkContext->UefiHiiHandle\r
99a83b4c 732 );\r
733 ASSERT_EFI_ERROR (Status);\r
734\r
0368663f 735 if (ThunkContext->IfrPackageCount != 0) {\r
736 UninstallDefaultConfigAccessProtocol (ThunkContext);\r
4259256b 737 }\r
99a83b4c 738\r
d4775f2a 739 DestroyThunkContext (ThunkContext);\r
63dd6a96 740 }else {\r
741 Status = EFI_NOT_FOUND;\r
4259256b 742 }\r
743\r
63dd6a96 744 mInFrameworkHiiRemovePack = FALSE;\r
63dd6a96 745 gBS->RestoreTPL (OldTpl);\r
746\r
747 return Status;\r
4259256b 748}\r
0368663f 749\r
a9d85320 750/**\r
751 This notification function will be called when a Package List is registered\r
752 using UEFI HII interface. The Package List registered need to be recorded in\r
753 Framework Thunk module as Thunk Module may need to look for String Package in\r
754 the package registered.\r
755\r
756 If the Package List registered is not either Sting Package or IFR package, \r
757 then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.\r
758 Both cases means UEFI HII Database itself is buggy. \r
759\r
760 @param PackageType The Package Type.\r
761 @param PackageGuid The Package GUID.\r
762 @param Package The Package Header.\r
763 @param Handle The HII Handle of this Package List.\r
764 @param NotifyType The reason of the notification. \r
765\r
766 @retval EFI_SUCCESS The notification function is successful.\r
767 \r
768**/\r
0368663f 769EFI_STATUS\r
770EFIAPI\r
771NewOrAddPackNotify (\r
772 IN UINT8 PackageType,\r
773 IN CONST EFI_GUID *PackageGuid,\r
774 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
775 IN EFI_HII_HANDLE Handle,\r
776 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
777 )\r
778{\r
779 EFI_STATUS Status;\r
780 HII_THUNK_PRIVATE_DATA *Private;\r
781 HII_THUNK_CONTEXT *ThunkContext;\r
782\r
4dd76ade 783 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS || PackageType == EFI_HII_PACKAGE_FORMS);\r
0368663f 784 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
785\r
786 Status = EFI_SUCCESS;\r
787 Private = mHiiThunkPrivateData;\r
788\r
789 if (mInFrameworkHiiNewPack || mInFrameworkUpdatePakcage) {\r
790 return EFI_SUCCESS;\r
791 }\r
792\r
793 //\r
a9d85320 794 // We will create a ThunkContext to log the package list only if the\r
795 // package is not registered with by Framework HII Thunk module yet.\r
0368663f 796 //\r
797 ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
798 if (ThunkContext == NULL) {\r
d4775f2a 799 ThunkContext = CreateThunkContextForUefiHiiHandle (Handle);\r
0368663f 800 ASSERT (ThunkContext != NULL);\r
d4775f2a 801\r
802 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
0368663f 803 } \r
804\r
4dd76ade 805 if (PackageType == EFI_HII_PACKAGE_FORMS) {\r
a9d85320 806 if (ThunkContext->FormSet != NULL) {\r
807 DestroyFormSet (ThunkContext->FormSet);\r
808 }\r
809\r
810 //\r
811 // Reparse the FormSet.\r
812 //\r
813 ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
0368663f 814 }\r
815\r
816 return Status; \r
817}\r
818\r
a9d85320 819/**\r
820 This notification function will be called when a Package List is removed\r
821 using UEFI HII interface. The Package List removed need to be removed from\r
822 Framework Thunk module too.\r
823\r
824 If the Package List registered is not Sting Package, \r
825 then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.\r
826 Both cases means UEFI HII Database itself is buggy. \r
827\r
828 @param PackageType The Package Type.\r
829 @param PackageGuid The Package GUID.\r
830 @param Package The Package Header.\r
831 @param Handle The HII Handle of this Package List.\r
832 @param NotifyType The reason of the notification. \r
0368663f 833\r
a9d85320 834 @retval EFI_SUCCESS The notification function is successful.\r
835 \r
836**/\r
0368663f 837EFI_STATUS\r
838EFIAPI\r
839RemovePackNotify (\r
840 IN UINT8 PackageType,\r
841 IN CONST EFI_GUID *PackageGuid,\r
842 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
843 IN EFI_HII_HANDLE Handle,\r
844 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
845 )\r
846{\r
59930165 847 EFI_STATUS Status;\r
848 HII_THUNK_PRIVATE_DATA *Private;\r
849 HII_THUNK_CONTEXT *ThunkContext;\r
850 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
851 UINTN BufferSize;\r
0368663f 852\r
853 Status = EFI_SUCCESS;\r
854\r
855 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
856 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);\r
857\r
858 if (mInFrameworkHiiRemovePack || mInFrameworkUpdatePakcage) {\r
859 return EFI_SUCCESS;\r
860 }\r
861\r
862 Private = mHiiThunkPrivateData;\r
863\r
864 ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
865\r
f38360fb 866 //\r
867 // BugBug: Change to ASSERT if HII Database fix the bug and to also invoke \r
868 // NEW_PACK_NOTIFY for package (String Package) created internally.\r
869 //\r
870 if (ThunkContext != NULL) {\r
871 if (!ThunkContext->ByFrameworkHiiNewPack) {\r
234980f6 872 HiiPackageList = NULL;\r
cb7d01c0 873 Status = ExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
f38360fb 874 ASSERT_EFI_ERROR (Status);\r
234980f6
LG
875 if (HiiPackageList == NULL) {\r
876 return EFI_NOT_FOUND;\r
877 }\r
59930165 878\r
f38360fb 879 if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {\r
880 //\r
881 // If the string package will be removed is the last string package\r
882 // in the package list, we will remove the HII Thunk entry from the\r
883 // database.\r
884 //\r
885 DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
886 }\r
59930165 887\r
f38360fb 888 FreePool (HiiPackageList);\r
889 }\r
0368663f 890 }\r
891\r
f38360fb 892 \r
0368663f 893 return Status;\r
894}\r
895\r
896\r
897\r