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