VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c

Last change on this file was 108794, checked in by vboxsync, 8 days ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 159.5 KB
Line 
1/** @file
2Implementation for EFI_HII_DATABASE_PROTOCOL.
3
4Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include "HiiDatabase.h"
10
11#define BASE_NUMBER 10
12
13EFI_HII_PACKAGE_LIST_HEADER *gRTDatabaseInfoBuffer = NULL;
14EFI_STRING gRTConfigRespBuffer = NULL;
15UINTN gDatabaseInfoSize = 0;
16UINTN gConfigRespSize = 0;
17BOOLEAN gExportConfigResp = FALSE;
18UINTN gNvDefaultStoreSize = 0;
19SKU_ID gSkuId = 0xFFFFFFFFFFFFFFFF;
20LIST_ENTRY gVarStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);
21
22//
23// HII database lock.
24//
25EFI_LOCK mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
26
27/**
28 This function generates a HII_DATABASE_RECORD node and adds into hii database.
29 This is a internal function.
30
31 @param Private hii database private structure
32 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a
33 package list
34
35 @retval EFI_SUCCESS A database record is generated successfully.
36 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
37 database contents.
38 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.
39
40**/
41EFI_STATUS
42GenerateHiiDatabaseRecord (
43 IN HII_DATABASE_PRIVATE_DATA *Private,
44 OUT HII_DATABASE_RECORD **DatabaseNode
45 )
46{
47 HII_DATABASE_RECORD *DatabaseRecord;
48 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
49 HII_HANDLE *HiiHandle;
50
51 if ((Private == NULL) || (DatabaseNode == NULL)) {
52 return EFI_INVALID_PARAMETER;
53 }
54
55 DatabaseRecord = (HII_DATABASE_RECORD *)AllocateZeroPool (sizeof (HII_DATABASE_RECORD));
56 if (DatabaseRecord == NULL) {
57 return EFI_OUT_OF_RESOURCES;
58 }
59
60 DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;
61
62 DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));
63 if (DatabaseRecord->PackageList == NULL) {
64 FreePool (DatabaseRecord);
65 return EFI_OUT_OF_RESOURCES;
66 }
67
68 PackageList = DatabaseRecord->PackageList;
69
70 InitializeListHead (&PackageList->GuidPkgHdr);
71 InitializeListHead (&PackageList->FormPkgHdr);
72 InitializeListHead (&PackageList->KeyboardLayoutHdr);
73 InitializeListHead (&PackageList->StringPkgHdr);
74 InitializeListHead (&PackageList->FontPkgHdr);
75 InitializeListHead (&PackageList->SimpleFontPkgHdr);
76 PackageList->ImagePkg = NULL;
77 PackageList->DevicePathPkg = NULL;
78
79 //
80 // Create a new hii handle
81 //
82 HiiHandle = (HII_HANDLE *)AllocateZeroPool (sizeof (HII_HANDLE));
83 if (HiiHandle == NULL) {
84 FreePool (DatabaseRecord->PackageList);
85 FreePool (DatabaseRecord);
86 return EFI_OUT_OF_RESOURCES;
87 }
88
89 HiiHandle->Signature = HII_HANDLE_SIGNATURE;
90 //
91 // Backup the number of Hii handles
92 //
93 Private->HiiHandleCount++;
94 HiiHandle->Key = (UINTN)Private->HiiHandleCount;
95 //
96 // Insert the handle to hii handle list of the whole database.
97 //
98 InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);
99
100 DatabaseRecord->Handle = (EFI_HII_HANDLE)HiiHandle;
101
102 //
103 // Insert the Package List node to Package List link of the whole database.
104 //
105 InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);
106
107 *DatabaseNode = DatabaseRecord;
108
109 return EFI_SUCCESS;
110}
111
112/**
113 This function checks whether a handle is a valid EFI_HII_HANDLE
114 This is a internal function.
115
116 @param Handle Pointer to a EFI_HII_HANDLE
117
118 @retval TRUE Valid
119 @retval FALSE Invalid
120
121**/
122BOOLEAN
123IsHiiHandleValid (
124 EFI_HII_HANDLE Handle
125 )
126{
127 HII_HANDLE *HiiHandle;
128
129 HiiHandle = (HII_HANDLE *)Handle;
130
131 if (HiiHandle == NULL) {
132 return FALSE;
133 }
134
135 if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {
136 return FALSE;
137 }
138
139 return TRUE;
140}
141
142/**
143 This function invokes the matching registered function.
144 This is a internal function.
145
146 @param Private HII Database driver private structure.
147 @param NotifyType The type of change concerning the database.
148 @param PackageInstance Points to the package referred to by the
149 notification.
150 @param PackageType Package type
151 @param Handle The handle of the package list which contains the
152 specified package.
153
154 @retval EFI_SUCCESS Already checked all registered function and
155 invoked if matched.
156 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
157
158**/
159EFI_STATUS
160InvokeRegisteredFunction (
161 IN HII_DATABASE_PRIVATE_DATA *Private,
162 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
163 IN VOID *PackageInstance,
164 IN UINT8 PackageType,
165 IN EFI_HII_HANDLE Handle
166 )
167{
168 HII_DATABASE_NOTIFY *Notify;
169 LIST_ENTRY *Link;
170 EFI_HII_PACKAGE_HEADER *Package;
171 UINT8 *Buffer;
172 UINT32 BufferSize;
173 UINT32 HeaderSize;
174 UINT32 ImageBlockSize;
175 UINT32 PaletteInfoSize;
176
177 if ((Private == NULL) || ((NotifyType & 0xF) == 0) || (PackageInstance == NULL)) {
178 return EFI_INVALID_PARAMETER;
179 }
180
181 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
182 return EFI_INVALID_PARAMETER;
183 }
184
185 if (!IsHiiHandleValid (Handle)) {
186 return EFI_INVALID_PARAMETER;
187 }
188
189 Buffer = NULL;
190 Package = NULL;
191
192 //
193 // Convert the incoming package from hii database storage format to UEFI
194 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.
195 //
196 switch (PackageType) {
197 case EFI_HII_PACKAGE_TYPE_GUID:
198 Package = (EFI_HII_PACKAGE_HEADER *)(((HII_GUID_PACKAGE_INSTANCE *)PackageInstance)->GuidPkg);
199 break;
200
201 case EFI_HII_PACKAGE_FORMS:
202 BufferSize = ((HII_IFR_PACKAGE_INSTANCE *)PackageInstance)->FormPkgHdr.Length;
203 Buffer = (UINT8 *)AllocateZeroPool (BufferSize);
204 ASSERT (Buffer != NULL);
205 CopyMem (
206 Buffer,
207 &((HII_IFR_PACKAGE_INSTANCE *)PackageInstance)->FormPkgHdr,
208 sizeof (EFI_HII_PACKAGE_HEADER)
209 );
210 CopyMem (
211 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
212 ((HII_IFR_PACKAGE_INSTANCE *)PackageInstance)->IfrData,
213 BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)
214 );
215 Package = (EFI_HII_PACKAGE_HEADER *)Buffer;
216 break;
217
218 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
219 Package = (EFI_HII_PACKAGE_HEADER *)(((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *)PackageInstance)->KeyboardPkg);
220 break;
221
222 case EFI_HII_PACKAGE_STRINGS:
223 BufferSize = ((HII_STRING_PACKAGE_INSTANCE *)PackageInstance)->StringPkgHdr->Header.Length;
224 HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *)PackageInstance)->StringPkgHdr->HdrSize;
225 Buffer = (UINT8 *)AllocateZeroPool (BufferSize);
226 ASSERT (Buffer != NULL);
227 CopyMem (
228 Buffer,
229 ((HII_STRING_PACKAGE_INSTANCE *)PackageInstance)->StringPkgHdr,
230 HeaderSize
231 );
232 CopyMem (
233 Buffer + HeaderSize,
234 ((HII_STRING_PACKAGE_INSTANCE *)PackageInstance)->StringBlock,
235 BufferSize - HeaderSize
236 );
237 Package = (EFI_HII_PACKAGE_HEADER *)Buffer;
238 break;
239
240 case EFI_HII_PACKAGE_FONTS:
241 BufferSize = ((HII_FONT_PACKAGE_INSTANCE *)PackageInstance)->FontPkgHdr->Header.Length;
242 HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *)PackageInstance)->FontPkgHdr->HdrSize;
243 Buffer = (UINT8 *)AllocateZeroPool (BufferSize);
244 ASSERT (Buffer != NULL);
245 CopyMem (
246 Buffer,
247 ((HII_FONT_PACKAGE_INSTANCE *)PackageInstance)->FontPkgHdr,
248 HeaderSize
249 );
250 CopyMem (
251 Buffer + HeaderSize,
252 ((HII_FONT_PACKAGE_INSTANCE *)PackageInstance)->GlyphBlock,
253 BufferSize - HeaderSize
254 );
255 Package = (EFI_HII_PACKAGE_HEADER *)Buffer;
256 break;
257
258 case EFI_HII_PACKAGE_IMAGES:
259 BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->ImagePkgHdr.Header.Length;
260 HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
261 Buffer = (UINT8 *)AllocateZeroPool (BufferSize);
262 ASSERT (Buffer != NULL);
263
264 CopyMem (
265 Buffer,
266 &((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->ImagePkgHdr,
267 HeaderSize
268 );
269 CopyMem (
270 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
271 &HeaderSize,
272 sizeof (UINT32)
273 );
274
275 ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->ImageBlockSize;
276 if (ImageBlockSize != 0) {
277 CopyMem (
278 Buffer + HeaderSize,
279 ((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->ImageBlock,
280 ImageBlockSize
281 );
282 }
283
284 PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->PaletteInfoSize;
285 if (PaletteInfoSize != 0) {
286 CopyMem (
287 Buffer + HeaderSize + ImageBlockSize,
288 ((HII_IMAGE_PACKAGE_INSTANCE *)PackageInstance)->PaletteBlock,
289 PaletteInfoSize
290 );
291 HeaderSize += ImageBlockSize;
292 CopyMem (
293 Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),
294 &HeaderSize,
295 sizeof (UINT32)
296 );
297 }
298
299 Package = (EFI_HII_PACKAGE_HEADER *)Buffer;
300 break;
301
302 case EFI_HII_PACKAGE_SIMPLE_FONTS:
303 BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *)PackageInstance)->SimpleFontPkgHdr->Header.Length;
304 Buffer = (UINT8 *)AllocateZeroPool (BufferSize);
305 ASSERT (Buffer != NULL);
306 CopyMem (
307 Buffer,
308 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *)PackageInstance)->SimpleFontPkgHdr,
309 BufferSize
310 );
311 Package = (EFI_HII_PACKAGE_HEADER *)Buffer;
312 break;
313
314 case EFI_HII_PACKAGE_DEVICE_PATH:
315 Package = (EFI_HII_PACKAGE_HEADER *)PackageInstance;
316 break;
317
318 default:
319 return EFI_INVALID_PARAMETER;
320 }
321
322 for (Link = Private->DatabaseNotifyList.ForwardLink;
323 Link != &Private->DatabaseNotifyList;
324 Link = Link->ForwardLink
325 )
326 {
327 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
328 if ((Notify->NotifyType == NotifyType) && (Notify->PackageType == PackageType)) {
329 //
330 // Check in case PackageGuid is not NULL when Package is GUID package
331 //
332 if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {
333 Notify->PackageGuid = NULL;
334 }
335
336 //
337 // Status of Registered Function is unknown so did not check it
338 //
339 Notify->PackageNotifyFn (
340 Notify->PackageType,
341 Notify->PackageGuid,
342 Package,
343 Handle,
344 NotifyType
345 );
346 }
347 }
348
349 if (Buffer != NULL) {
350 FreePool (Buffer);
351 }
352
353 return EFI_SUCCESS;
354}
355
356/**
357 This function insert a GUID package to a package list node.
358 This is a internal function.
359
360 @param PackageHdr Pointer to a buffer stored with GUID package
361 information.
362 @param NotifyType The type of change concerning the database.
363 @param PackageList Pointer to a package list which will be inserted
364 to.
365 @param Package Created GUID package
366
367 @retval EFI_SUCCESS Guid Package is inserted successfully.
368 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
369 Guid package.
370 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
371
372**/
373EFI_STATUS
374InsertGuidPackage (
375 IN VOID *PackageHdr,
376 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
377 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
378 OUT HII_GUID_PACKAGE_INSTANCE **Package
379 )
380{
381 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
382 EFI_HII_PACKAGE_HEADER PackageHeader;
383
384 if ((PackageHdr == NULL) || (PackageList == NULL)) {
385 return EFI_INVALID_PARAMETER;
386 }
387
388 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
389
390 //
391 // Create a GUID package node
392 //
393 GuidPackage = (HII_GUID_PACKAGE_INSTANCE *)AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));
394 if (GuidPackage == NULL) {
395 return EFI_OUT_OF_RESOURCES;
396 }
397
398 GuidPackage->GuidPkg = (UINT8 *)AllocateZeroPool (PackageHeader.Length);
399 if (GuidPackage->GuidPkg == NULL) {
400 FreePool (GuidPackage);
401 return EFI_OUT_OF_RESOURCES;
402 }
403
404 GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;
405 CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);
406 InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);
407 *Package = GuidPackage;
408
409 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
410 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
411 }
412
413 return EFI_SUCCESS;
414}
415
416/**
417 This function exports GUID packages to a buffer.
418 This is a internal function.
419
420 @param Private Hii database private structure.
421 @param Handle Identification of a package list.
422 @param PackageList Pointer to a package list which will be exported.
423 @param UsedSize The length of buffer be used.
424 @param BufferSize Length of the Buffer.
425 @param Buffer Allocated space for storing exported data.
426 @param ResultSize The size of the already exported content of this
427 package list.
428
429 @retval EFI_SUCCESS Guid Packages are exported successfully.
430 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
431
432**/
433EFI_STATUS
434ExportGuidPackages (
435 IN HII_DATABASE_PRIVATE_DATA *Private,
436 IN EFI_HII_HANDLE Handle,
437 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
438 IN UINTN UsedSize,
439 IN UINTN BufferSize,
440 IN OUT VOID *Buffer,
441 IN OUT UINTN *ResultSize
442 )
443{
444 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
445 LIST_ENTRY *Link;
446 UINTN PackageLength;
447 EFI_HII_PACKAGE_HEADER PackageHeader;
448 EFI_STATUS Status;
449
450 if ((PackageList == NULL) || (ResultSize == NULL)) {
451 return EFI_INVALID_PARAMETER;
452 }
453
454 if ((BufferSize > 0) && (Buffer == NULL)) {
455 return EFI_INVALID_PARAMETER;
456 }
457
458 PackageLength = 0;
459 Status = EFI_SUCCESS;
460
461 for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {
462 GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
463 CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
464 PackageLength += PackageHeader.Length;
465 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
466 Status = InvokeRegisteredFunction (
467 Private,
468 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
469 (VOID *)GuidPackage,
470 EFI_HII_PACKAGE_TYPE_GUID,
471 Handle
472 );
473 ASSERT_EFI_ERROR (Status);
474 CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);
475 Buffer = (UINT8 *)Buffer + PackageHeader.Length;
476 }
477 }
478
479 *ResultSize += PackageLength;
480 return EFI_SUCCESS;
481}
482
483/**
484 This function deletes all GUID packages from a package list node.
485 This is a internal function.
486
487 @param Private Hii database private data.
488 @param Handle Handle of the package list which contains the to
489 be removed GUID packages.
490 @param PackageList Pointer to a package list that contains removing
491 packages.
492
493 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.
494 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
495
496**/
497EFI_STATUS
498RemoveGuidPackages (
499 IN HII_DATABASE_PRIVATE_DATA *Private,
500 IN EFI_HII_HANDLE Handle,
501 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
502 )
503{
504 LIST_ENTRY *ListHead;
505 HII_GUID_PACKAGE_INSTANCE *Package;
506 EFI_STATUS Status;
507 EFI_HII_PACKAGE_HEADER PackageHeader;
508
509 ListHead = &PackageList->GuidPkgHdr;
510
511 while (!IsListEmpty (ListHead)) {
512 Package = CR (
513 ListHead->ForwardLink,
514 HII_GUID_PACKAGE_INSTANCE,
515 GuidEntry,
516 HII_GUID_PACKAGE_SIGNATURE
517 );
518 Status = InvokeRegisteredFunction (
519 Private,
520 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
521 (VOID *)Package,
522 EFI_HII_PACKAGE_TYPE_GUID,
523 Handle
524 );
525 if (EFI_ERROR (Status)) {
526 return Status;
527 }
528
529 RemoveEntryList (&Package->GuidEntry);
530 CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
531 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
532 FreePool (Package->GuidPkg);
533 FreePool (Package);
534 }
535
536 return EFI_SUCCESS;
537}
538
539/**
540 Check the input question related to EFI variable
541
542 @param IfrQuestionHdr Point to Question header
543 @param EfiVarStoreList Point to EFI VarStore List
544 @param EfiVarStoreNumber The number of EFI VarStore
545
546 @retval Index The index of the found EFI varstore in EFI varstore list
547 EfiVarStoreNumber will return if no EFI varstore is found.
548**/
549UINTN
550IsEfiVarStoreQuestion (
551 EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,
552 EFI_IFR_VARSTORE_EFI **EfiVarStoreList,
553 UINTN EfiVarStoreNumber
554 )
555{
556 UINTN Index;
557
558 for (Index = 0; Index < EfiVarStoreNumber; Index++) {
559 if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {
560 return Index;
561 }
562 }
563
564 return EfiVarStoreNumber;
565}
566
567/**
568 Find the matched variable from the input variable storage.
569
570 @param[in] VariableStorage Point to the variable storage header.
571 @param[in] VarGuid A unique identifier for the variable.
572 @param[in] VarAttribute The attributes bitmask for the variable.
573 @param[in] VarName A Null-terminated ascii string that is the name of the variable.
574
575 @return Pointer to the matched variable header or NULL if not found.
576**/
577AUTHENTICATED_VARIABLE_HEADER *
578AuthFindVariableData (
579 IN VARIABLE_STORE_HEADER *VariableStorage,
580 IN EFI_GUID *VarGuid,
581 IN UINT32 VarAttribute,
582 IN CHAR16 *VarName
583 )
584{
585 AUTHENTICATED_VARIABLE_HEADER *VariableHeader;
586 AUTHENTICATED_VARIABLE_HEADER *VariableEnd;
587
588 VariableEnd = (AUTHENTICATED_VARIABLE_HEADER *)((UINT8 *)VariableStorage + VariableStorage->Size);
589 VariableHeader = (AUTHENTICATED_VARIABLE_HEADER *)(VariableStorage + 1);
590 VariableHeader = (AUTHENTICATED_VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
591 while (VariableHeader < VariableEnd) {
592 if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&
593 (VariableHeader->Attributes == VarAttribute) &&
594 (StrCmp (VarName, (CHAR16 *)(VariableHeader + 1)) == 0))
595 {
596 return VariableHeader;
597 }
598
599 VariableHeader = (AUTHENTICATED_VARIABLE_HEADER *)((UINT8 *)VariableHeader + sizeof (AUTHENTICATED_VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);
600 VariableHeader = (AUTHENTICATED_VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
601 }
602
603 return NULL;
604}
605
606/**
607 Find the matched variable from the input variable storage.
608
609 @param[in] VariableStorage Point to the variable storage header.
610 @param[in] VarGuid A unique identifier for the variable.
611 @param[in] VarAttribute The attributes bitmask for the variable.
612 @param[in] VarName A Null-terminated ascii string that is the name of the variable.
613
614 @return Pointer to the matched variable header or NULL if not found.
615**/
616VARIABLE_HEADER *
617FindVariableData (
618 IN VARIABLE_STORE_HEADER *VariableStorage,
619 IN EFI_GUID *VarGuid,
620 IN UINT32 VarAttribute,
621 IN CHAR16 *VarName
622 )
623{
624 VARIABLE_HEADER *VariableHeader;
625 VARIABLE_HEADER *VariableEnd;
626
627 VariableEnd = (VARIABLE_HEADER *)((UINT8 *)VariableStorage + VariableStorage->Size);
628 VariableHeader = (VARIABLE_HEADER *)(VariableStorage + 1);
629 VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
630 while (VariableHeader < VariableEnd) {
631 if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&
632 (VariableHeader->Attributes == VarAttribute) &&
633 (StrCmp (VarName, (CHAR16 *)(VariableHeader + 1)) == 0))
634 {
635 return VariableHeader;
636 }
637
638 VariableHeader = (VARIABLE_HEADER *)((UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);
639 VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
640 }
641
642 return NULL;
643}
644
645/**
646 Find question default value from PcdNvStoreDefaultValueBuffer
647
648 @param DefaultId Default store ID
649 @param EfiVarStore Point to EFI VarStore header
650 @param IfrQuestionHdr Point to Question header
651 @param ValueBuffer Point to Buffer includes the found default setting
652 @param Width Width of the default value
653 @param BitFieldQuestion Whether the Question is stored in Bit field.
654
655 @retval EFI_SUCCESS Question default value is found.
656 @retval EFI_NOT_FOUND Question default value is not found.
657**/
658EFI_STATUS
659FindQuestionDefaultSetting (
660 IN UINT16 DefaultId,
661 IN EFI_IFR_VARSTORE_EFI *EfiVarStore,
662 IN EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,
663 OUT VOID *ValueBuffer,
664 IN UINTN Width,
665 IN BOOLEAN BitFieldQuestion
666 )
667{
668 AUTHENTICATED_VARIABLE_HEADER *AuthVariableHeader;
669 VARIABLE_HEADER *VariableHeader;
670 VARIABLE_STORE_HEADER *VariableStorage;
671 LIST_ENTRY *Link;
672 VARSTORAGE_DEFAULT_DATA *Entry;
673 VARIABLE_STORE_HEADER *NvStoreBuffer;
674 UINT8 *DataBuffer;
675 UINT8 *BufferEnd;
676 BOOLEAN IsFound;
677 UINTN Index;
678 UINT32 BufferValue;
679 UINT32 BitFieldVal;
680 UINTN BitOffset;
681 UINTN ByteOffset;
682 UINTN BitWidth;
683 UINTN StartBit;
684 UINTN EndBit;
685 PCD_DEFAULT_DATA *DataHeader;
686 PCD_DEFAULT_INFO *DefaultInfo;
687 PCD_DATA_DELTA *DeltaData;
688 BOOLEAN VarCheck;
689
690 if (gSkuId == 0xFFFFFFFFFFFFFFFF) {
691 gSkuId = LibPcdGetSku ();
692 }
693
694 //
695 // Find the DefaultId setting from the full DefaultSetting
696 //
697 VariableStorage = NULL;
698 Link = gVarStorageList.ForwardLink;
699 while (Link != &gVarStorageList) {
700 Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);
701 if (Entry->DefaultId == DefaultId) {
702 VariableStorage = Entry->VariableStorage;
703 break;
704 }
705
706 Link = Link->ForwardLink;
707 }
708
709 if (Link == &gVarStorageList) {
710 DataBuffer = (UINT8 *)PcdGetPtr (PcdNvStoreDefaultValueBuffer);
711 gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;
712 //
713 // The first section data includes NV storage default setting.
714 //
715 DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));
716 NvStoreBuffer = (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);
717 VariableStorage = AllocatePool (NvStoreBuffer->Size);
718 ASSERT (VariableStorage != NULL);
719 CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);
720
721 //
722 // Find the matched SkuId and DefaultId in the first section
723 //
724 IsFound = FALSE;
725 DefaultInfo = &(DataHeader->DefaultInfo[0]);
726 BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
727 while ((UINT8 *)DefaultInfo < BufferEnd) {
728 if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
729 IsFound = TRUE;
730 break;
731 }
732
733 DefaultInfo++;
734 }
735
736 //
737 // Find the matched SkuId and DefaultId in the remaining section
738 //
739 Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));
740 DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
741 while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {
742 DefaultInfo = &(DataHeader->DefaultInfo[0]);
743 BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
744 while ((UINT8 *)DefaultInfo < BufferEnd) {
745 if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
746 IsFound = TRUE;
747 break;
748 }
749
750 DefaultInfo++;
751 }
752
753 if (IsFound) {
754 DeltaData = (PCD_DATA_DELTA *)BufferEnd;
755 BufferEnd = (UINT8 *)DataHeader + DataHeader->DataSize;
756 while ((UINT8 *)DeltaData < BufferEnd) {
757 *((UINT8 *)VariableStorage + DeltaData->Offset) = (UINT8)DeltaData->Value;
758 DeltaData++;
759 }
760
761 break;
762 }
763
764 Index = (Index + DataHeader->DataSize + 7) & (~7);
765 DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
766 }
767
768 //
769 // Cache the found result in VarStorageList
770 //
771 if (!IsFound) {
772 FreePool (VariableStorage);
773 VariableStorage = NULL;
774 }
775
776 Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));
777 if (Entry != NULL) {
778 Entry->DefaultId = DefaultId;
779 Entry->VariableStorage = VariableStorage;
780 InsertTailList (&gVarStorageList, &Entry->Entry);
781 } else if (VariableStorage != NULL) {
782 FreePool (VariableStorage);
783 VariableStorage = NULL;
784 }
785 }
786
787 //
788 // The matched variable storage is not found.
789 //
790 if (VariableStorage == NULL) {
791 return EFI_NOT_FOUND;
792 }
793
794 VarCheck = (BOOLEAN)(CompareGuid (&VariableStorage->Signature, &gEfiAuthenticatedVariableGuid));
795
796 if (VarCheck) {
797 //
798 // Find the question default value from the variable storage
799 //
800 AuthVariableHeader = AuthFindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *)EfiVarStore->Name);
801 if (AuthVariableHeader == NULL) {
802 return EFI_NOT_FOUND;
803 }
804
805 StartBit = 0;
806 EndBit = 0;
807 ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
808 if (BitFieldQuestion) {
809 BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
810 ByteOffset = BitOffset / 8;
811 BitWidth = Width;
812 StartBit = BitOffset % 8;
813 EndBit = StartBit + BitWidth - 1;
814 Width = EndBit / 8 + 1;
815 }
816
817 if (AuthVariableHeader->DataSize < ByteOffset + Width) {
818 return EFI_INVALID_PARAMETER;
819 }
820
821 //
822 // Copy the question value
823 //
824 if (ValueBuffer != NULL) {
825 if (BitFieldQuestion) {
826 CopyMem (&BufferValue, (UINT8 *)AuthVariableHeader + sizeof (AUTHENTICATED_VARIABLE_HEADER) + AuthVariableHeader->NameSize + ByteOffset, Width);
827 BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);
828 CopyMem (ValueBuffer, &BitFieldVal, sizeof (UINT32));
829 } else {
830 CopyMem (ValueBuffer, (UINT8 *)AuthVariableHeader + sizeof (AUTHENTICATED_VARIABLE_HEADER) + AuthVariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);
831 }
832 }
833 } else {
834 //
835 // Find the question default value from the variable storage
836 //
837 VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *)EfiVarStore->Name);
838 if (VariableHeader == NULL) {
839 return EFI_NOT_FOUND;
840 }
841
842 StartBit = 0;
843 EndBit = 0;
844 ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
845 if (BitFieldQuestion) {
846 BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
847 ByteOffset = BitOffset / 8;
848 BitWidth = Width;
849 StartBit = BitOffset % 8;
850 EndBit = StartBit + BitWidth - 1;
851 Width = EndBit / 8 + 1;
852 }
853
854 if (VariableHeader->DataSize < ByteOffset + Width) {
855 return EFI_INVALID_PARAMETER;
856 }
857
858 //
859 // Copy the question value
860 //
861 if (ValueBuffer != NULL) {
862 if (BitFieldQuestion) {
863 CopyMem (&BufferValue, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);
864 BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);
865 CopyMem (ValueBuffer, &BitFieldVal, sizeof (UINT32));
866 } else {
867 CopyMem (ValueBuffer, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);
868 }
869 }
870 }
871
872 return EFI_SUCCESS;
873}
874
875/**
876 Update IFR default setting in Form Package.
877
878 @param FormPackage Form Package to be updated
879
880**/
881VOID
882UpdateDefaultSettingInFormPackage (
883 HII_IFR_PACKAGE_INSTANCE *FormPackage
884 )
885{
886 UINTN IfrOffset;
887 UINTN PackageLength;
888 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
889 EFI_IFR_OP_HEADER *IfrOpHdr;
890 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
891 UINT8 IfrQuestionType;
892 UINT8 IfrScope;
893 EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;
894 EFI_IFR_VARSTORE_EFI **EfiVarStoreList;
895 UINTN EfiVarStoreMaxNum;
896 UINTN EfiVarStoreNumber;
897 UINT16 *DefaultIdList;
898 UINTN DefaultIdNumber;
899 UINTN DefaultIdMaxNum;
900 UINTN Index;
901 UINTN EfiVarStoreIndex;
902 EFI_IFR_TYPE_VALUE IfrValue;
903 EFI_IFR_TYPE_VALUE IfrManufactValue;
904 BOOLEAN StandardDefaultIsSet;
905 BOOLEAN ManufactDefaultIsSet;
906 EFI_IFR_CHECKBOX *IfrCheckBox;
907 EFI_STATUS Status;
908 EFI_IFR_DEFAULT *IfrDefault;
909 UINTN Width;
910 EFI_IFR_QUESTION_HEADER VarStoreQuestionHeader;
911 BOOLEAN QuestionReferBitField;
912
913 //
914 // If no default setting, do nothing
915 //
916 if (gNvDefaultStoreSize == 0) {
917 gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
918 }
919
920 if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
921 return;
922 }
923
924 ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));
925 PackageLength = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
926 Width = 0;
927 IfrOffset = 0;
928 IfrScope = 0;
929 IfrOpHdr = (EFI_IFR_OP_HEADER *)FormPackage->IfrData;
930 IfrQuestionHdr = NULL;
931 IfrQuestionType = 0;
932 EfiVarStoreMaxNum = 0;
933 EfiVarStoreNumber = 0;
934 DefaultIdMaxNum = 0;
935 DefaultIdNumber = 0;
936 EfiVarStoreList = NULL;
937 DefaultIdList = NULL;
938 StandardDefaultIsSet = FALSE;
939 ManufactDefaultIsSet = FALSE;
940 QuestionReferBitField = FALSE;
941
942 while (IfrOffset < PackageLength) {
943 switch (IfrOpHdr->OpCode) {
944 case EFI_IFR_VARSTORE_EFI_OP:
945 if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {
946 //
947 // Reallocate EFI VarStore Buffer
948 //
949 EfiVarStoreList = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);
950 if (EfiVarStoreList == NULL) {
951 goto Done;
952 }
953
954 EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;
955 }
956
957 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
958 //
959 // Convert VarStore Name from ASCII string to Unicode string.
960 //
961 EfiVarStoreList[EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));
962 if (EfiVarStoreList[EfiVarStoreNumber] == NULL) {
963 break;
964 }
965
966 CopyMem (EfiVarStoreList[EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);
967 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(EfiVarStoreList[EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
968 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);
969 if (!EFI_ERROR (Status)) {
970 EfiVarStoreNumber++;
971 } else {
972 FreePool (EfiVarStoreList[EfiVarStoreNumber]);
973 EfiVarStoreList[EfiVarStoreNumber] = NULL;
974 }
975
976 break;
977 case EFI_IFR_DEFAULTSTORE_OP:
978 if (DefaultIdNumber >= DefaultIdMaxNum) {
979 //
980 // Reallocate DefaultIdNumber
981 //
982 DefaultIdList = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);
983 if (DefaultIdList == NULL) {
984 goto Done;
985 }
986
987 DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;
988 }
989
990 DefaultIdList[DefaultIdNumber++] = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;
991 break;
992 case EFI_IFR_FORM_OP:
993 case EFI_IFR_FORM_MAP_OP:
994 //
995 // No EFI varstore is found and directly return.
996 //
997 if ((EfiVarStoreNumber == 0) || (DefaultIdNumber == 0)) {
998 goto Done;
999 }
1000
1001 break;
1002 case EFI_IFR_CHECKBOX_OP:
1003 IfrScope = IfrOpHdr->Scope;
1004 IfrQuestionType = IfrOpHdr->OpCode;
1005 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
1006 IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;
1007 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
1008 Width = sizeof (BOOLEAN);
1009 if (EfiVarStoreIndex < EfiVarStoreNumber) {
1010 for (Index = 0; Index < DefaultIdNumber; Index++) {
1011 if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
1012 Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
1013 if (!EFI_ERROR (Status)) {
1014 if (IfrValue.b) {
1015 IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;
1016 } else {
1017 IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);
1018 }
1019 }
1020 } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
1021 Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
1022 if (!EFI_ERROR (Status)) {
1023 if (IfrValue.b) {
1024 IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;
1025 } else {
1026 IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);
1027 }
1028 }
1029 }
1030 }
1031 }
1032
1033 break;
1034 case EFI_IFR_NUMERIC_OP:
1035 IfrScope = IfrOpHdr->Scope;
1036 IfrQuestionType = IfrOpHdr->OpCode;
1037 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
1038 if (QuestionReferBitField) {
1039 Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
1040 } else {
1041 Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
1042 }
1043
1044 break;
1045 case EFI_IFR_ONE_OF_OP:
1046 IfrScope = IfrOpHdr->Scope;
1047 IfrQuestionType = IfrOpHdr->OpCode;
1048 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
1049 if (QuestionReferBitField) {
1050 Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
1051 } else {
1052 Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
1053 }
1054
1055 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
1056 StandardDefaultIsSet = FALSE;
1057 ManufactDefaultIsSet = FALSE;
1058 //
1059 // Find Default and Manufacturing default for OneOf question
1060 //
1061 if (EfiVarStoreIndex < EfiVarStoreNumber) {
1062 for (Index = 0; Index < DefaultIdNumber; Index++) {
1063 if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
1064 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);
1065 if (!EFI_ERROR (Status)) {
1066 StandardDefaultIsSet = TRUE;
1067 }
1068 } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
1069 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);
1070 if (!EFI_ERROR (Status)) {
1071 ManufactDefaultIsSet = TRUE;
1072 }
1073 }
1074 }
1075 }
1076
1077 break;
1078 case EFI_IFR_ORDERED_LIST_OP:
1079 IfrScope = IfrOpHdr->Scope;
1080 IfrQuestionType = IfrOpHdr->OpCode;
1081 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
1082 break;
1083 case EFI_IFR_ONE_OF_OPTION_OP:
1084 if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
1085 IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
1086 if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {
1087 Width = (UINTN)((UINT32)1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));
1088 if (StandardDefaultIsSet) {
1089 if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {
1090 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;
1091 } else {
1092 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;
1093 }
1094 }
1095
1096 if (ManufactDefaultIsSet) {
1097 if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {
1098 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;
1099 } else {
1100 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;
1101 }
1102 }
1103 }
1104 }
1105
1106 break;
1107 case EFI_IFR_DEFAULT_OP:
1108 if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
1109 IfrDefault = (EFI_IFR_DEFAULT *)IfrOpHdr;
1110 //
1111 // Collect default value width
1112 //
1113 if (!QuestionReferBitField) {
1114 Width = 0;
1115 if ((IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN)) {
1116 Width = 1;
1117 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {
1118 Width = 2;
1119 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {
1120 Width = 4;
1121 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
1122 Width = 8;
1123 } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {
1124 Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);
1125 }
1126 }
1127
1128 //
1129 // Update the default value
1130 //
1131 if (Width > 0) {
1132 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
1133 if (EfiVarStoreIndex < EfiVarStoreNumber) {
1134 Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);
1135 }
1136 }
1137 }
1138
1139 break;
1140 case EFI_IFR_END_OP:
1141 if (IfrQuestionHdr != NULL) {
1142 if (IfrScope > 0) {
1143 IfrScope--;
1144 }
1145
1146 if (IfrScope == 0) {
1147 IfrQuestionHdr = NULL;
1148 QuestionReferBitField = FALSE;
1149 }
1150 }
1151
1152 break;
1153 case EFI_IFR_GUID_OP:
1154 if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
1155 QuestionReferBitField = TRUE;
1156 }
1157
1158 break;
1159 default:
1160 break;
1161 }
1162
1163 IfrOffset = IfrOffset + IfrOpHdr->Length;
1164 IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *)IfrOpHdr + IfrOpHdr->Length);
1165 if (IfrScope > 0) {
1166 IfrScope += IfrOpHdr->Scope;
1167 }
1168 }
1169
1170Done:
1171 if (EfiVarStoreList != NULL) {
1172 for (Index = 0; Index < EfiVarStoreNumber; Index++) {
1173 FreePool (EfiVarStoreList[Index]);
1174 }
1175 }
1176
1177 return;
1178}
1179
1180/**
1181 This function insert a Form package to a package list node.
1182 This is a internal function.
1183
1184 @param PackageHdr Pointer to a buffer stored with Form package
1185 information.
1186 @param NotifyType The type of change concerning the database.
1187 @param PackageList Pointer to a package list which will be inserted
1188 to.
1189 @param Package Created Form package
1190
1191 @retval EFI_SUCCESS Form Package is inserted successfully.
1192 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1193 Form package.
1194 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1195
1196**/
1197EFI_STATUS
1198InsertFormPackage (
1199 IN VOID *PackageHdr,
1200 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1201 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1202 OUT HII_IFR_PACKAGE_INSTANCE **Package
1203 )
1204{
1205 HII_IFR_PACKAGE_INSTANCE *FormPackage;
1206 EFI_HII_PACKAGE_HEADER PackageHeader;
1207
1208 if ((PackageHdr == NULL) || (PackageList == NULL)) {
1209 return EFI_INVALID_PARAMETER;
1210 }
1211
1212 //
1213 // Get the length of the package, including package header itself
1214 //
1215 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
1216
1217 //
1218 // Create a Form package node
1219 //
1220 FormPackage = (HII_IFR_PACKAGE_INSTANCE *)AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));
1221 if (FormPackage == NULL) {
1222 return EFI_OUT_OF_RESOURCES;
1223 }
1224
1225 FormPackage->IfrData = (UINT8 *)AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));
1226 if (FormPackage->IfrData == NULL) {
1227 FreePool (FormPackage);
1228 return EFI_OUT_OF_RESOURCES;
1229 }
1230
1231 FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;
1232 //
1233 // Copy Package Header
1234 //
1235 CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
1236
1237 //
1238 // Copy Ifr contents
1239 //
1240 CopyMem (
1241 FormPackage->IfrData,
1242 (UINT8 *)PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),
1243 PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)
1244 );
1245
1246 InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);
1247 *Package = FormPackage;
1248
1249 //
1250 // Update FormPackage with the default setting
1251 //
1252 UpdateDefaultSettingInFormPackage (FormPackage);
1253
1254 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1255 PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;
1256 }
1257
1258 return EFI_SUCCESS;
1259}
1260
1261/**
1262 This function exports Form packages to a buffer.
1263 This is a internal function.
1264
1265 @param Private Hii database private structure.
1266 @param Handle Identification of a package list.
1267 @param PackageList Pointer to a package list which will be exported.
1268 @param UsedSize The length of buffer be used.
1269 @param BufferSize Length of the Buffer.
1270 @param Buffer Allocated space for storing exported data.
1271 @param ResultSize The size of the already exported content of this
1272 package list.
1273
1274 @retval EFI_SUCCESS Form Packages are exported successfully.
1275 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1276
1277**/
1278EFI_STATUS
1279ExportFormPackages (
1280 IN HII_DATABASE_PRIVATE_DATA *Private,
1281 IN EFI_HII_HANDLE Handle,
1282 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1283 IN UINTN UsedSize,
1284 IN UINTN BufferSize,
1285 IN OUT VOID *Buffer,
1286 IN OUT UINTN *ResultSize
1287 )
1288{
1289 HII_IFR_PACKAGE_INSTANCE *FormPackage;
1290 UINTN PackageLength;
1291 LIST_ENTRY *Link;
1292 EFI_STATUS Status;
1293
1294 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
1295 return EFI_INVALID_PARAMETER;
1296 }
1297
1298 if ((BufferSize > 0) && (Buffer == NULL)) {
1299 return EFI_INVALID_PARAMETER;
1300 }
1301
1302 PackageLength = 0;
1303 Status = EFI_SUCCESS;
1304
1305 //
1306 // Export Form packages.
1307 //
1308 for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {
1309 FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);
1310 PackageLength += FormPackage->FormPkgHdr.Length;
1311 if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {
1312 //
1313 // Invoke registered notification if exists
1314 //
1315 Status = InvokeRegisteredFunction (
1316 Private,
1317 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1318 (VOID *)FormPackage,
1319 EFI_HII_PACKAGE_FORMS,
1320 Handle
1321 );
1322 ASSERT_EFI_ERROR (Status);
1323 //
1324 // Copy the Form package content.
1325 //
1326 CopyMem (Buffer, (VOID *)(&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));
1327 Buffer = (UINT8 *)Buffer + sizeof (EFI_HII_PACKAGE_HEADER);
1328 CopyMem (
1329 Buffer,
1330 (VOID *)FormPackage->IfrData,
1331 FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)
1332 );
1333 Buffer = (UINT8 *)Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
1334 }
1335 }
1336
1337 *ResultSize += PackageLength;
1338
1339 return EFI_SUCCESS;
1340}
1341
1342/**
1343 This function deletes all Form packages from a package list node.
1344 This is a internal function.
1345
1346 @param Private Hii database private data.
1347 @param Handle Handle of the package list which contains the to
1348 be removed Form packages.
1349 @param PackageList Pointer to a package list that contains removing
1350 packages.
1351
1352 @retval EFI_SUCCESS Form Package(s) is deleted successfully.
1353 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1354
1355**/
1356EFI_STATUS
1357RemoveFormPackages (
1358 IN HII_DATABASE_PRIVATE_DATA *Private,
1359 IN EFI_HII_HANDLE Handle,
1360 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1361 )
1362{
1363 LIST_ENTRY *ListHead;
1364 HII_IFR_PACKAGE_INSTANCE *Package;
1365 EFI_STATUS Status;
1366
1367 ListHead = &PackageList->FormPkgHdr;
1368
1369 while (!IsListEmpty (ListHead)) {
1370 Package = CR (
1371 ListHead->ForwardLink,
1372 HII_IFR_PACKAGE_INSTANCE,
1373 IfrEntry,
1374 HII_IFR_PACKAGE_SIGNATURE
1375 );
1376 Status = InvokeRegisteredFunction (
1377 Private,
1378 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1379 (VOID *)Package,
1380 EFI_HII_PACKAGE_FORMS,
1381 Handle
1382 );
1383 if (EFI_ERROR (Status)) {
1384 return Status;
1385 }
1386
1387 RemoveEntryList (&Package->IfrEntry);
1388 PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;
1389 FreePool (Package->IfrData);
1390 FreePool (Package);
1391 //
1392 // If Hii runtime support feature is enabled,
1393 // will export Hii info for runtime use after ReadyToBoot event triggered.
1394 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
1395 // will need to export the content of HiiDatabase.
1396 // But if form packages removed, also need to export the ConfigResp string
1397 //
1398 if (gExportAfterReadyToBoot) {
1399 gExportConfigResp = TRUE;
1400 }
1401 }
1402
1403 return EFI_SUCCESS;
1404}
1405
1406/**
1407 This function insert a String package to a package list node.
1408 This is a internal function.
1409
1410 @param Private Hii database private structure.
1411 @param PackageHdr Pointer to a buffer stored with String package
1412 information.
1413 @param NotifyType The type of change concerning the database.
1414 @param PackageList Pointer to a package list which will be inserted
1415 to.
1416 @param Package Created String package
1417
1418 @retval EFI_SUCCESS String Package is inserted successfully.
1419 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1420 String package.
1421 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1422 @retval EFI_UNSUPPORTED A string package with the same language already
1423 exists in current package list.
1424
1425**/
1426EFI_STATUS
1427InsertStringPackage (
1428 IN HII_DATABASE_PRIVATE_DATA *Private,
1429 IN VOID *PackageHdr,
1430 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1431 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1432 OUT HII_STRING_PACKAGE_INSTANCE **Package
1433 )
1434{
1435 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1436 UINT32 HeaderSize;
1437 EFI_STATUS Status;
1438 EFI_HII_PACKAGE_HEADER PackageHeader;
1439 CHAR8 *Language;
1440 UINT32 LanguageSize;
1441 LIST_ENTRY *Link;
1442
1443 if ((Private == NULL) || (PackageHdr == NULL) || (PackageList == NULL)) {
1444 return EFI_INVALID_PARAMETER;
1445 }
1446
1447 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
1448 return EFI_INVALID_PARAMETER;
1449 }
1450
1451 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
1452 CopyMem (&HeaderSize, (UINT8 *)PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
1453
1454 //
1455 // It is illegal to have two string packages with same language within one packagelist
1456 // since the stringid will be duplicate if so. Check it to avoid this potential issue.
1457 //
1458 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);
1459 Language = (CHAR8 *)AllocateZeroPool (LanguageSize);
1460 if (Language == NULL) {
1461 return EFI_OUT_OF_RESOURCES;
1462 }
1463
1464 AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *)PackageHdr + HeaderSize - LanguageSize);
1465 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
1466 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1467 if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {
1468 FreePool (Language);
1469 return EFI_UNSUPPORTED;
1470 }
1471 }
1472
1473 FreePool (Language);
1474
1475 //
1476 // Create a String package node
1477 //
1478 StringPackage = (HII_STRING_PACKAGE_INSTANCE *)AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
1479 if (StringPackage == NULL) {
1480 Status = EFI_OUT_OF_RESOURCES;
1481 goto Error;
1482 }
1483
1484 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *)AllocateZeroPool (HeaderSize);
1485 if (StringPackage->StringPkgHdr == NULL) {
1486 Status = EFI_OUT_OF_RESOURCES;
1487 goto Error;
1488 }
1489
1490 StringPackage->StringBlock = (UINT8 *)AllocateZeroPool (PackageHeader.Length - HeaderSize);
1491 if (StringPackage->StringBlock == NULL) {
1492 Status = EFI_OUT_OF_RESOURCES;
1493 goto Error;
1494 }
1495
1496 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
1497 StringPackage->FontId = 0;
1498 InitializeListHead (&StringPackage->FontInfoList);
1499
1500 //
1501 // Copy the String package header.
1502 //
1503 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);
1504
1505 //
1506 // Copy the String blocks
1507 //
1508 CopyMem (
1509 StringPackage->StringBlock,
1510 (UINT8 *)PackageHdr + HeaderSize,
1511 PackageHeader.Length - HeaderSize
1512 );
1513
1514 //
1515 // Collect all font block info
1516 //
1517 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID)(-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL);
1518 if (EFI_ERROR (Status)) {
1519 return Status;
1520 }
1521
1522 //
1523 // Insert to String package array
1524 //
1525 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);
1526 *Package = StringPackage;
1527
1528 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1529 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
1530 }
1531
1532 return EFI_SUCCESS;
1533
1534Error:
1535
1536 if (StringPackage != NULL) {
1537 if (StringPackage->StringBlock != NULL) {
1538 FreePool (StringPackage->StringBlock);
1539 }
1540
1541 if (StringPackage->StringPkgHdr != NULL) {
1542 FreePool (StringPackage->StringPkgHdr);
1543 }
1544
1545 FreePool (StringPackage);
1546 }
1547
1548 return Status;
1549}
1550
1551/**
1552 Adjust all string packages in a single package list to have the same max string ID.
1553
1554 @param PackageList Pointer to a package list which will be adjusted.
1555
1556 @retval EFI_SUCCESS Adjust all string packages successfully.
1557 @retval others Can't adjust string packages.
1558
1559**/
1560EFI_STATUS
1561AdjustStringPackage (
1562 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1563 )
1564{
1565 LIST_ENTRY *Link;
1566 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1567 UINT32 Skip2BlockSize;
1568 UINT32 OldBlockSize;
1569 UINT8 *StringBlock;
1570 UINT8 *BlockPtr;
1571 EFI_STRING_ID MaxStringId;
1572 UINT16 SkipCount;
1573
1574 MaxStringId = 0;
1575 for (Link = PackageList->StringPkgHdr.ForwardLink;
1576 Link != &PackageList->StringPkgHdr;
1577 Link = Link->ForwardLink
1578 )
1579 {
1580 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1581 if (MaxStringId < StringPackage->MaxStringId) {
1582 MaxStringId = StringPackage->MaxStringId;
1583 }
1584 }
1585
1586 for (Link = PackageList->StringPkgHdr.ForwardLink;
1587 Link != &PackageList->StringPkgHdr;
1588 Link = Link->ForwardLink
1589 )
1590 {
1591 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1592 if (StringPackage->MaxStringId < MaxStringId) {
1593 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1594 //
1595 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.
1596 //
1597 SkipCount = (UINT16)(MaxStringId - StringPackage->MaxStringId);
1598 Skip2BlockSize = (UINT32)sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
1599
1600 StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Skip2BlockSize);
1601 if (StringBlock == NULL) {
1602 return EFI_OUT_OF_RESOURCES;
1603 }
1604
1605 //
1606 // Copy original string blocks, except the EFI_HII_SIBT_END.
1607 //
1608 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1609 //
1610 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks
1611 //
1612 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1613 *BlockPtr = EFI_HII_SIBT_SKIP2;
1614 CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));
1615 BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
1616
1617 //
1618 // Append a EFI_HII_SIBT_END block to the end.
1619 //
1620 *BlockPtr = EFI_HII_SIBT_END;
1621 FreePool (StringPackage->StringBlock);
1622 StringPackage->StringBlock = StringBlock;
1623 StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;
1624 PackageList->PackageListHdr.PackageLength += Skip2BlockSize;
1625 StringPackage->MaxStringId = MaxStringId;
1626 }
1627 }
1628
1629 return EFI_SUCCESS;
1630}
1631
1632/**
1633 This function exports String packages to a buffer.
1634 This is a internal function.
1635
1636 @param Private Hii database private structure.
1637 @param Handle Identification of a package list.
1638 @param PackageList Pointer to a package list which will be exported.
1639 @param UsedSize The length of buffer be used.
1640 @param BufferSize Length of the Buffer.
1641 @param Buffer Allocated space for storing exported data.
1642 @param ResultSize The size of the already exported content of this
1643 package list.
1644
1645 @retval EFI_SUCCESS String Packages are exported successfully.
1646 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1647
1648**/
1649EFI_STATUS
1650ExportStringPackages (
1651 IN HII_DATABASE_PRIVATE_DATA *Private,
1652 IN EFI_HII_HANDLE Handle,
1653 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1654 IN UINTN UsedSize,
1655 IN UINTN BufferSize,
1656 IN OUT VOID *Buffer,
1657 IN OUT UINTN *ResultSize
1658 )
1659{
1660 LIST_ENTRY *Link;
1661 UINTN PackageLength;
1662 EFI_STATUS Status;
1663 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1664
1665 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
1666 return EFI_INVALID_PARAMETER;
1667 }
1668
1669 if ((BufferSize > 0) && (Buffer == NULL)) {
1670 return EFI_INVALID_PARAMETER;
1671 }
1672
1673 PackageLength = 0;
1674 Status = EFI_SUCCESS;
1675
1676 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
1677 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1678 PackageLength += StringPackage->StringPkgHdr->Header.Length;
1679 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
1680 //
1681 // Invoke registered notification function with EXPORT_PACK notify type
1682 //
1683 Status = InvokeRegisteredFunction (
1684 Private,
1685 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1686 (VOID *)StringPackage,
1687 EFI_HII_PACKAGE_STRINGS,
1688 Handle
1689 );
1690 ASSERT_EFI_ERROR (Status);
1691 //
1692 // Copy String package header
1693 //
1694 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);
1695 Buffer = (UINT8 *)Buffer + StringPackage->StringPkgHdr->HdrSize;
1696
1697 //
1698 // Copy String blocks information
1699 //
1700 CopyMem (
1701 Buffer,
1702 StringPackage->StringBlock,
1703 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize
1704 );
1705 Buffer = (UINT8 *)Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1706 }
1707 }
1708
1709 *ResultSize += PackageLength;
1710 return EFI_SUCCESS;
1711}
1712
1713/**
1714 This function deletes all String packages from a package list node.
1715 This is a internal function.
1716
1717 @param Private Hii database private data.
1718 @param Handle Handle of the package list which contains the to
1719 be removed String packages.
1720 @param PackageList Pointer to a package list that contains removing
1721 packages.
1722
1723 @retval EFI_SUCCESS String Package(s) is deleted successfully.
1724 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1725
1726**/
1727EFI_STATUS
1728RemoveStringPackages (
1729 IN HII_DATABASE_PRIVATE_DATA *Private,
1730 IN EFI_HII_HANDLE Handle,
1731 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
1732 )
1733{
1734 LIST_ENTRY *ListHead;
1735 HII_STRING_PACKAGE_INSTANCE *Package;
1736 HII_FONT_INFO *FontInfo;
1737 EFI_STATUS Status;
1738
1739 ListHead = &PackageList->StringPkgHdr;
1740
1741 while (!IsListEmpty (ListHead)) {
1742 Package = CR (
1743 ListHead->ForwardLink,
1744 HII_STRING_PACKAGE_INSTANCE,
1745 StringEntry,
1746 HII_STRING_PACKAGE_SIGNATURE
1747 );
1748 Status = InvokeRegisteredFunction (
1749 Private,
1750 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
1751 (VOID *)Package,
1752 EFI_HII_PACKAGE_STRINGS,
1753 Handle
1754 );
1755 if (EFI_ERROR (Status)) {
1756 return Status;
1757 }
1758
1759 RemoveEntryList (&Package->StringEntry);
1760 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;
1761 FreePool (Package->StringBlock);
1762 FreePool (Package->StringPkgHdr);
1763 //
1764 // Delete font information
1765 //
1766 while (!IsListEmpty (&Package->FontInfoList)) {
1767 FontInfo = CR (
1768 Package->FontInfoList.ForwardLink,
1769 HII_FONT_INFO,
1770 Entry,
1771 HII_FONT_INFO_SIGNATURE
1772 );
1773 RemoveEntryList (&FontInfo->Entry);
1774 FreePool (FontInfo);
1775 }
1776
1777 FreePool (Package);
1778 }
1779
1780 return EFI_SUCCESS;
1781}
1782
1783/**
1784 This function insert a Font package to a package list node.
1785 This is a internal function.
1786
1787 @param Private Hii database private structure.
1788 @param PackageHdr Pointer to a buffer stored with Font package
1789 information.
1790 @param NotifyType The type of change concerning the database.
1791 @param PackageList Pointer to a package list which will be inserted
1792 to.
1793 @param Package Created Font package
1794
1795 @retval EFI_SUCCESS Font Package is inserted successfully.
1796 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1797 Font package.
1798 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1799 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already
1800 exists in current hii database.
1801
1802**/
1803EFI_STATUS
1804InsertFontPackage (
1805 IN HII_DATABASE_PRIVATE_DATA *Private,
1806 IN VOID *PackageHdr,
1807 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
1808 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1809 OUT HII_FONT_PACKAGE_INSTANCE **Package
1810 )
1811{
1812 HII_FONT_PACKAGE_INSTANCE *FontPackage;
1813 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;
1814 UINT32 HeaderSize;
1815 EFI_STATUS Status;
1816 EFI_HII_PACKAGE_HEADER PackageHeader;
1817 EFI_FONT_INFO *FontInfo;
1818 UINT32 FontInfoSize;
1819 HII_GLOBAL_FONT_INFO *GlobalFont;
1820
1821 if ((Private == NULL) || (PackageHdr == NULL) || (PackageList == NULL)) {
1822 return EFI_INVALID_PARAMETER;
1823 }
1824
1825 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
1826 CopyMem (&HeaderSize, (UINT8 *)PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
1827
1828 FontInfo = NULL;
1829 FontPackage = NULL;
1830 GlobalFont = NULL;
1831
1832 //
1833 // It is illegal to have two font packages with same EFI_FONT_INFO within hii
1834 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
1835 // attributes and identify a font uniquely.
1836 //
1837 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *)AllocateZeroPool (HeaderSize);
1838 if (FontPkgHdr == NULL) {
1839 Status = EFI_OUT_OF_RESOURCES;
1840 goto Error;
1841 }
1842
1843 CopyMem (FontPkgHdr, PackageHdr, HeaderSize);
1844
1845 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);
1846 FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoSize);
1847 if (FontInfo == NULL) {
1848 Status = EFI_OUT_OF_RESOURCES;
1849 goto Error;
1850 }
1851
1852 FontInfo->FontStyle = FontPkgHdr->FontStyle;
1853 FontInfo->FontSize = FontPkgHdr->Cell.Height;
1854 StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF (EFI_FONT_INFO, FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily);
1855
1856 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {
1857 Status = EFI_UNSUPPORTED;
1858 goto Error;
1859 }
1860
1861 //
1862 // Create a Font package node
1863 //
1864 FontPackage = (HII_FONT_PACKAGE_INSTANCE *)AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));
1865 if (FontPackage == NULL) {
1866 Status = EFI_OUT_OF_RESOURCES;
1867 goto Error;
1868 }
1869
1870 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;
1871 FontPackage->FontPkgHdr = FontPkgHdr;
1872 InitializeListHead (&FontPackage->GlyphInfoList);
1873
1874 FontPackage->GlyphBlock = (UINT8 *)AllocateZeroPool (PackageHeader.Length - HeaderSize);
1875 if (FontPackage->GlyphBlock == NULL) {
1876 Status = EFI_OUT_OF_RESOURCES;
1877 goto Error;
1878 }
1879
1880 CopyMem (FontPackage->GlyphBlock, (UINT8 *)PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);
1881
1882 //
1883 // Collect all default character cell information and backup in GlyphInfoList.
1884 //
1885 Status = FindGlyphBlock (FontPackage, (CHAR16)(-1), NULL, NULL, NULL);
1886 if (EFI_ERROR (Status)) {
1887 goto Error;
1888 }
1889
1890 //
1891 // This font package describes an unique EFI_FONT_INFO. Backup it in global
1892 // font info list.
1893 //
1894 GlobalFont = (HII_GLOBAL_FONT_INFO *)AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));
1895 if (GlobalFont == NULL) {
1896 Status = EFI_OUT_OF_RESOURCES;
1897 goto Error;
1898 }
1899
1900 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;
1901 GlobalFont->FontPackage = FontPackage;
1902 GlobalFont->FontInfoSize = FontInfoSize;
1903 GlobalFont->FontInfo = FontInfo;
1904 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);
1905
1906 //
1907 // Insert this font package to Font package array
1908 //
1909 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);
1910 *Package = FontPackage;
1911
1912 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
1913 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;
1914 }
1915
1916 return EFI_SUCCESS;
1917
1918Error:
1919
1920 if (FontPkgHdr != NULL) {
1921 FreePool (FontPkgHdr);
1922 }
1923
1924 if (FontInfo != NULL) {
1925 FreePool (FontInfo);
1926 }
1927
1928 if (FontPackage != NULL) {
1929 if (FontPackage->GlyphBlock != NULL) {
1930 FreePool (FontPackage->GlyphBlock);
1931 }
1932
1933 FreePool (FontPackage);
1934 }
1935
1936 if (GlobalFont != NULL) {
1937 FreePool (GlobalFont);
1938 }
1939
1940 return Status;
1941}
1942
1943/**
1944 This function exports Font packages to a buffer.
1945 This is a internal function.
1946
1947 @param Private Hii database private structure.
1948 @param Handle Identification of a package list.
1949 @param PackageList Pointer to a package list which will be exported.
1950 @param UsedSize The length of buffer be used.
1951 @param BufferSize Length of the Buffer.
1952 @param Buffer Allocated space for storing exported data.
1953 @param ResultSize The size of the already exported content of this
1954 package list.
1955
1956 @retval EFI_SUCCESS Font Packages are exported successfully.
1957 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1958
1959**/
1960EFI_STATUS
1961ExportFontPackages (
1962 IN HII_DATABASE_PRIVATE_DATA *Private,
1963 IN EFI_HII_HANDLE Handle,
1964 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
1965 IN UINTN UsedSize,
1966 IN UINTN BufferSize,
1967 IN OUT VOID *Buffer,
1968 IN OUT UINTN *ResultSize
1969 )
1970{
1971 LIST_ENTRY *Link;
1972 UINTN PackageLength;
1973 EFI_STATUS Status;
1974 HII_FONT_PACKAGE_INSTANCE *Package;
1975
1976 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
1977 return EFI_INVALID_PARAMETER;
1978 }
1979
1980 if ((BufferSize > 0) && (Buffer == NULL)) {
1981 return EFI_INVALID_PARAMETER;
1982 }
1983
1984 PackageLength = 0;
1985 Status = EFI_SUCCESS;
1986
1987 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {
1988 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);
1989 PackageLength += Package->FontPkgHdr->Header.Length;
1990 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
1991 //
1992 // Invoke registered notification function with EXPORT_PACK notify type
1993 //
1994 Status = InvokeRegisteredFunction (
1995 Private,
1996 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
1997 (VOID *)Package,
1998 EFI_HII_PACKAGE_FONTS,
1999 Handle
2000 );
2001 ASSERT_EFI_ERROR (Status);
2002 //
2003 // Copy Font package header
2004 //
2005 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);
2006 Buffer = (UINT8 *)Buffer + Package->FontPkgHdr->HdrSize;
2007
2008 //
2009 // Copy Glyph blocks information
2010 //
2011 CopyMem (
2012 Buffer,
2013 Package->GlyphBlock,
2014 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize
2015 );
2016 Buffer = (UINT8 *)Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;
2017 }
2018 }
2019
2020 *ResultSize += PackageLength;
2021 return EFI_SUCCESS;
2022}
2023
2024/**
2025 This function deletes all Font packages from a package list node.
2026 This is a internal function.
2027
2028 @param Private Hii database private data.
2029 @param Handle Handle of the package list which contains the to
2030 be removed Font packages.
2031 @param PackageList Pointer to a package list that contains removing
2032 packages.
2033
2034 @retval EFI_SUCCESS Font Package(s) is deleted successfully.
2035 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2036
2037**/
2038EFI_STATUS
2039RemoveFontPackages (
2040 IN HII_DATABASE_PRIVATE_DATA *Private,
2041 IN EFI_HII_HANDLE Handle,
2042 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2043 )
2044{
2045 LIST_ENTRY *ListHead;
2046 HII_FONT_PACKAGE_INSTANCE *Package;
2047 EFI_STATUS Status;
2048 HII_GLYPH_INFO *GlyphInfo;
2049 LIST_ENTRY *Link;
2050 HII_GLOBAL_FONT_INFO *GlobalFont;
2051
2052 ListHead = &PackageList->FontPkgHdr;
2053
2054 while (!IsListEmpty (ListHead)) {
2055 Package = CR (
2056 ListHead->ForwardLink,
2057 HII_FONT_PACKAGE_INSTANCE,
2058 FontEntry,
2059 HII_FONT_PACKAGE_SIGNATURE
2060 );
2061 Status = InvokeRegisteredFunction (
2062 Private,
2063 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2064 (VOID *)Package,
2065 EFI_HII_PACKAGE_FONTS,
2066 Handle
2067 );
2068 if (EFI_ERROR (Status)) {
2069 return Status;
2070 }
2071
2072 RemoveEntryList (&Package->FontEntry);
2073 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;
2074
2075 if (Package->GlyphBlock != NULL) {
2076 FreePool (Package->GlyphBlock);
2077 }
2078
2079 FreePool (Package->FontPkgHdr);
2080 //
2081 // Delete default character cell information
2082 //
2083 while (!IsListEmpty (&Package->GlyphInfoList)) {
2084 GlyphInfo = CR (
2085 Package->GlyphInfoList.ForwardLink,
2086 HII_GLYPH_INFO,
2087 Entry,
2088 HII_GLYPH_INFO_SIGNATURE
2089 );
2090 RemoveEntryList (&GlyphInfo->Entry);
2091 FreePool (GlyphInfo);
2092 }
2093
2094 //
2095 // Remove corresponding global font info
2096 //
2097 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
2098 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
2099 if (GlobalFont->FontPackage == Package) {
2100 RemoveEntryList (&GlobalFont->Entry);
2101 FreePool (GlobalFont->FontInfo);
2102 FreePool (GlobalFont);
2103 break;
2104 }
2105 }
2106
2107 FreePool (Package);
2108 }
2109
2110 return EFI_SUCCESS;
2111}
2112
2113/**
2114 This function insert a Image package to a package list node.
2115 This is a internal function.
2116
2117 @param PackageHdr Pointer to a buffer stored with Image package
2118 information.
2119 @param NotifyType The type of change concerning the database.
2120 @param PackageList Pointer to a package list which will be inserted
2121 to.
2122 @param Package Created Image package
2123
2124 @retval EFI_SUCCESS Image Package is inserted successfully.
2125 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2126 Image package.
2127 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2128
2129**/
2130EFI_STATUS
2131InsertImagePackage (
2132 IN VOID *PackageHdr,
2133 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2134 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2135 OUT HII_IMAGE_PACKAGE_INSTANCE **Package
2136 )
2137{
2138 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
2139 UINT32 PaletteSize;
2140 UINT32 ImageSize;
2141 UINT16 Index;
2142 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;
2143 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;
2144 UINT32 PaletteInfoOffset;
2145 UINT32 ImageInfoOffset;
2146 UINT16 CurrentSize;
2147
2148 if ((PackageHdr == NULL) || (PackageList == NULL)) {
2149 return EFI_INVALID_PARAMETER;
2150 }
2151
2152 //
2153 // Less than one image package is allowed in one package list.
2154 //
2155 if (PackageList->ImagePkg != NULL) {
2156 return EFI_INVALID_PARAMETER;
2157 }
2158
2159 //
2160 // Create a Image package node
2161 //
2162 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *)AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
2163 if (ImagePackage == NULL) {
2164 return EFI_OUT_OF_RESOURCES;
2165 }
2166
2167 //
2168 // Copy the Image package header.
2169 //
2170 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
2171
2172 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;
2173 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;
2174
2175 //
2176 // If PaletteInfoOffset is zero, there are no palettes in this image package.
2177 //
2178 PaletteSize = 0;
2179 ImagePackage->PaletteBlock = NULL;
2180 if (PaletteInfoOffset != 0) {
2181 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *)((UINT8 *)PackageHdr + PaletteInfoOffset);
2182 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
2183 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *)((UINT8 *)PaletteHdr + PaletteSize);
2184
2185 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {
2186 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));
2187 CurrentSize += sizeof (UINT16);
2188 PaletteSize += (UINT32)CurrentSize;
2189 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *)((UINT8 *)PaletteInfo + CurrentSize);
2190 }
2191
2192 ImagePackage->PaletteBlock = (UINT8 *)AllocateZeroPool (PaletteSize);
2193 if (ImagePackage->PaletteBlock == NULL) {
2194 FreePool (ImagePackage);
2195 return EFI_OUT_OF_RESOURCES;
2196 }
2197
2198 CopyMem (
2199 ImagePackage->PaletteBlock,
2200 (UINT8 *)PackageHdr + PaletteInfoOffset,
2201 PaletteSize
2202 );
2203 }
2204
2205 //
2206 // If ImageInfoOffset is zero, there are no images in this package.
2207 //
2208 ImageSize = 0;
2209 ImagePackage->ImageBlock = NULL;
2210 if (ImageInfoOffset != 0) {
2211 ImageSize = ImagePackage->ImagePkgHdr.Header.Length -
2212 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;
2213 ImagePackage->ImageBlock = AllocateZeroPool (ImageSize);
2214 if (ImagePackage->ImageBlock == NULL) {
2215 FreePool (ImagePackage->PaletteBlock);
2216 FreePool (ImagePackage);
2217 return EFI_OUT_OF_RESOURCES;
2218 }
2219
2220 CopyMem (
2221 ImagePackage->ImageBlock,
2222 (UINT8 *)PackageHdr + ImageInfoOffset,
2223 ImageSize
2224 );
2225 }
2226
2227 ImagePackage->ImageBlockSize = ImageSize;
2228 ImagePackage->PaletteInfoSize = PaletteSize;
2229 PackageList->ImagePkg = ImagePackage;
2230 *Package = ImagePackage;
2231
2232 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2233 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
2234 }
2235
2236 return EFI_SUCCESS;
2237}
2238
2239/**
2240 This function exports Image packages to a buffer.
2241 This is a internal function.
2242
2243 @param Private Hii database private structure.
2244 @param Handle Identification of a package list.
2245 @param PackageList Pointer to a package list which will be exported.
2246 @param UsedSize The length of buffer be used.
2247 @param BufferSize Length of the Buffer.
2248 @param Buffer Allocated space for storing exported data.
2249 @param ResultSize The size of the already exported content of this
2250 package list.
2251
2252 @retval EFI_SUCCESS Image Packages are exported successfully.
2253 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2254
2255**/
2256EFI_STATUS
2257ExportImagePackages (
2258 IN HII_DATABASE_PRIVATE_DATA *Private,
2259 IN EFI_HII_HANDLE Handle,
2260 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2261 IN UINTN UsedSize,
2262 IN UINTN BufferSize,
2263 IN OUT VOID *Buffer,
2264 IN OUT UINTN *ResultSize
2265 )
2266{
2267 UINTN PackageLength;
2268 EFI_STATUS Status;
2269 HII_IMAGE_PACKAGE_INSTANCE *Package;
2270
2271 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
2272 return EFI_INVALID_PARAMETER;
2273 }
2274
2275 if ((BufferSize > 0) && (Buffer == NULL)) {
2276 return EFI_INVALID_PARAMETER;
2277 }
2278
2279 Package = PackageList->ImagePkg;
2280
2281 if (Package == NULL) {
2282 return EFI_SUCCESS;
2283 }
2284
2285 PackageLength = Package->ImagePkgHdr.Header.Length;
2286
2287 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
2288 //
2289 // Invoke registered notification function with EXPORT_PACK notify type
2290 //
2291 Status = InvokeRegisteredFunction (
2292 Private,
2293 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
2294 (VOID *)Package,
2295 EFI_HII_PACKAGE_IMAGES,
2296 Handle
2297 );
2298 ASSERT_EFI_ERROR (Status);
2299 ASSERT (
2300 Package->ImagePkgHdr.Header.Length ==
2301 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize
2302 );
2303 //
2304 // Copy Image package header,
2305 // then justify the offset for image info and palette info in the header.
2306 //
2307 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
2308 Buffer = (UINT8 *)Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
2309
2310 //
2311 // Copy Image blocks information
2312 //
2313 if (Package->ImageBlockSize != 0) {
2314 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);
2315 Buffer = (UINT8 *)Buffer + Package->ImageBlockSize;
2316 }
2317
2318 //
2319 // Copy Palette information
2320 //
2321 if (Package->PaletteInfoSize != 0) {
2322 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);
2323 Buffer = (UINT8 *)Buffer + Package->PaletteInfoSize;
2324 }
2325 }
2326
2327 *ResultSize += PackageLength;
2328 return EFI_SUCCESS;
2329}
2330
2331/**
2332 This function deletes Image package from a package list node.
2333 This is a internal function.
2334
2335 @param Private Hii database private data.
2336 @param Handle Handle of the package list which contains the to
2337 be removed Image packages.
2338 @param PackageList Package List which contains the to be removed
2339 Image package.
2340
2341 @retval EFI_SUCCESS Image Package(s) is deleted successfully.
2342 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2343
2344**/
2345EFI_STATUS
2346RemoveImagePackages (
2347 IN HII_DATABASE_PRIVATE_DATA *Private,
2348 IN EFI_HII_HANDLE Handle,
2349 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2350 )
2351{
2352 HII_IMAGE_PACKAGE_INSTANCE *Package;
2353 EFI_STATUS Status;
2354
2355 Package = PackageList->ImagePkg;
2356
2357 //
2358 // Image package does not exist, return directly.
2359 //
2360 if (Package == NULL) {
2361 return EFI_SUCCESS;
2362 }
2363
2364 Status = InvokeRegisteredFunction (
2365 Private,
2366 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2367 (VOID *)Package,
2368 EFI_HII_PACKAGE_IMAGES,
2369 Handle
2370 );
2371 if (EFI_ERROR (Status)) {
2372 return Status;
2373 }
2374
2375 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;
2376
2377 FreePool (Package->ImageBlock);
2378 if (Package->PaletteBlock != NULL) {
2379 FreePool (Package->PaletteBlock);
2380 }
2381
2382 FreePool (Package);
2383
2384 PackageList->ImagePkg = NULL;
2385
2386 return EFI_SUCCESS;
2387}
2388
2389/**
2390 This function insert a Simple Font package to a package list node.
2391 This is a internal function.
2392
2393 @param PackageHdr Pointer to a buffer stored with Simple Font
2394 package information.
2395 @param NotifyType The type of change concerning the database.
2396 @param PackageList Pointer to a package list which will be inserted
2397 to.
2398 @param Package Created Simple Font package
2399
2400 @retval EFI_SUCCESS Simple Font Package is inserted successfully.
2401 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2402 Simple Font package.
2403 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2404
2405**/
2406EFI_STATUS
2407InsertSimpleFontPackage (
2408 IN VOID *PackageHdr,
2409 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2410 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2411 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package
2412 )
2413{
2414 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
2415 EFI_STATUS Status;
2416 EFI_HII_PACKAGE_HEADER Header;
2417
2418 if ((PackageHdr == NULL) || (PackageList == NULL)) {
2419 return EFI_INVALID_PARAMETER;
2420 }
2421
2422 //
2423 // Create a Simple Font package node
2424 //
2425 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));
2426 if (SimpleFontPackage == NULL) {
2427 Status = EFI_OUT_OF_RESOURCES;
2428 goto Error;
2429 }
2430
2431 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;
2432
2433 //
2434 // Copy the Simple Font package.
2435 //
2436 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
2437
2438 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);
2439 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {
2440 Status = EFI_OUT_OF_RESOURCES;
2441 goto Error;
2442 }
2443
2444 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);
2445
2446 //
2447 // Insert to Simple Font package array
2448 //
2449 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);
2450 *Package = SimpleFontPackage;
2451
2452 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2453 PackageList->PackageListHdr.PackageLength += Header.Length;
2454 }
2455
2456 return EFI_SUCCESS;
2457
2458Error:
2459
2460 if (SimpleFontPackage != NULL) {
2461 if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {
2462 FreePool (SimpleFontPackage->SimpleFontPkgHdr);
2463 }
2464
2465 FreePool (SimpleFontPackage);
2466 }
2467
2468 return Status;
2469}
2470
2471/**
2472 This function exports SimpleFont packages to a buffer.
2473 This is a internal function.
2474
2475 @param Private Hii database private structure.
2476 @param Handle Identification of a package list.
2477 @param PackageList Pointer to a package list which will be exported.
2478 @param UsedSize The length of buffer be used.
2479 @param BufferSize Length of the Buffer.
2480 @param Buffer Allocated space for storing exported data.
2481 @param ResultSize The size of the already exported content of this
2482 package list.
2483
2484 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.
2485 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2486
2487**/
2488EFI_STATUS
2489ExportSimpleFontPackages (
2490 IN HII_DATABASE_PRIVATE_DATA *Private,
2491 IN EFI_HII_HANDLE Handle,
2492 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2493 IN UINTN UsedSize,
2494 IN UINTN BufferSize,
2495 IN OUT VOID *Buffer,
2496 IN OUT UINTN *ResultSize
2497 )
2498{
2499 LIST_ENTRY *Link;
2500 UINTN PackageLength;
2501 EFI_STATUS Status;
2502 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
2503
2504 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
2505 return EFI_INVALID_PARAMETER;
2506 }
2507
2508 if ((BufferSize > 0) && (Buffer == NULL)) {
2509 return EFI_INVALID_PARAMETER;
2510 }
2511
2512 PackageLength = 0;
2513 Status = EFI_SUCCESS;
2514
2515 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {
2516 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
2517 PackageLength += Package->SimpleFontPkgHdr->Header.Length;
2518 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
2519 //
2520 // Invoke registered notification function with EXPORT_PACK notify type
2521 //
2522 Status = InvokeRegisteredFunction (
2523 Private,
2524 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
2525 (VOID *)Package,
2526 EFI_HII_PACKAGE_SIMPLE_FONTS,
2527 Handle
2528 );
2529 ASSERT_EFI_ERROR (Status);
2530
2531 //
2532 // Copy SimpleFont package
2533 //
2534 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);
2535 Buffer = (UINT8 *)Buffer + Package->SimpleFontPkgHdr->Header.Length;
2536 }
2537 }
2538
2539 *ResultSize += PackageLength;
2540 return EFI_SUCCESS;
2541}
2542
2543/**
2544 This function deletes all Simple Font packages from a package list node.
2545 This is a internal function.
2546
2547 @param Private Hii database private data.
2548 @param Handle Handle of the package list which contains the to
2549 be removed Simple Font packages.
2550 @param PackageList Pointer to a package list that contains removing
2551 packages.
2552
2553 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.
2554 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2555
2556**/
2557EFI_STATUS
2558RemoveSimpleFontPackages (
2559 IN HII_DATABASE_PRIVATE_DATA *Private,
2560 IN EFI_HII_HANDLE Handle,
2561 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2562 )
2563{
2564 LIST_ENTRY *ListHead;
2565 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
2566 EFI_STATUS Status;
2567
2568 ListHead = &PackageList->SimpleFontPkgHdr;
2569
2570 while (!IsListEmpty (ListHead)) {
2571 Package = CR (
2572 ListHead->ForwardLink,
2573 HII_SIMPLE_FONT_PACKAGE_INSTANCE,
2574 SimpleFontEntry,
2575 HII_S_FONT_PACKAGE_SIGNATURE
2576 );
2577 Status = InvokeRegisteredFunction (
2578 Private,
2579 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2580 (VOID *)Package,
2581 EFI_HII_PACKAGE_SIMPLE_FONTS,
2582 Handle
2583 );
2584 if (EFI_ERROR (Status)) {
2585 return Status;
2586 }
2587
2588 RemoveEntryList (&Package->SimpleFontEntry);
2589 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;
2590 FreePool (Package->SimpleFontPkgHdr);
2591 FreePool (Package);
2592 }
2593
2594 return EFI_SUCCESS;
2595}
2596
2597/**
2598 This function insert a Device path package to a package list node.
2599 This is a internal function.
2600
2601 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2602 instance
2603 @param NotifyType The type of change concerning the database.
2604 @param PackageList Pointer to a package list which will be inserted
2605 to.
2606
2607 @retval EFI_SUCCESS Device path Package is inserted successfully.
2608 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2609 Device path package.
2610 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2611
2612**/
2613EFI_STATUS
2614InsertDevicePathPackage (
2615 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2616 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2617 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2618 )
2619{
2620 UINT32 PackageLength;
2621 EFI_HII_PACKAGE_HEADER Header;
2622
2623 if ((DevicePath == NULL) || (PackageList == NULL)) {
2624 return EFI_INVALID_PARAMETER;
2625 }
2626
2627 //
2628 // Less than one device path package is allowed in one package list.
2629 //
2630 if (PackageList->DevicePathPkg != NULL) {
2631 return EFI_INVALID_PARAMETER;
2632 }
2633
2634 PackageLength = (UINT32)GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);
2635 PackageList->DevicePathPkg = (UINT8 *)AllocateZeroPool (PackageLength);
2636 if (PackageList->DevicePathPkg == NULL) {
2637 return EFI_OUT_OF_RESOURCES;
2638 }
2639
2640 Header.Length = PackageLength;
2641 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;
2642 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));
2643 CopyMem (
2644 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),
2645 DevicePath,
2646 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)
2647 );
2648
2649 //
2650 // Since Device Path package is created by NewPackageList, either NEW_PACK
2651 // or ADD_PACK should increase the length of package list.
2652 //
2653 PackageList->PackageListHdr.PackageLength += PackageLength;
2654 return EFI_SUCCESS;
2655}
2656
2657/**
2658 This function exports device path package to a buffer.
2659 This is a internal function.
2660
2661 @param Private Hii database private structure.
2662 @param Handle Identification of a package list.
2663 @param PackageList Pointer to a package list which will be exported.
2664 @param UsedSize The length of buffer be used.
2665 @param BufferSize Length of the Buffer.
2666 @param Buffer Allocated space for storing exported data.
2667 @param ResultSize The size of the already exported content of this
2668 package list.
2669
2670 @retval EFI_SUCCESS Device path Package is exported successfully.
2671 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2672
2673**/
2674EFI_STATUS
2675ExportDevicePathPackage (
2676 IN HII_DATABASE_PRIVATE_DATA *Private,
2677 IN EFI_HII_HANDLE Handle,
2678 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2679 IN UINTN UsedSize,
2680 IN UINTN BufferSize,
2681 IN OUT VOID *Buffer,
2682 IN OUT UINTN *ResultSize
2683 )
2684{
2685 EFI_STATUS Status;
2686 UINT8 *Package;
2687 EFI_HII_PACKAGE_HEADER Header;
2688
2689 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
2690 return EFI_INVALID_PARAMETER;
2691 }
2692
2693 if ((BufferSize > 0) && (Buffer == NULL)) {
2694 return EFI_INVALID_PARAMETER;
2695 }
2696
2697 Package = PackageList->DevicePathPkg;
2698
2699 if (Package == NULL) {
2700 return EFI_SUCCESS;
2701 }
2702
2703 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
2704
2705 if (Header.Length + *ResultSize + UsedSize <= BufferSize) {
2706 //
2707 // Invoke registered notification function with EXPORT_PACK notify type
2708 //
2709 Status = InvokeRegisteredFunction (
2710 Private,
2711 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
2712 (VOID *)Package,
2713 EFI_HII_PACKAGE_DEVICE_PATH,
2714 Handle
2715 );
2716 ASSERT_EFI_ERROR (Status);
2717
2718 //
2719 // Copy Device path package
2720 //
2721 CopyMem (Buffer, Package, Header.Length);
2722 }
2723
2724 *ResultSize += Header.Length;
2725 return EFI_SUCCESS;
2726}
2727
2728/**
2729 This function deletes Device Path package from a package list node.
2730 This is a internal function.
2731
2732 @param Private Hii database private data.
2733 @param Handle Handle of the package list.
2734 @param PackageList Package List which contains the to be removed
2735 Device Path package.
2736
2737 @retval EFI_SUCCESS Device Path Package is deleted successfully.
2738 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2739
2740**/
2741EFI_STATUS
2742RemoveDevicePathPackage (
2743 IN HII_DATABASE_PRIVATE_DATA *Private,
2744 IN EFI_HII_HANDLE Handle,
2745 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
2746 )
2747{
2748 EFI_STATUS Status;
2749 UINT8 *Package;
2750 EFI_HII_PACKAGE_HEADER Header;
2751
2752 Package = PackageList->DevicePathPkg;
2753
2754 //
2755 // No device path, return directly.
2756 //
2757 if (Package == NULL) {
2758 return EFI_SUCCESS;
2759 }
2760
2761 Status = InvokeRegisteredFunction (
2762 Private,
2763 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
2764 (VOID *)Package,
2765 EFI_HII_PACKAGE_DEVICE_PATH,
2766 Handle
2767 );
2768 if (EFI_ERROR (Status)) {
2769 return Status;
2770 }
2771
2772 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
2773 PackageList->PackageListHdr.PackageLength -= Header.Length;
2774
2775 FreePool (Package);
2776
2777 PackageList->DevicePathPkg = NULL;
2778
2779 return EFI_SUCCESS;
2780}
2781
2782/**
2783 This function will insert a device path package to package list firstly then
2784 invoke notification functions if any.
2785 This is a internal function.
2786
2787 @param Private Hii database private structure.
2788 @param NotifyType The type of change concerning the database.
2789 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2790 instance
2791 @param DatabaseRecord Pointer to a database record contains a package
2792 list which will be inserted to.
2793
2794 @retval EFI_SUCCESS Device path Package is inserted successfully.
2795 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2796 Device path package.
2797 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2798
2799**/
2800EFI_STATUS
2801AddDevicePathPackage (
2802 IN HII_DATABASE_PRIVATE_DATA *Private,
2803 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2804 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2805 IN OUT HII_DATABASE_RECORD *DatabaseRecord
2806 )
2807{
2808 EFI_STATUS Status;
2809
2810 if (DevicePath == NULL) {
2811 return EFI_SUCCESS;
2812 }
2813
2814 ASSERT (Private != NULL);
2815 ASSERT (DatabaseRecord != NULL);
2816
2817 //
2818 // Create a device path package and insert to packagelist
2819 //
2820 Status = InsertDevicePathPackage (
2821 DevicePath,
2822 NotifyType,
2823 DatabaseRecord->PackageList
2824 );
2825 if (EFI_ERROR (Status)) {
2826 return Status;
2827 }
2828
2829 return InvokeRegisteredFunction (
2830 Private,
2831 NotifyType,
2832 (VOID *)DatabaseRecord->PackageList->DevicePathPkg,
2833 EFI_HII_PACKAGE_DEVICE_PATH,
2834 DatabaseRecord->Handle
2835 );
2836}
2837
2838/**
2839 This function insert a Keyboard Layout package to a package list node.
2840 This is a internal function.
2841
2842 @param PackageHdr Pointer to a buffer stored with Keyboard Layout
2843 package information.
2844 @param NotifyType The type of change concerning the database.
2845 @param PackageList Pointer to a package list which will be inserted
2846 to.
2847 @param Package Created Keyboard Layout package
2848
2849 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.
2850 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2851 Keyboard Layout package.
2852 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2853
2854**/
2855EFI_STATUS
2856InsertKeyboardLayoutPackage (
2857 IN VOID *PackageHdr,
2858 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
2859 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2860 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package
2861 )
2862{
2863 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
2864 EFI_HII_PACKAGE_HEADER PackageHeader;
2865 EFI_STATUS Status;
2866
2867 if ((PackageHdr == NULL) || (PackageList == NULL)) {
2868 return EFI_INVALID_PARAMETER;
2869 }
2870
2871 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
2872
2873 //
2874 // Create a Keyboard Layout package node
2875 //
2876 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));
2877 if (KeyboardLayoutPackage == NULL) {
2878 Status = EFI_OUT_OF_RESOURCES;
2879 goto Error;
2880 }
2881
2882 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;
2883
2884 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *)AllocateZeroPool (PackageHeader.Length);
2885 if (KeyboardLayoutPackage->KeyboardPkg == NULL) {
2886 Status = EFI_OUT_OF_RESOURCES;
2887 goto Error;
2888 }
2889
2890 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);
2891 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);
2892
2893 *Package = KeyboardLayoutPackage;
2894
2895 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
2896 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
2897 }
2898
2899 return EFI_SUCCESS;
2900
2901Error:
2902
2903 if (KeyboardLayoutPackage != NULL) {
2904 if (KeyboardLayoutPackage->KeyboardPkg != NULL) {
2905 FreePool (KeyboardLayoutPackage->KeyboardPkg);
2906 }
2907
2908 FreePool (KeyboardLayoutPackage);
2909 }
2910
2911 return Status;
2912}
2913
2914/**
2915 This function exports Keyboard Layout packages to a buffer.
2916 This is a internal function.
2917
2918 @param Private Hii database private structure.
2919 @param Handle Identification of a package list.
2920 @param PackageList Pointer to a package list which will be exported.
2921 @param UsedSize The length of buffer be used.
2922 @param BufferSize Length of the Buffer.
2923 @param Buffer Allocated space for storing exported data.
2924 @param ResultSize The size of the already exported content of this
2925 package list.
2926
2927 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2928 successfully.
2929 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2930
2931**/
2932EFI_STATUS
2933ExportKeyboardLayoutPackages (
2934 IN HII_DATABASE_PRIVATE_DATA *Private,
2935 IN EFI_HII_HANDLE Handle,
2936 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
2937 IN UINTN UsedSize,
2938 IN UINTN BufferSize,
2939 IN OUT VOID *Buffer,
2940 IN OUT UINTN *ResultSize
2941 )
2942{
2943 LIST_ENTRY *Link;
2944 UINTN PackageLength;
2945 EFI_STATUS Status;
2946 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
2947 EFI_HII_PACKAGE_HEADER PackageHeader;
2948
2949 if ((Private == NULL) || (PackageList == NULL) || (ResultSize == NULL)) {
2950 return EFI_INVALID_PARAMETER;
2951 }
2952
2953 if ((BufferSize > 0) && (Buffer == NULL)) {
2954 return EFI_INVALID_PARAMETER;
2955 }
2956
2957 PackageLength = 0;
2958 Status = EFI_SUCCESS;
2959
2960 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {
2961 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);
2962 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
2963 PackageLength += PackageHeader.Length;
2964 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
2965 //
2966 // Invoke registered notification function with EXPORT_PACK notify type
2967 //
2968 Status = InvokeRegisteredFunction (
2969 Private,
2970 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
2971 (EFI_HII_PACKAGE_HEADER *)Package,
2972 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
2973 Handle
2974 );
2975 ASSERT_EFI_ERROR (Status);
2976
2977 //
2978 // Copy Keyboard Layout package
2979 //
2980 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);
2981 Buffer = (UINT8 *)Buffer + PackageHeader.Length;
2982 }
2983 }
2984
2985 *ResultSize += PackageLength;
2986 return EFI_SUCCESS;
2987}
2988
2989/**
2990 This function deletes all Keyboard Layout packages from a package list node.
2991 This is a internal function.
2992
2993 @param Private Hii database private data.
2994 @param Handle Handle of the package list which contains the to
2995 be removed Keyboard Layout packages.
2996 @param PackageList Pointer to a package list that contains removing
2997 packages.
2998
2999 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted
3000 successfully.
3001 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
3002
3003**/
3004EFI_STATUS
3005RemoveKeyboardLayoutPackages (
3006 IN HII_DATABASE_PRIVATE_DATA *Private,
3007 IN EFI_HII_HANDLE Handle,
3008 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
3009 )
3010{
3011 LIST_ENTRY *ListHead;
3012 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
3013 EFI_HII_PACKAGE_HEADER PackageHeader;
3014 EFI_STATUS Status;
3015
3016 ListHead = &PackageList->KeyboardLayoutHdr;
3017
3018 while (!IsListEmpty (ListHead)) {
3019 Package = CR (
3020 ListHead->ForwardLink,
3021 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
3022 KeyboardEntry,
3023 HII_KB_LAYOUT_PACKAGE_SIGNATURE
3024 );
3025 Status = InvokeRegisteredFunction (
3026 Private,
3027 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
3028 (VOID *)Package,
3029 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
3030 Handle
3031 );
3032 if (EFI_ERROR (Status)) {
3033 return Status;
3034 }
3035
3036 RemoveEntryList (&Package->KeyboardEntry);
3037 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
3038 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
3039 FreePool (Package->KeyboardPkg);
3040 FreePool (Package);
3041 }
3042
3043 return EFI_SUCCESS;
3044}
3045
3046/**
3047 This function will insert a package list to hii database firstly then
3048 invoke notification functions if any. It is the worker function of
3049 HiiNewPackageList and HiiUpdatePackageList.
3050
3051 This is a internal function.
3052
3053 @param Private Hii database private structure.
3054 @param NotifyType The type of change concerning the database.
3055 @param PackageList Pointer to a package list.
3056 @param DatabaseRecord Pointer to a database record contains a package
3057 list instance which will be inserted to.
3058
3059 @retval EFI_SUCCESS All incoming packages are inserted to current
3060 database.
3061 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
3062 Device path package.
3063 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
3064
3065**/
3066EFI_STATUS
3067AddPackages (
3068 IN HII_DATABASE_PRIVATE_DATA *Private,
3069 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
3070 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
3071 IN OUT HII_DATABASE_RECORD *DatabaseRecord
3072 )
3073{
3074 EFI_STATUS Status;
3075 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
3076 HII_IFR_PACKAGE_INSTANCE *FormPackage;
3077 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
3078 HII_STRING_PACKAGE_INSTANCE *StringPackage;
3079 HII_FONT_PACKAGE_INSTANCE *FontPackage;
3080 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
3081 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
3082 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
3083 EFI_HII_PACKAGE_HEADER PackageHeader;
3084 UINT32 OldPackageListLen;
3085 BOOLEAN StringPkgIsAdd;
3086
3087 //
3088 // Initialize Variables
3089 //
3090 StringPkgIsAdd = FALSE;
3091 FontPackage = NULL;
3092 StringPackage = NULL;
3093 GuidPackage = NULL;
3094 FormPackage = NULL;
3095 ImagePackage = NULL;
3096 SimpleFontPackage = NULL;
3097 KeyboardLayoutPackage = NULL;
3098
3099 //
3100 // Process the package list header
3101 //
3102 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;
3103 CopyMem (
3104 &DatabaseRecord->PackageList->PackageListHdr,
3105 (VOID *)PackageList,
3106 sizeof (EFI_HII_PACKAGE_LIST_HEADER)
3107 );
3108 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
3109 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;
3110 }
3111
3112 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *)((UINT8 *)PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
3113 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3114
3115 Status = EFI_SUCCESS;
3116
3117 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
3118 switch (PackageHeader.Type) {
3119 case EFI_HII_PACKAGE_TYPE_GUID:
3120 Status = InsertGuidPackage (
3121 PackageHdrPtr,
3122 NotifyType,
3123 DatabaseRecord->PackageList,
3124 &GuidPackage
3125 );
3126 if (EFI_ERROR (Status)) {
3127 return Status;
3128 }
3129
3130 Status = InvokeRegisteredFunction (
3131 Private,
3132 NotifyType,
3133 (VOID *)GuidPackage,
3134 (UINT8)(PackageHeader.Type),
3135 DatabaseRecord->Handle
3136 );
3137 break;
3138 case EFI_HII_PACKAGE_FORMS:
3139 Status = InsertFormPackage (
3140 PackageHdrPtr,
3141 NotifyType,
3142 DatabaseRecord->PackageList,
3143 &FormPackage
3144 );
3145 if (EFI_ERROR (Status)) {
3146 return Status;
3147 }
3148
3149 Status = InvokeRegisteredFunction (
3150 Private,
3151 NotifyType,
3152 (VOID *)FormPackage,
3153 (UINT8)(PackageHeader.Type),
3154 DatabaseRecord->Handle
3155 );
3156 //
3157 // If Hii runtime support feature is enabled,
3158 // will export Hii info for runtime use after ReadyToBoot event triggered.
3159 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
3160 // will need to export the content of HiiDatabase.
3161 // But if form packages added/updated, also need to export the ConfigResp string.
3162 //
3163 if (gExportAfterReadyToBoot) {
3164 gExportConfigResp = TRUE;
3165 }
3166
3167 break;
3168 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
3169 Status = InsertKeyboardLayoutPackage (
3170 PackageHdrPtr,
3171 NotifyType,
3172 DatabaseRecord->PackageList,
3173 &KeyboardLayoutPackage
3174 );
3175 if (EFI_ERROR (Status)) {
3176 return Status;
3177 }
3178
3179 Status = InvokeRegisteredFunction (
3180 Private,
3181 NotifyType,
3182 (VOID *)KeyboardLayoutPackage,
3183 (UINT8)(PackageHeader.Type),
3184 DatabaseRecord->Handle
3185 );
3186 break;
3187 case EFI_HII_PACKAGE_STRINGS:
3188 Status = InsertStringPackage (
3189 Private,
3190 PackageHdrPtr,
3191 NotifyType,
3192 DatabaseRecord->PackageList,
3193 &StringPackage
3194 );
3195 if (EFI_ERROR (Status)) {
3196 return Status;
3197 }
3198
3199 ASSERT (StringPackage != NULL);
3200 Status = InvokeRegisteredFunction (
3201 Private,
3202 NotifyType,
3203 (VOID *)StringPackage,
3204 (UINT8)(PackageHeader.Type),
3205 DatabaseRecord->Handle
3206 );
3207 StringPkgIsAdd = TRUE;
3208 break;
3209 case EFI_HII_PACKAGE_FONTS:
3210 Status = InsertFontPackage (
3211 Private,
3212 PackageHdrPtr,
3213 NotifyType,
3214 DatabaseRecord->PackageList,
3215 &FontPackage
3216 );
3217 if (EFI_ERROR (Status)) {
3218 return Status;
3219 }
3220
3221 Status = InvokeRegisteredFunction (
3222 Private,
3223 NotifyType,
3224 (VOID *)FontPackage,
3225 (UINT8)(PackageHeader.Type),
3226 DatabaseRecord->Handle
3227 );
3228 break;
3229 case EFI_HII_PACKAGE_IMAGES:
3230 Status = InsertImagePackage (
3231 PackageHdrPtr,
3232 NotifyType,
3233 DatabaseRecord->PackageList,
3234 &ImagePackage
3235 );
3236 if (EFI_ERROR (Status)) {
3237 return Status;
3238 }
3239
3240 Status = InvokeRegisteredFunction (
3241 Private,
3242 NotifyType,
3243 (VOID *)ImagePackage,
3244 (UINT8)(PackageHeader.Type),
3245 DatabaseRecord->Handle
3246 );
3247 break;
3248 case EFI_HII_PACKAGE_SIMPLE_FONTS:
3249 Status = InsertSimpleFontPackage (
3250 PackageHdrPtr,
3251 NotifyType,
3252 DatabaseRecord->PackageList,
3253 &SimpleFontPackage
3254 );
3255 if (EFI_ERROR (Status)) {
3256 return Status;
3257 }
3258
3259 Status = InvokeRegisteredFunction (
3260 Private,
3261 NotifyType,
3262 (VOID *)SimpleFontPackage,
3263 (UINT8)(PackageHeader.Type),
3264 DatabaseRecord->Handle
3265 );
3266 break;
3267 case EFI_HII_PACKAGE_DEVICE_PATH:
3268 Status = AddDevicePathPackage (
3269 Private,
3270 NotifyType,
3271 (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),
3272 DatabaseRecord
3273 );
3274 break;
3275 default:
3276 break;
3277 }
3278
3279 if (EFI_ERROR (Status)) {
3280 return Status;
3281 }
3282
3283 //
3284 // goto header of next package
3285 //
3286 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *)((UINT8 *)PackageHdrPtr + PackageHeader.Length);
3287 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3288 }
3289
3290 //
3291 // Adjust String Package to make sure all string packages have the same max string ID.
3292 //
3293 if (!EFI_ERROR (Status) && StringPkgIsAdd) {
3294 Status = AdjustStringPackage (DatabaseRecord->PackageList);
3295 }
3296
3297 return Status;
3298}
3299
3300/**
3301 This function exports a package list to a buffer. It is the worker function
3302 of HiiExportPackageList.
3303
3304 This is a internal function.
3305
3306 @param Private Hii database private structure.
3307 @param Handle Identification of a package list.
3308 @param PackageList Pointer to a package list which will be exported.
3309 @param UsedSize The length of buffer has been used by exporting
3310 package lists when Handle is NULL.
3311 @param BufferSize Length of the Buffer.
3312 @param Buffer Allocated space for storing exported data.
3313
3314 @retval EFI_SUCCESS Keyboard Layout Packages are exported
3315 successfully.
3316 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
3317
3318**/
3319EFI_STATUS
3320ExportPackageList (
3321 IN HII_DATABASE_PRIVATE_DATA *Private,
3322 IN EFI_HII_HANDLE Handle,
3323 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
3324 IN OUT UINTN *UsedSize,
3325 IN UINTN BufferSize,
3326 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
3327 )
3328{
3329 EFI_STATUS Status;
3330 UINTN ResultSize;
3331 EFI_HII_PACKAGE_HEADER EndofPackageList;
3332
3333 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);
3334 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
3335 ASSERT (IsHiiHandleValid (Handle));
3336
3337 if ((BufferSize > 0) && (Buffer == NULL)) {
3338 return EFI_INVALID_PARAMETER;
3339 }
3340
3341 //
3342 // Copy the package list header
3343 // ResultSize indicates the length of the exported bytes of this package list
3344 //
3345 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
3346 if (ResultSize + *UsedSize <= BufferSize) {
3347 CopyMem ((VOID *)Buffer, PackageList, ResultSize);
3348 }
3349
3350 //
3351 // Copy the packages and invoke EXPORT_PACK notify functions if exists.
3352 //
3353 Status = ExportGuidPackages (
3354 Private,
3355 Handle,
3356 PackageList,
3357 *UsedSize,
3358 BufferSize,
3359 (VOID *)((UINT8 *)Buffer + ResultSize),
3360 &ResultSize
3361 );
3362 if (EFI_ERROR (Status)) {
3363 return Status;
3364 }
3365
3366 Status = ExportFormPackages (
3367 Private,
3368 Handle,
3369 PackageList,
3370 *UsedSize,
3371 BufferSize,
3372 (VOID *)((UINT8 *)Buffer + ResultSize),
3373 &ResultSize
3374 );
3375 if (EFI_ERROR (Status)) {
3376 return Status;
3377 }
3378
3379 Status = ExportKeyboardLayoutPackages (
3380 Private,
3381 Handle,
3382 PackageList,
3383 *UsedSize,
3384 BufferSize,
3385 (VOID *)((UINT8 *)Buffer + ResultSize),
3386 &ResultSize
3387 );
3388 if (EFI_ERROR (Status)) {
3389 return Status;
3390 }
3391
3392 Status = ExportStringPackages (
3393 Private,
3394 Handle,
3395 PackageList,
3396 *UsedSize,
3397 BufferSize,
3398 (VOID *)((UINT8 *)Buffer + ResultSize),
3399 &ResultSize
3400 );
3401 if (EFI_ERROR (Status)) {
3402 return Status;
3403 }
3404
3405 Status = ExportFontPackages (
3406 Private,
3407 Handle,
3408 PackageList,
3409 *UsedSize,
3410 BufferSize,
3411 (VOID *)((UINT8 *)Buffer + ResultSize),
3412 &ResultSize
3413 );
3414 if (EFI_ERROR (Status)) {
3415 return Status;
3416 }
3417
3418 Status = ExportImagePackages (
3419 Private,
3420 Handle,
3421 PackageList,
3422 *UsedSize,
3423 BufferSize,
3424 (VOID *)((UINT8 *)Buffer + ResultSize),
3425 &ResultSize
3426 );
3427 if (EFI_ERROR (Status)) {
3428 return Status;
3429 }
3430
3431 Status = ExportSimpleFontPackages (
3432 Private,
3433 Handle,
3434 PackageList,
3435 *UsedSize,
3436 BufferSize,
3437 (VOID *)((UINT8 *)Buffer + ResultSize),
3438 &ResultSize
3439 );
3440 if (EFI_ERROR (Status)) {
3441 return Status;
3442 }
3443
3444 Status = ExportDevicePathPackage (
3445 Private,
3446 Handle,
3447 PackageList,
3448 *UsedSize,
3449 BufferSize,
3450 (VOID *)((UINT8 *)Buffer + ResultSize),
3451 &ResultSize
3452 );
3453 if (EFI_ERROR (Status)) {
3454 return Status;
3455 }
3456
3457 //
3458 // Append the package list end.
3459 //
3460 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);
3461 EndofPackageList.Type = EFI_HII_PACKAGE_END;
3462 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {
3463 CopyMem (
3464 (VOID *)((UINT8 *)Buffer + ResultSize),
3465 (VOID *)&EndofPackageList,
3466 sizeof (EFI_HII_PACKAGE_HEADER)
3467 );
3468 }
3469
3470 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);
3471
3472 return EFI_SUCCESS;
3473}
3474
3475/**
3476This function mainly use to get and update ConfigResp string.
3477
3478@param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
3479
3480@retval EFI_SUCCESS Get the information successfully.
3481@retval EFI_OUT_OF_RESOURCES Not enough memory to store the Configuration Setting data.
3482
3483**/
3484EFI_STATUS
3485HiiGetConfigRespInfo (
3486 IN CONST EFI_HII_DATABASE_PROTOCOL *This
3487 )
3488{
3489 EFI_STATUS Status;
3490 HII_DATABASE_PRIVATE_DATA *Private;
3491 EFI_STRING ConfigAltResp;
3492 UINTN ConfigSize;
3493
3494 ConfigAltResp = NULL;
3495 ConfigSize = 0;
3496
3497 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3498
3499 //
3500 // Get ConfigResp string
3501 //
3502 Status = HiiConfigRoutingExportConfig (&Private->ConfigRouting, &ConfigAltResp);
3503
3504 if (!EFI_ERROR (Status)) {
3505 ConfigSize = StrSize (ConfigAltResp);
3506 if (ConfigSize > gConfigRespSize) {
3507 //
3508 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3509 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3510 //
3511 gConfigRespSize = ConfigSize + (ConfigSize >> 2);
3512 if (gRTConfigRespBuffer != NULL) {
3513 FreePool (gRTConfigRespBuffer);
3514 DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3515 }
3516
3517 gRTConfigRespBuffer = (EFI_STRING)AllocateRuntimeZeroPool (gConfigRespSize);
3518 if (gRTConfigRespBuffer == NULL) {
3519 FreePool (ConfigAltResp);
3520 DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the ConfigResp string.\n"));
3521 //
3522 // Remove from the System Table when the configuration runtime buffer is freed.
3523 //
3524 gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, NULL);
3525 return EFI_OUT_OF_RESOURCES;
3526 }
3527 } else {
3528 ZeroMem (gRTConfigRespBuffer, gConfigRespSize);
3529 }
3530
3531 CopyMem (gRTConfigRespBuffer, ConfigAltResp, ConfigSize);
3532 gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, gRTConfigRespBuffer);
3533 FreePool (ConfigAltResp);
3534 }
3535
3536 return EFI_SUCCESS;
3537}
3538
3539/**
3540This is an internal function,mainly use to get HiiDatabase information.
3541
3542@param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
3543
3544@retval EFI_SUCCESS Get the information successfully.
3545@retval EFI_OUT_OF_RESOURCES Not enough memory to store the Hiidatabase data.
3546
3547**/
3548EFI_STATUS
3549HiiGetDatabaseInfo (
3550 IN CONST EFI_HII_DATABASE_PROTOCOL *This
3551 )
3552{
3553 EFI_STATUS Status;
3554 EFI_HII_PACKAGE_LIST_HEADER *DatabaseInfo;
3555 UINTN DatabaseInfoSize;
3556
3557 DatabaseInfo = NULL;
3558 DatabaseInfoSize = 0;
3559
3560 //
3561 // Get HiiDatabase information.
3562 //
3563 Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, DatabaseInfo);
3564
3565 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
3566
3567 if (DatabaseInfoSize > gDatabaseInfoSize ) {
3568 //
3569 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3570 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3571 //
3572 gDatabaseInfoSize = DatabaseInfoSize + (DatabaseInfoSize >> 2);
3573 if (gRTDatabaseInfoBuffer != NULL) {
3574 FreePool (gRTDatabaseInfoBuffer);
3575 DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3576 }
3577
3578 gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool (gDatabaseInfoSize);
3579 if (gRTDatabaseInfoBuffer == NULL) {
3580 DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));
3581 //
3582 // Remove from the System Table when the configuration runtime buffer is freed.
3583 //
3584 gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, NULL);
3585 return EFI_OUT_OF_RESOURCES;
3586 }
3587 } else {
3588 ZeroMem (gRTDatabaseInfoBuffer, gDatabaseInfoSize);
3589 }
3590
3591 Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, gRTDatabaseInfoBuffer);
3592 ASSERT_EFI_ERROR (Status);
3593 gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, gRTDatabaseInfoBuffer);
3594
3595 return EFI_SUCCESS;
3596}
3597
3598/**
3599 This function adds the packages in the package list to the database and returns a handle. If there is a
3600 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
3601 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
3602
3603 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3604 instance.
3605 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3606 structure.
3607 @param DriverHandle Associate the package list with this EFI handle.
3608 If a NULL is specified, this data will not be associate
3609 with any drivers and cannot have a callback induced.
3610 @param Handle A pointer to the EFI_HII_HANDLE instance.
3611
3612 @retval EFI_SUCCESS The package list associated with the Handle was
3613 added to the HII database.
3614 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
3615 database contents.
3616 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
3617 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
3618
3619**/
3620EFI_STATUS
3621EFIAPI
3622HiiNewPackageList (
3623 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3624 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
3625 IN CONST EFI_HANDLE DriverHandle OPTIONAL,
3626 OUT EFI_HII_HANDLE *Handle
3627 )
3628{
3629 EFI_STATUS Status;
3630 HII_DATABASE_PRIVATE_DATA *Private;
3631 HII_DATABASE_RECORD *DatabaseRecord;
3632 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
3633 LIST_ENTRY *Link;
3634 EFI_GUID PackageListGuid;
3635
3636 if ((This == NULL) || (PackageList == NULL) || (Handle == NULL)) {
3637 return EFI_INVALID_PARAMETER;
3638 }
3639
3640 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3641 CopyMem (&PackageListGuid, (VOID *)PackageList, sizeof (EFI_GUID));
3642
3643 //
3644 // Check the Package list GUID to guarantee this GUID is unique in database.
3645 //
3646 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3647 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3648 if (CompareGuid (
3649 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
3650 &PackageListGuid
3651 ) &&
3652 (DatabaseRecord->DriverHandle == DriverHandle))
3653 {
3654 return EFI_INVALID_PARAMETER;
3655 }
3656 }
3657
3658 EfiAcquireLock (&mHiiDatabaseLock);
3659
3660 //
3661 // Build a PackageList node
3662 //
3663 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
3664 if (EFI_ERROR (Status)) {
3665 EfiReleaseLock (&mHiiDatabaseLock);
3666 return Status;
3667 }
3668
3669 //
3670 // Fill in information of the created Package List node
3671 // according to incoming package list.
3672 //
3673 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
3674 if (EFI_ERROR (Status)) {
3675 EfiReleaseLock (&mHiiDatabaseLock);
3676 return Status;
3677 }
3678
3679 DatabaseRecord->DriverHandle = DriverHandle;
3680
3681 //
3682 // Create a Device path package and add into the package list if exists.
3683 //
3684 Status = gBS->HandleProtocol (
3685 DriverHandle,
3686 &gEfiDevicePathProtocolGuid,
3687 (VOID **)&DevicePath
3688 );
3689 if (!EFI_ERROR (Status)) {
3690 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
3691 ASSERT_EFI_ERROR (Status);
3692 }
3693
3694 *Handle = DatabaseRecord->Handle;
3695
3696 //
3697 // Check whether need to get the Database info.
3698 // Only after ReadyToBoot, need to do the export.
3699 //
3700 if (gExportAfterReadyToBoot) {
3701 HiiGetDatabaseInfo (This);
3702 }
3703
3704 EfiReleaseLock (&mHiiDatabaseLock);
3705
3706 //
3707 // Notes:
3708 // HiiGetDatabaseInfo () will get the contents of HII data base,
3709 // belong to the atomic behavior of Hii Database update.
3710 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3711 // we can not think it belong to the atomic behavior of Hii Database update.
3712 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3713 //
3714
3715 // Check whether need to get the configuration setting info from HII drivers.
3716 // When after ReadyToBoot and need to do the export for form package add.
3717 //
3718 if (gExportAfterReadyToBoot && gExportConfigResp) {
3719 HiiGetConfigRespInfo (This);
3720 }
3721
3722 return EFI_SUCCESS;
3723}
3724
3725/**
3726 This function removes the package list that is associated with Handle
3727 from the HII database. Before removing the package, any registered functions
3728 with the notification type REMOVE_PACK and the same package type will be called.
3729
3730 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3731 instance.
3732 @param Handle The handle that was registered to the data that is
3733 requested for removal.
3734
3735 @retval EFI_SUCCESS The data associated with the Handle was removed
3736 from the HII database.
3737 @retval EFI_NOT_FOUND The specified handle is not in database.
3738 @retval EFI_INVALID_PARAMETER The Handle was not valid.
3739
3740**/
3741EFI_STATUS
3742EFIAPI
3743HiiRemovePackageList (
3744 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3745 IN EFI_HII_HANDLE Handle
3746 )
3747{
3748 EFI_STATUS Status;
3749 HII_DATABASE_PRIVATE_DATA *Private;
3750 LIST_ENTRY *Link;
3751 HII_DATABASE_RECORD *Node;
3752 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
3753 HII_HANDLE *HiiHandle;
3754
3755 if (This == NULL) {
3756 return EFI_INVALID_PARAMETER;
3757 }
3758
3759 if (!IsHiiHandleValid (Handle)) {
3760 return EFI_NOT_FOUND;
3761 }
3762
3763 EfiAcquireLock (&mHiiDatabaseLock);
3764
3765 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3766
3767 //
3768 // Get the packagelist to be removed.
3769 //
3770 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3771 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3772 if (Node->Handle == Handle) {
3773 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(Node->PackageList);
3774 ASSERT (PackageList != NULL);
3775
3776 //
3777 // Call registered functions with REMOVE_PACK before removing packages
3778 // then remove them.
3779 //
3780 Status = RemoveGuidPackages (Private, Handle, PackageList);
3781 if (EFI_ERROR (Status)) {
3782 EfiReleaseLock (&mHiiDatabaseLock);
3783 return Status;
3784 }
3785
3786 Status = RemoveFormPackages (Private, Handle, PackageList);
3787 if (EFI_ERROR (Status)) {
3788 EfiReleaseLock (&mHiiDatabaseLock);
3789 return Status;
3790 }
3791
3792 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
3793 if (EFI_ERROR (Status)) {
3794 EfiReleaseLock (&mHiiDatabaseLock);
3795 return Status;
3796 }
3797
3798 Status = RemoveStringPackages (Private, Handle, PackageList);
3799 if (EFI_ERROR (Status)) {
3800 EfiReleaseLock (&mHiiDatabaseLock);
3801 return Status;
3802 }
3803
3804 Status = RemoveFontPackages (Private, Handle, PackageList);
3805 if (EFI_ERROR (Status)) {
3806 EfiReleaseLock (&mHiiDatabaseLock);
3807 return Status;
3808 }
3809
3810 Status = RemoveImagePackages (Private, Handle, PackageList);
3811 if (EFI_ERROR (Status)) {
3812 EfiReleaseLock (&mHiiDatabaseLock);
3813 return Status;
3814 }
3815
3816 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
3817 if (EFI_ERROR (Status)) {
3818 EfiReleaseLock (&mHiiDatabaseLock);
3819 return Status;
3820 }
3821
3822 Status = RemoveDevicePathPackage (Private, Handle, PackageList);
3823 if (EFI_ERROR (Status)) {
3824 EfiReleaseLock (&mHiiDatabaseLock);
3825 return Status;
3826 }
3827
3828 //
3829 // Free resources of the package list
3830 //
3831 RemoveEntryList (&Node->DatabaseEntry);
3832
3833 HiiHandle = (HII_HANDLE *)Handle;
3834 RemoveEntryList (&HiiHandle->Handle);
3835 Private->HiiHandleCount--;
3836 ASSERT (Private->HiiHandleCount >= 0);
3837
3838 HiiHandle->Signature = 0;
3839 FreePool (HiiHandle);
3840 FreePool (Node->PackageList);
3841 FreePool (Node);
3842
3843 //
3844 // Check whether need to get the Database info.
3845 // Only after ReadyToBoot, need to do the export.
3846 //
3847 if (gExportAfterReadyToBoot) {
3848 HiiGetDatabaseInfo (This);
3849 }
3850
3851 EfiReleaseLock (&mHiiDatabaseLock);
3852
3853 //
3854 // Notes:
3855 // HiiGetDatabaseInfo () will get the contents of HII data base,
3856 // belong to the atomic behavior of Hii Database update.
3857 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3858 // we can not think it belong to the atomic behavior of Hii Database update.
3859 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3860 //
3861
3862 //
3863 // Check whether need to get the configuration setting info from HII drivers.
3864 // When after ReadyToBoot and need to do the export for form package remove.
3865 //
3866 if (gExportAfterReadyToBoot && gExportConfigResp) {
3867 HiiGetConfigRespInfo (This);
3868 }
3869
3870 return EFI_SUCCESS;
3871 }
3872 }
3873
3874 EfiReleaseLock (&mHiiDatabaseLock);
3875 return EFI_NOT_FOUND;
3876}
3877
3878/**
3879 This function updates the existing package list (which has the specified Handle)
3880 in the HII databases, using the new package list specified by PackageList.
3881
3882 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3883 instance.
3884 @param Handle The handle that was registered to the data that is
3885 requested to be updated.
3886 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3887 package.
3888
3889 @retval EFI_SUCCESS The HII database was successfully updated.
3890 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
3891 database.
3892 @retval EFI_INVALID_PARAMETER PackageList was NULL.
3893 @retval EFI_NOT_FOUND The specified Handle is not in database.
3894
3895**/
3896EFI_STATUS
3897EFIAPI
3898HiiUpdatePackageList (
3899 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
3900 IN EFI_HII_HANDLE Handle,
3901 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
3902 )
3903{
3904 EFI_STATUS Status;
3905 HII_DATABASE_PRIVATE_DATA *Private;
3906 LIST_ENTRY *Link;
3907 HII_DATABASE_RECORD *Node;
3908 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
3909 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;
3910 EFI_HII_PACKAGE_HEADER PackageHeader;
3911
3912 if ((This == NULL) || (PackageList == NULL)) {
3913 return EFI_INVALID_PARAMETER;
3914 }
3915
3916 if (!IsHiiHandleValid (Handle)) {
3917 return EFI_NOT_FOUND;
3918 }
3919
3920 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
3921
3922 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *)((UINT8 *)PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
3923
3924 Status = EFI_SUCCESS;
3925
3926 EfiAcquireLock (&mHiiDatabaseLock);
3927 //
3928 // Get original packagelist to be updated
3929 //
3930 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
3931 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
3932 if (Node->Handle == Handle) {
3933 OldPackageList = Node->PackageList;
3934 //
3935 // Remove the package if its type matches one of the package types which is
3936 // contained in the new package list.
3937 //
3938 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3939 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
3940 switch (PackageHeader.Type) {
3941 case EFI_HII_PACKAGE_TYPE_GUID:
3942 Status = RemoveGuidPackages (Private, Handle, OldPackageList);
3943 break;
3944 case EFI_HII_PACKAGE_FORMS:
3945 Status = RemoveFormPackages (Private, Handle, OldPackageList);
3946 break;
3947 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
3948 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
3949 break;
3950 case EFI_HII_PACKAGE_STRINGS:
3951 Status = RemoveStringPackages (Private, Handle, OldPackageList);
3952 break;
3953 case EFI_HII_PACKAGE_FONTS:
3954 Status = RemoveFontPackages (Private, Handle, OldPackageList);
3955 break;
3956 case EFI_HII_PACKAGE_IMAGES:
3957 Status = RemoveImagePackages (Private, Handle, OldPackageList);
3958 break;
3959 case EFI_HII_PACKAGE_SIMPLE_FONTS:
3960 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
3961 break;
3962 case EFI_HII_PACKAGE_DEVICE_PATH:
3963 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
3964 break;
3965 }
3966
3967 if (EFI_ERROR (Status)) {
3968 EfiReleaseLock (&mHiiDatabaseLock);
3969 return Status;
3970 }
3971
3972 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *)((UINT8 *)PackageHdrPtr + PackageHeader.Length);
3973 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
3974 }
3975
3976 //
3977 // Add all of the packages within the new package list
3978 //
3979 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
3980
3981 //
3982 // Check whether need to get the Database info.
3983 // Only after ReadyToBoot, need to do the export.
3984 //
3985 if (gExportAfterReadyToBoot && (Status == EFI_SUCCESS)) {
3986 HiiGetDatabaseInfo (This);
3987 }
3988
3989 EfiReleaseLock (&mHiiDatabaseLock);
3990
3991 //
3992 // Notes:
3993 // HiiGetDatabaseInfo () will get the contents of HII data base,
3994 // belong to the atomic behavior of Hii Database update.
3995 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3996 // we can not think it belong to the atomic behavior of Hii Database update.
3997 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3998 //
3999
4000 //
4001 // Check whether need to get the configuration setting info from HII drivers.
4002 // When after ReadyToBoot and need to do the export for form package update.
4003 //
4004 if (gExportAfterReadyToBoot && gExportConfigResp && (Status == EFI_SUCCESS)) {
4005 HiiGetConfigRespInfo (This);
4006 }
4007
4008 return Status;
4009 }
4010 }
4011
4012 EfiReleaseLock (&mHiiDatabaseLock);
4013 return EFI_NOT_FOUND;
4014}
4015
4016/**
4017 This function returns a list of the package handles of the specified type
4018 that are currently active in the database. The pseudo-type
4019 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
4020
4021 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4022 instance.
4023 @param PackageType Specifies the package type of the packages to list
4024 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
4025 listed.
4026 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
4027 this is the pointer to the GUID which must match
4028 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
4029 Otherwise, it must be NULL.
4030 @param HandleBufferLength On input, a pointer to the length of the handle
4031 buffer. On output, the length of the handle
4032 buffer that is required for the handles found.
4033 @param Handle An array of EFI_HII_HANDLE instances returned.
4034
4035 @retval EFI_SUCCESS The matching handles are outputted successfully.
4036 HandleBufferLength is updated with the actual length.
4037 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
4038 Handle is too small to support the number of
4039 handles. HandleBufferLength is updated with a
4040 value that will enable the data to fit.
4041 @retval EFI_NOT_FOUND No matching handle could not be found in database.
4042 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.
4043 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not
4044 zero and Handle was NULL.
4045 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
4046 PackageGuid is not NULL, PackageType is a EFI_HII_
4047 PACKAGE_TYPE_GUID but PackageGuid is NULL.
4048
4049**/
4050EFI_STATUS
4051EFIAPI
4052HiiListPackageLists (
4053 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4054 IN UINT8 PackageType,
4055 IN CONST EFI_GUID *PackageGuid,
4056 IN OUT UINTN *HandleBufferLength,
4057 OUT EFI_HII_HANDLE *Handle
4058 )
4059{
4060 HII_GUID_PACKAGE_INSTANCE *GuidPackage;
4061 HII_DATABASE_PRIVATE_DATA *Private;
4062 HII_DATABASE_RECORD *Node;
4063 LIST_ENTRY *Link;
4064 BOOLEAN Matched;
4065 HII_HANDLE **Result;
4066 UINTN ResultSize;
4067 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
4068 LIST_ENTRY *Link1;
4069
4070 //
4071 // Check input parameters
4072 //
4073 if ((This == NULL) || (HandleBufferLength == NULL)) {
4074 return EFI_INVALID_PARAMETER;
4075 }
4076
4077 if ((*HandleBufferLength > 0) && (Handle == NULL)) {
4078 return EFI_INVALID_PARAMETER;
4079 }
4080
4081 if (((PackageType == EFI_HII_PACKAGE_TYPE_GUID) && (PackageGuid == NULL)) ||
4082 ((PackageType != EFI_HII_PACKAGE_TYPE_GUID) && (PackageGuid != NULL)))
4083 {
4084 return EFI_INVALID_PARAMETER;
4085 }
4086
4087 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4088 Matched = FALSE;
4089 Result = (HII_HANDLE **)Handle;
4090 ResultSize = 0;
4091
4092 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
4093 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4094 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(Node->PackageList);
4095 switch (PackageType) {
4096 case EFI_HII_PACKAGE_TYPE_GUID:
4097 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {
4098 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
4099 if (CompareGuid (
4100 (EFI_GUID *)PackageGuid,
4101 (EFI_GUID *)(GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))
4102 ))
4103 {
4104 Matched = TRUE;
4105 break;
4106 }
4107 }
4108
4109 break;
4110 case EFI_HII_PACKAGE_FORMS:
4111 if (!IsListEmpty (&PackageList->FormPkgHdr)) {
4112 Matched = TRUE;
4113 }
4114
4115 break;
4116 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
4117 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {
4118 Matched = TRUE;
4119 }
4120
4121 break;
4122 case EFI_HII_PACKAGE_STRINGS:
4123 if (!IsListEmpty (&PackageList->StringPkgHdr)) {
4124 Matched = TRUE;
4125 }
4126
4127 break;
4128 case EFI_HII_PACKAGE_FONTS:
4129 if (!IsListEmpty (&PackageList->FontPkgHdr)) {
4130 Matched = TRUE;
4131 }
4132
4133 break;
4134 case EFI_HII_PACKAGE_IMAGES:
4135 if (PackageList->ImagePkg != NULL) {
4136 Matched = TRUE;
4137 }
4138
4139 break;
4140 case EFI_HII_PACKAGE_SIMPLE_FONTS:
4141 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {
4142 Matched = TRUE;
4143 }
4144
4145 break;
4146 case EFI_HII_PACKAGE_DEVICE_PATH:
4147 if (PackageList->DevicePathPkg != NULL) {
4148 Matched = TRUE;
4149 }
4150
4151 break;
4152 //
4153 // Pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
4154 // to be listed.
4155 //
4156 case EFI_HII_PACKAGE_TYPE_ALL:
4157 Matched = TRUE;
4158 break;
4159 default:
4160 break;
4161 }
4162
4163 //
4164 // This active package list has the specified package type, list it.
4165 //
4166 if (Matched) {
4167 ResultSize += sizeof (EFI_HII_HANDLE);
4168 if (ResultSize <= *HandleBufferLength) {
4169 *Result++ = Node->Handle;
4170 }
4171 }
4172
4173 Matched = FALSE;
4174 }
4175
4176 if (ResultSize == 0) {
4177 return EFI_NOT_FOUND;
4178 }
4179
4180 if (*HandleBufferLength < ResultSize) {
4181 *HandleBufferLength = ResultSize;
4182 return EFI_BUFFER_TOO_SMALL;
4183 }
4184
4185 *HandleBufferLength = ResultSize;
4186 return EFI_SUCCESS;
4187}
4188
4189/**
4190 This function will export one or all package lists in the database to a buffer.
4191 For each package list exported, this function will call functions registered
4192 with EXPORT_PACK and then copy the package list to the buffer.
4193
4194 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4195 instance.
4196 @param Handle An EFI_HII_HANDLE that corresponds to the desired
4197 package list in the HII database to export or NULL
4198 to indicate all package lists should be exported.
4199 @param BufferSize On input, a pointer to the length of the buffer.
4200 On output, the length of the buffer that is
4201 required for the exported data.
4202 @param Buffer A pointer to a buffer that will contain the
4203 results of the export function.
4204
4205 @retval EFI_SUCCESS Package exported.
4206 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
4207 Handle is too small to support the number of
4208 handles. HandleBufferLength is updated with a
4209 value that will enable the data to fit.
4210 @retval EFI_NOT_FOUND The specified Handle could not be found in the
4211 current database.
4212 @retval EFI_INVALID_PARAMETER BufferSize was NULL.
4213 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero
4214 and Buffer was NULL.
4215
4216**/
4217EFI_STATUS
4218EFIAPI
4219HiiExportPackageLists (
4220 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4221 IN EFI_HII_HANDLE Handle,
4222 IN OUT UINTN *BufferSize,
4223 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
4224 )
4225{
4226 LIST_ENTRY *Link;
4227 EFI_STATUS Status;
4228 HII_DATABASE_PRIVATE_DATA *Private;
4229 HII_DATABASE_RECORD *Node;
4230 UINTN UsedSize;
4231
4232 if ((This == NULL) || (BufferSize == NULL)) {
4233 return EFI_INVALID_PARAMETER;
4234 }
4235
4236 if ((*BufferSize > 0) && (Buffer == NULL)) {
4237 return EFI_INVALID_PARAMETER;
4238 }
4239
4240 if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {
4241 return EFI_NOT_FOUND;
4242 }
4243
4244 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4245 UsedSize = 0;
4246
4247 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
4248 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4249 if (Handle == NULL) {
4250 //
4251 // Export all package lists in current hii database.
4252 //
4253 Status = ExportPackageList (
4254 Private,
4255 Node->Handle,
4256 (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(Node->PackageList),
4257 &UsedSize,
4258 *BufferSize,
4259 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *)Buffer + UsedSize)
4260 );
4261 ASSERT_EFI_ERROR (Status);
4262 } else if ((Handle != NULL) && (Node->Handle == Handle)) {
4263 Status = ExportPackageList (
4264 Private,
4265 Handle,
4266 (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(Node->PackageList),
4267 &UsedSize,
4268 *BufferSize,
4269 Buffer
4270 );
4271 ASSERT_EFI_ERROR (Status);
4272 if (*BufferSize < UsedSize) {
4273 *BufferSize = UsedSize;
4274 return EFI_BUFFER_TOO_SMALL;
4275 }
4276
4277 return EFI_SUCCESS;
4278 }
4279 }
4280
4281 if ((Handle == NULL) && (UsedSize != 0)) {
4282 if (*BufferSize < UsedSize) {
4283 *BufferSize = UsedSize;
4284 return EFI_BUFFER_TOO_SMALL;
4285 }
4286
4287 return EFI_SUCCESS;
4288 }
4289
4290 return EFI_NOT_FOUND;
4291}
4292
4293/**
4294 This function registers a function which will be called when specified actions related to packages of
4295 the specified type occur in the HII database. By registering a function, other HII-related drivers are
4296 notified when specific package types are added, removed or updated in the HII database.
4297 Each driver or application which registers a notification should use
4298 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
4299
4300 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4301 instance.
4302 @param PackageType Specifies the package type of the packages to list
4303 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
4304 listed.
4305 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
4306 this is the pointer to the GUID which must match
4307 the Guid field of
4308 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
4309 be NULL.
4310 @param PackageNotifyFn Points to the function to be called when the event
4311 specified by
4312 NotificationType occurs.
4313 @param NotifyType Describes the types of notification which this
4314 function will be receiving.
4315 @param NotifyHandle Points to the unique handle assigned to the
4316 registered notification. Can be used in
4317 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
4318 to stop notifications.
4319
4320 @retval EFI_SUCCESS Notification registered successfully.
4321 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
4322 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
4323 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
4324 EFI_HII_PACKAGE_TYPE_GUID.
4325 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
4326 EFI_HII_PACKAGE_TYPE_GUID.
4327
4328**/
4329EFI_STATUS
4330EFIAPI
4331HiiRegisterPackageNotify (
4332 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4333 IN UINT8 PackageType,
4334 IN CONST EFI_GUID *PackageGuid,
4335 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
4336 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
4337 OUT EFI_HANDLE *NotifyHandle
4338 )
4339{
4340 HII_DATABASE_PRIVATE_DATA *Private;
4341 HII_DATABASE_NOTIFY *Notify;
4342 EFI_STATUS Status;
4343
4344 if ((This == NULL) || (NotifyHandle == NULL)) {
4345 return EFI_INVALID_PARAMETER;
4346 }
4347
4348 if (((PackageType == EFI_HII_PACKAGE_TYPE_GUID) && (PackageGuid == NULL)) ||
4349 ((PackageType != EFI_HII_PACKAGE_TYPE_GUID) && (PackageGuid != NULL)))
4350 {
4351 return EFI_INVALID_PARAMETER;
4352 }
4353
4354 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4355
4356 //
4357 // Allocate a notification node
4358 //
4359 Notify = (HII_DATABASE_NOTIFY *)AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));
4360 if (Notify == NULL) {
4361 return EFI_OUT_OF_RESOURCES;
4362 }
4363
4364 //
4365 // Generate a notify handle
4366 //
4367 Status = gBS->InstallMultipleProtocolInterfaces (
4368 &Notify->NotifyHandle,
4369 &gEfiCallerIdGuid,
4370 NULL,
4371 NULL
4372 );
4373 ASSERT_EFI_ERROR (Status);
4374
4375 //
4376 // Fill in the information to the notification node
4377 //
4378 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;
4379 Notify->PackageType = PackageType;
4380 Notify->PackageGuid = (EFI_GUID *)PackageGuid;
4381 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY)PackageNotifyFn;
4382 Notify->NotifyType = NotifyType;
4383
4384 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);
4385 *NotifyHandle = Notify->NotifyHandle;
4386
4387 return EFI_SUCCESS;
4388}
4389
4390/**
4391 Removes the specified HII database package-related notification.
4392
4393 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4394 instance.
4395 @param NotificationHandle The handle of the notification function being
4396 unregistered.
4397
4398 @retval EFI_SUCCESS Notification is unregistered successfully.
4399 @retval EFI_INVALID_PARAMETER The Handle is invalid.
4400 @retval EFI_NOT_FOUND The incoming notification handle does not exist
4401 in current hii database.
4402
4403**/
4404EFI_STATUS
4405EFIAPI
4406HiiUnregisterPackageNotify (
4407 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4408 IN EFI_HANDLE NotificationHandle
4409 )
4410{
4411 HII_DATABASE_PRIVATE_DATA *Private;
4412 HII_DATABASE_NOTIFY *Notify;
4413 LIST_ENTRY *Link;
4414 EFI_STATUS Status;
4415
4416 if (This == NULL) {
4417 return EFI_INVALID_PARAMETER;
4418 }
4419
4420 if (NotificationHandle == NULL) {
4421 return EFI_NOT_FOUND;
4422 }
4423
4424 Status = gBS->OpenProtocol (
4425 NotificationHandle,
4426 &gEfiCallerIdGuid,
4427 NULL,
4428 NULL,
4429 NULL,
4430 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
4431 );
4432 if (EFI_ERROR (Status)) {
4433 return EFI_NOT_FOUND;
4434 }
4435
4436 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4437
4438 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {
4439 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
4440 if (Notify->NotifyHandle == NotificationHandle) {
4441 //
4442 // Remove the matching notification node
4443 //
4444 RemoveEntryList (&Notify->DatabaseNotifyEntry);
4445 Status = gBS->UninstallMultipleProtocolInterfaces (
4446 Notify->NotifyHandle,
4447 &gEfiCallerIdGuid,
4448 NULL,
4449 NULL
4450 );
4451 ASSERT_EFI_ERROR (Status);
4452 FreePool (Notify);
4453
4454 return EFI_SUCCESS;
4455 }
4456 }
4457
4458 return EFI_NOT_FOUND;
4459}
4460
4461/**
4462 This routine retrieves an array of GUID values for each keyboard layout that
4463 was previously registered in the system.
4464
4465 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4466 instance.
4467 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard
4468 GUID buffer. On output, the length of the handle
4469 buffer that is required for the handles found.
4470 @param KeyGuidBuffer An array of keyboard layout GUID instances
4471 returned.
4472
4473 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
4474 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
4475 that KeyGuidBuffer is too small to support the
4476 number of GUIDs. KeyGuidBufferLength is
4477 updated with a value that will enable the data to
4478 fit.
4479 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.
4480 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not
4481 zero and KeyGuidBuffer is NULL.
4482 @retval EFI_NOT_FOUND There was no keyboard layout.
4483
4484**/
4485EFI_STATUS
4486EFIAPI
4487HiiFindKeyboardLayouts (
4488 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4489 IN OUT UINT16 *KeyGuidBufferLength,
4490 OUT EFI_GUID *KeyGuidBuffer
4491 )
4492{
4493 HII_DATABASE_PRIVATE_DATA *Private;
4494 HII_DATABASE_RECORD *Node;
4495 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
4496 LIST_ENTRY *Link;
4497 LIST_ENTRY *Link1;
4498 UINT16 ResultSize;
4499 UINTN Index;
4500 UINT16 LayoutCount;
4501 UINT16 LayoutLength;
4502 UINT8 *Layout;
4503 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
4504
4505 if ((This == NULL) || (KeyGuidBufferLength == NULL)) {
4506 return EFI_INVALID_PARAMETER;
4507 }
4508
4509 if ((*KeyGuidBufferLength > 0) && (KeyGuidBuffer == NULL)) {
4510 return EFI_INVALID_PARAMETER;
4511 }
4512
4513 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4514 ResultSize = 0;
4515
4516 //
4517 // Search all package lists in whole database to retrieve keyboard layout.
4518 //
4519 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
4520 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4521 PackageList = Node->PackageList;
4522 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
4523 Link1 != &PackageList->KeyboardLayoutHdr;
4524 Link1 = Link1->ForwardLink
4525 )
4526 {
4527 //
4528 // Find out all Keyboard Layout packages in this package list.
4529 //
4530 Package = CR (
4531 Link1,
4532 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
4533 KeyboardEntry,
4534 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4535 );
4536 Layout = (UINT8 *)Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
4537 CopyMem (
4538 &LayoutCount,
4539 (UINT8 *)Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),
4540 sizeof (UINT16)
4541 );
4542 for (Index = 0; Index < LayoutCount; Index++) {
4543 ResultSize += sizeof (EFI_GUID);
4544 if (ResultSize <= *KeyGuidBufferLength) {
4545 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));
4546 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
4547 Layout = Layout + LayoutLength;
4548 }
4549 }
4550 }
4551 }
4552
4553 if (ResultSize == 0) {
4554 return EFI_NOT_FOUND;
4555 }
4556
4557 if (*KeyGuidBufferLength < ResultSize) {
4558 *KeyGuidBufferLength = ResultSize;
4559 return EFI_BUFFER_TOO_SMALL;
4560 }
4561
4562 *KeyGuidBufferLength = ResultSize;
4563 return EFI_SUCCESS;
4564}
4565
4566/**
4567 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
4568 on a keyboard and the character(s) that are associated with a particular set of key strokes.
4569
4570 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4571 instance.
4572 @param KeyGuid A pointer to the unique ID associated with a given
4573 keyboard layout. If KeyGuid is NULL then the
4574 current layout will be retrieved.
4575 @param KeyboardLayoutLength On input, a pointer to the length of the
4576 KeyboardLayout buffer. On output, the length of
4577 the data placed into KeyboardLayout.
4578 @param KeyboardLayout A pointer to a buffer containing the retrieved
4579 keyboard layout.
4580
4581 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
4582 @retval EFI_NOT_FOUND The requested keyboard layout was not found.
4583 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
4584 NULL.
4585 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
4586 that KeyboardLayout is too small to support the
4587 requested keyboard layout. KeyboardLayoutLength is
4588 updated with a value that will enable the
4589 data to fit.
4590
4591**/
4592EFI_STATUS
4593EFIAPI
4594HiiGetKeyboardLayout (
4595 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4596 IN CONST EFI_GUID *KeyGuid,
4597 IN OUT UINT16 *KeyboardLayoutLength,
4598 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
4599 )
4600{
4601 HII_DATABASE_PRIVATE_DATA *Private;
4602 HII_DATABASE_RECORD *Node;
4603 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
4604 LIST_ENTRY *Link;
4605 LIST_ENTRY *Link1;
4606 UINTN Index;
4607 UINT8 *Layout;
4608 UINT16 LayoutCount;
4609 UINT16 LayoutLength;
4610 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
4611
4612 if ((This == NULL) || (KeyboardLayoutLength == NULL)) {
4613 return EFI_INVALID_PARAMETER;
4614 }
4615
4616 if ((*KeyboardLayoutLength > 0) && (KeyboardLayout == NULL)) {
4617 return EFI_INVALID_PARAMETER;
4618 }
4619
4620 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4621 //
4622 // Retrieve the current keyboard layout.
4623 //
4624 if (KeyGuid == NULL) {
4625 if (Private->CurrentLayout == NULL) {
4626 return EFI_NOT_FOUND;
4627 }
4628
4629 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));
4630 if (*KeyboardLayoutLength < LayoutLength) {
4631 *KeyboardLayoutLength = LayoutLength;
4632 return EFI_BUFFER_TOO_SMALL;
4633 }
4634
4635 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);
4636 return EFI_SUCCESS;
4637 }
4638
4639 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
4640 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4641 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(Node->PackageList);
4642 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
4643 Link1 != &PackageList->KeyboardLayoutHdr;
4644 Link1 = Link1->ForwardLink
4645 )
4646 {
4647 Package = CR (
4648 Link1,
4649 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
4650 KeyboardEntry,
4651 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4652 );
4653
4654 Layout = (UINT8 *)Package->KeyboardPkg +
4655 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
4656 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));
4657 for (Index = 0; Index < LayoutCount; Index++) {
4658 CopyMem (&LayoutLength, Layout, sizeof (UINT16));
4659 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {
4660 if (LayoutLength <= *KeyboardLayoutLength) {
4661 CopyMem (KeyboardLayout, Layout, LayoutLength);
4662 return EFI_SUCCESS;
4663 } else {
4664 *KeyboardLayoutLength = LayoutLength;
4665 return EFI_BUFFER_TOO_SMALL;
4666 }
4667 }
4668
4669 Layout = Layout + LayoutLength;
4670 }
4671 }
4672 }
4673
4674 return EFI_NOT_FOUND;
4675}
4676
4677/**
4678 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
4679 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
4680 group type. This is so that agents which are sensitive to the current keyboard layout being changed
4681 can be notified of this change.
4682
4683 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4684 instance.
4685 @param KeyGuid A pointer to the unique ID associated with a given
4686 keyboard layout.
4687
4688 @retval EFI_SUCCESS The current keyboard layout was successfully set.
4689 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
4690 action was taken.
4691 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
4692
4693**/
4694EFI_STATUS
4695EFIAPI
4696HiiSetKeyboardLayout (
4697 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4698 IN CONST EFI_GUID *KeyGuid
4699 )
4700{
4701 HII_DATABASE_PRIVATE_DATA *Private;
4702 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
4703 UINT16 KeyboardLayoutLength;
4704 EFI_STATUS Status;
4705
4706 if ((This == NULL) || (KeyGuid == NULL)) {
4707 return EFI_INVALID_PARAMETER;
4708 }
4709
4710 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4711
4712 //
4713 // The specified GUID equals the current keyboard layout GUID,
4714 // return directly.
4715 //
4716 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {
4717 return EFI_SUCCESS;
4718 }
4719
4720 //
4721 // Try to find the incoming keyboard layout data in current database.
4722 //
4723 KeyboardLayoutLength = 0;
4724 KeyboardLayout = NULL;
4725 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
4726 if (Status != EFI_BUFFER_TOO_SMALL) {
4727 return Status;
4728 }
4729
4730 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *)AllocateZeroPool (KeyboardLayoutLength);
4731 ASSERT (KeyboardLayout != NULL);
4732 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
4733 ASSERT_EFI_ERROR (Status);
4734
4735 //
4736 // Backup current keyboard layout.
4737 //
4738 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));
4739 if (Private->CurrentLayout != NULL) {
4740 FreePool (Private->CurrentLayout);
4741 }
4742
4743 Private->CurrentLayout = KeyboardLayout;
4744
4745 //
4746 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
4747 // current keyboard layout is changed.
4748 //
4749 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);
4750 ASSERT_EFI_ERROR (Status);
4751
4752 return EFI_SUCCESS;
4753}
4754
4755/**
4756 Return the EFI handle associated with a package list.
4757
4758 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4759 instance.
4760 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
4761 package list in the HIIdatabase.
4762 @param DriverHandle On return, contains the EFI_HANDLE which was
4763 registered with the package list in
4764 NewPackageList().
4765
4766 @retval EFI_SUCCESS The DriverHandle was returned successfully.
4767 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
4768 DriverHandle was NULL.
4769 @retval EFI_NOT_FOUND This PackageList handle can not be found in
4770 current database.
4771
4772**/
4773EFI_STATUS
4774EFIAPI
4775HiiGetPackageListHandle (
4776 IN CONST EFI_HII_DATABASE_PROTOCOL *This,
4777 IN EFI_HII_HANDLE PackageListHandle,
4778 OUT EFI_HANDLE *DriverHandle
4779 )
4780{
4781 HII_DATABASE_PRIVATE_DATA *Private;
4782 HII_DATABASE_RECORD *Node;
4783 LIST_ENTRY *Link;
4784
4785 if ((This == NULL) || (DriverHandle == NULL)) {
4786 return EFI_INVALID_PARAMETER;
4787 }
4788
4789 if (!IsHiiHandleValid (PackageListHandle)) {
4790 return EFI_INVALID_PARAMETER;
4791 }
4792
4793 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4794
4795 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
4796 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4797 if (Node->Handle == PackageListHandle) {
4798 *DriverHandle = Node->DriverHandle;
4799 return EFI_SUCCESS;
4800 }
4801 }
4802
4803 return EFI_NOT_FOUND;
4804}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette