3 * Copyright (c) 2011-2013, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsInternal.h"
19 IN OUT CHAR16
*CmdLine
,
29 // The command line must be at least one character long
30 ASSERT (MaxCmdLine
> 0);
32 // Ensure the last character of the buffer is the NULL character
33 CmdLine
[MaxCmdLine
- 1] = '\0';
37 // To prevent a buffer overflow, we only allow to enter (MaxCmdLine-1) characters
38 for (CmdLineIndex
= StrLen (CmdLine
); CmdLineIndex
< MaxCmdLine
- 1; ) {
39 Status
= gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &WaitIndex
);
40 ASSERT_EFI_ERROR (Status
);
42 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
43 ASSERT_EFI_ERROR (Status
);
45 // Unicode character is valid when Scancode is NUll
46 if (Key
.ScanCode
== SCAN_NULL
) {
47 // Scan code is NUll, hence read Unicode character
48 Char
= (CHAR8
)Key
.UnicodeChar
;
53 if ((Char
== CHAR_LINEFEED
) || (Char
== CHAR_CARRIAGE_RETURN
) || (Char
== 0x7f)) {
54 CmdLine
[CmdLineIndex
] = '\0';
58 } else if ((Key
.UnicodeChar
== L
'\b') || (Key
.ScanCode
== SCAN_LEFT
) || (Key
.ScanCode
== SCAN_DELETE
)){
59 if (CmdLineIndex
!= 0) {
63 } else if ((Key
.ScanCode
== SCAN_ESC
) || (Char
== 0x1B) || (Char
== 0x0)) {
64 return EFI_INVALID_PARAMETER
;
66 CmdLine
[CmdLineIndex
++] = Key
.UnicodeChar
;
67 Print (L
"%c", Key
.UnicodeChar
);
76 IN OUT CHAR16
*CmdLine
,
82 // For a new input just passed an empty string
85 Status
= EditHIInputStr (CmdLine
, MaxCmdLine
);
92 IN OUT CHAR8
*CmdLine
,
99 Str
= (CHAR16
*)AllocatePool (MaxCmdLine
* sizeof(CHAR16
));
100 AsciiStrToUnicodeStr (CmdLine
, Str
);
102 Status
= EditHIInputStr (Str
, MaxCmdLine
);
103 if (!EFI_ERROR(Status
)) {
104 UnicodeStrToAsciiStr (Str
, CmdLine
);
113 IN OUT CHAR8
*CmdLine
,
117 // For a new input just passed an empty string
120 return EditHIInputAscii (CmdLine
,MaxCmdLine
);
132 Status
= EditHIInputStr (CmdLine
, 255);
133 if (!EFI_ERROR(Status
)) {
134 *Integer
= StrDecimalToUintn (CmdLine
);
142 OUT EFI_IP_ADDRESS
*Ip
150 Status
= EditHIInputStr (CmdLine
,255);
151 if (!EFI_ERROR(Status
)) {
153 Ip
->v4
.Addr
[0] = (UINT8
)StrDecimalToUintn (Str
);
155 Str
= StrStr (Str
, L
".");
157 return EFI_INVALID_PARAMETER
;
160 Ip
->v4
.Addr
[1] = (UINT8
)StrDecimalToUintn (++Str
);
162 Str
= StrStr (Str
, L
".");
164 return EFI_INVALID_PARAMETER
;
167 Ip
->v4
.Addr
[2] = (UINT8
)StrDecimalToUintn (++Str
);
169 Str
= StrStr (Str
, L
".");
171 return EFI_INVALID_PARAMETER
;
174 Ip
->v4
.Addr
[3] = (UINT8
)StrDecimalToUintn (++Str
);
185 CHAR16 CmdBoolean
[2];
190 // Set MaxCmdLine to 3 to give space for carriage return (when the user
191 // hits enter) and terminal '\0'.
192 Status
= GetHIInputStr (CmdBoolean
, 3);
193 if (EFI_ERROR(Status
)) {
195 } else if ((CmdBoolean
[0] == L
'y') || (CmdBoolean
[0] == L
'Y')) {
196 if (Value
) *Value
= TRUE
;
198 } else if ((CmdBoolean
[0] == L
'n') || (CmdBoolean
[0] == L
'N')) {
199 if (Value
) *Value
= FALSE
;
206 HasFilePathEfiExtension (
210 return (StrCmp (FilePath
+ (StrSize (FilePath
) / sizeof (CHAR16
)) - 5, L
".EFI") == 0) ||
211 (StrCmp (FilePath
+ (StrSize (FilePath
) / sizeof (CHAR16
)) - 5, L
".efi") == 0);
214 // Return the last non end-type Device Path Node from a Device Path
216 GetLastDevicePathNode (
217 IN EFI_DEVICE_PATH
* DevicePath
220 EFI_DEVICE_PATH
* PrevDevicePathNode
;
222 PrevDevicePathNode
= DevicePath
;
223 while (!IsDevicePathEndType (DevicePath
)) {
224 PrevDevicePathNode
= DevicePath
;
225 DevicePath
= NextDevicePathNode (DevicePath
);
228 return PrevDevicePathNode
;
232 GenerateDeviceDescriptionName (
233 IN EFI_HANDLE Handle
,
234 IN OUT CHAR16
* Description
238 EFI_COMPONENT_NAME_PROTOCOL
* ComponentName2Protocol
;
239 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
* DevicePathToTextProtocol
;
240 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
242 CHAR16
* DevicePathTxt
;
243 EFI_DEVICE_PATH
* DevicePathNode
;
245 ComponentName2Protocol
= NULL
;
246 Status
= gBS
->HandleProtocol (Handle
, &gEfiComponentName2ProtocolGuid
, (VOID
**)&ComponentName2Protocol
);
247 if (!EFI_ERROR(Status
)) {
248 //TODO: Fixme. we must find the best langague
249 Status
= ComponentName2Protocol
->GetDriverName (ComponentName2Protocol
,"en",&DriverName
);
250 if (!EFI_ERROR(Status
)) {
251 StrnCpy (Description
, DriverName
, BOOT_DEVICE_DESCRIPTION_MAX
);
255 if (EFI_ERROR(Status
)) {
256 // Use the lastest non null entry of the Device path as a description
257 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
258 if (EFI_ERROR(Status
)) {
262 // Convert the last non end-type Device Path Node in text for the description
263 DevicePathNode
= GetLastDevicePathNode (DevicePathProtocol
);
264 Status
= gBS
->LocateProtocol (&gEfiDevicePathToTextProtocolGuid
, NULL
, (VOID
**)&DevicePathToTextProtocol
);
265 ASSERT_EFI_ERROR(Status
);
266 DevicePathTxt
= DevicePathToTextProtocol
->ConvertDevicePathToText (DevicePathNode
, TRUE
, TRUE
);
267 StrnCpy (Description
, DevicePathTxt
, BOOT_DEVICE_DESCRIPTION_MAX
);
268 FreePool (DevicePathTxt
);
276 IN CHAR16
* BootOption
280 BDS_LOAD_OPTION
*BdsLoadOption
;
282 Status
= BootOptionFromLoadOptionVariable (BootOption
, &BdsLoadOption
);
283 if (!EFI_ERROR(Status
)) {
284 Status
= BootOptionStart (BdsLoadOption
);
285 FreePool (BdsLoadOption
);
287 if (!EFI_ERROR(Status
)) {
288 Status
= EFI_SUCCESS
;
290 Status
= EFI_NOT_STARTED
;
293 Status
= EFI_NOT_FOUND
;
299 GetUnalignedDevicePathSize (
300 IN EFI_DEVICE_PATH
* DevicePath
304 EFI_DEVICE_PATH
* AlignedDevicePath
;
306 if ((UINTN
)DevicePath
& 0x1) {
307 AlignedDevicePath
= DuplicateDevicePath (DevicePath
);
308 Size
= GetDevicePathSize (AlignedDevicePath
);
309 FreePool (AlignedDevicePath
);
311 Size
= GetDevicePathSize (DevicePath
);
317 GetAlignedDevicePath (
318 IN EFI_DEVICE_PATH
* DevicePath
321 if ((UINTN
)DevicePath
& 0x1) {
322 return DuplicateDevicePath (DevicePath
);