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