]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c
Modules cleanup.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / HiiDataBaseDxe / HiiDatabase.c
1 /*++
2
3 Copyright (c) 2006 - 2007, 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 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_HANDLE_DATABASE *Database;
158 EFI_HII_DATA *HiiData;
159 UINTN HandleCount;
160
161 if (This == NULL) {
162 return EFI_INVALID_PARAMETER;
163 }
164
165 HiiData = EFI_HII_DATA_FROM_THIS (This);
166
167 Database = HiiData->DatabaseHead;
168
169 if (Database == NULL) {
170 *HandleBufferLength = 0;
171 return EFI_NOT_FOUND;
172 }
173
174 for (HandleCount = 0; Database != NULL; HandleCount++) {
175 Database = Database->NextHandleDatabase;
176 }
177 //
178 // Is there a sufficient buffer for the data being passed back?
179 //
180 if (*HandleBufferLength >= (sizeof (EFI_HII_HANDLE) * HandleCount)) {
181 Database = HiiData->DatabaseHead;
182
183 //
184 // Copy the Head information
185 //
186 if (Database->Handle != 0) {
187 CopyMem (&Handle[0], &Database->Handle, sizeof (EFI_HII_HANDLE));
188 Database = Database->NextHandleDatabase;
189 }
190 //
191 // Copy more data if appropriate
192 //
193 for (HandleCount = 1; Database != NULL; HandleCount++) {
194 CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (EFI_HII_HANDLE));
195 Database = Database->NextHandleDatabase;
196 }
197
198 *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);
199 return EFI_SUCCESS;
200 } else {
201 //
202 // Insufficient buffer length
203 //
204 *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);
205 return EFI_BUFFER_TOO_SMALL;
206 }
207 }
208
209 EFI_STATUS
210 EFIAPI
211 HiiGetPrimaryLanguages (
212 IN EFI_HII_PROTOCOL *This,
213 IN EFI_HII_HANDLE Handle,
214 OUT EFI_STRING *LanguageString
215 )
216 /*++
217
218 Routine Description:
219
220 This function allows a program to determine what the primary languages that are supported on a given handle.
221
222 Arguments:
223
224 Returns:
225
226 --*/
227 {
228 UINTN Count;
229 EFI_HII_PACKAGE_INSTANCE *PackageInstance;
230 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
231 EFI_HII_DATA *HiiData;
232 EFI_HII_HANDLE_DATABASE *HandleDatabase;
233 EFI_HII_STRING_PACK *StringPack;
234 EFI_HII_STRING_PACK *Location;
235 UINT32 Length;
236 RELOFST Token;
237
238 if (This == NULL) {
239 return EFI_INVALID_PARAMETER;
240 }
241
242 HiiData = EFI_HII_DATA_FROM_THIS (This);
243
244 PackageInstance = NULL;
245 //
246 // Find matching handle in the handle database. Then get the package instance.
247 //
248 for (HandleDatabase = HiiData->DatabaseHead;
249 HandleDatabase != NULL;
250 HandleDatabase = HandleDatabase->NextHandleDatabase
251 ) {
252 if (Handle == HandleDatabase->Handle) {
253 PackageInstance = HandleDatabase->Buffer;
254 }
255 }
256 //
257 // No handle was found - error condition
258 //
259 if (PackageInstance == NULL) {
260 return EFI_INVALID_PARAMETER;
261 }
262
263 ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
264
265 //
266 // Based on if there is IFR data in this package instance, determine
267 // what the location is of the beginning of the string data.
268 //
269 if (StringPackageInstance->IfrSize > 0) {
270 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
271 } else {
272 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
273 }
274
275 Location = StringPack;
276 //
277 // Remember that the string packages are formed into contiguous blocks of language data.
278 //
279 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
280 for (Count = 0; Length != 0; Count = Count + 3) {
281 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
282 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
283 }
284
285 *LanguageString = AllocateZeroPool (2 * (Count + 1));
286
287 ASSERT (*LanguageString);
288
289 StringPack = (EFI_HII_STRING_PACK *) Location;
290
291 //
292 // Copy the 6 bytes to LanguageString - keep concatenating it. Shouldn't we just store uint8's since the ISO
293 // standard defines the lettering as all US English characters anyway? Save a few bytes.
294 //
295 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
296 for (Count = 0; Length != 0; Count = Count + 3) {
297 CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));
298 CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);
299 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
300 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
301 }
302
303 return EFI_SUCCESS;
304 }
305
306 EFI_STATUS
307 EFIAPI
308 HiiGetSecondaryLanguages (
309 IN EFI_HII_PROTOCOL *This,
310 IN EFI_HII_HANDLE Handle,
311 IN CHAR16 *PrimaryLanguage,
312 OUT EFI_STRING *LanguageString
313 )
314 /*++
315
316 Routine Description:
317
318 This function allows a program to determine which secondary languages are supported
319 on a given handle for a given primary language.
320
321 Arguments:
322
323 Returns:
324
325 --*/
326 {
327 UINTN Count;
328 EFI_HII_PACKAGE_INSTANCE *PackageInstance;
329 EFI_HII_PACKAGE_INSTANCE *StringPackageInstance;
330 EFI_HII_DATA *HiiData;
331 EFI_HII_HANDLE_DATABASE *HandleDatabase;
332 EFI_HII_STRING_PACK *StringPack;
333 RELOFST Token;
334 UINT32 Length;
335
336 if (This == NULL) {
337 return EFI_INVALID_PARAMETER;
338 }
339
340 HiiData = EFI_HII_DATA_FROM_THIS (This);
341 //
342 // Check numeric value against the head of the database
343 //
344 PackageInstance = NULL;
345 for (HandleDatabase = HiiData->DatabaseHead;
346 HandleDatabase != NULL;
347 HandleDatabase = HandleDatabase->NextHandleDatabase
348 ) {
349 //
350 // Match the numeric value with the database entry - if matched, extract PackageInstance
351 //
352 if (Handle == HandleDatabase->Handle) {
353 PackageInstance = HandleDatabase->Buffer;
354 }
355 }
356 //
357 // No handle was found - error condition
358 //
359 if (PackageInstance == NULL) {
360 return EFI_INVALID_PARAMETER;
361 }
362
363 ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);
364
365 //
366 // Based on if there is IFR data in this package instance, determine
367 // what the location is of the beginning of the string data.
368 //
369 if (StringPackageInstance->IfrSize > 0) {
370 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);
371 } else {
372 StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);
373 }
374
375 //
376 // Remember that the string packages are formed into contiguous blocks of language data.
377 //
378 for (; StringPack->Header.Length != 0;) {
379 //
380 // Find the PrimaryLanguage being requested
381 //
382 Token = StringPack->LanguageNameString;
383 if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {
384 //
385 // Now that we found the primary, the secondary languages will follow immediately
386 // or the next character is a NULL if there are no secondary languages. We determine
387 // the number by getting the stringsize based on the StringPack origination + the LanguageNameString
388 // offset + 6 (which is the size of the first 3 letter ISO primary language name). If we get 2, there
389 // are no secondary languages (2 = null-terminator).
390 //
391 Count = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));
392
393 *LanguageString = AllocateZeroPool (2 * (Count + 1));
394
395 ASSERT (*LanguageString);
396
397 CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);
398 break;
399 }
400
401 CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));
402 StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);
403 }
404
405 return EFI_SUCCESS;
406 }
407