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