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