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