2 EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
3 StdIn, StdOut, StdErr, etc...).
5 Copyright 2016 Dell Inc.
6 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
7 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "FileHandleInternal.h"
22 File style interface for console (Open).
24 @param[in] This Ignored.
25 @param[out] NewHandle Ignored.
26 @param[in] FileName Ignored.
27 @param[in] OpenMode Ignored.
28 @param[in] Attributes Ignored.
34 FileInterfaceOpenNotFound(
35 IN EFI_FILE_PROTOCOL
*This
,
36 OUT EFI_FILE_PROTOCOL
**NewHandle
,
42 return (EFI_NOT_FOUND
);
46 File style interface for console (Close, Delete, & Flush)
48 @param[in] This Ignored.
54 FileInterfaceNopGeneric(
55 IN EFI_FILE_PROTOCOL
*This
62 File style interface for console (GetPosition).
64 @param[in] This Ignored.
65 @param[out] Position Ignored.
67 @retval EFI_UNSUPPORTED
71 FileInterfaceNopGetPosition(
72 IN EFI_FILE_PROTOCOL
*This
,
76 return (EFI_UNSUPPORTED
);
80 File style interface for console (SetPosition).
82 @param[in] This Ignored.
83 @param[in] Position Ignored.
85 @retval EFI_UNSUPPORTED
89 FileInterfaceNopSetPosition(
90 IN EFI_FILE_PROTOCOL
*This
,
94 return (EFI_UNSUPPORTED
);
98 File style interface for console (GetInfo).
100 @param[in] This Ignored.
101 @param[in] InformationType Ignored.
102 @param[in, out] BufferSize Ignored.
103 @param[out] Buffer Ignored.
105 @retval EFI_UNSUPPORTED
109 FileInterfaceNopGetInfo(
110 IN EFI_FILE_PROTOCOL
*This
,
111 IN EFI_GUID
*InformationType
,
112 IN OUT UINTN
*BufferSize
,
116 return (EFI_UNSUPPORTED
);
120 File style interface for console (SetInfo).
122 @param[in] This Ignored.
123 @param[in] InformationType Ignored.
124 @param[in] BufferSize Ignored.
125 @param[in] Buffer Ignored.
127 @retval EFI_UNSUPPORTED
131 FileInterfaceNopSetInfo(
132 IN EFI_FILE_PROTOCOL
*This
,
133 IN EFI_GUID
*InformationType
,
138 return (EFI_UNSUPPORTED
);
142 File style interface for StdOut (Write).
144 Writes data to the screen.
146 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
147 @param[in, out] BufferSize Size in bytes of Buffer.
148 @param[in] Buffer The pointer to the buffer to write.
150 @retval EFI_UNSUPPORTED No output console is supported.
151 @return A return value from gST->ConOut->OutputString.
155 FileInterfaceStdOutWrite(
156 IN EFI_FILE_PROTOCOL
*This
,
157 IN OUT UINTN
*BufferSize
,
161 if (ShellInfoObject
.ShellInitSettings
.BitUnion
.Bits
.NoConsoleOut
) {
162 return (EFI_UNSUPPORTED
);
164 if (*((CHAR16
*)Buffer
) == gUnicodeFileTag
) {
165 return (gST
->ConOut
->OutputString(gST
->ConOut
, (CHAR16
*)Buffer
+ 1));
167 return (gST
->ConOut
->OutputString(gST
->ConOut
, Buffer
));
171 File style interface for StdIn (Write).
173 @param[in] This Ignored.
174 @param[in, out] BufferSize Ignored.
175 @param[in] Buffer Ignored.
177 @retval EFI_UNSUPPORTED
181 FileInterfaceStdInWrite(
182 IN EFI_FILE_PROTOCOL
*This
,
183 IN OUT UINTN
*BufferSize
,
187 return (EFI_UNSUPPORTED
);
191 File style interface for console StdErr (Write).
193 Writes error to the error output.
195 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
196 @param[in, out] BufferSize Size in bytes of Buffer.
197 @param[in] Buffer The pointer to the buffer to write.
199 @return A return value from gST->StdErr->OutputString.
203 FileInterfaceStdErrWrite(
204 IN EFI_FILE_PROTOCOL
*This
,
205 IN OUT UINTN
*BufferSize
,
209 return (gST
->StdErr
->OutputString(gST
->StdErr
, Buffer
));
213 File style interface for console StdOut (Read).
215 @param[in] This Ignored.
216 @param[in, out] BufferSize Ignored.
217 @param[out] Buffer Ignored.
219 @retval EFI_UNSUPPORTED
223 FileInterfaceStdOutRead(
224 IN EFI_FILE_PROTOCOL
*This
,
225 IN OUT UINTN
*BufferSize
,
229 return (EFI_UNSUPPORTED
);
233 File style interface for console StdErr (Read).
235 @param[in] This Ignored.
236 @param[in, out] BufferSize Ignored.
237 @param[out] Buffer Ignored.
239 @retval EFI_UNSUPPORTED Always.
243 FileInterfaceStdErrRead(
244 IN EFI_FILE_PROTOCOL
*This
,
245 IN OUT UINTN
*BufferSize
,
249 return (EFI_UNSUPPORTED
);
253 File style interface for NUL file (Read).
255 @param[in] This Ignored.
256 @param[in, out] BufferSize Poiner to 0 upon return.
257 @param[out] Buffer Ignored.
259 @retval EFI_SUCCESS Always.
263 FileInterfaceNulRead(
264 IN EFI_FILE_PROTOCOL
*This
,
265 IN OUT UINTN
*BufferSize
,
270 return (EFI_SUCCESS
);
274 File style interface for NUL file (Write).
276 @param[in] This Ignored.
277 @param[in, out] BufferSize Ignored.
278 @param[in] Buffer Ignored.
284 FileInterfaceNulWrite(
285 IN EFI_FILE_PROTOCOL
*This
,
286 IN OUT UINTN
*BufferSize
,
290 return (EFI_SUCCESS
);
294 File style interface for console (Read).
296 This will return a single line of input from the console.
298 @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
299 file handle to read data from. Not used.
300 @param BufferSize On input, the size of the Buffer. On output, the amount
301 of data returned in Buffer. In both cases, the size is
303 @param Buffer The buffer into which the data is read.
306 @retval EFI_SUCCESS The data was read.
307 @retval EFI_NO_MEDIA The device has no medium.
308 @retval EFI_DEVICE_ERROR The device reported an error.
309 @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
310 @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
311 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
312 @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
313 entry. BufferSize has been updated with the size
314 needed to complete the request.
315 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
319 FileInterfaceStdInRead(
320 IN EFI_FILE_PROTOCOL
*This
,
321 IN OUT UINTN
*BufferSize
,
325 CHAR16
*CurrentString
;
327 UINTN Column
; // Column of current cursor
328 UINTN Row
; // Row of current cursor
329 UINTN StartColumn
; // Column at the beginning of the line
330 UINTN Update
; // Line index for update
331 UINTN Delete
; // Num of chars to delete from console after update
332 UINTN StringLen
; // Total length of the line
333 UINTN StringCurPos
; // Line index corresponding to the cursor
334 UINTN MaxStr
; // Maximum possible line length
336 UINTN TotalColumn
; // Num of columns in the console
337 UINTN TotalRow
; // Num of rows in the console
339 UINTN OutputLength
; // Length of the update string
340 UINTN TailRow
; // Row of end of line
341 UINTN TailColumn
; // Column of end of line
344 BUFFER_LIST
*LinePos
;
348 BOOLEAN InTabScrolling
; // Whether in TAB-completion state
349 EFI_SHELL_FILE_INFO
*FoundFileList
;
350 EFI_SHELL_FILE_INFO
*TabLinePos
;
351 EFI_SHELL_FILE_INFO
*TempPos
;
353 CHAR16
*TabOutputStr
;
354 BOOLEAN InQuotationMode
;
356 UINTN TabPos
; // Start index of the string to search for TAB completion.
357 UINTN TabUpdatePos
; // Start index of the string updated by TAB stroke
363 // If buffer is not large enough to hold a CHAR16, return minimum buffer size
365 if (*BufferSize
< sizeof (CHAR16
) * 2) {
366 *BufferSize
= sizeof (CHAR16
) * 2;
367 return (EFI_BUFFER_TOO_SMALL
);
371 CurrentString
= Buffer
;
377 LinePos
= NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
379 InTabScrolling
= FALSE
;
380 Status
= EFI_SUCCESS
;
382 FoundFileList
= NULL
;
390 TabStr
= AllocateZeroPool (*BufferSize
);
391 if (TabStr
== NULL
) {
392 return EFI_OUT_OF_RESOURCES
;
394 TabOutputStr
= AllocateZeroPool (*BufferSize
);
395 if (TabOutputStr
== NULL
) {
397 return EFI_OUT_OF_RESOURCES
;
401 // Get the screen setting and the current cursor location
403 Column
= StartColumn
= gST
->ConOut
->Mode
->CursorColumn
;
404 Row
= gST
->ConOut
->Mode
->CursorRow
;
405 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &TotalColumn
, &TotalRow
);
408 // Limit the line length to the buffer size or the minimun size of the
409 // screen. (The smaller takes effect)
411 MaxStr
= TotalColumn
* (TotalRow
- 1) - StartColumn
;
412 if (MaxStr
> *BufferSize
/ sizeof (CHAR16
)) {
413 MaxStr
= *BufferSize
/ sizeof (CHAR16
);
415 ZeroMem (CurrentString
, MaxStr
* sizeof (CHAR16
));
420 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
421 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
422 if (EFI_ERROR (Status
)) {
427 // Press PageUp or PageDown to scroll the history screen up or down.
428 // Press any other key to quit scrolling.
430 if (Key
.UnicodeChar
== 0 && (Key
.ScanCode
== SCAN_PAGE_UP
|| Key
.ScanCode
== SCAN_PAGE_DOWN
)) {
431 if (Key
.ScanCode
== SCAN_PAGE_UP
) {
432 ConsoleLoggerDisplayHistory(FALSE
, 0, ShellInfoObject
.ConsoleInfo
);
433 } else if (Key
.ScanCode
== SCAN_PAGE_DOWN
) {
434 ConsoleLoggerDisplayHistory(TRUE
, 0, ShellInfoObject
.ConsoleInfo
);
440 ConsoleLoggerStopHistory(ShellInfoObject
.ConsoleInfo
);
446 // If we are quitting TAB scrolling...
448 if (InTabScrolling
&& Key
.UnicodeChar
!= CHAR_TAB
) {
449 if (FoundFileList
!= NULL
) {
450 ShellInfoObject
.NewEfiShellProtocol
->FreeFileList (&FoundFileList
);
451 DEBUG_CODE(FoundFileList
= NULL
;);
453 InTabScrolling
= FALSE
;
456 switch (Key
.UnicodeChar
) {
457 case CHAR_CARRIAGE_RETURN
:
459 // All done, print a newline at the end of the string
461 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
462 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
463 ShellPrintEx ((INT32
)TailColumn
, (INT32
)TailRow
, L
"%N\n");
468 if (StringCurPos
!= 0) {
470 // If not move back beyond string beginning, move all characters behind
471 // the current position one character forward
474 Update
= StringCurPos
;
476 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
479 // Adjust the current column and row
481 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
487 // handle auto complete of file and directory names...
489 if (InTabScrolling
) {
490 ASSERT(FoundFileList
!= NULL
);
491 ASSERT(TabLinePos
!= NULL
);
492 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &TabLinePos
->Link
);
493 if (IsNull(&(FoundFileList
->Link
), &TabLinePos
->Link
)) {
494 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &TabLinePos
->Link
);
499 InQuotationMode
= FALSE
;
500 for (Index
= 0; Index
< StringLen
; Index
++) {
501 if (CurrentString
[Index
] == L
'\"') {
502 InQuotationMode
= (BOOLEAN
)(!InQuotationMode
);
504 if (CurrentString
[Index
] == L
' ' && !InQuotationMode
) {
506 TabUpdatePos
= Index
+ 1;
508 if (CurrentString
[Index
] == L
'\\') {
509 TabUpdatePos
= Index
+ 1;
512 if (StrStr(CurrentString
+ TabPos
, L
":") == NULL
) {
513 Cwd
= ShellInfoObject
.NewEfiShellProtocol
->GetCurDir(NULL
);
515 StrnCpyS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), Cwd
, (*BufferSize
)/sizeof(CHAR16
) - 1);
516 StrCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), L
"\\");
517 if (TabStr
[StrLen(TabStr
)-1] == L
'\\' && *(CurrentString
+ TabPos
) == L
'\\' ) {
518 TabStr
[StrLen(TabStr
)-1] = CHAR_NULL
;
521 (*BufferSize
)/sizeof(CHAR16
),
522 CurrentString
+ TabPos
,
527 StrnCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), CurrentString
+ TabPos
, StringLen
- TabPos
);
530 StrnCpyS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), CurrentString
+ TabPos
, (*BufferSize
)/sizeof(CHAR16
) - 1);
532 StrnCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), L
"*", (*BufferSize
)/sizeof(CHAR16
) - 1 - StrLen(TabStr
));
533 FoundFileList
= NULL
;
534 Status
= ShellInfoObject
.NewEfiShellProtocol
->FindFiles(TabStr
, &FoundFileList
);
535 for ( TempStr
= CurrentString
537 ; TempStr
++); // note the ';'... empty for loop
539 // make sure we have a list before we do anything more...
541 if (EFI_ERROR (Status
) || FoundFileList
== NULL
) {
542 InTabScrolling
= FALSE
;
547 // enumerate through the list of files
549 for ( TempPos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&(FoundFileList
->Link
))
550 ; !IsNull(&FoundFileList
->Link
, &TempPos
->Link
)
551 ; TempPos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &(TempPos
->Link
))
554 // If "cd" is typed, only directory name will be auto-complete filled
555 // in either case . and .. will be removed.
557 if ((((TempStr
[0] == L
'c' || TempStr
[0] == L
'C') &&
558 (TempStr
[1] == L
'd' || TempStr
[1] == L
'D')
559 ) && ((ShellIsDirectory(TempPos
->FullName
) != EFI_SUCCESS
)
560 ||(StrCmp(TempPos
->FileName
, L
".") == 0)
561 ||(StrCmp(TempPos
->FileName
, L
"..") == 0)
562 )) || ((StrCmp(TempPos
->FileName
, L
".") == 0)
563 ||(StrCmp(TempPos
->FileName
, L
"..") == 0))){
564 TabLinePos
= TempPos
;
565 TempPos
= (EFI_SHELL_FILE_INFO
*)(RemoveEntryList(&(TempPos
->Link
))->BackLink
);
566 InternalFreeShellFileInfoNode(TabLinePos
);
569 if (FoundFileList
!= NULL
&& !IsListEmpty(&FoundFileList
->Link
)) {
570 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FoundFileList
->Link
);
571 InTabScrolling
= TRUE
;
573 FreePool(FoundFileList
);
574 FoundFileList
= NULL
;
581 if (Key
.UnicodeChar
>= ' ') {
583 // If we are at the buffer's end, drop the key
585 if (StringLen
== MaxStr
- 1 && (ShellInfoObject
.ViewingSettings
.InsertMode
|| StringCurPos
== StringLen
)) {
589 // If in insert mode, make space by moving each other character 1
590 // space higher in the array
592 if (ShellInfoObject
.ViewingSettings
.InsertMode
) {
593 CopyMem(CurrentString
+ StringCurPos
+ 1, CurrentString
+ StringCurPos
, (StringLen
- StringCurPos
)*sizeof(CurrentString
[0]));
596 CurrentString
[StringCurPos
] = Key
.UnicodeChar
;
597 Update
= StringCurPos
;
605 switch (Key
.ScanCode
) {
608 // Move characters behind current position one character forward
610 if (StringLen
!= 0) {
611 Update
= StringCurPos
;
613 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
619 // Prepare to print the previous command
621 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
622 if (IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
)) {
623 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
629 // Prepare to print the next command
631 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
632 if (NewPos
== (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
633 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
639 // Adjust current cursor position
641 if (StringCurPos
!= 0) {
643 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
649 // Adjust current cursor position
651 if (StringCurPos
< StringLen
) {
653 MoveCursorForward (TotalColumn
, TotalRow
, &Column
, &Row
);
659 // Move current cursor position to the beginning of the command line
661 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
662 Column
= StartColumn
;
668 // Move current cursor position to the end of the command line
670 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
671 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
674 StringCurPos
= StringLen
;
679 // Prepare to clear the current command line
681 CurrentString
[0] = 0;
684 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
685 Column
= StartColumn
;
691 // Toggle the SEnvInsertMode flag
693 ShellInfoObject
.ViewingSettings
.InsertMode
= (BOOLEAN
)!ShellInfoObject
.ViewingSettings
.InsertMode
;
698 // Print command history
700 PrintCommandHistory (TotalColumn
, TotalRow
, 4);
701 *CurrentString
= CHAR_NULL
;
712 // If we are in auto-complete mode, we are preparing to print
713 // the next file or directory name
715 if (InTabScrolling
) {
717 // Adjust the column and row to the start of TAB-completion string.
719 Column
= (StartColumn
+ TabUpdatePos
) % TotalColumn
;
720 Row
-= (StartColumn
+ StringCurPos
) / TotalColumn
- (StartColumn
+ TabUpdatePos
) / TotalColumn
;
721 OutputLength
= StrLen (TabLinePos
->FileName
);
723 // if the output string contains blank space, quotation marks L'\"'
724 // should be added to the output.
726 if (StrStr(TabLinePos
->FileName
, L
" ") != NULL
){
727 TabOutputStr
[0] = L
'\"';
728 CopyMem (TabOutputStr
+ 1, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
729 TabOutputStr
[OutputLength
+ 1] = L
'\"';
730 TabOutputStr
[OutputLength
+ 2] = CHAR_NULL
;
732 CopyMem (TabOutputStr
, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
733 TabOutputStr
[OutputLength
] = CHAR_NULL
;
735 OutputLength
= StrLen (TabOutputStr
) < MaxStr
- 1 ? StrLen (TabOutputStr
) : MaxStr
- 1;
736 CopyMem (CurrentString
+ TabUpdatePos
, TabOutputStr
, OutputLength
* sizeof (CHAR16
));
737 CurrentString
[TabUpdatePos
+ OutputLength
] = CHAR_NULL
;
738 StringCurPos
= TabUpdatePos
+ OutputLength
;
739 Update
= TabUpdatePos
;
740 if (StringLen
> TabUpdatePos
+ OutputLength
) {
741 Delete
= StringLen
- TabUpdatePos
- OutputLength
;
746 // If we have a new position, we are preparing to print a previous or
749 if (NewPos
!= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
750 Column
= StartColumn
;
751 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
754 NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
756 OutputLength
= StrLen (LinePos
->Buffer
) < MaxStr
- 1 ? StrLen (LinePos
->Buffer
) : MaxStr
- 1;
757 CopyMem (CurrentString
, LinePos
->Buffer
, OutputLength
* sizeof (CHAR16
));
758 CurrentString
[OutputLength
] = CHAR_NULL
;
760 StringCurPos
= OutputLength
;
763 // Draw new input string
766 if (StringLen
> OutputLength
) {
768 // If old string was longer, blank its tail
770 Delete
= StringLen
- OutputLength
;
774 // If we need to update the output do so now
776 if (Update
!= (UINTN
) -1) {
777 ShellPrintEx ((INT32
)Column
, (INT32
)Row
, L
"%s%.*s", CurrentString
+ Update
, Delete
, L
"");
778 StringLen
= StrLen (CurrentString
);
781 SetMem (CurrentString
+ StringLen
, Delete
* sizeof (CHAR16
), CHAR_NULL
);
784 if (StringCurPos
> StringLen
) {
785 StringCurPos
= StringLen
;
791 // After using print to reflect newly updates, if we're not using
792 // BACKSPACE and DELETE, we need to move the cursor position forward,
793 // so adjust row and column here.
795 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
797 // Calulate row and column of the tail of current string
799 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
+ OutputLength
) / TotalColumn
;
800 TailColumn
= (StringLen
- StringCurPos
+ Column
+ OutputLength
) % TotalColumn
;
803 // If the tail of string reaches screen end, screen rolls up, so if
804 // Row does not equal TailRow, Row should be decremented
806 // (if we are recalling commands using UPPER and DOWN key, and if the
807 // old command is too long to fit the screen, TailColumn must be 79.
809 if (TailColumn
== 0 && TailRow
>= TotalRow
&& Row
!= TailRow
) {
813 // Calculate the cursor position after current operation. If cursor
814 // reaches line end, update both row and column, otherwise, only
815 // column will be changed.
817 if (Column
+ OutputLength
>= TotalColumn
) {
818 SkipLength
= OutputLength
- (TotalColumn
- Column
);
820 Row
+= SkipLength
/ TotalColumn
+ 1;
821 if (Row
> TotalRow
- 1) {
825 Column
= SkipLength
% TotalColumn
;
827 Column
+= OutputLength
;
834 // Set the cursor position for this key
836 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, Column
, Row
);
839 if (CurrentString
!= NULL
&& StrLen(CurrentString
) > 0) {
841 // add the line to the history buffer
843 AddLineToCommandHistory(CurrentString
);
847 FreePool (TabOutputStr
);
849 // Return the data to the caller
851 *BufferSize
= StringLen
* sizeof (CHAR16
);
854 // if this was used it should be deallocated by now...
855 // prevent memory leaks...
857 ASSERT(FoundFileList
== NULL
);
863 // FILE sytle interfaces for StdIn/StdOut/StdErr
865 EFI_FILE_PROTOCOL FileInterfaceStdIn
= {
867 FileInterfaceOpenNotFound
,
868 FileInterfaceNopGeneric
,
869 FileInterfaceNopGeneric
,
870 FileInterfaceStdInRead
,
871 FileInterfaceStdInWrite
,
872 FileInterfaceNopGetPosition
,
873 FileInterfaceNopSetPosition
,
874 FileInterfaceNopGetInfo
,
875 FileInterfaceNopSetInfo
,
876 FileInterfaceNopGeneric
879 EFI_FILE_PROTOCOL FileInterfaceStdOut
= {
881 FileInterfaceOpenNotFound
,
882 FileInterfaceNopGeneric
,
883 FileInterfaceNopGeneric
,
884 FileInterfaceStdOutRead
,
885 FileInterfaceStdOutWrite
,
886 FileInterfaceNopGetPosition
,
887 FileInterfaceNopSetPosition
,
888 FileInterfaceNopGetInfo
,
889 FileInterfaceNopSetInfo
,
890 FileInterfaceNopGeneric
893 EFI_FILE_PROTOCOL FileInterfaceStdErr
= {
895 FileInterfaceOpenNotFound
,
896 FileInterfaceNopGeneric
,
897 FileInterfaceNopGeneric
,
898 FileInterfaceStdErrRead
,
899 FileInterfaceStdErrWrite
,
900 FileInterfaceNopGetPosition
,
901 FileInterfaceNopSetPosition
,
902 FileInterfaceNopGetInfo
,
903 FileInterfaceNopSetInfo
,
904 FileInterfaceNopGeneric
907 EFI_FILE_PROTOCOL FileInterfaceNulFile
= {
909 FileInterfaceOpenNotFound
,
910 FileInterfaceNopGeneric
,
911 FileInterfaceNopGeneric
,
912 FileInterfaceNulRead
,
913 FileInterfaceNulWrite
,
914 FileInterfaceNopGetPosition
,
915 FileInterfaceNopSetPosition
,
916 FileInterfaceNopGetInfo
,
917 FileInterfaceNopSetInfo
,
918 FileInterfaceNopGeneric
925 // This is identical to EFI_FILE_PROTOCOL except for the additional member
932 EFI_FILE_CLOSE Close
;
933 EFI_FILE_DELETE Delete
;
935 EFI_FILE_WRITE Write
;
936 EFI_FILE_GET_POSITION GetPosition
;
937 EFI_FILE_SET_POSITION SetPosition
;
938 EFI_FILE_GET_INFO GetInfo
;
939 EFI_FILE_SET_INFO SetInfo
;
940 EFI_FILE_FLUSH Flush
;
942 } EFI_FILE_PROTOCOL_ENVIRONMENT
;
943 //ANSI compliance helper to get size of the struct.
944 #define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)
947 File style interface for Environment Variable (Close).
949 Frees the memory for this object.
951 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
957 FileInterfaceEnvClose(
958 IN EFI_FILE_PROTOCOL
*This
966 // Most if not all UEFI commands will have an '\r\n' at the end of any output.
967 // Since the output was redirected to a variable, it does not make sense to
968 // keep this. So, before closing, strip the trailing '\r\n' from the variable
974 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
975 if (Status
== EFI_BUFFER_TOO_SMALL
) {
976 NewBuffer
= AllocateZeroPool(NewSize
+ sizeof(CHAR16
));
977 if (NewBuffer
== NULL
) {
978 return EFI_OUT_OF_RESOURCES
;
980 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
983 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
985 if (StrSize(NewBuffer
) > 6)
987 if ((((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 2] == CHAR_LINEFEED
)
988 && (((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] == CHAR_CARRIAGE_RETURN
)) {
989 ((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] = CHAR_NULL
;
992 if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
)) {
993 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
995 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1000 SHELL_FREE_NON_NULL(NewBuffer
);
1001 FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
);
1006 File style interface for Environment Variable (Delete).
1008 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1010 @retval The return value from FileInterfaceEnvClose().
1014 FileInterfaceEnvDelete(
1015 IN EFI_FILE_PROTOCOL
*This
1018 SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
);
1019 return (FileInterfaceEnvClose(This
));
1023 File style interface for Environment Variable (Read).
1025 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1026 @param[in, out] BufferSize Size in bytes of Buffer.
1027 @param[out] Buffer The pointer to the buffer to fill.
1029 @retval EFI_SUCCESS The data was read.
1033 FileInterfaceEnvRead(
1034 IN EFI_FILE_PROTOCOL
*This
,
1035 IN OUT UINTN
*BufferSize
,
1039 return (SHELL_GET_ENVIRONMENT_VARIABLE(
1040 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1046 File style interface for Volatile Environment Variable (Write).
1048 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1049 @param[in, out] BufferSize Size in bytes of Buffer.
1050 @param[in] Buffer The pointer to the buffer to write.
1052 @retval EFI_SUCCESS The data was read.
1056 FileInterfaceEnvVolWrite(
1057 IN EFI_FILE_PROTOCOL
*This
,
1058 IN OUT UINTN
*BufferSize
,
1069 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1070 if (Status
== EFI_BUFFER_TOO_SMALL
){
1071 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
+ sizeof(CHAR16
));
1072 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1074 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1075 while (((CHAR16
*)NewBuffer
)[NewSize
/2] == CHAR_NULL
) {
1077 // We want to overwrite the CHAR_NULL
1081 CopyMem((UINT8
*)NewBuffer
+ NewSize
+ 2, Buffer
, *BufferSize
);
1082 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1083 FreePool(NewBuffer
);
1086 SHELL_FREE_NON_NULL(NewBuffer
);
1087 return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, *BufferSize
, Buffer
));
1093 File style interface for Non Volatile Environment Variable (Write).
1095 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1096 @param[in, out] BufferSize Size in bytes of Buffer.
1097 @param[in] Buffer The pointer to the buffer to write.
1099 @retval EFI_SUCCESS The data was read.
1103 FileInterfaceEnvNonVolWrite(
1104 IN EFI_FILE_PROTOCOL
*This
,
1105 IN OUT UINTN
*BufferSize
,
1116 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1117 if (Status
== EFI_BUFFER_TOO_SMALL
){
1118 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
);
1119 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1121 if (!EFI_ERROR(Status
)) {
1122 CopyMem((UINT8
*)NewBuffer
+ NewSize
, Buffer
, *BufferSize
);
1123 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1124 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1125 NewSize
+ *BufferSize
,
1128 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1129 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1136 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1137 environment variables through file operations.
1139 @param EnvName The name of the Environment Variable to be operated on.
1141 @retval NULL Memory could not be allocated.
1142 @return other a pointer to an EFI_FILE_PROTOCOL structure
1146 CreateFileInterfaceEnv(
1147 IN CONST CHAR16
*EnvName
1150 EFI_FILE_PROTOCOL_ENVIRONMENT
*EnvFileInterface
;
1153 if (EnvName
== NULL
) {
1160 EnvNameSize
= StrSize(EnvName
);
1161 EnvFileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT
)+EnvNameSize
);
1162 if (EnvFileInterface
== NULL
){
1167 // Assign the generic members
1169 EnvFileInterface
->Revision
= EFI_FILE_REVISION
;
1170 EnvFileInterface
->Open
= FileInterfaceOpenNotFound
;
1171 EnvFileInterface
->Close
= FileInterfaceEnvClose
;
1172 EnvFileInterface
->GetPosition
= FileInterfaceNopGetPosition
;
1173 EnvFileInterface
->SetPosition
= FileInterfaceNopSetPosition
;
1174 EnvFileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1175 EnvFileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1176 EnvFileInterface
->Flush
= FileInterfaceNopGeneric
;
1177 EnvFileInterface
->Delete
= FileInterfaceEnvDelete
;
1178 EnvFileInterface
->Read
= FileInterfaceEnvRead
;
1180 CopyMem(EnvFileInterface
->Name
, EnvName
, EnvNameSize
);
1183 // Assign the different members for Volatile and Non-Volatile variables
1185 if (IsVolatileEnv(EnvName
)) {
1186 EnvFileInterface
->Write
= FileInterfaceEnvVolWrite
;
1188 EnvFileInterface
->Write
= FileInterfaceEnvNonVolWrite
;
1190 return ((EFI_FILE_PROTOCOL
*)EnvFileInterface
);
1194 Move the cursor position one character backward.
1196 @param[in] LineLength Length of a line. Get it by calling QueryMode
1197 @param[in, out] Column Current column of the cursor position
1198 @param[in, out] Row Current row of the cursor position
1202 MoveCursorBackward (
1203 IN UINTN LineLength
,
1204 IN OUT UINTN
*Column
,
1209 // If current column is 0, move to the last column of the previous line,
1210 // otherwise, just decrement column.
1213 *Column
= LineLength
- 1;
1223 Move the cursor position one character forward.
1225 @param[in] LineLength Length of a line.
1226 @param[in] TotalRow Total row of a screen
1227 @param[in, out] Column Current column of the cursor position
1228 @param[in, out] Row Current row of the cursor position
1233 IN UINTN LineLength
,
1235 IN OUT UINTN
*Column
,
1240 // Increment Column.
1241 // If this puts column past the end of the line, move to first column
1245 if (*Column
>= LineLength
) {
1247 if ((*Row
) < TotalRow
- 1) {
1254 Prints out each previously typed command in the command list history log.
1256 When each screen is full it will pause for a key before continuing.
1258 @param[in] TotalCols How many columns are on the screen
1259 @param[in] TotalRows How many rows are on the screen
1260 @param[in] StartColumn which column to start at
1264 PrintCommandHistory (
1265 IN CONST UINTN TotalCols
,
1266 IN CONST UINTN TotalRows
,
1267 IN CONST UINTN StartColumn
1275 ShellPrintEx (-1, -1, L
"\n");
1279 // go through history list...
1281 for ( Node
= (BUFFER_LIST
*)GetFirstNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
)
1282 ; !IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1283 ; Node
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1286 LineCount
= ((StrLen (Node
->Buffer
) + StartColumn
+ 1) / TotalCols
) + 1;
1288 if (LineNumber
+ LineCount
>= TotalRows
) {
1289 ShellPromptForResponseHii(
1290 ShellPromptResponseTypeEnterContinue
,
1291 STRING_TOKEN (STR_SHELL_ENTER_TO_CONT
),
1292 ShellInfoObject
.HiiHandle
,
1297 ShellPrintEx (-1, -1, L
"%2d. %s\n", Index
, Node
->Buffer
);
1298 LineNumber
+= LineCount
;
1308 // This is identical to EFI_FILE_PROTOCOL except for the additional members
1309 // for the buffer, size, and position.
1315 EFI_FILE_CLOSE Close
;
1316 EFI_FILE_DELETE Delete
;
1318 EFI_FILE_WRITE Write
;
1319 EFI_FILE_GET_POSITION GetPosition
;
1320 EFI_FILE_SET_POSITION SetPosition
;
1321 EFI_FILE_GET_INFO GetInfo
;
1322 EFI_FILE_SET_INFO SetInfo
;
1323 EFI_FILE_FLUSH Flush
;
1329 } EFI_FILE_PROTOCOL_MEM
;
1332 File style interface for Mem (SetPosition).
1334 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1335 @param[out] Position The position to set.
1337 @retval EFI_SUCCESS The position was successfully changed.
1338 @retval EFI_INVALID_PARAMETER The Position was invalid.
1342 FileInterfaceMemSetPosition(
1343 IN EFI_FILE_PROTOCOL
*This
,
1347 if (Position
<= ((EFI_FILE_PROTOCOL_MEM
*)This
)->FileSize
) {
1348 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= Position
;
1349 return (EFI_SUCCESS
);
1351 return (EFI_INVALID_PARAMETER
);
1356 File style interface for Mem (GetPosition).
1358 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1359 @param[out] Position The pointer to the position.
1361 @retval EFI_SUCCESS The position was retrieved.
1365 FileInterfaceMemGetPosition(
1366 IN EFI_FILE_PROTOCOL
*This
,
1367 OUT UINT64
*Position
1370 *Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
;
1371 return (EFI_SUCCESS
);
1375 File style interface for Mem (Write).
1377 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1378 @param[in, out] BufferSize Size in bytes of Buffer.
1379 @param[in] Buffer The pointer to the buffer to write.
1381 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
1382 @retval EFI_SUCCESS The data was written.
1386 FileInterfaceMemWrite(
1387 IN EFI_FILE_PROTOCOL
*This
,
1388 IN OUT UINTN
*BufferSize
,
1393 EFI_FILE_PROTOCOL_MEM
*MemFile
;
1395 MemFile
= (EFI_FILE_PROTOCOL_MEM
*) This
;
1396 if (MemFile
->Unicode
) {
1400 if ((UINTN
)(MemFile
->Position
+ (*BufferSize
)) > (UINTN
)(MemFile
->BufferSize
)) {
1401 MemFile
->Buffer
= ReallocatePool((UINTN
)(MemFile
->BufferSize
), (UINTN
)(MemFile
->BufferSize
) + (*BufferSize
) + 10, MemFile
->Buffer
);
1402 MemFile
->BufferSize
+= (*BufferSize
) + 10;
1404 CopyMem(((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, Buffer
, *BufferSize
);
1405 MemFile
->Position
+= (*BufferSize
);
1406 MemFile
->FileSize
= MemFile
->Position
;
1407 return (EFI_SUCCESS
);
1412 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1413 if (AsciiBuffer
== NULL
) {
1414 return (EFI_OUT_OF_RESOURCES
);
1416 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1417 if ((UINTN
)(MemFile
->Position
+ AsciiStrSize(AsciiBuffer
)) > (UINTN
)(MemFile
->BufferSize
)) {
1418 MemFile
->Buffer
= ReallocatePool((UINTN
)(MemFile
->BufferSize
), (UINTN
)(MemFile
->BufferSize
) + AsciiStrSize(AsciiBuffer
) + 10, MemFile
->Buffer
);
1419 MemFile
->BufferSize
+= AsciiStrSize(AsciiBuffer
) + 10;
1421 CopyMem(((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, AsciiBuffer
, AsciiStrSize(AsciiBuffer
));
1422 MemFile
->Position
+= (*BufferSize
/ sizeof(CHAR16
));
1423 MemFile
->FileSize
= MemFile
->Position
;
1424 FreePool(AsciiBuffer
);
1425 return (EFI_SUCCESS
);
1430 File style interface for Mem (Read).
1432 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1433 @param[in, out] BufferSize Size in bytes of Buffer.
1434 @param[in] Buffer The pointer to the buffer to fill.
1436 @retval EFI_SUCCESS The data was read.
1440 FileInterfaceMemRead(
1441 IN EFI_FILE_PROTOCOL
*This
,
1442 IN OUT UINTN
*BufferSize
,
1446 EFI_FILE_PROTOCOL_MEM
*MemFile
;
1448 MemFile
= (EFI_FILE_PROTOCOL_MEM
*) This
;
1449 if (*BufferSize
> (UINTN
)((MemFile
->FileSize
) - (UINTN
)(MemFile
->Position
))) {
1450 (*BufferSize
) = (UINTN
)((MemFile
->FileSize
) - (UINTN
)(MemFile
->Position
));
1452 CopyMem(Buffer
, ((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, (*BufferSize
));
1453 MemFile
->Position
= MemFile
->Position
+ (*BufferSize
);
1454 return (EFI_SUCCESS
);
1458 File style interface for Mem (Close).
1460 Frees all memory associated with this object.
1462 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1464 @retval EFI_SUCCESS The 'file' was closed.
1468 FileInterfaceMemClose(
1469 IN EFI_FILE_PROTOCOL
*This
1472 SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1473 SHELL_FREE_NON_NULL(This
);
1474 return (EFI_SUCCESS
);
1478 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1479 a file entirely in memory through file operations.
1481 @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.
1483 @retval NULL Memory could not be allocated.
1484 @return other A pointer to an EFI_FILE_PROTOCOL structure.
1488 CreateFileInterfaceMem(
1489 IN CONST BOOLEAN Unicode
1492 EFI_FILE_PROTOCOL_MEM
*FileInterface
;
1497 FileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM
));
1498 if (FileInterface
== NULL
){
1503 // Assign the generic members
1505 FileInterface
->Revision
= EFI_FILE_REVISION
;
1506 FileInterface
->Open
= FileInterfaceOpenNotFound
;
1507 FileInterface
->Close
= FileInterfaceMemClose
;
1508 FileInterface
->GetPosition
= FileInterfaceMemGetPosition
;
1509 FileInterface
->SetPosition
= FileInterfaceMemSetPosition
;
1510 FileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1511 FileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1512 FileInterface
->Flush
= FileInterfaceNopGeneric
;
1513 FileInterface
->Delete
= FileInterfaceNopGeneric
;
1514 FileInterface
->Read
= FileInterfaceMemRead
;
1515 FileInterface
->Write
= FileInterfaceMemWrite
;
1516 FileInterface
->Unicode
= Unicode
;
1518 ASSERT(FileInterface
->Buffer
== NULL
);
1519 ASSERT(FileInterface
->BufferSize
== 0);
1520 ASSERT(FileInterface
->Position
== 0);
1523 FileInterface
->Buffer
= AllocateZeroPool(sizeof(gUnicodeFileTag
));
1524 if (FileInterface
->Buffer
== NULL
) {
1525 FreePool (FileInterface
);
1528 *((CHAR16
*) (FileInterface
->Buffer
)) = EFI_UNICODE_BYTE_ORDER_MARK
;
1529 FileInterface
->BufferSize
= 2;
1530 FileInterface
->Position
= 2;
1533 return ((EFI_FILE_PROTOCOL
*)FileInterface
);
1539 EFI_FILE_CLOSE Close
;
1540 EFI_FILE_DELETE Delete
;
1542 EFI_FILE_WRITE Write
;
1543 EFI_FILE_GET_POSITION GetPosition
;
1544 EFI_FILE_SET_POSITION SetPosition
;
1545 EFI_FILE_GET_INFO GetInfo
;
1546 EFI_FILE_SET_INFO SetInfo
;
1547 EFI_FILE_FLUSH Flush
;
1549 EFI_FILE_PROTOCOL
*Orig
;
1550 } EFI_FILE_PROTOCOL_FILE
;
1553 Set a files current position
1555 @param This Protocol instance pointer.
1556 @param Position Byte position from the start of the file.
1558 @retval EFI_SUCCESS Data was written.
1559 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1564 FileInterfaceFileSetPosition(
1565 IN EFI_FILE_PROTOCOL
*This
,
1569 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1573 Get a file's current position
1575 @param This Protocol instance pointer.
1576 @param Position Byte position from the start of the file.
1578 @retval EFI_SUCCESS Data was written.
1579 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1584 FileInterfaceFileGetPosition(
1585 IN EFI_FILE_PROTOCOL
*This
,
1586 OUT UINT64
*Position
1589 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1593 Get information about a file.
1595 @param This Protocol instance pointer.
1596 @param InformationType Type of information to return in Buffer.
1597 @param BufferSize On input size of buffer, on output amount of data in buffer.
1598 @param Buffer The buffer to return data.
1600 @retval EFI_SUCCESS Data was returned.
1601 @retval EFI_UNSUPPORT InformationType is not supported.
1602 @retval EFI_NO_MEDIA The device has no media.
1603 @retval EFI_DEVICE_ERROR The device reported an error.
1604 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1605 @retval EFI_WRITE_PROTECTED The device is write protected.
1606 @retval EFI_ACCESS_DENIED The file was open for read only.
1607 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1612 FileInterfaceFileGetInfo(
1613 IN EFI_FILE_PROTOCOL
*This
,
1614 IN EFI_GUID
*InformationType
,
1615 IN OUT UINTN
*BufferSize
,
1619 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1623 Set information about a file
1625 @param This Protocol instance pointer.
1626 @param InformationType Type of information in Buffer.
1627 @param BufferSize Size of buffer.
1628 @param Buffer The data to write.
1630 @retval EFI_SUCCESS Data was returned.
1631 @retval EFI_UNSUPPORT InformationType is not supported.
1632 @retval EFI_NO_MEDIA The device has no media.
1633 @retval EFI_DEVICE_ERROR The device reported an error.
1634 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1635 @retval EFI_WRITE_PROTECTED The device is write protected.
1636 @retval EFI_ACCESS_DENIED The file was open for read only.
1641 FileInterfaceFileSetInfo(
1642 IN EFI_FILE_PROTOCOL
*This
,
1643 IN EFI_GUID
*InformationType
,
1644 IN UINTN BufferSize
,
1648 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1652 Flush data back for the file handle.
1654 @param This Protocol instance pointer.
1656 @retval EFI_SUCCESS Data was written.
1657 @retval EFI_UNSUPPORT Writes to Open directory are not supported.
1658 @retval EFI_NO_MEDIA The device has no media.
1659 @retval EFI_DEVICE_ERROR The device reported an error.
1660 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1661 @retval EFI_WRITE_PROTECTED The device is write protected.
1662 @retval EFI_ACCESS_DENIED The file was open for read only.
1663 @retval EFI_VOLUME_FULL The volume is full.
1668 FileInterfaceFileFlush(
1669 IN EFI_FILE_PROTOCOL
*This
1672 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Flush(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1676 Read data from the file.
1678 @param This Protocol instance pointer.
1679 @param BufferSize On input size of buffer, on output amount of data in buffer.
1680 @param Buffer The buffer in which data is read.
1682 @retval EFI_SUCCESS Data was read.
1683 @retval EFI_NO_MEDIA The device has no media.
1684 @retval EFI_DEVICE_ERROR The device reported an error.
1685 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1686 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1691 FileInterfaceFileRead(
1692 IN EFI_FILE_PROTOCOL
*This
,
1693 IN OUT UINTN
*BufferSize
,
1697 CHAR8
*AsciiStrBuffer
;
1698 CHAR16
*UscStrBuffer
;
1702 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1706 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1711 Size
= (*BufferSize
) / sizeof(CHAR16
);
1712 AsciiStrBuffer
= AllocateZeroPool(Size
+ sizeof(CHAR8
));
1713 if (AsciiStrBuffer
== NULL
) {
1714 return EFI_OUT_OF_RESOURCES
;
1716 UscStrBuffer
= AllocateZeroPool(*BufferSize
+ sizeof(CHAR16
));
1717 if (UscStrBuffer
== NULL
) {
1718 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1719 return EFI_OUT_OF_RESOURCES
;
1721 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiStrBuffer
));
1722 if (!EFI_ERROR(Status
)) {
1723 CharNum
= UnicodeSPrint(UscStrBuffer
, *BufferSize
+ sizeof(CHAR16
), L
"%a", AsciiStrBuffer
);
1724 if (CharNum
== Size
) {
1725 CopyMem (Buffer
, UscStrBuffer
, *BufferSize
);
1727 Status
= EFI_UNSUPPORTED
;
1730 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1731 SHELL_FREE_NON_NULL(UscStrBuffer
);
1737 Opens a new file relative to the source file's location.
1739 @param[in] This The protocol instance pointer.
1740 @param[out] NewHandle Returns File Handle for FileName.
1741 @param[in] FileName Null terminated string. "\", ".", and ".." are supported.
1742 @param[in] OpenMode Open mode for file.
1743 @param[in] Attributes Only used for EFI_FILE_MODE_CREATE.
1745 @retval EFI_SUCCESS The device was opened.
1746 @retval EFI_NOT_FOUND The specified file could not be found on the device.
1747 @retval EFI_NO_MEDIA The device has no media.
1748 @retval EFI_MEDIA_CHANGED The media has changed.
1749 @retval EFI_DEVICE_ERROR The device reported an error.
1750 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1751 @retval EFI_ACCESS_DENIED The service denied access to the file.
1752 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
1753 @retval EFI_VOLUME_FULL The volume is full.
1757 FileInterfaceFileOpen (
1758 IN EFI_FILE_PROTOCOL
*This
,
1759 OUT EFI_FILE_PROTOCOL
**NewHandle
,
1760 IN CHAR16
*FileName
,
1762 IN UINT64 Attributes
1765 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Open(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, NewHandle
, FileName
, OpenMode
, Attributes
);
1769 Close and delete the file handle.
1771 @param This Protocol instance pointer.
1773 @retval EFI_SUCCESS The device was opened.
1774 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
1779 FileInterfaceFileDelete(
1780 IN EFI_FILE_PROTOCOL
*This
1784 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Delete(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1790 File style interface for File (Close).
1792 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1794 @retval EFI_SUCCESS The file was closed.
1798 FileInterfaceFileClose(
1799 IN EFI_FILE_PROTOCOL
*This
1803 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Close(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1809 File style interface for File (Write).
1811 If the file was opened with ASCII mode the data will be processed through
1812 AsciiSPrint before writing.
1814 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1815 @param[in, out] BufferSize Size in bytes of Buffer.
1816 @param[in] Buffer The pointer to the buffer to write.
1818 @retval EFI_SUCCESS The data was written.
1822 FileInterfaceFileWrite(
1823 IN EFI_FILE_PROTOCOL
*This
,
1824 IN OUT UINTN
*BufferSize
,
1831 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1835 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1840 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1841 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1842 Size
= AsciiStrSize(AsciiBuffer
) - 1; // (we dont need the null terminator)
1843 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1844 FreePool(AsciiBuffer
);
1850 Create a file interface with unicode information.
1852 This will create a new EFI_FILE_PROTOCOL identical to the Templace
1853 except that the new one has Unicode and Ascii knowledge.
1855 @param[in] Template A pointer to the EFI_FILE_PROTOCOL object.
1856 @param[in] Unicode TRUE for UCS-2, FALSE for ASCII.
1858 @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
1861 CreateFileInterfaceFile(
1862 IN CONST EFI_FILE_PROTOCOL
*Template
,
1863 IN CONST BOOLEAN Unicode
1866 EFI_FILE_PROTOCOL_FILE
*NewOne
;
1868 NewOne
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE
));
1869 if (NewOne
== NULL
) {
1872 CopyMem(NewOne
, Template
, sizeof(EFI_FILE_PROTOCOL_FILE
));
1873 NewOne
->Orig
= (EFI_FILE_PROTOCOL
*)Template
;
1874 NewOne
->Unicode
= Unicode
;
1875 NewOne
->Open
= FileInterfaceFileOpen
;
1876 NewOne
->Close
= FileInterfaceFileClose
;
1877 NewOne
->Delete
= FileInterfaceFileDelete
;
1878 NewOne
->Read
= FileInterfaceFileRead
;
1879 NewOne
->Write
= FileInterfaceFileWrite
;
1880 NewOne
->GetPosition
= FileInterfaceFileGetPosition
;
1881 NewOne
->SetPosition
= FileInterfaceFileSetPosition
;
1882 NewOne
->GetInfo
= FileInterfaceFileGetInfo
;
1883 NewOne
->SetInfo
= FileInterfaceFileSetInfo
;
1884 NewOne
->Flush
= FileInterfaceFileFlush
;
1886 return ((EFI_FILE_PROTOCOL
*)NewOne
);