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