Files
system76-edk2/ArmPlatformPkg/Bds/BdsHelper.c
oliviermartin 74b961324c ArmPlatformPkg/Bds: Get User inputs in Unicode
The user input was getting in Ascii and converted later to Unicode
when required.
In this change, the user inputs are caught in Unicode and converted
to Ascii only when needed.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12310 6f19259b-4bc3-4df7-8a09-765794883524
2011-09-09 10:49:54 +00:00

346 lines
8.7 KiB
C

/** @file
*
* Copyright (c) 2011, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
* which accompanies this distribution. The full text of the license may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/
#include "BdsInternal.h"
EFI_STATUS
GetEnvironmentVariable (
IN CONST CHAR16* VariableName,
IN VOID* DefaultValue,
IN OUT UINTN* Size,
OUT VOID** Value
)
{
EFI_STATUS Status;
UINTN VariableSize;
// Try to get the variable size.
*Value = NULL;
VariableSize = 0;
Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
if (Status == EFI_NOT_FOUND) {
if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
// If the environment variable does not exist yet then set it with the default value
Status = gRT->SetVariable (
(CHAR16*)VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
*Size,
DefaultValue
);
*Value = DefaultValue;
} else {
return EFI_NOT_FOUND;
}
} else if (Status == EFI_BUFFER_TOO_SMALL) {
// Get the environment variable value
*Value = AllocatePool (VariableSize);
if (*Value == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
if (EFI_ERROR (Status)) {
FreePool(*Value);
return EFI_INVALID_PARAMETER;
}
if (Size) {
*Size = VariableSize;
}
} else {
*Value = DefaultValue;
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
EditHIInputStr (
IN OUT CHAR16 *CmdLine,
IN UINTN MaxCmdLine
)
{
UINTN CmdLineIndex;
UINTN WaitIndex;
CHAR8 Char;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
Print (CmdLine);
for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {
Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
ASSERT_EFI_ERROR (Status);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ASSERT_EFI_ERROR (Status);
// Unicode character is valid when Scancode is NUll
if (Key.ScanCode == SCAN_NULL) {
// Scan code is NUll, hence read Unicode character
Char = (CHAR8)Key.UnicodeChar;
} else {
Char = CHAR_NULL;
}
if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {
CmdLine[CmdLineIndex] = '\0';
Print (L"\n\r");
return EFI_SUCCESS;
} else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
if (CmdLineIndex != 0) {
CmdLineIndex--;
Print (L"\b \b");
}
} else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {
return EFI_INVALID_PARAMETER;
} else {
CmdLine[CmdLineIndex++] = Key.UnicodeChar;
Print (L"%c", Key.UnicodeChar);
}
}
return EFI_SUCCESS;
}
EFI_STATUS
GetHIInputStr (
IN OUT CHAR16 *CmdLine,
IN UINTN MaxCmdLine
)
{
EFI_STATUS Status;
// For a new input just passed an empty string
CmdLine[0] = L'\0';
Status = EditHIInputStr (CmdLine, MaxCmdLine);
return Status;
}
EFI_STATUS
EditHIInputAscii (
IN OUT CHAR8 *CmdLine,
IN UINTN MaxCmdLine
)
{
CHAR16* Str;
EFI_STATUS Status;
Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));
AsciiStrToUnicodeStr (CmdLine, Str);
Status = EditHIInputStr (Str, MaxCmdLine);
if (!EFI_ERROR(Status)) {
UnicodeStrToAsciiStr (Str, CmdLine);
}
FreePool (Str);
return Status;
}
EFI_STATUS
GetHIInputAscii (
IN OUT CHAR8 *CmdLine,
IN UINTN MaxCmdLine
)
{
// For a new input just passed an empty string
CmdLine[0] = '\0';
return EditHIInputAscii (CmdLine,MaxCmdLine);
}
EFI_STATUS
GetHIInputInteger (
OUT UINTN *Integer
)
{
CHAR16 CmdLine[255];
EFI_STATUS Status;
CmdLine[0] = '\0';
Status = EditHIInputStr (CmdLine, 255);
if (!EFI_ERROR(Status)) {
*Integer = StrDecimalToUintn (CmdLine);
}
return Status;
}
EFI_STATUS
GetHIInputIP (
OUT EFI_IP_ADDRESS *Ip
)
{
CHAR16 CmdLine[255];
CHAR16 *Str;
EFI_STATUS Status;
CmdLine[0] = '\0';
Status = EditHIInputStr (CmdLine,255);
if (!EFI_ERROR(Status)) {
Str = CmdLine;
Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);
Str = StrStr (Str, L".");
if (Str == NULL) {
return EFI_INVALID_PARAMETER;
}
Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);
Str = StrStr (Str, L".");
if (Str == NULL) {
return EFI_INVALID_PARAMETER;
}
Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);
Str = StrStr (Str, L".");
if (Str == NULL) {
return EFI_INVALID_PARAMETER;
}
Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);
}
return Status;
}
EFI_STATUS
GetHIInputBoolean (
OUT BOOLEAN *Value
)
{
CHAR16 CmdBoolean[2];
EFI_STATUS Status;
while(1) {
Print (L"[y/n] ");
Status = GetHIInputStr (CmdBoolean,2);
if (EFI_ERROR(Status)) {
return Status;
} else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {
if (Value) *Value = TRUE;
return EFI_SUCCESS;
} else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {
if (Value) *Value = FALSE;
return EFI_SUCCESS;
}
}
}
BOOLEAN
HasFilePathEfiExtension (
IN CHAR16* FilePath
)
{
return (StrCmp (FilePath + (StrSize(FilePath)/sizeof(CHAR16)) - 5, L".efi") == 0);
}
// Return the last non end-type Device Path Node from a Device Path
EFI_DEVICE_PATH*
GetLastDevicePathNode (
IN EFI_DEVICE_PATH* DevicePath
)
{
EFI_DEVICE_PATH* PrevDevicePathNode;
PrevDevicePathNode = DevicePath;
while (!IsDevicePathEndType (DevicePath)) {
PrevDevicePathNode = DevicePath;
DevicePath = NextDevicePathNode (DevicePath);
}
return PrevDevicePathNode;
}
EFI_STATUS
GenerateDeviceDescriptionName (
IN EFI_HANDLE Handle,
IN OUT CHAR16* Description
)
{
EFI_STATUS Status;
EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
CHAR16* DriverName;
CHAR16* DevicePathTxt;
EFI_DEVICE_PATH* DevicePathNode;
ComponentName2Protocol = NULL;
Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);
if (!EFI_ERROR(Status)) {
//TODO: Fixme. we must find the best langague
Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);
if (!EFI_ERROR(Status)) {
StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX);
}
}
if (EFI_ERROR(Status)) {
// Use the lastest non null entry of the Device path as a description
Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
if (EFI_ERROR(Status)) {
return Status;
}
// Convert the last non end-type Device Path Node in text for the description
DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);
Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
ASSERT_EFI_ERROR(Status);
DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE);
StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);
FreePool (DevicePathTxt);
}
return EFI_SUCCESS;
}
EFI_STATUS
BdsStartBootOption (
IN CHAR16* BootOption
)
{
EFI_STATUS Status;
EFI_LOAD_OPTION EfiLoadOption;
UINTN EfiLoadOptionSize;
BDS_LOAD_OPTION *BdsLoadOption;
Status = GetEnvironmentVariable (BootOption, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);
if (!EFI_ERROR(Status)) {
Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, &BdsLoadOption);
if (!EFI_ERROR(Status)) {
Status = BootOptionStart (BdsLoadOption);
FreePool (BdsLoadOption);
}
if (!EFI_ERROR(Status)) {
Status = EFI_SUCCESS;
} else {
Status = EFI_NOT_STARTED;
}
} else {
Status = EFI_NOT_FOUND;
}
return Status;
}