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