]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/HiiDatabase.c
Merge branch 'master' of https://github.com/tianocore/edk2
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / HiiDatabase.c
... / ...
CommitLineData
1/** @file\r
2Framework to UEFI 2.1 HII Thunk. The driver consume UEFI HII protocols\r
3to produce a Framework HII protocol.\r
4\r
5Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "HiiDatabase.h"\r
17#include "HiiHandle.h"\r
18\r
19HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;\r
20\r
21HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {\r
22 HII_THUNK_PRIVATE_DATA_SIGNATURE,\r
23 (EFI_HANDLE) NULL,\r
24 {\r
25 HiiNewPack,\r
26 HiiRemovePack,\r
27 HiiFindHandles,\r
28 HiiExportDatabase,\r
29 \r
30 HiiTestString,\r
31 HiiGetGlyph,\r
32 HiiGlyphToBlt,\r
33 \r
34 HiiNewString,\r
35 HiiGetPrimaryLanguages,\r
36 HiiGetSecondaryLanguages,\r
37 HiiThunkGetString,\r
38 HiiResetStrings,\r
39 HiiGetLine,\r
40 HiiGetForms,\r
41 HiiGetDefaultImage,\r
42 HiiThunkUpdateForm,\r
43 \r
44 HiiGetKeyboardLayout\r
45 },\r
46\r
47 {\r
48 ///\r
49 /// HiiHandleLinkList\r
50 ///\r
51 NULL, NULL \r
52 },\r
53};\r
54\r
55EFI_FORMBROWSER_THUNK_PRIVATE_DATA mBrowserThunkPrivateDataTemplate = {\r
56 EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE,\r
57 (EFI_HANDLE) NULL,\r
58 (HII_THUNK_PRIVATE_DATA *) NULL,\r
59 {\r
60 ThunkSendForm,\r
61 ThunkCreatePopUp\r
62 }\r
63};\r
64\r
65\r
66CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
67CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
68CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
69CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;\r
70CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
71CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2Protocol;\r
72\r
73\r
74/**\r
75 This routine initializes the HII Database.\r
76 \r
77 @param ImageHandle Image handle for PCD DXE driver.\r
78 @param SystemTable Pointer to SystemTable.\r
79\r
80 @retval EFI_SUCCESS The entry point alwasy return successfully.\r
81**/\r
82EFI_STATUS\r
83EFIAPI\r
84InitializeHiiDatabase (\r
85 IN EFI_HANDLE ImageHandle,\r
86 IN EFI_SYSTEM_TABLE *SystemTable\r
87 )\r
88{\r
89 HII_THUNK_PRIVATE_DATA *Private;\r
90 EFI_HANDLE Handle;\r
91 EFI_STATUS Status;\r
92 UINTN BufferLength;\r
93 EFI_HII_HANDLE *Buffer;\r
94 UINTN Index;\r
95 HII_THUNK_CONTEXT *ThunkContext;\r
96 \r
97\r
98 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiCompatibilityProtocolGuid);\r
99 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiFormBrowserCompatibilityProtocolGuid);\r
100\r
101 Private = AllocateCopyPool (sizeof (HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);\r
102 ASSERT (Private != NULL);\r
103 InitializeListHead (&Private->ThunkContextListHead);\r
104\r
105 InitHiiHandleDatabase ();\r
106\r
107 mHiiThunkPrivateData = Private;\r
108\r
109 Status = gBS->LocateProtocol (\r
110 &gEfiHiiDatabaseProtocolGuid,\r
111 NULL,\r
112 (VOID **) &mHiiDatabase\r
113 );\r
114 ASSERT_EFI_ERROR (Status);\r
115\r
116 Status = gBS->LocateProtocol (\r
117 &gEfiHiiStringProtocolGuid,\r
118 NULL,\r
119 (VOID **) &mHiiStringProtocol\r
120 );\r
121 ASSERT_EFI_ERROR (Status);\r
122\r
123 Status = gBS->LocateProtocol (\r
124 &gEfiHiiFontProtocolGuid,\r
125 NULL,\r
126 (VOID **) &mHiiFontProtocol\r
127 );\r
128 ASSERT_EFI_ERROR (Status);\r
129\r
130 Status = gBS->LocateProtocol (\r
131 &gEfiHiiConfigRoutingProtocolGuid,\r
132 NULL,\r
133 (VOID **) &mHiiConfigRoutingProtocol\r
134 );\r
135 ASSERT_EFI_ERROR (Status);\r
136\r
137\r
138 Status = gBS->LocateProtocol (\r
139 &gEfiFormBrowser2ProtocolGuid,\r
140 NULL,\r
141 (VOID **) &mFormBrowser2Protocol\r
142 );\r
143 ASSERT_EFI_ERROR (Status);\r
144\r
145\r
146 \r
147\r
148 //\r
149 // Install protocol interface\r
150 //\r
151 Status = gBS->InstallProtocolInterface (\r
152 &Private->Handle,\r
153 &gEfiHiiCompatibilityProtocolGuid,\r
154 EFI_NATIVE_INTERFACE,\r
155 (VOID *) &Private->Hii\r
156 );\r
157 ASSERT_EFI_ERROR (Status);\r
158\r
159 Status = ListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer);\r
160 if (Status == EFI_SUCCESS) {\r
161 ASSERT (Buffer != NULL);\r
162 for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) {\r
163 ThunkContext = CreateThunkContextForUefiHiiHandle (Buffer[Index]);\r
164 ASSERT (ThunkContext!= NULL);\r
165 \r
166 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
167 }\r
168\r
169 FreePool (Buffer);\r
170 }\r
171\r
172 Status = mHiiDatabase->RegisterPackageNotify (\r
173 mHiiDatabase,\r
174 EFI_HII_PACKAGE_STRINGS,\r
175 NULL,\r
176 NewOrAddPackNotify,\r
177 EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
178 &Handle\r
179 );\r
180 ASSERT_EFI_ERROR (Status);\r
181\r
182 Status = mHiiDatabase->RegisterPackageNotify (\r
183 mHiiDatabase,\r
184 EFI_HII_PACKAGE_STRINGS,\r
185 NULL,\r
186 NewOrAddPackNotify,\r
187 EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
188 &Handle\r
189 );\r
190 ASSERT_EFI_ERROR (Status);\r
191\r
192 Status = mHiiDatabase->RegisterPackageNotify (\r
193 mHiiDatabase,\r
194 EFI_HII_PACKAGE_FORMS,\r
195 NULL,\r
196 NewOrAddPackNotify,\r
197 EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
198 &Handle\r
199 );\r
200 ASSERT_EFI_ERROR (Status);\r
201\r
202 Status = mHiiDatabase->RegisterPackageNotify (\r
203 mHiiDatabase,\r
204 EFI_HII_PACKAGE_FORMS,\r
205 NULL,\r
206 NewOrAddPackNotify,\r
207 EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
208 &Handle\r
209 );\r
210 ASSERT_EFI_ERROR (Status);\r
211\r
212 Status = mHiiDatabase->RegisterPackageNotify (\r
213 mHiiDatabase,\r
214 EFI_HII_PACKAGE_STRINGS,\r
215 NULL,\r
216 RemovePackNotify,\r
217 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
218 &Handle\r
219 );\r
220 ASSERT_EFI_ERROR (Status);\r
221\r
222 InitSetBrowserStrings ();\r
223\r
224 mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;\r
225 Status = gBS->InstallProtocolInterface (\r
226 &mBrowserThunkPrivateDataTemplate.Handle,\r
227 &gEfiFormBrowserCompatibilityProtocolGuid,\r
228 EFI_NATIVE_INTERFACE,\r
229 (VOID *) &mBrowserThunkPrivateDataTemplate.FormBrowser\r
230 );\r
231 ASSERT_EFI_ERROR (Status);\r
232 \r
233 return Status;\r
234}\r
235\r
236/**\r
237 Determines the handles that are currently active in the database.\r
238\r
239 This function determines the handles that are currently active in the database. \r
240 For example, a program wishing to create a Setup-like configuration utility would use this call \r
241 to determine the handles that are available. It would then use calls defined in the forms section \r
242 below to extract forms and then interpret them.\r
243\r
244 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
245 @param HandleBufferLength On input, a pointer to the length of the handle buffer. \r
246 On output, the length of the handle buffer that is required for the handles found.\r
247 @param Handle Pointer to an array of EFI_HII_HANDLE instances returned. \r
248 Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
249\r
250 @retval EFI_SUCCESS Handle was updated successfully.\r
251 \r
252 @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates that Handle is too small \r
253 to support the number of handles. HandleBufferLength is updated with a value that \r
254 will enable the data to fit.\r
255**/\r
256EFI_STATUS\r
257EFIAPI\r
258HiiFindHandles (\r
259 IN EFI_HII_PROTOCOL *This,\r
260 IN OUT UINT16 *HandleBufferLength,\r
261 OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
262 )\r
263{\r
264 UINT16 Count;\r
265 LIST_ENTRY *Link;\r
266 HII_THUNK_CONTEXT *ThunkContext;\r
267 HII_THUNK_PRIVATE_DATA *Private;\r
268\r
269 if (HandleBufferLength == NULL) {\r
270 return EFI_INVALID_PARAMETER;\r
271 }\r
272\r
273 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); \r
274\r
275 //\r
276 // Count the number of handles.\r
277 //\r
278 Count = 0;\r
279 Link = GetFirstNode (&Private->ThunkContextListHead);\r
280 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
281 Count++;\r
282 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
283 }\r
284\r
285 if (Count > *HandleBufferLength) {\r
286 *HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
287 return EFI_BUFFER_TOO_SMALL;\r
288 }\r
289\r
290 //\r
291 // Output the handles.\r
292 //\r
293 Count = 0;\r
294 Link = GetFirstNode (&Private->ThunkContextListHead);\r
295 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
296\r
297 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
298 Handle[Count] = ThunkContext->FwHiiHandle;\r
299\r
300 Count++;\r
301 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
302\r
303 }\r
304\r
305 *HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
306 return EFI_SUCCESS;\r
307}\r
308\r
309/**\r
310 Allows a program to determine the primary languages that are supported on a given handle.\r
311\r
312 This routine is intended to be used by drivers to query the interface database for supported languages. \r
313 This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.\r
314\r
315 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
316 @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() \r
317 in the Packages section.\r
318 @param LanguageString A string allocated by GetPrimaryLanguages() that contains a list of all primary languages \r
319 registered on the handle. The routine will not return the three-spaces language identifier used in \r
320 other functions to indicate non-language-specific strings.\r
321\r
322 @retval EFI_SUCCESS LanguageString was correctly returned.\r
323 \r
324 @retval EFI_INVALID_PARAMETER The Handle was unknown.\r
325**/\r
326EFI_STATUS\r
327EFIAPI\r
328HiiGetPrimaryLanguages (\r
329 IN EFI_HII_PROTOCOL *This,\r
330 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
331 OUT EFI_STRING *LanguageString\r
332 )\r
333{\r
334 HII_THUNK_PRIVATE_DATA *Private;\r
335 EFI_HII_HANDLE UefiHiiHandle;\r
336 CHAR8 *LangCodes4646;\r
337 CHAR16 *UnicodeLangCodes639;\r
338 CHAR8 *LangCodes639;\r
339 EFI_STATUS Status;\r
340\r
341 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
342\r
343 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
344 if (UefiHiiHandle == NULL) {\r
345 return EFI_INVALID_PARAMETER;\r
346 }\r
347\r
348 LangCodes4646 = HiiGetSupportedLanguages (UefiHiiHandle);\r
349\r
350 if (LangCodes4646 == NULL) {\r
351 return EFI_INVALID_PARAMETER;\r
352 }\r
353\r
354 LangCodes639 = ConvertLanguagesRfc4646ToIso639 (LangCodes4646);\r
355 if (LangCodes639 == NULL) {\r
356 Status = EFI_INVALID_PARAMETER;\r
357 goto Done;\r
358 }\r
359 \r
360 UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));\r
361 if (UnicodeLangCodes639 == NULL) {\r
362 Status = EFI_OUT_OF_RESOURCES;\r
363 goto Done;\r
364 }\r
365\r
366 //\r
367 // The language returned is in RFC 639-2 format.\r
368 //\r
369 AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);\r
370 *LanguageString = UnicodeLangCodes639;\r
371 Status = EFI_SUCCESS;\r
372\r
373Done:\r
374 FreePool (LangCodes4646);\r
375 if (LangCodes639 != NULL) {\r
376 FreePool (LangCodes639);\r
377 }\r
378\r
379 return Status;\r
380}\r
381\r
382/**\r
383 This function returns the list of supported 2nd languages, in the format specified\r
384 in UEFI specification Appendix M.\r
385\r
386 If HiiHandle is not a valid Handle in the HII database, then ASSERT.\r
387 If not enough resource to complete the operation, then ASSERT.\r
388\r
389 @param HiiHandle The HII package list handle.\r
390 @param PrimaryLanguage Pointer to language name buffer.\r
391 \r
392 @return The supported languages.\r
393\r
394**/\r
395CHAR8 *\r
396EFIAPI\r
397HiiGetSupportedSecondaryLanguages (\r
398 IN EFI_HII_HANDLE HiiHandle,\r
399 IN CONST CHAR8 *PrimaryLanguage\r
400 )\r
401{\r
402 EFI_STATUS Status;\r
403 UINTN BufferSize;\r
404 CHAR8 *LanguageString;\r
405\r
406 ASSERT (HiiHandle != NULL);\r
407\r
408 //\r
409 // Collect current supported 2nd Languages for given HII handle\r
410 // First try allocate 4K buffer to store the current supported 2nd languages.\r
411 //\r
412 BufferSize = 0x1000;\r
413 LanguageString = AllocateZeroPool (BufferSize);\r
414 if (LanguageString == NULL) {\r
415 return NULL;\r
416 }\r
417\r
418 Status = mHiiStringProtocol->GetSecondaryLanguages (mHiiStringProtocol, HiiHandle, PrimaryLanguage, LanguageString, &BufferSize);\r
419 ASSERT (Status != EFI_NOT_FOUND);\r
420 \r
421 if (Status == EFI_BUFFER_TOO_SMALL) {\r
422 FreePool (LanguageString);\r
423 LanguageString = AllocateZeroPool (BufferSize);\r
424 if (LanguageString == NULL) {\r
425 return NULL;\r
426 }\r
427\r
428 Status = mHiiStringProtocol->GetSecondaryLanguages (mHiiStringProtocol, HiiHandle, PrimaryLanguage, LanguageString, &BufferSize);\r
429 }\r
430\r
431 if (EFI_ERROR (Status)) {\r
432 LanguageString = NULL;\r
433 }\r
434\r
435 return LanguageString;\r
436}\r
437\r
438/**\r
439 Allows a program to determine which secondary languages are supported on a given handle for a given primary language\r
440\r
441 This routine is intended to be used by drivers to query the interface database for supported languages. \r
442 This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.\r
443\r
444 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
445 @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() \r
446 in the Packages section.\r
447 @param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating \r
448 the primary language.\r
449 @param LanguageString A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered \r
450 on the handle. The routine will not return the three-spaces language identifier used in other functions \r
451 to indicate non-language-specific strings, nor will it return the primary language. This function succeeds \r
452 but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and \r
453 PrimaryLanguage pair. Type EFI_STRING is defined in String.\r
454 \r
455 @retval EFI_SUCCESS LanguageString was correctly returned.\r
456 @retval EFI_INVALID_PARAMETER The Handle was unknown.\r
457**/\r
458EFI_STATUS\r
459EFIAPI\r
460HiiGetSecondaryLanguages (\r
461 IN EFI_HII_PROTOCOL *This,\r
462 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
463 IN CHAR16 *PrimaryLanguage,\r
464 OUT EFI_STRING *LanguageString\r
465 )\r
466{\r
467 HII_THUNK_PRIVATE_DATA *Private;\r
468 EFI_HII_HANDLE UefiHiiHandle;\r
469 CHAR8 *PrimaryLang4646;\r
470 CHAR8 *PrimaryLang639;\r
471 CHAR8 *SecLangCodes4646;\r
472 CHAR8 *SecLangCodes639;\r
473 CHAR16 *UnicodeSecLangCodes639;\r
474 EFI_STATUS Status;\r
475\r
476 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
477\r
478 SecLangCodes639 = NULL;\r
479 SecLangCodes4646 = NULL;\r
480 PrimaryLang4646 = NULL;\r
481 UnicodeSecLangCodes639 = NULL;\r
482\r
483 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
484 if (UefiHiiHandle == NULL) {\r
485 return EFI_INVALID_PARAMETER;\r
486 }\r
487\r
488 PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);\r
489 if (PrimaryLang639 == NULL) {\r
490 Status = EFI_OUT_OF_RESOURCES;\r
491 goto Done;\r
492 }\r
493\r
494 UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);\r
495\r
496 PrimaryLang4646 = ConvertLanguagesIso639ToRfc4646 (PrimaryLang639);\r
497 ASSERT (PrimaryLang4646 != NULL);\r
498\r
499 SecLangCodes4646 = HiiGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang4646);\r
500\r
501 if (SecLangCodes4646 == NULL) {\r
502 Status = EFI_INVALID_PARAMETER;\r
503 goto Done;\r
504 }\r
505\r
506 SecLangCodes639 = ConvertLanguagesIso639ToRfc4646 (SecLangCodes4646);\r
507 if (SecLangCodes639 == NULL) {\r
508 Status = EFI_INVALID_PARAMETER;\r
509 goto Done;\r
510 }\r
511\r
512 UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));\r
513 if (UnicodeSecLangCodes639 == NULL) {\r
514 Status = EFI_OUT_OF_RESOURCES;\r
515 goto Done;\r
516 }\r
517\r
518 //\r
519 // The language returned is in RFC 4646 format.\r
520 //\r
521 *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);\r
522 Status = EFI_SUCCESS;\r
523\r
524Done:\r
525 if (PrimaryLang639 != NULL) {\r
526 FreePool (PrimaryLang639);\r
527 }\r
528\r
529 if (SecLangCodes639 != NULL) {\r
530 FreePool (SecLangCodes639);\r
531 }\r
532\r
533 if (PrimaryLang4646 != NULL) {\r
534 FreePool (PrimaryLang4646);\r
535 }\r
536\r
537 if (SecLangCodes4646 != NULL) {\r
538 FreePool (SecLangCodes4646);\r
539 }\r
540 if (UnicodeSecLangCodes639 != NULL) {\r
541 FreePool (UnicodeSecLangCodes639);\r
542 }\r
543 \r
544 return Status;\r
545}\r
546\r