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