]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg:Modify the incorrect DestStr length in safe string functions
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_DATABASE_PROTOCOL.\r
3\r
5ad66ec6 4Copyright (c) 2007 - 2015, 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
5ad66ec6 801 AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
93e3992d 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
4d5b0868 1185 StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily);\r
93e3992d 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
4e1005ec
ED
2420 StringPkgIsAdd = FALSE;\r
2421 FontPackage = NULL;\r
2422 StringPackage = NULL;\r
2423 GuidPackage = NULL;\r
2424 FormPackage = NULL;\r
2425 ImagePackage = NULL;\r
2426 SimpleFontPackage = NULL;\r
2427 KeyboardLayoutPackage = NULL;\r
6c46a5ab 2428\r
93e3992d 2429 //\r
2430 // Process the package list header\r
2431 //\r
2432 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;\r
2433 CopyMem (\r
2434 &DatabaseRecord->PackageList->PackageListHdr,\r
2435 (VOID *) PackageList,\r
2436 sizeof (EFI_HII_PACKAGE_LIST_HEADER)\r
2437 );\r
2438 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
2439 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;\r
2440 }\r
2441\r
2442 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
2443 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2444\r
2445 Status = EFI_SUCCESS;\r
2446\r
2447 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
2448 switch (PackageHeader.Type) {\r
2449 case EFI_HII_PACKAGE_TYPE_GUID:\r
2450 Status = InsertGuidPackage (\r
2451 PackageHdrPtr,\r
2452 NotifyType,\r
2453 DatabaseRecord->PackageList,\r
2454 &GuidPackage\r
2455 );\r
2456 if (EFI_ERROR (Status)) {\r
2457 return Status;\r
2458 }\r
2459 Status = InvokeRegisteredFunction (\r
2460 Private,\r
2461 NotifyType,\r
2462 (VOID *) GuidPackage,\r
2463 (UINT8) (PackageHeader.Type),\r
2464 DatabaseRecord->Handle\r
2465 );\r
2466 break;\r
8d00a0f1 2467 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 2468 Status = InsertFormPackage (\r
2469 PackageHdrPtr,\r
2470 NotifyType,\r
2471 DatabaseRecord->PackageList,\r
2472 &FormPackage\r
2473 );\r
2474 if (EFI_ERROR (Status)) {\r
2475 return Status;\r
2476 }\r
2477 Status = InvokeRegisteredFunction (\r
2478 Private,\r
2479 NotifyType,\r
2480 (VOID *) FormPackage,\r
2481 (UINT8) (PackageHeader.Type),\r
2482 DatabaseRecord->Handle\r
2483 );\r
2484 break;\r
2485 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
2486 Status = InsertKeyboardLayoutPackage (\r
2487 PackageHdrPtr,\r
2488 NotifyType,\r
2489 DatabaseRecord->PackageList,\r
2490 &KeyboardLayoutPackage\r
2491 );\r
2492 if (EFI_ERROR (Status)) {\r
2493 return Status;\r
2494 }\r
2495 Status = InvokeRegisteredFunction (\r
2496 Private,\r
2497 NotifyType,\r
2498 (VOID *) KeyboardLayoutPackage,\r
2499 (UINT8) (PackageHeader.Type),\r
2500 DatabaseRecord->Handle\r
2501 );\r
2502 break;\r
2503 case EFI_HII_PACKAGE_STRINGS:\r
2504 Status = InsertStringPackage (\r
2505 Private,\r
2506 PackageHdrPtr,\r
2507 NotifyType,\r
2508 DatabaseRecord->PackageList,\r
2509 &StringPackage\r
2510 );\r
2511 if (EFI_ERROR (Status)) {\r
2512 return Status;\r
2513 }\r
523f48e7 2514 ASSERT (StringPackage != NULL);\r
93e3992d 2515 Status = InvokeRegisteredFunction (\r
2516 Private,\r
2517 NotifyType,\r
2518 (VOID *) StringPackage,\r
2519 (UINT8) (PackageHeader.Type),\r
2520 DatabaseRecord->Handle\r
2521 );\r
6ddd3af7 2522 StringPkgIsAdd = TRUE;\r
93e3992d 2523 break;\r
2524 case EFI_HII_PACKAGE_FONTS:\r
2525 Status = InsertFontPackage (\r
2526 Private,\r
2527 PackageHdrPtr,\r
2528 NotifyType,\r
2529 DatabaseRecord->PackageList,\r
2530 &FontPackage\r
2531 );\r
2532 if (EFI_ERROR (Status)) {\r
2533 return Status;\r
2534 }\r
2535 Status = InvokeRegisteredFunction (\r
2536 Private,\r
2537 NotifyType,\r
2538 (VOID *) FontPackage,\r
2539 (UINT8) (PackageHeader.Type),\r
2540 DatabaseRecord->Handle\r
2541 );\r
2542 break;\r
2543 case EFI_HII_PACKAGE_IMAGES:\r
2544 Status = InsertImagePackage (\r
2545 PackageHdrPtr,\r
2546 NotifyType,\r
2547 DatabaseRecord->PackageList,\r
2548 &ImagePackage\r
2549 );\r
2550 if (EFI_ERROR (Status)) {\r
2551 return Status;\r
2552 }\r
2553 Status = InvokeRegisteredFunction (\r
2554 Private,\r
2555 NotifyType,\r
2556 (VOID *) ImagePackage,\r
2557 (UINT8) (PackageHeader.Type),\r
2558 DatabaseRecord->Handle\r
2559 );\r
2560 break;\r
2561 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
2562 Status = InsertSimpleFontPackage (\r
2563 PackageHdrPtr,\r
2564 NotifyType,\r
2565 DatabaseRecord->PackageList,\r
2566 &SimpleFontPackage\r
2567 );\r
2568 if (EFI_ERROR (Status)) {\r
2569 return Status;\r
2570 }\r
2571 Status = InvokeRegisteredFunction (\r
2572 Private,\r
2573 NotifyType,\r
2574 (VOID *) SimpleFontPackage,\r
2575 (UINT8) (PackageHeader.Type),\r
2576 DatabaseRecord->Handle\r
2577 );\r
2578 break;\r
2579 case EFI_HII_PACKAGE_DEVICE_PATH:\r
2580 Status = AddDevicePathPackage (\r
2581 Private,\r
2582 NotifyType,\r
2583 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),\r
2584 DatabaseRecord\r
2585 );\r
2586 break;\r
2587 default:\r
2588 break;\r
2589 }\r
2590\r
2591 if (EFI_ERROR (Status)) {\r
2592 return Status;\r
2593 }\r
2594 //\r
2595 // goto header of next package\r
2596 //\r
2597 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
2598 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
2599 }\r
6ddd3af7
LG
2600 \r
2601 //\r
2602 // Adjust String Package to make sure all string packages have the same max string ID.\r
2603 //\r
2604 if (!EFI_ERROR (Status) && StringPkgIsAdd) {\r
2605 Status = AdjustStringPackage (DatabaseRecord->PackageList);\r
2606 }\r
93e3992d 2607\r
2608 return Status;\r
2609}\r
2610\r
2611\r
2612/**\r
2613 This function exports a package list to a buffer. It is the worker function\r
2614 of HiiExportPackageList.\r
2615\r
e90b081a 2616 This is a internal function.\r
2617\r
93e3992d 2618 @param Private Hii database private structure.\r
2619 @param Handle Identification of a package list.\r
2620 @param PackageList Pointer to a package list which will be exported.\r
2621 @param UsedSize The length of buffer has been used by exporting\r
2622 package lists when Handle is NULL.\r
2623 @param BufferSize Length of the Buffer.\r
2624 @param Buffer Allocated space for storing exported data.\r
2625\r
2626 @retval EFI_SUCCESS Keyboard Layout Packages are exported\r
2627 successfully.\r
2628 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
2629\r
2630**/\r
93e3992d 2631EFI_STATUS\r
2632ExportPackageList (\r
2633 IN HII_DATABASE_PRIVATE_DATA *Private,\r
2634 IN EFI_HII_HANDLE Handle,\r
2635 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
2636 IN OUT UINTN *UsedSize,\r
2637 IN UINTN BufferSize,\r
2638 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
2639 )\r
2640{\r
2641 EFI_STATUS Status;\r
2642 UINTN ResultSize;\r
2643 EFI_HII_PACKAGE_HEADER EndofPackageList;\r
2644\r
96ff65a1 2645 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);\r
93e3992d 2646 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
2647 ASSERT (IsHiiHandleValid (Handle));\r
2648\r
2649 if (BufferSize > 0 && Buffer == NULL ) {\r
2650 return EFI_INVALID_PARAMETER;\r
2651 }\r
2652\r
2653 //\r
2654 // Copy the package list header\r
2655 // ResultSize indicates the length of the exported bytes of this package list\r
2656 //\r
2657 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
2658 if (ResultSize + *UsedSize <= BufferSize) {\r
2659 CopyMem ((VOID *) Buffer, PackageList, ResultSize);\r
2660 }\r
2661 //\r
2662 // Copy the packages and invoke EXPORT_PACK notify functions if exists.\r
2663 //\r
2664 Status = ExportGuidPackages (\r
2665 Private,\r
2666 Handle,\r
2667 PackageList,\r
2668 *UsedSize,\r
2669 BufferSize,\r
2670 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2671 &ResultSize\r
2672 );\r
2673 if (EFI_ERROR (Status)) {\r
2674 return Status;\r
2675 }\r
2676 Status = ExportFormPackages (\r
2677 Private,\r
2678 Handle,\r
2679 PackageList,\r
2680 *UsedSize,\r
2681 BufferSize,\r
2682 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2683 &ResultSize\r
2684 );\r
2685 if (EFI_ERROR (Status)) {\r
2686 return Status;\r
2687 }\r
2688 Status = ExportKeyboardLayoutPackages (\r
2689 Private,\r
2690 Handle,\r
2691 PackageList,\r
2692 *UsedSize,\r
2693 BufferSize,\r
2694 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2695 &ResultSize\r
2696 );\r
2697 if (EFI_ERROR (Status)) {\r
2698 return Status;\r
2699 }\r
2700 Status = ExportStringPackages (\r
2701 Private,\r
2702 Handle,\r
2703 PackageList,\r
2704 *UsedSize,\r
2705 BufferSize,\r
2706 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2707 &ResultSize\r
2708 );\r
2709 if (EFI_ERROR (Status)) {\r
2710 return Status;\r
2711 }\r
2712 Status = ExportFontPackages (\r
2713 Private,\r
2714 Handle,\r
2715 PackageList,\r
2716 *UsedSize,\r
2717 BufferSize,\r
2718 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2719 &ResultSize\r
2720 );\r
2721 if (EFI_ERROR (Status)) {\r
2722 return Status;\r
2723 }\r
2724 Status = ExportImagePackages (\r
2725 Private,\r
2726 Handle,\r
2727 PackageList,\r
2728 *UsedSize,\r
2729 BufferSize,\r
2730 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2731 &ResultSize\r
2732 );\r
2733 if (EFI_ERROR (Status)) {\r
2734 return Status;\r
2735 }\r
2736 Status = ExportSimpleFontPackages (\r
2737 Private,\r
2738 Handle,\r
2739 PackageList,\r
2740 *UsedSize,\r
2741 BufferSize,\r
2742 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2743 &ResultSize\r
2744 );\r
2745 if (EFI_ERROR (Status)) {\r
2746 return Status;\r
2747 }\r
2748 Status = ExportDevicePathPackage (\r
2749 Private,\r
2750 Handle,\r
2751 PackageList,\r
2752 *UsedSize,\r
2753 BufferSize,\r
2754 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2755 &ResultSize\r
2756 );\r
2757 if (EFI_ERROR (Status)) {\r
2758 return Status;\r
2759 }\r
2760 //\r
2761 // Append the package list end.\r
2762 //\r
2763 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
2764 EndofPackageList.Type = EFI_HII_PACKAGE_END;\r
2765 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {\r
2766 CopyMem (\r
2767 (VOID *) ((UINT8 *) Buffer + ResultSize),\r
2768 (VOID *) &EndofPackageList,\r
2769 sizeof (EFI_HII_PACKAGE_HEADER)\r
2770 );\r
2771 }\r
2772\r
2773 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);\r
2774\r
2775 return EFI_SUCCESS;\r
2776}\r
2777\r
2778\r
2779/**\r
2780 This function adds the packages in the package list to the database and returns a handle. If there is a\r
2781 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
2782 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.\r
2783\r
2784 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2785 instance.\r
2786 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2787 structure.\r
2788 @param DriverHandle Associate the package list with this EFI handle.\r
b1a803d1 2789 If a NULL is specified, this data will not be associate\r
2790 with any drivers and cannot have a callback induced.\r
93e3992d 2791 @param Handle A pointer to the EFI_HII_HANDLE instance.\r
2792\r
2793 @retval EFI_SUCCESS The package list associated with the Handle was\r
2794 added to the HII database.\r
2795 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new\r
2796 database contents.\r
2797 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.\r
2798 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.\r
2799\r
2800**/\r
2801EFI_STATUS\r
2802EFIAPI\r
2803HiiNewPackageList (\r
2804 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2805 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
b1a803d1 2806 IN CONST EFI_HANDLE DriverHandle, OPTIONAL\r
93e3992d 2807 OUT EFI_HII_HANDLE *Handle\r
2808 )\r
2809{\r
2810 EFI_STATUS Status;\r
2811 HII_DATABASE_PRIVATE_DATA *Private;\r
2812 HII_DATABASE_RECORD *DatabaseRecord;\r
2813 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2814 LIST_ENTRY *Link;\r
2815 EFI_GUID PackageListGuid;\r
2816\r
2817 if (This == NULL || PackageList == NULL || Handle == NULL) {\r
2818 return EFI_INVALID_PARAMETER;\r
2819 }\r
2820\r
2821 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2822 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));\r
2823\r
2824 //\r
2825 // Check the Package list GUID to guarantee this GUID is unique in database.\r
2826 //\r
2827 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2828 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2829 if (CompareGuid (\r
2830 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
aa2614b7 2831 &PackageListGuid) && \r
2832 DatabaseRecord->DriverHandle == DriverHandle) {\r
93e3992d 2833 return EFI_INVALID_PARAMETER;\r
2834 }\r
2835 }\r
2836\r
2837 //\r
2838 // Build a PackageList node\r
2839 //\r
2840 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
2841 if (EFI_ERROR (Status)) {\r
2842 return Status;\r
2843 }\r
2844\r
2845 //\r
2846 // Fill in information of the created Package List node\r
2847 // according to incoming package list.\r
2848 //\r
2849 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
2850 if (EFI_ERROR (Status)) {\r
2851 return Status;\r
2852 }\r
2853\r
2854 DatabaseRecord->DriverHandle = DriverHandle;\r
2855\r
2856 //\r
2857 // Create a Device path package and add into the package list if exists.\r
2858 //\r
2859 Status = gBS->HandleProtocol (\r
2860 DriverHandle,\r
2861 &gEfiDevicePathProtocolGuid,\r
2862 (VOID **) &DevicePath\r
2863 );\r
2864 if (!EFI_ERROR (Status)) {\r
2865 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);\r
2866 ASSERT_EFI_ERROR (Status);\r
2867 }\r
2868\r
2869 *Handle = DatabaseRecord->Handle;\r
2870 return EFI_SUCCESS;\r
2871}\r
2872\r
2873\r
2874/**\r
2875 This function removes the package list that is associated with a handle Handle\r
2876 from the HII database. Before removing the package, any registered functions\r
2877 with the notification type REMOVE_PACK and the same package type will be called.\r
2878\r
2879 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2880 instance.\r
2881 @param Handle The handle that was registered to the data that is\r
2882 requested for removal.\r
2883\r
2884 @retval EFI_SUCCESS The data associated with the Handle was removed\r
2885 from the HII database.\r
813acf3a 2886 @retval EFI_NOT_FOUND The specified andle is not in database.\r
93e3992d 2887 @retval EFI_INVALID_PARAMETER The Handle was not valid.\r
2888\r
2889**/\r
2890EFI_STATUS\r
2891EFIAPI\r
2892HiiRemovePackageList (\r
2893 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
2894 IN EFI_HII_HANDLE Handle\r
2895 )\r
2896{\r
2897 EFI_STATUS Status;\r
2898 HII_DATABASE_PRIVATE_DATA *Private;\r
2899 LIST_ENTRY *Link;\r
2900 HII_DATABASE_RECORD *Node;\r
2901 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
2902 HII_HANDLE *HiiHandle;\r
2903\r
813acf3a 2904 if (This == NULL) {\r
93e3992d 2905 return EFI_INVALID_PARAMETER;\r
2906 }\r
2907\r
813acf3a 2908 if (!IsHiiHandleValid (Handle)) {\r
2909 return EFI_NOT_FOUND;\r
2910 }\r
2911\r
93e3992d 2912 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2913\r
2914 //\r
2915 // Get the packagelist to be removed.\r
2916 //\r
2917 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
2918 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
2919 if (Node->Handle == Handle) {\r
2920 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
2921 ASSERT (PackageList != NULL);\r
2922\r
2923 //\r
2924 // Call registered functions with REMOVE_PACK before removing packages\r
2925 // then remove them.\r
2926 //\r
2927 Status = RemoveGuidPackages (Private, Handle, PackageList);\r
2928 if (EFI_ERROR (Status)) {\r
2929 return Status;\r
2930 }\r
2931 Status = RemoveFormPackages (Private, Handle, PackageList);\r
2932 if (EFI_ERROR (Status)) {\r
2933 return Status;\r
2934 }\r
2935 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
2936 if (EFI_ERROR (Status)) {\r
2937 return Status;\r
2938 }\r
2939 Status = RemoveStringPackages (Private, Handle, PackageList);\r
2940 if (EFI_ERROR (Status)) {\r
2941 return Status;\r
2942 }\r
2943 Status = RemoveFontPackages (Private, Handle, PackageList);\r
2944 if (EFI_ERROR (Status)) {\r
2945 return Status;\r
2946 }\r
2947 Status = RemoveImagePackages (Private, Handle, PackageList);\r
2948 if (EFI_ERROR (Status)) {\r
2949 return Status;\r
2950 }\r
2951 Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
2952 if (EFI_ERROR (Status)) {\r
2953 return Status;\r
2954 }\r
2955 Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
2956 if (EFI_ERROR (Status)) {\r
2957 return Status;\r
2958 }\r
2959\r
2960 //\r
2961 // Free resources of the package list\r
2962 //\r
2963 RemoveEntryList (&Node->DatabaseEntry);\r
2964\r
2965 HiiHandle = (HII_HANDLE *) Handle;\r
2966 RemoveEntryList (&HiiHandle->Handle);\r
2967 Private->HiiHandleCount--;\r
2968 ASSERT (Private->HiiHandleCount >= 0);\r
2969\r
2970 HiiHandle->Signature = 0;\r
676df92c 2971 FreePool (HiiHandle);\r
2972 FreePool (Node->PackageList);\r
2973 FreePool (Node);\r
93e3992d 2974\r
2975 return EFI_SUCCESS;\r
2976 }\r
2977 }\r
2978\r
2979 return EFI_NOT_FOUND;\r
2980}\r
2981\r
2982\r
2983/**\r
2984 This function updates the existing package list (which has the specified Handle)\r
2985 in the HII databases, using the new package list specified by PackageList.\r
2986\r
2987 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
2988 instance.\r
2989 @param Handle The handle that was registered to the data that is\r
2990 requested to be updated.\r
2991 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
2992 package.\r
2993\r
2994 @retval EFI_SUCCESS The HII database was successfully updated.\r
2995 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated\r
2996 database.\r
813acf3a 2997 @retval EFI_INVALID_PARAMETER PackageList was NULL.\r
2998 @retval EFI_NOT_FOUND The specified Handle is not in database.\r
93e3992d 2999\r
3000**/\r
3001EFI_STATUS\r
3002EFIAPI\r
3003HiiUpdatePackageList (\r
3004 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3005 IN EFI_HII_HANDLE Handle,\r
3006 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList\r
3007 )\r
3008{\r
3009 EFI_STATUS Status;\r
3010 HII_DATABASE_PRIVATE_DATA *Private;\r
3011 LIST_ENTRY *Link;\r
3012 HII_DATABASE_RECORD *Node;\r
3013 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
3014 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;\r
3015 EFI_HII_PACKAGE_HEADER PackageHeader;\r
3016\r
813acf3a 3017 if (This == NULL || PackageList == NULL) {\r
93e3992d 3018 return EFI_INVALID_PARAMETER;\r
3019 }\r
3020\r
3021 if (!IsHiiHandleValid (Handle)) {\r
3022 return EFI_NOT_FOUND;\r
3023 }\r
3024\r
3025 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3026\r
3027 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
3028\r
3029 Status = EFI_SUCCESS;\r
3030\r
3031 //\r
3032 // Get original packagelist to be updated\r
3033 //\r
3034 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3035 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3036 if (Node->Handle == Handle) {\r
3037 OldPackageList = Node->PackageList;\r
3038 //\r
3039 // Remove the package if its type matches one of the package types which is\r
3040 // contained in the new package list.\r
3041 //\r
3042 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3043 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
3044 switch (PackageHeader.Type) {\r
3045 case EFI_HII_PACKAGE_TYPE_GUID:\r
3046 Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
3047 break;\r
8d00a0f1 3048 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3049 Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
3050 break;\r
3051 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3052 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);\r
3053 break;\r
3054 case EFI_HII_PACKAGE_STRINGS:\r
3055 Status = RemoveStringPackages (Private, Handle, OldPackageList);\r
3056 break;\r
3057 case EFI_HII_PACKAGE_FONTS:\r
3058 Status = RemoveFontPackages (Private, Handle, OldPackageList);\r
3059 break;\r
3060 case EFI_HII_PACKAGE_IMAGES:\r
3061 Status = RemoveImagePackages (Private, Handle, OldPackageList);\r
3062 break;\r
3063 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3064 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);\r
3065 break;\r
3066 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3067 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);\r
3068 break;\r
3069 }\r
3070\r
3071 if (EFI_ERROR (Status)) {\r
3072 return Status;\r
3073 }\r
3074\r
3075 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
3076 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
3077 }\r
3078\r
3079 //\r
3080 // Add all of the packages within the new package list\r
3081 //\r
3082 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
3083 }\r
3084 }\r
3085\r
3086 return EFI_NOT_FOUND;\r
3087}\r
3088\r
3089\r
3090/**\r
3091 This function returns a list of the package handles of the specified type\r
3092 that are currently active in the database. The pseudo-type\r
3093 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.\r
3094\r
3095 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3096 instance.\r
3097 @param PackageType Specifies the package type of the packages to list\r
3098 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3099 listed.\r
3100 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3101 this is the pointer to the GUID which must match\r
3102 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.\r
3103 Otherwise, it must be NULL.\r
3104 @param HandleBufferLength On input, a pointer to the length of the handle\r
3105 buffer. On output, the length of the handle\r
3106 buffer that is required for the handles found.\r
3107 @param Handle An array of EFI_HII_HANDLE instances returned.\r
3108\r
3109 @retval EFI_SUCCESS The matching handles are outputed successfully.\r
c0a3c3da 3110 HandleBufferLength is updated with the actual length.\r
93e3992d 3111 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3112 Handle is too small to support the number of\r
3113 handles. HandleBufferLength is updated with a\r
3114 value that will enable the data to fit.\r
3115 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
c0a3c3da
ED
3116 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.\r
3117 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not\r
3118 zero and Handle was NULL.\r
813acf3a 3119 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
c0a3c3da
ED
3120 PackageGuid is not NULL, PackageType is a EFI_HII_\r
3121 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
93e3992d 3122\r
3123**/\r
3124EFI_STATUS\r
3125EFIAPI\r
3126HiiListPackageLists (\r
3127 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3128 IN UINT8 PackageType,\r
3129 IN CONST EFI_GUID *PackageGuid,\r
3130 IN OUT UINTN *HandleBufferLength,\r
3131 OUT EFI_HII_HANDLE *Handle\r
3132 )\r
3133{\r
3134 HII_GUID_PACKAGE_INSTANCE *GuidPackage;\r
3135 HII_DATABASE_PRIVATE_DATA *Private;\r
3136 HII_DATABASE_RECORD *Node;\r
3137 LIST_ENTRY *Link;\r
3138 BOOLEAN Matched;\r
3139 HII_HANDLE **Result;\r
3140 UINTN ResultSize;\r
3141 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3142 LIST_ENTRY *Link1;\r
3143\r
3144 //\r
3145 // Check input parameters\r
3146 //\r
3147 if (This == NULL || HandleBufferLength == NULL) {\r
3148 return EFI_INVALID_PARAMETER;\r
3149 }\r
3150 if (*HandleBufferLength > 0 && Handle == NULL) {\r
3151 return EFI_INVALID_PARAMETER;\r
3152 }\r
3153 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3154 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3155 return EFI_INVALID_PARAMETER;\r
3156 }\r
3157\r
3158 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3159 Matched = FALSE;\r
3160 Result = (HII_HANDLE **) Handle;\r
3161 ResultSize = 0;\r
3162\r
3163 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3164 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3165 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3166 switch (PackageType) {\r
3167 case EFI_HII_PACKAGE_TYPE_GUID:\r
3168 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {\r
3169 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);\r
3170 if (CompareGuid (\r
3171 (EFI_GUID *) PackageGuid,\r
3172 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))\r
3173 )) {\r
3174 Matched = TRUE;\r
3175 break;\r
3176 }\r
3177 }\r
3178 break;\r
8d00a0f1 3179 case EFI_HII_PACKAGE_FORMS:\r
93e3992d 3180 if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
3181 Matched = TRUE;\r
3182 }\r
3183 break;\r
3184 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
3185 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {\r
3186 Matched = TRUE;\r
3187 }\r
3188 break;\r
3189 case EFI_HII_PACKAGE_STRINGS:\r
3190 if (!IsListEmpty (&PackageList->StringPkgHdr)) {\r
3191 Matched = TRUE;\r
3192 }\r
3193 break;\r
3194 case EFI_HII_PACKAGE_FONTS:\r
3195 if (!IsListEmpty (&PackageList->FontPkgHdr)) {\r
3196 Matched = TRUE;\r
3197 }\r
3198 break;\r
3199 case EFI_HII_PACKAGE_IMAGES:\r
3200 if (PackageList->ImagePkg != NULL) {\r
3201 Matched = TRUE;\r
3202 }\r
3203 break;\r
3204 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
3205 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {\r
3206 Matched = TRUE;\r
3207 }\r
3208 break;\r
3209 case EFI_HII_PACKAGE_DEVICE_PATH:\r
3210 if (PackageList->DevicePathPkg != NULL) {\r
3211 Matched = TRUE;\r
3212 }\r
3213 break;\r
3214 //\r
3215 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
3216 // to be listed.\r
3217 //\r
3218 case EFI_HII_PACKAGE_TYPE_ALL:\r
3219 Matched = TRUE;\r
3220 break;\r
3221 default:\r
3222 break;\r
3223 }\r
3224\r
3225 //\r
3226 // This active package list has the specified package type, list it.\r
3227 //\r
3228 if (Matched) {\r
3229 ResultSize += sizeof (EFI_HII_HANDLE);\r
3230 if (ResultSize <= *HandleBufferLength) {\r
3231 *Result++ = Node->Handle;\r
3232 }\r
3233 }\r
3234 Matched = FALSE;\r
3235 }\r
3236\r
3237 if (ResultSize == 0) {\r
3238 return EFI_NOT_FOUND;\r
3239 }\r
3240\r
3241 if (*HandleBufferLength < ResultSize) {\r
3242 *HandleBufferLength = ResultSize;\r
3243 return EFI_BUFFER_TOO_SMALL;\r
3244 }\r
3245\r
3246 *HandleBufferLength = ResultSize;\r
3247 return EFI_SUCCESS;\r
3248}\r
3249\r
3250\r
3251/**\r
3252 This function will export one or all package lists in the database to a buffer.\r
3253 For each package list exported, this function will call functions registered\r
3254 with EXPORT_PACK and then copy the package list to the buffer.\r
3255\r
3256 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3257 instance.\r
3258 @param Handle An EFI_HII_HANDLE that corresponds to the desired\r
3259 package list in the HII database to export or NULL\r
3260 to indicate all package lists should be exported.\r
3261 @param BufferSize On input, a pointer to the length of the buffer.\r
3262 On output, the length of the buffer that is\r
3263 required for the exported data.\r
3264 @param Buffer A pointer to a buffer that will contain the\r
3265 results of the export function.\r
3266\r
3267 @retval EFI_SUCCESS Package exported.\r
3268 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that\r
3269 Handle is too small to support the number of\r
3270 handles. HandleBufferLength is updated with a\r
3271 value that will enable the data to fit.\r
3272 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the\r
3273 current database.\r
c0a3c3da
ED
3274 @retval EFI_INVALID_PARAMETER BufferSize was NULL.\r
3275 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero \r
3276 and Buffer was NULL.\r
93e3992d 3277\r
3278**/\r
3279EFI_STATUS\r
3280EFIAPI\r
3281HiiExportPackageLists (\r
3282 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3283 IN EFI_HII_HANDLE Handle,\r
3284 IN OUT UINTN *BufferSize,\r
3285 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer\r
3286 )\r
3287{\r
3288 LIST_ENTRY *Link;\r
3289 EFI_STATUS Status;\r
3290 HII_DATABASE_PRIVATE_DATA *Private;\r
3291 HII_DATABASE_RECORD *Node;\r
3292 UINTN UsedSize;\r
3293\r
68945618 3294 if (This == NULL || BufferSize == NULL) {\r
93e3992d 3295 return EFI_INVALID_PARAMETER;\r
3296 }\r
3297 if (*BufferSize > 0 && Buffer == NULL) {\r
3298 return EFI_INVALID_PARAMETER;\r
3299 }\r
68945618 3300 if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {\r
93e3992d 3301 return EFI_NOT_FOUND;\r
3302 }\r
3303\r
3304 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3305 UsedSize = 0;\r
3306\r
3307 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3308 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3309 if (Handle == NULL) {\r
3310 //\r
3311 // Export all package lists in current hii database.\r
3312 //\r
3313 Status = ExportPackageList (\r
3314 Private,\r
3315 Node->Handle,\r
3316 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3317 &UsedSize,\r
3318 *BufferSize,\r
3319 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
3320 );\r
3321 ASSERT_EFI_ERROR (Status);\r
6672d625 3322 } else if (Handle != NULL && Node->Handle == Handle) {\r
93e3992d 3323 Status = ExportPackageList (\r
3324 Private,\r
3325 Handle,\r
3326 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),\r
3327 &UsedSize,\r
3328 *BufferSize,\r
3329 Buffer\r
3330 );\r
3331 ASSERT_EFI_ERROR (Status);\r
3332 if (*BufferSize < UsedSize) {\r
3333 *BufferSize = UsedSize;\r
3334 return EFI_BUFFER_TOO_SMALL;\r
3335 }\r
3336 return EFI_SUCCESS;\r
3337 }\r
3338 }\r
3339\r
3340 if (Handle == NULL && UsedSize != 0) {\r
3341 if (*BufferSize < UsedSize) {\r
3342 *BufferSize = UsedSize;\r
3343 return EFI_BUFFER_TOO_SMALL;\r
3344 }\r
3345 return EFI_SUCCESS;\r
3346 }\r
3347\r
3348 return EFI_NOT_FOUND;\r
3349}\r
3350\r
3351\r
3352/**\r
3353 This function registers a function which will be called when specified actions related to packages of\r
3354 the specified type occur in the HII database. By registering a function, other HII-related drivers are\r
3355 notified when specific package types are added, removed or updated in the HII database.\r
3356 Each driver or application which registers a notification should use\r
3357 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.\r
3358\r
3359 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3360 instance.\r
3361 @param PackageType Specifies the package type of the packages to list\r
3362 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be\r
3363 listed.\r
3364 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then\r
3365 this is the pointer to the GUID which must match\r
3366 the Guid field of\r
3367 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must\r
3368 be NULL.\r
3369 @param PackageNotifyFn Points to the function to be called when the event\r
3370 specified by\r
3371 NotificationType occurs.\r
3372 @param NotifyType Describes the types of notification which this\r
3373 function will be receiving.\r
3374 @param NotifyHandle Points to the unique handle assigned to the\r
3375 registered notification. Can be used in\r
3376 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()\r
3377 to stop notifications.\r
3378\r
3379 @retval EFI_SUCCESS Notification registered successfully.\r
3380 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures\r
3381 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.\r
3382 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not\r
3383 EFI_HII_PACKAGE_TYPE_GUID.\r
3384 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is\r
3385 EFI_HII_PACKAGE_TYPE_GUID.\r
3386\r
3387**/\r
3388EFI_STATUS\r
3389EFIAPI\r
3390HiiRegisterPackageNotify (\r
3391 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3392 IN UINT8 PackageType,\r
3393 IN CONST EFI_GUID *PackageGuid,\r
3394 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,\r
3395 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
3396 OUT EFI_HANDLE *NotifyHandle\r
3397 )\r
3398{\r
3399 HII_DATABASE_PRIVATE_DATA *Private;\r
3400 HII_DATABASE_NOTIFY *Notify;\r
3401 EFI_STATUS Status;\r
3402\r
3403 if (This == NULL || NotifyHandle == NULL) {\r
3404 return EFI_INVALID_PARAMETER;\r
3405 }\r
3406 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||\r
3407 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {\r
3408 return EFI_INVALID_PARAMETER;\r
3409 }\r
3410\r
3411 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3412\r
3413 //\r
3414 // Allocate a notification node\r
3415 //\r
3416 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));\r
3417 if (Notify == NULL) {\r
3418 return EFI_OUT_OF_RESOURCES;\r
3419 }\r
3420\r
3421 //\r
3422 // Generate a notify handle\r
3423 //\r
3424 Status = gBS->InstallMultipleProtocolInterfaces (\r
3425 &Notify->NotifyHandle,\r
c8ad2d7a 3426 &gEfiCallerIdGuid,\r
93e3992d 3427 NULL,\r
3428 NULL\r
3429 );\r
3430 ASSERT_EFI_ERROR (Status);\r
3431\r
3432 //\r
3433 // Fill in the information to the notification node\r
3434 //\r
3435 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;\r
3436 Notify->PackageType = PackageType;\r
3437 Notify->PackageGuid = (EFI_GUID *) PackageGuid;\r
3438 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;\r
3439 Notify->NotifyType = NotifyType;\r
3440\r
3441 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);\r
3442 *NotifyHandle = Notify->NotifyHandle;\r
3443\r
3444 return EFI_SUCCESS;\r
3445}\r
3446\r
3447\r
3448/**\r
3449 Removes the specified HII database package-related notification.\r
3450\r
3451 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3452 instance.\r
e90b081a 3453 @param NotificationHandle The handle of the notification function being\r
93e3992d 3454 unregistered.\r
3455\r
3456 @retval EFI_SUCCESS Notification is unregistered successfully.\r
3457 @retval EFI_INVALID_PARAMETER The Handle is invalid.\r
3458 @retval EFI_NOT_FOUND The incoming notification handle does not exist\r
3459 in current hii database.\r
3460\r
3461**/\r
3462EFI_STATUS\r
3463EFIAPI\r
3464HiiUnregisterPackageNotify (\r
3465 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3466 IN EFI_HANDLE NotificationHandle\r
3467 )\r
3468{\r
3469 HII_DATABASE_PRIVATE_DATA *Private;\r
3470 HII_DATABASE_NOTIFY *Notify;\r
3471 LIST_ENTRY *Link;\r
3472 EFI_STATUS Status;\r
3473\r
813acf3a 3474 if (This == NULL) {\r
93e3992d 3475 return EFI_INVALID_PARAMETER;\r
3476 }\r
3477\r
813acf3a 3478 if (NotificationHandle == NULL) {\r
3479 return EFI_NOT_FOUND;\r
3480 }\r
3481\r
93e3992d 3482 Status = gBS->OpenProtocol (\r
3483 NotificationHandle,\r
c8ad2d7a 3484 &gEfiCallerIdGuid,\r
93e3992d 3485 NULL,\r
3486 NULL,\r
3487 NULL,\r
3488 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
3489 );\r
3490 if (EFI_ERROR (Status)) {\r
813acf3a 3491 return EFI_NOT_FOUND;\r
93e3992d 3492 }\r
3493\r
3494 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3495\r
3496 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {\r
3497 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);\r
3498 if (Notify->NotifyHandle == NotificationHandle) {\r
3499 //\r
3500 // Remove the matching notification node\r
3501 //\r
3502 RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
3503 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3504 Notify->NotifyHandle,\r
c8ad2d7a 3505 &gEfiCallerIdGuid,\r
93e3992d 3506 NULL,\r
3507 NULL\r
3508 );\r
3509 ASSERT_EFI_ERROR (Status);\r
676df92c 3510 FreePool (Notify);\r
93e3992d 3511\r
3512 return EFI_SUCCESS;\r
3513 }\r
3514 }\r
3515\r
3516 return EFI_NOT_FOUND;\r
3517}\r
3518\r
3519\r
3520/**\r
3521 This routine retrieves an array of GUID values for each keyboard layout that\r
3522 was previously registered in the system.\r
3523\r
3524 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3525 instance.\r
3526 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard\r
3527 GUID buffer. On output, the length of the handle\r
3528 buffer that is required for the handles found.\r
3529 @param KeyGuidBuffer An array of keyboard layout GUID instances\r
3530 returned.\r
3531\r
3532 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.\r
3533 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates\r
3534 that KeyGuidBuffer is too small to support the\r
3535 number of GUIDs. KeyGuidBufferLength is\r
3536 updated with a value that will enable the data to\r
3537 fit.\r
c0a3c3da
ED
3538 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.\r
3539 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not\r
3540 zero and KeyGuidBuffer is NULL.\r
93e3992d 3541 @retval EFI_NOT_FOUND There was no keyboard layout.\r
3542\r
3543**/\r
3544EFI_STATUS\r
3545EFIAPI\r
3546HiiFindKeyboardLayouts (\r
3547 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3548 IN OUT UINT16 *KeyGuidBufferLength,\r
3549 OUT EFI_GUID *KeyGuidBuffer\r
3550 )\r
3551{\r
3552 HII_DATABASE_PRIVATE_DATA *Private;\r
3553 HII_DATABASE_RECORD *Node;\r
3554 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3555 LIST_ENTRY *Link;\r
3556 LIST_ENTRY *Link1;\r
3557 UINT16 ResultSize;\r
3558 UINTN Index;\r
3559 UINT16 LayoutCount;\r
3560 UINT16 LayoutLength;\r
3561 UINT8 *Layout;\r
3562 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3563\r
3564 if (This == NULL || KeyGuidBufferLength == NULL) {\r
3565 return EFI_INVALID_PARAMETER;\r
3566 }\r
3567\r
3568 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {\r
3569 return EFI_INVALID_PARAMETER;\r
3570 }\r
3571\r
3572 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3573 ResultSize = 0;\r
3574\r
3575 //\r
3576 // Search all package lists in whole database to retrieve keyboard layout.\r
3577 //\r
3578 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3579 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3580 PackageList = Node->PackageList;\r
3581 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3582 Link1 != &PackageList->KeyboardLayoutHdr;\r
3583 Link1 = Link1->ForwardLink\r
3584 ) {\r
3585 //\r
3586 // Find out all Keyboard Layout packages in this package list.\r
3587 //\r
3588 Package = CR (\r
3589 Link1,\r
3590 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3591 KeyboardEntry,\r
3592 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3593 );\r
3594 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3595 CopyMem (\r
3596 &LayoutCount,\r
3597 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),\r
3598 sizeof (UINT16)\r
3599 );\r
3600 for (Index = 0; Index < LayoutCount; Index++) {\r
3601 ResultSize += sizeof (EFI_GUID);\r
3602 if (ResultSize <= *KeyGuidBufferLength) {\r
813acf3a 3603 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));\r
93e3992d 3604 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3605 Layout = Layout + LayoutLength;\r
3606 }\r
3607 }\r
3608 }\r
3609 }\r
3610\r
3611 if (ResultSize == 0) {\r
3612 return EFI_NOT_FOUND;\r
3613 }\r
3614\r
3615 if (*KeyGuidBufferLength < ResultSize) {\r
3616 *KeyGuidBufferLength = ResultSize;\r
3617 return EFI_BUFFER_TOO_SMALL;\r
3618 }\r
3619\r
3620 *KeyGuidBufferLength = ResultSize;\r
3621 return EFI_SUCCESS;\r
3622}\r
3623\r
3624\r
3625/**\r
3626 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys\r
3627 on a keyboard and the character(s) that are associated with a particular set of key strokes.\r
3628\r
3629 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3630 instance.\r
3631 @param KeyGuid A pointer to the unique ID associated with a given\r
3632 keyboard layout. If KeyGuid is NULL then the\r
3633 current layout will be retrieved.\r
3634 @param KeyboardLayoutLength On input, a pointer to the length of the\r
3635 KeyboardLayout buffer. On output, the length of\r
3636 the data placed into KeyboardLayout.\r
3637 @param KeyboardLayout A pointer to a buffer containing the retrieved\r
3638 keyboard layout.\r
3639\r
3640 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.\r
3641 @retval EFI_NOT_FOUND The requested keyboard layout was not found.\r
3642 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was\r
3643 NULL.\r
3644 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates\r
3645 that KeyboardLayout is too small to support the\r
3646 requested keyboard layout. KeyboardLayoutLength is\r
3647 updated with a value that will enable the\r
3648 data to fit.\r
3649\r
3650**/\r
3651EFI_STATUS\r
3652EFIAPI\r
3653HiiGetKeyboardLayout (\r
3654 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3655 IN CONST EFI_GUID *KeyGuid,\r
3656 IN OUT UINT16 *KeyboardLayoutLength,\r
3657 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout\r
3658 )\r
3659{\r
3660 HII_DATABASE_PRIVATE_DATA *Private;\r
3661 HII_DATABASE_RECORD *Node;\r
3662 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;\r
3663 LIST_ENTRY *Link;\r
3664 LIST_ENTRY *Link1;\r
3665 UINTN Index;\r
3666 UINT8 *Layout;\r
3667 UINT16 LayoutCount;\r
3668 UINT16 LayoutLength;\r
3669 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;\r
3670\r
3671 if (This == NULL || KeyboardLayoutLength == NULL) {\r
3672 return EFI_INVALID_PARAMETER;\r
3673 }\r
3674 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {\r
3675 return EFI_INVALID_PARAMETER;\r
3676 }\r
3677\r
3678 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3679 //\r
3680 // Retrieve the current keyboard layout.\r
3681 //\r
3682 if (KeyGuid == NULL) {\r
3683 if (Private->CurrentLayout == NULL) {\r
3684 return EFI_NOT_FOUND;\r
3685 }\r
3686 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));\r
3687 if (*KeyboardLayoutLength < LayoutLength) {\r
3688 *KeyboardLayoutLength = LayoutLength;\r
3689 return EFI_BUFFER_TOO_SMALL;\r
3690 }\r
3691 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);\r
3692 return EFI_SUCCESS;\r
3693 }\r
3694\r
3695 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3696 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3697 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);\r
3698 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;\r
3699 Link1 != &PackageList->KeyboardLayoutHdr;\r
3700 Link1 = Link1->ForwardLink\r
3701 ) {\r
3702 Package = CR (\r
3703 Link1,\r
3704 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,\r
3705 KeyboardEntry,\r
3706 HII_KB_LAYOUT_PACKAGE_SIGNATURE\r
3707 );\r
3708\r
3709 Layout = (UINT8 *) Package->KeyboardPkg +\r
3710 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);\r
3711 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));\r
3712 for (Index = 0; Index < LayoutCount; Index++) {\r
3713 CopyMem (&LayoutLength, Layout, sizeof (UINT16));\r
3714 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {\r
3715 if (LayoutLength <= *KeyboardLayoutLength) {\r
3716 CopyMem (KeyboardLayout, Layout, LayoutLength);\r
3717 return EFI_SUCCESS;\r
3718 } else {\r
3719 *KeyboardLayoutLength = LayoutLength;\r
3720 return EFI_BUFFER_TOO_SMALL;\r
3721 }\r
3722 }\r
3723 Layout = Layout + LayoutLength;\r
3724 }\r
3725 }\r
3726 }\r
3727\r
3728 return EFI_NOT_FOUND;\r
3729}\r
3730\r
3731\r
3732/**\r
3733 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine\r
3734 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
3735 group type. This is so that agents which are sensitive to the current keyboard layout being changed\r
3736 can be notified of this change.\r
3737\r
3738 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3739 instance.\r
3740 @param KeyGuid A pointer to the unique ID associated with a given\r
3741 keyboard layout.\r
3742\r
3743 @retval EFI_SUCCESS The current keyboard layout was successfully set.\r
3744 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so\r
3745 action was taken.\r
3746 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.\r
3747\r
3748**/\r
3749EFI_STATUS\r
3750EFIAPI\r
3751HiiSetKeyboardLayout (\r
3752 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3753 IN CONST EFI_GUID *KeyGuid\r
3754 )\r
3755{\r
3756 HII_DATABASE_PRIVATE_DATA *Private;\r
3757 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
3758 UINT16 KeyboardLayoutLength;\r
3759 EFI_STATUS Status;\r
3760\r
3761 if (This == NULL || KeyGuid == NULL) {\r
3762 return EFI_INVALID_PARAMETER;\r
3763 }\r
3764\r
3765 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3766\r
3767 //\r
3768 // The specified GUID equals the current keyboard layout GUID,\r
3769 // return directly.\r
3770 //\r
3771 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {\r
3772 return EFI_SUCCESS;\r
3773 }\r
3774\r
3775 //\r
3776 // Try to find the incoming keyboard layout data in current database.\r
3777 //\r
3778 KeyboardLayoutLength = 0;\r
3779 KeyboardLayout = NULL;\r
3780 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3781 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3782 return Status;\r
3783 }\r
3784\r
3785 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);\r
3786 ASSERT (KeyboardLayout != NULL);\r
3787 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);\r
3788 ASSERT_EFI_ERROR (Status);\r
3789\r
3790 //\r
3791 // Backup current keyboard layout.\r
3792 //\r
3793 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
676df92c 3794 if (Private->CurrentLayout != NULL) {\r
3795 FreePool(Private->CurrentLayout);\r
3796 }\r
93e3992d 3797 Private->CurrentLayout = KeyboardLayout;\r
3798\r
3799 //\r
3800 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify\r
3801 // current keyboard layout is changed.\r
3802 //\r
3803 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);\r
3804 ASSERT_EFI_ERROR (Status);\r
3805\r
3806 return EFI_SUCCESS;\r
3807}\r
3808\r
3809\r
3810/**\r
3811 Return the EFI handle associated with a package list.\r
3812\r
3813 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL\r
3814 instance.\r
3815 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired\r
3816 package list in the HIIdatabase.\r
3817 @param DriverHandle On return, contains the EFI_HANDLE which was\r
3818 registered with the package list in\r
3819 NewPackageList().\r
3820\r
3821 @retval EFI_SUCCESS The DriverHandle was returned successfully.\r
3822 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or\r
3823 DriverHandle was NULL.\r
3824 @retval EFI_NOT_FOUND This PackageList handle can not be found in\r
3825 current database.\r
3826\r
3827**/\r
3828EFI_STATUS\r
3829EFIAPI\r
3830HiiGetPackageListHandle (\r
3831 IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
3832 IN EFI_HII_HANDLE PackageListHandle,\r
3833 OUT EFI_HANDLE *DriverHandle\r
3834 )\r
3835{\r
3836 HII_DATABASE_PRIVATE_DATA *Private;\r
3837 HII_DATABASE_RECORD *Node;\r
3838 LIST_ENTRY *Link;\r
3839\r
3840 if (This == NULL || DriverHandle == NULL) {\r
3841 return EFI_INVALID_PARAMETER;\r
3842 }\r
3843\r
3844 if (!IsHiiHandleValid (PackageListHandle)) {\r
3845 return EFI_INVALID_PARAMETER;\r
3846 }\r
3847\r
3848 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
3849\r
3850 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
3851 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
3852 if (Node->Handle == PackageListHandle) {\r
3853 *DriverHandle = Node->DriverHandle;\r
3854 return EFI_SUCCESS;\r
3855 }\r
3856 }\r
3857\r
3858 return EFI_NOT_FOUND;\r
3859}\r
3860\r