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