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