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