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"
21 #define MEM_WRITE_REALLOC_OVERHEAD 1024
24 File style interface for console (Open).
26 @param[in] This Ignored.
27 @param[out] NewHandle Ignored.
28 @param[in] FileName Ignored.
29 @param[in] OpenMode Ignored.
30 @param[in] Attributes Ignored.
36 FileInterfaceOpenNotFound(
37 IN EFI_FILE_PROTOCOL
*This
,
38 OUT EFI_FILE_PROTOCOL
**NewHandle
,
44 return (EFI_NOT_FOUND
);
48 File style interface for console (Close, Delete, & Flush)
50 @param[in] This Ignored.
56 FileInterfaceNopGeneric(
57 IN EFI_FILE_PROTOCOL
*This
64 File style interface for console (GetPosition).
66 @param[in] This Ignored.
67 @param[out] Position Ignored.
69 @retval EFI_UNSUPPORTED
73 FileInterfaceNopGetPosition(
74 IN EFI_FILE_PROTOCOL
*This
,
78 return (EFI_UNSUPPORTED
);
82 File style interface for console (SetPosition).
84 @param[in] This Ignored.
85 @param[in] Position Ignored.
87 @retval EFI_UNSUPPORTED
91 FileInterfaceNopSetPosition(
92 IN EFI_FILE_PROTOCOL
*This
,
96 return (EFI_UNSUPPORTED
);
100 File style interface for console (GetInfo).
102 @param[in] This Ignored.
103 @param[in] InformationType Ignored.
104 @param[in, out] BufferSize Ignored.
105 @param[out] Buffer Ignored.
107 @retval EFI_UNSUPPORTED
111 FileInterfaceNopGetInfo(
112 IN EFI_FILE_PROTOCOL
*This
,
113 IN EFI_GUID
*InformationType
,
114 IN OUT UINTN
*BufferSize
,
118 return (EFI_UNSUPPORTED
);
122 File style interface for console (SetInfo).
124 @param[in] This Ignored.
125 @param[in] InformationType Ignored.
126 @param[in] BufferSize Ignored.
127 @param[in] Buffer Ignored.
129 @retval EFI_UNSUPPORTED
133 FileInterfaceNopSetInfo(
134 IN EFI_FILE_PROTOCOL
*This
,
135 IN EFI_GUID
*InformationType
,
140 return (EFI_UNSUPPORTED
);
144 File style interface for StdOut (Write).
146 Writes data to the screen.
148 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
149 @param[in, out] BufferSize Size in bytes of Buffer.
150 @param[in] Buffer The pointer to the buffer to write.
152 @retval EFI_UNSUPPORTED No output console is supported.
153 @return A return value from gST->ConOut->OutputString.
157 FileInterfaceStdOutWrite(
158 IN EFI_FILE_PROTOCOL
*This
,
159 IN OUT UINTN
*BufferSize
,
163 if (ShellInfoObject
.ShellInitSettings
.BitUnion
.Bits
.NoConsoleOut
) {
164 return (EFI_UNSUPPORTED
);
166 if (*((CHAR16
*)Buffer
) == gUnicodeFileTag
) {
167 return (gST
->ConOut
->OutputString(gST
->ConOut
, (CHAR16
*)Buffer
+ 1));
169 return (gST
->ConOut
->OutputString(gST
->ConOut
, Buffer
));
173 File style interface for StdIn (Write).
175 @param[in] This Ignored.
176 @param[in, out] BufferSize Ignored.
177 @param[in] Buffer Ignored.
179 @retval EFI_UNSUPPORTED
183 FileInterfaceStdInWrite(
184 IN EFI_FILE_PROTOCOL
*This
,
185 IN OUT UINTN
*BufferSize
,
189 return (EFI_UNSUPPORTED
);
193 File style interface for console StdErr (Write).
195 Writes error to the error output.
197 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
198 @param[in, out] BufferSize Size in bytes of Buffer.
199 @param[in] Buffer The pointer to the buffer to write.
201 @return A return value from gST->StdErr->OutputString.
205 FileInterfaceStdErrWrite(
206 IN EFI_FILE_PROTOCOL
*This
,
207 IN OUT UINTN
*BufferSize
,
211 return (gST
->StdErr
->OutputString(gST
->StdErr
, Buffer
));
215 File style interface for console StdOut (Read).
217 @param[in] This Ignored.
218 @param[in, out] BufferSize Ignored.
219 @param[out] Buffer Ignored.
221 @retval EFI_UNSUPPORTED
225 FileInterfaceStdOutRead(
226 IN EFI_FILE_PROTOCOL
*This
,
227 IN OUT UINTN
*BufferSize
,
231 return (EFI_UNSUPPORTED
);
235 File style interface for console StdErr (Read).
237 @param[in] This Ignored.
238 @param[in, out] BufferSize Ignored.
239 @param[out] Buffer Ignored.
241 @retval EFI_UNSUPPORTED Always.
245 FileInterfaceStdErrRead(
246 IN EFI_FILE_PROTOCOL
*This
,
247 IN OUT UINTN
*BufferSize
,
251 return (EFI_UNSUPPORTED
);
255 File style interface for NUL file (Read).
257 @param[in] This Ignored.
258 @param[in, out] BufferSize Poiner to 0 upon return.
259 @param[out] Buffer Ignored.
261 @retval EFI_SUCCESS Always.
265 FileInterfaceNulRead(
266 IN EFI_FILE_PROTOCOL
*This
,
267 IN OUT UINTN
*BufferSize
,
272 return (EFI_SUCCESS
);
276 File style interface for NUL file (Write).
278 @param[in] This Ignored.
279 @param[in, out] BufferSize Ignored.
280 @param[in] Buffer Ignored.
286 FileInterfaceNulWrite(
287 IN EFI_FILE_PROTOCOL
*This
,
288 IN OUT UINTN
*BufferSize
,
292 return (EFI_SUCCESS
);
296 Create the TAB completion list.
298 @param[in] InputString The command line to expand.
299 @param[in] StringLen Length of the command line.
300 @param[in] BufferSize Buffer size.
301 @param[out] TabCompletionList Return the TAB completion list.
302 @param[out] TabUpdatePos Return the TAB update position.
306 CreateTabCompletionList (
307 IN CONST CHAR16
*InputString
,
308 IN CONST UINTN StringLen
,
309 IN CONST UINTN BufferSize
,
310 IN OUT EFI_SHELL_FILE_INFO
**TabCompletionList
,
311 IN OUT UINTN
*TabUpdatePos
320 EFI_SHELL_FILE_INFO
*FileList
;
321 EFI_SHELL_FILE_INFO
*FileInfo
;
322 EFI_SHELL_FILE_INFO
*TempFileInfo
;
327 TabStr
= AllocateZeroPool (BufferSize
);
328 if (TabStr
== NULL
) {
329 return EFI_OUT_OF_RESOURCES
;
333 // handle auto complete of file and directory names...
334 // E.g.: cd fs0:\EFI\Bo<TAB>
336 // TabPos TabUpdatePos
342 for (Index
= 0; Index
< StringLen
; Index
++) {
343 switch (InputString
[Index
]) {
345 InQuotation
= (BOOLEAN
) (!InQuotation
);
351 *TabUpdatePos
= TabPos
;
357 // handle the case "fs0:<TAB>"
358 // Update the TabUpdatePos as well.
361 *TabUpdatePos
= Index
+ 1;
369 if (StrStr (InputString
+ TabPos
, L
":") == NULL
) {
371 // If file path doesn't contain ":", it's a path relative to current directory.
373 Cwd
= ShellInfoObject
.NewEfiShellProtocol
->GetCurDir (NULL
);
375 StrnCpyS (TabStr
, (BufferSize
) / sizeof (CHAR16
), Cwd
, (BufferSize
) / sizeof (CHAR16
) - 1);
376 if (InputString
[TabPos
] != L
'\\') {
377 StrCatS (TabStr
, (BufferSize
) / sizeof (CHAR16
), L
"\\");
381 StrnCatS (TabStr
, (BufferSize
) / sizeof (CHAR16
), InputString
+ TabPos
, StringLen
- TabPos
);
382 StrnCatS (TabStr
, (BufferSize
) / sizeof (CHAR16
), L
"*", (BufferSize
) / sizeof (CHAR16
) - 1 - StrLen (TabStr
));
383 Status
= ShellInfoObject
.NewEfiShellProtocol
->FindFiles(TabStr
, &FileList
);
386 // Filter out the non-directory for "CD" command
387 // Filter "." and ".." for all
389 if (!EFI_ERROR (Status
) && FileList
!= NULL
) {
391 // Skip the spaces in the beginning
393 while (*InputString
== L
' ') {
397 for (FileInfo
= (EFI_SHELL_FILE_INFO
*) GetFirstNode (&FileList
->Link
); !IsNull (&FileList
->Link
, &FileInfo
->Link
); ) {
398 if (((StrCmp (FileInfo
->FileName
, L
".") == 0) || (StrCmp (FileInfo
->FileName
, L
"..") == 0)) ||
399 (((InputString
[0] == L
'c' || InputString
[0] == L
'C') && (InputString
[1] == L
'd' || InputString
[1] == L
'D')) &&
400 (ShellIsDirectory (FileInfo
->FullName
) != EFI_SUCCESS
))) {
401 TempFileInfo
= FileInfo
;
402 FileInfo
= (EFI_SHELL_FILE_INFO
*) RemoveEntryList (&FileInfo
->Link
);
403 InternalFreeShellFileInfoNode (TempFileInfo
);
405 FileInfo
= (EFI_SHELL_FILE_INFO
*) GetNextNode (&FileList
->Link
, &FileInfo
->Link
);
410 if (FileList
!= NULL
&& !IsListEmpty (&FileList
->Link
)) {
411 Status
= EFI_SUCCESS
;
413 ShellInfoObject
.NewEfiShellProtocol
->FreeFileList (&FileList
);
414 Status
= EFI_NOT_FOUND
;
419 *TabCompletionList
= FileList
;
424 File style interface for console (Read).
426 This will return a single line of input from the console.
428 @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
429 file handle to read data from. Not used.
430 @param BufferSize On input, the size of the Buffer. On output, the amount
431 of data returned in Buffer. In both cases, the size is
433 @param Buffer The buffer into which the data is read.
436 @retval EFI_SUCCESS The data was read.
437 @retval EFI_NO_MEDIA The device has no medium.
438 @retval EFI_DEVICE_ERROR The device reported an error.
439 @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
440 @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
441 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
442 @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
443 entry. BufferSize has been updated with the size
444 needed to complete the request.
445 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
449 FileInterfaceStdInRead(
450 IN EFI_FILE_PROTOCOL
*This
,
451 IN OUT UINTN
*BufferSize
,
455 CHAR16
*CurrentString
;
457 UINTN TabUpdatePos
; // Start index of the string updated by TAB stroke
458 UINTN Column
; // Column of current cursor
459 UINTN Row
; // Row of current cursor
460 UINTN StartColumn
; // Column at the beginning of the line
461 UINTN Update
; // Line index for update
462 UINTN Delete
; // Num of chars to delete from console after update
463 UINTN StringLen
; // Total length of the line
464 UINTN StringCurPos
; // Line index corresponding to the cursor
465 UINTN MaxStr
; // Maximum possible line length
466 UINTN TotalColumn
; // Num of columns in the console
467 UINTN TotalRow
; // Num of rows in the console
469 UINTN OutputLength
; // Length of the update string
470 UINTN TailRow
; // Row of end of line
471 UINTN TailColumn
; // Column of end of line
474 BUFFER_LIST
*LinePos
;
478 BOOLEAN InTabScrolling
; // Whether in TAB-completion state
479 EFI_SHELL_FILE_INFO
*TabCompleteList
;
480 EFI_SHELL_FILE_INFO
*TabCurrent
;
482 CHAR16
*TabOutputStr
;
485 // If buffer is not large enough to hold a CHAR16, return minimum buffer size
487 if (*BufferSize
< sizeof (CHAR16
) * 2) {
488 *BufferSize
= sizeof (CHAR16
) * 2;
489 return (EFI_BUFFER_TOO_SMALL
);
493 CurrentString
= Buffer
;
499 LinePos
= NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
501 InTabScrolling
= FALSE
;
502 Status
= EFI_SUCCESS
;
505 TabCompleteList
= NULL
;
509 // Get the screen setting and the current cursor location
511 Column
= StartColumn
= gST
->ConOut
->Mode
->CursorColumn
;
512 Row
= gST
->ConOut
->Mode
->CursorRow
;
513 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &TotalColumn
, &TotalRow
);
516 // Limit the line length to the buffer size or the minimun size of the
517 // screen. (The smaller takes effect)
519 MaxStr
= TotalColumn
* (TotalRow
- 1) - StartColumn
;
520 if (MaxStr
> *BufferSize
/ sizeof (CHAR16
)) {
521 MaxStr
= *BufferSize
/ sizeof (CHAR16
);
523 ZeroMem (CurrentString
, MaxStr
* sizeof (CHAR16
));
528 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
529 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
530 if (EFI_ERROR (Status
)) {
532 if (Status
== EFI_NOT_READY
)
535 ZeroMem (CurrentString
, MaxStr
* sizeof(CHAR16
));
541 // Press PageUp or PageDown to scroll the history screen up or down.
542 // Press any other key to quit scrolling.
544 if (Key
.UnicodeChar
== 0 && (Key
.ScanCode
== SCAN_PAGE_UP
|| Key
.ScanCode
== SCAN_PAGE_DOWN
)) {
545 if (Key
.ScanCode
== SCAN_PAGE_UP
) {
546 ConsoleLoggerDisplayHistory(FALSE
, 0, ShellInfoObject
.ConsoleInfo
);
547 } else if (Key
.ScanCode
== SCAN_PAGE_DOWN
) {
548 ConsoleLoggerDisplayHistory(TRUE
, 0, ShellInfoObject
.ConsoleInfo
);
554 ConsoleLoggerStopHistory(ShellInfoObject
.ConsoleInfo
);
560 // If we are quitting TAB scrolling...
562 if (InTabScrolling
&& Key
.UnicodeChar
!= CHAR_TAB
) {
563 if (TabCompleteList
!= NULL
) {
564 ShellInfoObject
.NewEfiShellProtocol
->FreeFileList (&TabCompleteList
);
565 DEBUG_CODE(TabCompleteList
= NULL
;);
567 InTabScrolling
= FALSE
;
570 switch (Key
.UnicodeChar
) {
571 case CHAR_CARRIAGE_RETURN
:
573 // All done, print a newline at the end of the string
575 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
576 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
577 ShellPrintEx ((INT32
)TailColumn
, (INT32
)TailRow
, L
"%N\n");
582 if (StringCurPos
!= 0) {
584 // If not move back beyond string beginning, move all characters behind
585 // the current position one character forward
588 Update
= StringCurPos
;
590 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
593 // Adjust the current column and row
595 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
600 if (!InTabScrolling
) {
603 // Initialize a tab complete operation.
605 Status
= CreateTabCompletionList (CurrentString
, StringLen
, *BufferSize
, &TabCompleteList
, &TabUpdatePos
);
606 if (!EFI_ERROR(Status
)) {
607 InTabScrolling
= TRUE
;
611 // We do not set up the replacement.
612 // The next section will do that.
616 if (InTabScrolling
) {
618 // We are in a tab complete operation.
619 // set up the next replacement.
621 ASSERT(TabCompleteList
!= NULL
);
622 if (TabCurrent
== NULL
) {
623 TabCurrent
= (EFI_SHELL_FILE_INFO
*) GetFirstNode (&TabCompleteList
->Link
);
625 TabCurrent
= (EFI_SHELL_FILE_INFO
*) GetNextNode (&TabCompleteList
->Link
, &TabCurrent
->Link
);
629 // Skip over the empty list beginning node
631 if (IsNull(&TabCompleteList
->Link
, &TabCurrent
->Link
)) {
632 TabCurrent
= (EFI_SHELL_FILE_INFO
*) GetNextNode (&TabCompleteList
->Link
, &TabCurrent
->Link
);
638 if (Key
.UnicodeChar
>= ' ') {
640 // If we are at the buffer's end, drop the key
642 if (StringLen
== MaxStr
- 1 && (ShellInfoObject
.ViewingSettings
.InsertMode
|| StringCurPos
== StringLen
)) {
646 // If in insert mode, make space by moving each other character 1
647 // space higher in the array
649 if (ShellInfoObject
.ViewingSettings
.InsertMode
) {
650 CopyMem(CurrentString
+ StringCurPos
+ 1, CurrentString
+ StringCurPos
, (StringLen
- StringCurPos
)*sizeof(CurrentString
[0]));
653 CurrentString
[StringCurPos
] = Key
.UnicodeChar
;
654 Update
= StringCurPos
;
662 switch (Key
.ScanCode
) {
665 // Move characters behind current position one character forward
667 if (StringLen
!= 0) {
668 Update
= StringCurPos
;
670 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
676 // Prepare to print the previous command
678 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
679 if (IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
)) {
680 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
686 // Prepare to print the next command
688 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
689 if (NewPos
== (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
690 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
696 // Adjust current cursor position
698 if (StringCurPos
!= 0) {
700 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
706 // Adjust current cursor position
708 if (StringCurPos
< StringLen
) {
710 MoveCursorForward (TotalColumn
, TotalRow
, &Column
, &Row
);
716 // Move current cursor position to the beginning of the command line
718 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
719 Column
= StartColumn
;
725 // Move current cursor position to the end of the command line
727 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
728 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
731 StringCurPos
= StringLen
;
736 // Prepare to clear the current command line
738 CurrentString
[0] = 0;
741 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
742 Column
= StartColumn
;
748 // Toggle the SEnvInsertMode flag
750 ShellInfoObject
.ViewingSettings
.InsertMode
= (BOOLEAN
)!ShellInfoObject
.ViewingSettings
.InsertMode
;
755 // Print command history
757 PrintCommandHistory (TotalColumn
, TotalRow
, 4);
758 *CurrentString
= CHAR_NULL
;
769 // If we are in auto-complete mode, we are preparing to print
770 // the next file or directory name
772 if (InTabScrolling
) {
773 TabOutputStr
= AllocateZeroPool (*BufferSize
);
774 if (TabOutputStr
== NULL
) {
775 Status
= EFI_OUT_OF_RESOURCES
;
779 if (InTabScrolling
&& TabOutputStr
!= NULL
) {
782 // Adjust the column and row to the start of TAB-completion string.
784 Column
= (StartColumn
+ TabUpdatePos
) % TotalColumn
;
785 Row
-= (StartColumn
+ StringCurPos
) / TotalColumn
- (StartColumn
+ TabUpdatePos
) / TotalColumn
;
786 OutputLength
= StrLen (TabCurrent
->FileName
);
788 // if the output string contains blank space, quotation marks L'\"'
789 // should be added to the output.
791 if (StrStr(TabCurrent
->FileName
, L
" ") != NULL
){
792 TabOutputStr
[0] = L
'\"';
793 CopyMem (TabOutputStr
+ 1, TabCurrent
->FileName
, OutputLength
* sizeof (CHAR16
));
794 TabOutputStr
[OutputLength
+ 1] = L
'\"';
795 TabOutputStr
[OutputLength
+ 2] = CHAR_NULL
;
797 CopyMem (TabOutputStr
, TabCurrent
->FileName
, OutputLength
* sizeof (CHAR16
));
798 TabOutputStr
[OutputLength
] = CHAR_NULL
;
800 OutputLength
= StrLen (TabOutputStr
) < MaxStr
- 1 ? StrLen (TabOutputStr
) : MaxStr
- 1;
801 CopyMem (CurrentString
+ TabUpdatePos
, TabOutputStr
, OutputLength
* sizeof (CHAR16
));
802 CurrentString
[TabUpdatePos
+ OutputLength
] = CHAR_NULL
;
803 StringCurPos
= TabUpdatePos
+ OutputLength
;
804 Update
= TabUpdatePos
;
805 if (StringLen
> TabUpdatePos
+ OutputLength
) {
806 Delete
= StringLen
- TabUpdatePos
- OutputLength
;
809 FreePool(TabOutputStr
);
813 // If we have a new position, we are preparing to print a previous or
816 if (NewPos
!= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
817 Column
= StartColumn
;
818 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
821 NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
823 OutputLength
= StrLen (LinePos
->Buffer
) < MaxStr
- 1 ? StrLen (LinePos
->Buffer
) : MaxStr
- 1;
824 CopyMem (CurrentString
, LinePos
->Buffer
, OutputLength
* sizeof (CHAR16
));
825 CurrentString
[OutputLength
] = CHAR_NULL
;
827 StringCurPos
= OutputLength
;
830 // Draw new input string
833 if (StringLen
> OutputLength
) {
835 // If old string was longer, blank its tail
837 Delete
= StringLen
- OutputLength
;
841 // If we need to update the output do so now
843 if (Update
!= (UINTN
) -1) {
844 ShellPrintEx ((INT32
)Column
, (INT32
)Row
, L
"%s%.*s", CurrentString
+ Update
, Delete
, L
"");
845 StringLen
= StrLen (CurrentString
);
848 SetMem (CurrentString
+ StringLen
, Delete
* sizeof (CHAR16
), CHAR_NULL
);
851 if (StringCurPos
> StringLen
) {
852 StringCurPos
= StringLen
;
858 // After using print to reflect newly updates, if we're not using
859 // BACKSPACE and DELETE, we need to move the cursor position forward,
860 // so adjust row and column here.
862 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
864 // Calulate row and column of the tail of current string
866 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
+ OutputLength
) / TotalColumn
;
867 TailColumn
= (StringLen
- StringCurPos
+ Column
+ OutputLength
) % TotalColumn
;
870 // If the tail of string reaches screen end, screen rolls up, so if
871 // Row does not equal TailRow, Row should be decremented
873 // (if we are recalling commands using UPPER and DOWN key, and if the
874 // old command is too long to fit the screen, TailColumn must be 79.
876 if (TailColumn
== 0 && TailRow
>= TotalRow
&& Row
!= TailRow
) {
880 // Calculate the cursor position after current operation. If cursor
881 // reaches line end, update both row and column, otherwise, only
882 // column will be changed.
884 if (Column
+ OutputLength
>= TotalColumn
) {
885 SkipLength
= OutputLength
- (TotalColumn
- Column
);
887 Row
+= SkipLength
/ TotalColumn
+ 1;
888 if (Row
> TotalRow
- 1) {
892 Column
= SkipLength
% TotalColumn
;
894 Column
+= OutputLength
;
901 // Set the cursor position for this key
903 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, Column
, Row
);
906 if (CurrentString
!= NULL
&& StrLen(CurrentString
) > 0) {
908 // add the line to the history buffer
910 AddLineToCommandHistory(CurrentString
);
914 // Return the data to the caller
916 *BufferSize
= StringLen
* sizeof (CHAR16
);
919 // if this was used it should be deallocated by now...
920 // prevent memory leaks...
922 if (TabCompleteList
!= NULL
) {
923 ShellInfoObject
.NewEfiShellProtocol
->FreeFileList (&TabCompleteList
);
925 ASSERT(TabCompleteList
== NULL
);
931 // FILE sytle interfaces for StdIn/StdOut/StdErr
933 EFI_FILE_PROTOCOL FileInterfaceStdIn
= {
935 FileInterfaceOpenNotFound
,
936 FileInterfaceNopGeneric
,
937 FileInterfaceNopGeneric
,
938 FileInterfaceStdInRead
,
939 FileInterfaceStdInWrite
,
940 FileInterfaceNopGetPosition
,
941 FileInterfaceNopSetPosition
,
942 FileInterfaceNopGetInfo
,
943 FileInterfaceNopSetInfo
,
944 FileInterfaceNopGeneric
947 EFI_FILE_PROTOCOL FileInterfaceStdOut
= {
949 FileInterfaceOpenNotFound
,
950 FileInterfaceNopGeneric
,
951 FileInterfaceNopGeneric
,
952 FileInterfaceStdOutRead
,
953 FileInterfaceStdOutWrite
,
954 FileInterfaceNopGetPosition
,
955 FileInterfaceNopSetPosition
,
956 FileInterfaceNopGetInfo
,
957 FileInterfaceNopSetInfo
,
958 FileInterfaceNopGeneric
961 EFI_FILE_PROTOCOL FileInterfaceStdErr
= {
963 FileInterfaceOpenNotFound
,
964 FileInterfaceNopGeneric
,
965 FileInterfaceNopGeneric
,
966 FileInterfaceStdErrRead
,
967 FileInterfaceStdErrWrite
,
968 FileInterfaceNopGetPosition
,
969 FileInterfaceNopSetPosition
,
970 FileInterfaceNopGetInfo
,
971 FileInterfaceNopSetInfo
,
972 FileInterfaceNopGeneric
975 EFI_FILE_PROTOCOL FileInterfaceNulFile
= {
977 FileInterfaceOpenNotFound
,
978 FileInterfaceNopGeneric
,
979 FileInterfaceNopGeneric
,
980 FileInterfaceNulRead
,
981 FileInterfaceNulWrite
,
982 FileInterfaceNopGetPosition
,
983 FileInterfaceNopSetPosition
,
984 FileInterfaceNopGetInfo
,
985 FileInterfaceNopSetInfo
,
986 FileInterfaceNopGeneric
993 // This is identical to EFI_FILE_PROTOCOL except for the additional member
1000 EFI_FILE_CLOSE Close
;
1001 EFI_FILE_DELETE Delete
;
1003 EFI_FILE_WRITE Write
;
1004 EFI_FILE_GET_POSITION GetPosition
;
1005 EFI_FILE_SET_POSITION SetPosition
;
1006 EFI_FILE_GET_INFO GetInfo
;
1007 EFI_FILE_SET_INFO SetInfo
;
1008 EFI_FILE_FLUSH Flush
;
1010 } EFI_FILE_PROTOCOL_ENVIRONMENT
;
1011 //ANSI compliance helper to get size of the struct.
1012 #define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)
1015 File style interface for Environment Variable (Close).
1017 Frees the memory for this object.
1019 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1025 FileInterfaceEnvClose(
1026 IN EFI_FILE_PROTOCOL
*This
1035 // Most if not all UEFI commands will have an '\r\n' at the end of any output.
1036 // Since the output was redirected to a variable, it does not make sense to
1037 // keep this. So, before closing, strip the trailing '\r\n' from the variable
1043 Status
= IsVolatileEnv (((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &Volatile
);
1044 if (EFI_ERROR (Status
)) {
1048 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1049 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1050 NewBuffer
= AllocateZeroPool(NewSize
+ sizeof(CHAR16
));
1051 if (NewBuffer
== NULL
) {
1052 return EFI_OUT_OF_RESOURCES
;
1054 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1057 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1059 if (StrSize(NewBuffer
) > 6)
1061 if ((((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 2] == CHAR_LINEFEED
)
1062 && (((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] == CHAR_CARRIAGE_RETURN
)) {
1063 ((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] = CHAR_NULL
;
1067 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1069 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1074 SHELL_FREE_NON_NULL(NewBuffer
);
1075 FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
);
1080 File style interface for Environment Variable (Delete).
1082 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1084 @retval The return value from FileInterfaceEnvClose().
1088 FileInterfaceEnvDelete(
1089 IN EFI_FILE_PROTOCOL
*This
1092 SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
);
1093 return (FileInterfaceEnvClose(This
));
1097 File style interface for Environment Variable (Read).
1099 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1100 @param[in, out] BufferSize Size in bytes of Buffer.
1101 @param[out] Buffer The pointer to the buffer to fill.
1103 @retval EFI_SUCCESS The data was read.
1107 FileInterfaceEnvRead(
1108 IN EFI_FILE_PROTOCOL
*This
,
1109 IN OUT UINTN
*BufferSize
,
1113 return (SHELL_GET_ENVIRONMENT_VARIABLE(
1114 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1120 File style interface for Volatile Environment Variable (Write).
1122 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1123 @param[in, out] BufferSize Size in bytes of Buffer.
1124 @param[in] Buffer The pointer to the buffer to write.
1126 @retval EFI_SUCCESS The data was read.
1130 FileInterfaceEnvVolWrite(
1131 IN EFI_FILE_PROTOCOL
*This
,
1132 IN OUT UINTN
*BufferSize
,
1143 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1144 if (Status
== EFI_BUFFER_TOO_SMALL
){
1145 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
+ sizeof(CHAR16
));
1146 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1148 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1149 while (((CHAR16
*)NewBuffer
)[NewSize
/2] == CHAR_NULL
) {
1151 // We want to overwrite the CHAR_NULL
1155 CopyMem((UINT8
*)NewBuffer
+ NewSize
+ 2, Buffer
, *BufferSize
);
1156 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1157 FreePool(NewBuffer
);
1160 SHELL_FREE_NON_NULL(NewBuffer
);
1161 return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, *BufferSize
, Buffer
));
1167 File style interface for Non Volatile Environment Variable (Write).
1169 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1170 @param[in, out] BufferSize Size in bytes of Buffer.
1171 @param[in] Buffer The pointer to the buffer to write.
1173 @retval EFI_SUCCESS The data was read.
1177 FileInterfaceEnvNonVolWrite(
1178 IN EFI_FILE_PROTOCOL
*This
,
1179 IN OUT UINTN
*BufferSize
,
1190 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1191 if (Status
== EFI_BUFFER_TOO_SMALL
){
1192 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
);
1193 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1195 if (!EFI_ERROR(Status
)) {
1196 CopyMem((UINT8
*)NewBuffer
+ NewSize
, Buffer
, *BufferSize
);
1197 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1198 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1199 NewSize
+ *BufferSize
,
1202 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1203 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1210 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1211 environment variables through file operations.
1213 @param EnvName The name of the Environment Variable to be operated on.
1215 @retval NULL Memory could not be allocated.
1216 @return other a pointer to an EFI_FILE_PROTOCOL structure
1220 CreateFileInterfaceEnv(
1221 IN CONST CHAR16
*EnvName
1225 EFI_FILE_PROTOCOL_ENVIRONMENT
*EnvFileInterface
;
1229 if (EnvName
== NULL
) {
1233 Status
= IsVolatileEnv (EnvName
, &Volatile
);
1234 if (EFI_ERROR (Status
)) {
1241 EnvNameSize
= StrSize(EnvName
);
1242 EnvFileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT
)+EnvNameSize
);
1243 if (EnvFileInterface
== NULL
){
1248 // Assign the generic members
1250 EnvFileInterface
->Revision
= EFI_FILE_REVISION
;
1251 EnvFileInterface
->Open
= FileInterfaceOpenNotFound
;
1252 EnvFileInterface
->Close
= FileInterfaceEnvClose
;
1253 EnvFileInterface
->GetPosition
= FileInterfaceNopGetPosition
;
1254 EnvFileInterface
->SetPosition
= FileInterfaceNopSetPosition
;
1255 EnvFileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1256 EnvFileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1257 EnvFileInterface
->Flush
= FileInterfaceNopGeneric
;
1258 EnvFileInterface
->Delete
= FileInterfaceEnvDelete
;
1259 EnvFileInterface
->Read
= FileInterfaceEnvRead
;
1261 CopyMem(EnvFileInterface
->Name
, EnvName
, EnvNameSize
);
1264 // Assign the different members for Volatile and Non-Volatile variables
1267 EnvFileInterface
->Write
= FileInterfaceEnvVolWrite
;
1269 EnvFileInterface
->Write
= FileInterfaceEnvNonVolWrite
;
1271 return ((EFI_FILE_PROTOCOL
*)EnvFileInterface
);
1275 Move the cursor position one character backward.
1277 @param[in] LineLength Length of a line. Get it by calling QueryMode
1278 @param[in, out] Column Current column of the cursor position
1279 @param[in, out] Row Current row of the cursor position
1283 MoveCursorBackward (
1284 IN UINTN LineLength
,
1285 IN OUT UINTN
*Column
,
1290 // If current column is 0, move to the last column of the previous line,
1291 // otherwise, just decrement column.
1294 *Column
= LineLength
- 1;
1304 Move the cursor position one character forward.
1306 @param[in] LineLength Length of a line.
1307 @param[in] TotalRow Total row of a screen
1308 @param[in, out] Column Current column of the cursor position
1309 @param[in, out] Row Current row of the cursor position
1314 IN UINTN LineLength
,
1316 IN OUT UINTN
*Column
,
1321 // Increment Column.
1322 // If this puts column past the end of the line, move to first column
1326 if (*Column
>= LineLength
) {
1328 if ((*Row
) < TotalRow
- 1) {
1335 Prints out each previously typed command in the command list history log.
1337 When each screen is full it will pause for a key before continuing.
1339 @param[in] TotalCols How many columns are on the screen
1340 @param[in] TotalRows How many rows are on the screen
1341 @param[in] StartColumn which column to start at
1345 PrintCommandHistory (
1346 IN CONST UINTN TotalCols
,
1347 IN CONST UINTN TotalRows
,
1348 IN CONST UINTN StartColumn
1356 ShellPrintEx (-1, -1, L
"\n");
1360 // go through history list...
1362 for ( Node
= (BUFFER_LIST
*)GetFirstNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
)
1363 ; !IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1364 ; Node
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1367 LineCount
= ((StrLen (Node
->Buffer
) + StartColumn
+ 1) / TotalCols
) + 1;
1369 if (LineNumber
+ LineCount
>= TotalRows
) {
1370 ShellPromptForResponseHii(
1371 ShellPromptResponseTypeEnterContinue
,
1372 STRING_TOKEN (STR_SHELL_ENTER_TO_CONT
),
1373 ShellInfoObject
.HiiHandle
,
1378 ShellPrintEx (-1, -1, L
"%2d. %s\n", Index
, Node
->Buffer
);
1379 LineNumber
+= LineCount
;
1389 // This is identical to EFI_FILE_PROTOCOL except for the additional members
1390 // for the buffer, size, and position.
1396 EFI_FILE_CLOSE Close
;
1397 EFI_FILE_DELETE Delete
;
1399 EFI_FILE_WRITE Write
;
1400 EFI_FILE_GET_POSITION GetPosition
;
1401 EFI_FILE_SET_POSITION SetPosition
;
1402 EFI_FILE_GET_INFO GetInfo
;
1403 EFI_FILE_SET_INFO SetInfo
;
1404 EFI_FILE_FLUSH Flush
;
1410 } EFI_FILE_PROTOCOL_MEM
;
1413 File style interface for Mem (SetPosition).
1415 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1416 @param[out] Position The position to set.
1418 @retval EFI_SUCCESS The position was successfully changed.
1419 @retval EFI_INVALID_PARAMETER The Position was invalid.
1423 FileInterfaceMemSetPosition(
1424 IN EFI_FILE_PROTOCOL
*This
,
1428 if (Position
<= ((EFI_FILE_PROTOCOL_MEM
*)This
)->FileSize
) {
1429 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= Position
;
1430 return (EFI_SUCCESS
);
1432 return (EFI_INVALID_PARAMETER
);
1437 File style interface for Mem (GetPosition).
1439 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1440 @param[out] Position The pointer to the position.
1442 @retval EFI_SUCCESS The position was retrieved.
1446 FileInterfaceMemGetPosition(
1447 IN EFI_FILE_PROTOCOL
*This
,
1448 OUT UINT64
*Position
1451 *Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
;
1452 return (EFI_SUCCESS
);
1456 File style interface for Mem (Write).
1458 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1459 @param[in, out] BufferSize Size in bytes of Buffer.
1460 @param[in] Buffer The pointer to the buffer to write.
1462 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
1463 @retval EFI_SUCCESS The data was written.
1467 FileInterfaceMemWrite(
1468 IN EFI_FILE_PROTOCOL
*This
,
1469 IN OUT UINTN
*BufferSize
,
1474 EFI_FILE_PROTOCOL_MEM
*MemFile
;
1476 MemFile
= (EFI_FILE_PROTOCOL_MEM
*) This
;
1477 if (MemFile
->Unicode
) {
1481 if ((UINTN
)(MemFile
->Position
+ (*BufferSize
)) > (UINTN
)(MemFile
->BufferSize
)) {
1482 MemFile
->Buffer
= ReallocatePool((UINTN
)(MemFile
->BufferSize
), (UINTN
)(MemFile
->BufferSize
) + (*BufferSize
) + MEM_WRITE_REALLOC_OVERHEAD
, MemFile
->Buffer
);
1483 MemFile
->BufferSize
+= (*BufferSize
) + MEM_WRITE_REALLOC_OVERHEAD
;
1485 CopyMem(((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, Buffer
, *BufferSize
);
1486 MemFile
->Position
+= (*BufferSize
);
1487 MemFile
->FileSize
= MemFile
->Position
;
1488 return (EFI_SUCCESS
);
1493 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1494 if (AsciiBuffer
== NULL
) {
1495 return (EFI_OUT_OF_RESOURCES
);
1497 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1498 if ((UINTN
)(MemFile
->Position
+ AsciiStrSize(AsciiBuffer
)) > (UINTN
)(MemFile
->BufferSize
)) {
1499 MemFile
->Buffer
= ReallocatePool((UINTN
)(MemFile
->BufferSize
), (UINTN
)(MemFile
->BufferSize
) + AsciiStrSize(AsciiBuffer
) + MEM_WRITE_REALLOC_OVERHEAD
, MemFile
->Buffer
);
1500 MemFile
->BufferSize
+= AsciiStrSize(AsciiBuffer
) + MEM_WRITE_REALLOC_OVERHEAD
;
1502 CopyMem(((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, AsciiBuffer
, AsciiStrSize(AsciiBuffer
));
1503 MemFile
->Position
+= (*BufferSize
/ sizeof(CHAR16
));
1504 MemFile
->FileSize
= MemFile
->Position
;
1505 FreePool(AsciiBuffer
);
1506 return (EFI_SUCCESS
);
1511 File style interface for Mem (Read).
1513 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1514 @param[in, out] BufferSize Size in bytes of Buffer.
1515 @param[in] Buffer The pointer to the buffer to fill.
1517 @retval EFI_SUCCESS The data was read.
1521 FileInterfaceMemRead(
1522 IN EFI_FILE_PROTOCOL
*This
,
1523 IN OUT UINTN
*BufferSize
,
1527 EFI_FILE_PROTOCOL_MEM
*MemFile
;
1529 MemFile
= (EFI_FILE_PROTOCOL_MEM
*) This
;
1530 if (*BufferSize
> (UINTN
)((MemFile
->FileSize
) - (UINTN
)(MemFile
->Position
))) {
1531 (*BufferSize
) = (UINTN
)((MemFile
->FileSize
) - (UINTN
)(MemFile
->Position
));
1533 CopyMem(Buffer
, ((UINT8
*)MemFile
->Buffer
) + MemFile
->Position
, (*BufferSize
));
1534 MemFile
->Position
= MemFile
->Position
+ (*BufferSize
);
1535 return (EFI_SUCCESS
);
1539 File style interface for Mem (Close).
1541 Frees all memory associated with this object.
1543 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1545 @retval EFI_SUCCESS The 'file' was closed.
1549 FileInterfaceMemClose(
1550 IN EFI_FILE_PROTOCOL
*This
1553 SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1554 SHELL_FREE_NON_NULL(This
);
1555 return (EFI_SUCCESS
);
1559 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1560 a file entirely in memory through file operations.
1562 @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.
1564 @retval NULL Memory could not be allocated.
1565 @return other A pointer to an EFI_FILE_PROTOCOL structure.
1569 CreateFileInterfaceMem(
1570 IN CONST BOOLEAN Unicode
1573 EFI_FILE_PROTOCOL_MEM
*FileInterface
;
1578 FileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM
));
1579 if (FileInterface
== NULL
){
1584 // Assign the generic members
1586 FileInterface
->Revision
= EFI_FILE_REVISION
;
1587 FileInterface
->Open
= FileInterfaceOpenNotFound
;
1588 FileInterface
->Close
= FileInterfaceMemClose
;
1589 FileInterface
->GetPosition
= FileInterfaceMemGetPosition
;
1590 FileInterface
->SetPosition
= FileInterfaceMemSetPosition
;
1591 FileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1592 FileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1593 FileInterface
->Flush
= FileInterfaceNopGeneric
;
1594 FileInterface
->Delete
= FileInterfaceNopGeneric
;
1595 FileInterface
->Read
= FileInterfaceMemRead
;
1596 FileInterface
->Write
= FileInterfaceMemWrite
;
1597 FileInterface
->Unicode
= Unicode
;
1599 ASSERT(FileInterface
->Buffer
== NULL
);
1600 ASSERT(FileInterface
->BufferSize
== 0);
1601 ASSERT(FileInterface
->Position
== 0);
1604 FileInterface
->Buffer
= AllocateZeroPool(sizeof(gUnicodeFileTag
));
1605 if (FileInterface
->Buffer
== NULL
) {
1606 FreePool (FileInterface
);
1609 *((CHAR16
*) (FileInterface
->Buffer
)) = EFI_UNICODE_BYTE_ORDER_MARK
;
1610 FileInterface
->BufferSize
= 2;
1611 FileInterface
->Position
= 2;
1614 return ((EFI_FILE_PROTOCOL
*)FileInterface
);
1620 EFI_FILE_CLOSE Close
;
1621 EFI_FILE_DELETE Delete
;
1623 EFI_FILE_WRITE Write
;
1624 EFI_FILE_GET_POSITION GetPosition
;
1625 EFI_FILE_SET_POSITION SetPosition
;
1626 EFI_FILE_GET_INFO GetInfo
;
1627 EFI_FILE_SET_INFO SetInfo
;
1628 EFI_FILE_FLUSH Flush
;
1630 EFI_FILE_PROTOCOL
*Orig
;
1631 } EFI_FILE_PROTOCOL_FILE
;
1634 Set a files current position
1636 @param This Protocol instance pointer.
1637 @param Position Byte position from the start of the file.
1639 @retval EFI_SUCCESS Data was written.
1640 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1645 FileInterfaceFileSetPosition(
1646 IN EFI_FILE_PROTOCOL
*This
,
1650 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1654 Get a file's current position
1656 @param This Protocol instance pointer.
1657 @param Position Byte position from the start of the file.
1659 @retval EFI_SUCCESS Data was written.
1660 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1665 FileInterfaceFileGetPosition(
1666 IN EFI_FILE_PROTOCOL
*This
,
1667 OUT UINT64
*Position
1670 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1674 Get information about a file.
1676 @param This Protocol instance pointer.
1677 @param InformationType Type of information to return in Buffer.
1678 @param BufferSize On input size of buffer, on output amount of data in buffer.
1679 @param Buffer The buffer to return data.
1681 @retval EFI_SUCCESS Data was returned.
1682 @retval EFI_UNSUPPORT InformationType is not supported.
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_WRITE_PROTECTED The device is write protected.
1687 @retval EFI_ACCESS_DENIED The file was open for read only.
1688 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1693 FileInterfaceFileGetInfo(
1694 IN EFI_FILE_PROTOCOL
*This
,
1695 IN EFI_GUID
*InformationType
,
1696 IN OUT UINTN
*BufferSize
,
1700 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1704 Set information about a file
1706 @param This Protocol instance pointer.
1707 @param InformationType Type of information in Buffer.
1708 @param BufferSize Size of buffer.
1709 @param Buffer The data to write.
1711 @retval EFI_SUCCESS Data was returned.
1712 @retval EFI_UNSUPPORT InformationType is not supported.
1713 @retval EFI_NO_MEDIA The device has no media.
1714 @retval EFI_DEVICE_ERROR The device reported an error.
1715 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1716 @retval EFI_WRITE_PROTECTED The device is write protected.
1717 @retval EFI_ACCESS_DENIED The file was open for read only.
1722 FileInterfaceFileSetInfo(
1723 IN EFI_FILE_PROTOCOL
*This
,
1724 IN EFI_GUID
*InformationType
,
1725 IN UINTN BufferSize
,
1729 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1733 Flush data back for the file handle.
1735 @param This Protocol instance pointer.
1737 @retval EFI_SUCCESS Data was written.
1738 @retval EFI_UNSUPPORT Writes to Open directory are not supported.
1739 @retval EFI_NO_MEDIA The device has no media.
1740 @retval EFI_DEVICE_ERROR The device reported an error.
1741 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1742 @retval EFI_WRITE_PROTECTED The device is write protected.
1743 @retval EFI_ACCESS_DENIED The file was open for read only.
1744 @retval EFI_VOLUME_FULL The volume is full.
1749 FileInterfaceFileFlush(
1750 IN EFI_FILE_PROTOCOL
*This
1753 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Flush(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1757 Read data from the file.
1759 @param This Protocol instance pointer.
1760 @param BufferSize On input size of buffer, on output amount of data in buffer.
1761 @param Buffer The buffer in which data is read.
1763 @retval EFI_SUCCESS Data was read.
1764 @retval EFI_NO_MEDIA The device has no media.
1765 @retval EFI_DEVICE_ERROR The device reported an error.
1766 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1767 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1772 FileInterfaceFileRead(
1773 IN EFI_FILE_PROTOCOL
*This
,
1774 IN OUT UINTN
*BufferSize
,
1778 CHAR8
*AsciiStrBuffer
;
1779 CHAR16
*UscStrBuffer
;
1783 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1787 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1792 Size
= (*BufferSize
) / sizeof(CHAR16
);
1793 AsciiStrBuffer
= AllocateZeroPool(Size
+ sizeof(CHAR8
));
1794 if (AsciiStrBuffer
== NULL
) {
1795 return EFI_OUT_OF_RESOURCES
;
1797 UscStrBuffer
= AllocateZeroPool(*BufferSize
+ sizeof(CHAR16
));
1798 if (UscStrBuffer
== NULL
) {
1799 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1800 return EFI_OUT_OF_RESOURCES
;
1802 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiStrBuffer
));
1803 if (!EFI_ERROR(Status
)) {
1804 CharNum
= UnicodeSPrint(UscStrBuffer
, *BufferSize
+ sizeof(CHAR16
), L
"%a", AsciiStrBuffer
);
1805 if (CharNum
== Size
) {
1806 CopyMem (Buffer
, UscStrBuffer
, *BufferSize
);
1808 Status
= EFI_UNSUPPORTED
;
1811 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1812 SHELL_FREE_NON_NULL(UscStrBuffer
);
1818 Opens a new file relative to the source file's location.
1820 @param[in] This The protocol instance pointer.
1821 @param[out] NewHandle Returns File Handle for FileName.
1822 @param[in] FileName Null terminated string. "\", ".", and ".." are supported.
1823 @param[in] OpenMode Open mode for file.
1824 @param[in] Attributes Only used for EFI_FILE_MODE_CREATE.
1826 @retval EFI_SUCCESS The device was opened.
1827 @retval EFI_NOT_FOUND The specified file could not be found on the device.
1828 @retval EFI_NO_MEDIA The device has no media.
1829 @retval EFI_MEDIA_CHANGED The media has changed.
1830 @retval EFI_DEVICE_ERROR The device reported an error.
1831 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1832 @retval EFI_ACCESS_DENIED The service denied access to the file.
1833 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
1834 @retval EFI_VOLUME_FULL The volume is full.
1838 FileInterfaceFileOpen (
1839 IN EFI_FILE_PROTOCOL
*This
,
1840 OUT EFI_FILE_PROTOCOL
**NewHandle
,
1841 IN CHAR16
*FileName
,
1843 IN UINT64 Attributes
1846 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Open(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, NewHandle
, FileName
, OpenMode
, Attributes
);
1850 Close and delete the file handle.
1852 @param This Protocol instance pointer.
1854 @retval EFI_SUCCESS The device was opened.
1855 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
1860 FileInterfaceFileDelete(
1861 IN EFI_FILE_PROTOCOL
*This
1865 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Delete(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1871 File style interface for File (Close).
1873 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1875 @retval EFI_SUCCESS The file was closed.
1879 FileInterfaceFileClose(
1880 IN EFI_FILE_PROTOCOL
*This
1884 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Close(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1890 File style interface for File (Write).
1892 If the file was opened with ASCII mode the data will be processed through
1893 AsciiSPrint before writing.
1895 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1896 @param[in, out] BufferSize Size in bytes of Buffer.
1897 @param[in] Buffer The pointer to the buffer to write.
1899 @retval EFI_SUCCESS The data was written.
1903 FileInterfaceFileWrite(
1904 IN EFI_FILE_PROTOCOL
*This
,
1905 IN OUT UINTN
*BufferSize
,
1912 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1916 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1921 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1922 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1923 Size
= AsciiStrSize(AsciiBuffer
) - 1; // (we dont need the null terminator)
1924 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1925 FreePool(AsciiBuffer
);
1931 Create a file interface with unicode information.
1933 This will create a new EFI_FILE_PROTOCOL identical to the Templace
1934 except that the new one has Unicode and Ascii knowledge.
1936 @param[in] Template A pointer to the EFI_FILE_PROTOCOL object.
1937 @param[in] Unicode TRUE for UCS-2, FALSE for ASCII.
1939 @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
1942 CreateFileInterfaceFile(
1943 IN CONST EFI_FILE_PROTOCOL
*Template
,
1944 IN CONST BOOLEAN Unicode
1947 EFI_FILE_PROTOCOL_FILE
*NewOne
;
1949 NewOne
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE
));
1950 if (NewOne
== NULL
) {
1953 CopyMem(NewOne
, Template
, sizeof(EFI_FILE_PROTOCOL_FILE
));
1954 NewOne
->Orig
= (EFI_FILE_PROTOCOL
*)Template
;
1955 NewOne
->Unicode
= Unicode
;
1956 NewOne
->Open
= FileInterfaceFileOpen
;
1957 NewOne
->Close
= FileInterfaceFileClose
;
1958 NewOne
->Delete
= FileInterfaceFileDelete
;
1959 NewOne
->Read
= FileInterfaceFileRead
;
1960 NewOne
->Write
= FileInterfaceFileWrite
;
1961 NewOne
->GetPosition
= FileInterfaceFileGetPosition
;
1962 NewOne
->SetPosition
= FileInterfaceFileSetPosition
;
1963 NewOne
->GetInfo
= FileInterfaceFileGetInfo
;
1964 NewOne
->SetInfo
= FileInterfaceFileSetInfo
;
1965 NewOne
->Flush
= FileInterfaceFileFlush
;
1967 return ((EFI_FILE_PROTOCOL
*)NewOne
);