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