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