]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Application/Shell/ConsoleWrappers.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Application / Shell / ConsoleWrappers.c
1 /** @file
2 Function definitions for shell simple text in and out on top of file handles.
3
4 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "Shell.h"
11
12 extern BOOLEAN AsciiRedirection;
13
14 typedef struct {
15 EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
16 SHELL_FILE_HANDLE FileHandle;
17 EFI_HANDLE TheHandle;
18 UINT64 RemainingBytesOfInputFile;
19 } SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
20
21 typedef struct {
22 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;
23 SHELL_FILE_HANDLE FileHandle;
24 EFI_HANDLE TheHandle;
25 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalSimpleTextOut;
26 } SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
27
28 /**
29 Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
30 Signal the event if there is key available
31
32 @param Event Indicates the event that invoke this function.
33 @param Context Indicates the calling context.
34
35 **/
36 VOID
37 EFIAPI
38 ConInWaitForKey (
39 IN EFI_EVENT Event,
40 IN VOID *Context
41 )
42 {
43 gBS->SignalEvent (Event);
44 }
45
46 /**
47 Reset function for the fake simple text input.
48
49 @param[in] This A pointer to the SimpleTextIn structure.
50 @param[in] ExtendedVerification TRUE for extra validation, FALSE otherwise.
51
52 @retval EFI_SUCCESS The reset was successful.
53 **/
54 EFI_STATUS
55 EFIAPI
56 FileBasedSimpleTextInReset (
57 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
58 IN BOOLEAN ExtendedVerification
59 )
60 {
61 return (EFI_SUCCESS);
62 }
63
64 /**
65 ReadKeyStroke function for the fake simple text input.
66
67 @param[in] This A pointer to the SimpleTextIn structure.
68 @param[in, out] Key A pointer to the Key structure to fill.
69
70 @retval EFI_SUCCESS The read was successful.
71 **/
72 EFI_STATUS
73 EFIAPI
74 FileBasedSimpleTextInReadKeyStroke (
75 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
76 IN OUT EFI_INPUT_KEY *Key
77 )
78 {
79 UINTN Size;
80 UINTN CharSize;
81
82 //
83 // Verify the parameters
84 //
85 if ((Key == NULL) || (This == NULL)) {
86 return (EFI_INVALID_PARAMETER);
87 }
88
89 //
90 // Check if we have any characters left in the stream.
91 //
92 if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile == 0) {
93 return (EFI_NOT_READY);
94 }
95
96 Size = sizeof (CHAR16);
97
98 if (!AsciiRedirection) {
99 CharSize = sizeof (CHAR16);
100 } else {
101 CharSize = sizeof (CHAR8);
102 }
103
104 //
105 // Decrement the amount of free space by Size or set to zero (for odd length files)
106 //
107 if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > CharSize) {
108 ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= CharSize;
109 } else {
110 ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile = 0;
111 }
112
113 Key->ScanCode = 0;
114 return (ShellInfoObject.NewEfiShellProtocol->ReadFile (
115 ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->FileHandle,
116 &Size,
117 &Key->UnicodeChar
118 ));
119 }
120
121 /**
122 Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
123 SHELL_FILE_HANDLE to support redirecting input from a file.
124
125 @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
126 @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
127
128 @retval NULL There was insufficient memory available.
129 @return A pointer to the allocated protocol structure;
130 **/
131 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *
132 CreateSimpleTextInOnFile (
133 IN SHELL_FILE_HANDLE FileHandleToUse,
134 IN EFI_HANDLE *HandleLocation
135 )
136 {
137 SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ProtocolToReturn;
138 EFI_STATUS Status;
139 UINT64 CurrentPosition;
140 UINT64 FileSize;
141
142 if ((HandleLocation == NULL) || (FileHandleToUse == NULL)) {
143 return (NULL);
144 }
145
146 ProtocolToReturn = AllocateZeroPool (sizeof (SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL));
147 if (ProtocolToReturn == NULL) {
148 return (NULL);
149 }
150
151 ShellGetFileSize (FileHandleToUse, &FileSize);
152 ShellGetFilePosition (FileHandleToUse, &CurrentPosition);
153
154 //
155 // Initialize the protocol members
156 //
157 ProtocolToReturn->RemainingBytesOfInputFile = FileSize - CurrentPosition;
158 ProtocolToReturn->FileHandle = FileHandleToUse;
159 ProtocolToReturn->SimpleTextIn.Reset = FileBasedSimpleTextInReset;
160 ProtocolToReturn->SimpleTextIn.ReadKeyStroke = FileBasedSimpleTextInReadKeyStroke;
161
162 Status = gBS->CreateEvent (
163 EVT_NOTIFY_WAIT,
164 TPL_NOTIFY,
165 ConInWaitForKey,
166 &ProtocolToReturn->SimpleTextIn,
167 &ProtocolToReturn->SimpleTextIn.WaitForKey
168 );
169
170 if (EFI_ERROR (Status)) {
171 FreePool (ProtocolToReturn);
172 return (NULL);
173 }
174
175 /// @todo possibly also install SimpleTextInputEx on the handle at this point.
176 Status = gBS->InstallProtocolInterface (
177 &(ProtocolToReturn->TheHandle),
178 &gEfiSimpleTextInProtocolGuid,
179 EFI_NATIVE_INTERFACE,
180 &(ProtocolToReturn->SimpleTextIn)
181 );
182 if (!EFI_ERROR (Status)) {
183 *HandleLocation = ProtocolToReturn->TheHandle;
184 return ((EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)ProtocolToReturn);
185 } else {
186 FreePool (ProtocolToReturn);
187 return (NULL);
188 }
189 }
190
191 /**
192 Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
193 SHELL_FILE_HANDLE to support redirecting input from a file.
194
195 @param[in] SimpleTextIn The pointer to the SimpleTextIn to close.
196
197 @retval EFI_SUCCESS The object was closed.
198 **/
199 EFI_STATUS
200 CloseSimpleTextInOnFile (
201 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn
202 )
203 {
204 EFI_STATUS Status;
205 EFI_STATUS Status1;
206
207 if (SimpleTextIn == NULL) {
208 return (EFI_INVALID_PARAMETER);
209 }
210
211 Status = gBS->CloseEvent (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn.WaitForKey);
212
213 Status1 = gBS->UninstallProtocolInterface (
214 ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->TheHandle,
215 &gEfiSimpleTextInProtocolGuid,
216 &(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn)
217 );
218
219 FreePool (SimpleTextIn);
220 if (!EFI_ERROR (Status)) {
221 return (Status1);
222 } else {
223 return (Status);
224 }
225 }
226
227 /**
228 Reset the text output device hardware and optionally run diagnostics.
229
230 @param This pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
231 @param ExtendedVerification Indicates that a more extensive test may be performed
232
233 @retval EFI_SUCCESS The text output device was reset.
234 **/
235 EFI_STATUS
236 EFIAPI
237 FileBasedSimpleTextOutReset (
238 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
239 IN BOOLEAN ExtendedVerification
240 )
241 {
242 return (EFI_SUCCESS);
243 }
244
245 /**
246 Verifies that all characters in a Unicode string can be output to the
247 target device.
248
249 @param[in] This Protocol instance pointer.
250 @param[in] WString The NULL-terminated Unicode string to be examined.
251
252 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
253 **/
254 EFI_STATUS
255 EFIAPI
256 FileBasedSimpleTextOutTestString (
257 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
258 IN CHAR16 *WString
259 )
260 {
261 return (EFI_SUCCESS);
262 }
263
264 /**
265 Returns information for an available text mode that the output device(s)
266 supports.
267
268 @param[in] This Protocol instance pointer.
269 @param[in] ModeNumber The mode number to return information on.
270 @param[out] Columns Upon return, the number of columns in the selected geometry
271 @param[out] Rows Upon return, the number of rows in the selected geometry
272
273 @retval EFI_UNSUPPORTED The mode number was not valid.
274 **/
275 EFI_STATUS
276 EFIAPI
277 FileBasedSimpleTextOutQueryMode (
278 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
279 IN UINTN ModeNumber,
280 OUT UINTN *Columns,
281 OUT UINTN *Rows
282 )
283 {
284 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol;
285
286 PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
287
288 // Pass the QueryMode call thru to the original SimpleTextOutProtocol
289 return (PassThruProtocol->QueryMode (
290 PassThruProtocol,
291 ModeNumber,
292 Columns,
293 Rows
294 ));
295 }
296
297 /**
298 Sets the output device(s) to a specified mode.
299
300 @param[in] This Protocol instance pointer.
301 @param[in] ModeNumber The mode number to set.
302
303 @retval EFI_UNSUPPORTED The mode number was not valid.
304 **/
305 EFI_STATUS
306 EFIAPI
307 FileBasedSimpleTextOutSetMode (
308 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
309 IN UINTN ModeNumber
310 )
311 {
312 return (EFI_UNSUPPORTED);
313 }
314
315 /**
316 Sets the background and foreground colors for the OutputString () and
317 ClearScreen () functions.
318
319 @param[in] This Protocol instance pointer.
320 @param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and
321 bits 4..6 are the background color. All other bits are undefined
322 and must be zero. The valid Attributes are defined in this file.
323
324 @retval EFI_SUCCESS The attribute was set.
325 **/
326 EFI_STATUS
327 EFIAPI
328 FileBasedSimpleTextOutSetAttribute (
329 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
330 IN UINTN Attribute
331 )
332 {
333 return (EFI_SUCCESS);
334 }
335
336 /**
337 Clears the output device(s) display to the currently selected background
338 color.
339
340 @param[in] This Protocol instance pointer.
341
342 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
343 **/
344 EFI_STATUS
345 EFIAPI
346 FileBasedSimpleTextOutClearScreen (
347 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
348 )
349 {
350 return (EFI_SUCCESS);
351 }
352
353 /**
354 Sets the current coordinates of the cursor position
355
356 @param[in] This Protocol instance pointer.
357 @param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode
358 @param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode
359
360 @retval EFI_SUCCESS The operation completed successfully.
361 **/
362 EFI_STATUS
363 EFIAPI
364 FileBasedSimpleTextOutSetCursorPosition (
365 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
366 IN UINTN Column,
367 IN UINTN Row
368 )
369 {
370 return (EFI_SUCCESS);
371 }
372
373 /**
374 Makes the cursor visible or invisible
375
376 @param[in] This Protocol instance pointer.
377 @param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is
378 set to be invisible.
379
380 @retval EFI_SUCCESS The operation completed successfully.
381 **/
382 EFI_STATUS
383 EFIAPI
384 FileBasedSimpleTextOutEnableCursor (
385 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
386 IN BOOLEAN Visible
387 )
388 {
389 return (EFI_SUCCESS);
390 }
391
392 /**
393 Write a Unicode string to the output device.
394
395 @param[in] This Protocol instance pointer.
396 @param[in] WString The NULL-terminated Unicode string to be displayed on the output
397 device(s). All output devices must also support the Unicode
398 drawing defined in this file.
399 @retval EFI_SUCCESS The string was output to the device.
400 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output
401 the text.
402 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
403 defined text mode.
404 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
405 characters in the Unicode string could not be
406 rendered and were skipped.
407 **/
408 EFI_STATUS
409 EFIAPI
410 FileBasedSimpleTextOutOutputString (
411 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
412 IN CHAR16 *WString
413 )
414 {
415 UINTN Size;
416
417 Size = StrLen (WString) * sizeof (CHAR16);
418 return (ShellInfoObject.NewEfiShellProtocol->WriteFile (
419 ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->FileHandle,
420 &Size,
421 WString
422 ));
423 }
424
425 /**
426 Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
427 SHELL_FILE_HANDLE to support redirecting output from a file.
428
429 @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
430 @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
431 @param[in] OriginalProtocol The pointer to the original output protocol for pass thru of functions.
432
433 @retval NULL There was insufficient memory available.
434 @return A pointer to the allocated protocol structure;
435 **/
436 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *
437 CreateSimpleTextOutOnFile (
438 IN SHELL_FILE_HANDLE FileHandleToUse,
439 IN EFI_HANDLE *HandleLocation,
440 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
441 )
442 {
443 SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ProtocolToReturn;
444 EFI_STATUS Status;
445
446 if ((HandleLocation == NULL) || (FileHandleToUse == NULL)) {
447 return (NULL);
448 }
449
450 ProtocolToReturn = AllocateZeroPool (sizeof (SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL));
451 if (ProtocolToReturn == NULL) {
452 return (NULL);
453 }
454
455 ProtocolToReturn->FileHandle = FileHandleToUse;
456 ProtocolToReturn->OriginalSimpleTextOut = OriginalProtocol;
457 ProtocolToReturn->SimpleTextOut.Reset = FileBasedSimpleTextOutReset;
458 ProtocolToReturn->SimpleTextOut.TestString = FileBasedSimpleTextOutTestString;
459 ProtocolToReturn->SimpleTextOut.QueryMode = FileBasedSimpleTextOutQueryMode;
460 ProtocolToReturn->SimpleTextOut.SetMode = FileBasedSimpleTextOutSetMode;
461 ProtocolToReturn->SimpleTextOut.SetAttribute = FileBasedSimpleTextOutSetAttribute;
462 ProtocolToReturn->SimpleTextOut.ClearScreen = FileBasedSimpleTextOutClearScreen;
463 ProtocolToReturn->SimpleTextOut.SetCursorPosition = FileBasedSimpleTextOutSetCursorPosition;
464 ProtocolToReturn->SimpleTextOut.EnableCursor = FileBasedSimpleTextOutEnableCursor;
465 ProtocolToReturn->SimpleTextOut.OutputString = FileBasedSimpleTextOutOutputString;
466 ProtocolToReturn->SimpleTextOut.Mode = AllocateZeroPool (sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));
467 if (ProtocolToReturn->SimpleTextOut.Mode == NULL) {
468 FreePool (ProtocolToReturn);
469 return (NULL);
470 }
471
472 ProtocolToReturn->SimpleTextOut.Mode->MaxMode = OriginalProtocol->Mode->MaxMode;
473 ProtocolToReturn->SimpleTextOut.Mode->Mode = OriginalProtocol->Mode->Mode;
474 ProtocolToReturn->SimpleTextOut.Mode->Attribute = OriginalProtocol->Mode->Attribute;
475 ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = OriginalProtocol->Mode->CursorColumn;
476 ProtocolToReturn->SimpleTextOut.Mode->CursorRow = OriginalProtocol->Mode->CursorRow;
477 ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;
478
479 Status = gBS->InstallProtocolInterface (
480 &(ProtocolToReturn->TheHandle),
481 &gEfiSimpleTextOutProtocolGuid,
482 EFI_NATIVE_INTERFACE,
483 &(ProtocolToReturn->SimpleTextOut)
484 );
485 if (!EFI_ERROR (Status)) {
486 *HandleLocation = ProtocolToReturn->TheHandle;
487 return ((EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)ProtocolToReturn);
488 } else {
489 SHELL_FREE_NON_NULL (ProtocolToReturn->SimpleTextOut.Mode);
490 SHELL_FREE_NON_NULL (ProtocolToReturn);
491 return (NULL);
492 }
493 }
494
495 /**
496 Function to close a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
497 SHELL_FILE_HANDLE to support redirecting output from a file.
498
499 @param[in] SimpleTextOut The pointer to the SimpleTextOUT to close.
500
501 @retval EFI_SUCCESS The object was closed.
502 **/
503 EFI_STATUS
504 CloseSimpleTextOutOnFile (
505 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut
506 )
507 {
508 EFI_STATUS Status;
509
510 if (SimpleTextOut == NULL) {
511 return (EFI_INVALID_PARAMETER);
512 }
513
514 Status = gBS->UninstallProtocolInterface (
515 ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)SimpleTextOut)->TheHandle,
516 &gEfiSimpleTextOutProtocolGuid,
517 &(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)SimpleTextOut)->SimpleTextOut)
518 );
519 FreePool (SimpleTextOut->Mode);
520 FreePool (SimpleTextOut);
521 return (Status);
522 }