MdeModulePkg HiiDataBase: Fix the potential NULL pointer reference
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_DATABASE_PROTOCOL.\r
3\r
8ddbd227 4Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
93e3992d 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
93e3992d 13**/\r
14\r
15\r
16#include "HiiDatabase.h"\r
17\r
8ddbd227
LG
18#define BASE_NUMBER 10\r
19\r
8a45f80e
DB
20EFI_HII_PACKAGE_LIST_HEADER *gRTDatabaseInfoBuffer = NULL;\r
21EFI_STRING gRTConfigRespBuffer = NULL;\r
22UINTN gDatabaseInfoSize = 0;\r
23UINTN gConfigRespSize = 0;\r
c87b13cd 24BOOLEAN gExportConfigResp = TRUE;\r
8ddbd227
LG
25UINTN gNvDefaultStoreSize = 0;\r
26SKU_ID gSkuId = 0xFFFFFFFFFFFFFFFF;\r
27LIST_ENTRY gVarStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
8a45f80e 28\r
93e3992d 29/**\r
30 This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
e90b081a 31 This is a internal function.\r
93e3992d 32\r
33 @param Private hii database private structure\r
e90b081a 34 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a\r
93e3992d 35 package list\r
36\r
37 @retval EFI_SUCCESS A database record is generated successfully.\r
38 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
39 database contents.\r
40 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.\r
41\r
42**/\r
93e3992d 43EFI_STATUS\r
44GenerateHiiDatabaseRecord (\r
45 IN HII_DATABASE_PRIVATE_DATA *Private,\r
46 OUT HII_DATABASE_RECORD **DatabaseNode\r
47 )\r
48{\r
49 HII_DATABASE_RECORD *DatabaseRecord;\r
50 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
51 HII_HANDLE *HiiHandle;\r
52\r
53 if (Private == NULL || DatabaseNode == NULL) {\r
54 return EFI_INVALID_PARAMETER;\r
55 }\r
56\r
57 DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD));\r
58 if (DatabaseRecord == NULL) {\r
59 return EFI_OUT_OF_RESOURCES;\r
60 }\r
61 DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;\r
62\r
63 DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));\r
64 if (DatabaseRecord->PackageList == NULL) {\r
676df92c 65 FreePool (DatabaseRecord);\r
93e3992d 66 return EFI_OUT_OF_RESOURCES;\r
67 }\r
68\r
69 PackageList = DatabaseRecord->PackageList;\r
70\r
71 InitializeListHead (&PackageList->GuidPkgHdr);\r
72 InitializeListHead (&PackageList->FormPkgHdr);\r
73 InitializeListHead (&PackageList->KeyboardLayoutHdr);\r
74 InitializeListHead (&PackageList->StringPkgHdr);\r
75 InitializeListHead (&PackageList->FontPkgHdr);\r
76 InitializeListHead (&PackageList->SimpleFontPkgHdr);\r
77 PackageList->ImagePkg = NULL;\r
78 PackageList->DevicePathPkg = NULL;\r
79\r
80 //\r
81 // Create a new hii handle\r
82 //\r
83 HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));\r
84 if (HiiHandle == NULL) {\r
676df92c 85 FreePool (DatabaseRecord->PackageList);\r
86 FreePool (DatabaseRecord);\r
93e3992d 87 return EFI_OUT_OF_RESOURCES;\r
88 }\r
89 HiiHandle->Signature = HII_HANDLE_SIGNATURE;\r
90 //\r
91 // Backup the number of Hii handles\r
92 //\r
93 Private->HiiHandleCount++;\r
cd7bfc2c 94 HiiHandle->Key = (UINTN) Private->HiiHandleCount;\r
93e3992d 95 //\r
96 // Insert the handle to hii handle list of the whole database.\r
97 //\r
98 InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);\r
99\r
100 DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle;\r
101\r
102 //\r
103 // Insert the Package List node to Package List link of the whole database.\r
104 //\r
105 InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);\r
106\r
107 *DatabaseNode = DatabaseRecord;\r
108\r
109 return EFI_SUCCESS;\r
110\r
111}\r
112\r
113\r
114/**\r
115 This function checks whether a handle is a valid EFI_HII_HANDLE\r
e90b081a 116 This is a internal function.\r
93e3992d 117\r
118 @param Handle Pointer to a EFI_HII_HANDLE\r
119\r
120 @retval TRUE Valid\r
121 @retval FALSE Invalid\r
122\r
123**/\r
124BOOLEAN\r
125IsHiiHandleValid (\r
126 EFI_HII_HANDLE Handle\r
127 )\r
128{\r
129 HII_HANDLE *HiiHandle;\r
130\r
131 HiiHandle = (HII_HANDLE *) Handle;\r
132\r
133 if (HiiHandle == NULL) {\r
134 return FALSE;\r
135 }\r
136\r
137 if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {\r
138 return FALSE;\r
139 }\r
140\r
141 return TRUE;\r
142}\r
143\r
144\r
145/**\r
146 This function invokes the matching registered function.\r
e90b081a 147 This is a internal function.\r
93e3992d 148\r
149 @param Private HII Database driver private structure.\r
150 @param NotifyType The type of change concerning the database.\r
151 @param PackageInstance Points to the package referred to by the\r
152 notification.\r
153 @param PackageType Package type\r
154 @param Handle The handle of the package list which contains the\r
155 specified package.\r
156\r
157 @retval EFI_SUCCESS Already checked all registered function and\r
158 invoked if matched.\r
159 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
160\r
161**/\r
93e3992d 162EFI_STATUS\r
163InvokeRegisteredFunction (\r
164 IN HII_DATABASE_PRIVATE_DATA *Private,\r
165 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
166 IN VOID *PackageInstance,\r
167 IN UINT8 PackageType,\r
168 IN EFI_HII_HANDLE Handle\r
169 )\r
170{\r
171 HII_DATABASE_NOTIFY *Notify;\r
172 LIST_ENTRY *Link;\r
173 EFI_HII_PACKAGE_HEADER *Package;\r
174 UINT8 *Buffer;\r
175 UINT32 BufferSize;\r
176 UINT32 HeaderSize;\r
177 UINT32 ImageBlockSize;\r
178 UINT32 PaletteInfoSize;\r
179\r
180 if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) {\r
181 return EFI_INVALID_PARAMETER;\r
182 }\r
183 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
184 return EFI_INVALID_PARAMETER;\r
185 }\r
186 if (!IsHiiHandleValid (Handle)) {\r
187 return EFI_INVALID_PARAMETER;\r
188 }\r
189\r
190 Buffer = NULL;\r
191 Package = NULL;\r
192\r
193 //\r
194 // Convert the incoming package from hii database storage format to UEFI\r
195 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.\r
196 //\r
197 switch (PackageType) {\r
198 case EFI_HII_PACKAGE_TYPE_GUID:\r
199 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);\r
200 break;\r
201\r
8d00a0f1 202 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 203 BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;\r
204 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
205 ASSERT (Buffer != NULL);\r
206 CopyMem (\r
207 Buffer,\r
208 &((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr,\r
209 sizeof (EFI_HII_PACKAGE_HEADER)\r
210 );\r
211 CopyMem (\r
212 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),\r
213 ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData,\r
214 BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)\r
215 );\r
216 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
217 break;\r
218\r
219 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
220 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg);\r
221 break;\r
222\r
223 case EFI_HII_PACKAGE_STRINGS:\r
224 BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length;\r
225 HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize;\r
226 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
227 ASSERT (Buffer != NULL);\r
228 CopyMem (\r
229 Buffer,\r
230 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr,\r
231 HeaderSize\r
232 );\r
233 CopyMem (\r
234 Buffer + HeaderSize,\r
235 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock,\r
236 BufferSize - HeaderSize\r
237 );\r
238 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
239 break;\r
240\r
241 case EFI_HII_PACKAGE_FONTS:\r
242 BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length;\r
243 HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize;\r
244 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
245 ASSERT (Buffer != NULL);\r
246 CopyMem (\r
247 Buffer,\r
248 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr,\r
249 HeaderSize\r
250 );\r
251 CopyMem (\r
252 Buffer + HeaderSize,\r
253 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock,\r
254 BufferSize - HeaderSize\r
255 );\r
256 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
257 break;\r
258\r
259 case EFI_HII_PACKAGE_IMAGES:\r
260 BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length;\r
261 HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
262 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
263 ASSERT (Buffer != NULL);\r
264\r
265 CopyMem (\r
266 Buffer,\r
267 &((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr,\r
268 HeaderSize\r
269 );\r
270 CopyMem (\r
271 Buffer + sizeof (EFI_HII_PACKAGE_HEADER),\r
272 &HeaderSize,\r
273 sizeof (UINT32)\r
274 );\r
275\r
276 ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize;\r
277 if (ImageBlockSize != 0) {\r
278 CopyMem (\r
279 Buffer + HeaderSize,\r
280 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock,\r
281 ImageBlockSize\r
282 );\r
283 }\r
284\r
285 PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize;\r
286 if (PaletteInfoSize != 0) {\r
287 CopyMem (\r
288 Buffer + HeaderSize + ImageBlockSize,\r
289 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock,\r
290 PaletteInfoSize\r
291 );\r
292 HeaderSize += ImageBlockSize;\r
293 CopyMem (\r
294 Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),\r
295 &HeaderSize,\r
296 sizeof (UINT32)\r
297 );\r
298 }\r
299 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
300 break;\r
301\r
302 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
303 BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length;\r
304 Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
305 ASSERT (Buffer != NULL);\r
306 CopyMem (\r
307 Buffer,\r
308 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr,\r
309 BufferSize\r
310 );\r
311 Package = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
312 break;\r
313\r
314 case EFI_HII_PACKAGE_DEVICE_PATH:\r
315 Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance;\r
316 break;\r
317\r
318 default:\r
319 return EFI_INVALID_PARAMETER;\r
320 }\r
321\r
322 for (Link = Private->DatabaseNotifyList.ForwardLink;\r
323 Link != &Private->DatabaseNotifyList;\r
324 Link = Link->ForwardLink\r
325 ) {\r
326 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
327 if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) {\r
328 //\r
329 // Check in case PackageGuid is not NULL when Package is GUID package\r
330 //\r
331 if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {\r
332 Notify->PackageGuid = NULL;\r
333 }\r
334 //\r
335 // Status of Registered Function is unknown so did not check it\r
336 //\r
337 Notify->PackageNotifyFn (\r
338 Notify->PackageType,\r
339 Notify->PackageGuid,\r
340 Package,\r
341 Handle,\r
342 NotifyType\r
343 );\r
344 }\r
345 }\r
346\r
676df92c 347 if (Buffer != NULL) {\r
348 FreePool (Buffer);\r
349 }\r
93e3992d 350\r
351 return EFI_SUCCESS;\r
352}\r
353\r
354\r
355/**\r
356 This function insert a GUID package to a package list node.\r
e90b081a 357 This is a internal function.\r
93e3992d 358\r
359 @param PackageHdr Pointer to a buffer stored with GUID package\r
360 information.\r
361 @param NotifyType The type of change concerning the database.\r
362 @param PackageList Pointer to a package list which will be inserted\r
363 to.\r
4a429716 364 @param Package Created GUID package\r
93e3992d 365\r
366 @retval EFI_SUCCESS Guid Package is inserted successfully.\r
367 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
368 Guid package.\r
369 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
370\r
371**/\r
93e3992d 372EFI_STATUS\r
373InsertGuidPackage (\r
374 IN VOID *PackageHdr,\r
375 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
376 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
377 OUT HII_GUID_PACKAGE_INSTANCE **Package\r
378 )\r
379{\r
380 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
381 EFI_HII_PACKAGE_HEADER PackageHeader;\r
382\r
383 if (PackageHdr == NULL || PackageList == NULL) {\r
384 return EFI_INVALID_PARAMETER;\r
385 }\r
386\r
387 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
388\r
389 //\r
390 // Create a GUID package node\r
391 //\r
392 GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));\r
393 if (GuidPackage == NULL) {\r
394 return EFI_OUT_OF_RESOURCES;\r
395 }\r
396 GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
397 if (GuidPackage->GuidPkg == NULL) {\r
676df92c 398 FreePool (GuidPackage);\r
93e3992d 399 return EFI_OUT_OF_RESOURCES;\r
400 }\r
401\r
402 GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;\r
403 CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);\r
404 InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);\r
405 *Package = GuidPackage;\r
406\r
407 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
408 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;\r
409 }\r
410\r
411 return EFI_SUCCESS;\r
412}\r
413\r
414\r
415/**\r
416 This function exports GUID packages to a buffer.\r
e90b081a 417 This is a internal function.\r
93e3992d 418\r
419 @param Private Hii database private structure.\r
420 @param Handle Identification of a package list.\r
421 @param PackageList Pointer to a package list which will be exported.\r
422 @param UsedSize The length of buffer be used.\r
423 @param BufferSize Length of the Buffer.\r
424 @param Buffer Allocated space for storing exported data.\r
425 @param ResultSize The size of the already exported content of this\r
426 package list.\r
427\r
428 @retval EFI_SUCCESS Guid Packages are exported successfully.\r
429 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
430\r
431**/\r
93e3992d 432EFI_STATUS\r
433ExportGuidPackages (\r
434 IN HII_DATABASE_PRIVATE_DATA *Private,\r
435 IN EFI_HII_HANDLE Handle,\r
436 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
437 IN UINTN UsedSize,\r
438 IN UINTN BufferSize,\r
439 IN OUT VOID *Buffer,\r
440 IN OUT UINTN *ResultSize\r
441 )\r
442{\r
443 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
444 LIST_ENTRY *Link;\r
445 UINTN PackageLength;\r
446 EFI_HII_PACKAGE_HEADER PackageHeader;\r
447 EFI_STATUS Status;\r
448\r
449 if (PackageList == NULL || ResultSize == NULL) {\r
450 return EFI_INVALID_PARAMETER;\r
451 }\r
452\r
453 if (BufferSize > 0 && Buffer == NULL ) {\r
454 return EFI_INVALID_PARAMETER;\r
455 }\r
456\r
457 PackageLength = 0;\r
458 Status = EFI_SUCCESS;\r
459\r
460 for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {\r
461 GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
462 CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
463 PackageLength += PackageHeader.Length;\r
464 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
465 Status = InvokeRegisteredFunction (\r
466 Private,\r
467 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
468 (VOID *) GuidPackage,\r
469 EFI_HII_PACKAGE_TYPE_GUID,\r
470 Handle\r
471 );\r
472 ASSERT_EFI_ERROR (Status);\r
473 CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);\r
474 Buffer = (UINT8 *) Buffer + PackageHeader.Length;\r
475 }\r
476 }\r
477\r
478 *ResultSize += PackageLength;\r
479 return EFI_SUCCESS;\r
480}\r
481\r
482\r
483/**\r
484 This function deletes all GUID packages from a package list node.\r
e90b081a 485 This is a internal function.\r
93e3992d 486\r
487 @param Private Hii database private data.\r
488 @param Handle Handle of the package list which contains the to\r
489 be removed GUID packages.\r
490 @param PackageList Pointer to a package list that contains removing\r
491 packages.\r
492\r
493 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.\r
494 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
495\r
496**/\r
93e3992d 497EFI_STATUS\r
498RemoveGuidPackages (\r
499 IN HII_DATABASE_PRIVATE_DATA *Private,\r
500 IN EFI_HII_HANDLE Handle,\r
501 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
502 )\r
503{\r
504 LIST_ENTRY *ListHead;\r
505 HII_GUID_PACKAGE_INSTANCE *Package;\r
506 EFI_STATUS Status;\r
507 EFI_HII_PACKAGE_HEADER PackageHeader;\r
508\r
509 ListHead = &PackageList->GuidPkgHdr;\r
510\r
511 while (!IsListEmpty (ListHead)) {\r
512 Package = CR (\r
513 ListHead->ForwardLink,\r
514 HII_GUID_PACKAGE_INSTANCE,\r
515 GuidEntry,\r
516 HII_GUID_PACKAGE_SIGNATURE\r
517 );\r
518 Status = InvokeRegisteredFunction (\r
519 Private,\r
520 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
521 (VOID *) Package,\r
522 EFI_HII_PACKAGE_TYPE_GUID,\r
523 Handle\r
524 );\r
525 if (EFI_ERROR (Status)) {\r
526 return Status;\r
527 }\r
528\r
529 RemoveEntryList (&Package->GuidEntry);\r
530 CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
531 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
676df92c 532 FreePool (Package->GuidPkg);\r
533 FreePool (Package);\r
93e3992d 534 }\r
535\r
536 return EFI_SUCCESS;\r
537}\r
538\r
8ddbd227
LG
539/**\r
540 Check the input question related to EFI variable\r
541\r
542 @param IfrQuestionHdr Point to Question header\r
543 @param EfiVarStoreList Point to EFI VarStore List\r
544 @param EfiVarStoreNumber The number of EFI VarStore\r
545\r
546 @retval Index The index of the found EFI varstore in EFI varstore list\r
547 EfiVarStoreNumber will return if no EFI varstore is found.\r
548**/\r
549UINTN\r
550IsEfiVarStoreQuestion (\r
551 EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
552 EFI_IFR_VARSTORE_EFI **EfiVarStoreList,\r
553 UINTN EfiVarStoreNumber\r
554 )\r
555{\r
556 UINTN Index;\r
557 for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
558 if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {\r
559 return Index;\r
560 }\r
561 }\r
562\r
563 return EfiVarStoreNumber;\r
564}\r
565\r
566/**\r
567 Find the matched variable from the input variable storage.\r
568\r
569 @param[in] VariableStorage Point to the variable storage header.\r
570 @param[in] VarGuid A unique identifier for the variable.\r
571 @param[in] VarAttribute The attributes bitmask for the variable.\r
572 @param[in] VarName A Null-terminated ascii string that is the name of the variable.\r
573\r
574 @return Pointer to the matched variable header or NULL if not found.\r
575**/\r
576VARIABLE_HEADER *\r
577FindVariableData (\r
578 IN VARIABLE_STORE_HEADER *VariableStorage,\r
579 IN EFI_GUID *VarGuid,\r
580 IN UINT32 VarAttribute,\r
581 IN CHAR16 *VarName\r
582 )\r
583{\r
584 VARIABLE_HEADER *VariableHeader;\r
585 VARIABLE_HEADER *VariableEnd;\r
586\r
587 VariableEnd = (VARIABLE_HEADER *) ((UINT8 *) VariableStorage + VariableStorage->Size);\r
588 VariableHeader = (VARIABLE_HEADER *) (VariableStorage + 1);\r
589 VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
590 while (VariableHeader < VariableEnd) {\r
591 if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&\r
592 VariableHeader->Attributes == VarAttribute &&\r
593 StrCmp (VarName, (CHAR16 *) (VariableHeader + 1)) == 0) {\r
594 return VariableHeader;\r
595 }\r
596 VariableHeader = (VARIABLE_HEADER *) ((UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);\r
597 VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
598 }\r
599\r
600 return NULL;\r
601}\r
602\r
603/**\r
604 Find question default value from PcdNvStoreDefaultValueBuffer\r
605\r
606 @param DefaultId Default store ID\r
607 @param EfiVarStore Point to EFI VarStore header\r
608 @param IfrQuestionHdr Point to Question header\r
609 @param ValueBuffer Point to Buffer includes the found default setting\r
610 @param Width Width of the default value\r
611 @param BitFieldQuestion Whether the Question is stored in Bit field.\r
612\r
613 @retval EFI_SUCCESS Question default value is found.\r
614 @retval EFI_NOT_FOUND Question default value is not found.\r
615**/\r
616EFI_STATUS\r
617FindQuestionDefaultSetting (\r
618 IN UINT16 DefaultId,\r
619 IN EFI_IFR_VARSTORE_EFI *EfiVarStore,\r
620 IN EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
621 OUT VOID *ValueBuffer,\r
622 IN UINTN Width,\r
623 IN BOOLEAN BitFieldQuestion\r
624 )\r
625{\r
626 VARIABLE_HEADER *VariableHeader;\r
627 VARIABLE_STORE_HEADER *VariableStorage;\r
628 LIST_ENTRY *Link;\r
629 VARSTORAGE_DEFAULT_DATA *Entry;\r
630 VARIABLE_STORE_HEADER *NvStoreBuffer;\r
631 UINT8 *DataBuffer;\r
632 UINT8 *BufferEnd;\r
633 BOOLEAN IsFound;\r
634 UINTN Index;\r
635 UINT32 BufferValue;\r
636 UINT32 BitFieldVal;\r
637 UINTN BitOffset;\r
638 UINTN ByteOffset;\r
639 UINTN BitWidth;\r
640 UINTN StartBit;\r
641 UINTN EndBit;\r
642 PCD_DEFAULT_DATA *DataHeader;\r
643 PCD_DEFAULT_INFO *DefaultInfo;\r
644 PCD_DATA_DELTA *DeltaData;\r
645\r
646 if (gSkuId == 0xFFFFFFFFFFFFFFFF) {\r
647 gSkuId = LibPcdGetSku ();\r
648 }\r
649\r
650 //\r
651 // Find the DefaultId setting from the full DefaultSetting\r
652 //\r
653 VariableStorage = NULL;\r
654 Link = gVarStorageList.ForwardLink;\r
655 while (Link != &gVarStorageList) {\r
656 Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);\r
657 if (Entry->DefaultId == DefaultId) {\r
658 VariableStorage = Entry->VariableStorage;\r
659 break;\r
660 }\r
661 Link = Link->ForwardLink;\r
662 }\r
663\r
664 if (Link == &gVarStorageList) {\r
665 DataBuffer = (UINT8 *) PcdGetPtr (PcdNvStoreDefaultValueBuffer);\r
666 gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;\r
667 //\r
668 // The first section data includes NV storage default setting.\r
669 //\r
670 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));\r
671 NvStoreBuffer = (VARIABLE_STORE_HEADER *) ((UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);\r
672 VariableStorage = AllocatePool (NvStoreBuffer->Size);\r
673 ASSERT (VariableStorage != NULL);\r
674 CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);\r
675\r
676 //\r
677 // Find the matched SkuId and DefaultId in the first section\r
678 //\r
679 IsFound = FALSE;\r
680 DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
681 BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
682 while ((UINT8 *) DefaultInfo < BufferEnd) {\r
683 if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
684 IsFound = TRUE;\r
685 break;\r
686 }\r
687 DefaultInfo ++;\r
688 }\r
689 //\r
690 // Find the matched SkuId and DefaultId in the remaining section\r
691 //\r
692 Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));\r
693 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
694 while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {\r
695 DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
696 BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
697 while ((UINT8 *) DefaultInfo < BufferEnd) {\r
698 if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
699 IsFound = TRUE;\r
700 break;\r
701 }\r
702 DefaultInfo ++;\r
703 }\r
704 if (IsFound) {\r
705 DeltaData = (PCD_DATA_DELTA *) BufferEnd;\r
706 BufferEnd = (UINT8 *) DataHeader + DataHeader->DataSize;\r
707 while ((UINT8 *) DeltaData < BufferEnd) {\r
708 *((UINT8 *) VariableStorage + DeltaData->Offset) = (UINT8) DeltaData->Value;\r
709 DeltaData ++;\r
710 }\r
711 break;\r
712 }\r
713 Index = (Index + DataHeader->DataSize + 7) & (~7);\r
714 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
715 }\r
716 //\r
717 // Cache the found result in VarStorageList\r
718 //\r
719 if (!IsFound) {\r
720 FreePool (VariableStorage);\r
721 VariableStorage = NULL;\r
722 }\r
723 Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));\r
724 Entry->DefaultId = DefaultId;\r
725 Entry->VariableStorage = VariableStorage;\r
726 InsertTailList (&gVarStorageList, &Entry->Entry);\r
727 }\r
728 //\r
729 // The matched variable storage is not found.\r
730 //\r
731 if (VariableStorage == NULL) {\r
732 return EFI_NOT_FOUND;\r
733 }\r
734\r
735 //\r
736 // Find the question default value from the variable storage\r
737 //\r
738 VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *) EfiVarStore->Name);\r
739 if (VariableHeader == NULL) {\r
740 return EFI_NOT_FOUND;\r
741 }\r
718b6fe9
LG
742 StartBit = 0;\r
743 EndBit = 0;\r
8ddbd227
LG
744 ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
745 if (BitFieldQuestion) {\r
746 BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
747 ByteOffset = BitOffset / 8;\r
748 BitWidth = Width;\r
749 StartBit = BitOffset % 8;\r
750 EndBit = StartBit + BitWidth - 1;\r
751 Width = EndBit / 8 + 1;\r
752 }\r
753 if (VariableHeader->DataSize < ByteOffset + Width) {\r
754 return EFI_INVALID_PARAMETER;\r
755 }\r
756\r
757 //\r
758 // Copy the question value\r
759 //\r
760 if (ValueBuffer != NULL) {\r
761 if (BitFieldQuestion) {\r
762 CopyMem (&BufferValue, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);\r
763 BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
764 CopyMem (ValueBuffer, &BitFieldVal, Width);\r
765 } else {\r
766 CopyMem (ValueBuffer, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);\r
767 }\r
768 }\r
769\r
770 return EFI_SUCCESS;\r
771}\r
772\r
773/**\r
774 Update IFR default setting in Form Package.\r
775\r
776 @param FormPackage Form Package to be updated\r
777\r
778**/\r
779VOID\r
780UpdateDefaultSettingInFormPackage (\r
781 HII_IFR_PACKAGE_INSTANCE *FormPackage\r
782 )\r
783{\r
784 UINTN IfrOffset;\r
785 UINTN PackageLength;\r
786 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;\r
787 EFI_IFR_OP_HEADER *IfrOpHdr;\r
788 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;\r
789 UINT8 IfrQuestionType;\r
790 UINT8 IfrScope;\r
791 EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;\r
792 EFI_IFR_VARSTORE_EFI **EfiVarStoreList;\r
793 UINTN EfiVarStoreMaxNum;\r
794 UINTN EfiVarStoreNumber;\r
795 UINT16 *DefaultIdList;\r
796 UINTN DefaultIdNumber;\r
797 UINTN DefaultIdMaxNum;\r
798 UINTN Index;\r
799 UINTN EfiVarStoreIndex;\r
800 EFI_IFR_TYPE_VALUE IfrValue;\r
801 EFI_IFR_TYPE_VALUE IfrManufactValue;\r
802 BOOLEAN StandardDefaultIsSet;\r
803 BOOLEAN ManufactDefaultIsSet;\r
804 EFI_IFR_CHECKBOX *IfrCheckBox;\r
805 EFI_STATUS Status;\r
806 EFI_IFR_DEFAULT *IfrDefault;\r
807 UINTN Width;\r
808 EFI_IFR_QUESTION_HEADER VarStoreQuestionHeader;\r
809 BOOLEAN QuestionReferBitField;\r
810\r
811 //\r
812 // If no default setting, do nothing\r
813 //\r
814 if (gNvDefaultStoreSize == 0) {\r
815 gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);\r
816 }\r
817 if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
818 return;\r
819 }\r
820\r
821 ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));\r
822 PackageLength = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
718b6fe9 823 Width = 0;\r
8ddbd227
LG
824 IfrOffset = 0;\r
825 IfrScope = 0;\r
826 IfrOpHdr = (EFI_IFR_OP_HEADER *) FormPackage->IfrData;\r
827 IfrQuestionHdr = NULL;\r
828 IfrQuestionType = 0;\r
829 EfiVarStoreMaxNum = 0;\r
830 EfiVarStoreNumber = 0;\r
831 DefaultIdMaxNum = 0;\r
832 DefaultIdNumber = 0;\r
833 EfiVarStoreList = NULL;\r
834 DefaultIdList = NULL;\r
835 StandardDefaultIsSet = FALSE;\r
836 ManufactDefaultIsSet = FALSE;\r
837 QuestionReferBitField = FALSE;\r
838\r
839 while (IfrOffset < PackageLength) {\r
840 switch (IfrOpHdr->OpCode) {\r
841 case EFI_IFR_VARSTORE_EFI_OP:\r
842 if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {\r
843 //\r
844 // Reallocate EFI VarStore Buffer\r
845 //\r
846 EfiVarStoreList = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);\r
14b351e2 847 if (EfiVarStoreList == NULL) {\r
9eefa2ec 848 goto Done;\r
14b351e2 849 }\r
8ddbd227
LG
850 EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;\r
851 }\r
852 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
853 //\r
854 // Convert VarStore Name from ASCII string to Unicode string.\r
855 //\r
856 EfiVarStoreList [EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));\r
14b351e2
LG
857 if (EfiVarStoreList [EfiVarStoreNumber] == NULL) {\r
858 break;\r
859 }\r
8ddbd227
LG
860 CopyMem (EfiVarStoreList [EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);\r
861 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *) &(EfiVarStoreList [EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
862 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);\r
863 if (!EFI_ERROR (Status)) {\r
864 EfiVarStoreNumber ++;\r
865 } else {\r
866 FreePool (EfiVarStoreList [EfiVarStoreNumber]);\r
867 EfiVarStoreList [EfiVarStoreNumber] = NULL;\r
868 }\r
869 break;\r
870 case EFI_IFR_DEFAULTSTORE_OP:\r
871 if (DefaultIdNumber >= DefaultIdMaxNum) {\r
872 //\r
873 // Reallocate DefaultIdNumber\r
874 //\r
875 DefaultIdList = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);\r
14b351e2 876 if (DefaultIdList == NULL) {\r
9eefa2ec 877 goto Done;\r
14b351e2 878 }\r
8ddbd227
LG
879 DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;\r
880 }\r
881 DefaultIdList[DefaultIdNumber ++] = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
882 break;\r
883 case EFI_IFR_FORM_OP:\r
884 case EFI_IFR_FORM_MAP_OP:\r
885 //\r
886 // No EFI varstore is found and directly return.\r
887 //\r
888 if (EfiVarStoreNumber == 0 || DefaultIdNumber == 0) {\r
889 goto Done;\r
890 }\r
891 break;\r
892 case EFI_IFR_CHECKBOX_OP:\r
893 IfrScope = IfrOpHdr->Scope;\r
894 IfrQuestionType = IfrOpHdr->OpCode;\r
895 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
896 IfrCheckBox = (EFI_IFR_CHECKBOX *) (IfrOpHdr + 1);\r
897 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
898 Width = sizeof (BOOLEAN);\r
899 if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
900 for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
901 if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
902 Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
903 if (!EFI_ERROR (Status)) {\r
904 if (IfrValue.b) {\r
905 IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;\r
906 } else {\r
907 IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);\r
908 }\r
909 }\r
910 } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
911 Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
912 if (!EFI_ERROR (Status)) {\r
913 if (IfrValue.b) {\r
914 IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;\r
915 } else {\r
916 IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);\r
917 }\r
918 }\r
919 }\r
920 }\r
921 }\r
922 break;\r
923 case EFI_IFR_NUMERIC_OP:\r
924 IfrScope = IfrOpHdr->Scope;\r
925 IfrQuestionType = IfrOpHdr->OpCode;\r
926 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
927 if (QuestionReferBitField) {\r
928 Width = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
929 } else {\r
930 Width = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
931 }\r
932 break;\r
933 case EFI_IFR_ONE_OF_OP:\r
934 IfrScope = IfrOpHdr->Scope;\r
935 IfrQuestionType = IfrOpHdr->OpCode;\r
936 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
937 if (QuestionReferBitField) {\r
938 Width = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
939 } else {\r
940 Width = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
941 }\r
942 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
943 StandardDefaultIsSet = FALSE;\r
944 ManufactDefaultIsSet = FALSE;\r
945 //\r
946 // Find Default and Manufacturing default for OneOf question\r
947 //\r
948 if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
949 for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
950 if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
951 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);\r
952 if (!EFI_ERROR (Status)) {\r
953 StandardDefaultIsSet = TRUE;\r
954 }\r
955 } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
956 Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);\r
957 if (!EFI_ERROR (Status)) {\r
958 ManufactDefaultIsSet = TRUE;\r
959 }\r
960 }\r
961 }\r
962 }\r
963 break;\r
964 case EFI_IFR_ORDERED_LIST_OP:\r
965 IfrScope = IfrOpHdr->Scope;\r
966 IfrQuestionType = IfrOpHdr->OpCode;\r
967 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
968 break;\r
969 case EFI_IFR_ONE_OF_OPTION_OP:\r
970 if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
971 IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
972 if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {\r
973 Width = (UINTN) ((UINT32) 1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));\r
974 if (StandardDefaultIsSet) {\r
975 if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {\r
976 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;\r
977 } else {\r
978 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;\r
979 }\r
980 }\r
981 if (ManufactDefaultIsSet) {\r
982 if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {\r
983 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;\r
984 } else {\r
985 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;\r
986 }\r
987 }\r
988 }\r
989 }\r
990 break;\r
991 case EFI_IFR_DEFAULT_OP:\r
992 if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
993 IfrDefault = (EFI_IFR_DEFAULT *) IfrOpHdr;\r
994 //\r
995 // Collect default value width\r
996 //\r
997 if (!QuestionReferBitField) {\r
998 Width = 0;\r
999 if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8 || IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN) {\r
1000 Width = 1;\r
1001 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
1002 Width = 2;\r
1003 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
1004 Width = 4;\r
1005 } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
1006 Width = 8;\r
1007 } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {\r
1008 Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
1009 }\r
1010 }\r
1011 //\r
1012 // Update the default value\r
1013 //\r
1014 if (Width > 0) {\r
1015 EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
1016 if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
1017 Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);\r
1018 }\r
1019 }\r
1020 }\r
1021 break;\r
1022 case EFI_IFR_END_OP:\r
1023 if (IfrQuestionHdr != NULL) {\r
1024 if (IfrScope > 0) {\r
1025 IfrScope --;\r
1026 }\r
1027 if (IfrScope == 0) {\r
1028 IfrQuestionHdr = NULL;\r
1029 QuestionReferBitField = FALSE;\r
1030 }\r
1031 }\r
1032 break;\r
1033 case EFI_IFR_GUID_OP:\r
1034 if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
1035 QuestionReferBitField = TRUE;\r
1036 }\r
1037 break;\r
1038 default:\r
1039 break;\r
1040 }\r
1041 IfrOffset = IfrOffset + IfrOpHdr->Length;\r
1042 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrOpHdr + IfrOpHdr->Length);\r
1043 if (IfrScope > 0) {\r
1044 IfrScope += IfrOpHdr->Scope;\r
1045 }\r
1046 }\r
1047\r
1048Done:\r
9eefa2ec
LG
1049 if (EfiVarStoreList != NULL) {\r
1050 for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
1051 FreePool (EfiVarStoreList [Index]);\r
1052 }\r
8ddbd227
LG
1053 }\r
1054 return;\r
1055}\r
93e3992d 1056\r
1057/**\r
1058 This function insert a Form package to a package list node.\r
e90b081a 1059 This is a internal function.\r
93e3992d 1060\r
1061 @param PackageHdr Pointer to a buffer stored with Form package\r
1062 information.\r
1063 @param NotifyType The type of change concerning the database.\r
1064 @param PackageList Pointer to a package list which will be inserted\r
1065 to.\r
1066 @param Package Created Form package\r
1067\r
1068 @retval EFI_SUCCESS Form Package is inserted successfully.\r
1069 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1070 Form package.\r
1071 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1072\r
1073**/\r
93e3992d 1074EFI_STATUS\r
1075InsertFormPackage (\r
1076 IN VOID *PackageHdr,\r
1077 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1078 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1079 OUT HII_IFR_PACKAGE_INSTANCE **Package\r
1080 )\r
1081{\r
1082 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
1083 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1084\r
1085 if (PackageHdr == NULL || PackageList == NULL) {\r
1086 return EFI_INVALID_PARAMETER;\r
1087 }\r
1088\r
1089 //\r
1090 // Get the length of the package, including package header itself\r
1091 //\r
1092 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1093\r
1094 //\r
1095 // Create a Form package node\r
1096 //\r
1097 FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));\r
1098 if (FormPackage == NULL) {\r
1099 return EFI_OUT_OF_RESOURCES;\r
1100 }\r
1101\r
1102 FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));\r
1103 if (FormPackage->IfrData == NULL) {\r
676df92c 1104 FreePool (FormPackage);\r
93e3992d 1105 return EFI_OUT_OF_RESOURCES;\r
1106 }\r
1107\r
1108 FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;\r
1109 //\r
1110 // Copy Package Header\r
1111 //\r
1112 CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
1113\r
1114 //\r
1115 // Copy Ifr contents\r
1116 //\r
1117 CopyMem (\r
1118 FormPackage->IfrData,\r
1119 (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),\r
1120 PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)\r
1121 );\r
1122\r
1123 InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);\r
1124 *Package = FormPackage;\r
1125\r
8ddbd227
LG
1126 //\r
1127 // Update FormPackage with the default setting\r
1128 //\r
1129 UpdateDefaultSettingInFormPackage (FormPackage);\r
1130\r
93e3992d 1131 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1132 PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;\r
1133 }\r
1134 return EFI_SUCCESS;\r
1135}\r
1136\r
1137\r
1138/**\r
1139 This function exports Form packages to a buffer.\r
e90b081a 1140 This is a internal function.\r
93e3992d 1141\r
1142 @param Private Hii database private structure.\r
1143 @param Handle Identification of a package list.\r
1144 @param PackageList Pointer to a package list which will be exported.\r
1145 @param UsedSize The length of buffer be used.\r
1146 @param BufferSize Length of the Buffer.\r
1147 @param Buffer Allocated space for storing exported data.\r
1148 @param ResultSize The size of the already exported content of this\r
1149 package list.\r
1150\r
1151 @retval EFI_SUCCESS Form Packages are exported successfully.\r
1152 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1153\r
1154**/\r
93e3992d 1155EFI_STATUS\r
1156ExportFormPackages (\r
1157 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1158 IN EFI_HII_HANDLE Handle,\r
1159 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1160 IN UINTN UsedSize,\r
1161 IN UINTN BufferSize,\r
1162 IN OUT VOID *Buffer,\r
1163 IN OUT UINTN *ResultSize\r
1164 )\r
1165{\r
1166 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
1167 UINTN PackageLength;\r
1168 LIST_ENTRY *Link;\r
1169 EFI_STATUS Status;\r
1170\r
1171 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1172 return EFI_INVALID_PARAMETER;\r
1173 }\r
1174\r
1175 if (BufferSize > 0 && Buffer == NULL ) {\r
1176 return EFI_INVALID_PARAMETER;\r
1177 }\r
1178\r
1179 PackageLength = 0;\r
1180 Status = EFI_SUCCESS;\r
1181\r
1182 //\r
1183 // Export Form packages.\r
1184 //\r
1185 for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {\r
1186 FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);\r
1187 PackageLength += FormPackage->FormPkgHdr.Length;\r
6e3f5b2a 1188 if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {\r
93e3992d 1189 //\r
1190 // Invoke registered notification if exists\r
1191 //\r
1192 Status = InvokeRegisteredFunction (\r
1193 Private,\r
1194 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1195 (VOID *) FormPackage,\r
8d00a0f1 1196 EFI_HII_PACKAGE_FORMS,\r
93e3992d 1197 Handle\r
1198 );\r
1199 ASSERT_EFI_ERROR (Status);\r
1200 //\r
1201 // Copy the Form package content.\r
1202 //\r
1203 CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));\r
1204 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER);\r
1205 CopyMem (\r
1206 Buffer,\r
1207 (VOID *) FormPackage->IfrData,\r
1208 FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)\r
1209 );\r
1210 Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
1211 }\r
1212 }\r
1213\r
1214 *ResultSize += PackageLength;\r
1215\r
1216 return EFI_SUCCESS;\r
1217\r
1218}\r
1219\r
1220\r
1221/**\r
1222 This function deletes all Form packages from a package list node.\r
e90b081a 1223 This is a internal function.\r
93e3992d 1224\r
1225 @param Private Hii database private data.\r
1226 @param Handle Handle of the package list which contains the to\r
1227 be removed Form packages.\r
1228 @param PackageList Pointer to a package list that contains removing\r
1229 packages.\r
1230\r
1231 @retval EFI_SUCCESS Form Package(s) is deleted successfully.\r
1232 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1233\r
1234**/\r
93e3992d 1235EFI_STATUS\r
1236RemoveFormPackages (\r
1237 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1238 IN EFI_HII_HANDLE Handle,\r
1239 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1240 )\r
1241{\r
1242 LIST_ENTRY *ListHead;\r
1243 HII_IFR_PACKAGE_INSTANCE *Package;\r
1244 EFI_STATUS Status;\r
1245\r
1246 ListHead = &PackageList->FormPkgHdr;\r
1247\r
1248 while (!IsListEmpty (ListHead)) {\r
1249 Package = CR (\r
1250 ListHead->ForwardLink,\r
1251 HII_IFR_PACKAGE_INSTANCE,\r
1252 IfrEntry,\r
1253 HII_IFR_PACKAGE_SIGNATURE\r
1254 );\r
1255 Status = InvokeRegisteredFunction (\r
1256 Private,\r
1257 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1258 (VOID *) Package,\r
8d00a0f1 1259 EFI_HII_PACKAGE_FORMS,\r
93e3992d 1260 Handle\r
1261 );\r
1262 if (EFI_ERROR (Status)) {\r
1263 return Status;\r
1264 }\r
1265\r
1266 RemoveEntryList (&Package->IfrEntry);\r
1267 PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;\r
676df92c 1268 FreePool (Package->IfrData);\r
1269 FreePool (Package);\r
c87b13cd
DB
1270 //\r
1271 // If Hii runtime support feature is enabled,\r
1272 // will export Hii info for runtime use after ReadyToBoot event triggered.\r
1273 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,\r
1274 // will need to export the content of HiiDatabase.\r
1275 // But if form packages removed, also need to export the ConfigResp string\r
1276 //\r
1277 if (gExportAfterReadyToBoot) {\r
1278 gExportConfigResp = TRUE;\r
1279 }\r
93e3992d 1280 }\r
1281\r
1282 return EFI_SUCCESS;\r
1283}\r
1284\r
1285\r
1286\r
1287/**\r
1288 This function insert a String package to a package list node.\r
e90b081a 1289 This is a internal function.\r
93e3992d 1290\r
1291 @param Private Hii database private structure.\r
1292 @param PackageHdr Pointer to a buffer stored with String package\r
1293 information.\r
1294 @param NotifyType The type of change concerning the database.\r
1295 @param PackageList Pointer to a package list which will be inserted\r
1296 to.\r
1297 @param Package Created String package\r
1298\r
1299 @retval EFI_SUCCESS String Package is inserted successfully.\r
1300 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1301 String package.\r
1302 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1303 @retval EFI_UNSUPPORTED A string package with the same language already\r
1304 exists in current package list.\r
1305\r
1306**/\r
93e3992d 1307EFI_STATUS\r
1308InsertStringPackage (\r
1309 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1310 IN VOID *PackageHdr,\r
1311 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1312 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1313 OUT HII_STRING_PACKAGE_INSTANCE **Package\r
93e3992d 1314 )\r
1315{\r
1316 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1317 UINT32 HeaderSize;\r
1318 EFI_STATUS Status;\r
1319 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1320 CHAR8 *Language;\r
1321 UINT32 LanguageSize;\r
1322 LIST_ENTRY *Link;\r
1323\r
1324 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
1325 return EFI_INVALID_PARAMETER;\r
1326 }\r
1327 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
1328 return EFI_INVALID_PARAMETER;\r
1329 }\r
1330\r
1331 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1332 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
1333\r
1334 //\r
1335 // It is illegal to have two string packages with same language within one packagelist\r
1336 // since the stringid will be duplicate if so. Check it to avoid this potential issue.\r
1337 //\r
1338 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);\r
1339 Language = (CHAR8 *) AllocateZeroPool (LanguageSize);\r
1340 if (Language == NULL) {\r
1341 return EFI_OUT_OF_RESOURCES;\r
1342 }\r
5ad66ec6 1343 AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
93e3992d 1344 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
1345 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
f324bf4d 1346 if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
676df92c 1347 FreePool (Language);\r
93e3992d 1348 return EFI_UNSUPPORTED;\r
1349 }\r
1350 }\r
676df92c 1351 FreePool (Language);\r
93e3992d 1352\r
1353 //\r
1354 // Create a String package node\r
1355 //\r
1356 StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));\r
1357 if (StringPackage == NULL) {\r
1358 Status = EFI_OUT_OF_RESOURCES;\r
1359 goto Error;\r
1360 }\r
1361\r
1362 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
1363 if (StringPackage->StringPkgHdr == NULL) {\r
1364 Status = EFI_OUT_OF_RESOURCES;\r
1365 goto Error;\r
1366 }\r
1367\r
1368 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
1369 if (StringPackage->StringBlock == NULL) {\r
1370 Status = EFI_OUT_OF_RESOURCES;\r
1371 goto Error;\r
1372 }\r
1373\r
1374 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;\r
1375 StringPackage->FontId = 0;\r
1376 InitializeListHead (&StringPackage->FontInfoList);\r
1377\r
1378 //\r
1379 // Copy the String package header.\r
1380 //\r
1381 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);\r
1382\r
1383 //\r
1384 // Copy the String blocks\r
1385 //\r
1386 CopyMem (\r
1387 StringPackage->StringBlock,\r
1388 (UINT8 *) PackageHdr + HeaderSize,\r
1389 PackageHeader.Length - HeaderSize\r
1390 );\r
1391\r
1392 //\r
1393 // Collect all font block info\r
1394 //\r
e5c861ac 1395 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL);\r
93e3992d 1396 if (EFI_ERROR (Status)) {\r
1397 return Status;\r
1398 }\r
1399\r
1400 //\r
1401 // Insert to String package array\r
1402 //\r
1403 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);\r
1404 *Package = StringPackage;\r
1405\r
1406 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1407 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
1408 }\r
1409\r
1410 return EFI_SUCCESS;\r
1411\r
1412Error:\r
1413\r
676df92c 1414 if (StringPackage != NULL) {\r
c59634ea 1415 if (StringPackage->StringBlock != NULL) {\r
1416 FreePool (StringPackage->StringBlock);\r
1417 }\r
1418 if (StringPackage->StringPkgHdr != NULL) {\r
1419 FreePool (StringPackage->StringPkgHdr);\r
1420 }\r
676df92c 1421 FreePool (StringPackage);\r
1422 }\r
93e3992d 1423 return Status;\r
1424\r
1425}\r
1426\r
6ddd3af7
LG
1427/**\r
1428 Adjust all string packages in a single package list to have the same max string ID.\r
1429 \r
1430 @param PackageList Pointer to a package list which will be adjusted.\r
1431\r
1432 @retval EFI_SUCCESS Adjust all string packages successfully.\r
4a429716 1433 @retval others Can't adjust string packages.\r
6ddd3af7
LG
1434\r
1435**/\r
1436EFI_STATUS\r
1437AdjustStringPackage (\r
1438 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1439)\r
1440{\r
1441 LIST_ENTRY *Link;\r
1442 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1443 UINT32 Skip2BlockSize;\r
1444 UINT32 OldBlockSize;\r
1445 UINT8 *StringBlock;\r
1446 UINT8 *BlockPtr;\r
1447 EFI_STRING_ID MaxStringId;\r
1448 UINT16 SkipCount;\r
1449\r
1450 MaxStringId = 0;\r
1451 for (Link = PackageList->StringPkgHdr.ForwardLink;\r
1452 Link != &PackageList->StringPkgHdr;\r
1453 Link = Link->ForwardLink\r
1454 ) {\r
1455 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1456 if (MaxStringId < StringPackage->MaxStringId) {\r
1457 MaxStringId = StringPackage->MaxStringId;\r
1458 }\r
1459 }\r
1460\r
1461 for (Link = PackageList->StringPkgHdr.ForwardLink;\r
1462 Link != &PackageList->StringPkgHdr;\r
1463 Link = Link->ForwardLink\r
1464 ) {\r
1465 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1466 if (StringPackage->MaxStringId < MaxStringId) {\r
1467 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1468 //\r
1469 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.\r
1470 //\r
1471 SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId);\r
1472 Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
1473\r
1474 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize);\r
1475 if (StringBlock == NULL) {\r
1476 return EFI_OUT_OF_RESOURCES;\r
1477 }\r
1478 //\r
1479 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
1480 //\r
1481 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
1482 //\r
1483 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks\r
1484 //\r
1485 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
1486 *BlockPtr = EFI_HII_SIBT_SKIP2;\r
1487 CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));\r
1488 BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
1489\r
1490 //\r
1491 // Append a EFI_HII_SIBT_END block to the end.\r
1492 //\r
1493 *BlockPtr = EFI_HII_SIBT_END;\r
1494 FreePool (StringPackage->StringBlock);\r
1495 StringPackage->StringBlock = StringBlock;\r
1496 StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;\r
1497 PackageList->PackageListHdr.PackageLength += Skip2BlockSize;\r
1498 StringPackage->MaxStringId = MaxStringId;\r
1499 }\r
1500 }\r
1501\r
1502 return EFI_SUCCESS;\r
1503}\r
93e3992d 1504\r
1505/**\r
1506 This function exports String packages to a buffer.\r
e90b081a 1507 This is a internal function.\r
93e3992d 1508\r
1509 @param Private Hii database private structure.\r
1510 @param Handle Identification of a package list.\r
1511 @param PackageList Pointer to a package list which will be exported.\r
1512 @param UsedSize The length of buffer be used.\r
1513 @param BufferSize Length of the Buffer.\r
1514 @param Buffer Allocated space for storing exported data.\r
1515 @param ResultSize The size of the already exported content of this\r
1516 package list.\r
1517\r
1518 @retval EFI_SUCCESS String Packages are exported successfully.\r
1519 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1520\r
1521**/\r
93e3992d 1522EFI_STATUS\r
1523ExportStringPackages (\r
1524 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1525 IN EFI_HII_HANDLE Handle,\r
1526 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1527 IN UINTN UsedSize,\r
1528 IN UINTN BufferSize,\r
1529 IN OUT VOID *Buffer,\r
1530 IN OUT UINTN *ResultSize\r
1531 )\r
1532{\r
1533 LIST_ENTRY *Link;\r
1534 UINTN PackageLength;\r
1535 EFI_STATUS Status;\r
1536 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1537\r
1538 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1539 return EFI_INVALID_PARAMETER;\r
1540 }\r
1541\r
1542 if (BufferSize > 0 && Buffer == NULL ) {\r
1543 return EFI_INVALID_PARAMETER;\r
1544 }\r
1545\r
1546 PackageLength = 0;\r
1547 Status = EFI_SUCCESS;\r
1548\r
1549 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
1550 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1551 PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
1552 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1553 //\r
1554 // Invoke registered notification function with EXPORT_PACK notify type\r
1555 //\r
1556 Status = InvokeRegisteredFunction (\r
1557 Private,\r
1558 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1559 (VOID *) StringPackage,\r
1560 EFI_HII_PACKAGE_STRINGS,\r
1561 Handle\r
1562 );\r
1563 ASSERT_EFI_ERROR (Status);\r
1564 //\r
1565 // Copy String package header\r
1566 //\r
1567 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);\r
1568 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;\r
1569\r
1570 //\r
1571 // Copy String blocks information\r
1572 //\r
1573 CopyMem (\r
1574 Buffer,\r
1575 StringPackage->StringBlock,\r
1576 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize\r
1577 );\r
1578 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1579 }\r
1580 }\r
1581\r
1582 *ResultSize += PackageLength;\r
1583 return EFI_SUCCESS;\r
1584}\r
1585\r
1586\r
1587/**\r
1588 This function deletes all String packages from a package list node.\r
e90b081a 1589 This is a internal function.\r
93e3992d 1590\r
1591 @param Private Hii database private data.\r
1592 @param Handle Handle of the package list which contains the to\r
1593 be removed String packages.\r
1594 @param PackageList Pointer to a package list that contains removing\r
1595 packages.\r
1596\r
1597 @retval EFI_SUCCESS String Package(s) is deleted successfully.\r
1598 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1599\r
1600**/\r
93e3992d 1601EFI_STATUS\r
1602RemoveStringPackages (\r
1603 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1604 IN EFI_HII_HANDLE Handle,\r
1605 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1606 )\r
1607{\r
1608 LIST_ENTRY *ListHead;\r
1609 HII_STRING_PACKAGE_INSTANCE *Package;\r
1610 HII_FONT_INFO *FontInfo;\r
1611 EFI_STATUS Status;\r
1612\r
1613 ListHead = &PackageList->StringPkgHdr;\r
1614\r
1615 while (!IsListEmpty (ListHead)) {\r
1616 Package = CR (\r
1617 ListHead->ForwardLink,\r
1618 HII_STRING_PACKAGE_INSTANCE,\r
1619 StringEntry,\r
1620 HII_STRING_PACKAGE_SIGNATURE\r
1621 );\r
1622 Status = InvokeRegisteredFunction (\r
1623 Private,\r
1624 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1625 (VOID *) Package,\r
1626 EFI_HII_PACKAGE_STRINGS,\r
1627 Handle\r
1628 );\r
1629 if (EFI_ERROR (Status)) {\r
1630 return Status;\r
1631 }\r
1632\r
1633 RemoveEntryList (&Package->StringEntry);\r
1634 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;\r
676df92c 1635 FreePool (Package->StringBlock);\r
1636 FreePool (Package->StringPkgHdr);\r
93e3992d 1637 //\r
1638 // Delete font information\r
1639 //\r
1640 while (!IsListEmpty (&Package->FontInfoList)) {\r
1641 FontInfo = CR (\r
1642 Package->FontInfoList.ForwardLink,\r
1643 HII_FONT_INFO,\r
1644 Entry,\r
1645 HII_FONT_INFO_SIGNATURE\r
1646 );\r
1647 RemoveEntryList (&FontInfo->Entry);\r
676df92c 1648 FreePool (FontInfo);\r
93e3992d 1649 }\r
1650\r
676df92c 1651 FreePool (Package);\r
93e3992d 1652 }\r
1653\r
1654 return EFI_SUCCESS;\r
1655}\r
1656\r
1657\r
1658/**\r
1659 This function insert a Font package to a package list node.\r
e90b081a 1660 This is a internal function.\r
93e3992d 1661\r
1662 @param Private Hii database private structure.\r
1663 @param PackageHdr Pointer to a buffer stored with Font package\r
1664 information.\r
1665 @param NotifyType The type of change concerning the database.\r
1666 @param PackageList Pointer to a package list which will be inserted\r
1667 to.\r
1668 @param Package Created Font package\r
1669\r
1670 @retval EFI_SUCCESS Font Package is inserted successfully.\r
1671 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1672 Font package.\r
1673 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1674 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already\r
1675 exists in current hii database.\r
1676\r
1677**/\r
93e3992d 1678EFI_STATUS\r
1679InsertFontPackage (\r
1680 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1681 IN VOID *PackageHdr,\r
1682 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
1683 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1684 OUT HII_FONT_PACKAGE_INSTANCE **Package\r
1685 )\r
1686{\r
1687 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
1688 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;\r
1689 UINT32 HeaderSize;\r
1690 EFI_STATUS Status;\r
1691 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1692 EFI_FONT_INFO *FontInfo;\r
1693 UINT32 FontInfoSize;\r
1694 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1695\r
1696 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {\r
1697 return EFI_INVALID_PARAMETER;\r
1698 }\r
1699\r
1700 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
1701 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));\r
1702\r
1703 FontInfo = NULL;\r
1704 FontPackage = NULL;\r
1705 GlobalFont = NULL;\r
1706\r
1707 //\r
1708 // It is illegal to have two font packages with same EFI_FONT_INFO within hii\r
1709 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's\r
1710 // attributes and identify a font uniquely.\r
1711 //\r
1712 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);\r
1713 if (FontPkgHdr == NULL) {\r
1714 Status = EFI_OUT_OF_RESOURCES;\r
1715 goto Error;\r
1716 }\r
1717 CopyMem (FontPkgHdr, PackageHdr, HeaderSize);\r
1718\r
1719 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);\r
1720 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);\r
1721 if (FontInfo == NULL) {\r
1722 Status = EFI_OUT_OF_RESOURCES;\r
1723 goto Error;\r
1724 }\r
1725 FontInfo->FontStyle = FontPkgHdr->FontStyle;\r
1726 FontInfo->FontSize = FontPkgHdr->Cell.Height;\r
4d5b0868 1727 StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily);\r
93e3992d 1728\r
1729 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {\r
1730 Status = EFI_UNSUPPORTED;\r
1731 goto Error;\r
1732 }\r
1733\r
1734 //\r
1735 // Create a Font package node\r
1736 //\r
1737 FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));\r
1738 if (FontPackage == NULL) {\r
1739 Status = EFI_OUT_OF_RESOURCES;\r
1740 goto Error;\r
1741 }\r
1742 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;\r
1743 FontPackage->FontPkgHdr = FontPkgHdr;\r
1744 InitializeListHead (&FontPackage->GlyphInfoList);\r
1745\r
1746 FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);\r
1747 if (FontPackage->GlyphBlock == NULL) {\r
1748 Status = EFI_OUT_OF_RESOURCES;\r
1749 goto Error;\r
1750 }\r
1751 CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);\r
1752\r
1753 //\r
1754 // Collect all default character cell information and backup in GlyphInfoList.\r
1755 //\r
1756 Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);\r
1757 if (EFI_ERROR (Status)) {\r
1758 goto Error;\r
1759 }\r
1760\r
1761 //\r
1762 // This font package describes an unique EFI_FONT_INFO. Backup it in global\r
1763 // font info list.\r
1764 //\r
1765 GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));\r
1766 if (GlobalFont == NULL) {\r
1767 Status = EFI_OUT_OF_RESOURCES;\r
1768 goto Error;\r
1769 }\r
1770 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;\r
1771 GlobalFont->FontPackage = FontPackage;\r
1772 GlobalFont->FontInfoSize = FontInfoSize;\r
1773 GlobalFont->FontInfo = FontInfo;\r
1774 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);\r
1775\r
1776 //\r
1777 // Insert this font package to Font package array\r
1778 //\r
1779 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);\r
1780 *Package = FontPackage;\r
1781\r
1782 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
1783 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;\r
1784 }\r
1785\r
1786 return EFI_SUCCESS;\r
1787\r
1788Error:\r
1789\r
676df92c 1790 if (FontPkgHdr != NULL) {\r
1791 FreePool (FontPkgHdr);\r
1792 }\r
1793 if (FontInfo != NULL) {\r
1794 FreePool (FontInfo);\r
1795 }\r
676df92c 1796 if (FontPackage != NULL) {\r
c59634ea 1797 if (FontPackage->GlyphBlock != NULL) {\r
1798 FreePool (FontPackage->GlyphBlock);\r
1799 }\r
676df92c 1800 FreePool (FontPackage);\r
1801 }\r
1802 if (GlobalFont != NULL) {\r
1803 FreePool (GlobalFont);\r
1804 }\r
93e3992d 1805\r
1806 return Status;\r
1807\r
1808}\r
1809\r
1810\r
1811/**\r
1812 This function exports Font packages to a buffer.\r
e90b081a 1813 This is a internal function.\r
93e3992d 1814\r
1815 @param Private Hii database private structure.\r
1816 @param Handle Identification of a package list.\r
1817 @param PackageList Pointer to a package list which will be exported.\r
1818 @param UsedSize The length of buffer be used.\r
1819 @param BufferSize Length of the Buffer.\r
1820 @param Buffer Allocated space for storing exported data.\r
1821 @param ResultSize The size of the already exported content of this\r
1822 package list.\r
1823\r
1824 @retval EFI_SUCCESS Font Packages are exported successfully.\r
1825 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1826\r
1827**/\r
93e3992d 1828EFI_STATUS\r
1829ExportFontPackages (\r
1830 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1831 IN EFI_HII_HANDLE Handle,\r
1832 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
1833 IN UINTN UsedSize,\r
1834 IN UINTN BufferSize,\r
1835 IN OUT VOID *Buffer,\r
1836 IN OUT UINTN *ResultSize\r
1837 )\r
1838{\r
1839 LIST_ENTRY *Link;\r
1840 UINTN PackageLength;\r
1841 EFI_STATUS Status;\r
1842 HII_FONT_PACKAGE_INSTANCE *Package;\r
1843\r
1844\r
1845 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
1846 return EFI_INVALID_PARAMETER;\r
1847 }\r
1848\r
1849 if (BufferSize > 0 && Buffer == NULL ) {\r
1850 return EFI_INVALID_PARAMETER;\r
1851 }\r
1852\r
1853 PackageLength = 0;\r
1854 Status = EFI_SUCCESS;\r
1855\r
1856 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {\r
1857 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);\r
1858 PackageLength += Package->FontPkgHdr->Header.Length;\r
1859 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
1860 //\r
1861 // Invoke registered notification function with EXPORT_PACK notify type\r
1862 //\r
1863 Status = InvokeRegisteredFunction (\r
1864 Private,\r
1865 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
1866 (VOID *) Package,\r
1867 EFI_HII_PACKAGE_FONTS,\r
1868 Handle\r
1869 );\r
1870 ASSERT_EFI_ERROR (Status);\r
1871 //\r
1872 // Copy Font package header\r
1873 //\r
1874 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);\r
1875 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;\r
1876\r
1877 //\r
1878 // Copy Glyph blocks information\r
1879 //\r
1880 CopyMem (\r
1881 Buffer,\r
1882 Package->GlyphBlock,\r
1883 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize\r
1884 );\r
1885 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;\r
1886 }\r
1887 }\r
1888\r
1889 *ResultSize += PackageLength;\r
1890 return EFI_SUCCESS;\r
1891}\r
1892\r
1893\r
1894/**\r
1895 This function deletes all Font packages from a package list node.\r
e90b081a 1896 This is a internal function.\r
93e3992d 1897\r
1898 @param Private Hii database private data.\r
1899 @param Handle Handle of the package list which contains the to\r
1900 be removed Font packages.\r
1901 @param PackageList Pointer to a package list that contains removing\r
1902 packages.\r
1903\r
1904 @retval EFI_SUCCESS Font Package(s) is deleted successfully.\r
1905 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
1906\r
1907**/\r
93e3992d 1908EFI_STATUS\r
1909RemoveFontPackages (\r
1910 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1911 IN EFI_HII_HANDLE Handle,\r
1912 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
1913 )\r
1914{\r
1915 LIST_ENTRY *ListHead;\r
1916 HII_FONT_PACKAGE_INSTANCE *Package;\r
1917 EFI_STATUS Status;\r
1918 HII_GLYPH_INFO *GlyphInfo;\r
1919 LIST_ENTRY *Link;\r
1920 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1921\r
1922 ListHead = &PackageList->FontPkgHdr;\r
1923\r
1924 while (!IsListEmpty (ListHead)) {\r
1925 Package = CR (\r
1926 ListHead->ForwardLink,\r
1927 HII_FONT_PACKAGE_INSTANCE,\r
1928 FontEntry,\r
1929 HII_FONT_PACKAGE_SIGNATURE\r
1930 );\r
1931 Status = InvokeRegisteredFunction (\r
1932 Private,\r
1933 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
1934 (VOID *) Package,\r
1935 EFI_HII_PACKAGE_FONTS,\r
1936 Handle\r
1937 );\r
1938 if (EFI_ERROR (Status)) {\r
1939 return Status;\r
1940 }\r
1941\r
1942 RemoveEntryList (&Package->FontEntry);\r
1943 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;\r
676df92c 1944\r
1945 if (Package->GlyphBlock != NULL) {\r
1946 FreePool (Package->GlyphBlock);\r
1947 }\r
1948 FreePool (Package->FontPkgHdr);\r
93e3992d 1949 //\r
1950 // Delete default character cell information\r
1951 //\r
1952 while (!IsListEmpty (&Package->GlyphInfoList)) {\r
1953 GlyphInfo = CR (\r
1954 Package->GlyphInfoList.ForwardLink,\r
1955 HII_GLYPH_INFO,\r
1956 Entry,\r
1957 HII_GLYPH_INFO_SIGNATURE\r
1958 );\r
1959 RemoveEntryList (&GlyphInfo->Entry);\r
676df92c 1960 FreePool (GlyphInfo);\r
93e3992d 1961 }\r
1962\r
1963 //\r
1964 // Remove corresponding global font info\r
1965 //\r
1966 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
1967 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1968 if (GlobalFont->FontPackage == Package) {\r
1969 RemoveEntryList (&GlobalFont->Entry);\r
676df92c 1970 FreePool (GlobalFont->FontInfo);\r
1971 FreePool (GlobalFont);\r
93e3992d 1972 break;\r
1973 }\r
1974 }\r
1975\r
676df92c 1976 FreePool (Package);\r
93e3992d 1977 }\r
1978\r
1979 return EFI_SUCCESS;\r
1980}\r
1981\r
1982\r
1983/**\r
1984 This function insert a Image package to a package list node.\r
e90b081a 1985 This is a internal function.\r
93e3992d 1986\r
1987 @param PackageHdr Pointer to a buffer stored with Image package\r
1988 information.\r
1989 @param NotifyType The type of change concerning the database.\r
1990 @param PackageList Pointer to a package list which will be inserted\r
1991 to.\r
1992 @param Package Created Image package\r
1993\r
1994 @retval EFI_SUCCESS Image Package is inserted successfully.\r
1995 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
1996 Image package.\r
1997 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
1998\r
1999**/\r
93e3992d 2000EFI_STATUS\r
2001InsertImagePackage (\r
2002 IN VOID *PackageHdr,\r
2003 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2004 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2005 OUT HII_IMAGE_PACKAGE_INSTANCE **Package\r
2006 )\r
2007{\r
2008 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
2009 UINT32 PaletteSize;\r
2010 UINT32 ImageSize;\r
2011 UINT16 Index;\r
2012 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;\r
2013 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;\r
2014 UINT32 PaletteInfoOffset;\r
2015 UINT32 ImageInfoOffset;\r
2016 UINT16 CurrentSize;\r
2017\r
2018 if (PackageHdr == NULL || PackageList == NULL) {\r
2019 return EFI_INVALID_PARAMETER;\r
2020 }\r
2021\r
2022 //\r
2023 // Less than one image package is allowed in one package list.\r
2024 //\r
2025 if (PackageList->ImagePkg != NULL) {\r
2026 return EFI_INVALID_PARAMETER;\r
2027 }\r
2028\r
2029 //\r
2030 // Create a Image package node\r
2031 //\r
2032 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));\r
2033 if (ImagePackage == NULL) {\r
2034 return EFI_OUT_OF_RESOURCES;\r
2035 }\r
2036\r
2037 //\r
2038 // Copy the Image package header.\r
2039 //\r
2040 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
2041\r
2042 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;\r
2043 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;\r
2044\r
2045 //\r
2046 // If PaletteInfoOffset is zero, there are no palettes in this image package.\r
2047 //\r
2048 PaletteSize = 0;\r
2049 ImagePackage->PaletteBlock = NULL;\r
2050 if (PaletteInfoOffset != 0) {\r
2051 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);\r
2052 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);\r
2053 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);\r
2054\r
2055 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {\r
2056 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));\r
2057 CurrentSize += sizeof (UINT16);\r
2058 PaletteSize += (UINT32) CurrentSize;\r
2059 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);\r
2060 }\r
2061\r
2062 ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);\r
2063 if (ImagePackage->PaletteBlock == NULL) {\r
676df92c 2064 FreePool (ImagePackage);\r
93e3992d 2065 return EFI_OUT_OF_RESOURCES;\r
2066 }\r
2067 CopyMem (\r
2068 ImagePackage->PaletteBlock,\r
2069 (UINT8 *) PackageHdr + PaletteInfoOffset,\r
2070 PaletteSize\r
2071 );\r
2072 }\r
2073\r
2074 //\r
2075 // If ImageInfoOffset is zero, there are no images in this package.\r
2076 //\r
2077 ImageSize = 0;\r
2078 ImagePackage->ImageBlock = NULL;\r
2079 if (ImageInfoOffset != 0) {\r
2080 ImageSize = ImagePackage->ImagePkgHdr.Header.Length -\r
2081 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;\r
7c28fcb8 2082 ImagePackage->ImageBlock = AllocateZeroPool (ImageSize);\r
93e3992d 2083 if (ImagePackage->ImageBlock == NULL) {\r
676df92c 2084 FreePool (ImagePackage->PaletteBlock);\r
2085 FreePool (ImagePackage);\r
93e3992d 2086 return EFI_OUT_OF_RESOURCES;\r
2087 }\r
2088 CopyMem (\r
2089 ImagePackage->ImageBlock,\r
2090 (UINT8 *) PackageHdr + ImageInfoOffset,\r
2091 ImageSize\r
2092 );\r
2093 }\r
2094\r
2095 ImagePackage->ImageBlockSize = ImageSize;\r
2096 ImagePackage->PaletteInfoSize = PaletteSize;\r
2097 PackageList->ImagePkg = ImagePackage;\r
2098 *Package = ImagePackage;\r
2099\r
2100 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2101 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;\r
2102 }\r
2103\r
2104 return EFI_SUCCESS;\r
2105}\r
2106\r
2107\r
2108/**\r
2109 This function exports Image packages to a buffer.\r
e90b081a 2110 This is a internal function.\r
93e3992d 2111\r
2112 @param Private Hii database private structure.\r
2113 @param Handle Identification of a package list.\r
2114 @param PackageList Pointer to a package list which will be exported.\r
2115 @param UsedSize The length of buffer be used.\r
2116 @param BufferSize Length of the Buffer.\r
2117 @param Buffer Allocated space for storing exported data.\r
2118 @param ResultSize The size of the already exported content of this\r
2119 package list.\r
2120\r
2121 @retval EFI_SUCCESS Image Packages are exported successfully.\r
2122 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2123\r
2124**/\r
93e3992d 2125EFI_STATUS\r
2126ExportImagePackages (\r
2127 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2128 IN EFI_HII_HANDLE Handle,\r
2129 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2130 IN UINTN UsedSize,\r
2131 IN UINTN BufferSize,\r
2132 IN OUT VOID *Buffer,\r
2133 IN OUT UINTN *ResultSize\r
2134 )\r
2135{\r
2136 UINTN PackageLength;\r
2137 EFI_STATUS Status;\r
2138 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
2139\r
2140\r
2141 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2142 return EFI_INVALID_PARAMETER;\r
2143 }\r
2144\r
2145 if (BufferSize > 0 && Buffer == NULL ) {\r
2146 return EFI_INVALID_PARAMETER;\r
2147 }\r
2148\r
2149 Package = PackageList->ImagePkg;\r
2150\r
2151 if (Package == NULL) {\r
2152 return EFI_SUCCESS;\r
2153 }\r
2154\r
2155 PackageLength = Package->ImagePkgHdr.Header.Length;\r
2156\r
2157 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
2158 //\r
2159 // Invoke registered notification function with EXPORT_PACK notify type\r
2160 //\r
2161 Status = InvokeRegisteredFunction (\r
2162 Private,\r
2163 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2164 (VOID *) Package,\r
2165 EFI_HII_PACKAGE_IMAGES,\r
2166 Handle\r
2167 );\r
2168 ASSERT_EFI_ERROR (Status);\r
2169 ASSERT (Package->ImagePkgHdr.Header.Length ==\r
2170 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);\r
2171 //\r
2172 // Copy Image package header,\r
2173 // then justify the offset for image info and palette info in the header.\r
2174 //\r
2175 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));\r
2176 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
2177\r
2178 //\r
2179 // Copy Image blocks information\r
2180 //\r
2181 if (Package->ImageBlockSize != 0) {\r
2182 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);\r
2183 Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;\r
2184 }\r
2185 //\r
2186 // Copy Palette information\r
2187 //\r
2188 if (Package->PaletteInfoSize != 0) {\r
2189 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);\r
2190 Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;\r
2191 }\r
2192 }\r
2193\r
2194 *ResultSize += PackageLength;\r
2195 return EFI_SUCCESS;\r
2196}\r
2197\r
2198\r
2199/**\r
2200 This function deletes Image package from a package list node.\r
e90b081a 2201 This is a internal function.\r
93e3992d 2202\r
2203 @param Private Hii database private data.\r
2204 @param Handle Handle of the package list which contains the to\r
2205 be removed Image packages.\r
2206 @param PackageList Package List which contains the to be removed\r
2207 Image package.\r
2208\r
2209 @retval EFI_SUCCESS Image Package(s) is deleted successfully.\r
2210 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2211\r
2212**/\r
93e3992d 2213EFI_STATUS\r
2214RemoveImagePackages (\r
2215 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2216 IN EFI_HII_HANDLE Handle,\r
2217 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2218 )\r
2219{\r
2220 HII_IMAGE_PACKAGE_INSTANCE *Package;\r
2221 EFI_STATUS Status;\r
2222\r
2223 Package = PackageList->ImagePkg;\r
2224\r
2225 //\r
2226 // Image package does not exist, return directly.\r
2227 //\r
2228 if (Package == NULL) {\r
2229 return EFI_SUCCESS;\r
2230 }\r
2231\r
2232 Status = InvokeRegisteredFunction (\r
2233 Private,\r
2234 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2235 (VOID *) Package,\r
2236 EFI_HII_PACKAGE_IMAGES,\r
2237 Handle\r
2238 );\r
2239 if (EFI_ERROR (Status)) {\r
2240 return Status;\r
2241 }\r
2242\r
2243 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;\r
2244\r
676df92c 2245 FreePool (Package->ImageBlock);\r
2246 if (Package->PaletteBlock != NULL) {\r
2247 FreePool (Package->PaletteBlock);\r
2248 }\r
2249 FreePool (Package);\r
93e3992d 2250\r
2251 PackageList->ImagePkg = NULL;\r
2252\r
2253 return EFI_SUCCESS;\r
2254}\r
2255\r
2256\r
2257/**\r
2258 This function insert a Simple Font package to a package list node.\r
e90b081a 2259 This is a internal function.\r
93e3992d 2260\r
2261 @param PackageHdr Pointer to a buffer stored with Simple Font\r
2262 package information.\r
2263 @param NotifyType The type of change concerning the database.\r
2264 @param PackageList Pointer to a package list which will be inserted\r
2265 to.\r
2266 @param Package Created Simple Font package\r
2267\r
2268 @retval EFI_SUCCESS Simple Font Package is inserted successfully.\r
2269 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2270 Simple Font package.\r
2271 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
2272\r
2273**/\r
93e3992d 2274EFI_STATUS\r
2275InsertSimpleFontPackage (\r
2276 IN VOID *PackageHdr,\r
2277 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2278 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2279 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package\r
2280 )\r
2281{\r
2282 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
2283 EFI_STATUS Status;\r
2284 EFI_HII_PACKAGE_HEADER Header;\r
2285\r
2286 if (PackageHdr == NULL || PackageList == NULL) {\r
2287 return EFI_INVALID_PARAMETER;\r
2288 }\r
2289\r
2290 //\r
2291 // Create a Simple Font package node\r
2292 //\r
2293 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));\r
2294 if (SimpleFontPackage == NULL) {\r
2295 Status = EFI_OUT_OF_RESOURCES;\r
2296 goto Error;\r
2297 }\r
2298 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;\r
2299\r
2300 //\r
2301 // Copy the Simple Font package.\r
2302 //\r
2303 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2304\r
2305 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);\r
2306 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {\r
2307 Status = EFI_OUT_OF_RESOURCES;\r
2308 goto Error;\r
2309 }\r
2310\r
2311 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);\r
2312\r
2313 //\r
2314 // Insert to Simple Font package array\r
2315 //\r
2316 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);\r
2317 *Package = SimpleFontPackage;\r
2318\r
2319 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2320 PackageList->PackageListHdr.PackageLength += Header.Length;\r
2321 }\r
2322\r
2323 return EFI_SUCCESS;\r
2324\r
2325Error:\r
2326\r
676df92c 2327 if (SimpleFontPackage != NULL) {\r
c59634ea 2328 if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {\r
2329 FreePool (SimpleFontPackage->SimpleFontPkgHdr);\r
2330 }\r
676df92c 2331 FreePool (SimpleFontPackage);\r
2332 }\r
93e3992d 2333 return Status;\r
2334}\r
2335\r
2336\r
2337/**\r
2338 This function exports SimpleFont packages to a buffer.\r
e90b081a 2339 This is a internal function.\r
93e3992d 2340\r
2341 @param Private Hii database private structure.\r
2342 @param Handle Identification of a package list.\r
2343 @param PackageList Pointer to a package list which will be exported.\r
2344 @param UsedSize The length of buffer be used.\r
2345 @param BufferSize Length of the Buffer.\r
2346 @param Buffer Allocated space for storing exported data.\r
2347 @param ResultSize The size of the already exported content of this\r
2348 package list.\r
2349\r
2350 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.\r
2351 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2352\r
2353**/\r
93e3992d 2354EFI_STATUS\r
2355ExportSimpleFontPackages (\r
2356 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2357 IN EFI_HII_HANDLE Handle,\r
2358 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2359 IN UINTN UsedSize,\r
2360 IN UINTN BufferSize,\r
2361 IN OUT VOID *Buffer,\r
2362 IN OUT UINTN *ResultSize\r
2363 )\r
2364{\r
2365 LIST_ENTRY *Link;\r
2366 UINTN PackageLength;\r
2367 EFI_STATUS Status;\r
2368 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
2369\r
2370 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2371 return EFI_INVALID_PARAMETER;\r
2372 }\r
2373\r
2374 if (BufferSize > 0 && Buffer == NULL ) {\r
2375 return EFI_INVALID_PARAMETER;\r
2376 }\r
2377\r
2378 PackageLength = 0;\r
2379 Status = EFI_SUCCESS;\r
2380\r
2381 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {\r
2382 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);\r
2383 PackageLength += Package->SimpleFontPkgHdr->Header.Length;\r
2384 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
2385 //\r
2386 // Invoke registered notification function with EXPORT_PACK notify type\r
2387 //\r
2388 Status = InvokeRegisteredFunction (\r
2389 Private,\r
2390 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2391 (VOID *) Package,\r
2392 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
2393 Handle\r
2394 );\r
2395 ASSERT_EFI_ERROR (Status);\r
2396\r
2397 //\r
2398 // Copy SimpleFont package\r
2399 //\r
2400 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);\r
2401 Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;\r
2402 }\r
2403 }\r
2404\r
2405 *ResultSize += PackageLength;\r
2406 return EFI_SUCCESS;\r
2407}\r
2408\r
2409\r
2410/**\r
2411 This function deletes all Simple Font packages from a package list node.\r
e90b081a 2412 This is a internal function.\r
93e3992d 2413\r
2414 @param Private Hii database private data.\r
2415 @param Handle Handle of the package list which contains the to\r
2416 be removed Simple Font packages.\r
2417 @param PackageList Pointer to a package list that contains removing\r
2418 packages.\r
2419\r
2420 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.\r
2421 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2422\r
2423**/\r
93e3992d 2424EFI_STATUS\r
2425RemoveSimpleFontPackages (\r
2426 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2427 IN EFI_HII_HANDLE Handle,\r
2428 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2429 )\r
2430{\r
2431 LIST_ENTRY *ListHead;\r
2432 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;\r
2433 EFI_STATUS Status;\r
2434\r
2435 ListHead = &PackageList->SimpleFontPkgHdr;\r
2436\r
2437 while (!IsListEmpty (ListHead)) {\r
2438 Package = CR (\r
2439 ListHead->ForwardLink,\r
2440 HII_SIMPLE_FONT_PACKAGE_INSTANCE,\r
2441 SimpleFontEntry,\r
2442 HII_S_FONT_PACKAGE_SIGNATURE\r
2443 );\r
2444 Status = InvokeRegisteredFunction (\r
2445 Private,\r
2446 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2447 (VOID *) Package,\r
2448 EFI_HII_PACKAGE_SIMPLE_FONTS,\r
2449 Handle\r
2450 );\r
2451 if (EFI_ERROR (Status)) {\r
2452 return Status;\r
2453 }\r
2454\r
2455 RemoveEntryList (&Package->SimpleFontEntry);\r
2456 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;\r
676df92c 2457 FreePool (Package->SimpleFontPkgHdr);\r
2458 FreePool (Package);\r
93e3992d 2459 }\r
2460\r
2461 return EFI_SUCCESS;\r
2462}\r
2463\r
2464\r
2465/**\r
2466 This function insert a Device path package to a package list node.\r
e90b081a 2467 This is a internal function.\r
93e3992d 2468\r
2469 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
2470 instance\r
2471 @param NotifyType The type of change concerning the database.\r
2472 @param PackageList Pointer to a package list which will be inserted\r
2473 to.\r
2474\r
2475 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
2476 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2477 Device path package.\r
2478 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
2479\r
2480**/\r
93e3992d 2481EFI_STATUS\r
2482InsertDevicePathPackage (\r
2483 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
2484 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2485 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2486 )\r
2487{\r
2488 UINT32 PackageLength;\r
2489 EFI_HII_PACKAGE_HEADER Header;\r
2490\r
2491 if (DevicePath == NULL || PackageList == NULL) {\r
2492 return EFI_INVALID_PARAMETER;\r
2493 }\r
2494 //\r
2495 // Less than one device path package is allowed in one package list.\r
2496 //\r
2497 if (PackageList->DevicePathPkg != NULL) {\r
2498 return EFI_INVALID_PARAMETER;\r
2499 }\r
2500\r
2501 PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);\r
2502 PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);\r
2503 if (PackageList->DevicePathPkg == NULL) {\r
2504 return EFI_OUT_OF_RESOURCES;\r
2505 }\r
2506\r
2507 Header.Length = PackageLength;\r
2508 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;\r
2509 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));\r
2510 CopyMem (\r
2511 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
2512 DevicePath,\r
2513 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)\r
2514 );\r
2515\r
2516 //\r
2517 // Since Device Path package is created by NewPackageList, either NEW_PACK\r
2518 // or ADD_PACK should increase the length of package list.\r
2519 //\r
2520 PackageList->PackageListHdr.PackageLength += PackageLength;\r
2521 return EFI_SUCCESS;\r
2522}\r
2523\r
2524\r
2525/**\r
2526 This function exports device path package to a buffer.\r
e90b081a 2527 This is a internal function.\r
93e3992d 2528\r
2529 @param Private Hii database private structure.\r
2530 @param Handle Identification of a package list.\r
2531 @param PackageList Pointer to a package list which will be exported.\r
2532 @param UsedSize The length of buffer be used.\r
2533 @param BufferSize Length of the Buffer.\r
2534 @param Buffer Allocated space for storing exported data.\r
2535 @param ResultSize The size of the already exported content of this\r
2536 package list.\r
2537\r
2538 @retval EFI_SUCCESS Device path Package is exported successfully.\r
2539 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2540\r
2541**/\r
93e3992d 2542EFI_STATUS\r
2543ExportDevicePathPackage (\r
2544 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2545 IN EFI_HII_HANDLE Handle,\r
2546 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2547 IN UINTN UsedSize,\r
2548 IN UINTN BufferSize,\r
2549 IN OUT VOID *Buffer,\r
2550 IN OUT UINTN *ResultSize\r
2551 )\r
2552{\r
2553 EFI_STATUS Status;\r
2554 UINT8 *Package;\r
2555 EFI_HII_PACKAGE_HEADER Header;\r
2556\r
2557 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2558 return EFI_INVALID_PARAMETER;\r
2559 }\r
2560 if (BufferSize > 0 && Buffer == NULL ) {\r
2561 return EFI_INVALID_PARAMETER;\r
2562 }\r
2563\r
2564 Package = PackageList->DevicePathPkg;\r
2565\r
2566 if (Package == NULL) {\r
2567 return EFI_SUCCESS;\r
2568 }\r
2569\r
2570 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2571\r
2572 if (Header.Length + *ResultSize + UsedSize <= BufferSize) {\r
2573 //\r
2574 // Invoke registered notification function with EXPORT_PACK notify type\r
2575 //\r
2576 Status = InvokeRegisteredFunction (\r
2577 Private,\r
2578 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2579 (VOID *) Package,\r
2580 EFI_HII_PACKAGE_DEVICE_PATH,\r
2581 Handle\r
2582 );\r
2583 ASSERT_EFI_ERROR (Status);\r
2584\r
2585 //\r
2586 // Copy Device path package\r
2587 //\r
2588 CopyMem (Buffer, Package, Header.Length);\r
2589 }\r
2590\r
2591 *ResultSize += Header.Length;\r
2592 return EFI_SUCCESS;\r
2593}\r
2594\r
2595\r
2596/**\r
2597 This function deletes Device Path package from a package list node.\r
e90b081a 2598 This is a internal function.\r
93e3992d 2599\r
2600 @param Private Hii database private data.\r
2601 @param Handle Handle of the package list.\r
2602 @param PackageList Package List which contains the to be removed\r
2603 Device Path package.\r
2604\r
2605 @retval EFI_SUCCESS Device Path Package is deleted successfully.\r
2606 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2607\r
2608**/\r
93e3992d 2609EFI_STATUS\r
2610RemoveDevicePathPackage (\r
2611 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2612 IN EFI_HII_HANDLE Handle,\r
2613 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2614 )\r
2615{\r
2616 EFI_STATUS Status;\r
2617 UINT8 *Package;\r
2618 EFI_HII_PACKAGE_HEADER Header;\r
2619\r
2620 Package = PackageList->DevicePathPkg;\r
2621\r
2622 //\r
2623 // No device path, return directly.\r
2624 //\r
2625 if (Package == NULL) {\r
2626 return EFI_SUCCESS;\r
2627 }\r
2628\r
2629 Status = InvokeRegisteredFunction (\r
2630 Private,\r
2631 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2632 (VOID *) Package,\r
2633 EFI_HII_PACKAGE_DEVICE_PATH,\r
2634 Handle\r
2635 );\r
2636 if (EFI_ERROR (Status)) {\r
2637 return Status;\r
2638 }\r
2639\r
2640 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2641 PackageList->PackageListHdr.PackageLength -= Header.Length;\r
2642\r
676df92c 2643 FreePool (Package);\r
93e3992d 2644\r
2645 PackageList->DevicePathPkg = NULL;\r
2646\r
2647 return EFI_SUCCESS;\r
2648}\r
2649\r
2650\r
2651/**\r
2652 This function will insert a device path package to package list firstly then\r
2653 invoke notification functions if any.\r
e90b081a 2654 This is a internal function.\r
93e3992d 2655\r
2656 @param Private Hii database private structure.\r
2657 @param NotifyType The type of change concerning the database.\r
2658 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
2659 instance\r
2660 @param DatabaseRecord Pointer to a database record contains a package\r
2661 list which will be inserted to.\r
2662\r
2663 @retval EFI_SUCCESS Device path Package is inserted successfully.\r
2664 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2665 Device path package.\r
2666 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.\r
2667\r
2668**/\r
93e3992d 2669EFI_STATUS\r
2670AddDevicePathPackage (\r
2671 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2672 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2673 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
2674 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2675 )\r
2676{\r
2677 EFI_STATUS Status;\r
2678\r
2679 if (DevicePath == NULL) {\r
2680 return EFI_SUCCESS;\r
2681 }\r
2682\r
2683 ASSERT (Private != NULL);\r
2684 ASSERT (DatabaseRecord != NULL);\r
2685\r
2686 //\r
2687 // Create a device path package and insert to packagelist\r
2688 //\r
2689 Status = InsertDevicePathPackage (\r
2690 DevicePath,\r
2691 NotifyType,\r
2692 DatabaseRecord->PackageList\r
2693 );\r
2694 if (EFI_ERROR (Status)) {\r
2695 return Status;\r
2696 }\r
2697\r
2698 return InvokeRegisteredFunction (\r
2699 Private,\r
2700 NotifyType,\r
2701 (VOID *) DatabaseRecord->PackageList->DevicePathPkg,\r
2702 EFI_HII_PACKAGE_DEVICE_PATH,\r
2703 DatabaseRecord->Handle\r
2704 );\r
2705}\r
2706\r
2707\r
2708/**\r
2709 This function insert a Keyboard Layout package to a package list node.\r
e90b081a 2710 This is a internal function.\r
93e3992d 2711\r
2712 @param PackageHdr Pointer to a buffer stored with Keyboard Layout\r
2713 package information.\r
2714 @param NotifyType The type of change concerning the database.\r
2715 @param PackageList Pointer to a package list which will be inserted\r
2716 to.\r
2717 @param Package Created Keyboard Layout package\r
2718\r
2719 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.\r
2720 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2721 Keyboard Layout package.\r
2722 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.\r
2723\r
2724**/\r
93e3992d 2725EFI_STATUS\r
2726InsertKeyboardLayoutPackage (\r
2727 IN VOID *PackageHdr,\r
2728 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2729 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2730 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package\r
2731 )\r
2732{\r
2733 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2734 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2735 EFI_STATUS Status;\r
2736\r
2737 if (PackageHdr == NULL || PackageList == NULL) {\r
2738 return EFI_INVALID_PARAMETER;\r
2739 }\r
2740\r
2741 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2742\r
2743 //\r
2744 // Create a Keyboard Layout package node\r
2745 //\r
2746 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));\r
2747 if (KeyboardLayoutPackage == NULL) {\r
2748 Status = EFI_OUT_OF_RESOURCES;\r
2749 goto Error;\r
2750 }\r
2751 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;\r
2752\r
2753 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
2754 if (KeyboardLayoutPackage->KeyboardPkg == NULL) {\r
2755 Status = EFI_OUT_OF_RESOURCES;\r
2756 goto Error;\r
2757 }\r
2758\r
2759 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);\r
2760 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);\r
2761\r
2762 *Package = KeyboardLayoutPackage;\r
2763\r
2764 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2765 PackageList->PackageListHdr.PackageLength += PackageHeader.Length;\r
2766 }\r
2767\r
2768 return EFI_SUCCESS;\r
2769\r
2770Error:\r
2771\r
c59634ea 2772\r
676df92c 2773 if (KeyboardLayoutPackage != NULL) {\r
c59634ea 2774 if (KeyboardLayoutPackage->KeyboardPkg != NULL) {\r
2775 FreePool (KeyboardLayoutPackage->KeyboardPkg);\r
2776 }\r
676df92c 2777 FreePool (KeyboardLayoutPackage);\r
2778 }\r
93e3992d 2779\r
2780 return Status;\r
2781}\r
2782\r
2783\r
2784/**\r
2785 This function exports Keyboard Layout packages to a buffer.\r
e90b081a 2786 This is a internal function.\r
93e3992d 2787\r
2788 @param Private Hii database private structure.\r
2789 @param Handle Identification of a package list.\r
2790 @param PackageList Pointer to a package list which will be exported.\r
2791 @param UsedSize The length of buffer be used.\r
2792 @param BufferSize Length of the Buffer.\r
2793 @param Buffer Allocated space for storing exported data.\r
2794 @param ResultSize The size of the already exported content of this\r
2795 package list.\r
2796\r
2797 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2798 successfully.\r
2799 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2800\r
2801**/\r
93e3992d 2802EFI_STATUS\r
2803ExportKeyboardLayoutPackages (\r
2804 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2805 IN EFI_HII_HANDLE Handle,\r
2806 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2807 IN UINTN UsedSize,\r
2808 IN UINTN BufferSize,\r
2809 IN OUT VOID *Buffer,\r
2810 IN OUT UINTN *ResultSize\r
2811 )\r
2812{\r
2813 LIST_ENTRY *Link;\r
2814 UINTN PackageLength;\r
2815 EFI_STATUS Status;\r
2816 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2817 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2818\r
2819 if (Private == NULL || PackageList == NULL || ResultSize == NULL) {\r
2820 return EFI_INVALID_PARAMETER;\r
2821 }\r
2822\r
2823 if (BufferSize > 0 && Buffer == NULL ) {\r
2824 return EFI_INVALID_PARAMETER;\r
2825 }\r
2826\r
2827 PackageLength = 0;\r
2828 Status = EFI_SUCCESS;\r
2829\r
2830 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {\r
2831 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);\r
2832 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2833 PackageLength += PackageHeader.Length;\r
2834 if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
2835 //\r
2836 // Invoke registered notification function with EXPORT_PACK notify type\r
2837 //\r
2838 Status = InvokeRegisteredFunction (\r
2839 Private,\r
2840 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
2841 (EFI_HII_PACKAGE_HEADER *) Package,\r
2842 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2843 Handle\r
2844 );\r
2845 ASSERT_EFI_ERROR (Status);\r
2846\r
2847 //\r
2848 // Copy Keyboard Layout package\r
2849 //\r
2850 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);\r
2851 Buffer = (UINT8 *) Buffer + PackageHeader.Length;\r
2852 }\r
2853 }\r
2854\r
2855 *ResultSize += PackageLength;\r
2856 return EFI_SUCCESS;\r
2857}\r
2858\r
2859\r
2860/**\r
2861 This function deletes all Keyboard Layout packages from a package list node.\r
e90b081a 2862 This is a internal function.\r
93e3992d 2863\r
2864 @param Private Hii database private data.\r
2865 @param Handle Handle of the package list which contains the to\r
2866 be removed Keyboard Layout packages.\r
2867 @param PackageList Pointer to a package list that contains removing\r
2868 packages.\r
2869\r
2870 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted\r
2871 successfully.\r
2872 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.\r
2873\r
2874**/\r
93e3992d 2875EFI_STATUS\r
2876RemoveKeyboardLayoutPackages (\r
2877 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2878 IN EFI_HII_HANDLE Handle,\r
2879 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
2880 )\r
2881{\r
2882 LIST_ENTRY *ListHead;\r
2883 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
2884 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2885 EFI_STATUS Status;\r
2886\r
2887 ListHead = &PackageList->KeyboardLayoutHdr;\r
2888\r
2889 while (!IsListEmpty (ListHead)) {\r
2890 Package = CR (\r
2891 ListHead->ForwardLink,\r
2892 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
2893 KeyboardEntry,\r
2894 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
2895 );\r
2896 Status = InvokeRegisteredFunction (\r
2897 Private,\r
2898 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2899 (VOID *) Package,\r
2900 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,\r
2901 Handle\r
2902 );\r
2903 if (EFI_ERROR (Status)) {\r
2904 return Status;\r
2905 }\r
2906\r
2907 RemoveEntryList (&Package->KeyboardEntry);\r
2908 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
2909 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
676df92c 2910 FreePool (Package->KeyboardPkg);\r
2911 FreePool (Package);\r
93e3992d 2912 }\r
2913\r
2914 return EFI_SUCCESS;\r
2915}\r
2916\r
2917\r
2918/**\r
2919 This function will insert a package list to hii database firstly then\r
2920 invoke notification functions if any. It is the worker function of\r
2921 HiiNewPackageList and HiiUpdatePackageList.\r
2922\r
e90b081a 2923 This is a internal function.\r
2924\r
93e3992d 2925 @param Private Hii database private structure.\r
2926 @param NotifyType The type of change concerning the database.\r
2927 @param PackageList Pointer to a package list.\r
2928 @param DatabaseRecord Pointer to a database record contains a package\r
2929 list instance which will be inserted to.\r
2930\r
2931 @retval EFI_SUCCESS All incoming packages are inserted to current\r
2932 database.\r
2933 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2934 Device path package.\r
2935 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2936\r
2937**/\r
93e3992d 2938EFI_STATUS\r
2939AddPackages (\r
2940 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2941 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
2942 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
2943 IN OUT HII_DATABASE_RECORD *DatabaseRecord\r
2944 )\r
2945{\r
2946 EFI_STATUS Status;\r
2947 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
2948 HII_IFR_PACKAGE_INSTANCE *FormPackage;\r
2949 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;\r
2950 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
2951 HII_FONT_PACKAGE_INSTANCE *FontPackage;\r
2952 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;\r
2953 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
2954 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
2955 EFI_HII_PACKAGE_HEADER PackageHeader;\r
2956 UINT32 OldPackageListLen;\r
6ddd3af7 2957 BOOLEAN StringPkgIsAdd;\r
93e3992d 2958\r
6c46a5ab 2959 //\r
2960 // Initialize Variables\r
2961 //\r
4e1005ec
ED
2962 StringPkgIsAdd = FALSE;\r
2963 FontPackage = NULL;\r
2964 StringPackage = NULL;\r
2965 GuidPackage = NULL;\r
2966 FormPackage = NULL;\r
2967 ImagePackage = NULL;\r
2968 SimpleFontPackage = NULL;\r
2969 KeyboardLayoutPackage = NULL;\r
6c46a5ab 2970\r
93e3992d 2971 //\r
2972 // Process the package list header\r
2973 //\r
2974 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;\r
2975 CopyMem (\r
2976 &DatabaseRecord->PackageList->PackageListHdr,\r
2977 (VOID *) PackageList,\r
2978 sizeof (EFI_HII_PACKAGE_LIST_HEADER)\r
2979 );\r
2980 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2981 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;\r
2982 }\r
2983\r
2984 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2985 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2986\r
2987 Status = EFI_SUCCESS;\r
2988\r
2989 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2990 switch (PackageHeader.Type) {\r
2991 case EFI_HII_PACKAGE_TYPE_GUID:\r
2992 Status = InsertGuidPackage (\r
2993 PackageHdrPtr,\r
2994 NotifyType,\r
2995 DatabaseRecord->PackageList,\r
2996 &GuidPackage\r
2997 );\r
2998 if (EFI_ERROR (Status)) {\r
2999 return Status;\r
3000 }\r
3001 Status = InvokeRegisteredFunction (\r
3002 Private,\r
3003 NotifyType,\r
3004 (VOID *) GuidPackage,\r
3005 (UINT8) (PackageHeader.Type),\r
3006 DatabaseRecord->Handle\r
3007 );\r
3008 break;\r
8d00a0f1 3009 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3010 Status = InsertFormPackage (\r
3011 PackageHdrPtr,\r
3012 NotifyType,\r
3013 DatabaseRecord->PackageList,\r
3014 &FormPackage\r
3015 );\r
3016 if (EFI_ERROR (Status)) {\r
3017 return Status;\r
3018 }\r
3019 Status = InvokeRegisteredFunction (\r
3020 Private,\r
3021 NotifyType,\r
3022 (VOID *) FormPackage,\r
3023 (UINT8) (PackageHeader.Type),\r
3024 DatabaseRecord->Handle\r
3025 );\r
c87b13cd
DB
3026 //\r
3027 // If Hii runtime support feature is enabled,\r
3028 // will export Hii info for runtime use after ReadyToBoot event triggered.\r
3029 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,\r
3030 // will need to export the content of HiiDatabase.\r
3031 // But if form packages added/updated, also need to export the ConfigResp string.\r
3032 //\r
3033 if (gExportAfterReadyToBoot) {\r
3034 gExportConfigResp = TRUE;\r
3035 }\r
93e3992d 3036 break;\r
3037 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3038 Status = InsertKeyboardLayoutPackage (\r
3039 PackageHdrPtr,\r
3040 NotifyType,\r
3041 DatabaseRecord->PackageList,\r
3042 &KeyboardLayoutPackage\r
3043 );\r
3044 if (EFI_ERROR (Status)) {\r
3045 return Status;\r
3046 }\r
3047 Status = InvokeRegisteredFunction (\r
3048 Private,\r
3049 NotifyType,\r
3050 (VOID *) KeyboardLayoutPackage,\r
3051 (UINT8) (PackageHeader.Type),\r
3052 DatabaseRecord->Handle\r
3053 );\r
3054 break;\r
3055 case EFI_HII_PACKAGE_STRINGS:\r
3056 Status = InsertStringPackage (\r
3057 Private,\r
3058 PackageHdrPtr,\r
3059 NotifyType,\r
3060 DatabaseRecord->PackageList,\r
3061 &StringPackage\r
3062 );\r
3063 if (EFI_ERROR (Status)) {\r
3064 return Status;\r
3065 }\r
523f48e7 3066 ASSERT (StringPackage != NULL);\r
93e3992d 3067 Status = InvokeRegisteredFunction (\r
3068 Private,\r
3069 NotifyType,\r
3070 (VOID *) StringPackage,\r
3071 (UINT8) (PackageHeader.Type),\r
3072 DatabaseRecord->Handle\r
3073 );\r
6ddd3af7 3074 StringPkgIsAdd = TRUE;\r
93e3992d 3075 break;\r
3076 case EFI_HII_PACKAGE_FONTS:\r
3077 Status = InsertFontPackage (\r
3078 Private,\r
3079 PackageHdrPtr,\r
3080 NotifyType,\r
3081 DatabaseRecord->PackageList,\r
3082 &FontPackage\r
3083 );\r
3084 if (EFI_ERROR (Status)) {\r
3085 return Status;\r
3086 }\r
3087 Status = InvokeRegisteredFunction (\r
3088 Private,\r
3089 NotifyType,\r
3090 (VOID *) FontPackage,\r
3091 (UINT8) (PackageHeader.Type),\r
3092 DatabaseRecord->Handle\r
3093 );\r
3094 break;\r
3095 case EFI_HII_PACKAGE_IMAGES:\r
3096 Status = InsertImagePackage (\r
3097 PackageHdrPtr,\r
3098 NotifyType,\r
3099 DatabaseRecord->PackageList,\r
3100 &ImagePackage\r
3101 );\r
3102 if (EFI_ERROR (Status)) {\r
3103 return Status;\r
3104 }\r
3105 Status = InvokeRegisteredFunction (\r
3106 Private,\r
3107 NotifyType,\r
3108 (VOID *) ImagePackage,\r
3109 (UINT8) (PackageHeader.Type),\r
3110 DatabaseRecord->Handle\r
3111 );\r
3112 break;\r
3113 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3114 Status = InsertSimpleFontPackage (\r
3115 PackageHdrPtr,\r
3116 NotifyType,\r
3117 DatabaseRecord->PackageList,\r
3118 &SimpleFontPackage\r
3119 );\r
3120 if (EFI_ERROR (Status)) {\r
3121 return Status;\r
3122 }\r
3123 Status = InvokeRegisteredFunction (\r
3124 Private,\r
3125 NotifyType,\r
3126 (VOID *) SimpleFontPackage,\r
3127 (UINT8) (PackageHeader.Type),\r
3128 DatabaseRecord->Handle\r
3129 );\r
3130 break;\r
3131 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3132 Status = AddDevicePathPackage (\r
3133 Private,\r
3134 NotifyType,\r
3135 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),\r
3136 DatabaseRecord\r
3137 );\r
3138 break;\r
3139 default:\r
3140 break;\r
3141 }\r
3142\r
3143 if (EFI_ERROR (Status)) {\r
3144 return Status;\r
3145 }\r
3146 //\r
3147 // goto header of next package\r
3148 //\r
3149 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
3150 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3151 }\r
6ddd3af7
LG
3152 \r
3153 //\r
3154 // Adjust String Package to make sure all string packages have the same max string ID.\r
3155 //\r
3156 if (!EFI_ERROR (Status) && StringPkgIsAdd) {\r
3157 Status = AdjustStringPackage (DatabaseRecord->PackageList);\r
3158 }\r
93e3992d 3159\r
3160 return Status;\r
3161}\r
3162\r
3163\r
3164/**\r
3165 This function exports a package list to a buffer. It is the worker function\r
3166 of HiiExportPackageList.\r
3167\r
e90b081a