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