]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
Make the module GCC clean.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / HiiDatabase.c
1 /**@file
2 Framework to UEFI 2.1 HII Thunk. The driver consume UEFI HII protocols
3 to produce a Framework HII protocol.
4
5 Copyright (c) 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "HiiDatabase.h"
17
18 EFI_HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;
19
20 EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {
21 //Signature
22 EFI_HII_THUNK_DRIVER_DATA_SIGNATURE
23 ,
24 //Handle
25 (EFI_HANDLE) NULL
26 ,
27 { //Hii
28 HiiNewPack,
29 HiiRemovePack,
30 HiiFindHandles,
31 HiiExportDatabase,
32
33 HiiTestString,
34 HiiGetGlyph,
35 HiiGlyphToBlt,
36
37 HiiNewString,
38 HiiGetPrimaryLanguages,
39 HiiGetSecondaryLanguages,
40 HiiGetString,
41 HiiResetStrings,
42 HiiGetLine,
43 HiiGetForms,
44 HiiGetDefaultImage,
45 HiiUpdateForm,
46
47 HiiGetKeyboardLayout
48 },
49 //StaticHiiHandle
50 //The FRAMEWORK_EFI_HII_HANDLE starts from 1
51 // and increase upwords untill reach the value of StaticPureUefiHiiHandle.
52 // The code will assert to prevent overflow.
53 (FRAMEWORK_EFI_HII_HANDLE) 1
54 ,
55 //StaticPureUefiHiiHandle
56 //The Static FRAMEWORK_EFI_HII_HANDLE starts from 0xFFFF
57 // and decrease downwords untill reach the value of StaticHiiHandle.
58 // The code will assert to prevent overflow.
59 (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF
60 ,
61 {
62 NULL, NULL //HiiHandleLinkList
63 },
64 };
65
66 CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
67 CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;
68 CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
69 CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
70 CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
71
72 EFI_STATUS
73 RegisterUefiHiiHandle (
74 EFI_HII_THUNK_PRIVATE_DATA *Private,
75 EFI_HII_HANDLE UefiHiiHandle
76 )
77 {
78 EFI_STATUS Status;
79 EFI_GUID PackageGuid;
80 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;
81
82 HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));
83 HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;
84
85 Status = AssignPureUefiHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle);
86 if (EFI_ERROR (Status)) {
87 return Status;
88 }
89
90 HandleMappingEntry->UefiHiiHandle = UefiHiiHandle;
91 Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);
92 ASSERT_EFI_ERROR (Status);
93
94 CopyGuid(&HandleMappingEntry->TagGuid, &PackageGuid);
95
96 InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);
97
98 return EFI_SUCCESS;
99 }
100
101
102 EFI_STATUS
103 UnRegisterUefiHiiHandle (
104 EFI_HII_THUNK_PRIVATE_DATA *Private,
105 EFI_HII_HANDLE UefiHiiHandle
106 )
107 {
108 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry;
109
110 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, UefiHiiHandle);
111 ASSERT (MapEntry != NULL);
112
113 RemoveEntryList (&MapEntry->List);
114
115 FreePool (MapEntry);
116
117 return EFI_SUCCESS;
118 }
119
120 EFI_STATUS
121 EFIAPI
122 AddPackNotify (
123 IN UINT8 PackageType,
124 IN CONST EFI_GUID *PackageGuid,
125 IN CONST EFI_HII_PACKAGE_HEADER *Package,
126 IN EFI_HII_HANDLE Handle,
127 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
128 )
129 {
130 EFI_STATUS Status;
131 EFI_HII_THUNK_PRIVATE_DATA *Private;
132
133 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
134 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK);
135
136 Status = EFI_SUCCESS;
137 Private = mHiiThunkPrivateData;
138
139 if (mInFrameworkHiiNewPack) {
140 return EFI_SUCCESS;
141 }
142
143 //
144 // We only create a MapEntry if the Uefi Hii Handle is only already registered
145 // by the HII Thunk Layer.
146 //
147 if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {
148 Status = RegisterUefiHiiHandle (Private, Handle);
149 }
150
151 return Status;
152 }
153 EFI_STATUS
154 EFIAPI
155 NewPackNotify (
156 IN UINT8 PackageType,
157 IN CONST EFI_GUID *PackageGuid,
158 IN CONST EFI_HII_PACKAGE_HEADER *Package,
159 IN EFI_HII_HANDLE Handle,
160 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
161 )
162 {
163 EFI_STATUS Status;
164 EFI_HII_THUNK_PRIVATE_DATA *Private;
165
166 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
167 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);
168
169 if (mInFrameworkHiiNewPack) {
170 return EFI_SUCCESS;
171 }
172
173 Status = EFI_SUCCESS;
174 Private = mHiiThunkPrivateData;
175
176 //
177 // We only
178 //
179 if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {
180 Status = RegisterUefiHiiHandle (Private, Handle);
181 }
182
183 return Status;
184 }
185
186 BOOLEAN
187 IsLastStringPack (
188 IN CONST EFI_HII_PACKAGE_HEADER *Package,
189 IN EFI_HII_HANDLE Handle
190 )
191 {
192 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
193 UINTN BufferSize;
194 EFI_STATUS Status;
195 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
196 EFI_HII_PACKAGE_HEADER PackageHeader;
197 BOOLEAN Match;
198
199 Match = FALSE;
200 HiiPackageList = NULL;
201 BufferSize = 0;
202 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
203 ASSERT (Status != EFI_NOT_FOUND);
204
205 if (Status == EFI_BUFFER_TOO_SMALL) {
206 HiiPackageList = AllocateZeroPool (BufferSize);
207 ASSERT (HiiPackageList != NULL);
208
209 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
210 }
211
212
213 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
214 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
215
216 Status = EFI_SUCCESS;
217
218 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
219 switch (PackageHeader.Type) {
220 case EFI_HII_PACKAGE_STRINGS:
221 if (CompareMem (Package, PackageHdrPtr, Package->Length) != 0) {
222 FreePool (HiiPackageList);
223 return FALSE;
224 }
225 break;
226 default:
227 break;
228 }
229 //
230 // goto header of next package
231 //
232 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
233 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
234 }
235
236 FreePool (HiiPackageList);
237 return TRUE;
238 }
239
240 EFI_STATUS
241 EFIAPI
242 RemovePackNotify (
243 IN UINT8 PackageType,
244 IN CONST EFI_GUID *PackageGuid,
245 IN CONST EFI_HII_PACKAGE_HEADER *Package,
246 IN EFI_HII_HANDLE Handle,
247 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
248 )
249 {
250 EFI_STATUS Status;
251 EFI_HII_THUNK_PRIVATE_DATA *Private;
252 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;
253
254 Status = EFI_SUCCESS;
255
256 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
257 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);
258
259 if (mInFrameworkHiiRemovePack) {
260 return EFI_SUCCESS;
261 }
262
263 Private = mHiiThunkPrivateData;
264
265 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, Handle);
266
267 if (MapEntry->FrameworkHiiHandle > Private->StaticHiiHandle) {
268 //
269 // This is a PackageList registered using UEFI HII Protocol Instance.
270 // The MapEntry->TagGuid for this type of PackageList is a auto generated GUID
271 // to link StringPack with IfrPack.
272 // RemovePackNotify is only used to remove PackageList when it is removed by
273 // calling mHiiDatabase->RemovePackageList interface.
274 if (IsLastStringPack (Package, Handle)) {
275 Status = UnRegisterUefiHiiHandle (Private, Handle);
276 }
277 }
278
279 return Status;
280 }
281
282 EFI_STATUS
283 EFIAPI
284 MapUefiHiiHandles (
285 EFI_HII_THUNK_PRIVATE_DATA *Private
286 )
287 {
288 UINTN HandleBufferLength;
289 EFI_HII_HANDLE *HandleBuffer;
290 EFI_STATUS Status;
291 UINTN Index;
292 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;
293
294 HandleBufferLength = 0;
295 HandleBuffer = NULL;
296 Status = mHiiDatabase->ListPackageLists (
297 mHiiDatabase,
298 EFI_HII_PACKAGE_TYPE_ALL,
299 NULL,
300 &HandleBufferLength,
301 HandleBuffer
302 );
303 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
304 //
305 // As no package is registered to UEFI HII Database, EFI_SUCCESS is returned.
306 //
307 //
308 if (Status == EFI_NOT_FOUND) {
309 return EFI_SUCCESS;
310 } else {
311 return Status;
312 }
313 }
314
315 HandleBuffer = AllocateZeroPool (HandleBufferLength);
316 Status = mHiiDatabase->ListPackageLists (
317 mHiiDatabase,
318 EFI_HII_PACKAGE_TYPE_ALL,
319 NULL,
320 &HandleBufferLength,
321 HandleBuffer
322 );
323
324 for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) {
325 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]);
326 //
327 // Only register those UEFI HII Handles that are registered using the UEFI HII database interface.
328 //
329 if (MapEntry == NULL) {
330 Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]);
331 ASSERT_EFI_ERROR (Status);
332 }
333 }
334
335 return EFI_SUCCESS;
336 }
337
338 EFI_STATUS
339 EFIAPI
340 InitializeHiiDatabase (
341 IN EFI_HANDLE ImageHandle,
342 IN EFI_SYSTEM_TABLE *SystemTable
343 )
344 /*++
345
346 Routine Description:
347 Initialize HII Database
348
349 Arguments:
350 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
351
352 Returns:
353 EFI_SUCCESS - Setup loaded.
354 other - Setup Error
355
356 --*/
357 {
358 EFI_HII_THUNK_PRIVATE_DATA *HiiData;
359 EFI_HANDLE Handle;
360 EFI_STATUS Status;
361
362 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);
363
364 HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);
365 ASSERT (HiiData != NULL);
366 InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead);
367
368 mHiiThunkPrivateData = HiiData;
369
370 Status = gBS->LocateProtocol (
371 &gEfiHiiDatabaseProtocolGuid,
372 NULL,
373 (VOID **) &mHiiDatabase
374 );
375 ASSERT_EFI_ERROR (Status);
376
377 Status = gBS->LocateProtocol (
378 &gEfiHiiFontProtocolGuid,
379 NULL,
380 (VOID **) &mHiiFontProtocol
381 );
382 ASSERT_EFI_ERROR (Status);
383
384 Status = gBS->LocateProtocol (
385 &gEfiHiiImageProtocolGuid,
386 NULL,
387 (VOID **) &mHiiImageProtocol
388 );
389 ASSERT_EFI_ERROR (Status);
390
391 Status = gBS->LocateProtocol (
392 &gEfiHiiStringProtocolGuid,
393 NULL,
394 (VOID **) &mHiiStringProtocol
395 );
396 ASSERT_EFI_ERROR (Status);
397
398 Status = gBS->LocateProtocol (
399 &gEfiHiiConfigRoutingProtocolGuid,
400 NULL,
401 (VOID **) &mHiiConfigRoutingProtocol
402 );
403 ASSERT_EFI_ERROR (Status);
404
405 //
406 // Install protocol interface
407 //
408 Handle = NULL;
409 Status = gBS->InstallProtocolInterface (
410 &HiiData->Handle,
411 &gEfiHiiProtocolGuid,
412 EFI_NATIVE_INTERFACE,
413 (VOID *) &HiiData->Hii
414 );
415 ASSERT_EFI_ERROR (Status);
416
417 Status = MapUefiHiiHandles (HiiData);
418 ASSERT_EFI_ERROR (Status);
419
420 Status = mHiiDatabase->RegisterPackageNotify (
421 mHiiDatabase,
422 EFI_HII_PACKAGE_STRINGS,
423 NULL,
424 NewPackNotify,
425 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
426 &HiiData->NewPackNotifyHandle
427 );
428 ASSERT_EFI_ERROR (Status);
429
430 Status = mHiiDatabase->RegisterPackageNotify (
431 mHiiDatabase,
432 EFI_HII_PACKAGE_STRINGS,
433 NULL,
434 AddPackNotify,
435 EFI_HII_DATABASE_NOTIFY_ADD_PACK,
436 &HiiData->AddPackNotifyHandle
437 );
438 ASSERT_EFI_ERROR (Status);
439
440 Status = mHiiDatabase->RegisterPackageNotify (
441 mHiiDatabase,
442 EFI_HII_PACKAGE_STRINGS,
443 NULL,
444 RemovePackNotify,
445 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
446 &HiiData->RemovePackNotifyHandle
447 );
448 ASSERT_EFI_ERROR (Status);
449
450 return Status;
451 }
452
453 EFI_STATUS
454 EFIAPI
455 HiiFindHandles (
456 IN EFI_HII_PROTOCOL *This,
457 IN OUT UINT16 *HandleBufferLength,
458 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]
459 )
460 /*++
461
462 Routine Description:
463 Determines the handles that are currently active in the database.
464
465 Arguments:
466
467 Returns:
468
469 --*/
470 {
471 UINT16 Count;
472 LIST_ENTRY *ListEntry;
473 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;
474 EFI_HII_THUNK_PRIVATE_DATA *Private;
475
476 if (HandleBufferLength == NULL) {
477 return EFI_INVALID_PARAMETER;
478 }
479
480 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
481
482 Count = 0;
483 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
484 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
485 ListEntry = ListEntry->ForwardLink
486 ) {
487 Count++;
488 }
489
490 if (Count > *HandleBufferLength) {
491 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
492 return EFI_BUFFER_TOO_SMALL;
493 }
494
495 Count = 0;
496 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
497 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
498 ListEntry = ListEntry->ForwardLink
499 ) {
500 HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);
501
502 Handle[Count] = HandleMapEntry->FrameworkHiiHandle;
503
504 Count++;
505 }
506
507 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
508 return EFI_SUCCESS;
509 }
510
511 EFI_STATUS
512 EFIAPI
513 HiiGetPrimaryLanguages (
514 IN EFI_HII_PROTOCOL *This,
515 IN FRAMEWORK_EFI_HII_HANDLE Handle,
516 OUT EFI_STRING *LanguageString
517 )
518 /*++
519
520 Routine Description:
521
522 This function allows a program to determine what the primary languages that are supported on a given handle.
523
524 Arguments:
525
526 Returns:
527
528 --*/
529 {
530 EFI_HII_THUNK_PRIVATE_DATA *Private;
531 EFI_HII_HANDLE UefiHiiHandle;
532 CHAR8 *AsciiLanguageCodes;
533 CHAR16 *UnicodeLanguageCodes;
534
535 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
536
537
538
539 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
540 if (UefiHiiHandle == NULL) {
541 return EFI_INVALID_PARAMETER;
542 }
543
544 AsciiLanguageCodes = HiiLibGetSupportedLanguages (UefiHiiHandle);
545
546 if (AsciiLanguageCodes == NULL) {
547 return EFI_INVALID_PARAMETER;
548 }
549
550 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
551 if (UnicodeLanguageCodes == NULL) {
552 return EFI_OUT_OF_RESOURCES;
553 }
554
555 //
556 // The language returned is in RFC 3066 format.
557 //
558 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
559
560 return EFI_SUCCESS;
561 }
562
563 EFI_STATUS
564 EFIAPI
565 HiiGetSecondaryLanguages (
566 IN EFI_HII_PROTOCOL *This,
567 IN FRAMEWORK_EFI_HII_HANDLE Handle,
568 IN CHAR16 *PrimaryLanguage,
569 OUT EFI_STRING *LanguageString
570 )
571 /*++
572
573 Routine Description:
574
575 This function allows a program to determine which secondary languages are supported
576 on a given handle for a given primary language.
577
578 Arguments:
579
580 Returns:
581
582 --*/
583 {
584 EFI_HII_THUNK_PRIVATE_DATA *Private;
585 EFI_HII_HANDLE UefiHiiHandle;
586 CHAR8 *AsciiPrimaryLanguage;
587 CHAR8 *AsciiLanguageCodes;
588 CHAR16 *UnicodeLanguageCodes;
589
590 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
591
592
593
594 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
595 if (UefiHiiHandle == NULL) {
596 return EFI_INVALID_PARAMETER;
597 }
598
599 AsciiPrimaryLanguage = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
600
601 UnicodeStrToAsciiStr (PrimaryLanguage, AsciiPrimaryLanguage);
602
603 AsciiLanguageCodes = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, AsciiPrimaryLanguage);
604
605 if (AsciiLanguageCodes == NULL) {
606 return EFI_INVALID_PARAMETER;
607 }
608
609 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
610 if (UnicodeLanguageCodes == NULL) {
611 return EFI_OUT_OF_RESOURCES;
612 }
613
614 //
615 // The language returned is in RFC 3066 format.
616 //
617 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
618
619 return EFI_SUCCESS;
620 }
621
622