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