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
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.
18 This file contains the entry code to the HII database.
22 #include "HiiDatabase.h"
26 InitializeHiiDatabase (
27 IN EFI_HANDLE ImageHandle
,
28 IN EFI_SYSTEM_TABLE
*SystemTable
33 Initialize HII Database
36 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
39 EFI_SUCCESS - Setup loaded.
45 EFI_HII_DATA
*HiiData
;
46 EFI_HII_GLOBAL_DATA
*GlobalData
;
47 EFI_HANDLE
*HandleBuffer
;
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.
57 Status
= gBS
->LocateHandleBuffer (
66 // If there was no error, assume there is an installation and fail to load
68 if (!EFI_ERROR (Status
)) {
69 if (HandleBuffer
!= NULL
) {
70 gBS
->FreePool (HandleBuffer
);
73 return EFI_DEVICE_ERROR
;
76 HiiData
= AllocatePool (sizeof (EFI_HII_DATA
));
80 GlobalData
= AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA
));
85 // Seed the Font Database with a known non-character glyph
87 for (Index
= 0; Index
<= MAX_GLYPH_COUNT
; Index
++) {
89 // Seeding the UnicodeWeight with 0 signifies that it is uninitialized
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
);
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
;
124 // Install protocol interface
127 Status
= gBS
->InstallProtocolInterface (
129 &gEfiHiiProtocolGuid
,
130 EFI_NATIVE_INTERFACE
,
134 ASSERT_EFI_ERROR (Status
);
142 IN EFI_HII_PROTOCOL
*This
,
143 IN OUT UINT16
*HandleBufferLength
,
144 OUT EFI_HII_HANDLE Handle
[1]
149 Determines the handles that are currently active in the database.
157 EFI_HII_GLOBAL_DATA
*GlobalData
;
158 EFI_HII_HANDLE_DATABASE
*Database
;
159 EFI_HII_DATA
*HiiData
;
163 return EFI_INVALID_PARAMETER
;
166 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
168 GlobalData
= HiiData
->GlobalData
;
170 Database
= HiiData
->DatabaseHead
;
172 if (Database
== NULL
) {
173 *HandleBufferLength
= 0;
174 return EFI_NOT_FOUND
;
177 for (HandleCount
= 0; Database
!= NULL
; HandleCount
++) {
178 Database
= Database
->NextHandleDatabase
;
181 // Is there a sufficient buffer for the data being passed back?
183 if (*HandleBufferLength
>= (sizeof (EFI_HII_HANDLE
) * HandleCount
)) {
184 Database
= HiiData
->DatabaseHead
;
187 // Copy the Head information
189 if (Database
->Handle
!= 0) {
190 CopyMem (&Handle
[0], &Database
->Handle
, sizeof (EFI_HII_HANDLE
));
191 Database
= Database
->NextHandleDatabase
;
194 // Copy more data if appropriate
196 for (HandleCount
= 1; Database
!= NULL
; HandleCount
++) {
197 CopyMem (&Handle
[HandleCount
], &Database
->Handle
, sizeof (EFI_HII_HANDLE
));
198 Database
= Database
->NextHandleDatabase
;
201 *HandleBufferLength
= (UINT16
) (sizeof (EFI_HII_HANDLE
) * HandleCount
);
205 // Insufficient buffer length
207 *HandleBufferLength
= (UINT16
) (sizeof (EFI_HII_HANDLE
) * HandleCount
);
208 return EFI_BUFFER_TOO_SMALL
;
214 HiiGetPrimaryLanguages (
215 IN EFI_HII_PROTOCOL
*This
,
216 IN EFI_HII_HANDLE Handle
,
217 OUT EFI_STRING
*LanguageString
223 This function allows a program to determine what the primary languages that are supported on a given handle.
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
;
242 return EFI_INVALID_PARAMETER
;
245 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
247 PackageInstance
= NULL
;
249 // Find matching handle in the handle database. Then get the package instance.
251 for (HandleDatabase
= HiiData
->DatabaseHead
;
252 HandleDatabase
!= NULL
;
253 HandleDatabase
= HandleDatabase
->NextHandleDatabase
255 if (Handle
== HandleDatabase
->Handle
) {
256 PackageInstance
= HandleDatabase
->Buffer
;
260 // No handle was found - error condition
262 if (PackageInstance
== NULL
) {
263 return EFI_INVALID_PARAMETER
;
266 ValidatePack (This
, PackageInstance
, &StringPackageInstance
, NULL
);
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.
272 if (StringPackageInstance
->IfrSize
> 0) {
273 StringPack
= (EFI_HII_STRING_PACK
*) ((CHAR8
*) (&StringPackageInstance
->IfrData
) + StringPackageInstance
->IfrSize
);
275 StringPack
= (EFI_HII_STRING_PACK
*) (&StringPackageInstance
->IfrData
);
278 Location
= StringPack
;
280 // Remember that the string packages are formed into contiguous blocks of language data.
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
));
288 *LanguageString
= AllocateZeroPool (2 * (Count
+ 1));
290 ASSERT (*LanguageString
);
292 StringPack
= (EFI_HII_STRING_PACK
*) Location
;
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.
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
));
311 HiiGetSecondaryLanguages (
312 IN EFI_HII_PROTOCOL
*This
,
313 IN EFI_HII_HANDLE Handle
,
314 IN CHAR16
*PrimaryLanguage
,
315 OUT EFI_STRING
*LanguageString
321 This function allows a program to determine which secondary languages are supported
322 on a given handle for a given primary language.
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
;
341 return EFI_INVALID_PARAMETER
;
344 HiiData
= EFI_HII_DATA_FROM_THIS (This
);
346 // Check numeric value against the head of the database
348 PackageInstance
= NULL
;
349 for (HandleDatabase
= HiiData
->DatabaseHead
;
350 HandleDatabase
!= NULL
;
351 HandleDatabase
= HandleDatabase
->NextHandleDatabase
354 // Match the numeric value with the database entry - if matched, extract PackageInstance
356 if (Handle
== HandleDatabase
->Handle
) {
357 PackageInstance
= HandleDatabase
->Buffer
;
361 // No handle was found - error condition
363 if (PackageInstance
== NULL
) {
364 return EFI_INVALID_PARAMETER
;
367 ValidatePack (This
, PackageInstance
, &StringPackageInstance
, NULL
);
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.
373 if (StringPackageInstance
->IfrSize
> 0) {
374 StringPack
= (EFI_HII_STRING_PACK
*) ((CHAR8
*) (&StringPackageInstance
->IfrData
) + StringPackageInstance
->IfrSize
);
376 StringPack
= (EFI_HII_STRING_PACK
*) (&StringPackageInstance
->IfrData
);
379 Location
= StringPack
;
382 // Remember that the string packages are formed into contiguous blocks of language data.
384 for (; StringPack
->Header
.Length
!= 0;) {
386 // Find the PrimaryLanguage being requested
388 Token
= StringPack
->LanguageNameString
;
389 if (CompareMem ((VOID
*) ((CHAR8
*) (StringPack
) + Token
), PrimaryLanguage
, 3) == 0) {
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).
397 Count
= StrSize ((VOID
*) ((CHAR8
*) (StringPack
) + Token
+ 6));
399 *LanguageString
= AllocateZeroPool (2 * (Count
+ 1));
401 ASSERT (*LanguageString
);
403 CopyMem (*LanguageString
, (VOID
*) ((CHAR8
*) (StringPack
) + Token
+ 6), Count
);
407 CopyMem (&Length
, &StringPack
->Header
.Length
, sizeof (UINT32
));
408 StringPack
= (EFI_HII_STRING_PACK
*) ((CHAR8
*) (StringPack
) + Length
);