]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / HiiDataBaseDxe / HiiDatabase.c
CommitLineData
3db51098 1/**@file\r
2\r
3 This file contains the keyboard processing code to the HII database.\r
103b6520 4\r
3db51098 5Copyright (c) 2006, Intel Corporation\r
ececc2eb 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
3db51098 9http://opensource.org/licenses/bsd-license.php\r
10\r
ececc2eb 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
103b6520 13\r
3db51098 14**/\r
103b6520 15\r
103b6520 16#include "HiiDatabase.h"\r
17\r
18EFI_STATUS\r
19EFIAPI\r
20InitializeHiiDatabase (\r
21 IN EFI_HANDLE ImageHandle,\r
22 IN EFI_SYSTEM_TABLE *SystemTable\r
23 )\r
24/*++\r
25\r
26Routine Description:\r
27 Initialize HII Database\r
ececc2eb 28\r
103b6520 29Arguments:\r
30 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
31\r
ececc2eb 32Returns:\r
103b6520 33 EFI_SUCCESS - Setup loaded.\r
34 other - Setup Error\r
35\r
36--*/\r
37{\r
38 EFI_STATUS Status;\r
39 EFI_HII_DATA *HiiData;\r
40 EFI_HII_GLOBAL_DATA *GlobalData;\r
41 EFI_HANDLE *HandleBuffer;\r
42 EFI_HANDLE Handle;\r
43 UINTN HandleCount;\r
44 UINTN Index;\r
45\r
46 //\r
47 // There will be only one HII Database in the system\r
48 // If there is another out there, someone is trying to install us\r
49 // again. Fail that scenario.\r
50 //\r
51 Status = gBS->LocateHandleBuffer (\r
52 ByProtocol,\r
53 &gEfiHiiProtocolGuid,\r
54 NULL,\r
55 &HandleCount,\r
56 &HandleBuffer\r
57 );\r
58\r
59 //\r
60 // If there was no error, assume there is an installation and fail to load\r
61 //\r
62 if (!EFI_ERROR (Status)) {\r
63 if (HandleBuffer != NULL) {\r
64 FreePool (HandleBuffer);\r
65 }\r
66\r
67 return EFI_DEVICE_ERROR;\r
68 }\r
69\r
70 HiiData = AllocatePool (sizeof (EFI_HII_DATA));\r
71\r
72 ASSERT (HiiData);\r
73\r
74 GlobalData = AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA));\r
75\r
76 ASSERT (GlobalData);\r
77\r
78 //\r
79 // Seed the Font Database with a known non-character glyph\r
80 //\r
81 for (Index = 0; Index <= MAX_GLYPH_COUNT; Index++) {\r
82 //\r
83 // Seeding the UnicodeWeight with 0 signifies that it is uninitialized\r
84 //\r
85 GlobalData->NarrowGlyphs[Index].UnicodeWeight = 0;\r
86 GlobalData->WideGlyphs[Index].UnicodeWeight = 0;\r
87 GlobalData->NarrowGlyphs[Index].Attributes = 0;\r
88 GlobalData->WideGlyphs[Index].Attributes = 0;\r
89 CopyMem (GlobalData->NarrowGlyphs[Index].GlyphCol1, &mUnknownGlyph, NARROW_GLYPH_ARRAY_SIZE);\r
90 CopyMem (GlobalData->WideGlyphs[Index].GlyphCol1, &mUnknownGlyph, WIDE_GLYPH_ARRAY_SIZE);\r
91 }\r
92 //\r
93 // Fill in HII data\r
94 //\r
95 HiiData->Signature = EFI_HII_DATA_SIGNATURE;\r
96 HiiData->GlobalData = GlobalData;\r
97 HiiData->GlobalData->SystemKeyboardUpdate = FALSE;\r
98 HiiData->DatabaseHead = NULL;\r
99 HiiData->Hii.NewPack = HiiNewPack;\r
100 HiiData->Hii.RemovePack = HiiRemovePack;\r
101 HiiData->Hii.FindHandles = HiiFindHandles;\r
102 HiiData->Hii.ExportDatabase = HiiExportDatabase;\r
103 HiiData->Hii.GetGlyph = HiiGetGlyph;\r
104 HiiData->Hii.GetPrimaryLanguages = HiiGetPrimaryLanguages;\r
105 HiiData->Hii.GetSecondaryLanguages = HiiGetSecondaryLanguages;\r
106 HiiData->Hii.NewString = HiiNewString;\r
107 HiiData->Hii.GetString = HiiGetString;\r
108 HiiData->Hii.ResetStrings = HiiResetStrings;\r
109 HiiData->Hii.TestString = HiiTestString;\r
110 HiiData->Hii.GetLine = HiiGetLine;\r
111 HiiData->Hii.GetForms = HiiGetForms;\r
112 HiiData->Hii.GetDefaultImage = HiiGetDefaultImage;\r
113 HiiData->Hii.UpdateForm = HiiUpdateForm;\r
114 HiiData->Hii.GetKeyboardLayout = HiiGetKeyboardLayout;\r
115 HiiData->Hii.GlyphToBlt = HiiGlyphToBlt;\r
116\r
117 //\r
118 // Install protocol interface\r
119 //\r
120 Handle = NULL;\r
121 Status = gBS->InstallProtocolInterface (\r
122 &Handle,\r
123 &gEfiHiiProtocolGuid,\r
124 EFI_NATIVE_INTERFACE,\r
125 &HiiData->Hii\r
126 );\r
127\r
128 ASSERT_EFI_ERROR (Status);\r
129\r
130 return Status;\r
131}\r
132\r
133EFI_STATUS\r
134EFIAPI\r
135HiiFindHandles (\r
136 IN EFI_HII_PROTOCOL *This,\r
137 IN OUT UINT16 *HandleBufferLength,\r
f79314fa 138 OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]\r
103b6520 139 )\r
140/*++\r
141\r
142Routine Description:\r
143 Determines the handles that are currently active in the database.\r
ececc2eb 144\r
103b6520 145Arguments:\r
146\r
ececc2eb 147Returns:\r
103b6520 148\r
149--*/\r
150{\r
151 EFI_HII_HANDLE_DATABASE *Database;\r
152 EFI_HII_DATA *HiiData;\r
153 UINTN HandleCount;\r
154\r
155 if (This == NULL) {\r
156 return EFI_INVALID_PARAMETER;\r
157 }\r
158\r
159 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
160\r
161 Database = HiiData->DatabaseHead;\r
162\r
163 if (Database == NULL) {\r
164 *HandleBufferLength = 0;\r
165 return EFI_NOT_FOUND;\r
166 }\r
167\r
168 for (HandleCount = 0; Database != NULL; HandleCount++) {\r
169 Database = Database->NextHandleDatabase;\r
170 }\r
171 //\r
172 // Is there a sufficient buffer for the data being passed back?\r
173 //\r
f79314fa 174 if (*HandleBufferLength >= (sizeof (FRAMEWORK_EFI_HII_HANDLE ) * HandleCount)) {\r
103b6520 175 Database = HiiData->DatabaseHead;\r
176\r
177 //\r
178 // Copy the Head information\r
179 //\r
180 if (Database->Handle != 0) {\r
f79314fa 181 CopyMem (&Handle[0], &Database->Handle, sizeof (FRAMEWORK_EFI_HII_HANDLE ));\r
103b6520 182 Database = Database->NextHandleDatabase;\r
183 }\r
184 //\r
185 // Copy more data if appropriate\r
186 //\r
187 for (HandleCount = 1; Database != NULL; HandleCount++) {\r
f79314fa 188 CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (FRAMEWORK_EFI_HII_HANDLE ));\r
103b6520 189 Database = Database->NextHandleDatabase;\r
190 }\r
191\r
f79314fa 192 *HandleBufferLength = (UINT16) (sizeof (FRAMEWORK_EFI_HII_HANDLE ) * HandleCount);\r
103b6520 193 return EFI_SUCCESS;\r
194 } else {\r
195 //\r
196 // Insufficient buffer length\r
197 //\r
f79314fa 198 *HandleBufferLength = (UINT16) (sizeof (FRAMEWORK_EFI_HII_HANDLE ) * HandleCount);\r
103b6520 199 return EFI_BUFFER_TOO_SMALL;\r
200 }\r
201}\r
202\r
203EFI_STATUS\r
204EFIAPI\r
205HiiGetPrimaryLanguages (\r
206 IN EFI_HII_PROTOCOL *This,\r
f79314fa 207 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
103b6520 208 OUT EFI_STRING *LanguageString\r
209 )\r
210/*++\r
211\r
212Routine Description:\r
ececc2eb 213\r
103b6520 214 This function allows a program to determine what the primary languages that are supported on a given handle.\r
215\r
216Arguments:\r
217\r
ececc2eb 218Returns:\r
103b6520 219\r
220--*/\r
221{\r
222 UINTN Count;\r
223 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
224 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;\r
225 EFI_HII_DATA *HiiData;\r
226 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
227 EFI_HII_STRING_PACK *StringPack;\r
228 EFI_HII_STRING_PACK *Location;\r
229 UINT32 Length;\r
230 RELOFST Token;\r
231\r
232 if (This == NULL) {\r
233 return EFI_INVALID_PARAMETER;\r
234 }\r
235\r
236 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
237\r
238 PackageInstance = NULL;\r
239 //\r
240 // Find matching handle in the handle database. Then get the package instance.\r
241 //\r
242 for (HandleDatabase = HiiData->DatabaseHead;\r
243 HandleDatabase != NULL;\r
244 HandleDatabase = HandleDatabase->NextHandleDatabase\r
245 ) {\r
246 if (Handle == HandleDatabase->Handle) {\r
247 PackageInstance = HandleDatabase->Buffer;\r
248 }\r
249 }\r
250 //\r
251 // No handle was found - error condition\r
252 //\r
253 if (PackageInstance == NULL) {\r
254 return EFI_INVALID_PARAMETER;\r
255 }\r
256\r
257 ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
258\r
259 //\r
260 // Based on if there is IFR data in this package instance, determine\r
261 // what the location is of the beginning of the string data.\r
262 //\r
263 if (StringPackageInstance->IfrSize > 0) {\r
264 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
265 } else {\r
266 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
267 }\r
268\r
269 Location = StringPack;\r
270 //\r
271 // Remember that the string packages are formed into contiguous blocks of language data.\r
272 //\r
273 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
274 for (Count = 0; Length != 0; Count = Count + 3) {\r
275 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
276 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
277 }\r
278\r
279 *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
280\r
281 ASSERT (*LanguageString);\r
282\r
283 StringPack = (EFI_HII_STRING_PACK *) Location;\r
284\r
285 //\r
286 // Copy the 6 bytes to LanguageString - keep concatenating it. Shouldn't we just store uint8's since the ISO\r
287 // standard defines the lettering as all US English characters anyway? Save a few bytes.\r
288 //\r
289 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
290 for (Count = 0; Length != 0; Count = Count + 3) {\r
291 CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));\r
292 CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);\r
293 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
294 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
295 }\r
296\r
297 return EFI_SUCCESS;\r
298}\r
299\r
300EFI_STATUS\r
301EFIAPI\r
302HiiGetSecondaryLanguages (\r
303 IN EFI_HII_PROTOCOL *This,\r
f79314fa 304 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
103b6520 305 IN CHAR16 *PrimaryLanguage,\r
306 OUT EFI_STRING *LanguageString\r
307 )\r
308/*++\r
309\r
310Routine Description:\r
ececc2eb 311\r
312 This function allows a program to determine which secondary languages are supported\r
103b6520 313 on a given handle for a given primary language.\r
314\r
315 Arguments:\r
316\r
ececc2eb 317Returns:\r
103b6520 318\r
319--*/\r
320{\r
321 UINTN Count;\r
322 EFI_HII_PACKAGE_INSTANCE *PackageInstance;\r
323 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;\r
324 EFI_HII_DATA *HiiData;\r
325 EFI_HII_HANDLE_DATABASE *HandleDatabase;\r
326 EFI_HII_STRING_PACK *StringPack;\r
327 RELOFST Token;\r
328 UINT32 Length;\r
329\r
330 if (This == NULL) {\r
331 return EFI_INVALID_PARAMETER;\r
332 }\r
333\r
334 HiiData = EFI_HII_DATA_FROM_THIS (This);\r
335 //\r
336 // Check numeric value against the head of the database\r
337 //\r
338 PackageInstance = NULL;\r
339 for (HandleDatabase = HiiData->DatabaseHead;\r
340 HandleDatabase != NULL;\r
341 HandleDatabase = HandleDatabase->NextHandleDatabase\r
342 ) {\r
343 //\r
344 // Match the numeric value with the database entry - if matched, extract PackageInstance\r
345 //\r
346 if (Handle == HandleDatabase->Handle) {\r
347 PackageInstance = HandleDatabase->Buffer;\r
348 }\r
349 }\r
350 //\r
351 // No handle was found - error condition\r
352 //\r
353 if (PackageInstance == NULL) {\r
354 return EFI_INVALID_PARAMETER;\r
355 }\r
356\r
357 ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
358\r
359 //\r
360 // Based on if there is IFR data in this package instance, determine\r
361 // what the location is of the beginning of the string data.\r
362 //\r
363 if (StringPackageInstance->IfrSize > 0) {\r
364 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
365 } else {\r
366 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
367 }\r
368\r
369 //\r
370 // Remember that the string packages are formed into contiguous blocks of language data.\r
371 //\r
372 for (; StringPack->Header.Length != 0;) {\r
373 //\r
374 // Find the PrimaryLanguage being requested\r
375 //\r
376 Token = StringPack->LanguageNameString;\r
377 if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {\r
378 //\r
379 // Now that we found the primary, the secondary languages will follow immediately\r
380 // or the next character is a NULL if there are no secondary languages. We determine\r
381 // the number by getting the stringsize based on the StringPack origination + the LanguageNameString\r
382 // offset + 6 (which is the size of the first 3 letter ISO primary language name). If we get 2, there\r
383 // are no secondary languages (2 = null-terminator).\r
384 //\r
385 Count = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));\r
386\r
387 *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
388\r
389 ASSERT (*LanguageString);\r
390\r
391 CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);\r
392 break;\r
393 }\r
394\r
395 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
396 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
397 }\r
398\r
399 return EFI_SUCCESS;\r
400}\r
401\r
f79314fa 402\r