]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/HiiDatabase.c
Fix some inconsistencies in EFIAPI usage.
[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, Intel Corporation\r
6All rights reserved. This 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 HiiGetString,\r
38 HiiResetStrings,\r
39 HiiGetLine,\r
40 HiiGetForms,\r
41 HiiGetDefaultImage,\r
42 HiiUpdateForm,\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 = HiiLibListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer);\r
160 if (Status == EFI_SUCCESS) {\r
161 for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) {\r
162 ThunkContext = CreateThunkContextForUefiHiiHandle (Buffer[Index]);\r
163 ASSERT (ThunkContext!= NULL);\r
164 \r
165 InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
166 }\r
167\r
168 FreePool (Buffer);\r
169 }\r
170\r
171 Status = mHiiDatabase->RegisterPackageNotify (\r
172 mHiiDatabase,\r
173 EFI_HII_PACKAGE_STRINGS,\r
174 NULL,\r
175 NewOrAddPackNotify,\r
176 EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
177 &Handle\r
178 );\r
179 ASSERT_EFI_ERROR (Status);\r
180\r
181 Status = mHiiDatabase->RegisterPackageNotify (\r
182 mHiiDatabase,\r
183 EFI_HII_PACKAGE_STRINGS,\r
184 NULL,\r
185 NewOrAddPackNotify,\r
186 EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
187 &Handle\r
188 );\r
189 ASSERT_EFI_ERROR (Status);\r
190\r
191 Status = mHiiDatabase->RegisterPackageNotify (\r
192 mHiiDatabase,\r
193 EFI_HII_PACKAGE_FORMS,\r
194 NULL,\r
195 NewOrAddPackNotify,\r
196 EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
197 &Handle\r
198 );\r
199 ASSERT_EFI_ERROR (Status);\r
200\r
201 Status = mHiiDatabase->RegisterPackageNotify (\r
202 mHiiDatabase,\r
203 EFI_HII_PACKAGE_FORMS,\r
204 NULL,\r
205 NewOrAddPackNotify,\r
206 EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
207 &Handle\r
208 );\r
209 ASSERT_EFI_ERROR (Status);\r
210\r
211 Status = mHiiDatabase->RegisterPackageNotify (\r
212 mHiiDatabase,\r
213 EFI_HII_PACKAGE_STRINGS,\r
214 NULL,\r
215 RemovePackNotify,\r
216 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
217 &Handle\r
218 );\r
219 ASSERT_EFI_ERROR (Status);\r
220\r
221 InitSetBrowserStrings ();\r
222\r
223 mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;\r
224 Status = gBS->InstallProtocolInterface (\r
225 &mBrowserThunkPrivateDataTemplate.Handle,\r
226 &gEfiFormBrowserCompatibilityProtocolGuid,\r
227 EFI_NATIVE_INTERFACE,\r
228 (VOID *) &mBrowserThunkPrivateDataTemplate.FormBrowser\r
229 );\r
230 ASSERT_EFI_ERROR (Status);\r
231 \r
232 return Status;\r
233}\r
234\r
235/**\r
236 Determines the handles that are currently active in the database.\r
237\r
238 This function determines the handles that are currently active in the database. \r
239 For example, a program wishing to create a Setup-like configuration utility would use this call \r
240 to determine the handles that are available. It would then use calls defined in the forms section \r
241 below to extract forms and then interpret them.\r
242\r
243 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
244 @param HandleBufferLength On input, a pointer to the length of the handle buffer. \r
245 On output, the length of the handle buffer that is required for the handles found.\r
246 @param Handle An array of EFI_HII_HANDLE instances returned. \r
247 Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
248\r
249 @retval EFI_SUCCESS Handle was updated successfully.\r
250 \r
251 @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates that Handle is too small \r
252 to support the number of handles. HandleBufferLength is updated with a value that \r
253 will enable the data to fit.\r
254**/\r
255EFI_STATUS\r
256EFIAPI\r
257HiiFindHandles (\r
258 IN EFI_HII_PROTOCOL *This,\r
259 IN OUT UINT16 *HandleBufferLength,\r
260 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]\r
261 )\r
262{\r
263 UINT16 Count;\r
264 LIST_ENTRY *Link;\r
265 HII_THUNK_CONTEXT *ThunkContext;\r
266 HII_THUNK_PRIVATE_DATA *Private;\r
267\r
268 if (HandleBufferLength == NULL) {\r
269 return EFI_INVALID_PARAMETER;\r
270 }\r
271\r
272 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); \r
273\r
274 //\r
275 // Count the number of handles.\r
276 //\r
277 Count = 0;\r
278 Link = GetFirstNode (&Private->ThunkContextListHead);\r
279 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
280 Count++;\r
281 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
282 }\r
283\r
284 if (Count > *HandleBufferLength) {\r
285 *HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
286 return EFI_BUFFER_TOO_SMALL;\r
287 }\r
288\r
289 //\r
290 // Output the handles.\r
291 //\r
292 Count = 0;\r
293 Link = GetFirstNode (&Private->ThunkContextListHead);\r
294 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
295\r
296 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
297 Handle[Count] = ThunkContext->FwHiiHandle;\r
298\r
299 Count++;\r
300 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
301\r
302 }\r
303\r
304 *HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
305 return EFI_SUCCESS;\r
306}\r
307\r
308EFI_STATUS\r
309LangCodes3066To639 (\r
310 IN CHAR8 *LangCodes3066,\r
311 IN CHAR8 **LangCodes639\r
312 )\r
313{\r
314 CHAR8 *AsciiLangCodes;\r
315 CHAR8 *Lang;\r
316 UINTN Index;\r
317 UINTN Count;\r
318 EFI_STATUS Status;\r
319\r
320 ASSERT (LangCodes3066 != NULL);\r
321 ASSERT (LangCodes639 != NULL);\r
322 \r
323 //\r
324 // Allocate working buffer to contain substring of LangCodes3066.\r
325 //\r
326 Lang = AllocatePool (AsciiStrSize (LangCodes3066));\r
327 if (Lang == NULL) {\r
328 return EFI_OUT_OF_RESOURCES;\r
329 }\r
330\r
331 //\r
332 // Count the number of RFC 3066 language codes.\r
333 //\r
334 Index = 0;\r
335 AsciiLangCodes = LangCodes3066;\r
336 while (AsciiStrLen (AsciiLangCodes) != 0) {\r
337 HiiLibGetNextLanguage (&AsciiLangCodes, Lang);\r
338 Index++;\r
339 }\r
340\r
341 Count = Index;\r
342\r
343 //\r
344 // \r
345 //\r
346 *LangCodes639 = AllocateZeroPool (ISO_639_2_ENTRY_SIZE * Count + 1);\r
347 if (*LangCodes639 == NULL) {\r
348 Status = EFI_OUT_OF_RESOURCES;\r
349 goto Done;\r
350 }\r
351\r
352 AsciiLangCodes = LangCodes3066;\r
353\r
354 for (Index = 0; Index < Count; Index++) {\r
355 HiiLibGetNextLanguage (&AsciiLangCodes, Lang);\r
356 Status = ConvertRfc3066LanguageToIso639Language (Lang, *LangCodes639 + Index * ISO_639_2_ENTRY_SIZE);\r
357 ASSERT_EFI_ERROR (Status);\r
358 }\r
359\r
360 Status = EFI_SUCCESS;\r
361\r
362Done:\r
363 FreePool (Lang);\r
364 return Status;\r
365}\r
366\r
367/**\r
368 Allows a program to determine the primary languages that are supported on a given handle.\r
369\r
370 This routine is intended to be used by drivers to query the interface database for supported languages. \r
371 This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.\r
372\r
373 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
374 @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() \r
375 in the Packages section.\r
376 @param LanguageString A string allocated by GetPrimaryLanguages() that contains a list of all primary languages \r
377 registered on the handle. The routine will not return the three-spaces language identifier used in \r
378 other functions to indicate non-language-specific strings.\r
379\r
380 @reval EFI_SUCCESS LanguageString was correctly returned.\r
381 \r
382 @reval EFI_INVALID_PARAMETER The Handle was unknown.\r
383**/\r
384EFI_STATUS\r
385EFIAPI\r
386HiiGetPrimaryLanguages (\r
387 IN EFI_HII_PROTOCOL *This,\r
388 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
389 OUT EFI_STRING *LanguageString\r
390 )\r
391{\r
392 HII_THUNK_PRIVATE_DATA *Private;\r
393 EFI_HII_HANDLE UefiHiiHandle;\r
394 CHAR8 *LangCodes3066;\r
395 CHAR16 *UnicodeLangCodes639;\r
396 CHAR8 *LangCodes639;\r
397 EFI_STATUS Status;\r
398\r
399 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
400\r
401 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
402 if (UefiHiiHandle == NULL) {\r
403 return EFI_INVALID_PARAMETER;\r
404 }\r
405\r
406 LangCodes3066 = HiiLibGetSupportedLanguages (UefiHiiHandle);\r
407\r
408 if (LangCodes3066 == NULL) {\r
409 return EFI_INVALID_PARAMETER;\r
410 }\r
411\r
412\r
413 LangCodes639 = NULL;\r
414 Status = LangCodes3066To639 (LangCodes3066, &LangCodes639);\r
415 if (EFI_ERROR (Status)) {\r
416 goto Done;\r
417 }\r
418 \r
419 UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));\r
420 if (UnicodeLangCodes639 == NULL) {\r
421 Status = EFI_OUT_OF_RESOURCES;\r
422 goto Done;\r
423 }\r
424\r
425 //\r
426 // The language returned is in RFC 639-2 format.\r
427 //\r
428 AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);\r
429 *LanguageString = UnicodeLangCodes639;\r
430\r
431Done:\r
432 FreePool (LangCodes3066);\r
433 if (LangCodes639 != NULL) {\r
434 FreePool (LangCodes639);\r
435 }\r
436\r
437 return Status;\r
438}\r
439\r
440\r
441/**\r
442 Allows a program to determine which secondary languages are supported on a given handle for a given primary language\r
443\r
444 This routine is intended to be used by drivers to query the interface database for supported languages. \r
445 This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.\r
446\r
447 @param This A pointer to the EFI_HII_PROTOCOL instance.\r
448 @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() \r
449 in the Packages section.\r
450 @param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating \r
451 the primary language.\r
452 @param LanguageString A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered \r
453 on the handle. The routine will not return the three-spaces language identifier used in other functions \r
454 to indicate non-language-specific strings, nor will it return the primary language. This function succeeds \r
455 but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and \r
456 PrimaryLanguage pair. Type EFI_STRING is defined in String.\r
457 \r
458 @reval EFI_SUCCESS LanguageString was correctly returned.\r
459 @reval EFI_INVALID_PARAMETER The Handle was unknown.\r
460**/\r
461EFI_STATUS\r
462EFIAPI\r
463HiiGetSecondaryLanguages (\r
464 IN EFI_HII_PROTOCOL *This,\r
465 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
466 IN CHAR16 *PrimaryLanguage,\r
467 OUT EFI_STRING *LanguageString\r
468 )\r
469{\r
470 HII_THUNK_PRIVATE_DATA *Private;\r
471 EFI_HII_HANDLE UefiHiiHandle;\r
472 CHAR8 *PrimaryLang3066;\r
473 CHAR8 *PrimaryLang639;\r
474 CHAR8 *SecLangCodes3066;\r
475 CHAR8 *SecLangCodes639;\r
476 CHAR16 *UnicodeSecLangCodes639;\r
477 EFI_STATUS Status;\r
478\r
479 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
480\r
481 SecLangCodes639 = NULL;\r
482 SecLangCodes3066 = NULL;\r
483 PrimaryLang3066 = NULL;\r
484 UnicodeSecLangCodes639 = NULL;\r
485\r
486 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
487 if (UefiHiiHandle == NULL) {\r
488 return EFI_INVALID_PARAMETER;\r
489 }\r
490\r
491 PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);\r
492 if (PrimaryLang639 == NULL) {\r
493 Status = EFI_OUT_OF_RESOURCES;\r
494 goto Done;\r
495 }\r
496\r
497 UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);\r
498\r
499 PrimaryLang3066 = ConvertIso639LanguageToRfc3066Language (PrimaryLang639);\r
500 ASSERT_EFI_ERROR (PrimaryLang3066 != NULL);\r
501\r
502 SecLangCodes3066 = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang3066);\r
503\r
504 if (SecLangCodes3066 == NULL) {\r
505 Status = EFI_INVALID_PARAMETER;\r
506 goto Done;\r
507 }\r
508\r
509 Status = LangCodes3066To639 (SecLangCodes3066, &SecLangCodes639);\r
510 if (EFI_ERROR (Status)) {\r
511 goto Done;\r
512 }\r
513\r
514 UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));\r
515 if (UnicodeSecLangCodes639 == NULL) {\r
516 Status = EFI_OUT_OF_RESOURCES;\r
517 goto Done;\r
518 }\r
519\r
520 //\r
521 // The language returned is in RFC 3066 format.\r
522 //\r
523 *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);\r
524\r
525Done:\r
526 if (PrimaryLang639 != NULL) {\r
527 FreePool (PrimaryLang639);\r
528 }\r
529\r
530 if (SecLangCodes639 != NULL) {\r
531 FreePool (SecLangCodes639);\r
532 }\r
533\r
534 if (PrimaryLang3066 != NULL) {\r
535 FreePool (PrimaryLang3066);\r
536 }\r
537\r
538 if (SecLangCodes3066 != NULL) {\r
539 FreePool (SecLangCodes3066);\r
540 }\r
541 if (UnicodeSecLangCodes639 != NULL) {\r
542 FreePool (UnicodeSecLangCodes639);\r
543 }\r
544 \r
545 return Status;\r
546}\r
547\r
548 \r