]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
Add in supports for platform Setup module which is programmed using Framework HII...
[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 //
140 // We only create a MapEntry if the Uefi Hii Handle is only already registered
141 // by the HII Thunk Layer.
142 //
143 if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {
144 Status = RegisterUefiHiiHandle (Private, Handle);
145 }
146
147 return Status;
148 }
149 EFI_STATUS
150 EFIAPI
151 NewPackNotify (
152 IN UINT8 PackageType,
153 IN CONST EFI_GUID *PackageGuid,
154 IN CONST EFI_HII_PACKAGE_HEADER *Package,
155 IN EFI_HII_HANDLE Handle,
156 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
157 )
158 {
159 EFI_STATUS Status;
160 EFI_HII_THUNK_PRIVATE_DATA *Private;
161
162 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
163 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);
164
165 if (mInFrameworkHiiNewPack) {
166 return EFI_SUCCESS;
167 }
168
169 Status = EFI_SUCCESS;
170 Private = mHiiThunkPrivateData;
171
172 //
173 // We only
174 //
175 if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {
176 Status = RegisterUefiHiiHandle (Private, Handle);
177 }
178
179 return Status;
180 }
181
182 BOOLEAN
183 IsLastStringPack (
184 IN CONST EFI_HII_PACKAGE_HEADER *Package,
185 IN EFI_HII_HANDLE Handle
186 )
187 {
188 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
189 UINTN BufferSize;
190 EFI_STATUS Status;
191 EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
192 EFI_HII_PACKAGE_HEADER PackageHeader;
193 BOOLEAN Match;
194
195 Match = FALSE;
196 HiiPackageList = NULL;
197 BufferSize = 0;
198 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
199 ASSERT (Status != EFI_NOT_FOUND);
200
201 if (Status == EFI_BUFFER_TOO_SMALL) {
202 HiiPackageList = AllocateZeroPool (BufferSize);
203 ASSERT (HiiPackageList != NULL);
204
205 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
206 }
207
208
209 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
210 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
211
212 Status = EFI_SUCCESS;
213
214 while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
215 switch (PackageHeader.Type) {
216 case EFI_HII_PACKAGE_STRINGS:
217 if (CompareMem (Package, PackageHdrPtr, Package->Length) != 0) {
218 FreePool (HiiPackageList);
219 return FALSE;
220 }
221 break;
222 default:
223 break;
224 }
225 //
226 // goto header of next package
227 //
228 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
229 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
230 }
231
232 FreePool (HiiPackageList);
233 return TRUE;
234 }
235
236 EFI_STATUS
237 EFIAPI
238 RemovePackNotify (
239 IN UINT8 PackageType,
240 IN CONST EFI_GUID *PackageGuid,
241 IN CONST EFI_HII_PACKAGE_HEADER *Package,
242 IN EFI_HII_HANDLE Handle,
243 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
244 )
245 {
246 EFI_STATUS Status;
247 EFI_HII_THUNK_PRIVATE_DATA *Private;
248 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;
249
250 Status = EFI_SUCCESS;
251
252 ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
253 ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);
254
255 Private = mHiiThunkPrivateData;
256
257 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, Handle);
258
259 if (MapEntry->FrameworkHiiHandle > Private->StaticHiiHandle) {
260 //
261 // This is a PackageList registered using UEFI HII Protocol Instance.
262 // The MapEntry->TagGuid for this type of PackageList is a auto generated GUID
263 // to link StringPack with IfrPack.
264 // RemovePackNotify is only used to remove PackageList when it is removed by
265 // calling mHiiDatabase->RemovePackageList interface.
266 if (IsLastStringPack (Package, Handle)) {
267 Status = UnRegisterUefiHiiHandle (Private, Handle);
268 }
269 }
270
271 return Status;
272 }
273
274 EFI_STATUS
275 EFIAPI
276 MapUefiHiiHandles (
277 EFI_HII_THUNK_PRIVATE_DATA *Private
278 )
279 {
280 UINTN HandleBufferLength;
281 EFI_HII_HANDLE *HandleBuffer;
282 EFI_STATUS Status;
283 UINTN Index;
284 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;
285
286 HandleBufferLength = 0;
287 HandleBuffer = NULL;
288 Status = mHiiDatabase->ListPackageLists (
289 mHiiDatabase,
290 EFI_HII_PACKAGE_TYPE_ALL,
291 NULL,
292 &HandleBufferLength,
293 HandleBuffer
294 );
295 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
296 return Status;
297 }
298
299 HandleBuffer = AllocateZeroPool (HandleBufferLength);
300 Status = mHiiDatabase->ListPackageLists (
301 mHiiDatabase,
302 EFI_HII_PACKAGE_TYPE_ALL,
303 NULL,
304 &HandleBufferLength,
305 HandleBuffer
306 );
307
308 for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) {
309 MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]);
310 //
311 // Only register those UEFI HII Handles that are registered using the UEFI HII database interface.
312 //
313 if (MapEntry == NULL) {
314 Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]);
315 ASSERT_EFI_ERROR (Status);
316 }
317 }
318
319 return EFI_SUCCESS;
320 }
321
322 EFI_STATUS
323 EFIAPI
324 InitializeHiiDatabase (
325 IN EFI_HANDLE ImageHandle,
326 IN EFI_SYSTEM_TABLE *SystemTable
327 )
328 /*++
329
330 Routine Description:
331 Initialize HII Database
332
333 Arguments:
334 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
335
336 Returns:
337 EFI_SUCCESS - Setup loaded.
338 other - Setup Error
339
340 --*/
341 {
342 EFI_HII_THUNK_PRIVATE_DATA *HiiData;
343 EFI_HANDLE Handle;
344 EFI_STATUS Status;
345
346 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);
347
348 HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);
349 ASSERT (HiiData != NULL);
350 InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead);
351
352 mHiiThunkPrivateData = HiiData;
353
354 Status = gBS->LocateProtocol (
355 &gEfiHiiDatabaseProtocolGuid,
356 NULL,
357 (VOID **) &mHiiDatabase
358 );
359 ASSERT_EFI_ERROR (Status);
360
361 Status = gBS->LocateProtocol (
362 &gEfiHiiFontProtocolGuid,
363 NULL,
364 (VOID **) &mHiiFontProtocol
365 );
366 ASSERT_EFI_ERROR (Status);
367
368 Status = gBS->LocateProtocol (
369 &gEfiHiiImageProtocolGuid,
370 NULL,
371 (VOID **) &mHiiImageProtocol
372 );
373 ASSERT_EFI_ERROR (Status);
374
375 Status = gBS->LocateProtocol (
376 &gEfiHiiStringProtocolGuid,
377 NULL,
378 (VOID **) &mHiiStringProtocol
379 );
380 ASSERT_EFI_ERROR (Status);
381
382 Status = gBS->LocateProtocol (
383 &gEfiHiiConfigRoutingProtocolGuid,
384 NULL,
385 (VOID **) &mHiiConfigRoutingProtocol
386 );
387 ASSERT_EFI_ERROR (Status);
388
389 //
390 // Install protocol interface
391 //
392 Handle = NULL;
393 Status = gBS->InstallProtocolInterface (
394 &HiiData->Handle,
395 &gEfiHiiProtocolGuid,
396 EFI_NATIVE_INTERFACE,
397 (VOID *) &HiiData->Hii
398 );
399 ASSERT_EFI_ERROR (Status);
400
401 Status = MapUefiHiiHandles (HiiData);
402 ASSERT_EFI_ERROR (Status);
403
404 Status = mHiiDatabase->RegisterPackageNotify (
405 mHiiDatabase,
406 EFI_HII_PACKAGE_STRINGS,
407 NULL,
408 NewPackNotify,
409 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
410 &HiiData->NewPackNotifyHandle
411 );
412 ASSERT_EFI_ERROR (Status);
413
414 Status = mHiiDatabase->RegisterPackageNotify (
415 mHiiDatabase,
416 EFI_HII_PACKAGE_STRINGS,
417 NULL,
418 AddPackNotify,
419 EFI_HII_DATABASE_NOTIFY_ADD_PACK,
420 &HiiData->AddPackNotifyHandle
421 );
422 ASSERT_EFI_ERROR (Status);
423
424 Status = mHiiDatabase->RegisterPackageNotify (
425 mHiiDatabase,
426 EFI_HII_PACKAGE_STRINGS,
427 NULL,
428 RemovePackNotify,
429 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
430 &HiiData->RemovePackNotifyHandle
431 );
432 ASSERT_EFI_ERROR (Status);
433
434 return Status;
435 }
436
437 EFI_STATUS
438 EFIAPI
439 HiiFindHandles (
440 IN EFI_HII_PROTOCOL *This,
441 IN OUT UINT16 *HandleBufferLength,
442 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]
443 )
444 /*++
445
446 Routine Description:
447 Determines the handles that are currently active in the database.
448
449 Arguments:
450
451 Returns:
452
453 --*/
454 {
455 UINT16 Count;
456 LIST_ENTRY *ListEntry;
457 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;
458 EFI_HII_THUNK_PRIVATE_DATA *Private;
459
460 if (HandleBufferLength == NULL) {
461 return EFI_INVALID_PARAMETER;
462 }
463
464 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
465
466 Count = 0;
467 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
468 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
469 ListEntry = ListEntry->ForwardLink
470 ) {
471 Count++;
472 }
473
474 if (Count > *HandleBufferLength) {
475 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
476 return EFI_BUFFER_TOO_SMALL;
477 }
478
479 Count = 0;
480 for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;
481 ListEntry != &Private->HiiThunkHandleMappingDBListHead;
482 ListEntry = ListEntry->ForwardLink
483 ) {
484 HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);
485
486 Handle[Count] = HandleMapEntry->FrameworkHiiHandle;
487
488 Count++;
489 }
490
491 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
492 return EFI_SUCCESS;
493 }
494
495 EFI_STATUS
496 EFIAPI
497 HiiGetPrimaryLanguages (
498 IN EFI_HII_PROTOCOL *This,
499 IN FRAMEWORK_EFI_HII_HANDLE Handle,
500 OUT EFI_STRING *LanguageString
501 )
502 /*++
503
504 Routine Description:
505
506 This function allows a program to determine what the primary languages that are supported on a given handle.
507
508 Arguments:
509
510 Returns:
511
512 --*/
513 {
514 EFI_HII_THUNK_PRIVATE_DATA *Private;
515 EFI_HII_HANDLE UefiHiiHandle;
516 CHAR8 *AsciiLanguageCodes;
517 CHAR16 *UnicodeLanguageCodes;
518
519 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
520
521
522
523 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
524 if (UefiHiiHandle == NULL) {
525 return EFI_INVALID_PARAMETER;
526 }
527
528 AsciiLanguageCodes = HiiLibGetSupportedLanguages (UefiHiiHandle);
529
530 if (AsciiLanguageCodes == NULL) {
531 return EFI_INVALID_PARAMETER;
532 }
533
534 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
535 if (UnicodeLanguageCodes == NULL) {
536 return EFI_OUT_OF_RESOURCES;
537 }
538
539 //
540 // The language returned is in RFC 3066 format.
541 //
542 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
543
544 return EFI_SUCCESS;
545 }
546
547 EFI_STATUS
548 EFIAPI
549 HiiGetSecondaryLanguages (
550 IN EFI_HII_PROTOCOL *This,
551 IN FRAMEWORK_EFI_HII_HANDLE Handle,
552 IN CHAR16 *PrimaryLanguage,
553 OUT EFI_STRING *LanguageString
554 )
555 /*++
556
557 Routine Description:
558
559 This function allows a program to determine which secondary languages are supported
560 on a given handle for a given primary language.
561
562 Arguments:
563
564 Returns:
565
566 --*/
567 {
568 EFI_HII_THUNK_PRIVATE_DATA *Private;
569 EFI_HII_HANDLE UefiHiiHandle;
570 CHAR8 *AsciiPrimaryLanguage;
571 CHAR8 *AsciiLanguageCodes;
572 CHAR16 *UnicodeLanguageCodes;
573
574 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
575
576
577
578 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);
579 if (UefiHiiHandle == NULL) {
580 return EFI_INVALID_PARAMETER;
581 }
582
583 AsciiPrimaryLanguage = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
584
585 UnicodeStrToAsciiStr (PrimaryLanguage, AsciiPrimaryLanguage);
586
587 AsciiLanguageCodes = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, AsciiPrimaryLanguage);
588
589 if (AsciiLanguageCodes == NULL) {
590 return EFI_INVALID_PARAMETER;
591 }
592
593 UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));
594 if (UnicodeLanguageCodes == NULL) {
595 return EFI_OUT_OF_RESOURCES;
596 }
597
598 //
599 // The language returned is in RFC 3066 format.
600 //
601 *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);
602
603 return EFI_SUCCESS;
604 }
605
606