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