]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
1) Fix a bug. Before this fix, a Module that calling UEFI HII Interface to get the...
[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 return Status;
305 }
306
307 HandleBuffer = AllocateZeroPool (HandleBufferLength);
308 Status = mHiiDatabase->ListPackageLists (
309 mHiiDatabase,
310 EFI_HII_PACKAGE_TYPE_ALL,
311 NULL,
312 &HandleBufferLength,
313 HandleBuffer
314 );
315
316 for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) {
317 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]);
318 //
319 // Only register those UEFI HII Handles that are registered using the UEFI HII database interface.
320 //
321 if (MapEntry == NULL) {
322 Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]);
323 ASSERT_EFI_ERROR (Status);
324 }
325 }
326
327 return EFI_SUCCESS;
328 }
329
330 EFI_STATUS
331 EFIAPI
332 InitializeHiiDatabase (
333 IN EFI_HANDLE ImageHandle,
334 IN EFI_SYSTEM_TABLE *SystemTable
335 )
336 /*++
337
338 Routine Description:
339 Initialize HII Database
340
341 Arguments:
342 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
343
344 Returns:
345 EFI_SUCCESS - Setup loaded.
346 other - Setup Error
347
348 --*/
349 {
350 EFI_HII_THUNK_PRIVATE_DATA *HiiData;
351 EFI_HANDLE Handle;
352 EFI_STATUS Status;
353
354 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);
355
356 HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);
357 ASSERT (HiiData != NULL);
358 InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead);
359
360 mHiiThunkPrivateData = HiiData;
361
362 Status = gBS->LocateProtocol (
363 &gEfiHiiDatabaseProtocolGuid,
364 NULL,
365 (VOID **) &mHiiDatabase
366 );
367 ASSERT_EFI_ERROR (Status);
368
369 Status = gBS->LocateProtocol (
370 &gEfiHiiFontProtocolGuid,
371 NULL,
372 (VOID **) &mHiiFontProtocol
373 );
374 ASSERT_EFI_ERROR (Status);
375
376 Status = gBS->LocateProtocol (
377 &gEfiHiiImageProtocolGuid,
378 NULL,
379 (VOID **) &mHiiImageProtocol
380 );
381 ASSERT_EFI_ERROR (Status);
382
383 Status = gBS->LocateProtocol (
384 &gEfiHiiStringProtocolGuid,
385 NULL,
386 (VOID **) &mHiiStringProtocol
387 );
388 ASSERT_EFI_ERROR (Status);
389
390 Status = gBS->LocateProtocol (
391 &gEfiHiiConfigRoutingProtocolGuid,
392 NULL,
393 (VOID **) &mHiiConfigRoutingProtocol
394 );
395 ASSERT_EFI_ERROR (Status);
396
397 //
398 // Install protocol interface
399 //
400 Handle = NULL;
401 Status = gBS->InstallProtocolInterface (
402 &HiiData->Handle,
403 &gEfiHiiProtocolGuid,
404 EFI_NATIVE_INTERFACE,
405 (VOID *) &HiiData->Hii
406 );
407 ASSERT_EFI_ERROR (Status);
408
409 Status = MapUefiHiiHandles (HiiData);
410 ASSERT_EFI_ERROR (Status);
411
412 Status = mHiiDatabase->RegisterPackageNotify (
413 mHiiDatabase,
414 EFI_HII_PACKAGE_STRINGS,
415 NULL,
416 NewPackNotify,
417 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
418 &HiiData->NewPackNotifyHandle
419 );
420 ASSERT_EFI_ERROR (Status);
421
422 Status = mHiiDatabase->RegisterPackageNotify (
423 mHiiDatabase,
424 EFI_HII_PACKAGE_STRINGS,
425 NULL,
426 AddPackNotify,
427 EFI_HII_DATABASE_NOTIFY_ADD_PACK,
428 &HiiData->AddPackNotifyHandle
429 );
430 ASSERT_EFI_ERROR (Status);
431
432 Status = mHiiDatabase->RegisterPackageNotify (
433 mHiiDatabase,
434 EFI_HII_PACKAGE_STRINGS,
435 NULL,
436 RemovePackNotify,
437 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
438 &HiiData->RemovePackNotifyHandle
439 );
440 ASSERT_EFI_ERROR (Status);
441
442 return Status;
443 }
444
445 EFI_STATUS
446 EFIAPI
447 HiiFindHandles (
448 IN EFI_HII_PROTOCOL *This,
449 IN OUT UINT16 *HandleBufferLength,
450 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]
451 )
452 /*++
453
454 Routine Description:
455 Determines the handles that are currently active in the database.
456
457 Arguments:
458
459 Returns:
460
461 --*/
462 {
463 UINT16 Count;
464 LIST_ENTRY *ListEntry;
465 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;
466 EFI_HII_THUNK_PRIVATE_DATA *Private;
467
468 if (HandleBufferLength == NULL) {
469 return EFI_INVALID_PARAMETER;
470 }
471
472 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
473
474 Count = 0;
475 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
476 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
477 ListEntry = ListEntry->ForwardLink
478 ) {
479 Count++;
480 }
481
482 if (Count > *HandleBufferLength) {
483 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
484 return EFI_BUFFER_TOO_SMALL;
485 }
486
487 Count = 0;
488 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
489 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
490 ListEntry = ListEntry->ForwardLink
491 ) {
492 HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);
493
494 Handle[Count] = HandleMapEntry->FrameworkHiiHandle;
495
496 Count++;
497 }
498
499 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
500 return EFI_SUCCESS;
501 }
502
503 EFI_STATUS
504 EFIAPI
505 HiiGetPrimaryLanguages (
506 IN EFI_HII_PROTOCOL *This,
507 IN FRAMEWORK_EFI_HII_HANDLE Handle,
508 OUT EFI_STRING *LanguageString
509 )
510 /*++
511
512 Routine Description:
513
514 This function allows a program to determine what the primary languages that are supported on a given handle.
515
516 Arguments:
517
518 Returns:
519
520 --*/
521 {
522 EFI_HII_THUNK_PRIVATE_DATA *Private;
523 EFI_HII_HANDLE UefiHiiHandle;
524 CHAR8 *AsciiLanguageCodes;
525 CHAR16 *UnicodeLanguageCodes;
526
527 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
528
529
530
531 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
532 if (UefiHiiHandle == NULL) {
533 return EFI_INVALID_PARAMETER;
534 }
535
536 AsciiLanguageCodes = HiiLibGetSupportedLanguages (UefiHiiHandle);
537
538 if (AsciiLanguageCodes == NULL) {
539 return EFI_INVALID_PARAMETER;
540 }
541
542 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
543 if (UnicodeLanguageCodes == NULL) {
544 return EFI_OUT_OF_RESOURCES;
545 }
546
547 //
548 // The language returned is in RFC 3066 format.
549 //
550 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
551
552 return EFI_SUCCESS;
553 }
554
555 EFI_STATUS
556 EFIAPI
557 HiiGetSecondaryLanguages (
558 IN EFI_HII_PROTOCOL *This,
559 IN FRAMEWORK_EFI_HII_HANDLE Handle,
560 IN CHAR16 *PrimaryLanguage,
561 OUT EFI_STRING *LanguageString
562 )
563 /*++
564
565 Routine Description:
566
567 This function allows a program to determine which secondary languages are supported
568 on a given handle for a given primary language.
569
570 Arguments:
571
572 Returns:
573
574 --*/
575 {
576 EFI_HII_THUNK_PRIVATE_DATA *Private;
577 EFI_HII_HANDLE UefiHiiHandle;
578 CHAR8 *AsciiPrimaryLanguage;
579 CHAR8 *AsciiLanguageCodes;
580 CHAR16 *UnicodeLanguageCodes;
581
582 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
583
584
585
586 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
587 if (UefiHiiHandle == NULL) {
588 return EFI_INVALID_PARAMETER;
589 }
590
591 AsciiPrimaryLanguage = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
592
593 UnicodeStrToAsciiStr (PrimaryLanguage, AsciiPrimaryLanguage);
594
595 AsciiLanguageCodes = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, AsciiPrimaryLanguage);
596
597 if (AsciiLanguageCodes == NULL) {
598 return EFI_INVALID_PARAMETER;
599 }
600
601 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
602 if (UnicodeLanguageCodes == NULL) {
603 return EFI_OUT_OF_RESOURCES;
604 }
605
606 //
607 // The language returned is in RFC 3066 format.
608 //
609 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
610
611 return EFI_SUCCESS;
612 }
613
614