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