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