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