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