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