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