]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Database.c
15
16 Abstract:
17
18 Implementation for EFI_HII_DATABASE_PROTOCOL.
19
20 Revision History
21
22
23 **/
24
25
26 #include "HiiDatabase.h"
27
28 //
29 // Global variables
30 //
31 STATIC EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;
32
33
34 /**
35 This function generates a HII_DATABASE_RECORD node and adds into hii database.
36
37 @param Private hii database private structure
38 @param DatabaseRecord HII_DATABASE_RECORD node which is used to store a
39 package list
40
41 @retval EFI_SUCCESS A database record is generated successfully.
42 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
43 database contents.
44 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.
45
46 **/
47 STATIC
48 EFI_STATUS
49 GenerateHiiDatabaseRecord (
50 IN HII_DATABASE_PRIVATE_DATA *Private,
51 OUT HII_DATABASE_RECORD **DatabaseNode
52 )
53 {
54 HII_DATABASE_RECORD *DatabaseRecord;
55 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
56 HII_HANDLE *HiiHandle;
57
58 if (Private == NULL || DatabaseNode == NULL) {
59 return EFI_INVALID_PARAMETER;
60 }
61
62 DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD));
63 if (DatabaseRecord == NULL) {
64 return EFI_OUT_OF_RESOURCES;
65 }
66 DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;
67
68 DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));
69 if (DatabaseRecord->PackageList == NULL) {
70 SafeFreePool (DatabaseRecord);
71 return EFI_OUT_OF_RESOURCES;
72 }
73
74 PackageList = DatabaseRecord->PackageList;
75
76 InitializeListHead (&PackageList->GuidPkgHdr);
77 InitializeListHead (&PackageList->FormPkgHdr);
78 InitializeListHead (&PackageList->KeyboardLayoutHdr);
79 InitializeListHead (&PackageList->StringPkgHdr);
80 InitializeListHead (&PackageList->FontPkgHdr);
81 InitializeListHead (&PackageList->SimpleFontPkgHdr);
82 PackageList->ImagePkg = NULL;
83 PackageList->DevicePathPkg = NULL;
84
85 //
86 // Create a new hii handle
87 //
88 HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));
89 if (HiiHandle == NULL) {
90 SafeFreePool (DatabaseRecord->PackageList);
91 SafeFreePool (DatabaseRecord);
92 return EFI_OUT_OF_RESOURCES;
93 }
94 HiiHandle->Signature = HII_HANDLE_SIGNATURE;
95 //
96 // Backup the number of Hii handles
97 //
98 Private->HiiHandleCount++;
99 HiiHandle->Key = Private->HiiHandleCount;
100 //
101 // Insert the handle to hii handle list of the whole database.
102 //
103 InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);
104
105 DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle;
106
107 //
108 // Insert the Package List node to Package List link of the whole database.
109 //
110 InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);
111
112 *DatabaseNode = DatabaseRecord;
113
114 return EFI_SUCCESS;
115
116 }
117
118
119 /**
120 This function checks whether a handle is a valid EFI_HII_HANDLE
121
122 @param Handle Pointer to a EFI_HII_HANDLE
123
124 @retval TRUE Valid
125 @retval FALSE Invalid
126
127 **/
128 BOOLEAN
129 IsHiiHandleValid (
130 EFI_HII_HANDLE Handle
131 )
132 {
133 HII_HANDLE *HiiHandle;
134
135 HiiHandle = (HII_HANDLE *) Handle;
136
137 if (HiiHandle == NULL) {
138 return FALSE;
139 }
140
141 if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {
142 return FALSE;
143 }
144
145 return TRUE;
146 }
147
148
149 /**
150 This function invokes the matching registered function.
151
152 @param Private HII Database driver private structure.
153 @param NotifyType The type of change concerning the database.
154 @param PackageInstance Points to the package referred to by the
155 notification.
156 @param PackageType Package type
157 @param Handle The handle of the package list which contains the
158 specified package.
159
160 @retval EFI_SUCCESS Already checked all registered function and
161 invoked if matched.
162 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
163
164 **/
165 STATIC
166 EFI_STATUS
167 InvokeRegisteredFunction (
168 IN HII_DATABASE_PRIVATE_DATA *Private,
169 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
170 IN VOID *PackageInstance,
171 IN UINT8 PackageType,
172 IN EFI_HII_HANDLE Handle
173 )
174 {
175 HII_DATABASE_NOTIFY *Notify;
176 LIST_ENTRY *Link;
177 EFI_HII_PACKAGE_HEADER *Package;
178 UINT8 *Buffer;
179 UINT32 BufferSize;
180 UINT32 HeaderSize;
181 UINT32 ImageBlockSize;
182 UINT32 PaletteInfoSize;
183
184 if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) {
185 return EFI_INVALID_PARAMETER;
186 }
187 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
188 return EFI_INVALID_PARAMETER;
189 }
190 if (!IsHiiHandleValid (Handle)) {
191 return EFI_INVALID_PARAMETER;
192 }
193
194 Buffer = NULL;
195 Package = NULL;
196
197 //
198 // Convert the incoming package from hii database storage format to UEFI
199 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.
200 //
201 switch (PackageType) {
202 case EFI_HII_PACKAGE_TYPE_GUID:
203 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);
204 break;
205
206 case EFI_HII_PACKAGE_FORM:
207 BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;
208 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
209 ASSERT (Buffer != NULL);
210 CopyMem (
211 Buffer,
212 &((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr,
213 sizeof (EFI_HII_PACKAGE_HEADER)
214 );
215 CopyMem (
216 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
217 ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData,
218 BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)
219 );
220 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
221 break;
222
223 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
224 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg);
225 break;
226
227 case EFI_HII_PACKAGE_STRINGS:
228 BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length;
229 HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize;
230 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
231 ASSERT (Buffer != NULL);
232 CopyMem (
233 Buffer,
234 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr,
235 HeaderSize
236 );
237 CopyMem (
238 Buffer + HeaderSize,
239 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock,
240 BufferSize - HeaderSize
241 );
242 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
243 break;
244
245 case EFI_HII_PACKAGE_FONTS:
246 BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length;
247 HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize;
248 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
249 ASSERT (Buffer != NULL);
250 CopyMem (
251 Buffer,
252 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr,
253 HeaderSize
254 );
255 CopyMem (
256 Buffer + HeaderSize,
257 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock,
258 BufferSize - HeaderSize
259 );
260 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
261 break;
262
263 case EFI_HII_PACKAGE_IMAGES:
264 BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length;
265 HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
266 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
267 ASSERT (Buffer != NULL);
268
269 CopyMem (
270 Buffer,
271 &((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr,
272 HeaderSize
273 );
274 CopyMem (
275 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
276 &HeaderSize,
277 sizeof (UINT32)
278 );
279
280 ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize;
281 if (ImageBlockSize != 0) {
282 CopyMem (
283 Buffer + HeaderSize,
284 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock,
285 ImageBlockSize
286 );
287 }
288
289 PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize;
290 if (PaletteInfoSize != 0) {
291 CopyMem (
292 Buffer + HeaderSize + ImageBlockSize,
293 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock,
294 PaletteInfoSize
295 );
296 HeaderSize += ImageBlockSize;
297 CopyMem (
298 Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),
299 &HeaderSize,
300 sizeof (UINT32)
301 );
302 }
303 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
304 break;
305
306 case EFI_HII_PACKAGE_SIMPLE_FONTS:
307 BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length;
308 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
309 ASSERT (Buffer != NULL);
310 CopyMem (
311 Buffer,
312 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr,
313 BufferSize
314 );
315 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
316 break;
317
318 case EFI_HII_PACKAGE_DEVICE_PATH:
319 Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance;
320 break;
321
322 default:
323 return EFI_INVALID_PARAMETER;
324 }
325
326 for (Link = Private->DatabaseNotifyList.ForwardLink;
327 Link != &Private->DatabaseNotifyList;
328 Link = Link->ForwardLink
329 ) {
330 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
331 if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) {
332 //
333 // Check in case PackageGuid is not NULL when Package is GUID package
334 //
335 if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {
336 Notify->PackageGuid = NULL;
337 }
338 //
339 // Status of Registered Function is unknown so did not check it
340 //
341 Notify->PackageNotifyFn (
342 Notify->PackageType,
343 Notify->PackageGuid,
344 Package,
345 Handle,
346 NotifyType
347 );
348 }
349 }
350
351 SafeFreePool (Buffer);
352 Buffer = NULL;
353
354 return EFI_SUCCESS;
355 }
356
357
358 /**
359 This function insert a GUID package to a package list node.
360
361 @param PackageHdr Pointer to a buffer stored with GUID package
362 information.
363 @param NotifyType The type of change concerning the database.
364 @param PackageList Pointer to a package list which will be inserted
365 to.
366 @param Package Created GUID pacakge
367
368 @retval EFI_SUCCESS Guid Package is inserted successfully.
369 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
370 Guid package.
371 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
372
373 **/
374 STATIC
375 EFI_STATUS
376 InsertGuidPackage (
377 IN VOID *PackageHdr,
378 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
379 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
380 OUT HII_GUID_PACKAGE_INSTANCE **Package
381 )
382 {
383 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
384 EFI_HII_PACKAGE_HEADER PackageHeader;
385
386 if (PackageHdr == NULL || PackageList == NULL) {
387 return EFI_INVALID_PARAMETER;
388 }
389
390 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
391
392 //
393 // Create a GUID package node
394 //
395 GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));
396 if (GuidPackage == NULL) {
397 return EFI_OUT_OF_RESOURCES;
398 }
399 GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
400 if (GuidPackage->GuidPkg == NULL) {
401 SafeFreePool (GuidPackage);
402 return EFI_OUT_OF_RESOURCES;
403 }
404
405 GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;
406 CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);
407 InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);
408 *Package = GuidPackage;
409
410 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
411 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
412 }
413
414 return EFI_SUCCESS;
415 }
416
417
418 /**
419 This function exports GUID packages to a buffer.
420
421 @param Private Hii database private structure.
422 @param Handle Identification of a package list.
423 @param PackageList Pointer to a package list which will be exported.
424 @param UsedSize The length of buffer be used.
425 @param BufferSize Length of the Buffer.
426 @param Buffer Allocated space for storing exported data.
427 @param ResultSize The size of the already exported content of this
428 package list.
429
430 @retval EFI_SUCCESS Guid Packages are exported successfully.
431 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
432
433 **/
434 STATIC
435 EFI_STATUS
436 ExportGuidPackages (
437 IN HII_DATABASE_PRIVATE_DATA *Private,
438 IN EFI_HII_HANDLE Handle,
439 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
440 IN UINTN UsedSize,
441 IN UINTN BufferSize,
442 IN OUT VOID *Buffer,
443 IN OUT UINTN *ResultSize
444 )
445 {
446 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
447 LIST_ENTRY *Link;
448 UINTN PackageLength;
449 EFI_HII_PACKAGE_HEADER PackageHeader;
450 EFI_STATUS Status;
451
452 if (PackageList == NULL || ResultSize == NULL) {
453 return EFI_INVALID_PARAMETER;
454 }
455
456 if (BufferSize > 0 && Buffer == NULL ) {
457 return EFI_INVALID_PARAMETER;
458 }
459
460 PackageLength = 0;
461 Status = EFI_SUCCESS;
462
463 for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {
464 GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
465 CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
466 PackageLength += PackageHeader.Length;
467 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
468 Status = InvokeRegisteredFunction (
469 Private,
470 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
471 (VOID *) GuidPackage,
472 EFI_HII_PACKAGE_TYPE_GUID,
473 Handle
474 );
475 ASSERT_EFI_ERROR (Status);
476 CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);
477 Buffer = (UINT8 *) Buffer + PackageHeader.Length;
478 }
479 }
480
481 *ResultSize += PackageLength;
482 return EFI_SUCCESS;
483 }
484
485
486 /**
487 This function deletes all GUID packages from a package list node.
488
489 @param Private Hii database private data.
490 @param Handle Handle of the package list which contains the to
491 be removed GUID packages.
492 @param PackageList Pointer to a package list that contains removing
493 packages.
494
495 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.
496 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
497
498 **/
499 STATIC
500 EFI_STATUS
501 RemoveGuidPackages (
502 IN HII_DATABASE_PRIVATE_DATA *Private,
503 IN EFI_HII_HANDLE Handle,
504 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
505 )
506 {
507 LIST_ENTRY *ListHead;
508 HII_GUID_PACKAGE_INSTANCE *Package;
509 EFI_STATUS Status;
510 EFI_HII_PACKAGE_HEADER PackageHeader;
511
512 ListHead = &PackageList->GuidPkgHdr;
513
514 while (!IsListEmpty (ListHead)) {
515 Package = CR (
516 ListHead->ForwardLink,
517 HII_GUID_PACKAGE_INSTANCE,
518 GuidEntry,
519 HII_GUID_PACKAGE_SIGNATURE
520 );
521 Status = InvokeRegisteredFunction (
522 Private,
523 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
524 (VOID *) Package,
525 EFI_HII_PACKAGE_TYPE_GUID,
526 Handle
527 );
528 if (EFI_ERROR (Status)) {
529 return Status;
530 }
531
532 RemoveEntryList (&Package->GuidEntry);
533 CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
534 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
535 SafeFreePool (Package->GuidPkg);
536 SafeFreePool (Package);
537 }
538
539 return EFI_SUCCESS;
540 }
541
542
543 /**
544 This function insert a Form package to a package list node.
545
546 @param PackageHdr Pointer to a buffer stored with Form package
547 information.
548 @param NotifyType The type of change concerning the database.
549 @param PackageList Pointer to a package list which will be inserted
550 to.
551 @param Package Created Form package
552
553 @retval EFI_SUCCESS Form Package is inserted successfully.
554 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
555 Form package.
556 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
557
558 **/
559 STATIC
560 EFI_STATUS
561 InsertFormPackage (
562 IN VOID *PackageHdr,
563 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
564 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
565 OUT HII_IFR_PACKAGE_INSTANCE **Package
566 )
567 {
568 HII_IFR_PACKAGE_INSTANCE *FormPackage;
569 EFI_HII_PACKAGE_HEADER PackageHeader;
570
571 if (PackageHdr == NULL || PackageList == NULL) {
572 return EFI_INVALID_PARAMETER;
573 }
574
575 //
576 // Get the length of the package, including package header itself
577 //
578 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
579
580 //
581 // Create a Form package node
582 //
583 FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));
584 if (FormPackage == NULL) {
585 return EFI_OUT_OF_RESOURCES;
586 }
587
588 FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));
589 if (FormPackage->IfrData == NULL) {
590 SafeFreePool (FormPackage);
591 return EFI_OUT_OF_RESOURCES;
592 }
593
594 FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;
595 //
596 // Copy Package Header
597 //
598 CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
599
600 //
601 // Copy Ifr contents
602 //
603 CopyMem (
604 FormPackage->IfrData,
605 (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),
606 PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)
607 );
608
609 InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);
610 *Package = FormPackage;
611
612 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
613 PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;
614 }
615 return EFI_SUCCESS;
616 }
617
618
619 /**
620 This function exports Form packages to a buffer.
621
622 @param Private Hii database private structure.
623 @param Handle Identification of a package list.
624 @param PackageList Pointer to a package list which will be exported.
625 @param UsedSize The length of buffer be used.
626 @param BufferSize Length of the Buffer.
627 @param Buffer Allocated space for storing exported data.
628 @param ResultSize The size of the already exported content of this
629 package list.
630
631 @retval EFI_SUCCESS Form Packages are exported successfully.
632 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
633
634 **/
635 STATIC
636 EFI_STATUS
637 ExportFormPackages (
638 IN HII_DATABASE_PRIVATE_DATA *Private,
639 IN EFI_HII_HANDLE Handle,
640 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
641 IN UINTN UsedSize,
642 IN UINTN BufferSize,
643 IN OUT VOID *Buffer,
644 IN OUT UINTN *ResultSize
645 )
646 {
647 HII_IFR_PACKAGE_INSTANCE *FormPackage;
648 UINTN PackageLength;
649 LIST_ENTRY *Link;
650 EFI_STATUS Status;
651
652 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
653 return EFI_INVALID_PARAMETER;
654 }
655
656 if (BufferSize > 0 && Buffer == NULL ) {
657 return EFI_INVALID_PARAMETER;
658 }
659
660 PackageLength = 0;
661 Status = EFI_SUCCESS;
662
663 //
664 // Export Form packages.
665 //
666 for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {
667 FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);
668 PackageLength += FormPackage->FormPkgHdr.Length;
669 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
670 //
671 // Invoke registered notification if exists
672 //
673 Status = InvokeRegisteredFunction (
674 Private,
675 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
676 (VOID *) FormPackage,
677 EFI_HII_PACKAGE_FORM,
678 Handle
679 );
680 ASSERT_EFI_ERROR (Status);
681 //
682 // Copy the Form package content.
683 //
684 CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));
685 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER);
686 CopyMem (
687 Buffer,
688 (VOID *) FormPackage->IfrData,
689 FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)
690 );
691 Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
692 }
693 }
694
695 *ResultSize += PackageLength;
696
697 return EFI_SUCCESS;
698
699 }
700
701
702 /**
703 This function deletes all Form packages from a package list node.
704
705 @param Private Hii database private data.
706 @param Handle Handle of the package list which contains the to
707 be removed Form packages.
708 @param PackageList Pointer to a package list that contains removing
709 packages.
710
711 @retval EFI_SUCCESS Form Package(s) is deleted successfully.
712 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
713
714 **/
715 STATIC
716 EFI_STATUS
717 RemoveFormPackages (
718 IN HII_DATABASE_PRIVATE_DATA *Private,
719 IN EFI_HII_HANDLE Handle,
720 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
721 )
722 {
723 LIST_ENTRY *ListHead;
724 HII_IFR_PACKAGE_INSTANCE *Package;
725 EFI_STATUS Status;
726
727 ListHead = &PackageList->FormPkgHdr;
728
729 while (!IsListEmpty (ListHead)) {
730 Package = CR (
731 ListHead->ForwardLink,
732 HII_IFR_PACKAGE_INSTANCE,
733 IfrEntry,
734 HII_IFR_PACKAGE_SIGNATURE
735 );
736 Status = InvokeRegisteredFunction (
737 Private,
738 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
739 (VOID *) Package,
740 EFI_HII_PACKAGE_FORM,
741 Handle
742 );
743 if (EFI_ERROR (Status)) {
744 return Status;
745 }
746
747 RemoveEntryList (&Package->IfrEntry);
748 PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;
749 SafeFreePool (Package->IfrData);
750 SafeFreePool (Package);
751
752 }
753
754 return EFI_SUCCESS;
755 }
756
757
758
759 /**
760 This function insert a String package to a package list node.
761
762 @param Private Hii database private structure.
763 @param PackageHdr Pointer to a buffer stored with String package
764 information.
765 @param NotifyType The type of change concerning the database.
766 @param PackageList Pointer to a package list which will be inserted
767 to.
768 @param Package Created String package
769
770 @retval EFI_SUCCESS String Package is inserted successfully.
771 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
772 String package.
773 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
774 @retval EFI_UNSUPPORTED A string package with the same language already
775 exists in current package list.
776
777 **/
778 STATIC
779 EFI_STATUS
780 InsertStringPackage (
781 IN HII_DATABASE_PRIVATE_DATA *Private,
782 IN VOID *PackageHdr,
783 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
784 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
785 OUT HII_STRING_PACKAGE_INSTANCE **Package
786
787 )
788 {
789 HII_STRING_PACKAGE_INSTANCE *StringPackage;
790 UINT32 HeaderSize;
791 EFI_STATUS Status;
792 EFI_HII_PACKAGE_HEADER PackageHeader;
793 CHAR8 *Language;
794 UINT32 LanguageSize;
795 LIST_ENTRY *Link;
796
797 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
798 return EFI_INVALID_PARAMETER;
799 }
800 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
801 return EFI_INVALID_PARAMETER;
802 }
803
804 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
805 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
806
807 //
808 // It is illegal to have two string packages with same language within one packagelist
809 // since the stringid will be duplicate if so. Check it to avoid this potential issue.
810 //
811 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);
812 Language = (CHAR8 *) AllocateZeroPool (LanguageSize);
813 if (Language == NULL) {
814 return EFI_OUT_OF_RESOURCES;
815 }
816 AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);
817 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
818 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
819 if (R8_EfiLibCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {
820 SafeFreePool (Language);
821 return EFI_UNSUPPORTED;
822 }
823 }
824 SafeFreePool (Language);
825
826 //
827 // Create a String package node
828 //
829 StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
830 if (StringPackage == NULL) {
831 Status = EFI_OUT_OF_RESOURCES;
832 goto Error;
833 }
834
835 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
836 if (StringPackage->StringPkgHdr == NULL) {
837 Status = EFI_OUT_OF_RESOURCES;
838 goto Error;
839 }
840
841 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
842 if (StringPackage->StringBlock == NULL) {
843 Status = EFI_OUT_OF_RESOURCES;
844 goto Error;
845 }
846
847 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
848 StringPackage->FontId = 0;
849 InitializeListHead (&StringPackage->FontInfoList);
850
851 //
852 // Copy the String package header.
853 //
854 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);
855
856 //
857 // Copy the String blocks
858 //
859 CopyMem (
860 StringPackage->StringBlock,
861 (UINT8 *) PackageHdr + HeaderSize,
862 PackageHeader.Length - HeaderSize
863 );
864
865 //
866 // Collect all font block info
867 //
868 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL);
869 if (EFI_ERROR (Status)) {
870 return Status;
871 }
872
873 //
874 // Insert to String package array
875 //
876 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);
877 *Package = StringPackage;
878
879 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
880 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
881 }
882
883 return EFI_SUCCESS;
884
885 Error:
886
887 SafeFreePool (StringPackage->StringBlock);
888 SafeFreePool (StringPackage->StringPkgHdr);
889 SafeFreePool (StringPackage);
890 return Status;
891
892 }
893
894
895 /**
896 This function exports String packages to a buffer.
897
898 @param Private Hii database private structure.
899 @param Handle Identification of a package list.
900 @param PackageList Pointer to a package list which will be exported.
901 @param UsedSize The length of buffer be used.
902 @param BufferSize Length of the Buffer.
903 @param Buffer Allocated space for storing exported data.
904 @param ResultSize The size of the already exported content of this
905 package list.
906
907 @retval EFI_SUCCESS String Packages are exported successfully.
908 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
909
910 **/
911 STATIC
912 EFI_STATUS
913 ExportStringPackages (
914 IN HII_DATABASE_PRIVATE_DATA *Private,
915 IN EFI_HII_HANDLE Handle,
916 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
917 IN UINTN UsedSize,
918 IN UINTN BufferSize,
919 IN OUT VOID *Buffer,
920 IN OUT UINTN *ResultSize
921 )
922 {
923 LIST_ENTRY *Link;
924 UINTN PackageLength;
925 EFI_STATUS Status;
926 HII_STRING_PACKAGE_INSTANCE *StringPackage;
927
928 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
929 return EFI_INVALID_PARAMETER;
930 }
931
932 if (BufferSize > 0 && Buffer == NULL ) {
933 return EFI_INVALID_PARAMETER;
934 }
935
936 PackageLength = 0;
937 Status = EFI_SUCCESS;
938
939 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
940 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
941 PackageLength += StringPackage->StringPkgHdr->Header.Length;
942 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
943 //
944 // Invoke registered notification function with EXPORT_PACK notify type
945 //
946 Status = InvokeRegisteredFunction (
947 Private,
948 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
949 (VOID *) StringPackage,
950 EFI_HII_PACKAGE_STRINGS,
951 Handle
952 );
953 ASSERT_EFI_ERROR (Status);
954 //
955 // Copy String package header
956 //
957 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);
958 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;
959
960 //
961 // Copy String blocks information
962 //
963 CopyMem (
964 Buffer,
965 StringPackage->StringBlock,
966 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize
967 );
968 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
969 }
970 }
971
972 *ResultSize += PackageLength;
973 return EFI_SUCCESS;
974 }
975
976
977 /**
978 This function deletes all String packages from a package list node.
979
980 @param Private Hii database private data.
981 @param Handle Handle of the package list which contains the to
982 be removed String packages.
983 @param PackageList Pointer to a package list that contains removing
984 packages.
985
986 @retval EFI_SUCCESS String Package(s) is deleted successfully.
987 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
988
989 **/
990 STATIC
991 EFI_STATUS
992 RemoveStringPackages (
993 IN HII_DATABASE_PRIVATE_DATA *Private,
994 IN EFI_HII_HANDLE Handle,
995 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
996 )
997 {
998 LIST_ENTRY *ListHead;
999 HII_STRING_PACKAGE_INSTANCE *Package;
1000 HII_FONT_INFO *FontInfo;
1001 EFI_STATUS Status;
1002
1003 ListHead = &PackageList->StringPkgHdr;
1004
1005 while (!IsListEmpty (ListHead)) {
1006 Package = CR (
1007 ListHead->ForwardLink,
1008 HII_STRING_PACKAGE_INSTANCE,
1009 StringEntry,
1010 HII_STRING_PACKAGE_SIGNATURE
1011 );
1012 Status = InvokeRegisteredFunction (
1013 Private,
1014 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1015 (VOID *) Package,
1016 EFI_HII_PACKAGE_STRINGS,
1017 Handle
1018 );
1019 if (EFI_ERROR (Status)) {
1020 return Status;
1021 }
1022
1023 RemoveEntryList (&Package->StringEntry);
1024 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;
1025 SafeFreePool (Package->StringBlock);
1026 SafeFreePool (Package->StringPkgHdr);
1027 //
1028 // Delete font information
1029 //
1030 while (!IsListEmpty (&Package->FontInfoList)) {
1031 FontInfo = CR (
1032 Package->FontInfoList.ForwardLink,
1033 HII_FONT_INFO,
1034 Entry,
1035 HII_FONT_INFO_SIGNATURE
1036 );
1037 RemoveEntryList (&FontInfo->Entry);
1038 SafeFreePool (FontInfo);
1039 }
1040
1041 SafeFreePool (Package);
1042 }
1043
1044 return EFI_SUCCESS;
1045 }
1046
1047
1048 /**
1049 This function insert a Font package to a package list node.
1050
1051 @param Private Hii database private structure.
1052 @param PackageHdr Pointer to a buffer stored with Font package
1053 information.
1054 @param NotifyType The type of change concerning the database.
1055 @param PackageList Pointer to a package list which will be inserted
1056 to.
1057 @param Package Created Font package
1058
1059 @retval EFI_SUCCESS Font Package is inserted successfully.
1060 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1061 Font package.
1062 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1063 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already
1064 exists in current hii database.
1065
1066 **/
1067 STATIC
1068 EFI_STATUS
1069 InsertFontPackage (
1070 IN HII_DATABASE_PRIVATE_DATA *Private,
1071 IN VOID *PackageHdr,
1072 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1073 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1074 OUT HII_FONT_PACKAGE_INSTANCE **Package
1075 )
1076 {
1077 HII_FONT_PACKAGE_INSTANCE *FontPackage;
1078 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;
1079 UINT32 HeaderSize;
1080 EFI_STATUS Status;
1081 EFI_HII_PACKAGE_HEADER PackageHeader;
1082 EFI_FONT_INFO *FontInfo;
1083 UINT32 FontInfoSize;
1084 HII_GLOBAL_FONT_INFO *GlobalFont;
1085
1086 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
1087 return EFI_INVALID_PARAMETER;
1088 }
1089
1090 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
1091 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
1092
1093 FontInfo = NULL;
1094 FontPackage = NULL;
1095 GlobalFont = NULL;
1096
1097 //
1098 // It is illegal to have two font packages with same EFI_FONT_INFO within hii
1099 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
1100 // attributes and identify a font uniquely.
1101 //
1102 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
1103 if (FontPkgHdr == NULL) {
1104 Status = EFI_OUT_OF_RESOURCES;
1105 goto Error;
1106 }
1107 CopyMem (FontPkgHdr, PackageHdr, HeaderSize);
1108
1109 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);
1110 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);
1111 if (FontInfo == NULL) {
1112 Status = EFI_OUT_OF_RESOURCES;
1113 goto Error;
1114 }
1115 FontInfo->FontStyle = FontPkgHdr->FontStyle;
1116 FontInfo->FontSize = FontPkgHdr->Cell.Height;
1117 StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);
1118
1119 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {
1120 Status = EFI_UNSUPPORTED;
1121 goto Error;
1122 }
1123
1124 //
1125 // Create a Font package node
1126 //
1127 FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));
1128 if (FontPackage == NULL) {
1129 Status = EFI_OUT_OF_RESOURCES;
1130 goto Error;
1131 }
1132 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;
1133 FontPackage->FontPkgHdr = FontPkgHdr;
1134 InitializeListHead (&FontPackage->GlyphInfoList);
1135
1136 FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
1137 if (FontPackage->GlyphBlock == NULL) {
1138 Status = EFI_OUT_OF_RESOURCES;
1139 goto Error;
1140 }
1141 CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);
1142
1143 //
1144 // Collect all default character cell information and backup in GlyphInfoList.
1145 //
1146 Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);
1147 if (EFI_ERROR (Status)) {
1148 goto Error;
1149 }
1150
1151 //
1152 // This font package describes an unique EFI_FONT_INFO. Backup it in global
1153 // font info list.
1154 //
1155 GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));
1156 if (GlobalFont == NULL) {
1157 Status = EFI_OUT_OF_RESOURCES;
1158 goto Error;
1159 }
1160 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;
1161 GlobalFont->FontPackage = FontPackage;
1162 GlobalFont->FontInfoSize = FontInfoSize;
1163 GlobalFont->FontInfo = FontInfo;
1164 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);
1165
1166 //
1167 // Insert this font package to Font package array
1168 //
1169 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);
1170 *Package = FontPackage;
1171
1172 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1173 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;
1174 }
1175
1176 return EFI_SUCCESS;
1177
1178 Error:
1179
1180 SafeFreePool (FontPkgHdr);
1181 SafeFreePool (FontInfo);
1182 SafeFreePool (FontPackage->GlyphBlock);
1183 SafeFreePool (FontPackage);
1184 SafeFreePool (GlobalFont);
1185
1186 return Status;
1187
1188 }
1189
1190
1191 /**
1192 This function exports Font packages to a buffer.
1193
1194 @param Private Hii database private structure.
1195 @param Handle Identification of a package list.
1196 @param PackageList Pointer to a package list which will be exported.
1197 @param UsedSize The length of buffer be used.
1198 @param BufferSize Length of the Buffer.
1199 @param Buffer Allocated space for storing exported data.
1200 @param ResultSize The size of the already exported content of this
1201 package list.
1202
1203 @retval EFI_SUCCESS Font Packages are exported successfully.
1204 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1205
1206 **/
1207 STATIC
1208 EFI_STATUS
1209 ExportFontPackages (
1210 IN HII_DATABASE_PRIVATE_DATA *Private,
1211 IN EFI_HII_HANDLE Handle,
1212 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1213 IN UINTN UsedSize,
1214 IN UINTN BufferSize,
1215 IN OUT VOID *Buffer,
1216 IN OUT UINTN *ResultSize
1217 )
1218 {
1219 LIST_ENTRY *Link;
1220 UINTN PackageLength;
1221 EFI_STATUS Status;
1222 HII_FONT_PACKAGE_INSTANCE *Package;
1223
1224
1225 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
1226 return EFI_INVALID_PARAMETER;
1227 }
1228
1229 if (BufferSize > 0 && Buffer == NULL ) {
1230 return EFI_INVALID_PARAMETER;
1231 }
1232
1233 PackageLength = 0;
1234 Status = EFI_SUCCESS;
1235
1236 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {
1237 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);
1238 PackageLength += Package->FontPkgHdr->Header.Length;
1239 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
1240 //
1241 // Invoke registered notification function with EXPORT_PACK notify type
1242 //
1243 Status = InvokeRegisteredFunction (
1244 Private,
1245 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1246 (VOID *) Package,
1247 EFI_HII_PACKAGE_FONTS,
1248 Handle
1249 );
1250 ASSERT_EFI_ERROR (Status);
1251 //
1252 // Copy Font package header
1253 //
1254 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);
1255 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;
1256
1257 //
1258 // Copy Glyph blocks information
1259 //
1260 CopyMem (
1261 Buffer,
1262 Package->GlyphBlock,
1263 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize
1264 );
1265 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;
1266 }
1267 }
1268
1269 *ResultSize += PackageLength;
1270 return EFI_SUCCESS;
1271 }
1272
1273
1274 /**
1275 This function deletes all Font packages from a package list node.
1276
1277 @param Private Hii database private data.
1278 @param Handle Handle of the package list which contains the to
1279 be removed Font packages.
1280 @param PackageList Pointer to a package list that contains removing
1281 packages.
1282
1283 @retval EFI_SUCCESS Font Package(s) is deleted successfully.
1284 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1285
1286 **/
1287 STATIC
1288 EFI_STATUS
1289 RemoveFontPackages (
1290 IN HII_DATABASE_PRIVATE_DATA *Private,
1291 IN EFI_HII_HANDLE Handle,
1292 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1293 )
1294 {
1295 LIST_ENTRY *ListHead;
1296 HII_FONT_PACKAGE_INSTANCE *Package;
1297 EFI_STATUS Status;
1298 HII_GLYPH_INFO *GlyphInfo;
1299 LIST_ENTRY *Link;
1300 HII_GLOBAL_FONT_INFO *GlobalFont;
1301
1302 ListHead = &PackageList->FontPkgHdr;
1303
1304 while (!IsListEmpty (ListHead)) {
1305 Package = CR (
1306 ListHead->ForwardLink,
1307 HII_FONT_PACKAGE_INSTANCE,
1308 FontEntry,
1309 HII_FONT_PACKAGE_SIGNATURE
1310 );
1311 Status = InvokeRegisteredFunction (
1312 Private,
1313 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1314 (VOID *) Package,
1315 EFI_HII_PACKAGE_FONTS,
1316 Handle
1317 );
1318 if (EFI_ERROR (Status)) {
1319 return Status;
1320 }
1321
1322 RemoveEntryList (&Package->FontEntry);
1323 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;
1324 SafeFreePool (Package->GlyphBlock);
1325 SafeFreePool (Package->FontPkgHdr);
1326 //
1327 // Delete default character cell information
1328 //
1329 while (!IsListEmpty (&Package->GlyphInfoList)) {
1330 GlyphInfo = CR (
1331 Package->GlyphInfoList.ForwardLink,
1332 HII_GLYPH_INFO,
1333 Entry,
1334 HII_GLYPH_INFO_SIGNATURE
1335 );
1336 RemoveEntryList (&GlyphInfo->Entry);
1337 SafeFreePool (GlyphInfo);
1338 }
1339
1340 //
1341 // Remove corresponding global font info
1342 //
1343 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
1344 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
1345 if (GlobalFont->FontPackage == Package) {
1346 RemoveEntryList (&GlobalFont->Entry);
1347 SafeFreePool (GlobalFont->FontInfo);
1348 SafeFreePool (GlobalFont);
1349 break;
1350 }
1351 }
1352
1353 SafeFreePool (Package);
1354 }
1355
1356 return EFI_SUCCESS;
1357 }
1358
1359
1360 /**
1361 This function insert a Image package to a package list node.
1362
1363 @param PackageHdr Pointer to a buffer stored with Image package
1364 information.
1365 @param NotifyType The type of change concerning the database.
1366 @param PackageList Pointer to a package list which will be inserted
1367 to.
1368 @param Package Created Image package
1369
1370 @retval EFI_SUCCESS Image Package is inserted successfully.
1371 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1372 Image package.
1373 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1374
1375 **/
1376 STATIC
1377 EFI_STATUS
1378 InsertImagePackage (
1379 IN VOID *PackageHdr,
1380 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1381 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1382 OUT HII_IMAGE_PACKAGE_INSTANCE **Package
1383 )
1384 {
1385 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
1386 UINT32 PaletteSize;
1387 UINT32 ImageSize;
1388 UINT16 Index;
1389 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;
1390 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;
1391 UINT32 PaletteInfoOffset;
1392 UINT32 ImageInfoOffset;
1393 UINT16 CurrentSize;
1394
1395 if (PackageHdr == NULL || PackageList == NULL) {
1396 return EFI_INVALID_PARAMETER;
1397 }
1398
1399 //
1400 // Less than one image package is allowed in one package list.
1401 //
1402 if (PackageList->ImagePkg != NULL) {
1403 return EFI_INVALID_PARAMETER;
1404 }
1405
1406 //
1407 // Create a Image package node
1408 //
1409 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
1410 if (ImagePackage == NULL) {
1411 return EFI_OUT_OF_RESOURCES;
1412 }
1413
1414 //
1415 // Copy the Image package header.
1416 //
1417 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
1418
1419 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;
1420 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;
1421
1422 //
1423 // If PaletteInfoOffset is zero, there are no palettes in this image package.
1424 //
1425 PaletteSize = 0;
1426 ImagePackage->PaletteBlock = NULL;
1427 if (PaletteInfoOffset != 0) {
1428 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);
1429 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
1430 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);
1431
1432 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {
1433 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));
1434 CurrentSize += sizeof (UINT16);
1435 PaletteSize += (UINT32) CurrentSize;
1436 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);
1437 }
1438
1439 ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);
1440 if (ImagePackage->PaletteBlock == NULL) {
1441 SafeFreePool (ImagePackage);
1442 return EFI_OUT_OF_RESOURCES;
1443 }
1444 CopyMem (
1445 ImagePackage->PaletteBlock,
1446 (UINT8 *) PackageHdr + PaletteInfoOffset,
1447 PaletteSize
1448 );
1449 }
1450
1451 //
1452 // If ImageInfoOffset is zero, there are no images in this package.
1453 //
1454 ImageSize = 0;
1455 ImagePackage->ImageBlock = NULL;
1456 if (ImageInfoOffset != 0) {
1457 ImageSize = ImagePackage->ImagePkgHdr.Header.Length -
1458 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;
1459 ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);
1460 if (ImagePackage->ImageBlock == NULL) {
1461 SafeFreePool (ImagePackage->PaletteBlock);
1462 SafeFreePool (ImagePackage);
1463 return EFI_OUT_OF_RESOURCES;
1464 }
1465 CopyMem (
1466 ImagePackage->ImageBlock,
1467 (UINT8 *) PackageHdr + ImageInfoOffset,
1468 ImageSize
1469 );
1470 }
1471
1472 ImagePackage->ImageBlockSize = ImageSize;
1473 ImagePackage->PaletteInfoSize = PaletteSize;
1474 PackageList->ImagePkg = ImagePackage;
1475 *Package = ImagePackage;
1476
1477 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1478 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
1479 }
1480
1481 return EFI_SUCCESS;
1482 }
1483
1484
1485 /**
1486 This function exports Image packages to a buffer.
1487
1488 @param Private Hii database private structure.
1489 @param Handle Identification of a package list.
1490 @param PackageList Pointer to a package list which will be exported.
1491 @param UsedSize The length of buffer be used.
1492 @param BufferSize Length of the Buffer.
1493 @param Buffer Allocated space for storing exported data.
1494 @param ResultSize The size of the already exported content of this
1495 package list.
1496
1497 @retval EFI_SUCCESS Image Packages are exported successfully.
1498 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1499
1500 **/
1501 STATIC
1502 EFI_STATUS
1503 ExportImagePackages (
1504 IN HII_DATABASE_PRIVATE_DATA *Private,
1505 IN EFI_HII_HANDLE Handle,
1506 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1507 IN UINTN UsedSize,
1508 IN UINTN BufferSize,
1509 IN OUT VOID *Buffer,
1510 IN OUT UINTN *ResultSize
1511 )
1512 {
1513 UINTN PackageLength;
1514 EFI_STATUS Status;
1515 HII_IMAGE_PACKAGE_INSTANCE *Package;
1516
1517
1518 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
1519 return EFI_INVALID_PARAMETER;
1520 }
1521
1522 if (BufferSize > 0 && Buffer == NULL ) {
1523 return EFI_INVALID_PARAMETER;
1524 }
1525
1526 Package = PackageList->ImagePkg;
1527
1528 if (Package == NULL) {
1529 return EFI_SUCCESS;
1530 }
1531
1532 PackageLength = Package->ImagePkgHdr.Header.Length;
1533
1534 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
1535 //
1536 // Invoke registered notification function with EXPORT_PACK notify type
1537 //
1538 Status = InvokeRegisteredFunction (
1539 Private,
1540 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1541 (VOID *) Package,
1542 EFI_HII_PACKAGE_IMAGES,
1543 Handle
1544 );
1545 ASSERT_EFI_ERROR (Status);
1546 ASSERT (Package->ImagePkgHdr.Header.Length ==
1547 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);
1548 //
1549 // Copy Image package header,
1550 // then justify the offset for image info and palette info in the header.
1551 //
1552 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
1553 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
1554
1555 //
1556 // Copy Image blocks information
1557 //
1558 if (Package->ImageBlockSize != 0) {
1559 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);
1560 Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;
1561 }
1562 //
1563 // Copy Palette information
1564 //
1565 if (Package->PaletteInfoSize != 0) {
1566 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);
1567 Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;
1568 }
1569 }
1570
1571 *ResultSize += PackageLength;
1572 return EFI_SUCCESS;
1573 }
1574
1575
1576 /**
1577 This function deletes Image package from a package list node.
1578
1579 @param Private Hii database private data.
1580 @param Handle Handle of the package list which contains the to
1581 be removed Image packages.
1582 @param PackageList Package List which contains the to be removed
1583 Image package.
1584
1585 @retval EFI_SUCCESS Image Package(s) is deleted successfully.
1586 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1587
1588 **/
1589 STATIC
1590 EFI_STATUS
1591 RemoveImagePackages (
1592 IN HII_DATABASE_PRIVATE_DATA *Private,
1593 IN EFI_HII_HANDLE Handle,
1594 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1595 )
1596 {
1597 HII_IMAGE_PACKAGE_INSTANCE *Package;
1598 EFI_STATUS Status;
1599
1600 Package = PackageList->ImagePkg;
1601
1602 //
1603 // Image package does not exist, return directly.
1604 //
1605 if (Package == NULL) {
1606 return EFI_SUCCESS;
1607 }
1608
1609 Status = InvokeRegisteredFunction (
1610 Private,
1611 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1612 (VOID *) Package,
1613 EFI_HII_PACKAGE_IMAGES,
1614 Handle
1615 );
1616 if (EFI_ERROR (Status)) {
1617 return Status;
1618 }
1619
1620 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;
1621
1622 SafeFreePool (Package->ImageBlock);
1623 SafeFreePool (Package->PaletteBlock);
1624 SafeFreePool (Package);
1625
1626 PackageList->ImagePkg = NULL;
1627
1628 return EFI_SUCCESS;
1629 }
1630
1631
1632 /**
1633 This function insert a Simple Font package to a package list node.
1634
1635 @param PackageHdr Pointer to a buffer stored with Simple Font
1636 package information.
1637 @param NotifyType The type of change concerning the database.
1638 @param PackageList Pointer to a package list which will be inserted
1639 to.
1640 @param Package Created Simple Font package
1641
1642 @retval EFI_SUCCESS Simple Font Package is inserted successfully.
1643 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1644 Simple Font package.
1645 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1646
1647 **/
1648 STATIC
1649 EFI_STATUS
1650 InsertSimpleFontPackage (
1651 IN VOID *PackageHdr,
1652 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1653 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1654 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package
1655 )
1656 {
1657 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
1658 EFI_STATUS Status;
1659 EFI_HII_PACKAGE_HEADER Header;
1660
1661 if (PackageHdr == NULL || PackageList == NULL) {
1662 return EFI_INVALID_PARAMETER;
1663 }
1664
1665 //
1666 // Create a Simple Font package node
1667 //
1668 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));
1669 if (SimpleFontPackage == NULL) {
1670 Status = EFI_OUT_OF_RESOURCES;
1671 goto Error;
1672 }
1673 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;
1674
1675 //
1676 // Copy the Simple Font package.
1677 //
1678 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
1679
1680 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);
1681 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {
1682 Status = EFI_OUT_OF_RESOURCES;
1683 goto Error;
1684 }
1685
1686 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);
1687
1688 //
1689 // Insert to Simple Font package array
1690 //
1691 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);
1692 *Package = SimpleFontPackage;
1693
1694 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1695 PackageList->PackageListHdr.PackageLength += Header.Length;
1696 }
1697
1698 return EFI_SUCCESS;
1699
1700 Error:
1701
1702 SafeFreePool (SimpleFontPackage->SimpleFontPkgHdr);
1703 SafeFreePool (SimpleFontPackage);
1704 return Status;
1705 }
1706
1707
1708 /**
1709 This function exports SimpleFont packages to a buffer.
1710
1711 @param Private Hii database private structure.
1712 @param Handle Identification of a package list.
1713 @param PackageList Pointer to a package list which will be exported.
1714 @param UsedSize The length of buffer be used.
1715 @param BufferSize Length of the Buffer.
1716 @param Buffer Allocated space for storing exported data.
1717 @param ResultSize The size of the already exported content of this
1718 package list.
1719
1720 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.
1721 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1722
1723 **/
1724 STATIC
1725 EFI_STATUS
1726 ExportSimpleFontPackages (
1727 IN HII_DATABASE_PRIVATE_DATA *Private,
1728 IN EFI_HII_HANDLE Handle,
1729 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1730 IN UINTN UsedSize,
1731 IN UINTN BufferSize,
1732 IN OUT VOID *Buffer,
1733 IN OUT UINTN *ResultSize
1734 )
1735 {
1736 LIST_ENTRY *Link;
1737 UINTN PackageLength;
1738 EFI_STATUS Status;
1739 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
1740
1741 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
1742 return EFI_INVALID_PARAMETER;
1743 }
1744
1745 if (BufferSize > 0 && Buffer == NULL ) {
1746 return EFI_INVALID_PARAMETER;
1747 }
1748
1749 PackageLength = 0;
1750 Status = EFI_SUCCESS;
1751
1752 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {
1753 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
1754 PackageLength += Package->SimpleFontPkgHdr->Header.Length;
1755 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
1756 //
1757 // Invoke registered notification function with EXPORT_PACK notify type
1758 //
1759 Status = InvokeRegisteredFunction (
1760 Private,
1761 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1762 (VOID *) Package,
1763 EFI_HII_PACKAGE_SIMPLE_FONTS,
1764 Handle
1765 );
1766 ASSERT_EFI_ERROR (Status);
1767
1768 //
1769 // Copy SimpleFont package
1770 //
1771 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);
1772 Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;
1773 }
1774 }
1775
1776 *ResultSize += PackageLength;
1777 return EFI_SUCCESS;
1778 }
1779
1780
1781 /**
1782 This function deletes all Simple Font packages from a package list node.
1783
1784 @param Private Hii database private data.
1785 @param Handle Handle of the package list which contains the to
1786 be removed Simple Font packages.
1787 @param PackageList Pointer to a package list that contains removing
1788 packages.
1789
1790 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.
1791 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1792
1793 **/
1794 STATIC
1795 EFI_STATUS
1796 RemoveSimpleFontPackages (
1797 IN HII_DATABASE_PRIVATE_DATA *Private,
1798 IN EFI_HII_HANDLE Handle,
1799 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1800 )
1801 {
1802 LIST_ENTRY *ListHead;
1803 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
1804 EFI_STATUS Status;
1805
1806 ListHead = &PackageList->SimpleFontPkgHdr;
1807
1808 while (!IsListEmpty (ListHead)) {
1809 Package = CR (
1810 ListHead->ForwardLink,
1811 HII_SIMPLE_FONT_PACKAGE_INSTANCE,
1812 SimpleFontEntry,
1813 HII_S_FONT_PACKAGE_SIGNATURE
1814 );
1815 Status = InvokeRegisteredFunction (
1816 Private,
1817 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1818 (VOID *) Package,
1819 EFI_HII_PACKAGE_SIMPLE_FONTS,
1820 Handle
1821 );
1822 if (EFI_ERROR (Status)) {
1823 return Status;
1824 }
1825
1826 RemoveEntryList (&Package->SimpleFontEntry);
1827 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;
1828 SafeFreePool (Package->SimpleFontPkgHdr);
1829 SafeFreePool (Package);
1830 }
1831
1832 return EFI_SUCCESS;
1833 }
1834
1835
1836 /**
1837 This function insert a Device path package to a package list node.
1838
1839 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
1840 instance
1841 @param NotifyType The type of change concerning the database.
1842 @param PackageList Pointer to a package list which will be inserted
1843 to.
1844
1845 @retval EFI_SUCCESS Device path Package is inserted successfully.
1846 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1847 Device path package.
1848 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
1849
1850 **/
1851 STATIC
1852 EFI_STATUS
1853 InsertDevicePathPackage (
1854 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1855 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1856 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1857 )
1858 {
1859 UINT32 PackageLength;
1860 EFI_HII_PACKAGE_HEADER Header;
1861
1862 if (DevicePath == NULL || PackageList == NULL) {
1863 return EFI_INVALID_PARAMETER;
1864 }
1865 //
1866 // Less than one device path package is allowed in one package list.
1867 //
1868 if (PackageList->DevicePathPkg != NULL) {
1869 return EFI_INVALID_PARAMETER;
1870 }
1871
1872 PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);
1873 PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);
1874 if (PackageList->DevicePathPkg == NULL) {
1875 return EFI_OUT_OF_RESOURCES;
1876 }
1877
1878 Header.Length = PackageLength;
1879 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;
1880 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));
1881 CopyMem (
1882 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),
1883 DevicePath,
1884 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)
1885 );
1886
1887 //
1888 // Since Device Path package is created by NewPackageList, either NEW_PACK
1889 // or ADD_PACK should increase the length of package list.
1890 //
1891 PackageList->PackageListHdr.PackageLength += PackageLength;
1892 return EFI_SUCCESS;
1893 }
1894
1895
1896 /**
1897 This function exports device path package to a buffer.
1898
1899 @param Private Hii database private structure.
1900 @param Handle Identification of a package list.
1901 @param PackageList Pointer to a package list which will be exported.
1902 @param UsedSize The length of buffer be used.
1903 @param BufferSize Length of the Buffer.
1904 @param Buffer Allocated space for storing exported data.
1905 @param ResultSize The size of the already exported content of this
1906 package list.
1907
1908 @retval EFI_SUCCESS Device path Package is exported successfully.
1909 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1910
1911 **/
1912 STATIC
1913 EFI_STATUS
1914 ExportDevicePathPackage (
1915 IN HII_DATABASE_PRIVATE_DATA *Private,
1916 IN EFI_HII_HANDLE Handle,
1917 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1918 IN UINTN UsedSize,
1919 IN UINTN BufferSize,
1920 IN OUT VOID *Buffer,
1921 IN OUT UINTN *ResultSize
1922 )
1923 {
1924 EFI_STATUS Status;
1925 UINT8 *Package;
1926 EFI_HII_PACKAGE_HEADER Header;
1927
1928 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
1929 return EFI_INVALID_PARAMETER;
1930 }
1931 if (BufferSize > 0 && Buffer == NULL ) {
1932 return EFI_INVALID_PARAMETER;
1933 }
1934
1935 Package = PackageList->DevicePathPkg;
1936
1937 if (Package == NULL) {
1938 return EFI_SUCCESS;
1939 }
1940
1941 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
1942
1943 if (Header.Length + *ResultSize + UsedSize <= BufferSize) {
1944 //
1945 // Invoke registered notification function with EXPORT_PACK notify type
1946 //
1947 Status = InvokeRegisteredFunction (
1948 Private,
1949 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1950 (VOID *) Package,
1951 EFI_HII_PACKAGE_DEVICE_PATH,
1952 Handle
1953 );
1954 ASSERT_EFI_ERROR (Status);
1955
1956 //
1957 // Copy Device path package
1958 //
1959 CopyMem (Buffer, Package, Header.Length);
1960 }
1961
1962 *ResultSize += Header.Length;
1963 return EFI_SUCCESS;
1964 }
1965
1966
1967 /**
1968 This function deletes Device Path package from a package list node.
1969
1970 @param Private Hii database private data.
1971 @param Handle Handle of the package list.
1972 @param PackageList Package List which contains the to be removed
1973 Device Path package.
1974
1975 @retval EFI_SUCCESS Device Path Package is deleted successfully.
1976 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1977
1978 **/
1979 STATIC
1980 EFI_STATUS
1981 RemoveDevicePathPackage (
1982 IN HII_DATABASE_PRIVATE_DATA *Private,
1983 IN EFI_HII_HANDLE Handle,
1984 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1985 )
1986 {
1987 EFI_STATUS Status;
1988 UINT8 *Package;
1989 EFI_HII_PACKAGE_HEADER Header;
1990
1991 Package = PackageList->DevicePathPkg;
1992
1993 //
1994 // No device path, return directly.
1995 //
1996 if (Package == NULL) {
1997 return EFI_SUCCESS;
1998 }
1999
2000 Status = InvokeRegisteredFunction (
2001 Private,
2002 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2003 (VOID *) Package,
2004 EFI_HII_PACKAGE_DEVICE_PATH,
2005 Handle
2006 );
2007 if (EFI_ERROR (Status)) {
2008 return Status;
2009 }
2010
2011 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
2012 PackageList->PackageListHdr.PackageLength -= Header.Length;
2013
2014 SafeFreePool (Package);
2015
2016 PackageList->DevicePathPkg = NULL;
2017
2018 return EFI_SUCCESS;
2019 }
2020
2021
2022 /**
2023 This function will insert a device path package to package list firstly then
2024 invoke notification functions if any.
2025
2026 @param Private Hii database private structure.
2027 @param NotifyType The type of change concerning the database.
2028 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2029 instance
2030 @param DatabaseRecord Pointer to a database record contains a package
2031 list which will be inserted to.
2032
2033 @retval EFI_SUCCESS Device path Package is inserted successfully.
2034 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2035 Device path package.
2036 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2037
2038 **/
2039 STATIC
2040 EFI_STATUS
2041 AddDevicePathPackage (
2042 IN HII_DATABASE_PRIVATE_DATA *Private,
2043 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2044 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2045 IN OUT HII_DATABASE_RECORD *DatabaseRecord
2046 )
2047 {
2048 EFI_STATUS Status;
2049
2050 if (DevicePath == NULL) {
2051 return EFI_SUCCESS;
2052 }
2053
2054 ASSERT (Private != NULL);
2055 ASSERT (DatabaseRecord != NULL);
2056
2057 //
2058 // Create a device path package and insert to packagelist
2059 //
2060 Status = InsertDevicePathPackage (
2061 DevicePath,
2062 NotifyType,
2063 DatabaseRecord->PackageList
2064 );
2065 if (EFI_ERROR (Status)) {
2066 return Status;
2067 }
2068
2069 return InvokeRegisteredFunction (
2070 Private,
2071 NotifyType,
2072 (VOID *) DatabaseRecord->PackageList->DevicePathPkg,
2073 EFI_HII_PACKAGE_DEVICE_PATH,
2074 DatabaseRecord->Handle
2075 );
2076 }
2077
2078
2079 /**
2080 This function insert a Keyboard Layout package to a package list node.
2081
2082 @param PackageHdr Pointer to a buffer stored with Keyboard Layout
2083 package information.
2084 @param NotifyType The type of change concerning the database.
2085 @param PackageList Pointer to a package list which will be inserted
2086 to.
2087 @param Package Created Keyboard Layout package
2088
2089 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.
2090 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2091 Keyboard Layout package.
2092 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2093
2094 **/
2095 STATIC
2096 EFI_STATUS
2097 InsertKeyboardLayoutPackage (
2098 IN VOID *PackageHdr,
2099 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2100 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2101 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package
2102 )
2103 {
2104 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
2105 EFI_HII_PACKAGE_HEADER PackageHeader;
2106 EFI_STATUS Status;
2107
2108 if (PackageHdr == NULL || PackageList == NULL) {
2109 return EFI_INVALID_PARAMETER;
2110 }
2111
2112 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
2113
2114 //
2115 // Create a Keyboard Layout package node
2116 //
2117 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));
2118 if (KeyboardLayoutPackage == NULL) {
2119 Status = EFI_OUT_OF_RESOURCES;
2120 goto Error;
2121 }
2122 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;
2123
2124 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
2125 if (KeyboardLayoutPackage->KeyboardPkg == NULL) {
2126 Status = EFI_OUT_OF_RESOURCES;
2127 goto Error;
2128 }
2129
2130 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);
2131 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);
2132
2133 *Package = KeyboardLayoutPackage;
2134
2135 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2136 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
2137 }
2138
2139 return EFI_SUCCESS;
2140
2141 Error:
2142
2143 SafeFreePool (KeyboardLayoutPackage->KeyboardPkg);
2144 SafeFreePool (KeyboardLayoutPackage);
2145
2146 return Status;
2147 }
2148
2149
2150 /**
2151 This function exports Keyboard Layout packages to a buffer.
2152
2153 @param Private Hii database private structure.
2154 @param Handle Identification of a package list.
2155 @param PackageList Pointer to a package list which will be exported.
2156 @param UsedSize The length of buffer be used.
2157 @param BufferSize Length of the Buffer.
2158 @param Buffer Allocated space for storing exported data.
2159 @param ResultSize The size of the already exported content of this
2160 package list.
2161
2162 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2163 successfully.
2164 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2165
2166 **/
2167 STATIC
2168 EFI_STATUS
2169 ExportKeyboardLayoutPackages (
2170 IN HII_DATABASE_PRIVATE_DATA *Private,
2171 IN EFI_HII_HANDLE Handle,
2172 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2173 IN UINTN UsedSize,
2174 IN UINTN BufferSize,
2175 IN OUT VOID *Buffer,
2176 IN OUT UINTN *ResultSize
2177 )
2178 {
2179 LIST_ENTRY *Link;
2180 UINTN PackageLength;
2181 EFI_STATUS Status;
2182 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
2183 EFI_HII_PACKAGE_HEADER PackageHeader;
2184
2185 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
2186 return EFI_INVALID_PARAMETER;
2187 }
2188
2189 if (BufferSize > 0 && Buffer == NULL ) {
2190 return EFI_INVALID_PARAMETER;
2191 }
2192
2193 PackageLength = 0;
2194 Status = EFI_SUCCESS;
2195
2196 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {
2197 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);
2198 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
2199 PackageLength += PackageHeader.Length;
2200 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
2201 //
2202 // Invoke registered notification function with EXPORT_PACK notify type
2203 //
2204 Status = InvokeRegisteredFunction (
2205 Private,
2206 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
2207 (EFI_HII_PACKAGE_HEADER *) Package,
2208 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
2209 Handle
2210 );
2211 ASSERT_EFI_ERROR (Status);
2212
2213 //
2214 // Copy Keyboard Layout package
2215 //
2216 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);
2217 Buffer = (UINT8 *) Buffer + PackageHeader.Length;
2218 }
2219 }
2220
2221 *ResultSize += PackageLength;
2222 return EFI_SUCCESS;
2223 }
2224
2225
2226 /**
2227 This function deletes all Keyboard Layout packages from a package list node.
2228
2229 @param Private Hii database private data.
2230 @param Handle Handle of the package list which contains the to
2231 be removed Keyboard Layout packages.
2232 @param PackageList Pointer to a package list that contains removing
2233 packages.
2234
2235 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted
2236 successfully.
2237 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2238
2239 **/
2240 STATIC
2241 EFI_STATUS
2242 RemoveKeyboardLayoutPackages (
2243 IN HII_DATABASE_PRIVATE_DATA *Private,
2244 IN EFI_HII_HANDLE Handle,
2245 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2246 )
2247 {
2248 LIST_ENTRY *ListHead;
2249 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
2250 EFI_HII_PACKAGE_HEADER PackageHeader;
2251 EFI_STATUS Status;
2252
2253 ListHead = &PackageList->KeyboardLayoutHdr;
2254
2255 while (!IsListEmpty (ListHead)) {
2256 Package = CR (
2257 ListHead->ForwardLink,
2258 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
2259 KeyboardEntry,
2260 HII_KB_LAYOUT_PACKAGE_SIGNATURE
2261 );
2262 Status = InvokeRegisteredFunction (
2263 Private,
2264 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2265 (VOID *) Package,
2266 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
2267 Handle
2268 );
2269 if (EFI_ERROR (Status)) {
2270 return Status;
2271 }
2272
2273 RemoveEntryList (&Package->KeyboardEntry);
2274 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
2275 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
2276 SafeFreePool (Package->KeyboardPkg);
2277 SafeFreePool (Package);
2278 }
2279
2280 return EFI_SUCCESS;
2281 }
2282
2283
2284 /**
2285 This function will insert a package list to hii database firstly then
2286 invoke notification functions if any. It is the worker function of
2287 HiiNewPackageList and HiiUpdatePackageList.
2288
2289 @param Private Hii database private structure.
2290 @param NotifyType The type of change concerning the database.
2291 @param PackageList Pointer to a package list.
2292 @param DatabaseRecord Pointer to a database record contains a package
2293 list instance which will be inserted to.
2294
2295 @retval EFI_SUCCESS All incoming packages are inserted to current
2296 database.
2297 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2298 Device path package.
2299 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2300
2301 **/
2302 STATIC
2303 EFI_STATUS
2304 AddPackages (
2305 IN HII_DATABASE_PRIVATE_DATA *Private,
2306 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2307 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
2308 IN OUT HII_DATABASE_RECORD *DatabaseRecord
2309 )
2310 {
2311 EFI_STATUS Status;
2312 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
2313 HII_IFR_PACKAGE_INSTANCE *FormPackage;
2314 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
2315 HII_STRING_PACKAGE_INSTANCE *StringPackage;
2316 HII_FONT_PACKAGE_INSTANCE *FontPackage;
2317 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
2318 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
2319 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
2320 EFI_HII_PACKAGE_HEADER PackageHeader;
2321 UINT32 OldPackageListLen;
2322
2323 //
2324 // Process the package list header
2325 //
2326 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;
2327 CopyMem (
2328 &DatabaseRecord->PackageList->PackageListHdr,
2329 (VOID *) PackageList,
2330 sizeof (EFI_HII_PACKAGE_LIST_HEADER)
2331 );
2332 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2333 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;
2334 }
2335
2336 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
2337 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2338
2339 Status = EFI_SUCCESS;
2340
2341 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
2342 switch (PackageHeader.Type) {
2343 case EFI_HII_PACKAGE_TYPE_GUID:
2344 Status = InsertGuidPackage (
2345 PackageHdrPtr,
2346 NotifyType,
2347 DatabaseRecord->PackageList,
2348 &GuidPackage
2349 );
2350 if (EFI_ERROR (Status)) {
2351 return Status;
2352 }
2353 Status = InvokeRegisteredFunction (
2354 Private,
2355 NotifyType,
2356 (VOID *) GuidPackage,
2357 (UINT8) (PackageHeader.Type),
2358 DatabaseRecord->Handle
2359 );
2360 break;
2361 case EFI_HII_PACKAGE_FORM:
2362 Status = InsertFormPackage (
2363 PackageHdrPtr,
2364 NotifyType,
2365 DatabaseRecord->PackageList,
2366 &FormPackage
2367 );
2368 if (EFI_ERROR (Status)) {
2369 return Status;
2370 }
2371 Status = InvokeRegisteredFunction (
2372 Private,
2373 NotifyType,
2374 (VOID *) FormPackage,
2375 (UINT8) (PackageHeader.Type),
2376 DatabaseRecord->Handle
2377 );
2378 break;
2379 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
2380 Status = InsertKeyboardLayoutPackage (
2381 PackageHdrPtr,
2382 NotifyType,
2383 DatabaseRecord->PackageList,
2384 &KeyboardLayoutPackage
2385 );
2386 if (EFI_ERROR (Status)) {
2387 return Status;
2388 }
2389 Status = InvokeRegisteredFunction (
2390 Private,
2391 NotifyType,
2392 (VOID *) KeyboardLayoutPackage,
2393 (UINT8) (PackageHeader.Type),
2394 DatabaseRecord->Handle
2395 );
2396 break;
2397 case EFI_HII_PACKAGE_STRINGS:
2398 Status = InsertStringPackage (
2399 Private,
2400 PackageHdrPtr,
2401 NotifyType,
2402 DatabaseRecord->PackageList,
2403 &StringPackage
2404 );
2405 if (EFI_ERROR (Status)) {
2406 return Status;
2407 }
2408 Status = InvokeRegisteredFunction (
2409 Private,
2410 NotifyType,
2411 (VOID *) StringPackage,
2412 (UINT8) (PackageHeader.Type),
2413 DatabaseRecord->Handle
2414 );
2415 break;
2416 case EFI_HII_PACKAGE_FONTS:
2417 Status = InsertFontPackage (
2418 Private,
2419 PackageHdrPtr,
2420 NotifyType,
2421 DatabaseRecord->PackageList,
2422 &FontPackage
2423 );
2424 if (EFI_ERROR (Status)) {
2425 return Status;
2426 }
2427 Status = InvokeRegisteredFunction (
2428 Private,
2429 NotifyType,
2430 (VOID *) FontPackage,
2431 (UINT8) (PackageHeader.Type),
2432 DatabaseRecord->Handle
2433 );
2434 break;
2435 case EFI_HII_PACKAGE_IMAGES:
2436 Status = InsertImagePackage (
2437 PackageHdrPtr,
2438 NotifyType,
2439 DatabaseRecord->PackageList,
2440 &ImagePackage
2441 );
2442 if (EFI_ERROR (Status)) {
2443 return Status;
2444 }
2445 Status = InvokeRegisteredFunction (
2446 Private,
2447 NotifyType,
2448 (VOID *) ImagePackage,
2449 (UINT8) (PackageHeader.Type),
2450 DatabaseRecord->Handle
2451 );
2452 break;
2453 case EFI_HII_PACKAGE_SIMPLE_FONTS:
2454 Status = InsertSimpleFontPackage (
2455 PackageHdrPtr,
2456 NotifyType,
2457 DatabaseRecord->PackageList,
2458 &SimpleFontPackage
2459 );
2460 if (EFI_ERROR (Status)) {
2461 return Status;
2462 }
2463 Status = InvokeRegisteredFunction (
2464 Private,
2465 NotifyType,
2466 (VOID *) SimpleFontPackage,
2467 (UINT8) (PackageHeader.Type),
2468 DatabaseRecord->Handle
2469 );
2470 break;
2471 case EFI_HII_PACKAGE_DEVICE_PATH:
2472 Status = AddDevicePathPackage (
2473 Private,
2474 NotifyType,
2475 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),
2476 DatabaseRecord
2477 );
2478 break;
2479 default:
2480 break;
2481 }
2482
2483 if (EFI_ERROR (Status)) {
2484 return Status;
2485 }
2486 //
2487 // goto header of next package
2488 //
2489 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
2490 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2491 }
2492
2493 return Status;
2494 }
2495
2496
2497 /**
2498 This function exports a package list to a buffer. It is the worker function
2499 of HiiExportPackageList.
2500
2501 @param Private Hii database private structure.
2502 @param Handle Identification of a package list.
2503 @param PackageList Pointer to a package list which will be exported.
2504 @param UsedSize The length of buffer has been used by exporting
2505 package lists when Handle is NULL.
2506 @param BufferSize Length of the Buffer.
2507 @param Buffer Allocated space for storing exported data.
2508
2509 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2510 successfully.
2511 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2512
2513 **/
2514 STATIC
2515 EFI_STATUS
2516 ExportPackageList (
2517 IN HII_DATABASE_PRIVATE_DATA *Private,
2518 IN EFI_HII_HANDLE Handle,
2519 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2520 IN OUT UINTN *UsedSize,
2521 IN UINTN BufferSize,
2522 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
2523 )
2524 {
2525 EFI_STATUS Status;
2526 UINTN ResultSize;
2527 EFI_HII_PACKAGE_HEADER EndofPackageList;
2528
2529 ASSERT (Private != NULL || PackageList != NULL || UsedSize != NULL);
2530 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
2531 ASSERT (IsHiiHandleValid (Handle));
2532
2533 if (BufferSize > 0 && Buffer == NULL ) {
2534 return EFI_INVALID_PARAMETER;
2535 }
2536
2537 //
2538 // Copy the package list header
2539 // ResultSize indicates the length of the exported bytes of this package list
2540 //
2541 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
2542 if (ResultSize + *UsedSize <= BufferSize) {
2543 CopyMem ((VOID *) Buffer, PackageList, ResultSize);
2544 }
2545 //
2546 // Copy the packages and invoke EXPORT_PACK notify functions if exists.
2547 //
2548 Status = ExportGuidPackages (
2549 Private,
2550 Handle,
2551 PackageList,
2552 *UsedSize,
2553 BufferSize,
2554 (VOID *) ((UINT8 *) Buffer + ResultSize),
2555 &ResultSize
2556 );
2557 if (EFI_ERROR (Status)) {
2558 return Status;
2559 }
2560 Status = ExportFormPackages (
2561 Private,
2562 Handle,
2563 PackageList,
2564 *UsedSize,
2565 BufferSize,
2566 (VOID *) ((UINT8 *) Buffer + ResultSize),
2567 &ResultSize
2568 );
2569 if (EFI_ERROR (Status)) {
2570 return Status;
2571 }
2572 Status = ExportKeyboardLayoutPackages (
2573 Private,
2574 Handle,
2575 PackageList,
2576 *UsedSize,
2577 BufferSize,
2578 (VOID *) ((UINT8 *) Buffer + ResultSize),
2579 &ResultSize
2580 );
2581 if (EFI_ERROR (Status)) {
2582 return Status;
2583 }
2584 Status = ExportStringPackages (
2585 Private,
2586 Handle,
2587 PackageList,
2588 *UsedSize,
2589 BufferSize,
2590 (VOID *) ((UINT8 *) Buffer + ResultSize),
2591 &ResultSize
2592 );
2593 if (EFI_ERROR (Status)) {
2594 return Status;
2595 }
2596 Status = ExportFontPackages (
2597 Private,
2598 Handle,
2599 PackageList,
2600 *UsedSize,
2601 BufferSize,
2602 (VOID *) ((UINT8 *) Buffer + ResultSize),
2603 &ResultSize
2604 );
2605 if (EFI_ERROR (Status)) {
2606 return Status;
2607 }
2608 Status = ExportImagePackages (
2609 Private,
2610 Handle,
2611 PackageList,
2612 *UsedSize,
2613 BufferSize,
2614 (VOID *) ((UINT8 *) Buffer + ResultSize),
2615 &ResultSize
2616 );
2617 if (EFI_ERROR (Status)) {
2618 return Status;
2619 }
2620 Status = ExportSimpleFontPackages (
2621 Private,
2622 Handle,
2623 PackageList,
2624 *UsedSize,
2625 BufferSize,
2626 (VOID *) ((UINT8 *) Buffer + ResultSize),
2627 &ResultSize
2628 );
2629 if (EFI_ERROR (Status)) {
2630 return Status;
2631 }
2632 Status = ExportDevicePathPackage (
2633 Private,
2634 Handle,
2635 PackageList,
2636 *UsedSize,
2637 BufferSize,
2638 (VOID *) ((UINT8 *) Buffer + ResultSize),
2639 &ResultSize
2640 );
2641 if (EFI_ERROR (Status)) {
2642 return Status;
2643 }
2644 //
2645 // Append the package list end.
2646 //
2647 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);
2648 EndofPackageList.Type = EFI_HII_PACKAGE_END;
2649 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {
2650 CopyMem (
2651 (VOID *) ((UINT8 *) Buffer + ResultSize),
2652 (VOID *) &EndofPackageList,
2653 sizeof (EFI_HII_PACKAGE_HEADER)
2654 );
2655 }
2656
2657 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);
2658
2659 return EFI_SUCCESS;
2660 }
2661
2662
2663 /**
2664 This function adds the packages in the package list to the database and returns a handle. If there is a
2665 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
2666 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
2667
2668 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2669 instance.
2670 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
2671 structure.
2672 @param DriverHandle Associate the package list with this EFI handle.
2673 @param Handle A pointer to the EFI_HII_HANDLE instance.
2674
2675 @retval EFI_SUCCESS The package list associated with the Handle was
2676 added to the HII database.
2677 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2678 database contents.
2679 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
2680 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
2681
2682 **/
2683 EFI_STATUS
2684 EFIAPI
2685 HiiNewPackageList (
2686 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
2687 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
2688 IN CONST EFI_HANDLE DriverHandle,
2689 OUT EFI_HII_HANDLE *Handle
2690 )
2691 {
2692 EFI_STATUS Status;
2693 HII_DATABASE_PRIVATE_DATA *Private;
2694 HII_DATABASE_RECORD *DatabaseRecord;
2695 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
2696 LIST_ENTRY *Link;
2697 EFI_GUID PackageListGuid;
2698
2699 if (This == NULL || PackageList == NULL || Handle == NULL) {
2700 return EFI_INVALID_PARAMETER;
2701 }
2702
2703 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2704 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));
2705
2706 //
2707 // Check the Package list GUID to guarantee this GUID is unique in database.
2708 //
2709 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
2710 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
2711 if (CompareGuid (
2712 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
2713 &PackageListGuid
2714 )
2715 ) {
2716 return EFI_INVALID_PARAMETER;
2717 }
2718 }
2719
2720 //
2721 // Build a PackageList node
2722 //
2723 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
2724 if (EFI_ERROR (Status)) {
2725 return Status;
2726 }
2727
2728 //
2729 // Fill in information of the created Package List node
2730 // according to incoming package list.
2731 //
2732 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
2733 if (EFI_ERROR (Status)) {
2734 return Status;
2735 }
2736
2737 DatabaseRecord->DriverHandle = DriverHandle;
2738
2739 //
2740 // Create a Device path package and add into the package list if exists.
2741 //
2742 Status = gBS->HandleProtocol (
2743 DriverHandle,
2744 &gEfiDevicePathProtocolGuid,
2745 (VOID **) &DevicePath
2746 );
2747 if (!EFI_ERROR (Status)) {
2748 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
2749 ASSERT_EFI_ERROR (Status);
2750 }
2751
2752 *Handle = DatabaseRecord->Handle;
2753 return EFI_SUCCESS;
2754 }
2755
2756
2757 /**
2758 This function removes the package list that is associated with a handle Handle
2759 from the HII database. Before removing the package, any registered functions
2760 with the notification type REMOVE_PACK and the same package type will be called.
2761
2762 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2763 instance.
2764 @param Handle The handle that was registered to the data that is
2765 requested for removal.
2766
2767 @retval EFI_SUCCESS The data associated with the Handle was removed
2768 from the HII database.
2769 @retval EFI_NOT_FOUND The specified PackageList could not be found in
2770 database.
2771 @retval EFI_INVALID_PARAMETER The Handle was not valid.
2772
2773 **/
2774 EFI_STATUS
2775 EFIAPI
2776 HiiRemovePackageList (
2777 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
2778 IN EFI_HII_HANDLE Handle
2779 )
2780 {
2781 EFI_STATUS Status;
2782 HII_DATABASE_PRIVATE_DATA *Private;
2783 LIST_ENTRY *Link;
2784 HII_DATABASE_RECORD *Node;
2785 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
2786 HII_HANDLE *HiiHandle;
2787
2788 if (This == NULL || !IsHiiHandleValid (Handle)) {
2789 return EFI_INVALID_PARAMETER;
2790 }
2791
2792 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2793
2794 //
2795 // Get the packagelist to be removed.
2796 //
2797 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
2798 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
2799 if (Node->Handle == Handle) {
2800 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
2801 ASSERT (PackageList != NULL);
2802
2803 //
2804 // Call registered functions with REMOVE_PACK before removing packages
2805 // then remove them.
2806 //
2807 Status = RemoveGuidPackages (Private, Handle, PackageList);
2808 if (EFI_ERROR (Status)) {
2809 return Status;
2810 }
2811 Status = RemoveFormPackages (Private, Handle, PackageList);
2812 if (EFI_ERROR (Status)) {
2813 return Status;
2814 }
2815 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
2816 if (EFI_ERROR (Status)) {
2817 return Status;
2818 }
2819 Status = RemoveStringPackages (Private, Handle, PackageList);
2820 if (EFI_ERROR (Status)) {
2821 return Status;
2822 }
2823 Status = RemoveFontPackages (Private, Handle, PackageList);
2824 if (EFI_ERROR (Status)) {
2825 return Status;
2826 }
2827 Status = RemoveImagePackages (Private, Handle, PackageList);
2828 if (EFI_ERROR (Status)) {
2829 return Status;
2830 }
2831 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
2832 if (EFI_ERROR (Status)) {
2833 return Status;
2834 }
2835 Status = RemoveDevicePathPackage (Private, Handle, PackageList);
2836 if (EFI_ERROR (Status)) {
2837 return Status;
2838 }
2839
2840 //
2841 // Free resources of the package list
2842 //
2843 RemoveEntryList (&Node->DatabaseEntry);
2844
2845 HiiHandle = (HII_HANDLE *) Handle;
2846 RemoveEntryList (&HiiHandle->Handle);
2847 Private->HiiHandleCount--;
2848 ASSERT (Private->HiiHandleCount >= 0);
2849
2850 HiiHandle->Signature = 0;
2851 SafeFreePool (HiiHandle);
2852 SafeFreePool (Node->PackageList);
2853 SafeFreePool (Node);
2854
2855 return EFI_SUCCESS;
2856 }
2857 }
2858
2859 return EFI_NOT_FOUND;
2860 }
2861
2862
2863 /**
2864 This function updates the existing package list (which has the specified Handle)
2865 in the HII databases, using the new package list specified by PackageList.
2866
2867 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2868 instance.
2869 @param Handle The handle that was registered to the data that is
2870 requested to be updated.
2871 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
2872 package.
2873
2874 @retval EFI_SUCCESS The HII database was successfully updated.
2875 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
2876 database.
2877 @retval EFI_INVALID_PARAMETER Handle or PackageList was NULL.
2878 @retval EFI_NOT_FOUND The Handle was not valid or could not be found in
2879 database.
2880
2881 **/
2882 EFI_STATUS
2883 EFIAPI
2884 HiiUpdatePackageList (
2885 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
2886 IN EFI_HII_HANDLE Handle,
2887 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
2888 )
2889 {
2890 EFI_STATUS Status;
2891 HII_DATABASE_PRIVATE_DATA *Private;
2892 LIST_ENTRY *Link;
2893 HII_DATABASE_RECORD *Node;
2894 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
2895 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;
2896 EFI_HII_PACKAGE_HEADER PackageHeader;
2897
2898 if (This == NULL || PackageList == NULL || Handle == NULL) {
2899 return EFI_INVALID_PARAMETER;
2900 }
2901
2902 if (!IsHiiHandleValid (Handle)) {
2903 return EFI_NOT_FOUND;
2904 }
2905
2906 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2907
2908 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
2909
2910 Status = EFI_SUCCESS;
2911
2912 //
2913 // Get original packagelist to be updated
2914 //
2915 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
2916 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
2917 if (Node->Handle == Handle) {
2918 OldPackageList = Node->PackageList;
2919 //
2920 // Remove the package if its type matches one of the package types which is
2921 // contained in the new package list.
2922 //
2923 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2924 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
2925 switch (PackageHeader.Type) {
2926 case EFI_HII_PACKAGE_TYPE_GUID:
2927 Status = RemoveGuidPackages (Private, Handle, OldPackageList);
2928 break;
2929 case EFI_HII_PACKAGE_FORM:
2930 Status = RemoveFormPackages (Private, Handle, OldPackageList);
2931 break;
2932 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
2933 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
2934 break;
2935 case EFI_HII_PACKAGE_STRINGS:
2936 Status = RemoveStringPackages (Private, Handle, OldPackageList);
2937 break;
2938 case EFI_HII_PACKAGE_FONTS:
2939 Status = RemoveFontPackages (Private, Handle, OldPackageList);
2940 break;
2941 case EFI_HII_PACKAGE_IMAGES:
2942 Status = RemoveImagePackages (Private, Handle, OldPackageList);
2943 break;
2944 case EFI_HII_PACKAGE_SIMPLE_FONTS:
2945 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
2946 break;
2947 case EFI_HII_PACKAGE_DEVICE_PATH:
2948 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
2949 break;
2950 }
2951
2952 if (EFI_ERROR (Status)) {
2953 return Status;
2954 }
2955
2956 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
2957 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2958 }
2959
2960 //
2961 // Add all of the packages within the new package list
2962 //
2963 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
2964 }
2965 }
2966
2967 return EFI_NOT_FOUND;
2968 }
2969
2970
2971 /**
2972 This function returns a list of the package handles of the specified type
2973 that are currently active in the database. The pseudo-type
2974 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
2975
2976 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2977 instance.
2978 @param PackageType Specifies the package type of the packages to list
2979 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
2980 listed.
2981 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
2982 this is the pointer to the GUID which must match
2983 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
2984 Otherwise, it must be NULL.
2985 @param HandleBufferLength On input, a pointer to the length of the handle
2986 buffer. On output, the length of the handle
2987 buffer that is required for the handles found.
2988 @param Handle An array of EFI_HII_HANDLE instances returned.
2989
2990 @retval EFI_SUCCESS The matching handles are outputed successfully.
2991 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
2992 Handle is too small to support the number of
2993 handles. HandleBufferLength is updated with a
2994 value that will enable the data to fit.
2995 @retval EFI_NOT_FOUND No matching handle could not be found in database.
2996 @retval EFI_INVALID_PARAMETER Handle or HandleBufferLength was NULL.
2997
2998 **/
2999 EFI_STATUS
3000 EFIAPI
3001 HiiListPackageLists (
3002 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3003 IN UINT8 PackageType,
3004 IN CONST EFI_GUID *PackageGuid,
3005 IN OUT UINTN *HandleBufferLength,
3006 OUT EFI_HII_HANDLE *Handle
3007 )
3008 {
3009 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
3010 HII_DATABASE_PRIVATE_DATA *Private;
3011 HII_DATABASE_RECORD *Node;
3012 LIST_ENTRY *Link;
3013 BOOLEAN Matched;
3014 HII_HANDLE **Result;
3015 UINTN ResultSize;
3016 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3017 LIST_ENTRY *Link1;
3018
3019 //
3020 // Check input parameters
3021 //
3022 if (This == NULL || HandleBufferLength == NULL) {
3023 return EFI_INVALID_PARAMETER;
3024 }
3025 if (*HandleBufferLength > 0 && Handle == NULL) {
3026 return EFI_INVALID_PARAMETER;
3027 }
3028 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
3029 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
3030 return EFI_INVALID_PARAMETER;
3031 }
3032
3033 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3034 Matched = FALSE;
3035 Result = (HII_HANDLE **) Handle;
3036 ResultSize = 0;
3037
3038 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3039 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3040 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
3041 switch (PackageType) {
3042 case EFI_HII_PACKAGE_TYPE_GUID:
3043 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {
3044 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
3045 if (CompareGuid (
3046 (EFI_GUID *) PackageGuid,
3047 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))
3048 )) {
3049 Matched = TRUE;
3050 break;
3051 }
3052 }
3053 break;
3054 case EFI_HII_PACKAGE_FORM:
3055 if (!IsListEmpty (&PackageList->FormPkgHdr)) {
3056 Matched = TRUE;
3057 }
3058 break;
3059 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
3060 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {
3061 Matched = TRUE;
3062 }
3063 break;
3064 case EFI_HII_PACKAGE_STRINGS:
3065 if (!IsListEmpty (&PackageList->StringPkgHdr)) {
3066 Matched = TRUE;
3067 }
3068 break;
3069 case EFI_HII_PACKAGE_FONTS:
3070 if (!IsListEmpty (&PackageList->FontPkgHdr)) {
3071 Matched = TRUE;
3072 }
3073 break;
3074 case EFI_HII_PACKAGE_IMAGES:
3075 if (PackageList->ImagePkg != NULL) {
3076 Matched = TRUE;
3077 }
3078 break;
3079 case EFI_HII_PACKAGE_SIMPLE_FONTS:
3080 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {
3081 Matched = TRUE;
3082 }
3083 break;
3084 case EFI_HII_PACKAGE_DEVICE_PATH:
3085 if (PackageList->DevicePathPkg != NULL) {
3086 Matched = TRUE;
3087 }
3088 break;
3089 //
3090 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
3091 // to be listed.
3092 //
3093 case EFI_HII_PACKAGE_TYPE_ALL:
3094 Matched = TRUE;
3095 break;
3096 default:
3097 break;
3098 }
3099
3100 //
3101 // This active package list has the specified package type, list it.
3102 //
3103 if (Matched) {
3104 ResultSize += sizeof (EFI_HII_HANDLE);
3105 if (ResultSize <= *HandleBufferLength) {
3106 *Result++ = Node->Handle;
3107 }
3108 }
3109 Matched = FALSE;
3110 }
3111
3112 if (ResultSize == 0) {
3113 return EFI_NOT_FOUND;
3114 }
3115
3116 if (*HandleBufferLength < ResultSize) {
3117 *HandleBufferLength = ResultSize;
3118 return EFI_BUFFER_TOO_SMALL;
3119 }
3120
3121 *HandleBufferLength = ResultSize;
3122 return EFI_SUCCESS;
3123 }
3124
3125
3126 /**
3127 This function will export one or all package lists in the database to a buffer.
3128 For each package list exported, this function will call functions registered
3129 with EXPORT_PACK and then copy the package list to the buffer.
3130
3131 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3132 instance.
3133 @param Handle An EFI_HII_HANDLE that corresponds to the desired
3134 package list in the HII database to export or NULL
3135 to indicate all package lists should be exported.
3136 @param BufferSize On input, a pointer to the length of the buffer.
3137 On output, the length of the buffer that is
3138 required for the exported data.
3139 @param Buffer A pointer to a buffer that will contain the
3140 results of the export function.
3141
3142 @retval EFI_SUCCESS Package exported.
3143 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
3144 Handle is too small to support the number of
3145 handles. HandleBufferLength is updated with a
3146 value that will enable the data to fit.
3147 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the
3148 current database.
3149 @retval EFI_INVALID_PARAMETER Handle or Buffer or BufferSize was NULL.
3150
3151 **/
3152 EFI_STATUS
3153 EFIAPI
3154 HiiExportPackageLists (
3155 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3156 IN EFI_HII_HANDLE Handle,
3157 IN OUT UINTN *BufferSize,
3158 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
3159 )
3160 {
3161 LIST_ENTRY *Link;
3162 EFI_STATUS Status;
3163 HII_DATABASE_PRIVATE_DATA *Private;
3164 HII_DATABASE_RECORD *Node;
3165 UINTN UsedSize;
3166
3167 if (This == NULL || BufferSize == NULL || Handle == NULL) {
3168 return EFI_INVALID_PARAMETER;
3169 }
3170 if (*BufferSize > 0 && Buffer == NULL) {
3171 return EFI_INVALID_PARAMETER;
3172 }
3173 if (!IsHiiHandleValid (Handle)) {
3174 return EFI_NOT_FOUND;
3175 }
3176
3177 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3178 UsedSize = 0;
3179
3180 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3181 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3182 if (Handle == NULL) {
3183 //
3184 // Export all package lists in current hii database.
3185 //
3186 Status = ExportPackageList (
3187 Private,
3188 Node->Handle,
3189 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
3190 &UsedSize,
3191 *BufferSize,
3192 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)
3193 );
3194 ASSERT_EFI_ERROR (Status);
3195 }
3196 else if (Handle != NULL && Node->Handle == Handle) {
3197 Status = ExportPackageList (
3198 Private,
3199 Handle,
3200 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
3201 &UsedSize,
3202 *BufferSize,
3203 Buffer
3204 );
3205 ASSERT_EFI_ERROR (Status);
3206 if (*BufferSize < UsedSize) {
3207 *BufferSize = UsedSize;
3208 return EFI_BUFFER_TOO_SMALL;
3209 }
3210 return EFI_SUCCESS;
3211 }
3212 }
3213
3214 if (Handle == NULL && UsedSize != 0) {
3215 if (*BufferSize < UsedSize) {
3216 *BufferSize = UsedSize;
3217 return EFI_BUFFER_TOO_SMALL;
3218 }
3219 return EFI_SUCCESS;
3220 }
3221
3222 return EFI_NOT_FOUND;
3223 }
3224
3225
3226 /**
3227 This function registers a function which will be called when specified actions related to packages of
3228 the specified type occur in the HII database. By registering a function, other HII-related drivers are
3229 notified when specific package types are added, removed or updated in the HII database.
3230 Each driver or application which registers a notification should use
3231 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
3232
3233 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3234 instance.
3235 @param PackageType Specifies the package type of the packages to list
3236 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
3237 listed.
3238 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
3239 this is the pointer to the GUID which must match
3240 the Guid field of
3241 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
3242 be NULL.
3243 @param PackageNotifyFn Points to the function to be called when the event
3244 specified by
3245 NotificationType occurs.
3246 @param NotifyType Describes the types of notification which this
3247 function will be receiving.
3248 @param NotifyHandle Points to the unique handle assigned to the
3249 registered notification. Can be used in
3250 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
3251 to stop notifications.
3252
3253 @retval EFI_SUCCESS Notification registered successfully.
3254 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
3255 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
3256 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
3257 EFI_HII_PACKAGE_TYPE_GUID.
3258 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
3259 EFI_HII_PACKAGE_TYPE_GUID.
3260
3261 **/
3262 EFI_STATUS
3263 EFIAPI
3264 HiiRegisterPackageNotify (
3265 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3266 IN UINT8 PackageType,
3267 IN CONST EFI_GUID *PackageGuid,
3268 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
3269 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
3270 OUT EFI_HANDLE *NotifyHandle
3271 )
3272 {
3273 HII_DATABASE_PRIVATE_DATA *Private;
3274 HII_DATABASE_NOTIFY *Notify;
3275 EFI_STATUS Status;
3276
3277 if (This == NULL || NotifyHandle == NULL) {
3278 return EFI_INVALID_PARAMETER;
3279 }
3280 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
3281 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
3282 return EFI_INVALID_PARAMETER;
3283 }
3284
3285 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3286
3287 //
3288 // Allocate a notification node
3289 //
3290 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));
3291 if (Notify == NULL) {
3292 return EFI_OUT_OF_RESOURCES;
3293 }
3294
3295 //
3296 // Generate a notify handle
3297 //
3298 Status = gBS->InstallMultipleProtocolInterfaces (
3299 &Notify->NotifyHandle,
3300 &mHiiDatabaseNotifyGuid,
3301 NULL,
3302 NULL
3303 );
3304 ASSERT_EFI_ERROR (Status);
3305
3306 //
3307 // Fill in the information to the notification node
3308 //
3309 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;
3310 Notify->PackageType = PackageType;
3311 Notify->PackageGuid = (EFI_GUID *) PackageGuid;
3312 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;
3313 Notify->NotifyType = NotifyType;
3314
3315 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);
3316 *NotifyHandle = Notify->NotifyHandle;
3317
3318 return EFI_SUCCESS;
3319 }
3320
3321
3322 /**
3323 Removes the specified HII database package-related notification.
3324
3325 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3326 instance.
3327 @param NotifyHandle The handle of the notification function being
3328 unregistered.
3329
3330 @retval EFI_SUCCESS Notification is unregistered successfully.
3331 @retval EFI_INVALID_PARAMETER The Handle is invalid.
3332 @retval EFI_NOT_FOUND The incoming notification handle does not exist
3333 in current hii database.
3334
3335 **/
3336 EFI_STATUS
3337 EFIAPI
3338 HiiUnregisterPackageNotify (
3339 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3340 IN EFI_HANDLE NotificationHandle
3341 )
3342 {
3343 HII_DATABASE_PRIVATE_DATA *Private;
3344 HII_DATABASE_NOTIFY *Notify;
3345 LIST_ENTRY *Link;
3346 EFI_STATUS Status;
3347
3348 if (This == NULL || NotificationHandle == NULL) {
3349 return EFI_INVALID_PARAMETER;
3350 }
3351
3352 Status = gBS->OpenProtocol (
3353 NotificationHandle,
3354 &mHiiDatabaseNotifyGuid,
3355 NULL,
3356 NULL,
3357 NULL,
3358 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3359 );
3360 if (EFI_ERROR (Status)) {
3361 return EFI_INVALID_PARAMETER;
3362 }
3363
3364 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3365
3366 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {
3367 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
3368 if (Notify->NotifyHandle == NotificationHandle) {
3369 //
3370 // Remove the matching notification node
3371 //
3372 RemoveEntryList (&Notify->DatabaseNotifyEntry);
3373 Status = gBS->UninstallMultipleProtocolInterfaces (
3374 Notify->NotifyHandle,
3375 &mHiiDatabaseNotifyGuid,
3376 NULL,
3377 NULL
3378 );
3379 ASSERT_EFI_ERROR (Status);
3380 SafeFreePool (Notify);
3381 Notify = NULL;
3382
3383 return EFI_SUCCESS;
3384 }
3385 }
3386
3387 return EFI_NOT_FOUND;
3388 }
3389
3390
3391 /**
3392 This routine retrieves an array of GUID values for each keyboard layout that
3393 was previously registered in the system.
3394
3395 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3396 instance.
3397 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard
3398 GUID buffer. On output, the length of the handle
3399 buffer that is required for the handles found.
3400 @param KeyGuidBuffer An array of keyboard layout GUID instances
3401 returned.
3402
3403 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
3404 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
3405 that KeyGuidBuffer is too small to support the
3406 number of GUIDs. KeyGuidBufferLength is
3407 updated with a value that will enable the data to
3408 fit.
3409 @retval EFI_INVALID_PARAMETER The KeyGuidBuffer or KeyGuidBufferLength was NULL.
3410 @retval EFI_NOT_FOUND There was no keyboard layout.
3411
3412 **/
3413 EFI_STATUS
3414 EFIAPI
3415 HiiFindKeyboardLayouts (
3416 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3417 IN OUT UINT16 *KeyGuidBufferLength,
3418 OUT EFI_GUID *KeyGuidBuffer
3419 )
3420 {
3421 HII_DATABASE_PRIVATE_DATA *Private;
3422 HII_DATABASE_RECORD *Node;
3423 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3424 LIST_ENTRY *Link;
3425 LIST_ENTRY *Link1;
3426 UINT16 ResultSize;
3427 UINTN Index;
3428 UINT16 LayoutCount;
3429 UINT16 LayoutLength;
3430 UINT8 *Layout;
3431 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
3432
3433 if (This == NULL || KeyGuidBufferLength == NULL) {
3434 return EFI_INVALID_PARAMETER;
3435 }
3436
3437 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {
3438 return EFI_INVALID_PARAMETER;
3439 }
3440
3441 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3442 ResultSize = 0;
3443
3444 //
3445 // Search all package lists in whole database to retrieve keyboard layout.
3446 //
3447 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3448 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3449 PackageList = Node->PackageList;
3450 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
3451 Link1 != &PackageList->KeyboardLayoutHdr;
3452 Link1 = Link1->ForwardLink
3453 ) {
3454 //
3455 // Find out all Keyboard Layout packages in this package list.
3456 //
3457 Package = CR (
3458 Link1,
3459 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
3460 KeyboardEntry,
3461 HII_KB_LAYOUT_PACKAGE_SIGNATURE
3462 );
3463 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
3464 CopyMem (
3465 &LayoutCount,
3466 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),
3467 sizeof (UINT16)
3468 );
3469 for (Index = 0; Index < LayoutCount; Index++) {
3470 ResultSize += sizeof (EFI_GUID);
3471 if (ResultSize <= *KeyGuidBufferLength) {
3472 CopyMem (KeyGuidBuffer + Index, Layout + sizeof (UINT16), sizeof (EFI_GUID));
3473 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
3474 Layout = Layout + LayoutLength;
3475 }
3476 }
3477 }
3478 }
3479
3480 if (ResultSize == 0) {
3481 return EFI_NOT_FOUND;
3482 }
3483
3484 if (*KeyGuidBufferLength < ResultSize) {
3485 *KeyGuidBufferLength = ResultSize;
3486 return EFI_BUFFER_TOO_SMALL;
3487 }
3488
3489 *KeyGuidBufferLength = ResultSize;
3490 return EFI_SUCCESS;
3491 }
3492
3493
3494 /**
3495 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
3496 on a keyboard and the character(s) that are associated with a particular set of key strokes.
3497
3498 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3499 instance.
3500 @param KeyGuid A pointer to the unique ID associated with a given
3501 keyboard layout. If KeyGuid is NULL then the
3502 current layout will be retrieved.
3503 @param KeyboardLayoutLength On input, a pointer to the length of the
3504 KeyboardLayout buffer. On output, the length of
3505 the data placed into KeyboardLayout.
3506 @param KeyboardLayout A pointer to a buffer containing the retrieved
3507 keyboard layout.
3508
3509 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
3510 @retval EFI_NOT_FOUND The requested keyboard layout was not found.
3511 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
3512 NULL.
3513 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
3514 that KeyboardLayout is too small to support the
3515 requested keyboard layout. KeyboardLayoutLength is
3516 updated with a value that will enable the
3517 data to fit.
3518
3519 **/
3520 EFI_STATUS
3521 EFIAPI
3522 HiiGetKeyboardLayout (
3523 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3524 IN CONST EFI_GUID *KeyGuid,
3525 IN OUT UINT16 *KeyboardLayoutLength,
3526 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
3527 )
3528 {
3529 HII_DATABASE_PRIVATE_DATA *Private;
3530 HII_DATABASE_RECORD *Node;
3531 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3532 LIST_ENTRY *Link;
3533 LIST_ENTRY *Link1;
3534 UINTN Index;
3535 UINT8 *Layout;
3536 UINT16 LayoutCount;
3537 UINT16 LayoutLength;
3538 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
3539
3540 if (This == NULL || KeyboardLayoutLength == NULL) {
3541 return EFI_INVALID_PARAMETER;
3542 }
3543 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {
3544 return EFI_INVALID_PARAMETER;
3545 }
3546
3547 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3548 //
3549 // Retrieve the current keyboard layout.
3550 //
3551 if (KeyGuid == NULL) {
3552 if (Private->CurrentLayout == NULL) {
3553 return EFI_NOT_FOUND;
3554 }
3555 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));
3556 if (*KeyboardLayoutLength < LayoutLength) {
3557 *KeyboardLayoutLength = LayoutLength;
3558 return EFI_BUFFER_TOO_SMALL;
3559 }
3560 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);
3561 return EFI_SUCCESS;
3562 }
3563
3564 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3565 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3566 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
3567 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
3568 Link1 != &PackageList->KeyboardLayoutHdr;
3569 Link1 = Link1->ForwardLink
3570 ) {
3571 Package = CR (
3572 Link1,
3573 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
3574 KeyboardEntry,
3575 HII_KB_LAYOUT_PACKAGE_SIGNATURE
3576 );
3577
3578 Layout = (UINT8 *) Package->KeyboardPkg +
3579 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
3580 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));
3581 for (Index = 0; Index < LayoutCount; Index++) {
3582 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
3583 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {
3584 if (LayoutLength <= *KeyboardLayoutLength) {
3585 CopyMem (KeyboardLayout, Layout, LayoutLength);
3586 return EFI_SUCCESS;
3587 } else {
3588 *KeyboardLayoutLength = LayoutLength;
3589 return EFI_BUFFER_TOO_SMALL;
3590 }
3591 }
3592 Layout = Layout + LayoutLength;
3593 }
3594 }
3595 }
3596
3597 return EFI_NOT_FOUND;
3598 }
3599
3600
3601 /**
3602 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
3603 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
3604 group type. This is so that agents which are sensitive to the current keyboard layout being changed
3605 can be notified of this change.
3606
3607 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3608 instance.
3609 @param KeyGuid A pointer to the unique ID associated with a given
3610 keyboard layout.
3611
3612 @retval EFI_SUCCESS The current keyboard layout was successfully set.
3613 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
3614 action was taken.
3615 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
3616
3617 **/
3618 EFI_STATUS
3619 EFIAPI
3620 HiiSetKeyboardLayout (
3621 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3622 IN CONST EFI_GUID *KeyGuid
3623 )
3624 {
3625 HII_DATABASE_PRIVATE_DATA *Private;
3626 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
3627 UINT16 KeyboardLayoutLength;
3628 EFI_STATUS Status;
3629
3630 if (This == NULL || KeyGuid == NULL) {
3631 return EFI_INVALID_PARAMETER;
3632 }
3633
3634 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3635
3636 //
3637 // The specified GUID equals the current keyboard layout GUID,
3638 // return directly.
3639 //
3640 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {
3641 return EFI_SUCCESS;
3642 }
3643
3644 //
3645 // Try to find the incoming keyboard layout data in current database.
3646 //
3647 KeyboardLayoutLength = 0;
3648 KeyboardLayout = NULL;
3649 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
3650 if (Status != EFI_BUFFER_TOO_SMALL) {
3651 return Status;
3652 }
3653
3654 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);
3655 ASSERT (KeyboardLayout != NULL);
3656 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
3657 ASSERT_EFI_ERROR (Status);
3658
3659 //
3660 // Backup current keyboard layout.
3661 //
3662 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));
3663 SafeFreePool(Private->CurrentLayout);
3664 Private->CurrentLayout = KeyboardLayout;
3665
3666 //
3667 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
3668 // current keyboard layout is changed.
3669 //
3670 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);
3671 ASSERT_EFI_ERROR (Status);
3672
3673 return EFI_SUCCESS;
3674 }
3675
3676
3677 /**
3678 Return the EFI handle associated with a package list.
3679
3680 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3681 instance.
3682 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
3683 package list in the HIIdatabase.
3684 @param DriverHandle On return, contains the EFI_HANDLE which was
3685 registered with the package list in
3686 NewPackageList().
3687
3688 @retval EFI_SUCCESS The DriverHandle was returned successfully.
3689 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
3690 DriverHandle was NULL.
3691 @retval EFI_NOT_FOUND This PackageList handle can not be found in
3692 current database.
3693
3694 **/
3695 EFI_STATUS
3696 EFIAPI
3697 HiiGetPackageListHandle (
3698 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3699 IN EFI_HII_HANDLE PackageListHandle,
3700 OUT EFI_HANDLE *DriverHandle
3701 )
3702 {
3703 HII_DATABASE_PRIVATE_DATA *Private;
3704 HII_DATABASE_RECORD *Node;
3705 LIST_ENTRY *Link;
3706
3707 if (This == NULL || DriverHandle == NULL) {
3708 return EFI_INVALID_PARAMETER;
3709 }
3710
3711 if (!IsHiiHandleValid (PackageListHandle)) {
3712 return EFI_INVALID_PARAMETER;
3713 }
3714
3715 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3716
3717 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3718 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3719 if (Node->Handle == PackageListHandle) {
3720 *DriverHandle = Node->DriverHandle;
3721 return EFI_SUCCESS;
3722 }
3723 }
3724
3725 return EFI_NOT_FOUND;
3726 }
3727