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