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