]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[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 HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;
19
20 HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {
21 HII_THUNK_PRIVATE_DATA_SIGNATURE,
22 (EFI_HANDLE) NULL,
23 {
24 HiiNewPack,
25 HiiRemovePack,
26 HiiFindHandles,
27 HiiExportDatabase,
28
29 HiiTestString,
30 HiiGetGlyph,
31 HiiGlyphToBlt,
32
33 HiiNewString,
34 HiiGetPrimaryLanguages,
35 HiiGetSecondaryLanguages,
36 HiiGetString,
37 HiiResetStrings,
38 HiiGetLine,
39 HiiGetForms,
40 HiiGetDefaultImage,
41 HiiUpdateForm,
42
43 HiiGetKeyboardLayout
44 },
45
46 //
47 //StaticHiiHandle
48 //The FRAMEWORK_EFI_HII_HANDLE starts from 1
49 // and increase upwords untill reach the value of StaticPureUefiHiiHandle.
50 // The code will assert to prevent overflow.
51 (FRAMEWORK_EFI_HII_HANDLE) 1,
52
53 //
54 //StaticPureUefiHiiHandle
55 //The Static FRAMEWORK_EFI_HII_HANDLE starts from 0xFFFF
56 // and decrease downwords untill reach the value of StaticHiiHandle.
57 // The code will assert to prevent overflow.
58 //
59 (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF,
60 {
61 NULL, NULL //HiiHandleLinkList
62 },
63 };
64
65 EFI_FORMBROWSER_THUNK_PRIVATE_DATA mBrowserThunkPrivateDataTemplate = {
66 EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE,
67 (EFI_HANDLE) NULL,
68 (HII_THUNK_PRIVATE_DATA *) NULL,
69 {
70 ThunkSendForm,
71 ThunkCreatePopUp
72 }
73 };
74
75
76 CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
77 CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
78 CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
79 CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
80 CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2Protocol;
81
82
83
84
85
86
87 EFI_STATUS
88 EFIAPI
89 InitializeHiiDatabase (
90 IN EFI_HANDLE ImageHandle,
91 IN EFI_SYSTEM_TABLE *SystemTable
92 )
93 /*++
94
95 Routine Description:
96 Initialize HII Database
97
98 Arguments:
99 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
100
101 Returns:
102 EFI_SUCCESS - Setup loaded.
103 other - Setup Error
104
105 --*/
106 {
107 HII_THUNK_PRIVATE_DATA *Private;
108 EFI_HANDLE Handle;
109 EFI_STATUS Status;
110 UINTN BufferLength;
111 EFI_HII_HANDLE *Buffer;
112 UINTN Index;
113
114
115 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);
116
117 Private = AllocateCopyPool (sizeof (HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);
118 ASSERT (Private != NULL);
119 InitializeListHead (&Private->ThunkContextListHead);
120
121 mHiiThunkPrivateData = Private;
122
123 Status = gBS->LocateProtocol (
124 &gEfiHiiDatabaseProtocolGuid,
125 NULL,
126 (VOID **) &mHiiDatabase
127 );
128 ASSERT_EFI_ERROR (Status);
129
130 Status = gBS->LocateProtocol (
131 &gEfiHiiStringProtocolGuid,
132 NULL,
133 (VOID **) &mHiiStringProtocol
134 );
135 ASSERT_EFI_ERROR (Status);
136
137 Status = gBS->LocateProtocol (
138 &gEfiHiiConfigRoutingProtocolGuid,
139 NULL,
140 (VOID **) &mHiiConfigRoutingProtocol
141 );
142 ASSERT_EFI_ERROR (Status);
143
144
145 Status = gBS->LocateProtocol (
146 &gEfiFormBrowser2ProtocolGuid,
147 NULL,
148 (VOID **) &mFormBrowser2Protocol
149 );
150 ASSERT_EFI_ERROR (Status);
151
152
153
154
155 //
156 // Install protocol interface
157 //
158 Status = gBS->InstallProtocolInterface (
159 &Private->Handle,
160 &gEfiHiiProtocolGuid,
161 EFI_NATIVE_INTERFACE,
162 (VOID *) &Private->Hii
163 );
164 ASSERT_EFI_ERROR (Status);
165
166 Status = HiiLibListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer);
167 if (Status == EFI_SUCCESS) {
168 for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) {
169 CreateThunkContextForUefiHiiHandle (Private, Buffer[Index]);
170 ASSERT_EFI_ERROR (Status);
171 }
172
173 FreePool (Buffer);
174 }
175
176 Status = mHiiDatabase->RegisterPackageNotify (
177 mHiiDatabase,
178 EFI_HII_PACKAGE_STRINGS,
179 NULL,
180 NewOrAddPackNotify,
181 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
182 &Handle
183 );
184 ASSERT_EFI_ERROR (Status);
185
186 Status = mHiiDatabase->RegisterPackageNotify (
187 mHiiDatabase,
188 EFI_HII_PACKAGE_STRINGS,
189 NULL,
190 NewOrAddPackNotify,
191 EFI_HII_DATABASE_NOTIFY_ADD_PACK,
192 &Handle
193 );
194 ASSERT_EFI_ERROR (Status);
195
196 Status = mHiiDatabase->RegisterPackageNotify (
197 mHiiDatabase,
198 EFI_HII_PACKAGE_FORM,
199 NULL,
200 NewOrAddPackNotify,
201 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
202 &Handle
203 );
204 ASSERT_EFI_ERROR (Status);
205
206 Status = mHiiDatabase->RegisterPackageNotify (
207 mHiiDatabase,
208 EFI_HII_PACKAGE_FORM,
209 NULL,
210 NewOrAddPackNotify,
211 EFI_HII_DATABASE_NOTIFY_ADD_PACK,
212 &Handle
213 );
214 ASSERT_EFI_ERROR (Status);
215
216 Status = mHiiDatabase->RegisterPackageNotify (
217 mHiiDatabase,
218 EFI_HII_PACKAGE_STRINGS,
219 NULL,
220 RemovePackNotify,
221 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
222 &Handle
223 );
224 ASSERT_EFI_ERROR (Status);
225
226 mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;
227 Status = gBS->InstallProtocolInterface (
228 &mBrowserThunkPrivateDataTemplate.Handle,
229 &gEfiFormBrowserProtocolGuid,
230 EFI_NATIVE_INTERFACE,
231 (VOID *) &mBrowserThunkPrivateDataTemplate.FormBrowser
232 );
233 ASSERT_EFI_ERROR (Status);
234
235 return Status;
236 }
237
238 EFI_STATUS
239 EFIAPI
240 HiiFindHandles (
241 IN EFI_HII_PROTOCOL *This,
242 IN OUT UINT16 *HandleBufferLength,
243 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]
244 )
245 /*++
246
247 Routine Description:
248 Determines the handles that are currently active in the database.
249
250 Arguments:
251
252 Returns:
253
254 --*/
255 {
256 UINT16 Count;
257 LIST_ENTRY *Link;
258 HII_THUNK_CONTEXT *ThunkContext;
259 HII_THUNK_PRIVATE_DATA *Private;
260
261 if (HandleBufferLength == NULL) {
262 return EFI_INVALID_PARAMETER;
263 }
264
265 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
266
267 //
268 // Count the number of handles.
269 //
270 Count = 0;
271 Link = GetFirstNode (&Private->ThunkContextListHead);
272 while (!IsNull (&Private->ThunkContextListHead, Link)) {
273 Count++;
274 Link = GetNextNode (&Private->ThunkContextListHead, Link);
275 }
276
277 if (Count > *HandleBufferLength) {
278 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
279 return EFI_BUFFER_TOO_SMALL;
280 }
281
282 //
283 // Output the handles.
284 //
285 Count = 0;
286 Link = GetFirstNode (&Private->ThunkContextListHead);
287 while (!IsNull (&Private->ThunkContextListHead, Link)) {
288
289 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
290 Handle[Count] = ThunkContext->FwHiiHandle;
291
292 Count++;
293 Link = GetNextNode (&Private->ThunkContextListHead, Link);
294
295 }
296
297 *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
298 return EFI_SUCCESS;
299 }
300
301 EFI_STATUS
302 LangCodes3066To639 (
303 IN CHAR8 *LangCodes3066,
304 IN CHAR8 **LangCodes639
305 )
306 {
307 CHAR8 *AsciiLangCodes;
308 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
309 UINTN Index;
310 UINTN Count;
311 EFI_STATUS Status;
312
313 ASSERT (LangCodes3066 != NULL);
314 ASSERT (LangCodes639 != NULL);
315
316 //
317 // Count the number of RFC 3066 language codes.
318 //
319 Index = 0;
320 AsciiLangCodes = LangCodes3066;
321 while (AsciiStrLen (AsciiLangCodes) != 0) {
322 HiiLibGetNextLanguage (&AsciiLangCodes, Lang);
323 Index++;
324 }
325
326 Count = Index;
327
328 //
329 //
330 //
331 *LangCodes639 = AllocateZeroPool (ISO_639_2_ENTRY_SIZE * Count + 1);
332 if (*LangCodes639 == NULL) {
333 return EFI_OUT_OF_RESOURCES;
334 }
335
336 AsciiLangCodes = LangCodes3066;
337
338 for (Index = 0; Index < Count; Index++) {
339 HiiLibGetNextLanguage (&AsciiLangCodes, Lang);
340 Status = ConvertRfc3066LanguageToIso639Language (Lang, *LangCodes639 + Index * ISO_639_2_ENTRY_SIZE);
341 ASSERT_EFI_ERROR (Status);
342 }
343
344 return EFI_SUCCESS;
345 }
346
347 EFI_STATUS
348 EFIAPI
349 HiiGetPrimaryLanguages (
350 IN EFI_HII_PROTOCOL *This,
351 IN FRAMEWORK_EFI_HII_HANDLE Handle,
352 OUT EFI_STRING *LanguageString
353 )
354 /*++
355
356 Routine Description:
357
358 This function allows a program to determine what the primary languages that are supported on a given handle.
359
360 Arguments:
361
362 Returns:
363
364 --*/
365 {
366 HII_THUNK_PRIVATE_DATA *Private;
367 EFI_HII_HANDLE UefiHiiHandle;
368 CHAR8 *LangCodes3066;
369 CHAR16 *UnicodeLangCodes639;
370 CHAR8 *LangCodes639;
371 EFI_STATUS Status;
372
373 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
374
375 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
376 if (UefiHiiHandle == NULL) {
377 return EFI_INVALID_PARAMETER;
378 }
379
380 LangCodes3066 = HiiLibGetSupportedLanguages (UefiHiiHandle);
381
382 if (LangCodes3066 == NULL) {
383 return EFI_INVALID_PARAMETER;
384 }
385
386
387 LangCodes639 = NULL;
388 Status = LangCodes3066To639 (LangCodes3066, &LangCodes639);
389 if (EFI_ERROR (Status)) {
390 goto Done;
391 }
392
393 UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));
394 if (UnicodeLangCodes639 == NULL) {
395 Status = EFI_OUT_OF_RESOURCES;
396 goto Done;
397 }
398
399 //
400 // The language returned is in RFC 639-2 format.
401 //
402 AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);
403 *LanguageString = UnicodeLangCodes639;
404
405 Done:
406 FreePool (LangCodes3066);
407 SafeFreePool (LangCodes639);
408
409 return Status;
410 }
411
412
413
414 EFI_STATUS
415 EFIAPI
416 HiiGetSecondaryLanguages (
417 IN EFI_HII_PROTOCOL *This,
418 IN FRAMEWORK_EFI_HII_HANDLE Handle,
419 IN CHAR16 *PrimaryLanguage,
420 OUT EFI_STRING *LanguageString
421 )
422 /*++
423
424 Routine Description:
425
426 This function allows a program to determine which secondary languages are supported
427 on a given handle for a given primary language.
428
429 Arguments:
430
431 Returns:
432
433 --*/
434 {
435 HII_THUNK_PRIVATE_DATA *Private;
436 EFI_HII_HANDLE UefiHiiHandle;
437 CHAR8 PrimaryLang3066[RFC_3066_ENTRY_SIZE];
438 CHAR8 *PrimaryLang639;
439 CHAR8 *SecLangCodes3066;
440 CHAR8 *SecLangCodes639;
441 CHAR16 *UnicodeSecLangCodes639;
442 EFI_STATUS Status;
443
444 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
445
446 SecLangCodes639 = NULL;
447 SecLangCodes3066 = NULL;
448 UnicodeSecLangCodes639 = NULL;
449
450 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
451 if (UefiHiiHandle == NULL) {
452 return EFI_INVALID_PARAMETER;
453 }
454
455 PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
456 if (PrimaryLang639 == NULL) {
457 Status = EFI_OUT_OF_RESOURCES;
458 goto Done;
459 }
460
461 UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);
462
463 Status = ConvertIso639LanguageToRfc3066Language (PrimaryLang639, PrimaryLang3066);
464 ASSERT_EFI_ERROR (Status);
465
466 SecLangCodes3066 = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang3066);
467
468 if (SecLangCodes3066 == NULL) {
469 Status = EFI_INVALID_PARAMETER;
470 goto Done;
471 }
472
473 Status = LangCodes3066To639 (SecLangCodes3066, &SecLangCodes639);
474 if (EFI_ERROR (Status)) {
475 goto Done;
476 }
477
478 UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));
479 if (UnicodeSecLangCodes639 == NULL) {
480 Status = EFI_OUT_OF_RESOURCES;
481 goto Done;
482 }
483
484 //
485 // The language returned is in RFC 3066 format.
486 //
487 *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);
488
489 Done:
490
491 SafeFreePool (PrimaryLang639);
492 SafeFreePool (SecLangCodes639);
493 SafeFreePool (SecLangCodes3066);
494 SafeFreePool (UnicodeSecLangCodes639);
495
496 return Status;
497 }
498
499