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