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