diff options
Diffstat (limited to 'Core/CORE_DXE/UefiHii/UefiHiiUtils.c')
-rw-r--r-- | Core/CORE_DXE/UefiHii/UefiHiiUtils.c | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/Core/CORE_DXE/UefiHii/UefiHiiUtils.c b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c new file mode 100644 index 0000000..d58aed3 --- /dev/null +++ b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c @@ -0,0 +1,750 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c 16 5/22/12 4:38p Artems $ +// +// $Revision: 16 $ +// +// $Date: 5/22/12 4:38p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c $ +// +// 16 5/22/12 4:38p Artems +// [TAG] EIP N/A +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] In certain cases system font is absent +// [RootCause] When font FFS file is not found system doesn't publish +// system font +// [Solution] If font FFS file is not found, publish font supplied with +// Core +// [Files] UefiHiiUtils.c +// +// 15 4/30/12 3:52p Artems +// [TAG] EIP N/A +// [Category] Improvement +// [Description] Modified GraphicsConsole driver to output whole string +// instead of symbol-by-symbol output +// [Files] Gc.c, AmiDxeLib.h, EfiLib.c, UefiHiiUtils.c +// +// 14 1/05/12 5:05p Artems +// EIP 76735: Font FFS file is not loaded in framework mode, when in +// nested FV +// +// 13 1/05/11 12:12p Artems +// EIP 51298: BufferSize value gets corrupted after call to ConfigToBlock +// function - fixed +// +// 12 10/07/10 12:18p Felixp +// Minor bug fix in LoadSystemFont: don't call FreePool if font section +// has not been read. +// +// 11 10/01/10 4:44p Artems +// Added implementation of function SetBrowserData +// +// 10 3/22/10 3:25p Felixp +// SetCallback bug fix (the bug introduced during previous check in). +// +// 9 3/12/10 2:21p Felixp +// Enhencement: LoadResources is updated to properly publish the packages +// when NumberOfCallbacks is zero. +// +// 7 2/23/10 10:30p Felixp +// SetBrowserData function is added. +// +// 6 2/19/10 4:15p Felixp +// GetString function is updated: if the string is not defined for the +// PlatformLang , try with the default language. +// If still no luck, try English. +// +// 5 2/12/10 5:47p Felixp +// Bug fix in LoadResources and LoadString functions +// (memory corruption in projects with more than one supported language). +// +// 4 11/25/09 11:27a Felixp +// Action parameter of the Callback function is updated based on UEFI +// errata +// +// 3 11/24/09 4:39p Felixp +// +// 2 11/24/09 11:27a Felixp +// GetString udpated: if PlatformLang variable does not exist use default +// language instead of English. +// +// 1 10/09/09 6:12p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: UefiHiiUtils.c +// +// Description: UEFI 2.1 HII Utilities Protocol Implementation +// +//<AMI_FHDR_END> +//********************************************************************** +#include <AmiDxeLib.h> +#include <Protocol/HiiUtilities.h> +#include <Protocol/HiiDatabase.h> +#include <Protocol/HiiString.h> +#include <Protocol/FormBrowser2.h> +#include <Protocol/HiiConfigRouting.h> +#include <Protocol/LoadedImage.h> +#include <Protocol/DevicePath.h> +#include "HiiPrivate.h" + +EFI_STATUS HiiAccessExtractConfig( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results +); +EFI_STATUS HiiAccessRouteConfig( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress +); +EFI_STATUS HiiAccessFormCallback( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +); + +VOID StripValuePattern( + IN OUT EFI_STRING String, + IN UINTN Size +); + +UINT32 StrSize16( + IN CHAR16 *String +); + +static EFI_HII_DATABASE_PROTOCOL *HiiDatabase=NULL; +static EFI_HII_STRING_PROTOCOL *HiiString=NULL; +static EFI_FORM_BROWSER2_PROTOCOL *FormBrowser = NULL; +static EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting = NULL; + +static EFI_GUID HiiResourcesFfsSectionGuid= HII_RESOURCES_FFS_SECTION_GUID; +static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE; +static CHAR8 *PlatformLang = NULL; + +extern const char *DefaultLanguageCode; +extern SIMPLE_FONT DefaultFont[]; + +//************************************************************************* +//<AMI_PHDR_START> +// +// Name: SetCallback +// +// Description: +// EFI_STATUS SetCallback(EFI_HII_IFR_PACK *pIfr, +// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo, +// CALLBACK_INFO **CallBackFound) +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +// +//<AMI_PHDR_END> +//************************************************************************* +static EFI_STATUS SetCallback( + EFI_LOADED_IMAGE_PROTOCOL *Image, + EFI_IFR_FORM_SET *FormSet, UINTN NumberOfCallbacks, + CALLBACK_INFO *CallbackInfo, CALLBACK_INFO **CallBackFound, + EFI_HANDLE *CallbackHandle +) +{ + UINTN i; + EFI_STATUS Status; + EFI_HANDLE Handle=NULL; + EFI_DEVICE_PATH_PROTOCOL *pPath, *pPath2; + CALLBACK_INFO *CallbackInfoPtr; + + static EFI_HII_CONFIG_ACCESS_PROTOCOL DefaultConfigAccess = { + HiiAccessExtractConfig, HiiAccessRouteConfig, HiiAccessFormCallback + }; + static CALLBACK_INFO DefaultCallbackInfo = { + NULL,&DefaultConfigAccess, 0, 0, NULL + }; + static VENDOR_DEVICE_PATH FormSetDevicePathNode = { + { + MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, + sizeof(VENDOR_DEVICE_PATH) + }, + {0} + }; + + for( i=0 + ; i<NumberOfCallbacks + && ( CallbackInfo[i].pGuid == NULL + || guidcmp(&FormSet->Guid,CallbackInfo[i].pGuid) != 0 + ) + ; i++ + ); + if (i==NumberOfCallbacks){ + CallbackInfoPtr = &DefaultCallbackInfo; + }else{ + CallbackInfoPtr = &CallbackInfo[i]; + if (CallbackInfoPtr->pFormCallback == NULL){ + CallbackInfoPtr->pFormCallback = &DefaultConfigAccess; + }else{ + if (CallbackInfoPtr->pFormCallback->ExtractConfig==NULL) + CallbackInfoPtr->pFormCallback->ExtractConfig = + HiiAccessExtractConfig; + if (CallbackInfoPtr->pFormCallback->RouteConfig==NULL) + CallbackInfoPtr->pFormCallback->RouteConfig = + HiiAccessRouteConfig; + if (CallbackInfoPtr->pFormCallback->Callback==NULL) + CallbackInfoPtr->pFormCallback->Callback = + HiiAccessFormCallback; + } + } + Status=pBS->HandleProtocol(Image->DeviceHandle, &guidDevicePath, &pPath); + if (EFI_ERROR(Status)) pPath=NULL; + pPath = DPAddNode(pPath, Image->FilePath); + FormSetDevicePathNode.Guid = FormSet->Guid; + pPath2 = DPAddNode(pPath, &FormSetDevicePathNode.Header); + pBS->FreePool(pPath); + Status = pBS->InstallMultipleProtocolInterfaces( + &Handle, + &guidDevicePath, pPath2, + &gEfiHiiConfigAccessProtocolGuid, CallbackInfoPtr->pFormCallback, + NULL + ); + if (EFI_ERROR(Status)) return Status; + if (CallbackHandle) *CallbackHandle=Handle; + if (CallBackFound){ + *CallBackFound= (CallbackInfoPtr == &DefaultCallbackInfo) + ? NULL + : CallbackInfoPtr; + } + return EFI_SUCCESS; +} + +static EFI_STATUS PublishPackages( + IN VOID *PackagePointers, IN UINTN NumberOfPackages, + IN EFI_GUID *PackageGuid, IN EFI_HANDLE DriverHandle OPTIONAL, + OUT EFI_HII_HANDLE *HiiHandle +){ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + UINTN i; + UINT32 PackageLength; + UINT8 *PackagePtr; + EFI_HII_PACKAGE_HEADER **Packages = PackagePointers; + if (NumberOfPackages==0) return EFI_SUCCESS; + if ( !HiiDatabase + && EFI_ERROR(Status=pBS->LocateProtocol( + &gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase + )) + ) return Status; + //calculate the package list length + PackageLength = sizeof(EFI_HII_PACKAGE_LIST_HEADER) + + sizeof(EFI_HII_PACKAGE_HEADER); //package list terminator + for(i=0; i<NumberOfPackages; i++){ + PackageLength += Packages[i]->Length; + } + PackageList = Malloc(PackageLength); + if(PackageList==NULL) return EFI_OUT_OF_RESOURCES; + PackageList->PackageListGuid = *PackageGuid; + PackageList->PackageLength = PackageLength; + + PackagePtr = (UINT8*)(PackageList+1); + for( i=0; i<NumberOfPackages; i++){ + pBS->CopyMem(PackagePtr, Packages[i], Packages[i]->Length); + PackagePtr += Packages[i]->Length; + } + ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Length = sizeof(EFI_HII_PACKAGE_HEADER); + ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Type = EFI_HII_PACKAGE_END; + + Status = HiiDatabase->NewPackageList( + HiiDatabase, PackageList, DriverHandle, HiiHandle + ); + pBS->FreePool(PackageList); + return Status; +} + +UINT32 GetNumerOfResourcePackages( + HII_RESOURCE_SECTION_HEADER *pSection, UINTN SectionSize +){ + EFI_HII_PACKAGE_HEADER *PackagePtr; + UINT32 NumberOfPackages = 0; + PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1); + while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){ + PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length); + NumberOfPackages++; + } + return NumberOfPackages; +} + +//************************************************************************* +//<AMI_PHDR_START> +// +// Name: LoadStrings +// +// Description: +// EFI_STATUS LoadStrings(EFI_HANDLE ImageHandle, +// EFI_HII_HANDLE *HiiHandle) +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +// +//<AMI_PHDR_END> +//************************************************************************* +static EFI_STATUS LoadStrings( + EFI_HANDLE ImageHandle, EFI_HII_HANDLE *HiiHandle +) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *Image; + HII_RESOURCE_SECTION_HEADER *pSection; + UINTN SectionSize; + EFI_HII_PACKAGE_HEADER *pPack; + EFI_HII_PACKAGE_HEADER **StringPackagPtr; + UINTN NumberOfStringPackages; + if (EFI_ERROR(Status=pBS->HandleProtocol( + ImageHandle, &gEfiLoadedImageProtocolGuid, &Image + )) + ) return Status; +#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1 +{ +#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_ + UINT8 *pData; + pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize); + if (!pData) return EFI_NOT_FOUND; + pSection = Malloc(SectionSize); + pBS->CopyMem(pSection,pData,SectionSize); + Status = EFI_SUCCESS; +} +#else +{ + Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize); + if (EFI_ERROR(Status)) return Status; +} +#endif + //Calculate number of packages. + //Original value of pSection->NumberOfPackages treats string packages + //for multiple languages as a single package. We need the real number of packages. + pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize); + + pPack = (EFI_HII_PACKAGE_HEADER *)(pSection + 1); + + StringPackagPtr = Malloc(pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*)); + NumberOfStringPackages=0; + while(pPack < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){ + if (pPack->Type != EFI_HII_PACKAGE_STRINGS){ + Status=EFI_INVALID_PARAMETER; + break; + } + StringPackagPtr[NumberOfStringPackages++]=pPack; + pPack = (EFI_HII_PACKAGE_HEADER*)((UINT8*)pPack+pPack->Length); + } + Status = PublishPackages( + StringPackagPtr, NumberOfStringPackages, + &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid, + NULL, HiiHandle + ); + pBS->FreePool(StringPackagPtr); + pBS->FreePool(pSection); + return Status; +} + +//************************************************************************* +//<AMI_PHDR_START> +// +// Name: LoadResources +// +// Description: +// EFI_STATUS LoadResources(EFI_HANDLE ImageHandle, +// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo, +// INIT_HII_PACK InitFunction) +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +// +//<AMI_PHDR_END> +//************************************************************************* +static EFI_STATUS LoadResources( + EFI_HANDLE ImageHandle, UINTN NumberOfCallbacks, + CALLBACK_INFO *CallbackInfo, INIT_HII_PACK InitFunction +) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_LOADED_IMAGE_PROTOCOL *Image; + HII_RESOURCE_SECTION_HEADER *pSection; + UINTN SectionSize; + CALLBACK_INFO *pCallBackFound; + if (EFI_ERROR(Status=pBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, &Image))) return Status; +#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1 +{ +#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_ + UINT8 *pData; + pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize); + if (!pData) return EFI_NOT_FOUND; + pSection = Malloc(SectionSize); + pBS->CopyMem(pSection,pData,SectionSize); +} +#else +{ + Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize); + if (EFI_ERROR(Status)) return Status; +} +#endif +{ + EFI_HII_PACKAGE_HEADER **IfrPackagPtr, **GlobalPackagPtr, **SharedPackagPtr; + UINTN NumberOfIfrPackages, NumberOfGlobalPackages, NumberOfSharedPackages, i; + UINT8 *PackagePtrBuffer; + EFI_HII_PACKAGE_HEADER *PackagePtr; + + //Calculate number of packages. + //Original value of pSection->NumberOfPackages treats string packages + //for multiple languages as a single package. We need the real number of packages. + pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize); + + PackagePtrBuffer = Malloc(3*pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*)); + IfrPackagPtr = (EFI_HII_PACKAGE_HEADER**)PackagePtrBuffer; + GlobalPackagPtr = IfrPackagPtr+pSection->NumberOfPackages; + SharedPackagPtr = GlobalPackagPtr+pSection->NumberOfPackages; + NumberOfIfrPackages = 0; + NumberOfGlobalPackages = 0; + NumberOfSharedPackages = 0; + + PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1); + while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){ + switch(PackagePtr->Type){ + case EFI_HII_PACKAGE_FORMS: + IfrPackagPtr[NumberOfIfrPackages++]=PackagePtr; + break; + case EFI_HII_PACKAGE_FONTS: case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: + GlobalPackagPtr[NumberOfGlobalPackages++]=PackagePtr; + break; + default: + SharedPackagPtr[NumberOfSharedPackages++]=PackagePtr; + break; + } + PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length); + } + Status = PublishPackages( + GlobalPackagPtr, NumberOfGlobalPackages, + &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid, + NULL, &HiiHandle + ); + for(i=0; i<NumberOfIfrPackages; i++){ + EFI_HANDLE CallbackHandle; + + SharedPackagPtr[NumberOfSharedPackages]=IfrPackagPtr[i]; + SetCallback( + Image, (EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1), + NumberOfCallbacks,CallbackInfo,&pCallBackFound,&CallbackHandle + ); + Status = PublishPackages( + SharedPackagPtr, NumberOfSharedPackages+1, + &((EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1))->Guid, + CallbackHandle, &HiiHandle + ); + if (pCallBackFound) pCallBackFound->HiiHandle=HiiHandle; + if (InitFunction) InitFunction(HiiHandle,pCallBackFound); + pCallBackFound=NULL; + } + pBS->FreePool(PackagePtrBuffer); + pBS->FreePool(pSection); +} + return EFI_SUCCESS; +} + +//TODO: header +static EFI_STATUS GetString( + IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId, + IN OUT UINTN *StringSize, OUT EFI_STRING String +){ + EFI_STATUS Status; + + if ( !HiiString + && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString)) + ) return EFI_NOT_FOUND; + if (PlatformLang==NULL){ + UINTN Size; + if (EFI_ERROR(GetEfiVariable( + L"PlatformLang", &EfiVariableGuid, NULL, &Size, &PlatformLang + ))) PlatformLang = (CHAR8*)DefaultLanguageCode; + } + Status = HiiString->GetString( + HiiString, PlatformLang, HiiHandle,StringId, String, StringSize, NULL + ); + // If the string representation for the PlatformLang is not defined, + // try with the default language. + // If still no luck, try English + if (Status==EFI_INVALID_LANGUAGE){ + Status = HiiString->GetString( + HiiString, (CHAR8*)DefaultLanguageCode, HiiHandle, + StringId, String, StringSize, NULL + ); + if (Status==EFI_INVALID_LANGUAGE) + Status = HiiString->GetString( + HiiString, LANGUAGE_CODE_ENGLISH, HiiHandle, + StringId, String, StringSize, NULL + ); + } + return Status; +} + +//TODO header +static EFI_STATUS SetString( + IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId, IN EFI_STRING String +){ + CHAR8 *LanguageList = NULL; + UINTN Size = 0; + EFI_STATUS Status; + + if ( !HiiString + && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString)) + ) return EFI_NOT_FOUND; + + Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size); + if (Status!=EFI_BUFFER_TOO_SMALL) return Status; + LanguageList = Malloc(Size); + Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size); + if (!EFI_ERROR(Status)){ + CHAR8 *CurrentLang, *EndOfCurrentLang; + EndOfCurrentLang = LanguageList; + while(EndOfCurrentLang < LanguageList+Size){ + CHAR8 OriginalChar; + CurrentLang = EndOfCurrentLang; + while(*EndOfCurrentLang!=';'&&*EndOfCurrentLang!=0) EndOfCurrentLang++; + OriginalChar = *EndOfCurrentLang; + *EndOfCurrentLang = 0; + Status = HiiString->SetString( + HiiString, HiiHandle, StringId, CurrentLang, String, NULL + ); + if (EFI_ERROR(Status)) break; + *EndOfCurrentLang = OriginalChar; + EndOfCurrentLang++; + } + } + pBS->FreePool(LanguageList); + return Status; +} + +static EFI_STATUS GetBrowserData( + IN UINTN *BufferSize, OUT VOID *Buffer, + IN CONST EFI_GUID *VarStoreGuid, OPTIONAL + IN CONST CHAR16 *VarStoreName OPTIONAL +){ + UINTN StringDataSize = 0; + CHAR16 *StringData = NULL; + EFI_STATUS Status; + EFI_STRING Progress; + + if ( !FormBrowser + && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser)) + ) return EFI_NOT_FOUND; + if ( !HiiConfigRouting + && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting)) + ) return EFI_NOT_FOUND; + + Status = FormBrowser->BrowserCallback( + FormBrowser, &StringDataSize, StringData, TRUE, + VarStoreGuid, VarStoreName + ); + if (Status!=EFI_BUFFER_TOO_SMALL) return Status; + StringData = Malloc(StringDataSize); + Status = FormBrowser->BrowserCallback( + FormBrowser, &StringDataSize, StringData, TRUE, + VarStoreGuid, VarStoreName + ); + if (!EFI_ERROR(Status)){ + StringDataSize = *BufferSize; //preserve passed buffer size value, as + //ConfigToBlock may change it as per UEFI 2.1 spec + //it will contain index of last updated byte + Status = HiiConfigRouting->ConfigToBlock( + HiiConfigRouting, StringData, Buffer, BufferSize, &Progress + ); + *BufferSize = StringDataSize; //restore original value + } + pBS->FreePool(StringData); + return Status; +} + +static EFI_STATUS SetBrowserData( + IN UINTN BufferSize, IN VOID *Buffer, + IN CONST EFI_GUID *VarStoreGuid, OPTIONAL //TODO: Can it be optional??? + IN CONST CHAR16 *VarStoreName OPTIONAL +) +{ + UINTN StringDataSize = 0; + CHAR16 *StringData = NULL; + EFI_STATUS Status; + EFI_STRING Config; + EFI_STRING Progress; + + if ( !FormBrowser + && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser)) + ) return EFI_NOT_FOUND; + if ( !HiiConfigRouting + && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting)) + ) return EFI_NOT_FOUND; + + Status = FormBrowser->BrowserCallback( + FormBrowser, &StringDataSize, StringData, TRUE, + VarStoreGuid, VarStoreName + ); + if (Status!=EFI_BUFFER_TOO_SMALL) return Status; + StringData = Malloc(StringDataSize); + Status = FormBrowser->BrowserCallback( + FormBrowser, &StringDataSize, StringData, TRUE, + VarStoreGuid, VarStoreName + ); + if (EFI_ERROR(Status)) + return Status; + +//we have StringData in format &OFFSET=XXXX&WIDTH=XXXX&VALUE=XXXX&OFFSET=... +//in order for function BlockToConfig to work we need to modify StringData as follows: +//&OFFSET=XXXX&WIDTH=XXXX&OFFSET=... (i.e. remove all &VALUE=XXX patterns) + + StripValuePattern(StringData, StringDataSize); + + Status = HiiConfigRouting->BlockToConfig( + HiiConfigRouting, StringData, Buffer, BufferSize, + &Config, &Progress + ); + + if(!EFI_ERROR(Status)) { + StringDataSize = StrSize16(Config); + Status = FormBrowser->BrowserCallback( + FormBrowser, &StringDataSize, Config, FALSE, + VarStoreGuid, VarStoreName + ); + pBS->FreePool(Config); + } + + pBS->FreePool(StringData); + return Status; +} + +EFI_STATUS LoadSystemFont(){ +///// Load Font Pack +#define FONT_FFS_FILE_GUID { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0xd, 0xcc, 0x77, 0x6, 0x1b, 0x9b } } +static EFI_GUID FontFfsFileGuid = FONT_FFS_FILE_GUID; +extern UINT8 UsStdNarrowGlyphData[]; + EFI_FIRMWARE_VOLUME_PROTOCOL *pFV; + UINTN DataSize; + EFI_GUID *pSectionGuid = NULL; + UINT32 Authentication; + EFI_HANDLE *pHandle; + UINTN Number,i; + EFI_STATUS FontStatus; + EFI_HII_PACKAGE_HEADER *FontPackage; + EFI_HII_HANDLE HiiFontHandle; + + FontPackage = (EFI_HII_PACKAGE_HEADER*)&UsStdNarrowGlyphData; + FontStatus = pBS->LocateHandleBuffer(ByProtocol,&guidFV, NULL, &Number, &pHandle); + for(i=0;i<Number; i++) + { + FontStatus=pBS->HandleProtocol(pHandle[i], &guidFV, &pFV); + if (EFI_ERROR(FontStatus)) continue; + pSectionGuid=NULL; + DataSize=0; + FontStatus=pFV->ReadSection ( + pFV,&FontFfsFileGuid, + EFI_SECTION_FREEFORM_SUBTYPE_GUID,0, &pSectionGuid, &DataSize, + &Authentication + ); + if (!EFI_ERROR(FontStatus)) + { + FontPackage=(EFI_HII_PACKAGE_HEADER*)((UINT32*)(pSectionGuid+1)+1); + break; + } + } + + if (FontPackage->Type!=EFI_HII_PACKAGE_SIMPLE_FONTS){ + //The font package is in the Framework HII format + //Convert the header to the UEFI HII format + DataSize=FontPackage->Length; + FontPackage = (EFI_HII_PACKAGE_HEADER*)((UINT8*)FontPackage+2); + FontPackage->Type=EFI_HII_PACKAGE_SIMPLE_FONTS; + FontPackage->Length=(UINT32)DataSize; + } + FontStatus = PublishPackages(&FontPackage, 1, &FontFfsFileGuid, NULL, &HiiFontHandle); + if (pSectionGuid!=NULL) pBS->FreePool(pSectionGuid); + return FontStatus; +} + +static EFI_STATUS UtilGetGlyphWidth( + IN CHAR16 Char, + OUT UINT16 *Width +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + if(DefaultFont[(UINTN)Char].NarrowGlyph != NULL) { + *Width = ((DefaultFont[(UINTN)Char].NarrowGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDTH; + } else if(DefaultFont[(UINTN)Char].WideGlyph != NULL) { + *Width = ((DefaultFont[(UINTN)Char].WideGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDE_WIDTH; + } else if(DefaultFont[0xfffd].NarrowGlyph != NULL) { + *Width = EFI_GLYPH_WIDTH; + Status = EFI_WARN_UNKNOWN_GLYPH; + } else if(DefaultFont[0xfffd].WideGlyph != NULL) { + *Width = EFI_GLYPH_WIDE_WIDTH; + Status = EFI_WARN_UNKNOWN_GLYPH; + } else { + *Width = 0; + Status = EFI_WARN_UNKNOWN_GLYPH; + } + return Status; +} + +HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol = { + LoadResources, LoadStrings, PublishPackages, + GetBrowserData, SetBrowserData, GetString, SetString, UtilGetGlyphWidth +}; + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file |