]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
Refine code to make it more safely.
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
1 /** @file
2 Implementation for EFI_HII_DATABASE_PROTOCOL.
3
4 Copyright (c) 2007 - 2014, 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 StringPackage = NULL;
2423
2424 //
2425 // Process the package list header
2426 //
2427 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;
2428 CopyMem (
2429 &DatabaseRecord->PackageList->PackageListHdr,
2430 (VOID *) PackageList,
2431 sizeof (EFI_HII_PACKAGE_LIST_HEADER)
2432 );
2433 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2434 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;
2435 }
2436
2437 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
2438 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2439
2440 Status = EFI_SUCCESS;
2441
2442 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
2443 switch (PackageHeader.Type) {
2444 case EFI_HII_PACKAGE_TYPE_GUID:
2445 Status = InsertGuidPackage (
2446 PackageHdrPtr,
2447 NotifyType,
2448 DatabaseRecord->PackageList,
2449 &GuidPackage
2450 );
2451 if (EFI_ERROR (Status)) {
2452 return Status;
2453 }
2454 Status = InvokeRegisteredFunction (
2455 Private,
2456 NotifyType,
2457 (VOID *) GuidPackage,
2458 (UINT8) (PackageHeader.Type),
2459 DatabaseRecord->Handle
2460 );
2461 break;
2462 case EFI_HII_PACKAGE_FORMS:
2463 Status = InsertFormPackage (
2464 PackageHdrPtr,
2465 NotifyType,
2466 DatabaseRecord->PackageList,
2467 &FormPackage
2468 );
2469 if (EFI_ERROR (Status)) {
2470 return Status;
2471 }
2472 Status = InvokeRegisteredFunction (
2473 Private,
2474 NotifyType,
2475 (VOID *) FormPackage,
2476 (UINT8) (PackageHeader.Type),
2477 DatabaseRecord->Handle
2478 );
2479 break;
2480 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
2481 Status = InsertKeyboardLayoutPackage (
2482 PackageHdrPtr,
2483 NotifyType,
2484 DatabaseRecord->PackageList,
2485 &KeyboardLayoutPackage
2486 );
2487 if (EFI_ERROR (Status)) {
2488 return Status;
2489 }
2490 Status = InvokeRegisteredFunction (
2491 Private,
2492 NotifyType,
2493 (VOID *) KeyboardLayoutPackage,
2494 (UINT8) (PackageHeader.Type),
2495 DatabaseRecord->Handle
2496 );
2497 break;
2498 case EFI_HII_PACKAGE_STRINGS:
2499 Status = InsertStringPackage (
2500 Private,
2501 PackageHdrPtr,
2502 NotifyType,
2503 DatabaseRecord->PackageList,
2504 &StringPackage
2505 );
2506 if (EFI_ERROR (Status)) {
2507 return Status;
2508 }
2509 ASSERT (StringPackage != NULL);
2510 Status = InvokeRegisteredFunction (
2511 Private,
2512 NotifyType,
2513 (VOID *) StringPackage,
2514 (UINT8) (PackageHeader.Type),
2515 DatabaseRecord->Handle
2516 );
2517 StringPkgIsAdd = TRUE;
2518 break;
2519 case EFI_HII_PACKAGE_FONTS:
2520 Status = InsertFontPackage (
2521 Private,
2522 PackageHdrPtr,
2523 NotifyType,
2524 DatabaseRecord->PackageList,
2525 &FontPackage
2526 );
2527 if (EFI_ERROR (Status)) {
2528 return Status;
2529 }
2530 Status = InvokeRegisteredFunction (
2531 Private,
2532 NotifyType,
2533 (VOID *) FontPackage,
2534 (UINT8) (PackageHeader.Type),
2535 DatabaseRecord->Handle
2536 );
2537 break;
2538 case EFI_HII_PACKAGE_IMAGES:
2539 Status = InsertImagePackage (
2540 PackageHdrPtr,
2541 NotifyType,
2542 DatabaseRecord->PackageList,
2543 &ImagePackage
2544 );
2545 if (EFI_ERROR (Status)) {
2546 return Status;
2547 }
2548 Status = InvokeRegisteredFunction (
2549 Private,
2550 NotifyType,
2551 (VOID *) ImagePackage,
2552 (UINT8) (PackageHeader.Type),
2553 DatabaseRecord->Handle
2554 );
2555 break;
2556 case EFI_HII_PACKAGE_SIMPLE_FONTS:
2557 Status = InsertSimpleFontPackage (
2558 PackageHdrPtr,
2559 NotifyType,
2560 DatabaseRecord->PackageList,
2561 &SimpleFontPackage
2562 );
2563 if (EFI_ERROR (Status)) {
2564 return Status;
2565 }
2566 Status = InvokeRegisteredFunction (
2567 Private,
2568 NotifyType,
2569 (VOID *) SimpleFontPackage,
2570 (UINT8) (PackageHeader.Type),
2571 DatabaseRecord->Handle
2572 );
2573 break;
2574 case EFI_HII_PACKAGE_DEVICE_PATH:
2575 Status = AddDevicePathPackage (
2576 Private,
2577 NotifyType,
2578 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),
2579 DatabaseRecord
2580 );
2581 break;
2582 default:
2583 break;
2584 }
2585
2586 if (EFI_ERROR (Status)) {
2587 return Status;
2588 }
2589 //
2590 // goto header of next package
2591 //
2592 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
2593 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
2594 }
2595
2596 //
2597 // Adjust String Package to make sure all string packages have the same max string ID.
2598 //
2599 if (!EFI_ERROR (Status) && StringPkgIsAdd) {
2600 Status = AdjustStringPackage (DatabaseRecord->PackageList);
2601 }
2602
2603 return Status;
2604 }
2605
2606
2607 /**
2608 This function exports a package list to a buffer. It is the worker function
2609 of HiiExportPackageList.
2610
2611 This is a internal function.
2612
2613 @param Private Hii database private structure.
2614 @param Handle Identification of a package list.
2615 @param PackageList Pointer to a package list which will be exported.
2616 @param UsedSize The length of buffer has been used by exporting
2617 package lists when Handle is NULL.
2618 @param BufferSize Length of the Buffer.
2619 @param Buffer Allocated space for storing exported data.
2620
2621 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2622 successfully.
2623 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2624
2625 **/
2626 EFI_STATUS
2627 ExportPackageList (
2628 IN HII_DATABASE_PRIVATE_DATA *Private,
2629 IN EFI_HII_HANDLE Handle,
2630 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2631 IN OUT UINTN *UsedSize,
2632 IN UINTN BufferSize,
2633 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
2634 )
2635 {
2636 EFI_STATUS Status;
2637 UINTN ResultSize;
2638 EFI_HII_PACKAGE_HEADER EndofPackageList;
2639
2640 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);
2641 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
2642 ASSERT (IsHiiHandleValid (Handle));
2643
2644 if (BufferSize > 0 && Buffer == NULL ) {
2645 return EFI_INVALID_PARAMETER;
2646 }
2647
2648 //
2649 // Copy the package list header
2650 // ResultSize indicates the length of the exported bytes of this package list
2651 //
2652 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
2653 if (ResultSize + *UsedSize <= BufferSize) {
2654 CopyMem ((VOID *) Buffer, PackageList, ResultSize);
2655 }
2656 //
2657 // Copy the packages and invoke EXPORT_PACK notify functions if exists.
2658 //
2659 Status = ExportGuidPackages (
2660 Private,
2661 Handle,
2662 PackageList,
2663 *UsedSize,
2664 BufferSize,
2665 (VOID *) ((UINT8 *) Buffer + ResultSize),
2666 &ResultSize
2667 );
2668 if (EFI_ERROR (Status)) {
2669 return Status;
2670 }
2671 Status = ExportFormPackages (
2672 Private,
2673 Handle,
2674 PackageList,
2675 *UsedSize,
2676 BufferSize,
2677 (VOID *) ((UINT8 *) Buffer + ResultSize),
2678 &ResultSize
2679 );
2680 if (EFI_ERROR (Status)) {
2681 return Status;
2682 }
2683 Status = ExportKeyboardLayoutPackages (
2684 Private,
2685 Handle,
2686 PackageList,
2687 *UsedSize,
2688 BufferSize,
2689 (VOID *) ((UINT8 *) Buffer + ResultSize),
2690 &ResultSize
2691 );
2692 if (EFI_ERROR (Status)) {
2693 return Status;
2694 }
2695 Status = ExportStringPackages (
2696 Private,
2697 Handle,
2698 PackageList,
2699 *UsedSize,
2700 BufferSize,
2701 (VOID *) ((UINT8 *) Buffer + ResultSize),
2702 &ResultSize
2703 );
2704 if (EFI_ERROR (Status)) {
2705 return Status;
2706 }
2707 Status = ExportFontPackages (
2708 Private,
2709 Handle,
2710 PackageList,
2711 *UsedSize,
2712 BufferSize,
2713 (VOID *) ((UINT8 *) Buffer + ResultSize),
2714 &ResultSize
2715 );
2716 if (EFI_ERROR (Status)) {
2717 return Status;
2718 }
2719 Status = ExportImagePackages (
2720 Private,
2721 Handle,
2722 PackageList,
2723 *UsedSize,
2724 BufferSize,
2725 (VOID *) ((UINT8 *) Buffer + ResultSize),
2726 &ResultSize
2727 );
2728 if (EFI_ERROR (Status)) {
2729 return Status;
2730 }
2731 Status = ExportSimpleFontPackages (
2732 Private,
2733 Handle,
2734 PackageList,
2735 *UsedSize,
2736 BufferSize,
2737 (VOID *) ((UINT8 *) Buffer + ResultSize),
2738 &ResultSize
2739 );
2740 if (EFI_ERROR (Status)) {
2741 return Status;
2742 }
2743 Status = ExportDevicePathPackage (
2744 Private,
2745 Handle,
2746 PackageList,
2747 *UsedSize,
2748 BufferSize,
2749 (VOID *) ((UINT8 *) Buffer + ResultSize),
2750 &ResultSize
2751 );
2752 if (EFI_ERROR (Status)) {
2753 return Status;
2754 }
2755 //
2756 // Append the package list end.
2757 //
2758 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);
2759 EndofPackageList.Type = EFI_HII_PACKAGE_END;
2760 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {
2761 CopyMem (
2762 (VOID *) ((UINT8 *) Buffer + ResultSize),
2763 (VOID *) &EndofPackageList,
2764 sizeof (EFI_HII_PACKAGE_HEADER)
2765 );
2766 }
2767
2768 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);
2769
2770 return EFI_SUCCESS;
2771 }
2772
2773
2774 /**
2775 This function adds the packages in the package list to the database and returns a handle. If there is a
2776 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
2777 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
2778
2779 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2780 instance.
2781 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
2782 structure.
2783 @param DriverHandle Associate the package list with this EFI handle.
2784 If a NULL is specified, this data will not be associate
2785 with any drivers and cannot have a callback induced.
2786 @param Handle A pointer to the EFI_HII_HANDLE instance.
2787
2788 @retval EFI_SUCCESS The package list associated with the Handle was
2789 added to the HII database.
2790 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2791 database contents.
2792 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
2793 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
2794
2795 **/
2796 EFI_STATUS
2797 EFIAPI
2798 HiiNewPackageList (
2799 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
2800 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
2801 IN CONST EFI_HANDLE DriverHandle, OPTIONAL
2802 OUT EFI_HII_HANDLE *Handle
2803 )
2804 {
2805 EFI_STATUS Status;
2806 HII_DATABASE_PRIVATE_DATA *Private;
2807 HII_DATABASE_RECORD *DatabaseRecord;
2808 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
2809 LIST_ENTRY *Link;
2810 EFI_GUID PackageListGuid;
2811
2812 if (This == NULL || PackageList == NULL || Handle == NULL) {
2813 return EFI_INVALID_PARAMETER;
2814 }
2815
2816 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2817 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));
2818
2819 //
2820 // Check the Package list GUID to guarantee this GUID is unique in database.
2821 //
2822 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
2823 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
2824 if (CompareGuid (
2825 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
2826 &PackageListGuid) &&
2827 DatabaseRecord->DriverHandle == DriverHandle) {
2828 return EFI_INVALID_PARAMETER;
2829 }
2830 }
2831
2832 //
2833 // Build a PackageList node
2834 //
2835 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
2836 if (EFI_ERROR (Status)) {
2837 return Status;
2838 }
2839
2840 //
2841 // Fill in information of the created Package List node
2842 // according to incoming package list.
2843 //
2844 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
2845 if (EFI_ERROR (Status)) {
2846 return Status;
2847 }
2848
2849 DatabaseRecord->DriverHandle = DriverHandle;
2850
2851 //
2852 // Create a Device path package and add into the package list if exists.
2853 //
2854 Status = gBS->HandleProtocol (
2855 DriverHandle,
2856 &gEfiDevicePathProtocolGuid,
2857 (VOID **) &DevicePath
2858 );
2859 if (!EFI_ERROR (Status)) {
2860 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
2861 ASSERT_EFI_ERROR (Status);
2862 }
2863
2864 *Handle = DatabaseRecord->Handle;
2865 return EFI_SUCCESS;
2866 }
2867
2868
2869 /**
2870 This function removes the package list that is associated with a handle Handle
2871 from the HII database. Before removing the package, any registered functions
2872 with the notification type REMOVE_PACK and the same package type will be called.
2873
2874 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2875 instance.
2876 @param Handle The handle that was registered to the data that is
2877 requested for removal.
2878
2879 @retval EFI_SUCCESS The data associated with the Handle was removed
2880 from the HII database.
2881 @retval EFI_NOT_FOUND The specified andle is not in database.
2882 @retval EFI_INVALID_PARAMETER The Handle was not valid.
2883
2884 **/
2885 EFI_STATUS
2886 EFIAPI
2887 HiiRemovePackageList (
2888 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
2889 IN EFI_HII_HANDLE Handle
2890 )
2891 {
2892 EFI_STATUS Status;
2893 HII_DATABASE_PRIVATE_DATA *Private;
2894 LIST_ENTRY *Link;
2895 HII_DATABASE_RECORD *Node;
2896 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
2897 HII_HANDLE *HiiHandle;
2898
2899 if (This == NULL) {
2900 return EFI_INVALID_PARAMETER;
2901 }
2902
2903 if (!IsHiiHandleValid (Handle)) {
2904 return EFI_NOT_FOUND;
2905 }
2906
2907 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2908
2909 //
2910 // Get the packagelist to be removed.
2911 //
2912 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
2913 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
2914 if (Node->Handle == Handle) {
2915 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
2916 ASSERT (PackageList != NULL);
2917
2918 //
2919 // Call registered functions with REMOVE_PACK before removing packages
2920 // then remove them.
2921 //
2922 Status = RemoveGuidPackages (Private, Handle, PackageList);
2923 if (EFI_ERROR (Status)) {
2924 return Status;
2925 }
2926 Status = RemoveFormPackages (Private, Handle, PackageList);
2927 if (EFI_ERROR (Status)) {
2928 return Status;
2929 }
2930 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
2931 if (EFI_ERROR (Status)) {
2932 return Status;
2933 }
2934 Status = RemoveStringPackages (Private, Handle, PackageList);
2935 if (EFI_ERROR (Status)) {
2936 return Status;
2937 }
2938 Status = RemoveFontPackages (Private, Handle, PackageList);
2939 if (EFI_ERROR (Status)) {
2940 return Status;
2941 }
2942 Status = RemoveImagePackages (Private, Handle, PackageList);
2943 if (EFI_ERROR (Status)) {
2944 return Status;
2945 }
2946 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
2947 if (EFI_ERROR (Status)) {
2948 return Status;
2949 }
2950 Status = RemoveDevicePathPackage (Private, Handle, PackageList);
2951 if (EFI_ERROR (Status)) {
2952 return Status;
2953 }
2954
2955 //
2956 // Free resources of the package list
2957 //
2958 RemoveEntryList (&Node->DatabaseEntry);
2959
2960 HiiHandle = (HII_HANDLE *) Handle;
2961 RemoveEntryList (&HiiHandle->Handle);
2962 Private->HiiHandleCount--;
2963 ASSERT (Private->HiiHandleCount >= 0);
2964
2965 HiiHandle->Signature = 0;
2966 FreePool (HiiHandle);
2967 FreePool (Node->PackageList);
2968 FreePool (Node);
2969
2970 return EFI_SUCCESS;
2971 }
2972 }
2973
2974 return EFI_NOT_FOUND;
2975 }
2976
2977
2978 /**
2979 This function updates the existing package list (which has the specified Handle)
2980 in the HII databases, using the new package list specified by PackageList.
2981
2982 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
2983 instance.
2984 @param Handle The handle that was registered to the data that is
2985 requested to be updated.
2986 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
2987 package.
2988
2989 @retval EFI_SUCCESS The HII database was successfully updated.
2990 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
2991 database.
2992 @retval EFI_INVALID_PARAMETER PackageList was NULL.
2993 @retval EFI_NOT_FOUND The specified Handle is not in database.
2994
2995 **/
2996 EFI_STATUS
2997 EFIAPI
2998 HiiUpdatePackageList (
2999 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3000 IN EFI_HII_HANDLE Handle,
3001 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
3002 )
3003 {
3004 EFI_STATUS Status;
3005 HII_DATABASE_PRIVATE_DATA *Private;
3006 LIST_ENTRY *Link;
3007 HII_DATABASE_RECORD *Node;
3008 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
3009 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;
3010 EFI_HII_PACKAGE_HEADER PackageHeader;
3011
3012 if (This == NULL || PackageList == NULL) {
3013 return EFI_INVALID_PARAMETER;
3014 }
3015
3016 if (!IsHiiHandleValid (Handle)) {
3017 return EFI_NOT_FOUND;
3018 }
3019
3020 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3021
3022 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
3023
3024 Status = EFI_SUCCESS;
3025
3026 //
3027 // Get original packagelist to be updated
3028 //
3029 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3030 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3031 if (Node->Handle == Handle) {
3032 OldPackageList = Node->PackageList;
3033 //
3034 // Remove the package if its type matches one of the package types which is
3035 // contained in the new package list.
3036 //
3037 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3038 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
3039 switch (PackageHeader.Type) {
3040 case EFI_HII_PACKAGE_TYPE_GUID:
3041 Status = RemoveGuidPackages (Private, Handle, OldPackageList);
3042 break;
3043 case EFI_HII_PACKAGE_FORMS:
3044 Status = RemoveFormPackages (Private, Handle, OldPackageList);
3045 break;
3046 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
3047 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
3048 break;
3049 case EFI_HII_PACKAGE_STRINGS:
3050 Status = RemoveStringPackages (Private, Handle, OldPackageList);
3051 break;
3052 case EFI_HII_PACKAGE_FONTS:
3053 Status = RemoveFontPackages (Private, Handle, OldPackageList);
3054 break;
3055 case EFI_HII_PACKAGE_IMAGES:
3056 Status = RemoveImagePackages (Private, Handle, OldPackageList);
3057 break;
3058 case EFI_HII_PACKAGE_SIMPLE_FONTS:
3059 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
3060 break;
3061 case EFI_HII_PACKAGE_DEVICE_PATH:
3062 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
3063 break;
3064 }
3065
3066 if (EFI_ERROR (Status)) {
3067 return Status;
3068 }
3069
3070 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
3071 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3072 }
3073
3074 //
3075 // Add all of the packages within the new package list
3076 //
3077 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
3078 }
3079 }
3080
3081 return EFI_NOT_FOUND;
3082 }
3083
3084
3085 /**
3086 This function returns a list of the package handles of the specified type
3087 that are currently active in the database. The pseudo-type
3088 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
3089
3090 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3091 instance.
3092 @param PackageType Specifies the package type of the packages to list
3093 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
3094 listed.
3095 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
3096 this is the pointer to the GUID which must match
3097 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
3098 Otherwise, it must be NULL.
3099 @param HandleBufferLength On input, a pointer to the length of the handle
3100 buffer. On output, the length of the handle
3101 buffer that is required for the handles found.
3102 @param Handle An array of EFI_HII_HANDLE instances returned.
3103
3104 @retval EFI_SUCCESS The matching handles are outputed successfully.
3105 HandleBufferLength is updated with the actual length.
3106 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
3107 Handle is too small to support the number of
3108 handles. HandleBufferLength is updated with a
3109 value that will enable the data to fit.
3110 @retval EFI_NOT_FOUND No matching handle could not be found in database.
3111 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.
3112 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not
3113 zero and Handle was NULL.
3114 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
3115 PackageGuid is not NULL, PackageType is a EFI_HII_
3116 PACKAGE_TYPE_GUID but PackageGuid is NULL.
3117
3118 **/
3119 EFI_STATUS
3120 EFIAPI
3121 HiiListPackageLists (
3122 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3123 IN UINT8 PackageType,
3124 IN CONST EFI_GUID *PackageGuid,
3125 IN OUT UINTN *HandleBufferLength,
3126 OUT EFI_HII_HANDLE *Handle
3127 )
3128 {
3129 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
3130 HII_DATABASE_PRIVATE_DATA *Private;
3131 HII_DATABASE_RECORD *Node;
3132 LIST_ENTRY *Link;
3133 BOOLEAN Matched;
3134 HII_HANDLE **Result;
3135 UINTN ResultSize;
3136 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3137 LIST_ENTRY *Link1;
3138
3139 //
3140 // Check input parameters
3141 //
3142 if (This == NULL || HandleBufferLength == NULL) {
3143 return EFI_INVALID_PARAMETER;
3144 }
3145 if (*HandleBufferLength > 0 && Handle == NULL) {
3146 return EFI_INVALID_PARAMETER;
3147 }
3148 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
3149 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
3150 return EFI_INVALID_PARAMETER;
3151 }
3152
3153 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3154 Matched = FALSE;
3155 Result = (HII_HANDLE **) Handle;
3156 ResultSize = 0;
3157
3158 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3159 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3160 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
3161 switch (PackageType) {
3162 case EFI_HII_PACKAGE_TYPE_GUID:
3163 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {
3164 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
3165 if (CompareGuid (
3166 (EFI_GUID *) PackageGuid,
3167 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))
3168 )) {
3169 Matched = TRUE;
3170 break;
3171 }
3172 }
3173 break;
3174 case EFI_HII_PACKAGE_FORMS:
3175 if (!IsListEmpty (&PackageList->FormPkgHdr)) {
3176 Matched = TRUE;
3177 }
3178 break;
3179 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
3180 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {
3181 Matched = TRUE;
3182 }
3183 break;
3184 case EFI_HII_PACKAGE_STRINGS:
3185 if (!IsListEmpty (&PackageList->StringPkgHdr)) {
3186 Matched = TRUE;
3187 }
3188 break;
3189 case EFI_HII_PACKAGE_FONTS:
3190 if (!IsListEmpty (&PackageList->FontPkgHdr)) {
3191 Matched = TRUE;
3192 }
3193 break;
3194 case EFI_HII_PACKAGE_IMAGES:
3195 if (PackageList->ImagePkg != NULL) {
3196 Matched = TRUE;
3197 }
3198 break;
3199 case EFI_HII_PACKAGE_SIMPLE_FONTS:
3200 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {
3201 Matched = TRUE;
3202 }
3203 break;
3204 case EFI_HII_PACKAGE_DEVICE_PATH:
3205 if (PackageList->DevicePathPkg != NULL) {
3206 Matched = TRUE;
3207 }
3208 break;
3209 //
3210 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
3211 // to be listed.
3212 //
3213 case EFI_HII_PACKAGE_TYPE_ALL:
3214 Matched = TRUE;
3215 break;
3216 default:
3217 break;
3218 }
3219
3220 //
3221 // This active package list has the specified package type, list it.
3222 //
3223 if (Matched) {
3224 ResultSize += sizeof (EFI_HII_HANDLE);
3225 if (ResultSize <= *HandleBufferLength) {
3226 *Result++ = Node->Handle;
3227 }
3228 }
3229 Matched = FALSE;
3230 }
3231
3232 if (ResultSize == 0) {
3233 return EFI_NOT_FOUND;
3234 }
3235
3236 if (*HandleBufferLength < ResultSize) {
3237 *HandleBufferLength = ResultSize;
3238 return EFI_BUFFER_TOO_SMALL;
3239 }
3240
3241 *HandleBufferLength = ResultSize;
3242 return EFI_SUCCESS;
3243 }
3244
3245
3246 /**
3247 This function will export one or all package lists in the database to a buffer.
3248 For each package list exported, this function will call functions registered
3249 with EXPORT_PACK and then copy the package list to the buffer.
3250
3251 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3252 instance.
3253 @param Handle An EFI_HII_HANDLE that corresponds to the desired
3254 package list in the HII database to export or NULL
3255 to indicate all package lists should be exported.
3256 @param BufferSize On input, a pointer to the length of the buffer.
3257 On output, the length of the buffer that is
3258 required for the exported data.
3259 @param Buffer A pointer to a buffer that will contain the
3260 results of the export function.
3261
3262 @retval EFI_SUCCESS Package exported.
3263 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
3264 Handle is too small to support the number of
3265 handles. HandleBufferLength is updated with a
3266 value that will enable the data to fit.
3267 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the
3268 current database.
3269 @retval EFI_INVALID_PARAMETER BufferSize was NULL.
3270 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero
3271 and Buffer was NULL.
3272
3273 **/
3274 EFI_STATUS
3275 EFIAPI
3276 HiiExportPackageLists (
3277 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3278 IN EFI_HII_HANDLE Handle,
3279 IN OUT UINTN *BufferSize,
3280 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
3281 )
3282 {
3283 LIST_ENTRY *Link;
3284 EFI_STATUS Status;
3285 HII_DATABASE_PRIVATE_DATA *Private;
3286 HII_DATABASE_RECORD *Node;
3287 UINTN UsedSize;
3288
3289 if (This == NULL || BufferSize == NULL) {
3290 return EFI_INVALID_PARAMETER;
3291 }
3292 if (*BufferSize > 0 && Buffer == NULL) {
3293 return EFI_INVALID_PARAMETER;
3294 }
3295 if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {
3296 return EFI_NOT_FOUND;
3297 }
3298
3299 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3300 UsedSize = 0;
3301
3302 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3303 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3304 if (Handle == NULL) {
3305 //
3306 // Export all package lists in current hii database.
3307 //
3308 Status = ExportPackageList (
3309 Private,
3310 Node->Handle,
3311 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
3312 &UsedSize,
3313 *BufferSize,
3314 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)
3315 );
3316 ASSERT_EFI_ERROR (Status);
3317 } else if (Handle != NULL && Node->Handle == Handle) {
3318 Status = ExportPackageList (
3319 Private,
3320 Handle,
3321 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
3322 &UsedSize,
3323 *BufferSize,
3324 Buffer
3325 );
3326 ASSERT_EFI_ERROR (Status);
3327 if (*BufferSize < UsedSize) {
3328 *BufferSize = UsedSize;
3329 return EFI_BUFFER_TOO_SMALL;
3330 }
3331 return EFI_SUCCESS;
3332 }
3333 }
3334
3335 if (Handle == NULL && UsedSize != 0) {
3336 if (*BufferSize < UsedSize) {
3337 *BufferSize = UsedSize;
3338 return EFI_BUFFER_TOO_SMALL;
3339 }
3340 return EFI_SUCCESS;
3341 }
3342
3343 return EFI_NOT_FOUND;
3344 }
3345
3346
3347 /**
3348 This function registers a function which will be called when specified actions related to packages of
3349 the specified type occur in the HII database. By registering a function, other HII-related drivers are
3350 notified when specific package types are added, removed or updated in the HII database.
3351 Each driver or application which registers a notification should use
3352 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
3353
3354 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3355 instance.
3356 @param PackageType Specifies the package type of the packages to list
3357 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
3358 listed.
3359 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
3360 this is the pointer to the GUID which must match
3361 the Guid field of
3362 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
3363 be NULL.
3364 @param PackageNotifyFn Points to the function to be called when the event
3365 specified by
3366 NotificationType occurs.
3367 @param NotifyType Describes the types of notification which this
3368 function will be receiving.
3369 @param NotifyHandle Points to the unique handle assigned to the
3370 registered notification. Can be used in
3371 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
3372 to stop notifications.
3373
3374 @retval EFI_SUCCESS Notification registered successfully.
3375 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
3376 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
3377 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
3378 EFI_HII_PACKAGE_TYPE_GUID.
3379 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
3380 EFI_HII_PACKAGE_TYPE_GUID.
3381
3382 **/
3383 EFI_STATUS
3384 EFIAPI
3385 HiiRegisterPackageNotify (
3386 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3387 IN UINT8 PackageType,
3388 IN CONST EFI_GUID *PackageGuid,
3389 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
3390 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
3391 OUT EFI_HANDLE *NotifyHandle
3392 )
3393 {
3394 HII_DATABASE_PRIVATE_DATA *Private;
3395 HII_DATABASE_NOTIFY *Notify;
3396 EFI_STATUS Status;
3397
3398 if (This == NULL || NotifyHandle == NULL) {
3399 return EFI_INVALID_PARAMETER;
3400 }
3401 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
3402 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
3403 return EFI_INVALID_PARAMETER;
3404 }
3405
3406 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3407
3408 //
3409 // Allocate a notification node
3410 //
3411 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));
3412 if (Notify == NULL) {
3413 return EFI_OUT_OF_RESOURCES;
3414 }
3415
3416 //
3417 // Generate a notify handle
3418 //
3419 Status = gBS->InstallMultipleProtocolInterfaces (
3420 &Notify->NotifyHandle,
3421 &gEfiCallerIdGuid,
3422 NULL,
3423 NULL
3424 );
3425 ASSERT_EFI_ERROR (Status);
3426
3427 //
3428 // Fill in the information to the notification node
3429 //
3430 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;
3431 Notify->PackageType = PackageType;
3432 Notify->PackageGuid = (EFI_GUID *) PackageGuid;
3433 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;
3434 Notify->NotifyType = NotifyType;
3435
3436 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);
3437 *NotifyHandle = Notify->NotifyHandle;
3438
3439 return EFI_SUCCESS;
3440 }
3441
3442
3443 /**
3444 Removes the specified HII database package-related notification.
3445
3446 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3447 instance.
3448 @param NotificationHandle The handle of the notification function being
3449 unregistered.
3450
3451 @retval EFI_SUCCESS Notification is unregistered successfully.
3452 @retval EFI_INVALID_PARAMETER The Handle is invalid.
3453 @retval EFI_NOT_FOUND The incoming notification handle does not exist
3454 in current hii database.
3455
3456 **/
3457 EFI_STATUS
3458 EFIAPI
3459 HiiUnregisterPackageNotify (
3460 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3461 IN EFI_HANDLE NotificationHandle
3462 )
3463 {
3464 HII_DATABASE_PRIVATE_DATA *Private;
3465 HII_DATABASE_NOTIFY *Notify;
3466 LIST_ENTRY *Link;
3467 EFI_STATUS Status;
3468
3469 if (This == NULL) {
3470 return EFI_INVALID_PARAMETER;
3471 }
3472
3473 if (NotificationHandle == NULL) {
3474 return EFI_NOT_FOUND;
3475 }
3476
3477 Status = gBS->OpenProtocol (
3478 NotificationHandle,
3479 &gEfiCallerIdGuid,
3480 NULL,
3481 NULL,
3482 NULL,
3483 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
3484 );
3485 if (EFI_ERROR (Status)) {
3486 return EFI_NOT_FOUND;
3487 }
3488
3489 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3490
3491 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {
3492 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
3493 if (Notify->NotifyHandle == NotificationHandle) {
3494 //
3495 // Remove the matching notification node
3496 //
3497 RemoveEntryList (&Notify->DatabaseNotifyEntry);
3498 Status = gBS->UninstallMultipleProtocolInterfaces (
3499 Notify->NotifyHandle,
3500 &gEfiCallerIdGuid,
3501 NULL,
3502 NULL
3503 );
3504 ASSERT_EFI_ERROR (Status);
3505 FreePool (Notify);
3506
3507 return EFI_SUCCESS;
3508 }
3509 }
3510
3511 return EFI_NOT_FOUND;
3512 }
3513
3514
3515 /**
3516 This routine retrieves an array of GUID values for each keyboard layout that
3517 was previously registered in the system.
3518
3519 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3520 instance.
3521 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard
3522 GUID buffer. On output, the length of the handle
3523 buffer that is required for the handles found.
3524 @param KeyGuidBuffer An array of keyboard layout GUID instances
3525 returned.
3526
3527 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
3528 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
3529 that KeyGuidBuffer is too small to support the
3530 number of GUIDs. KeyGuidBufferLength is
3531 updated with a value that will enable the data to
3532 fit.
3533 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.
3534 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not
3535 zero and KeyGuidBuffer is NULL.
3536 @retval EFI_NOT_FOUND There was no keyboard layout.
3537
3538 **/
3539 EFI_STATUS
3540 EFIAPI
3541 HiiFindKeyboardLayouts (
3542 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3543 IN OUT UINT16 *KeyGuidBufferLength,
3544 OUT EFI_GUID *KeyGuidBuffer
3545 )
3546 {
3547 HII_DATABASE_PRIVATE_DATA *Private;
3548 HII_DATABASE_RECORD *Node;
3549 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3550 LIST_ENTRY *Link;
3551 LIST_ENTRY *Link1;
3552 UINT16 ResultSize;
3553 UINTN Index;
3554 UINT16 LayoutCount;
3555 UINT16 LayoutLength;
3556 UINT8 *Layout;
3557 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
3558
3559 if (This == NULL || KeyGuidBufferLength == NULL) {
3560 return EFI_INVALID_PARAMETER;
3561 }
3562
3563 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {
3564 return EFI_INVALID_PARAMETER;
3565 }
3566
3567 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3568 ResultSize = 0;
3569
3570 //
3571 // Search all package lists in whole database to retrieve keyboard layout.
3572 //
3573 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3574 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3575 PackageList = Node->PackageList;
3576 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
3577 Link1 != &PackageList->KeyboardLayoutHdr;
3578 Link1 = Link1->ForwardLink
3579 ) {
3580 //
3581 // Find out all Keyboard Layout packages in this package list.
3582 //
3583 Package = CR (
3584 Link1,
3585 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
3586 KeyboardEntry,
3587 HII_KB_LAYOUT_PACKAGE_SIGNATURE
3588 );
3589 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
3590 CopyMem (
3591 &LayoutCount,
3592 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),
3593 sizeof (UINT16)
3594 );
3595 for (Index = 0; Index < LayoutCount; Index++) {
3596 ResultSize += sizeof (EFI_GUID);
3597 if (ResultSize <= *KeyGuidBufferLength) {
3598 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));
3599 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
3600 Layout = Layout + LayoutLength;
3601 }
3602 }
3603 }
3604 }
3605
3606 if (ResultSize == 0) {
3607 return EFI_NOT_FOUND;
3608 }
3609
3610 if (*KeyGuidBufferLength < ResultSize) {
3611 *KeyGuidBufferLength = ResultSize;
3612 return EFI_BUFFER_TOO_SMALL;
3613 }
3614
3615 *KeyGuidBufferLength = ResultSize;
3616 return EFI_SUCCESS;
3617 }
3618
3619
3620 /**
3621 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
3622 on a keyboard and the character(s) that are associated with a particular set of key strokes.
3623
3624 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3625 instance.
3626 @param KeyGuid A pointer to the unique ID associated with a given
3627 keyboard layout. If KeyGuid is NULL then the
3628 current layout will be retrieved.
3629 @param KeyboardLayoutLength On input, a pointer to the length of the
3630 KeyboardLayout buffer. On output, the length of
3631 the data placed into KeyboardLayout.
3632 @param KeyboardLayout A pointer to a buffer containing the retrieved
3633 keyboard layout.
3634
3635 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
3636 @retval EFI_NOT_FOUND The requested keyboard layout was not found.
3637 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
3638 NULL.
3639 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
3640 that KeyboardLayout is too small to support the
3641 requested keyboard layout. KeyboardLayoutLength is
3642 updated with a value that will enable the
3643 data to fit.
3644
3645 **/
3646 EFI_STATUS
3647 EFIAPI
3648 HiiGetKeyboardLayout (
3649 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3650 IN CONST EFI_GUID *KeyGuid,
3651 IN OUT UINT16 *KeyboardLayoutLength,
3652 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
3653 )
3654 {
3655 HII_DATABASE_PRIVATE_DATA *Private;
3656 HII_DATABASE_RECORD *Node;
3657 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3658 LIST_ENTRY *Link;
3659 LIST_ENTRY *Link1;
3660 UINTN Index;
3661 UINT8 *Layout;
3662 UINT16 LayoutCount;
3663 UINT16 LayoutLength;
3664 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
3665
3666 if (This == NULL || KeyboardLayoutLength == NULL) {
3667 return EFI_INVALID_PARAMETER;
3668 }
3669 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {
3670 return EFI_INVALID_PARAMETER;
3671 }
3672
3673 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3674 //
3675 // Retrieve the current keyboard layout.
3676 //
3677 if (KeyGuid == NULL) {
3678 if (Private->CurrentLayout == NULL) {
3679 return EFI_NOT_FOUND;
3680 }
3681 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));
3682 if (*KeyboardLayoutLength < LayoutLength) {
3683 *KeyboardLayoutLength = LayoutLength;
3684 return EFI_BUFFER_TOO_SMALL;
3685 }
3686 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);
3687 return EFI_SUCCESS;
3688 }
3689
3690 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3691 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3692 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
3693 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
3694 Link1 != &PackageList->KeyboardLayoutHdr;
3695 Link1 = Link1->ForwardLink
3696 ) {
3697 Package = CR (
3698 Link1,
3699 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
3700 KeyboardEntry,
3701 HII_KB_LAYOUT_PACKAGE_SIGNATURE
3702 );
3703
3704 Layout = (UINT8 *) Package->KeyboardPkg +
3705 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
3706 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));
3707 for (Index = 0; Index < LayoutCount; Index++) {
3708 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
3709 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {
3710 if (LayoutLength <= *KeyboardLayoutLength) {
3711 CopyMem (KeyboardLayout, Layout, LayoutLength);
3712 return EFI_SUCCESS;
3713 } else {
3714 *KeyboardLayoutLength = LayoutLength;
3715 return EFI_BUFFER_TOO_SMALL;
3716 }
3717 }
3718 Layout = Layout + LayoutLength;
3719 }
3720 }
3721 }
3722
3723 return EFI_NOT_FOUND;
3724 }
3725
3726
3727 /**
3728 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
3729 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
3730 group type. This is so that agents which are sensitive to the current keyboard layout being changed
3731 can be notified of this change.
3732
3733 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3734 instance.
3735 @param KeyGuid A pointer to the unique ID associated with a given
3736 keyboard layout.
3737
3738 @retval EFI_SUCCESS The current keyboard layout was successfully set.
3739 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
3740 action was taken.
3741 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
3742
3743 **/
3744 EFI_STATUS
3745 EFIAPI
3746 HiiSetKeyboardLayout (
3747 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3748 IN CONST EFI_GUID *KeyGuid
3749 )
3750 {
3751 HII_DATABASE_PRIVATE_DATA *Private;
3752 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
3753 UINT16 KeyboardLayoutLength;
3754 EFI_STATUS Status;
3755
3756 if (This == NULL || KeyGuid == NULL) {
3757 return EFI_INVALID_PARAMETER;
3758 }
3759
3760 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3761
3762 //
3763 // The specified GUID equals the current keyboard layout GUID,
3764 // return directly.
3765 //
3766 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {
3767 return EFI_SUCCESS;
3768 }
3769
3770 //
3771 // Try to find the incoming keyboard layout data in current database.
3772 //
3773 KeyboardLayoutLength = 0;
3774 KeyboardLayout = NULL;
3775 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
3776 if (Status != EFI_BUFFER_TOO_SMALL) {
3777 return Status;
3778 }
3779
3780 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);
3781 ASSERT (KeyboardLayout != NULL);
3782 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
3783 ASSERT_EFI_ERROR (Status);
3784
3785 //
3786 // Backup current keyboard layout.
3787 //
3788 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));
3789 if (Private->CurrentLayout != NULL) {
3790 FreePool(Private->CurrentLayout);
3791 }
3792 Private->CurrentLayout = KeyboardLayout;
3793
3794 //
3795 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
3796 // current keyboard layout is changed.
3797 //
3798 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);
3799 ASSERT_EFI_ERROR (Status);
3800
3801 return EFI_SUCCESS;
3802 }
3803
3804
3805 /**
3806 Return the EFI handle associated with a package list.
3807
3808 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3809 instance.
3810 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
3811 package list in the HIIdatabase.
3812 @param DriverHandle On return, contains the EFI_HANDLE which was
3813 registered with the package list in
3814 NewPackageList().
3815
3816 @retval EFI_SUCCESS The DriverHandle was returned successfully.
3817 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
3818 DriverHandle was NULL.
3819 @retval EFI_NOT_FOUND This PackageList handle can not be found in
3820 current database.
3821
3822 **/
3823 EFI_STATUS
3824 EFIAPI
3825 HiiGetPackageListHandle (
3826 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3827 IN EFI_HII_HANDLE PackageListHandle,
3828 OUT EFI_HANDLE *DriverHandle
3829 )
3830 {
3831 HII_DATABASE_PRIVATE_DATA *Private;
3832 HII_DATABASE_RECORD *Node;
3833 LIST_ENTRY *Link;
3834
3835 if (This == NULL || DriverHandle == NULL) {
3836 return EFI_INVALID_PARAMETER;
3837 }
3838
3839 if (!IsHiiHandleValid (PackageListHandle)) {
3840 return EFI_INVALID_PARAMETER;
3841 }
3842
3843 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3844
3845 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3846 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3847 if (Node->Handle == PackageListHandle) {
3848 *DriverHandle = Node->DriverHandle;
3849 return EFI_SUCCESS;
3850 }
3851 }
3852
3853 return EFI_NOT_FOUND;
3854 }
3855