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