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