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