]>
Commit | Line | Data |
---|---|---|
ea46ebbe | 1 | /** @file |
2 | * | |
3 | * Copyright (c) 2011, ARM Limited. All rights reserved. | |
4 | * | |
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 | |
9 | * | |
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. | |
12 | * | |
13 | **/ | |
14 | ||
15 | #include "BdsInternal.h" | |
16 | ||
17 | EFI_STATUS | |
18 | GetEnvironmentVariable ( | |
19 | IN CONST CHAR16* VariableName, | |
20 | IN VOID* DefaultValue, | |
21 | IN OUT UINTN* Size, | |
22 | OUT VOID** Value | |
23 | ) | |
24 | { | |
25 | EFI_STATUS Status; | |
26 | UINTN VariableSize; | |
27 | ||
28 | // Try to get the variable size. | |
29 | *Value = NULL; | |
30 | VariableSize = 0; | |
31 | Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value); | |
32 | if (Status == EFI_NOT_FOUND) { | |
33 | if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) { | |
34 | // If the environment variable does not exist yet then set it with the default value | |
35 | Status = gRT->SetVariable ( | |
36 | (CHAR16*)VariableName, | |
37 | &gEfiGlobalVariableGuid, | |
38 | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
39 | *Size, | |
40 | DefaultValue | |
41 | ); | |
42 | *Value = DefaultValue; | |
43 | } else { | |
44 | return EFI_NOT_FOUND; | |
45 | } | |
46 | } else if (Status == EFI_BUFFER_TOO_SMALL) { | |
47 | // Get the environment variable value | |
48 | *Value = AllocatePool (VariableSize); | |
49 | if (*Value == NULL) { | |
50 | return EFI_OUT_OF_RESOURCES; | |
51 | } | |
52 | ||
53 | Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value); | |
54 | if (EFI_ERROR (Status)) { | |
55 | FreePool(*Value); | |
56 | return EFI_INVALID_PARAMETER; | |
57 | } | |
58 | ||
59 | if (Size) { | |
60 | *Size = VariableSize; | |
61 | } | |
62 | } else { | |
63 | *Value = DefaultValue; | |
64 | return Status; | |
65 | } | |
66 | ||
67 | return EFI_SUCCESS; | |
68 | } | |
69 | ||
70 | EFI_STATUS | |
74b96132 | 71 | EditHIInputStr ( |
72 | IN OUT CHAR16 *CmdLine, | |
ea46ebbe | 73 | IN UINTN MaxCmdLine |
74 | ) | |
75 | { | |
76 | UINTN CmdLineIndex; | |
77 | UINTN WaitIndex; | |
78 | CHAR8 Char; | |
79 | EFI_INPUT_KEY Key; | |
80 | EFI_STATUS Status; | |
81 | ||
74b96132 | 82 | Print (CmdLine); |
ea46ebbe | 83 | |
74b96132 | 84 | for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) { |
ea46ebbe | 85 | Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex); |
86 | ASSERT_EFI_ERROR (Status); | |
87 | ||
88 | Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); | |
89 | ASSERT_EFI_ERROR (Status); | |
90 | ||
91 | // Unicode character is valid when Scancode is NUll | |
92 | if (Key.ScanCode == SCAN_NULL) { | |
93 | // Scan code is NUll, hence read Unicode character | |
94 | Char = (CHAR8)Key.UnicodeChar; | |
95 | } else { | |
96 | Char = CHAR_NULL; | |
97 | } | |
98 | ||
99 | if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) { | |
100 | CmdLine[CmdLineIndex] = '\0'; | |
74b96132 | 101 | Print (L"\n\r"); |
ea46ebbe | 102 | |
103 | return EFI_SUCCESS; | |
74b96132 | 104 | } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){ |
ea46ebbe | 105 | if (CmdLineIndex != 0) { |
106 | CmdLineIndex--; | |
74b96132 | 107 | Print (L"\b \b"); |
ea46ebbe | 108 | } |
109 | } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) { | |
110 | return EFI_INVALID_PARAMETER; | |
111 | } else { | |
74b96132 | 112 | CmdLine[CmdLineIndex++] = Key.UnicodeChar; |
113 | Print (L"%c", Key.UnicodeChar); | |
ea46ebbe | 114 | } |
115 | } | |
116 | ||
117 | return EFI_SUCCESS; | |
118 | } | |
119 | ||
74b96132 | 120 | EFI_STATUS |
121 | GetHIInputStr ( | |
122 | IN OUT CHAR16 *CmdLine, | |
123 | IN UINTN MaxCmdLine | |
124 | ) | |
125 | { | |
126 | EFI_STATUS Status; | |
127 | ||
128 | // For a new input just passed an empty string | |
129 | CmdLine[0] = L'\0'; | |
130 | ||
131 | Status = EditHIInputStr (CmdLine, MaxCmdLine); | |
132 | ||
133 | return Status; | |
134 | } | |
135 | ||
136 | EFI_STATUS | |
137 | EditHIInputAscii ( | |
138 | IN OUT CHAR8 *CmdLine, | |
139 | IN UINTN MaxCmdLine | |
140 | ) | |
141 | { | |
142 | CHAR16* Str; | |
143 | EFI_STATUS Status; | |
144 | ||
145 | Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16)); | |
146 | AsciiStrToUnicodeStr (CmdLine, Str); | |
147 | ||
148 | Status = EditHIInputStr (Str, MaxCmdLine); | |
149 | ||
150 | if (!EFI_ERROR(Status)) { | |
151 | UnicodeStrToAsciiStr (Str, CmdLine); | |
152 | } | |
153 | FreePool (Str); | |
154 | ||
155 | return Status; | |
156 | } | |
157 | ||
ea46ebbe | 158 | EFI_STATUS |
159 | GetHIInputAscii ( | |
160 | IN OUT CHAR8 *CmdLine, | |
161 | IN UINTN MaxCmdLine | |
162 | ) | |
163 | { | |
164 | // For a new input just passed an empty string | |
165 | CmdLine[0] = '\0'; | |
166 | ||
167 | return EditHIInputAscii (CmdLine,MaxCmdLine); | |
168 | } | |
169 | ||
170 | EFI_STATUS | |
171 | GetHIInputInteger ( | |
172 | OUT UINTN *Integer | |
173 | ) | |
174 | { | |
74b96132 | 175 | CHAR16 CmdLine[255]; |
ea46ebbe | 176 | EFI_STATUS Status; |
177 | ||
178 | CmdLine[0] = '\0'; | |
74b96132 | 179 | Status = EditHIInputStr (CmdLine, 255); |
ea46ebbe | 180 | if (!EFI_ERROR(Status)) { |
74b96132 | 181 | *Integer = StrDecimalToUintn (CmdLine); |
ea46ebbe | 182 | } |
183 | ||
184 | return Status; | |
185 | } | |
186 | ||
187 | EFI_STATUS | |
188 | GetHIInputIP ( | |
189 | OUT EFI_IP_ADDRESS *Ip | |
190 | ) | |
191 | { | |
74b96132 | 192 | CHAR16 CmdLine[255]; |
193 | CHAR16 *Str; | |
ea46ebbe | 194 | EFI_STATUS Status; |
195 | ||
196 | CmdLine[0] = '\0'; | |
74b96132 | 197 | Status = EditHIInputStr (CmdLine,255); |
ea46ebbe | 198 | if (!EFI_ERROR(Status)) { |
199 | Str = CmdLine; | |
74b96132 | 200 | Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str); |
ea46ebbe | 201 | |
74b96132 | 202 | Str = StrStr (Str, L"."); |
ea46ebbe | 203 | if (Str == NULL) { |
204 | return EFI_INVALID_PARAMETER; | |
205 | } | |
206 | ||
74b96132 | 207 | Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str); |
ea46ebbe | 208 | |
74b96132 | 209 | Str = StrStr (Str, L"."); |
ea46ebbe | 210 | if (Str == NULL) { |
211 | return EFI_INVALID_PARAMETER; | |
212 | } | |
213 | ||
74b96132 | 214 | Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str); |
ea46ebbe | 215 | |
74b96132 | 216 | Str = StrStr (Str, L"."); |
ea46ebbe | 217 | if (Str == NULL) { |
218 | return EFI_INVALID_PARAMETER; | |
219 | } | |
220 | ||
74b96132 | 221 | Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str); |
ea46ebbe | 222 | } |
223 | ||
224 | return Status; | |
225 | } | |
226 | ||
227 | EFI_STATUS | |
228 | GetHIInputBoolean ( | |
229 | OUT BOOLEAN *Value | |
230 | ) | |
231 | { | |
74b96132 | 232 | CHAR16 CmdBoolean[2]; |
ea46ebbe | 233 | EFI_STATUS Status; |
234 | ||
235 | while(1) { | |
236 | Print (L"[y/n] "); | |
74b96132 | 237 | Status = GetHIInputStr (CmdBoolean,2); |
ea46ebbe | 238 | if (EFI_ERROR(Status)) { |
239 | return Status; | |
74b96132 | 240 | } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) { |
ea46ebbe | 241 | if (Value) *Value = TRUE; |
242 | return EFI_SUCCESS; | |
74b96132 | 243 | } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) { |
ea46ebbe | 244 | if (Value) *Value = FALSE; |
245 | return EFI_SUCCESS; | |
246 | } | |
247 | } | |
248 | } | |
249 | ||
250 | BOOLEAN | |
251 | HasFilePathEfiExtension ( | |
252 | IN CHAR16* FilePath | |
253 | ) | |
254 | { | |
255 | return (StrCmp (FilePath + (StrSize(FilePath)/sizeof(CHAR16)) - 5, L".efi") == 0); | |
256 | } | |
257 | ||
258 | // Return the last non end-type Device Path Node from a Device Path | |
259 | EFI_DEVICE_PATH* | |
260 | GetLastDevicePathNode ( | |
261 | IN EFI_DEVICE_PATH* DevicePath | |
262 | ) | |
263 | { | |
264 | EFI_DEVICE_PATH* PrevDevicePathNode; | |
265 | ||
266 | PrevDevicePathNode = DevicePath; | |
267 | while (!IsDevicePathEndType (DevicePath)) { | |
268 | PrevDevicePathNode = DevicePath; | |
269 | DevicePath = NextDevicePathNode (DevicePath); | |
270 | } | |
271 | ||
272 | return PrevDevicePathNode; | |
273 | } | |
274 | ||
275 | EFI_STATUS | |
276 | GenerateDeviceDescriptionName ( | |
277 | IN EFI_HANDLE Handle, | |
278 | IN OUT CHAR16* Description | |
279 | ) | |
280 | { | |
281 | EFI_STATUS Status; | |
282 | EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol; | |
283 | EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; | |
284 | EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; | |
285 | CHAR16* DriverName; | |
286 | CHAR16* DevicePathTxt; | |
287 | EFI_DEVICE_PATH* DevicePathNode; | |
288 | ||
289 | ComponentName2Protocol = NULL; | |
290 | Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol); | |
291 | if (!EFI_ERROR(Status)) { | |
292 | //TODO: Fixme. we must find the best langague | |
293 | Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName); | |
294 | if (!EFI_ERROR(Status)) { | |
295 | StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX); | |
296 | } | |
297 | } | |
298 | ||
299 | if (EFI_ERROR(Status)) { | |
300 | // Use the lastest non null entry of the Device path as a description | |
301 | Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); | |
302 | if (EFI_ERROR(Status)) { | |
303 | return Status; | |
304 | } | |
305 | ||
306 | // Convert the last non end-type Device Path Node in text for the description | |
307 | DevicePathNode = GetLastDevicePathNode (DevicePathProtocol); | |
308 | Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); | |
309 | ASSERT_EFI_ERROR(Status); | |
310 | DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE); | |
311 | StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX); | |
312 | FreePool (DevicePathTxt); | |
313 | } | |
314 | ||
315 | return EFI_SUCCESS; | |
316 | } | |
317 | ||
318 | EFI_STATUS | |
319 | BdsStartBootOption ( | |
320 | IN CHAR16* BootOption | |
321 | ) | |
322 | { | |
323 | EFI_STATUS Status; | |
324 | EFI_LOAD_OPTION EfiLoadOption; | |
325 | UINTN EfiLoadOptionSize; | |
326 | BDS_LOAD_OPTION *BdsLoadOption; | |
327 | ||
328 | Status = GetEnvironmentVariable (BootOption, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption); | |
329 | if (!EFI_ERROR(Status)) { | |
330 | Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, &BdsLoadOption); | |
331 | if (!EFI_ERROR(Status)) { | |
332 | Status = BootOptionStart (BdsLoadOption); | |
333 | FreePool (BdsLoadOption); | |
334 | } | |
335 | ||
336 | if (!EFI_ERROR(Status)) { | |
337 | Status = EFI_SUCCESS; | |
338 | } else { | |
339 | Status = EFI_NOT_STARTED; | |
340 | } | |
341 | } else { | |
342 | Status = EFI_NOT_FOUND; | |
343 | } | |
344 | return Status; | |
345 | } |