ArmPlatformPkg/Bds: Make ".EFI" files recognizable as EFI applications
[mirror_edk2.git] / ArmPlatformPkg / Bds / BdsHelper.c
CommitLineData
1e57a462 1/** @file\r
2*\r
7ff3b949 3* Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
1e57a462 4* \r
5* This program and the accompanying materials \r
6* are licensed and made available under the terms and conditions of the BSD License \r
7* which accompanies this distribution. The full text of the license may be found at \r
8* http://opensource.org/licenses/bsd-license.php \r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12*\r
13**/\r
14\r
15#include "BdsInternal.h"\r
16\r
17EFI_STATUS\r
18EditHIInputStr (\r
19 IN OUT CHAR16 *CmdLine,\r
20 IN UINTN MaxCmdLine\r
21 )\r
22{\r
23 UINTN CmdLineIndex;\r
24 UINTN WaitIndex;\r
25 CHAR8 Char;\r
26 EFI_INPUT_KEY Key;\r
27 EFI_STATUS Status;\r
28\r
7ff3b949
RH
29 // The command line must be at least one character long\r
30 ASSERT (MaxCmdLine > 0);\r
31\r
7ff3b949
RH
32 // Ensure the last character of the buffer is the NULL character\r
33 CmdLine[MaxCmdLine - 1] = '\0';\r
34\r
40761653
OM
35 Print (CmdLine);\r
36\r
7ff3b949 37 // To prevent a buffer overflow, we only allow to enter (MaxCmdLine-1) characters\r
40761653 38 for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine - 1; ) {\r
1e57a462 39 Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);\r
40 ASSERT_EFI_ERROR (Status);\r
41\r
42 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
43 ASSERT_EFI_ERROR (Status);\r
44\r
45 // Unicode character is valid when Scancode is NUll\r
46 if (Key.ScanCode == SCAN_NULL) {\r
47 // Scan code is NUll, hence read Unicode character\r
48 Char = (CHAR8)Key.UnicodeChar;\r
49 } else {\r
50 Char = CHAR_NULL;\r
51 }\r
52\r
53 if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {\r
54 CmdLine[CmdLineIndex] = '\0';\r
55 Print (L"\n\r");\r
56\r
57 return EFI_SUCCESS;\r
58 } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){\r
59 if (CmdLineIndex != 0) {\r
60 CmdLineIndex--;\r
61 Print (L"\b \b");\r
62 }\r
63 } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {\r
64 return EFI_INVALID_PARAMETER;\r
65 } else {\r
66 CmdLine[CmdLineIndex++] = Key.UnicodeChar;\r
67 Print (L"%c", Key.UnicodeChar);\r
68 }\r
69 }\r
70\r
71 return EFI_SUCCESS;\r
72}\r
73\r
74EFI_STATUS\r
75GetHIInputStr (\r
76 IN OUT CHAR16 *CmdLine,\r
77 IN UINTN MaxCmdLine\r
78 )\r
79{\r
80 EFI_STATUS Status;\r
81\r
82 // For a new input just passed an empty string\r
83 CmdLine[0] = L'\0';\r
84\r
85 Status = EditHIInputStr (CmdLine, MaxCmdLine);\r
86\r
87 return Status;\r
88}\r
89\r
90EFI_STATUS\r
91EditHIInputAscii (\r
92 IN OUT CHAR8 *CmdLine,\r
93 IN UINTN MaxCmdLine\r
94 )\r
95{\r
96 CHAR16* Str;\r
97 EFI_STATUS Status;\r
98\r
99 Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));\r
100 AsciiStrToUnicodeStr (CmdLine, Str);\r
101\r
102 Status = EditHIInputStr (Str, MaxCmdLine);\r
103 if (!EFI_ERROR(Status)) {\r
104 UnicodeStrToAsciiStr (Str, CmdLine);\r
105 }\r
106 FreePool (Str);\r
107\r
108 return Status;\r
109}\r
110\r
111EFI_STATUS\r
112GetHIInputAscii (\r
113 IN OUT CHAR8 *CmdLine,\r
114 IN UINTN MaxCmdLine\r
115 )\r
116{\r
117 // For a new input just passed an empty string\r
118 CmdLine[0] = '\0';\r
119\r
120 return EditHIInputAscii (CmdLine,MaxCmdLine);\r
121}\r
122\r
123EFI_STATUS\r
124GetHIInputInteger (\r
125 OUT UINTN *Integer\r
126 )\r
127{\r
128 CHAR16 CmdLine[255];\r
129 EFI_STATUS Status;\r
130\r
131 CmdLine[0] = '\0';\r
132 Status = EditHIInputStr (CmdLine, 255);\r
133 if (!EFI_ERROR(Status)) {\r
134 *Integer = StrDecimalToUintn (CmdLine);\r
135 }\r
136\r
137 return Status;\r
138}\r
139\r
140EFI_STATUS\r
141GetHIInputIP (\r
142 OUT EFI_IP_ADDRESS *Ip\r
143 )\r
144{\r
145 CHAR16 CmdLine[255];\r
146 CHAR16 *Str;\r
147 EFI_STATUS Status;\r
148\r
149 CmdLine[0] = '\0';\r
150 Status = EditHIInputStr (CmdLine,255);\r
151 if (!EFI_ERROR(Status)) {\r
152 Str = CmdLine;\r
153 Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);\r
154\r
155 Str = StrStr (Str, L".");\r
156 if (Str == NULL) {\r
157 return EFI_INVALID_PARAMETER;\r
158 }\r
159\r
160 Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);\r
161\r
162 Str = StrStr (Str, L".");\r
163 if (Str == NULL) {\r
164 return EFI_INVALID_PARAMETER;\r
165 }\r
166\r
167 Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);\r
168\r
169 Str = StrStr (Str, L".");\r
170 if (Str == NULL) {\r
171 return EFI_INVALID_PARAMETER;\r
172 }\r
173\r
174 Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);\r
175 }\r
176\r
177 return Status;\r
178}\r
179\r
180EFI_STATUS\r
181GetHIInputBoolean (\r
182 OUT BOOLEAN *Value\r
183 )\r
184{\r
185 CHAR16 CmdBoolean[2];\r
186 EFI_STATUS Status;\r
187\r
188 while(1) {\r
189 Print (L"[y/n] ");\r
190 Status = GetHIInputStr (CmdBoolean, 2);\r
191 if (EFI_ERROR(Status)) {\r
192 return Status;\r
193 } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {\r
194 if (Value) *Value = TRUE;\r
195 return EFI_SUCCESS;\r
196 } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {\r
197 if (Value) *Value = FALSE;\r
198 return EFI_SUCCESS;\r
199 }\r
200 }\r
201}\r
202\r
203BOOLEAN\r
204HasFilePathEfiExtension (\r
205 IN CHAR16* FilePath\r
206 )\r
207{\r
0d304bef
LL
208 return (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".EFI") == 0) ||\r
209 (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".efi") == 0);\r
1e57a462 210}\r
211\r
212// Return the last non end-type Device Path Node from a Device Path\r
213EFI_DEVICE_PATH*\r
214GetLastDevicePathNode (\r
215 IN EFI_DEVICE_PATH* DevicePath\r
216 )\r
217{\r
218 EFI_DEVICE_PATH* PrevDevicePathNode;\r
219\r
220 PrevDevicePathNode = DevicePath;\r
221 while (!IsDevicePathEndType (DevicePath)) {\r
222 PrevDevicePathNode = DevicePath;\r
223 DevicePath = NextDevicePathNode (DevicePath);\r
224 }\r
225\r
226 return PrevDevicePathNode;\r
227}\r
228\r
229EFI_STATUS\r
230GenerateDeviceDescriptionName (\r
231 IN EFI_HANDLE Handle,\r
232 IN OUT CHAR16* Description\r
233 )\r
234{\r
235 EFI_STATUS Status;\r
236 EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol;\r
237 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
238 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
239 CHAR16* DriverName;\r
240 CHAR16* DevicePathTxt;\r
241 EFI_DEVICE_PATH* DevicePathNode;\r
242\r
243 ComponentName2Protocol = NULL;\r
244 Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);\r
245 if (!EFI_ERROR(Status)) {\r
246 //TODO: Fixme. we must find the best langague\r
247 Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);\r
248 if (!EFI_ERROR(Status)) {\r
249 StrnCpy (Description, DriverName, BOOT_DEVICE_DESCRIPTION_MAX);\r
250 }\r
251 }\r
252\r
253 if (EFI_ERROR(Status)) {\r
254 // Use the lastest non null entry of the Device path as a description\r
255 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
256 if (EFI_ERROR(Status)) {\r
257 return Status;\r
258 }\r
259\r
260 // Convert the last non end-type Device Path Node in text for the description\r
261 DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);\r
262 Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
263 ASSERT_EFI_ERROR(Status);\r
264 DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePathNode, TRUE, TRUE);\r
265 StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);\r
266 FreePool (DevicePathTxt);\r
267 }\r
268\r
269 return EFI_SUCCESS;\r
270}\r
271\r
272EFI_STATUS\r
273BdsStartBootOption (\r
274 IN CHAR16* BootOption\r
275 )\r
276{\r
277 EFI_STATUS Status;\r
278 BDS_LOAD_OPTION *BdsLoadOption;\r
279\r
280 Status = BootOptionFromLoadOptionVariable (BootOption, &BdsLoadOption);\r
281 if (!EFI_ERROR(Status)) {\r
282 Status = BootOptionStart (BdsLoadOption);\r
283 FreePool (BdsLoadOption);\r
284\r
285 if (!EFI_ERROR(Status)) {\r
286 Status = EFI_SUCCESS;\r
287 } else {\r
288 Status = EFI_NOT_STARTED;\r
289 }\r
290 } else {\r
291 Status = EFI_NOT_FOUND;\r
292 }\r
293 return Status;\r
294}\r
295\r
296UINTN\r
297GetUnalignedDevicePathSize (\r
298 IN EFI_DEVICE_PATH* DevicePath\r
299 )\r
300{\r
301 UINTN Size;\r
302 EFI_DEVICE_PATH* AlignedDevicePath;\r
303\r
304 if ((UINTN)DevicePath & 0x1) {\r
305 AlignedDevicePath = DuplicateDevicePath (DevicePath);\r
306 Size = GetDevicePathSize (AlignedDevicePath);\r
307 FreePool (AlignedDevicePath);\r
308 } else {\r
309 Size = GetDevicePathSize (DevicePath);\r
310 }\r
311 return Size;\r
312}\r
313\r
314EFI_DEVICE_PATH*\r
315GetAlignedDevicePath (\r
316 IN EFI_DEVICE_PATH* DevicePath\r
317 )\r
318{\r
319 if ((UINTN)DevicePath & 0x1) {\r
320 return DuplicateDevicePath (DevicePath);\r
321 } else {\r
322 return DevicePath;\r
323 }\r
324}\r
325\r