]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/Package.c
Remove dependency on include file in package outside of EKD2.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / Package.c
... / ...
CommitLineData
1/**@file\r
2 Implement protocol interface related to package registrations.\r
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
17#include "HiiHandle.h"\r
18\r
19\r
20BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
21BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
22BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
23UINT64 mGuidCount = 0;\r
24\r
25EFI_GUID mGuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
26\r
27\r
28\r
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
42EFI_STATUS\r
43GetPackageCount (\r
44 IN CONST EFI_HII_PACKAGES *Packages,\r
45 OUT UINTN *IfrPackageCount,\r
46 OUT UINTN *StringPackageCount,\r
47 OUT UINTN *FontPackageCount\r
48 )\r
49{\r
50 UINTN Index;\r
51 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
52\r
53 ASSERT (Packages != NULL);\r
54 ASSERT (IfrPackageCount != NULL);\r
55 ASSERT (StringPackageCount != NULL);\r
56 ASSERT (FontPackageCount != NULL);\r
57\r
58 *IfrPackageCount = 0;\r
59 *StringPackageCount = 0;\r
60 *FontPackageCount = 0;\r
61\r
62 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
63 \r
64 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
65 //\r
66 // The current UEFI HII build tool generate a binary in the format defined by \r
67 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
68 // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
69 // may not be the exact number of valid package number in the binary generated \r
70 // by HII Build tool.\r
71 //\r
72 switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
73 case EFI_HII_IFR:\r
74 *IfrPackageCount += 1;\r
75 break;\r
76 case EFI_HII_STRING:\r
77 *StringPackageCount += 1;\r
78 break;\r
79\r
80 case EFI_HII_FONT:\r
81 *FontPackageCount += 1;\r
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
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
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
109VOID\r
110UpdatePackListWithOnlyIfrPack (\r
111 IN HII_THUNK_PRIVATE_DATA *Private,\r
112 IN HII_THUNK_CONTEXT *StringPackageThunkContext,\r
113 IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
114 )\r
115{\r
116 EFI_STATUS Status;\r
117 LIST_ENTRY *Link;\r
118 HII_THUNK_CONTEXT *ThunkContext;\r
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
141 ASSERT_EFI_ERROR (Status);\r
142\r
143 ThunkContext->SharingStringPack = TRUE;\r
144 StringPackageThunkContext->SharingStringPack = TRUE;\r
145\r
146 }\r
147 }\r
148 \r
149 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
150 }\r
151\r
152}\r
153\r
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
246\r
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
259EFI_HII_PACKAGE_LIST_HEADER *\r
260PrepareUefiPackageListFromFrameworkHiiPackages (\r
261 IN CONST EFI_HII_PACKAGES *Packages,\r
262 IN CONST EFI_GUID *PackageListGuid\r
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
272 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
273 EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
274 \r
275\r
276 ASSERT (Packages != NULL);\r
277 ASSERT (PackageListGuid != NULL);\r
278\r
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
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
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
316\r
317 CopyMem (&PackageListHeader->PackageListGuid, PackageListGuid, sizeof (EFI_GUID));\r
318 PackageListHeader->PackageLength = PackageListLength;\r
319\r
320 PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
321\r
322 //\r
323 // Build the UEFI Package List.\r
324 //\r
325 for (Index = 0; Index < NumberOfPackages; Index++) {\r
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
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
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
358VOID\r
359GenerateRandomGuid (\r
360 OUT EFI_GUID * Guid\r
361 )\r
362{\r
363 CopyGuid (Guid, &mGuidBase);\r
364\r
365 mGuidCount++; \r
366 *((UINT64 *) Guid) = *((UINT64 *) Guid) + mGuidCount;\r
367}\r
368\r
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
384EFI_STATUS\r
385FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
386 IN HII_THUNK_PRIVATE_DATA *Private,\r
387 IN HII_THUNK_CONTEXT *IfrThunkContext\r
388 )\r
389{\r
390 EFI_STATUS Status;\r
391 LIST_ENTRY *Link;\r
392 EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
393 UINTN Size;\r
394 HII_THUNK_CONTEXT *ThunkContext;\r
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
404 Status = ExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);\r
405 ASSERT_EFI_ERROR (Status);\r
406\r
407 IfrThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
408 //\r
409 // Add Function to only get only String Packages from the Package List\r
410 //\r
411 Status = mHiiDatabase->UpdatePackageList (\r
412 mHiiDatabase,\r
413 IfrThunkContext->UefiHiiHandle,\r
414 StringPackageListHeader\r
415 );\r
416 ASSERT_EFI_ERROR (Status);\r
417 \r
418 FreePool (StringPackageListHeader);\r
419\r
420 IfrThunkContext->SharingStringPack = TRUE;\r
421 ThunkContext->SharingStringPack = TRUE;\r
422 \r
423 return EFI_SUCCESS;\r
424\r
425 }\r
426 }\r
427\r
428 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
429 }\r
430\r
431 //\r
432 // A Form Package must have a String Package to function.\r
433 // If ASSERT here, check the sequence of call to Hii->NewPack. \r
434 // String Pack must be registered before Ifr Package is registered.\r
435 //\r
436 ASSERT (FALSE);\r
437 return EFI_NOT_FOUND;\r
438 \r
439}\r
440\r
441\r
442/**\r
443 Register the Package List passed from the Framework HII NewPack () interface.\r
444 The FRAMEWORK_EFI_HII_HANDLE will be returned.\r
445\r
446 @param This The EFI_HII_PROTOCOL context data. Only used\r
447 to call HiiRemovePack.\r
448 @param Private The HII THUNK driver context data.\r
449 @param Package Package List.\r
450 @param Handle On output, a FRAMEWORK_EFI_HII_HANDLE number is\r
451 returned.\r
452\r
453 @retval EFI_SUCCESS The Package List is registered successfull in \r
454 the database.\r
455 @retval EFI_UNSUPPORTED The number of IFR package in the package list\r
456 is greater than 1.\r
457 @retval EFI_OUT_OF_RESOURCE Not enough resouce.\r
458 \r
459**/\r
460EFI_STATUS\r
461UefiRegisterPackageList (\r
462 IN EFI_HII_PROTOCOL *This,\r
463 IN HII_THUNK_PRIVATE_DATA *Private,\r
464 IN EFI_HII_PACKAGES *Packages,\r
465 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
466 )\r
467{\r
468 EFI_STATUS Status;\r
469 UINTN StringPackageCount;\r
470 UINTN IfrPackageCount;\r
471 UINTN FontPackageCount;\r
472 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
473 HII_THUNK_CONTEXT *ThunkContext;\r
474 HII_THUNK_CONTEXT *ThunkContextToRemove;\r
475 EFI_GUID GuidId;\r
476 EFI_HII_PACKAGE_HEADER *IfrPackage;\r
477\r
478 PackageListHeader = NULL;\r
479\r
480 Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);\r
481 ASSERT_EFI_ERROR (Status);\r
482 \r
483 if (IfrPackageCount > 1) {\r
484 //\r
485 // HII Thunk only handle package with 0 or 1 IFR package. \r
486 //\r
487 ASSERT (FALSE);\r
488 return EFI_UNSUPPORTED;\r
489 }\r
490\r
491 ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);\r
492 if (ThunkContext == NULL) {\r
493 return EFI_OUT_OF_RESOURCES;\r
494 }\r
495 ThunkContext->ByFrameworkHiiNewPack = TRUE;\r
496 \r
497 if (Packages->GuidId == NULL) {\r
498 //\r
499 // UEFI HII Database require Package List GUID must be unique.\r
500 //\r
501 // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
502 // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
503 // not used as the name of the package list. Formset GUID is used as the Package List\r
504 // GUID instead.\r
505 //\r
506 ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));\r
507 if (IfrPackageCount > 0) {\r
508 IfrPackage = GetIfrPackage (Packages);\r
509 GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);\r
510 } else {\r
511 ASSERT (FontPackageCount > 0);\r
512 GenerateRandomGuid (&ThunkContext->TagGuid);\r
513 }\r
514 \r
515 } else {\r
516 ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);\r
517 \r
518 if (IfrPackageCount > 0 && \r
519 StringPackageCount > 0 && \r
520 (ThunkContextToRemove != NULL)) {\r
521 DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));\r
522 DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));\r
523 HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);\r
524 }\r
525 CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
526 \r
527 }\r
528\r
529 //\r
530 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
531 // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only\r
532 // produce IFR package generated with Buffer Storage type and EFI Variable Storage.\r
533 // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.\r
534 //\r
535 if (IfrPackageCount != 0) {\r
536 InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
537 }\r
538 \r
539 PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);\r
540 Status = mHiiDatabase->NewPackageList (\r
541 mHiiDatabase,\r
542 PackageListHeader, \r
543 ThunkContext->UefiHiiDriverHandle,\r
544 &ThunkContext->UefiHiiHandle\r
545 );\r
546 if (Status == EFI_INVALID_PARAMETER) {\r
547 FreePool (PackageListHeader);\r
548 \r
549 //\r
550 // UEFI HII database does not allow two package list with the same GUID.\r
551 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
552 // a PackageList with only IFR to a Package list the with String package.\r
553 //\r
554 GenerateRandomGuid (&GuidId);\r
555\r
556 PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
557 Status = mHiiDatabase->NewPackageList (\r
558 mHiiDatabase,\r
559 PackageListHeader, \r
560 ThunkContext->UefiHiiDriverHandle,\r
561 &ThunkContext->UefiHiiHandle\r
562 );\r
563 }\r
564\r
565 //\r
566 // BUGBUG: Remove when development is done\r
567 //\r
568 ASSERT_EFI_ERROR (Status);\r
569 if (EFI_ERROR (Status)) {\r
570 goto Done;\r
571 }\r
572 \r
573 if (IfrPackageCount == 0) {\r
574 if (StringPackageCount != 0) {\r
575 //\r
576 // Look for a Package List with only IFR Package with the same TAG GUID name.\r
577 // If found one, add the String Packages to the found Package List.\r
578 // This is needed because Framework HII Module may not register the String Package\r
579 // and IFR Package in one NewPack () call.\r
580 //\r
581 UpdatePackListWithOnlyIfrPack (\r
582 Private,\r
583 ThunkContext,\r
584 PackageListHeader\r
585 );\r
586 }\r
587 } else {\r
588 if (StringPackageCount == 0) {\r
589 //\r
590 // Look for the String Package with the same TAG GUID name and add\r
591 // the found String Package to this Package List.\r
592 // This is needed because Framework HII Module may not register the String Package\r
593 // and IFR Package in one NewPack () call.\r
594 //\r
595 Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
596 Private,\r
597 ThunkContext\r
598 );\r
599\r
600 if (EFI_ERROR (Status)) {\r
601 goto Done;\r
602 }\r
603 }\r
604 \r
605 //\r
606 // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so\r
607 // that String Package is ready.\r
608 //\r
609 ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
610 ASSERT (ThunkContext->FormSet != NULL);\r
611 \r
612 }\r
613\r
614Done:\r
615 if (EFI_ERROR (Status)) {\r
616 DestroyThunkContext (ThunkContext);\r
617 } else {\r
618 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
619 *Handle = ThunkContext->FwHiiHandle;\r
620 }\r
621\r
622 if (PackageListHeader != NULL) {\r
623 FreePool (PackageListHeader);\r
624 }\r
625 \r
626 return Status;\r
627}\r
628\r
629\r
630/**\r
631\r
632 Registers the various packages that are passed in a Package List.\r
633\r
634 @param This Pointer of Frameowk HII protocol instance.\r
635 @param Packages Pointer of HII packages.\r
636 @param Handle Handle value to be returned.\r
637\r
638 @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
639 @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
640\r
641**/\r
642EFI_STATUS\r
643EFIAPI\r
644HiiNewPack (\r
645 IN EFI_HII_PROTOCOL *This,\r
646 IN EFI_HII_PACKAGES *Packages,\r
647 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
648 )\r
649{\r
650 EFI_STATUS Status;\r
651 HII_THUNK_PRIVATE_DATA *Private;\r
652 EFI_TPL OldTpl;\r
653\r
654 if (Handle == NULL) {\r
655 return EFI_INVALID_PARAMETER;\r
656 }\r
657\r
658 if (Packages == NULL) {\r
659 return EFI_INVALID_PARAMETER;\r
660 }\r
661\r
662 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
663 \r
664 //\r
665 // We use a simple Global variable to inform NewOrAddPackNotify()\r
666 // that the package list registered here is already registered\r
667 // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to\r
668 // call registered the Package List again.\r
669 //\r
670 mInFrameworkHiiNewPack = TRUE;\r
671\r
672 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
673\r
674 Status = UefiRegisterPackageList (\r
675 This,\r
676 Private,\r
677 Packages,\r
678 Handle\r
679 );\r
680\r
681 mInFrameworkHiiNewPack = FALSE;\r
682\r
683 gBS->RestoreTPL (OldTpl);\r
684\r
685 return Status;\r
686}\r
687\r
688/**\r
689\r
690 Remove a package from the HII database.\r
691\r
692 @param This Pointer of Frameowk HII protocol instance.\r
693 @param Handle Handle value to be removed.\r
694\r
695 @retval EFI_SUCCESS Pacakges has added to HII database successfully.\r
696 @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
697\r
698**/\r
699EFI_STATUS\r
700EFIAPI\r
701HiiRemovePack (\r
702 IN EFI_HII_PROTOCOL *This,\r
703 IN FRAMEWORK_EFI_HII_HANDLE Handle\r
704 )\r
705{\r
706 EFI_STATUS Status;\r
707 HII_THUNK_PRIVATE_DATA *Private;\r
708 HII_THUNK_CONTEXT *ThunkContext;\r
709 EFI_TPL OldTpl;\r
710\r
711 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
712\r
713 mInFrameworkHiiRemovePack = TRUE;\r
714\r
715 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
716\r
717 ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
718\r
719 if (ThunkContext != NULL) {\r
720 Status = mHiiDatabase->RemovePackageList (\r
721 mHiiDatabase,\r
722 ThunkContext->UefiHiiHandle\r
723 );\r
724 ASSERT_EFI_ERROR (Status);\r
725\r
726 if (ThunkContext->IfrPackageCount != 0) {\r
727 UninstallDefaultConfigAccessProtocol (ThunkContext);\r
728 }\r
729\r
730 DestroyThunkContext (ThunkContext);\r
731 }else {\r
732 Status = EFI_NOT_FOUND;\r
733 }\r
734\r
735 mInFrameworkHiiRemovePack = FALSE;\r
736 gBS->RestoreTPL (OldTpl);\r
737\r
738 return Status;\r
739}\r
740\r
741/**\r
742 This notification function will be called when a Package List is registered\r
743 using UEFI HII interface. The Package List registered need to be recorded in\r
744 Framework Thunk module as Thunk Module may need to look for String Package in\r
745 the package registered.\r
746\r
747 If the Package List registered is not either Sting Package or IFR package, \r
748 then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.\r
749 Both cases means UEFI HII Database itself is buggy. \r
750\r
751 @param PackageType The Package Type.\r
752 @param PackageGuid The Package GUID.\r
753 @param Package The Package Header.\r
754 @param Handle The HII Handle of this Package List.\r
755 @param NotifyType The reason of the notification. \r
756\r
757 @retval EFI_SUCCESS The notification function is successful.\r
758 \r
759**/\r
760EFI_STATUS\r
761EFIAPI\r
762NewOrAddPackNotify (\r
763 IN UINT8 PackageType,\r
764 IN CONST EFI_GUID *PackageGuid,\r
765 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
766 IN EFI_HII_HANDLE Handle,\r
767 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
768 )\r
769{\r
770 EFI_STATUS Status;\r
771 HII_THUNK_PRIVATE_DATA *Private;\r
772 HII_THUNK_CONTEXT *ThunkContext;\r
773\r
774 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS || PackageType == EFI_HII_PACKAGE_FORMS);\r
775 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
776\r
777 Status = EFI_SUCCESS;\r
778 Private = mHiiThunkPrivateData;\r
779\r
780 if (mInFrameworkHiiNewPack || mInFrameworkUpdatePakcage) {\r
781 return EFI_SUCCESS;\r
782 }\r
783\r
784 //\r
785 // We will create a ThunkContext to log the package list only if the\r
786 // package is not registered with by Framework HII Thunk module yet.\r
787 //\r
788 ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
789 if (ThunkContext == NULL) {\r
790 ThunkContext = CreateThunkContextForUefiHiiHandle (Handle);\r
791 ASSERT (ThunkContext != NULL);\r
792\r
793 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
794 } \r
795\r
796 if (PackageType == EFI_HII_PACKAGE_FORMS) {\r
797 if (ThunkContext->FormSet != NULL) {\r
798 DestroyFormSet (ThunkContext->FormSet);\r
799 }\r
800\r
801 //\r
802 // Reparse the FormSet.\r
803 //\r
804 ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
805 }\r
806\r
807 return Status; \r
808}\r
809\r
810/**\r
811 This notification function will be called when a Package List is removed\r
812 using UEFI HII interface. The Package List removed need to be removed from\r
813 Framework Thunk module too.\r
814\r
815 If the Package List registered is not Sting Package, \r
816 then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.\r
817 Both cases means UEFI HII Database itself is buggy. \r
818\r
819 @param PackageType The Package Type.\r
820 @param PackageGuid The Package GUID.\r
821 @param Package The Package Header.\r
822 @param Handle The HII Handle of this Package List.\r
823 @param NotifyType The reason of the notification. \r
824\r
825 @retval EFI_SUCCESS The notification function is successful.\r
826 \r
827**/\r
828EFI_STATUS\r
829EFIAPI\r
830RemovePackNotify (\r
831 IN UINT8 PackageType,\r
832 IN CONST EFI_GUID *PackageGuid,\r
833 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
834 IN EFI_HII_HANDLE Handle,\r
835 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
836 )\r
837{\r
838 EFI_STATUS Status;\r
839 HII_THUNK_PRIVATE_DATA *Private;\r
840 HII_THUNK_CONTEXT *ThunkContext;\r
841 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
842 UINTN BufferSize;\r
843\r
844 Status = EFI_SUCCESS;\r
845\r
846 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
847 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);\r
848\r
849 if (mInFrameworkHiiRemovePack || mInFrameworkUpdatePakcage) {\r
850 return EFI_SUCCESS;\r
851 }\r
852\r
853 Private = mHiiThunkPrivateData;\r
854\r
855 ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
856\r
857 //\r
858 // BugBug: Change to ASSERT if HII Database fix the bug and to also invoke \r
859 // NEW_PACK_NOTIFY for package (String Package) created internally.\r
860 //\r
861 if (ThunkContext != NULL) {\r
862 if (!ThunkContext->ByFrameworkHiiNewPack) {\r
863 Status = ExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
864 ASSERT_EFI_ERROR (Status);\r
865\r
866 if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {\r
867 //\r
868 // If the string package will be removed is the last string package\r
869 // in the package list, we will remove the HII Thunk entry from the\r
870 // database.\r
871 //\r
872 DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
873 }\r
874\r
875 FreePool (HiiPackageList);\r
876 }\r
877 }\r
878\r
879 \r
880 return Status;\r
881}\r
882\r
883\r
884\r