]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg/HiiDB: Remove configuration table when it's freed (CVE-2019-14586)
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_DATABASE_PROTOCOL.\r
3\r
c32be82e 4Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
93e3992d 6\r
93e3992d 7**/\r
8\r
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
c32be82e
DB
3379 //\r
3380 // Remove from the System Table when the configuration runtime buffer is freed.\r
3381 //\r
3382 gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, NULL);\r
8a45f80e
DB
3383 return EFI_OUT_OF_RESOURCES;\r
3384 }\r
3385 } else {\r
3386 ZeroMem(gRTConfigRespBuffer,gConfigRespSize);\r
3387 }\r
3388 CopyMem(gRTConfigRespBuffer,ConfigAltResp,ConfigSize);\r
3389 gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, gRTConfigRespBuffer);\r
3390 FreePool(ConfigAltResp);\r
3391 }\r
3392\r
3393 return EFI_SUCCESS;\r
3394\r
3395}\r
3396\r
3397/**\r
3398This is an internal function,mainly use to get HiiDatabase information.\r
3399\r
3400@param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
3401\r
3402@retval EFI_SUCCESS Get the information successfully.\r
3403@retval EFI_OUT_OF_RESOURCES Not enough memory to store the Hiidatabase data.\r
3404\r
3405**/\r
3406EFI_STATUS\r
3407HiiGetDatabaseInfo(\r
3408 IN CONST EFI_HII_DATABASE_PROTOCOL *This\r
3409 )\r
3410{\r
3411 EFI_STATUS Status;\r
3412 EFI_HII_PACKAGE_LIST_HEADER *DatabaseInfo;\r
3413 UINTN DatabaseInfoSize;\r
3414\r
3415 DatabaseInfo = NULL;\r
3416 DatabaseInfoSize = 0;\r
3417\r
3418 //\r
3419 // Get HiiDatabase information.\r
3420 //\r
3421 Status = HiiExportPackageLists(This, NULL, &DatabaseInfoSize, DatabaseInfo);\r
3422\r
3423 ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
3424\r
3425 if(DatabaseInfoSize > gDatabaseInfoSize ) {\r
60a86abf
DB
3426 //\r
3427 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.\r
3428 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.\r
3429 //\r
3430 gDatabaseInfoSize = DatabaseInfoSize + (DatabaseInfoSize >> 2);\r
8a45f80e
DB
3431 if (gRTDatabaseInfoBuffer != NULL){\r
3432 FreePool(gRTDatabaseInfoBuffer);\r
60a86abf 3433 DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));\r
8a45f80e 3434 }\r
60a86abf 3435 gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool (gDatabaseInfoSize);\r
8a45f80e 3436 if (gRTDatabaseInfoBuffer == NULL){\r
60a86abf 3437 DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));\r
c32be82e
DB
3438 //\r
3439 // Remove from the System Table when the configuration runtime buffer is freed.\r
3440 //\r
3441 gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, NULL);\r
8a45f80e
DB
3442 return EFI_OUT_OF_RESOURCES;\r
3443 }\r
3444 } else {\r
3445 ZeroMem(gRTDatabaseInfoBuffer,gDatabaseInfoSize);\r
3446 }\r
3447 Status = HiiExportPackageLists(This, NULL, &DatabaseInfoSize, gRTDatabaseInfoBuffer);\r
3448 ASSERT_EFI_ERROR (Status);\r
3449 gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, gRTDatabaseInfoBuffer);\r
3450\r
3451 return EFI_SUCCESS;\r
3452\r
3453}\r
93e3992d 3454\r
3455/**\r
3456 This function adds the packages in the package list to the database and returns a handle. If there is a\r
3457 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
3458 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.\r
3459\r
3460 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3461 instance.\r
3462 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
3463 structure.\r
3464 @param DriverHandle Associate the package list with this EFI handle.\r
b1a803d1 3465 If a NULL is specified, this data will not be associate\r
3466 with any drivers and cannot have a callback induced.\r
93e3992d 3467 @param Handle A pointer to the EFI_HII_HANDLE instance.\r
3468\r
3469 @retval EFI_SUCCESS The package list associated with the Handle was\r
3470 added to the HII database.\r
3471 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
3472 database contents.\r
3473 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.\r
3474 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.\r
3475\r
3476**/\r
3477EFI_STATUS\r
3478EFIAPI\r
3479HiiNewPackageList (\r
3480 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3481 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
b1a803d1 3482 IN CONST EFI_HANDLE DriverHandle, OPTIONAL\r
93e3992d 3483 OUT EFI_HII_HANDLE *Handle\r
3484 )\r
3485{\r
3486 EFI_STATUS Status;\r
3487 HII_DATABASE_PRIVATE_DATA *Private;\r
3488 HII_DATABASE_RECORD *DatabaseRecord;\r
3489 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
3490 LIST_ENTRY *Link;\r
3491 EFI_GUID PackageListGuid;\r
3492\r
3493 if (This == NULL || PackageList == NULL || Handle == NULL) {\r
3494 return EFI_INVALID_PARAMETER;\r
3495 }\r
3496\r
3497 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3498 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));\r
3499\r
3500 //\r
3501 // Check the Package list GUID to guarantee this GUID is unique in database.\r
3502 //\r
3503 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3504 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3505 if (CompareGuid (\r
3506 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
d1102dba 3507 &PackageListGuid) &&\r
aa2614b7 3508 DatabaseRecord->DriverHandle == DriverHandle) {\r
93e3992d 3509 return EFI_INVALID_PARAMETER;\r
3510 }\r
3511 }\r
3512\r
979b7d80
DB
3513 EfiAcquireLock (&mHiiDatabaseLock);\r
3514\r
93e3992d 3515 //\r
3516 // Build a PackageList node\r
3517 //\r
3518 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
3519 if (EFI_ERROR (Status)) {\r
979b7d80 3520 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3521 return Status;\r
3522 }\r
3523\r
3524 //\r
3525 // Fill in information of the created Package List node\r
3526 // according to incoming package list.\r
3527 //\r
3528 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
3529 if (EFI_ERROR (Status)) {\r
979b7d80 3530 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3531 return Status;\r
3532 }\r
3533\r
3534 DatabaseRecord->DriverHandle = DriverHandle;\r
3535\r
3536 //\r
3537 // Create a Device path package and add into the package list if exists.\r
3538 //\r
3539 Status = gBS->HandleProtocol (\r
3540 DriverHandle,\r
3541 &gEfiDevicePathProtocolGuid,\r
3542 (VOID **) &DevicePath\r
3543 );\r
3544 if (!EFI_ERROR (Status)) {\r
3545 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);\r
3546 ASSERT_EFI_ERROR (Status);\r
3547 }\r
3548\r
3549 *Handle = DatabaseRecord->Handle;\r
8a45f80e
DB
3550\r
3551 //\r
adb2c050 3552 // Check whether need to get the Database info.\r
8a45f80e
DB
3553 // Only after ReadyToBoot, need to do the export.\r
3554 //\r
3555 if (gExportAfterReadyToBoot) {\r
adb2c050
DB
3556 HiiGetDatabaseInfo (This);\r
3557 }\r
979b7d80 3558 EfiReleaseLock (&mHiiDatabaseLock);\r
adb2c050
DB
3559\r
3560 //\r
979b7d80
DB
3561 // Notes:\r
3562 // HiiGetDatabaseInfo () will get the contents of HII data base,\r
3563 // belong to the atomic behavior of Hii Database update.\r
3564 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
3565 // we can not think it belong to the atomic behavior of Hii Database update.\r
3566 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
3567 //\r
3568\r
adb2c050
DB
3569 // Check whether need to get the configuration setting info from HII drivers.\r
3570 // When after ReadyToBoot and need to do the export for form package add.\r
3571 //\r
3572 if (gExportAfterReadyToBoot && gExportConfigResp) {\r
3573 HiiGetConfigRespInfo (This);\r
8a45f80e
DB
3574 }\r
3575\r
93e3992d 3576 return EFI_SUCCESS;\r
3577}\r
3578\r
3579\r
3580/**\r
4a429716 3581 This function removes the package list that is associated with Handle\r
93e3992d 3582 from the HII database. Before removing the package, any registered functions\r
3583 with the notification type REMOVE_PACK and the same package type will be called.\r
3584\r
3585 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3586 instance.\r
3587 @param Handle The handle that was registered to the data that is\r
3588 requested for removal.\r
3589\r
3590 @retval EFI_SUCCESS The data associated with the Handle was removed\r
3591 from the HII database.\r
4a429716 3592 @retval EFI_NOT_FOUND The specified handle is not in database.\r
93e3992d 3593 @retval EFI_INVALID_PARAMETER The Handle was not valid.\r
3594\r
3595**/\r
3596EFI_STATUS\r
3597EFIAPI\r
3598HiiRemovePackageList (\r
3599 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3600 IN EFI_HII_HANDLE Handle\r
3601 )\r
3602{\r
3603 EFI_STATUS Status;\r
3604 HII_DATABASE_PRIVATE_DATA *Private;\r
3605 LIST_ENTRY *Link;\r
3606 HII_DATABASE_RECORD *Node;\r
3607 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3608 HII_HANDLE *HiiHandle;\r
3609\r
813acf3a 3610 if (This == NULL) {\r
93e3992d 3611 return EFI_INVALID_PARAMETER;\r
3612 }\r
3613\r
813acf3a 3614 if (!IsHiiHandleValid (Handle)) {\r
3615 return EFI_NOT_FOUND;\r
3616 }\r
3617\r
979b7d80
DB
3618 EfiAcquireLock (&mHiiDatabaseLock);\r
3619\r
93e3992d 3620 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3621\r
3622 //\r
3623 // Get the packagelist to be removed.\r
3624 //\r
3625 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3626 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3627 if (Node->Handle == Handle) {\r
3628 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3629 ASSERT (PackageList != NULL);\r
3630\r
3631 //\r
3632 // Call registered functions with REMOVE_PACK before removing packages\r
3633 // then remove them.\r
3634 //\r
3635 Status = RemoveGuidPackages (Private, Handle, PackageList);\r
3636 if (EFI_ERROR (Status)) {\r
979b7d80 3637 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3638 return Status;\r
3639 }\r
3640 Status = RemoveFormPackages (Private, Handle, PackageList);\r
3641 if (EFI_ERROR (Status)) {\r
979b7d80 3642 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3643 return Status;\r
3644 }\r
3645 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
3646 if (EFI_ERROR (Status)) {\r
979b7d80 3647 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3648 return Status;\r
3649 }\r
3650 Status = RemoveStringPackages (Private, Handle, PackageList);\r
3651 if (EFI_ERROR (Status)) {\r
979b7d80 3652 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3653 return Status;\r
3654 }\r
3655 Status = RemoveFontPackages (Private, Handle, PackageList);\r
3656 if (EFI_ERROR (Status)) {\r
979b7d80 3657 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3658 return Status;\r
3659 }\r
3660 Status = RemoveImagePackages (Private, Handle, PackageList);\r
3661 if (EFI_ERROR (Status)) {\r
979b7d80 3662 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3663 return Status;\r
3664 }\r
3665 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
3666 if (EFI_ERROR (Status)) {\r
979b7d80 3667 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3668 return Status;\r
3669 }\r
3670 Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
3671 if (EFI_ERROR (Status)) {\r
979b7d80 3672 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3673 return Status;\r
3674 }\r
3675\r
3676 //\r
3677 // Free resources of the package list\r
3678 //\r
3679 RemoveEntryList (&Node->DatabaseEntry);\r
3680\r
3681 HiiHandle = (HII_HANDLE *) Handle;\r
3682 RemoveEntryList (&HiiHandle->Handle);\r
3683 Private->HiiHandleCount--;\r
3684 ASSERT (Private->HiiHandleCount >= 0);\r
3685\r
3686 HiiHandle->Signature = 0;\r
676df92c 3687 FreePool (HiiHandle);\r
3688 FreePool (Node->PackageList);\r
3689 FreePool (Node);\r
93e3992d 3690\r
8a45f80e 3691 //\r
adb2c050 3692 // Check whether need to get the Database info.\r
8a45f80e
DB
3693 // Only after ReadyToBoot, need to do the export.\r
3694 //\r
3695 if (gExportAfterReadyToBoot) {\r
adb2c050
DB
3696 HiiGetDatabaseInfo (This);\r
3697 }\r
979b7d80
DB
3698 EfiReleaseLock (&mHiiDatabaseLock);\r
3699\r
3700 //\r
3701 // Notes:\r
3702 // HiiGetDatabaseInfo () will get the contents of HII data base,\r
3703 // belong to the atomic behavior of Hii Database update.\r
3704 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
3705 // we can not think it belong to the atomic behavior of Hii Database update.\r
3706 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
3707 //\r
adb2c050
DB
3708\r
3709 //\r
3710 // Check whether need to get the configuration setting info from HII drivers.\r
3711 // When after ReadyToBoot and need to do the export for form package remove.\r
3712 //\r
3713 if (gExportAfterReadyToBoot && gExportConfigResp) {\r
3714 HiiGetConfigRespInfo (This);\r
8a45f80e 3715 }\r
93e3992d 3716 return EFI_SUCCESS;\r
3717 }\r
3718 }\r
3719\r
979b7d80 3720 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3721 return EFI_NOT_FOUND;\r
3722}\r
3723\r
3724\r
3725/**\r
3726 This function updates the existing package list (which has the specified Handle)\r
3727 in the HII databases, using the new package list specified by PackageList.\r
3728\r
3729 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3730 instance.\r
3731 @param Handle The handle that was registered to the data that is\r
3732 requested to be updated.\r
3733 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
3734 package.\r
3735\r
3736 @retval EFI_SUCCESS The HII database was successfully updated.\r
3737 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated\r
3738 database.\r
813acf3a 3739 @retval EFI_INVALID_PARAMETER PackageList was NULL.\r
3740 @retval EFI_NOT_FOUND The specified Handle is not in database.\r
93e3992d 3741\r
3742**/\r
3743EFI_STATUS\r
3744EFIAPI\r
3745HiiUpdatePackageList (\r
3746 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3747 IN EFI_HII_HANDLE Handle,\r
3748 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList\r
3749 )\r
3750{\r
3751 EFI_STATUS Status;\r
3752 HII_DATABASE_PRIVATE_DATA *Private;\r
3753 LIST_ENTRY *Link;\r
3754 HII_DATABASE_RECORD *Node;\r
3755 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
3756 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;\r
3757 EFI_HII_PACKAGE_HEADER PackageHeader;\r
3758\r
813acf3a 3759 if (This == NULL || PackageList == NULL) {\r
93e3992d 3760 return EFI_INVALID_PARAMETER;\r
3761 }\r
3762\r
3763 if (!IsHiiHandleValid (Handle)) {\r
3764 return EFI_NOT_FOUND;\r
3765 }\r
3766\r
3767 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3768\r
3769 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
3770\r
3771 Status = EFI_SUCCESS;\r
3772\r
979b7d80 3773 EfiAcquireLock (&mHiiDatabaseLock);\r
93e3992d 3774 //\r
3775 // Get original packagelist to be updated\r
3776 //\r
3777 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3778 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3779 if (Node->Handle == Handle) {\r
3780 OldPackageList = Node->PackageList;\r
3781 //\r
3782 // Remove the package if its type matches one of the package types which is\r
3783 // contained in the new package list.\r
3784 //\r
3785 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3786 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
3787 switch (PackageHeader.Type) {\r
3788 case EFI_HII_PACKAGE_TYPE_GUID:\r
3789 Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
3790 break;\r
8d00a0f1 3791 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3792 Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
3793 break;\r
3794 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3795 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);\r
3796 break;\r
3797 case EFI_HII_PACKAGE_STRINGS:\r
3798 Status = RemoveStringPackages (Private, Handle, OldPackageList);\r
3799 break;\r
3800 case EFI_HII_PACKAGE_FONTS:\r
3801 Status = RemoveFontPackages (Private, Handle, OldPackageList);\r
3802 break;\r
3803 case EFI_HII_PACKAGE_IMAGES:\r
3804 Status = RemoveImagePackages (Private, Handle, OldPackageList);\r
3805 break;\r
3806 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3807 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);\r
3808 break;\r
3809 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3810 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);\r
3811 break;\r
3812 }\r
3813\r
3814 if (EFI_ERROR (Status)) {\r
979b7d80 3815 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3816 return Status;\r
3817 }\r
3818\r
3819 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
3820 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3821 }\r
3822\r
3823 //\r
3824 // Add all of the packages within the new package list\r
3825 //\r
8a45f80e
DB
3826 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
3827\r
3828 //\r
adb2c050 3829 // Check whether need to get the Database info.\r
8a45f80e
DB
3830 // Only after ReadyToBoot, need to do the export.\r
3831 //\r
adb2c050
DB
3832 if (gExportAfterReadyToBoot && Status == EFI_SUCCESS) {\r
3833 HiiGetDatabaseInfo (This);\r
3834 }\r
979b7d80
DB
3835 EfiReleaseLock (&mHiiDatabaseLock);\r
3836\r
3837 //\r
3838 // Notes:\r
3839 // HiiGetDatabaseInfo () will get the contents of HII data base,\r
3840 // belong to the atomic behavior of Hii Database update.\r
3841 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
3842 // we can not think it belong to the atomic behavior of Hii Database update.\r
3843 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
3844 //\r
adb2c050
DB
3845\r
3846 //\r
3847 // Check whether need to get the configuration setting info from HII drivers.\r
3848 // When after ReadyToBoot and need to do the export for form package update.\r
3849 //\r
3850 if (gExportAfterReadyToBoot && gExportConfigResp && Status == EFI_SUCCESS) {\r
3851 HiiGetConfigRespInfo (This);\r
8a45f80e
DB
3852 }\r
3853\r
3854 return Status;\r
93e3992d 3855 }\r
3856 }\r
979b7d80 3857 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 3858 return EFI_NOT_FOUND;\r
3859}\r
3860\r
3861\r
3862/**\r
3863 This function returns a list of the package handles of the specified type\r
3864 that are currently active in the database. The pseudo-type\r
3865 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.\r
3866\r
3867 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3868 instance.\r
3869 @param PackageType Specifies the package type of the packages to list\r
3870 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3871 listed.\r
3872 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3873 this is the pointer to the GUID which must match\r
3874 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.\r
3875 Otherwise, it must be NULL.\r
3876 @param HandleBufferLength On input, a pointer to the length of the handle\r
3877 buffer. On output, the length of the handle\r
3878 buffer that is required for the handles found.\r
3879 @param Handle An array of EFI_HII_HANDLE instances returned.\r
3880\r
4a429716 3881 @retval EFI_SUCCESS The matching handles are outputted successfully.\r
c0a3c3da 3882 HandleBufferLength is updated with the actual length.\r
93e3992d 3883 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3884 Handle is too small to support the number of\r
3885 handles. HandleBufferLength is updated with a\r
3886 value that will enable the data to fit.\r
3887 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
c0a3c3da
ED
3888 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.\r
3889 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not\r
3890 zero and Handle was NULL.\r
813acf3a 3891 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
c0a3c3da
ED
3892 PackageGuid is not NULL, PackageType is a EFI_HII_\r
3893 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
93e3992d 3894\r
3895**/\r
3896EFI_STATUS\r
3897EFIAPI\r
3898HiiListPackageLists (\r
3899 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3900 IN UINT8 PackageType,\r
3901 IN CONST EFI_GUID *PackageGuid,\r
3902 IN OUT UINTN *HandleBufferLength,\r
3903 OUT EFI_HII_HANDLE *Handle\r
3904 )\r
3905{\r
3906 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
3907 HII_DATABASE_PRIVATE_DATA *Private;\r
3908 HII_DATABASE_RECORD *Node;\r
3909 LIST_ENTRY *Link;\r
3910 BOOLEAN Matched;\r
3911 HII_HANDLE **Result;\r
3912 UINTN ResultSize;\r
3913 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3914 LIST_ENTRY *Link1;\r
3915\r
3916 //\r
3917 // Check input parameters\r
3918 //\r
3919 if (This == NULL || HandleBufferLength == NULL) {\r
3920 return EFI_INVALID_PARAMETER;\r
3921 }\r
3922 if (*HandleBufferLength > 0 && Handle == NULL) {\r
3923 return EFI_INVALID_PARAMETER;\r
3924 }\r
3925 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3926 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3927 return EFI_INVALID_PARAMETER;\r
3928 }\r
3929\r
3930 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3931 Matched = FALSE;\r
3932 Result = (HII_HANDLE **) Handle;\r
3933 ResultSize = 0;\r
3934\r
3935 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3936 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3937 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3938 switch (PackageType) {\r
3939 case EFI_HII_PACKAGE_TYPE_GUID:\r
3940 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {\r
3941 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
3942 if (CompareGuid (\r
3943 (EFI_GUID *) PackageGuid,\r
3944 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))\r
3945 )) {\r
3946 Matched = TRUE;\r
3947 break;\r
3948 }\r
3949 }\r
3950 break;\r
8d00a0f1 3951 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3952 if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
3953 Matched = TRUE;\r
3954 }\r
3955 break;\r
3956 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3957 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {\r
3958 Matched = TRUE;\r
3959 }\r
3960 break;\r
3961 case EFI_HII_PACKAGE_STRINGS:\r
3962 if (!IsListEmpty (&PackageList->StringPkgHdr)) {\r
3963 Matched = TRUE;\r
3964 }\r
3965 break;\r
3966 case EFI_HII_PACKAGE_FONTS:\r
3967 if (!IsListEmpty (&PackageList->FontPkgHdr)) {\r
3968 Matched = TRUE;\r
3969 }\r
3970 break;\r
3971 case EFI_HII_PACKAGE_IMAGES:\r
3972 if (PackageList->ImagePkg != NULL) {\r
3973 Matched = TRUE;\r
3974 }\r
3975 break;\r
3976 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3977 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {\r
3978 Matched = TRUE;\r
3979 }\r
3980 break;\r
3981 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3982 if (PackageList->DevicePathPkg != NULL) {\r
3983 Matched = TRUE;\r
3984 }\r
3985 break;\r
3986 //\r
4a429716 3987 // Pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
93e3992d 3988 // to be listed.\r
3989 //\r
3990 case EFI_HII_PACKAGE_TYPE_ALL:\r
3991 Matched = TRUE;\r
3992 break;\r
3993 default:\r
3994 break;\r
3995 }\r
3996\r
3997 //\r
3998 // This active package list has the specified package type, list it.\r
3999 //\r
4000 if (Matched) {\r
4001 ResultSize += sizeof (EFI_HII_HANDLE);\r
4002 if (ResultSize <= *HandleBufferLength) {\r
4003 *Result++ = Node->Handle;\r
4004 }\r
4005 }\r
4006 Matched = FALSE;\r
4007 }\r
4008\r
4009 if (ResultSize == 0) {\r
4010 return EFI_NOT_FOUND;\r
4011 }\r
4012\r
4013 if (*HandleBufferLength < ResultSize) {\r
4014 *HandleBufferLength = ResultSize;\r
4015 return EFI_BUFFER_TOO_SMALL;\r
4016 }\r
4017\r
4018 *HandleBufferLength = ResultSize;\r
4019 return EFI_SUCCESS;\r
4020}\r
4021\r
4022\r
4023/**\r
4024 This function will export one or all package lists in the database to a buffer.\r
4025 For each package list exported, this function will call functions registered\r
4026 with EXPORT_PACK and then copy the package list to the buffer.\r
4027\r
4028 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4029 instance.\r
4030 @param Handle An EFI_HII_HANDLE that corresponds to the desired\r
4031 package list in the HII database to export or NULL\r
4032 to indicate all package lists should be exported.\r
4033 @param BufferSize On input, a pointer to the length of the buffer.\r
4034 On output, the length of the buffer that is\r
4035 required for the exported data.\r
4036 @param Buffer A pointer to a buffer that will contain the\r
4037 results of the export function.\r
4038\r
4039 @retval EFI_SUCCESS Package exported.\r
4040 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
4041 Handle is too small to support the number of\r
4042 handles. HandleBufferLength is updated with a\r
4043 value that will enable the data to fit.\r
4a429716 4044 @retval EFI_NOT_FOUND The specified Handle could not be found in the\r
93e3992d 4045 current database.\r
c0a3c3da 4046 @retval EFI_INVALID_PARAMETER BufferSize was NULL.\r
d1102dba 4047 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero\r
c0a3c3da 4048 and Buffer was NULL.\r
93e3992d 4049\r
4050**/\r
4051EFI_STATUS\r
4052EFIAPI\r
4053HiiExportPackageLists (\r
4054 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4055 IN EFI_HII_HANDLE Handle,\r
4056 IN OUT UINTN *BufferSize,\r
4057 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
4058 )\r
4059{\r
4060 LIST_ENTRY *Link;\r
4061 EFI_STATUS Status;\r
4062 HII_DATABASE_PRIVATE_DATA *Private;\r
4063 HII_DATABASE_RECORD *Node;\r
4064 UINTN UsedSize;\r
4065\r
68945618 4066 if (This == NULL || BufferSize == NULL) {\r
93e3992d 4067 return EFI_INVALID_PARAMETER;\r
4068 }\r
4069 if (*BufferSize > 0 && Buffer == NULL) {\r
4070 return EFI_INVALID_PARAMETER;\r
4071 }\r
68945618 4072 if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {\r
93e3992d 4073 return EFI_NOT_FOUND;\r
4074 }\r
4075\r
4076 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4077 UsedSize = 0;\r
4078\r
4079 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
4080 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
4081 if (Handle == NULL) {\r
4082 //\r
4083 // Export all package lists in current hii database.\r
4084 //\r
4085 Status = ExportPackageList (\r
4086 Private,\r
4087 Node->Handle,\r
4088 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
4089 &UsedSize,\r
4090 *BufferSize,\r
4091 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
4092 );\r
4093 ASSERT_EFI_ERROR (Status);\r
6672d625 4094 } else if (Handle != NULL && Node->Handle == Handle) {\r
93e3992d 4095 Status = ExportPackageList (\r
4096 Private,\r
4097 Handle,\r
4098 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
4099 &UsedSize,\r
4100 *BufferSize,\r
4101 Buffer\r
4102 );\r
4103 ASSERT_EFI_ERROR (Status);\r
4104 if (*BufferSize < UsedSize) {\r
4105 *BufferSize = UsedSize;\r
4106 return EFI_BUFFER_TOO_SMALL;\r
4107 }\r
4108 return EFI_SUCCESS;\r
4109 }\r
4110 }\r
4111\r
4112 if (Handle == NULL && UsedSize != 0) {\r
4113 if (*BufferSize < UsedSize) {\r
4114 *BufferSize = UsedSize;\r
4115 return EFI_BUFFER_TOO_SMALL;\r
4116 }\r
4117 return EFI_SUCCESS;\r
4118 }\r
4119\r
4120 return EFI_NOT_FOUND;\r
4121}\r
4122\r
4123\r
4124/**\r
4125 This function registers a function which will be called when specified actions related to packages of\r
4126 the specified type occur in the HII database. By registering a function, other HII-related drivers are\r
4127 notified when specific package types are added, removed or updated in the HII database.\r
4128 Each driver or application which registers a notification should use\r
4129 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.\r
4130\r
4131 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4132 instance.\r
4133 @param PackageType Specifies the package type of the packages to list\r
4134 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
4135 listed.\r
4136 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
4137 this is the pointer to the GUID which must match\r
4138 the Guid field of\r
4139 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must\r
4140 be NULL.\r
4141 @param PackageNotifyFn Points to the function to be called when the event\r
4142 specified by\r
4143 NotificationType occurs.\r
4144 @param NotifyType Describes the types of notification which this\r
4145 function will be receiving.\r
4146 @param NotifyHandle Points to the unique handle assigned to the\r
4147 registered notification. Can be used in\r
4148 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()\r
4149 to stop notifications.\r
4150\r
4151 @retval EFI_SUCCESS Notification registered successfully.\r
4152 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures\r
4153 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.\r
4154 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not\r
4155 EFI_HII_PACKAGE_TYPE_GUID.\r
4156 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is\r
4157 EFI_HII_PACKAGE_TYPE_GUID.\r
4158\r
4159**/\r
4160EFI_STATUS\r
4161EFIAPI\r
4162HiiRegisterPackageNotify (\r
4163 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4164 IN UINT8 PackageType,\r
4165 IN CONST EFI_GUID *PackageGuid,\r
4166 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,\r
4167 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
4168 OUT EFI_HANDLE *NotifyHandle\r
4169 )\r
4170{\r
4171 HII_DATABASE_PRIVATE_DATA *Private;\r
4172 HII_DATABASE_NOTIFY *Notify;\r
4173 EFI_STATUS Status;\r
4174\r
4175 if (This == NULL || NotifyHandle == NULL) {\r
4176 return EFI_INVALID_PARAMETER;\r
4177 }\r
4178 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
4179 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
4180 return EFI_INVALID_PARAMETER;\r
4181 }\r
4182\r
4183 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4184\r
4185 //\r
4186 // Allocate a notification node\r
4187 //\r
4188 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));\r
4189 if (Notify == NULL) {\r
4190 return EFI_OUT_OF_RESOURCES;\r
4191 }\r
4192\r
4193 //\r
4194 // Generate a notify handle\r
4195 //\r
4196 Status = gBS->InstallMultipleProtocolInterfaces (\r
4197 &Notify->NotifyHandle,\r
c8ad2d7a 4198 &gEfiCallerIdGuid,\r
93e3992d 4199 NULL,\r
4200 NULL\r
4201 );\r
4202 ASSERT_EFI_ERROR (Status);\r
4203\r
4204 //\r
4205 // Fill in the information to the notification node\r
4206 //\r
4207 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;\r
4208 Notify->PackageType = PackageType;\r
4209 Notify->PackageGuid = (EFI_GUID *) PackageGuid;\r
4210 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;\r
4211 Notify->NotifyType = NotifyType;\r
4212\r
4213 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);\r
4214 *NotifyHandle = Notify->NotifyHandle;\r
4215\r
4216 return EFI_SUCCESS;\r
4217}\r
4218\r
4219\r
4220/**\r
4221 Removes the specified HII database package-related notification.\r
4222\r
4223 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4224 instance.\r
e90b081a 4225 @param NotificationHandle The handle of the notification function being\r
93e3992d 4226 unregistered.\r
4227\r
4228 @retval EFI_SUCCESS Notification is unregistered successfully.\r
4229 @retval EFI_INVALID_PARAMETER The Handle is invalid.\r
4230 @retval EFI_NOT_FOUND The incoming notification handle does not exist\r
4231 in current hii database.\r
4232\r
4233**/\r
4234EFI_STATUS\r
4235EFIAPI\r
4236HiiUnregisterPackageNotify (\r
4237 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4238 IN EFI_HANDLE NotificationHandle\r
4239 )\r
4240{\r
4241 HII_DATABASE_PRIVATE_DATA *Private;\r
4242 HII_DATABASE_NOTIFY *Notify;\r
4243 LIST_ENTRY *Link;\r
4244 EFI_STATUS Status;\r
4245\r
813acf3a 4246 if (This == NULL) {\r
93e3992d 4247 return EFI_INVALID_PARAMETER;\r
4248 }\r
4249\r
813acf3a 4250 if (NotificationHandle == NULL) {\r
4251 return EFI_NOT_FOUND;\r
4252 }\r
4253\r
93e3992d 4254 Status = gBS->OpenProtocol (\r
4255 NotificationHandle,\r
c8ad2d7a 4256 &gEfiCallerIdGuid,\r
93e3992d 4257 NULL,\r
4258 NULL,\r
4259 NULL,\r
4260 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
4261 );\r
4262 if (EFI_ERROR (Status)) {\r
813acf3a 4263 return EFI_NOT_FOUND;\r
93e3992d 4264 }\r
4265\r
4266 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4267\r
4268 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {\r
4269 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
4270 if (Notify->NotifyHandle == NotificationHandle) {\r
4271 //\r
4272 // Remove the matching notification node\r
4273 //\r
4274 RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
4275 Status = gBS->UninstallMultipleProtocolInterfaces (\r
4276 Notify->NotifyHandle,\r
c8ad2d7a 4277 &gEfiCallerIdGuid,\r
93e3992d 4278 NULL,\r
4279 NULL\r
4280 );\r
4281 ASSERT_EFI_ERROR (Status);\r
676df92c 4282 FreePool (Notify);\r
93e3992d 4283\r
4284 return EFI_SUCCESS;\r
4285 }\r
4286 }\r
4287\r
4288 return EFI_NOT_FOUND;\r
4289}\r
4290\r
4291\r
4292/**\r
4293 This routine retrieves an array of GUID values for each keyboard layout that\r
4294 was previously registered in the system.\r
4295\r
4296 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4297 instance.\r
4298 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard\r
4299 GUID buffer. On output, the length of the handle\r
4300 buffer that is required for the handles found.\r
4301 @param KeyGuidBuffer An array of keyboard layout GUID instances\r
4302 returned.\r
4303\r
4304 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.\r
4305 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates\r
4306 that KeyGuidBuffer is too small to support the\r
4307 number of GUIDs. KeyGuidBufferLength is\r
4308 updated with a value that will enable the data to\r
4309 fit.\r
c0a3c3da
ED
4310 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.\r
4311 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not\r
4312 zero and KeyGuidBuffer is NULL.\r
93e3992d 4313 @retval EFI_NOT_FOUND There was no keyboard layout.\r
4314\r
4315**/\r
4316EFI_STATUS\r
4317EFIAPI\r
4318HiiFindKeyboardLayouts (\r
4319 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4320 IN OUT UINT16 *KeyGuidBufferLength,\r
4321 OUT EFI_GUID *KeyGuidBuffer\r
4322 )\r
4323{\r
4324 HII_DATABASE_PRIVATE_DATA *Private;\r
4325 HII_DATABASE_RECORD *Node;\r
4326 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
4327 LIST_ENTRY *Link;\r
4328 LIST_ENTRY *Link1;\r
4329 UINT16 ResultSize;\r
4330 UINTN Index;\r
4331 UINT16 LayoutCount;\r
4332 UINT16 LayoutLength;\r
4333 UINT8 *Layout;\r
4334 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
4335\r
4336 if (This == NULL || KeyGuidBufferLength == NULL) {\r
4337 return EFI_INVALID_PARAMETER;\r
4338 }\r
4339\r
4340 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {\r
4341 return EFI_INVALID_PARAMETER;\r
4342 }\r
4343\r
4344 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4345 ResultSize = 0;\r
4346\r
4347 //\r
4348 // Search all package lists in whole database to retrieve keyboard layout.\r
4349 //\r
4350 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
4351 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
4352 PackageList = Node->PackageList;\r
4353 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
4354 Link1 != &PackageList->KeyboardLayoutHdr;\r
4355 Link1 = Link1->ForwardLink\r
4356 ) {\r
4357 //\r
4358 // Find out all Keyboard Layout packages in this package list.\r
4359 //\r
4360 Package = CR (\r
4361 Link1,\r
4362 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
4363 KeyboardEntry,\r
4364 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
4365 );\r
4366 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
4367 CopyMem (\r
4368 &LayoutCount,\r
4369 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
4370 sizeof (UINT16)\r
4371 );\r
4372 for (Index = 0; Index < LayoutCount; Index++) {\r
4373 ResultSize += sizeof (EFI_GUID);\r
4374 if (ResultSize <= *KeyGuidBufferLength) {\r
813acf3a 4375 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));\r
93e3992d 4376 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
4377 Layout = Layout + LayoutLength;\r
4378 }\r
4379 }\r
4380 }\r
4381 }\r
4382\r
4383 if (ResultSize == 0) {\r
4384 return EFI_NOT_FOUND;\r
4385 }\r
4386\r
4387 if (*KeyGuidBufferLength < ResultSize) {\r
4388 *KeyGuidBufferLength = ResultSize;\r
4389 return EFI_BUFFER_TOO_SMALL;\r
4390 }\r
4391\r
4392 *KeyGuidBufferLength = ResultSize;\r
4393 return EFI_SUCCESS;\r
4394}\r
4395\r
4396\r
4397/**\r
4398 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys\r
4399 on a keyboard and the character(s) that are associated with a particular set of key strokes.\r
4400\r
4401 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4402 instance.\r
4403 @param KeyGuid A pointer to the unique ID associated with a given\r
4404 keyboard layout. If KeyGuid is NULL then the\r
4405 current layout will be retrieved.\r
4406 @param KeyboardLayoutLength On input, a pointer to the length of the\r
4407 KeyboardLayout buffer. On output, the length of\r
4408 the data placed into KeyboardLayout.\r
4409 @param KeyboardLayout A pointer to a buffer containing the retrieved\r
4410 keyboard layout.\r
4411\r
4412 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
4413 @retval EFI_NOT_FOUND The requested keyboard layout was not found.\r
4414 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was\r
4415 NULL.\r
4416 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates\r
4417 that KeyboardLayout is too small to support the\r
4418 requested keyboard layout. KeyboardLayoutLength is\r
4419 updated with a value that will enable the\r
4420 data to fit.\r
4421\r
4422**/\r
4423EFI_STATUS\r
4424EFIAPI\r
4425HiiGetKeyboardLayout (\r
4426 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4427 IN CONST EFI_GUID *KeyGuid,\r
4428 IN OUT UINT16 *KeyboardLayoutLength,\r
4429 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout\r
4430 )\r
4431{\r
4432 HII_DATABASE_PRIVATE_DATA *Private;\r
4433 HII_DATABASE_RECORD *Node;\r
4434 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
4435 LIST_ENTRY *Link;\r
4436 LIST_ENTRY *Link1;\r
4437 UINTN Index;\r
4438 UINT8 *Layout;\r
4439 UINT16 LayoutCount;\r
4440 UINT16 LayoutLength;\r
4441 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
4442\r
4443 if (This == NULL || KeyboardLayoutLength == NULL) {\r
4444 return EFI_INVALID_PARAMETER;\r
4445 }\r
4446 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {\r
4447 return EFI_INVALID_PARAMETER;\r
4448 }\r
4449\r
4450 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4451 //\r
4452 // Retrieve the current keyboard layout.\r
4453 //\r
4454 if (KeyGuid == NULL) {\r
4455 if (Private->CurrentLayout == NULL) {\r
4456 return EFI_NOT_FOUND;\r
4457 }\r
4458 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));\r
4459 if (*KeyboardLayoutLength < LayoutLength) {\r
4460 *KeyboardLayoutLength = LayoutLength;\r
4461 return EFI_BUFFER_TOO_SMALL;\r
4462 }\r
4463 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);\r
4464 return EFI_SUCCESS;\r
4465 }\r
4466\r
4467 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
4468 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
4469 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
4470 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
4471 Link1 != &PackageList->KeyboardLayoutHdr;\r
4472 Link1 = Link1->ForwardLink\r
4473 ) {\r
4474 Package = CR (\r
4475 Link1,\r
4476 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
4477 KeyboardEntry,\r
4478 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
4479 );\r
4480\r
4481 Layout = (UINT8 *) Package->KeyboardPkg +\r
4482 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
4483 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));\r
4484 for (Index = 0; Index < LayoutCount; Index++) {\r
4485 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
4486 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {\r
4487 if (LayoutLength <= *KeyboardLayoutLength) {\r
4488 CopyMem (KeyboardLayout, Layout, LayoutLength);\r
4489 return EFI_SUCCESS;\r
4490 } else {\r
4491 *KeyboardLayoutLength = LayoutLength;\r
4492 return EFI_BUFFER_TOO_SMALL;\r
4493 }\r
4494 }\r
4495 Layout = Layout + LayoutLength;\r
4496 }\r
4497 }\r
4498 }\r
4499\r
4500 return EFI_NOT_FOUND;\r
4501}\r
4502\r
4503\r
4504/**\r
4505 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine\r
4506 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
4507 group type. This is so that agents which are sensitive to the current keyboard layout being changed\r
4508 can be notified of this change.\r
4509\r
4510 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4511 instance.\r
4512 @param KeyGuid A pointer to the unique ID associated with a given\r
4513 keyboard layout.\r
4514\r
4515 @retval EFI_SUCCESS The current keyboard layout was successfully set.\r
4516 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so\r
4517 action was taken.\r
4518 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.\r
4519\r
4520**/\r
4521EFI_STATUS\r
4522EFIAPI\r
4523HiiSetKeyboardLayout (\r
4524 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4525 IN CONST EFI_GUID *KeyGuid\r
4526 )\r
4527{\r
4528 HII_DATABASE_PRIVATE_DATA *Private;\r
4529 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
4530 UINT16 KeyboardLayoutLength;\r
4531 EFI_STATUS Status;\r
4532\r
4533 if (This == NULL || KeyGuid == NULL) {\r
4534 return EFI_INVALID_PARAMETER;\r
4535 }\r
4536\r
4537 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4538\r
4539 //\r
4540 // The specified GUID equals the current keyboard layout GUID,\r
4541 // return directly.\r
4542 //\r
4543 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {\r
4544 return EFI_SUCCESS;\r
4545 }\r
4546\r
4547 //\r
4548 // Try to find the incoming keyboard layout data in current database.\r
4549 //\r
4550 KeyboardLayoutLength = 0;\r
4551 KeyboardLayout = NULL;\r
4552 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
4553 if (Status != EFI_BUFFER_TOO_SMALL) {\r
4554 return Status;\r
4555 }\r
4556\r
4557 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);\r
4558 ASSERT (KeyboardLayout != NULL);\r
4559 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
4560 ASSERT_EFI_ERROR (Status);\r
4561\r
4562 //\r
4563 // Backup current keyboard layout.\r
4564 //\r
4565 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
676df92c 4566 if (Private->CurrentLayout != NULL) {\r
4567 FreePool(Private->CurrentLayout);\r
4568 }\r
93e3992d 4569 Private->CurrentLayout = KeyboardLayout;\r
4570\r
4571 //\r
4572 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify\r
4573 // current keyboard layout is changed.\r
4574 //\r
4575 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);\r
4576 ASSERT_EFI_ERROR (Status);\r
4577\r
4578 return EFI_SUCCESS;\r
4579}\r
4580\r
4581\r
4582/**\r
4583 Return the EFI handle associated with a package list.\r
4584\r
4585 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
4586 instance.\r
4587 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired\r
4588 package list in the HIIdatabase.\r
4589 @param DriverHandle On return, contains the EFI_HANDLE which was\r
4590 registered with the package list in\r
4591 NewPackageList().\r
4592\r
4593 @retval EFI_SUCCESS The DriverHandle was returned successfully.\r
4594 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or\r
4595 DriverHandle was NULL.\r
4596 @retval EFI_NOT_FOUND This PackageList handle can not be found in\r
4597 current database.\r
4598\r
4599**/\r
4600EFI_STATUS\r
4601EFIAPI\r
4602HiiGetPackageListHandle (\r
4603 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
4604 IN EFI_HII_HANDLE PackageListHandle,\r
4605 OUT EFI_HANDLE *DriverHandle\r
4606 )\r
4607{\r
4608 HII_DATABASE_PRIVATE_DATA *Private;\r
4609 HII_DATABASE_RECORD *Node;\r
4610 LIST_ENTRY *Link;\r
4611\r
4612 if (This == NULL || DriverHandle == NULL) {\r
4613 return EFI_INVALID_PARAMETER;\r
4614 }\r
4615\r
4616 if (!IsHiiHandleValid (PackageListHandle)) {\r
4617 return EFI_INVALID_PARAMETER;\r
4618 }\r
4619\r
4620 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
4621\r
4622 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
4623 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
4624 if (Node->Handle == PackageListHandle) {\r
4625 *DriverHandle = Node->DriverHandle;\r
4626 return EFI_SUCCESS;\r
4627 }\r
4628 }\r
4629\r
4630 return EFI_NOT_FOUND;\r
4631}\r
4632\r