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