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