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