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