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