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