2 EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
3 StdIn, StdOut, StdErr, etc...).
5 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "FileHandleInternal.h"
21 File style interface for console (Open).
23 @param[in] This Ignored.
24 @param[out] NewHandle Ignored.
25 @param[in] FileName Ignored.
26 @param[in] OpenMode Ignored.
27 @param[in] Attributes Ignored.
33 FileInterfaceOpenNotFound(
34 IN EFI_FILE_PROTOCOL
*This
,
35 OUT EFI_FILE_PROTOCOL
**NewHandle
,
41 return (EFI_NOT_FOUND
);
45 File style interface for console (Close, Delete, & Flush)
47 @param[in] This Ignored.
53 FileInterfaceNopGeneric(
54 IN EFI_FILE_PROTOCOL
*This
61 File style interface for console (GetPosition).
63 @param[in] This Ignored.
64 @param[out] Position Ignored.
66 @retval EFI_UNSUPPORTED
70 FileInterfaceNopGetPosition(
71 IN EFI_FILE_PROTOCOL
*This
,
75 return (EFI_UNSUPPORTED
);
79 File style interface for console (SetPosition).
81 @param[in] This Ignored.
82 @param[in] Position Ignored.
84 @retval EFI_UNSUPPORTED
88 FileInterfaceNopSetPosition(
89 IN EFI_FILE_PROTOCOL
*This
,
93 return (EFI_UNSUPPORTED
);
97 File style interface for console (GetInfo).
99 @param[in] This Ignored.
100 @param[in] InformationType Ignored.
101 @param[in, out] BufferSize Ignored.
102 @param[out] Buffer Ignored.
104 @retval EFI_UNSUPPORTED
108 FileInterfaceNopGetInfo(
109 IN EFI_FILE_PROTOCOL
*This
,
110 IN EFI_GUID
*InformationType
,
111 IN OUT UINTN
*BufferSize
,
115 return (EFI_UNSUPPORTED
);
119 File style interface for console (SetInfo).
121 @param[in] This Ignored.
122 @param[in] InformationType Ignored.
123 @param[in] BufferSize Ignored.
124 @param[in] Buffer Ignored.
126 @retval EFI_UNSUPPORTED
130 FileInterfaceNopSetInfo(
131 IN EFI_FILE_PROTOCOL
*This
,
132 IN EFI_GUID
*InformationType
,
137 return (EFI_UNSUPPORTED
);
141 File style interface for StdOut (Write).
143 Writes data to the screen.
145 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
146 @param[in, out] BufferSize Size in bytes of Buffer.
147 @param[in] Buffer The pointer to the buffer to write.
149 @retval EFI_UNSUPPORTED No output console is supported.
150 @return A return value from gST->ConOut->OutputString.
154 FileInterfaceStdOutWrite(
155 IN EFI_FILE_PROTOCOL
*This
,
156 IN OUT UINTN
*BufferSize
,
160 if (ShellInfoObject
.ShellInitSettings
.BitUnion
.Bits
.NoConsoleOut
) {
161 return (EFI_UNSUPPORTED
);
163 return (gST
->ConOut
->OutputString(gST
->ConOut
, Buffer
));
168 File style interface for StdIn (Write).
170 @param[in] This Ignored.
171 @param[in, out] BufferSize Ignored.
172 @param[in] Buffer Ignored.
174 @retval EFI_UNSUPPORTED
178 FileInterfaceStdInWrite(
179 IN EFI_FILE_PROTOCOL
*This
,
180 IN OUT UINTN
*BufferSize
,
184 return (EFI_UNSUPPORTED
);
188 File style interface for console StdErr (Write).
190 Writes error to the error output.
192 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
193 @param[in, out] BufferSize Size in bytes of Buffer.
194 @param[in] Buffer The pointer to the buffer to write.
196 @return A return value from gST->StdErr->OutputString.
200 FileInterfaceStdErrWrite(
201 IN EFI_FILE_PROTOCOL
*This
,
202 IN OUT UINTN
*BufferSize
,
206 return (gST
->StdErr
->OutputString(gST
->StdErr
, Buffer
));
210 File style interface for console StdOut (Read).
212 @param[in] This Ignored.
213 @param[in, out] BufferSize Ignored.
214 @param[out] Buffer Ignored.
216 @retval EFI_UNSUPPORTED
220 FileInterfaceStdOutRead(
221 IN EFI_FILE_PROTOCOL
*This
,
222 IN OUT UINTN
*BufferSize
,
226 return (EFI_UNSUPPORTED
);
230 File style interface for console StdErr (Read).
232 @param[in] This Ignored.
233 @param[in, out] BufferSize Ignored.
234 @param[out] Buffer Ignored.
236 @retval EFI_UNSUPPORTED Always.
240 FileInterfaceStdErrRead(
241 IN EFI_FILE_PROTOCOL
*This
,
242 IN OUT UINTN
*BufferSize
,
246 return (EFI_UNSUPPORTED
);
250 File style interface for NUL file (Read).
252 @param[in] This Ignored.
253 @param[in, out] BufferSize Poiner to 0 upon return.
254 @param[out] Buffer Ignored.
256 @retval EFI_SUCCESS Always.
260 FileInterfaceNulRead(
261 IN EFI_FILE_PROTOCOL
*This
,
262 IN OUT UINTN
*BufferSize
,
267 return (EFI_SUCCESS
);
271 File style interface for NUL file (Write).
273 @param[in] This Ignored.
274 @param[in, out] BufferSize Ignored.
275 @param[in] Buffer Ignored.
281 FileInterfaceNulWrite(
282 IN EFI_FILE_PROTOCOL
*This
,
283 IN OUT UINTN
*BufferSize
,
287 return (EFI_SUCCESS
);
291 File style interface for console (Read).
293 This will return a single line of input from the console.
295 @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
296 file handle to read data from. Not used.
297 @param BufferSize On input, the size of the Buffer. On output, the amount
298 of data returned in Buffer. In both cases, the size is
300 @param Buffer The buffer into which the data is read.
303 @retval EFI_SUCCESS The data was read.
304 @retval EFI_NO_MEDIA The device has no medium.
305 @retval EFI_DEVICE_ERROR The device reported an error.
306 @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
307 @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
308 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
309 @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
310 entry. BufferSize has been updated with the size
311 needed to complete the request.
312 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
316 FileInterfaceStdInRead(
317 IN EFI_FILE_PROTOCOL
*This
,
318 IN OUT UINTN
*BufferSize
,
322 CHAR16
*CurrentString
;
324 UINTN Column
; // Column of current cursor
325 UINTN Row
; // Row of current cursor
326 UINTN StartColumn
; // Column at the beginning of the line
327 UINTN Update
; // Line index for update
328 UINTN Delete
; // Num of chars to delete from console after update
329 UINTN StringLen
; // Total length of the line
330 UINTN StringCurPos
; // Line index corresponding to the cursor
331 UINTN MaxStr
; // Maximum possible line length
333 UINTN TotalColumn
; // Num of columns in the console
334 UINTN TotalRow
; // Num of rows in the console
336 UINTN OutputLength
; // Length of the update string
337 UINTN TailRow
; // Row of end of line
338 UINTN TailColumn
; // Column of end of line
341 BUFFER_LIST
*LinePos
;
345 BOOLEAN InTabScrolling
; // Whether in TAB-completion state
346 EFI_SHELL_FILE_INFO
*FoundFileList
;
347 EFI_SHELL_FILE_INFO
*TabLinePos
;
348 EFI_SHELL_FILE_INFO
*TempPos
;
350 CHAR16
*TabOutputStr
;
351 BOOLEAN InQuotationMode
;
353 UINTN TabPos
; // Start index of the string to search for TAB completion.
354 UINTN TabUpdatePos
; // Start index of the string updated by TAB stroke
360 // If buffer is not large enough to hold a CHAR16, return minimum buffer size
362 if (*BufferSize
< sizeof (CHAR16
) * 2) {
363 *BufferSize
= sizeof (CHAR16
) * 2;
364 return (EFI_BUFFER_TOO_SMALL
);
368 CurrentString
= Buffer
;
374 LinePos
= NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
376 InTabScrolling
= FALSE
;
377 Status
= EFI_SUCCESS
;
379 FoundFileList
= NULL
;
387 TabStr
= AllocateZeroPool (*BufferSize
);
388 if (TabStr
== NULL
) {
389 return EFI_OUT_OF_RESOURCES
;
391 TabOutputStr
= AllocateZeroPool (*BufferSize
);
392 if (TabOutputStr
== NULL
) {
394 return EFI_OUT_OF_RESOURCES
;
398 // Get the screen setting and the current cursor location
400 Column
= StartColumn
= gST
->ConOut
->Mode
->CursorColumn
;
401 Row
= gST
->ConOut
->Mode
->CursorRow
;
402 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &TotalColumn
, &TotalRow
);
405 // Limit the line length to the buffer size or the minimun size of the
406 // screen. (The smaller takes effect)
408 MaxStr
= TotalColumn
* (TotalRow
- 1) - StartColumn
;
409 if (MaxStr
> *BufferSize
/ sizeof (CHAR16
)) {
410 MaxStr
= *BufferSize
/ sizeof (CHAR16
);
412 ZeroMem (CurrentString
, MaxStr
* sizeof (CHAR16
));
417 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
418 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
419 if (EFI_ERROR (Status
)) {
424 // Press PageUp or PageDown to scroll the history screen up or down.
425 // Press any other key to quit scrolling.
427 if (Key
.UnicodeChar
== 0 && (Key
.ScanCode
== SCAN_PAGE_UP
|| Key
.ScanCode
== SCAN_PAGE_DOWN
)) {
428 if (Key
.ScanCode
== SCAN_PAGE_UP
) {
429 ConsoleLoggerDisplayHistory(FALSE
, 0, ShellInfoObject
.ConsoleInfo
);
430 } else if (Key
.ScanCode
== SCAN_PAGE_DOWN
) {
431 ConsoleLoggerDisplayHistory(TRUE
, 0, ShellInfoObject
.ConsoleInfo
);
437 ConsoleLoggerStopHistory(ShellInfoObject
.ConsoleInfo
);
443 // If we are quitting TAB scrolling...
445 if (InTabScrolling
&& Key
.UnicodeChar
!= CHAR_TAB
) {
446 if (FoundFileList
!= NULL
) {
447 ShellInfoObject
.NewEfiShellProtocol
->FreeFileList (&FoundFileList
);
448 DEBUG_CODE(FoundFileList
= NULL
;);
450 InTabScrolling
= FALSE
;
453 switch (Key
.UnicodeChar
) {
454 case CHAR_CARRIAGE_RETURN
:
456 // All done, print a newline at the end of the string
458 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
459 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
460 ShellPrintEx ((INT32
)TailColumn
, (INT32
)TailRow
, L
"%N\n");
465 if (StringCurPos
!= 0) {
467 // If not move back beyond string beginning, move all characters behind
468 // the current position one character forward
471 Update
= StringCurPos
;
473 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
476 // Adjust the current column and row
478 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
484 // handle auto complete of file and directory names...
486 if (InTabScrolling
) {
487 ASSERT(FoundFileList
!= NULL
);
488 ASSERT(TabLinePos
!= NULL
);
489 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &TabLinePos
->Link
);
490 if (IsNull(&(FoundFileList
->Link
), &TabLinePos
->Link
)) {
491 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &TabLinePos
->Link
);
496 InQuotationMode
= FALSE
;
497 for (Index
= 0; Index
< StringLen
; Index
++) {
498 if (CurrentString
[Index
] == L
'\"') {
499 InQuotationMode
= (BOOLEAN
)(!InQuotationMode
);
501 if (CurrentString
[Index
] == L
' ' && !InQuotationMode
) {
503 TabUpdatePos
= Index
+ 1;
505 if (CurrentString
[Index
] == L
'\\') {
506 TabUpdatePos
= Index
+ 1;
509 if (StrStr(CurrentString
+ TabPos
, L
":") == NULL
) {
510 Cwd
= ShellInfoObject
.NewEfiShellProtocol
->GetCurDir(NULL
);
512 StrnCpyS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), Cwd
, (*BufferSize
)/sizeof(CHAR16
) - 1);
513 StrCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), L
"\\");
514 if (TabStr
[StrLen(TabStr
)-1] == L
'\\' && *(CurrentString
+ TabPos
) == L
'\\' ) {
515 TabStr
[StrLen(TabStr
)-1] = CHAR_NULL
;
518 (*BufferSize
)/sizeof(CHAR16
),
519 CurrentString
+ TabPos
,
524 StrnCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), CurrentString
+ TabPos
, StringLen
- TabPos
);
527 StrnCpyS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), CurrentString
+ TabPos
, (*BufferSize
)/sizeof(CHAR16
) - 1);
529 StrnCatS(TabStr
, (*BufferSize
)/sizeof(CHAR16
), L
"*", (*BufferSize
)/sizeof(CHAR16
) - 1 - StrLen(TabStr
));
530 FoundFileList
= NULL
;
531 Status
= ShellInfoObject
.NewEfiShellProtocol
->FindFiles(TabStr
, &FoundFileList
);
532 for ( TempStr
= CurrentString
534 ; TempStr
++); // note the ';'... empty for loop
536 // make sure we have a list before we do anything more...
538 if (EFI_ERROR (Status
) || FoundFileList
== NULL
) {
539 InTabScrolling
= FALSE
;
544 // enumerate through the list of files
546 for ( TempPos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&(FoundFileList
->Link
))
547 ; !IsNull(&FoundFileList
->Link
, &TempPos
->Link
)
548 ; TempPos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &(TempPos
->Link
))
551 // If "cd" is typed, only directory name will be auto-complete filled
552 // in either case . and .. will be removed.
554 if ((((TempStr
[0] == L
'c' || TempStr
[0] == L
'C') &&
555 (TempStr
[1] == L
'd' || TempStr
[1] == L
'D')
556 ) && ((ShellIsDirectory(TempPos
->FullName
) != EFI_SUCCESS
)
557 ||(StrCmp(TempPos
->FileName
, L
".") == 0)
558 ||(StrCmp(TempPos
->FileName
, L
"..") == 0)
559 )) || ((StrCmp(TempPos
->FileName
, L
".") == 0)
560 ||(StrCmp(TempPos
->FileName
, L
"..") == 0))){
561 TabLinePos
= TempPos
;
562 TempPos
= (EFI_SHELL_FILE_INFO
*)(RemoveEntryList(&(TempPos
->Link
))->BackLink
);
563 InternalFreeShellFileInfoNode(TabLinePos
);
566 if (FoundFileList
!= NULL
&& !IsListEmpty(&FoundFileList
->Link
)) {
567 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FoundFileList
->Link
);
568 InTabScrolling
= TRUE
;
570 FreePool(FoundFileList
);
571 FoundFileList
= NULL
;
578 if (Key
.UnicodeChar
>= ' ') {
580 // If we are at the buffer's end, drop the key
582 if (StringLen
== MaxStr
- 1 && (ShellInfoObject
.ViewingSettings
.InsertMode
|| StringCurPos
== StringLen
)) {
586 // If in insert mode, make space by moving each other character 1
587 // space higher in the array
589 if (ShellInfoObject
.ViewingSettings
.InsertMode
) {
590 CopyMem(CurrentString
+ StringCurPos
+ 1, CurrentString
+ StringCurPos
, (StringLen
- StringCurPos
)*sizeof(CurrentString
[0]));
593 CurrentString
[StringCurPos
] = Key
.UnicodeChar
;
594 Update
= StringCurPos
;
602 switch (Key
.ScanCode
) {
605 // Move characters behind current position one character forward
607 if (StringLen
!= 0) {
608 Update
= StringCurPos
;
610 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
616 // Prepare to print the previous command
618 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
619 if (IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
)) {
620 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
626 // Prepare to print the next command
628 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
629 if (NewPos
== (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
630 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
636 // Adjust current cursor position
638 if (StringCurPos
!= 0) {
640 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
646 // Adjust current cursor position
648 if (StringCurPos
< StringLen
) {
650 MoveCursorForward (TotalColumn
, TotalRow
, &Column
, &Row
);
656 // Move current cursor position to the beginning of the command line
658 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
659 Column
= StartColumn
;
665 // Move current cursor position to the end of the command line
667 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
668 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
671 StringCurPos
= StringLen
;
676 // Prepare to clear the current command line
678 CurrentString
[0] = 0;
681 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
682 Column
= StartColumn
;
688 // Toggle the SEnvInsertMode flag
690 ShellInfoObject
.ViewingSettings
.InsertMode
= (BOOLEAN
)!ShellInfoObject
.ViewingSettings
.InsertMode
;
695 // Print command history
697 PrintCommandHistory (TotalColumn
, TotalRow
, 4);
698 *CurrentString
= CHAR_NULL
;
709 // If we are in auto-complete mode, we are preparing to print
710 // the next file or directory name
712 if (InTabScrolling
) {
714 // Adjust the column and row to the start of TAB-completion string.
716 Column
= (StartColumn
+ TabUpdatePos
) % TotalColumn
;
717 Row
-= (StartColumn
+ StringCurPos
) / TotalColumn
- (StartColumn
+ TabUpdatePos
) / TotalColumn
;
718 OutputLength
= StrLen (TabLinePos
->FileName
);
720 // if the output string contains blank space, quotation marks L'\"'
721 // should be added to the output.
723 if (StrStr(TabLinePos
->FileName
, L
" ") != NULL
){
724 TabOutputStr
[0] = L
'\"';
725 CopyMem (TabOutputStr
+ 1, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
726 TabOutputStr
[OutputLength
+ 1] = L
'\"';
727 TabOutputStr
[OutputLength
+ 2] = CHAR_NULL
;
729 CopyMem (TabOutputStr
, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
730 TabOutputStr
[OutputLength
] = CHAR_NULL
;
732 OutputLength
= StrLen (TabOutputStr
) < MaxStr
- 1 ? StrLen (TabOutputStr
) : MaxStr
- 1;
733 CopyMem (CurrentString
+ TabUpdatePos
, TabOutputStr
, OutputLength
* sizeof (CHAR16
));
734 CurrentString
[TabUpdatePos
+ OutputLength
] = CHAR_NULL
;
735 StringCurPos
= TabUpdatePos
+ OutputLength
;
736 Update
= TabUpdatePos
;
737 if (StringLen
> TabUpdatePos
+ OutputLength
) {
738 Delete
= StringLen
- TabUpdatePos
- OutputLength
;
743 // If we have a new position, we are preparing to print a previous or
746 if (NewPos
!= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
747 Column
= StartColumn
;
748 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
751 NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
753 OutputLength
= StrLen (LinePos
->Buffer
) < MaxStr
- 1 ? StrLen (LinePos
->Buffer
) : MaxStr
- 1;
754 CopyMem (CurrentString
, LinePos
->Buffer
, OutputLength
* sizeof (CHAR16
));
755 CurrentString
[OutputLength
] = CHAR_NULL
;
757 StringCurPos
= OutputLength
;
760 // Draw new input string
763 if (StringLen
> OutputLength
) {
765 // If old string was longer, blank its tail
767 Delete
= StringLen
- OutputLength
;
771 // If we need to update the output do so now
773 if (Update
!= (UINTN
) -1) {
774 ShellPrintEx ((INT32
)Column
, (INT32
)Row
, L
"%s%.*s", CurrentString
+ Update
, Delete
, L
"");
775 StringLen
= StrLen (CurrentString
);
778 SetMem (CurrentString
+ StringLen
, Delete
* sizeof (CHAR16
), CHAR_NULL
);
781 if (StringCurPos
> StringLen
) {
782 StringCurPos
= StringLen
;
788 // After using print to reflect newly updates, if we're not using
789 // BACKSPACE and DELETE, we need to move the cursor position forward,
790 // so adjust row and column here.
792 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
794 // Calulate row and column of the tail of current string
796 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
+ OutputLength
) / TotalColumn
;
797 TailColumn
= (StringLen
- StringCurPos
+ Column
+ OutputLength
) % TotalColumn
;
800 // If the tail of string reaches screen end, screen rolls up, so if
801 // Row does not equal TailRow, Row should be decremented
803 // (if we are recalling commands using UPPER and DOWN key, and if the
804 // old command is too long to fit the screen, TailColumn must be 79.
806 if (TailColumn
== 0 && TailRow
>= TotalRow
&& Row
!= TailRow
) {
810 // Calculate the cursor position after current operation. If cursor
811 // reaches line end, update both row and column, otherwise, only
812 // column will be changed.
814 if (Column
+ OutputLength
>= TotalColumn
) {
815 SkipLength
= OutputLength
- (TotalColumn
- Column
);
817 Row
+= SkipLength
/ TotalColumn
+ 1;
818 if (Row
> TotalRow
- 1) {
822 Column
= SkipLength
% TotalColumn
;
824 Column
+= OutputLength
;
831 // Set the cursor position for this key
833 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, Column
, Row
);
836 if (CurrentString
!= NULL
&& StrLen(CurrentString
) > 0) {
838 // add the line to the history buffer
840 AddLineToCommandHistory(CurrentString
);
844 FreePool (TabOutputStr
);
846 // Return the data to the caller
848 *BufferSize
= StringLen
* sizeof (CHAR16
);
851 // if this was used it should be deallocated by now...
852 // prevent memory leaks...
854 ASSERT(FoundFileList
== NULL
);
860 // FILE sytle interfaces for StdIn/StdOut/StdErr
862 EFI_FILE_PROTOCOL FileInterfaceStdIn
= {
864 FileInterfaceOpenNotFound
,
865 FileInterfaceNopGeneric
,
866 FileInterfaceNopGeneric
,
867 FileInterfaceStdInRead
,
868 FileInterfaceStdInWrite
,
869 FileInterfaceNopGetPosition
,
870 FileInterfaceNopSetPosition
,
871 FileInterfaceNopGetInfo
,
872 FileInterfaceNopSetInfo
,
873 FileInterfaceNopGeneric
876 EFI_FILE_PROTOCOL FileInterfaceStdOut
= {
878 FileInterfaceOpenNotFound
,
879 FileInterfaceNopGeneric
,
880 FileInterfaceNopGeneric
,
881 FileInterfaceStdOutRead
,
882 FileInterfaceStdOutWrite
,
883 FileInterfaceNopGetPosition
,
884 FileInterfaceNopSetPosition
,
885 FileInterfaceNopGetInfo
,
886 FileInterfaceNopSetInfo
,
887 FileInterfaceNopGeneric
890 EFI_FILE_PROTOCOL FileInterfaceStdErr
= {
892 FileInterfaceOpenNotFound
,
893 FileInterfaceNopGeneric
,
894 FileInterfaceNopGeneric
,
895 FileInterfaceStdErrRead
,
896 FileInterfaceStdErrWrite
,
897 FileInterfaceNopGetPosition
,
898 FileInterfaceNopSetPosition
,
899 FileInterfaceNopGetInfo
,
900 FileInterfaceNopSetInfo
,
901 FileInterfaceNopGeneric
904 EFI_FILE_PROTOCOL FileInterfaceNulFile
= {
906 FileInterfaceOpenNotFound
,
907 FileInterfaceNopGeneric
,
908 FileInterfaceNopGeneric
,
909 FileInterfaceNulRead
,
910 FileInterfaceNulWrite
,
911 FileInterfaceNopGetPosition
,
912 FileInterfaceNopSetPosition
,
913 FileInterfaceNopGetInfo
,
914 FileInterfaceNopSetInfo
,
915 FileInterfaceNopGeneric
922 // This is identical to EFI_FILE_PROTOCOL except for the additional member
929 EFI_FILE_CLOSE Close
;
930 EFI_FILE_DELETE Delete
;
932 EFI_FILE_WRITE Write
;
933 EFI_FILE_GET_POSITION GetPosition
;
934 EFI_FILE_SET_POSITION SetPosition
;
935 EFI_FILE_GET_INFO GetInfo
;
936 EFI_FILE_SET_INFO SetInfo
;
937 EFI_FILE_FLUSH Flush
;
939 } EFI_FILE_PROTOCOL_ENVIRONMENT
;
940 //ANSI compliance helper to get size of the struct.
941 #define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)
944 File style interface for Environment Variable (Close).
946 Frees the memory for this object.
948 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
954 FileInterfaceEnvClose(
955 IN EFI_FILE_PROTOCOL
*This
963 // Most if not all UEFI commands will have an '\r\n' at the end of any output.
964 // Since the output was redirected to a variable, it does not make sense to
965 // keep this. So, before closing, strip the trailing '\r\n' from the variable
971 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
972 if (Status
== EFI_BUFFER_TOO_SMALL
) {
973 NewBuffer
= AllocateZeroPool(NewSize
+ sizeof(CHAR16
));
974 if (NewBuffer
== NULL
) {
975 return EFI_OUT_OF_RESOURCES
;
977 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
980 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
982 if (StrSize(NewBuffer
) > 6)
984 if ((((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 2] == CHAR_LINEFEED
)
985 && (((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] == CHAR_CARRIAGE_RETURN
)) {
986 ((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] = CHAR_NULL
;
989 if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
)) {
990 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
992 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
997 SHELL_FREE_NON_NULL(NewBuffer
);
998 FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
);
1003 File style interface for Environment Variable (Delete).
1005 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1007 @retval The return value from FileInterfaceEnvClose().
1011 FileInterfaceEnvDelete(
1012 IN EFI_FILE_PROTOCOL
*This
1015 SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
);
1016 return (FileInterfaceEnvClose(This
));
1020 File style interface for Environment Variable (Read).
1022 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1023 @param[in, out] BufferSize Size in bytes of Buffer.
1024 @param[out] Buffer The pointer to the buffer to fill.
1026 @retval EFI_SUCCESS The data was read.
1030 FileInterfaceEnvRead(
1031 IN EFI_FILE_PROTOCOL
*This
,
1032 IN OUT UINTN
*BufferSize
,
1036 return (SHELL_GET_ENVIRONMENT_VARIABLE(
1037 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1043 File style interface for Volatile Environment Variable (Write).
1045 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1046 @param[in, out] BufferSize Size in bytes of Buffer.
1047 @param[in] Buffer The pointer to the buffer to write.
1049 @retval EFI_SUCCESS The data was read.
1053 FileInterfaceEnvVolWrite(
1054 IN EFI_FILE_PROTOCOL
*This
,
1055 IN OUT UINTN
*BufferSize
,
1066 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1067 if (Status
== EFI_BUFFER_TOO_SMALL
){
1068 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
+ sizeof(CHAR16
));
1069 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1071 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1072 while (((CHAR16
*)NewBuffer
)[NewSize
/2] == CHAR_NULL
) {
1074 // We want to overwrite the CHAR_NULL
1078 CopyMem((UINT8
*)NewBuffer
+ NewSize
+ 2, Buffer
, *BufferSize
);
1079 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1080 FreePool(NewBuffer
);
1083 SHELL_FREE_NON_NULL(NewBuffer
);
1084 return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, *BufferSize
, Buffer
));
1090 File style interface for Non Volatile Environment Variable (Write).
1092 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1093 @param[in, out] BufferSize Size in bytes of Buffer.
1094 @param[in] Buffer The pointer to the buffer to write.
1096 @retval EFI_SUCCESS The data was read.
1100 FileInterfaceEnvNonVolWrite(
1101 IN EFI_FILE_PROTOCOL
*This
,
1102 IN OUT UINTN
*BufferSize
,
1113 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1114 if (Status
== EFI_BUFFER_TOO_SMALL
){
1115 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
);
1116 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1118 if (!EFI_ERROR(Status
)) {
1119 CopyMem((UINT8
*)NewBuffer
+ NewSize
, Buffer
, *BufferSize
);
1120 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1121 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1122 NewSize
+ *BufferSize
,
1125 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1126 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1133 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1134 environment variables through file operations.
1136 @param EnvName The name of the Environment Variable to be operated on.
1138 @retval NULL Memory could not be allocated.
1139 @return other a pointer to an EFI_FILE_PROTOCOL structure
1143 CreateFileInterfaceEnv(
1144 IN CONST CHAR16
*EnvName
1147 EFI_FILE_PROTOCOL_ENVIRONMENT
*EnvFileInterface
;
1150 if (EnvName
== NULL
) {
1157 EnvNameSize
= StrSize(EnvName
);
1158 EnvFileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT
)+EnvNameSize
);
1159 if (EnvFileInterface
== NULL
){
1164 // Assign the generic members
1166 EnvFileInterface
->Revision
= EFI_FILE_REVISION
;
1167 EnvFileInterface
->Open
= FileInterfaceOpenNotFound
;
1168 EnvFileInterface
->Close
= FileInterfaceEnvClose
;
1169 EnvFileInterface
->GetPosition
= FileInterfaceNopGetPosition
;
1170 EnvFileInterface
->SetPosition
= FileInterfaceNopSetPosition
;
1171 EnvFileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1172 EnvFileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1173 EnvFileInterface
->Flush
= FileInterfaceNopGeneric
;
1174 EnvFileInterface
->Delete
= FileInterfaceEnvDelete
;
1175 EnvFileInterface
->Read
= FileInterfaceEnvRead
;
1177 CopyMem(EnvFileInterface
->Name
, EnvName
, EnvNameSize
);
1180 // Assign the different members for Volatile and Non-Volatile variables
1182 if (IsVolatileEnv(EnvName
)) {
1183 EnvFileInterface
->Write
= FileInterfaceEnvVolWrite
;
1185 EnvFileInterface
->Write
= FileInterfaceEnvNonVolWrite
;
1187 return ((EFI_FILE_PROTOCOL
*)EnvFileInterface
);
1191 Move the cursor position one character backward.
1193 @param[in] LineLength Length of a line. Get it by calling QueryMode
1194 @param[in, out] Column Current column of the cursor position
1195 @param[in, out] Row Current row of the cursor position
1199 MoveCursorBackward (
1200 IN UINTN LineLength
,
1201 IN OUT UINTN
*Column
,
1206 // If current column is 0, move to the last column of the previous line,
1207 // otherwise, just decrement column.
1210 *Column
= LineLength
- 1;
1220 Move the cursor position one character forward.
1222 @param[in] LineLength Length of a line.
1223 @param[in] TotalRow Total row of a screen
1224 @param[in, out] Column Current column of the cursor position
1225 @param[in, out] Row Current row of the cursor position
1230 IN UINTN LineLength
,
1232 IN OUT UINTN
*Column
,
1237 // Increment Column.
1238 // If this puts column past the end of the line, move to first column
1242 if (*Column
>= LineLength
) {
1244 if ((*Row
) < TotalRow
- 1) {
1251 Prints out each previously typed command in the command list history log.
1253 When each screen is full it will pause for a key before continuing.
1255 @param[in] TotalCols How many columns are on the screen
1256 @param[in] TotalRows How many rows are on the screen
1257 @param[in] StartColumn which column to start at
1261 PrintCommandHistory (
1262 IN CONST UINTN TotalCols
,
1263 IN CONST UINTN TotalRows
,
1264 IN CONST UINTN StartColumn
1272 ShellPrintEx (-1, -1, L
"\n");
1276 // go through history list...
1278 for ( Node
= (BUFFER_LIST
*)GetFirstNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
)
1279 ; !IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1280 ; Node
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1283 LineCount
= ((StrLen (Node
->Buffer
) + StartColumn
+ 1) / TotalCols
) + 1;
1285 if (LineNumber
+ LineCount
>= TotalRows
) {
1286 ShellPromptForResponseHii(
1287 ShellPromptResponseTypeEnterContinue
,
1288 STRING_TOKEN (STR_SHELL_ENTER_TO_CONT
),
1289 ShellInfoObject
.HiiHandle
,
1294 ShellPrintEx (-1, -1, L
"%2d. %s\n", Index
, Node
->Buffer
);
1295 LineNumber
+= LineCount
;
1305 // This is identical to EFI_FILE_PROTOCOL except for the additional members
1306 // for the buffer, size, and position.
1312 EFI_FILE_CLOSE Close
;
1313 EFI_FILE_DELETE Delete
;
1315 EFI_FILE_WRITE Write
;
1316 EFI_FILE_GET_POSITION GetPosition
;
1317 EFI_FILE_SET_POSITION SetPosition
;
1318 EFI_FILE_GET_INFO GetInfo
;
1319 EFI_FILE_SET_INFO SetInfo
;
1320 EFI_FILE_FLUSH Flush
;
1325 } EFI_FILE_PROTOCOL_MEM
;
1328 File style interface for Mem (SetPosition).
1330 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1331 @param[out] Position The position to set.
1333 @retval EFI_SUCCESS The position was successfully changed.
1334 @retval EFI_INVALID_PARAMETER The Position was invalid.
1338 FileInterfaceMemSetPosition(
1339 IN EFI_FILE_PROTOCOL
*This
,
1343 if (Position
<= ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) {
1344 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= Position
;
1345 return (EFI_SUCCESS
);
1347 return (EFI_INVALID_PARAMETER
);
1352 File style interface for Mem (GetPosition).
1354 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1355 @param[out] Position The pointer to the position.
1357 @retval EFI_SUCCESS The position was retrieved.
1361 FileInterfaceMemGetPosition(
1362 IN EFI_FILE_PROTOCOL
*This
,
1363 OUT UINT64
*Position
1366 *Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
;
1367 return (EFI_SUCCESS
);
1371 File style interface for Mem (Write).
1373 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1374 @param[in, out] BufferSize Size in bytes of Buffer.
1375 @param[in] Buffer The pointer to the buffer to write.
1377 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
1378 @retval EFI_SUCCESS The data was written.
1382 FileInterfaceMemWrite(
1383 IN EFI_FILE_PROTOCOL
*This
,
1384 IN OUT UINTN
*BufferSize
,
1389 if (((EFI_FILE_PROTOCOL_MEM
*)This
)->Unicode
) {
1393 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1394 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
= ReallocatePool((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
), (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) + (*BufferSize
) + 10, ((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1395 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= (*BufferSize
) + 10;
1397 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, Buffer
, *BufferSize
);
1398 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= (*BufferSize
);
1399 return (EFI_SUCCESS
);
1404 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1405 if (AsciiBuffer
== NULL
) {
1406 return (EFI_OUT_OF_RESOURCES
);
1408 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1409 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ AsciiStrSize(AsciiBuffer
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1410 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
= ReallocatePool((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
), (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) + AsciiStrSize(AsciiBuffer
) + 10, ((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1411 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= AsciiStrSize(AsciiBuffer
) + 10;
1413 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, AsciiBuffer
, AsciiStrSize(AsciiBuffer
));
1414 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= AsciiStrSize(AsciiBuffer
);
1415 FreePool(AsciiBuffer
);
1416 return (EFI_SUCCESS
);
1421 File style interface for Mem (Read).
1423 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1424 @param[in, out] BufferSize Size in bytes of Buffer.
1425 @param[in] Buffer The pointer to the buffer to fill.
1427 @retval EFI_SUCCESS The data was read.
1431 FileInterfaceMemRead(
1432 IN EFI_FILE_PROTOCOL
*This
,
1433 IN OUT UINTN
*BufferSize
,
1437 if (*BufferSize
> (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
))) {
1438 (*BufferSize
) = (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
));
1440 CopyMem(Buffer
, ((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, (*BufferSize
));
1441 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
);
1442 return (EFI_SUCCESS
);
1446 File style interface for Mem (Close).
1448 Frees all memory associated with this object.
1450 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1452 @retval EFI_SUCCESS The 'file' was closed.
1456 FileInterfaceMemClose(
1457 IN EFI_FILE_PROTOCOL
*This
1460 SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1461 SHELL_FREE_NON_NULL(This
);
1462 return (EFI_SUCCESS
);
1466 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1467 a file entirely in memory through file operations.
1469 @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.
1471 @retval NULL Memory could not be allocated.
1472 @return other A pointer to an EFI_FILE_PROTOCOL structure.
1476 CreateFileInterfaceMem(
1477 IN CONST BOOLEAN Unicode
1480 EFI_FILE_PROTOCOL_MEM
*FileInterface
;
1485 FileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM
));
1486 if (FileInterface
== NULL
){
1491 // Assign the generic members
1493 FileInterface
->Revision
= EFI_FILE_REVISION
;
1494 FileInterface
->Open
= FileInterfaceOpenNotFound
;
1495 FileInterface
->Close
= FileInterfaceMemClose
;
1496 FileInterface
->GetPosition
= FileInterfaceMemGetPosition
;
1497 FileInterface
->SetPosition
= FileInterfaceMemSetPosition
;
1498 FileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1499 FileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1500 FileInterface
->Flush
= FileInterfaceNopGeneric
;
1501 FileInterface
->Delete
= FileInterfaceNopGeneric
;
1502 FileInterface
->Read
= FileInterfaceMemRead
;
1503 FileInterface
->Write
= FileInterfaceMemWrite
;
1504 FileInterface
->Unicode
= Unicode
;
1506 ASSERT(FileInterface
->Buffer
== NULL
);
1507 ASSERT(FileInterface
->BufferSize
== 0);
1508 ASSERT(FileInterface
->Position
== 0);
1510 return ((EFI_FILE_PROTOCOL
*)FileInterface
);
1516 EFI_FILE_CLOSE Close
;
1517 EFI_FILE_DELETE Delete
;
1519 EFI_FILE_WRITE Write
;
1520 EFI_FILE_GET_POSITION GetPosition
;
1521 EFI_FILE_SET_POSITION SetPosition
;
1522 EFI_FILE_GET_INFO GetInfo
;
1523 EFI_FILE_SET_INFO SetInfo
;
1524 EFI_FILE_FLUSH Flush
;
1526 EFI_FILE_PROTOCOL
*Orig
;
1527 } EFI_FILE_PROTOCOL_FILE
;
1530 Set a files current position
1532 @param This Protocol instance pointer.
1533 @param Position Byte position from the start of the file.
1535 @retval EFI_SUCCESS Data was written.
1536 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1541 FileInterfaceFileSetPosition(
1542 IN EFI_FILE_PROTOCOL
*This
,
1546 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1550 Get a file's current position
1552 @param This Protocol instance pointer.
1553 @param Position Byte position from the start of the file.
1555 @retval EFI_SUCCESS Data was written.
1556 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1561 FileInterfaceFileGetPosition(
1562 IN EFI_FILE_PROTOCOL
*This
,
1563 OUT UINT64
*Position
1566 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1570 Get information about a file.
1572 @param This Protocol instance pointer.
1573 @param InformationType Type of information to return in Buffer.
1574 @param BufferSize On input size of buffer, on output amount of data in buffer.
1575 @param Buffer The buffer to return data.
1577 @retval EFI_SUCCESS Data was returned.
1578 @retval EFI_UNSUPPORT InformationType is not supported.
1579 @retval EFI_NO_MEDIA The device has no media.
1580 @retval EFI_DEVICE_ERROR The device reported an error.
1581 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1582 @retval EFI_WRITE_PROTECTED The device is write protected.
1583 @retval EFI_ACCESS_DENIED The file was open for read only.
1584 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1589 FileInterfaceFileGetInfo(
1590 IN EFI_FILE_PROTOCOL
*This
,
1591 IN EFI_GUID
*InformationType
,
1592 IN OUT UINTN
*BufferSize
,
1596 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1600 Set information about a file
1602 @param This Protocol instance pointer.
1603 @param InformationType Type of information in Buffer.
1604 @param BufferSize Size of buffer.
1605 @param Buffer The data to write.
1607 @retval EFI_SUCCESS Data was returned.
1608 @retval EFI_UNSUPPORT InformationType is not supported.
1609 @retval EFI_NO_MEDIA The device has no media.
1610 @retval EFI_DEVICE_ERROR The device reported an error.
1611 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1612 @retval EFI_WRITE_PROTECTED The device is write protected.
1613 @retval EFI_ACCESS_DENIED The file was open for read only.
1618 FileInterfaceFileSetInfo(
1619 IN EFI_FILE_PROTOCOL
*This
,
1620 IN EFI_GUID
*InformationType
,
1621 IN UINTN BufferSize
,
1625 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1629 Flush data back for the file handle.
1631 @param This Protocol instance pointer.
1633 @retval EFI_SUCCESS Data was written.
1634 @retval EFI_UNSUPPORT Writes to Open directory are not supported.
1635 @retval EFI_NO_MEDIA The device has no media.
1636 @retval EFI_DEVICE_ERROR The device reported an error.
1637 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1638 @retval EFI_WRITE_PROTECTED The device is write protected.
1639 @retval EFI_ACCESS_DENIED The file was open for read only.
1640 @retval EFI_VOLUME_FULL The volume is full.
1645 FileInterfaceFileFlush(
1646 IN EFI_FILE_PROTOCOL
*This
1649 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Flush(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1653 Read data from the file.
1655 @param This Protocol instance pointer.
1656 @param BufferSize On input size of buffer, on output amount of data in buffer.
1657 @param Buffer The buffer in which data is read.
1659 @retval EFI_SUCCESS Data was read.
1660 @retval EFI_NO_MEDIA The device has no media.
1661 @retval EFI_DEVICE_ERROR The device reported an error.
1662 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1663 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1668 FileInterfaceFileRead(
1669 IN EFI_FILE_PROTOCOL
*This
,
1670 IN OUT UINTN
*BufferSize
,
1674 CHAR8
*AsciiStrBuffer
;
1675 CHAR16
*UscStrBuffer
;
1679 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1683 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1688 Size
= (*BufferSize
) / sizeof(CHAR16
);
1689 AsciiStrBuffer
= AllocateZeroPool(Size
+ sizeof(CHAR8
));
1690 if (AsciiStrBuffer
== NULL
) {
1691 return EFI_OUT_OF_RESOURCES
;
1693 UscStrBuffer
= AllocateZeroPool(*BufferSize
+ sizeof(CHAR16
));
1694 if (UscStrBuffer
== NULL
) {
1695 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1696 return EFI_OUT_OF_RESOURCES
;
1698 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiStrBuffer
));
1699 if (!EFI_ERROR(Status
)) {
1700 CharNum
= UnicodeSPrint(UscStrBuffer
, *BufferSize
+ sizeof(CHAR16
), L
"%a", AsciiStrBuffer
);
1701 if (CharNum
== Size
) {
1702 CopyMem (Buffer
, UscStrBuffer
, *BufferSize
);
1704 Status
= EFI_UNSUPPORTED
;
1707 SHELL_FREE_NON_NULL(AsciiStrBuffer
);
1708 SHELL_FREE_NON_NULL(UscStrBuffer
);
1714 Opens a new file relative to the source file's location.
1716 @param[in] This The protocol instance pointer.
1717 @param[out] NewHandle Returns File Handle for FileName.
1718 @param[in] FileName Null terminated string. "\", ".", and ".." are supported.
1719 @param[in] OpenMode Open mode for file.
1720 @param[in] Attributes Only used for EFI_FILE_MODE_CREATE.
1722 @retval EFI_SUCCESS The device was opened.
1723 @retval EFI_NOT_FOUND The specified file could not be found on the device.
1724 @retval EFI_NO_MEDIA The device has no media.
1725 @retval EFI_MEDIA_CHANGED The media has changed.
1726 @retval EFI_DEVICE_ERROR The device reported an error.
1727 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1728 @retval EFI_ACCESS_DENIED The service denied access to the file.
1729 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
1730 @retval EFI_VOLUME_FULL The volume is full.
1734 FileInterfaceFileOpen (
1735 IN EFI_FILE_PROTOCOL
*This
,
1736 OUT EFI_FILE_PROTOCOL
**NewHandle
,
1737 IN CHAR16
*FileName
,
1739 IN UINT64 Attributes
1742 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Open(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, NewHandle
, FileName
, OpenMode
, Attributes
);
1746 Close and delete the file handle.
1748 @param This Protocol instance pointer.
1750 @retval EFI_SUCCESS The device was opened.
1751 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
1756 FileInterfaceFileDelete(
1757 IN EFI_FILE_PROTOCOL
*This
1761 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Delete(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1767 File style interface for File (Close).
1769 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1771 @retval EFI_SUCCESS The file was closed.
1775 FileInterfaceFileClose(
1776 IN EFI_FILE_PROTOCOL
*This
1780 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Close(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1786 File style interface for File (Write).
1788 If the file was opened with ASCII mode the data will be processed through
1789 AsciiSPrint before writing.
1791 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1792 @param[in, out] BufferSize Size in bytes of Buffer.
1793 @param[in] Buffer The pointer to the buffer to write.
1795 @retval EFI_SUCCESS The data was written.
1799 FileInterfaceFileWrite(
1800 IN EFI_FILE_PROTOCOL
*This
,
1801 IN OUT UINTN
*BufferSize
,
1808 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1812 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1817 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1818 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1819 Size
= AsciiStrSize(AsciiBuffer
) - 1; // (we dont need the null terminator)
1820 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1821 FreePool(AsciiBuffer
);
1827 Create a file interface with unicode information.
1829 This will create a new EFI_FILE_PROTOCOL identical to the Templace
1830 except that the new one has Unicode and Ascii knowledge.
1832 @param[in] Template A pointer to the EFI_FILE_PROTOCOL object.
1833 @param[in] Unicode TRUE for UCS-2, FALSE for ASCII.
1835 @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
1838 CreateFileInterfaceFile(
1839 IN CONST EFI_FILE_PROTOCOL
*Template
,
1840 IN CONST BOOLEAN Unicode
1843 EFI_FILE_PROTOCOL_FILE
*NewOne
;
1845 NewOne
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE
));
1846 if (NewOne
== NULL
) {
1849 CopyMem(NewOne
, Template
, sizeof(EFI_FILE_PROTOCOL_FILE
));
1850 NewOne
->Orig
= (EFI_FILE_PROTOCOL
*)Template
;
1851 NewOne
->Unicode
= Unicode
;
1852 NewOne
->Open
= FileInterfaceFileOpen
;
1853 NewOne
->Close
= FileInterfaceFileClose
;
1854 NewOne
->Delete
= FileInterfaceFileDelete
;
1855 NewOne
->Read
= FileInterfaceFileRead
;
1856 NewOne
->Write
= FileInterfaceFileWrite
;
1857 NewOne
->GetPosition
= FileInterfaceFileGetPosition
;
1858 NewOne
->SetPosition
= FileInterfaceFileSetPosition
;
1859 NewOne
->GetInfo
= FileInterfaceFileGetInfo
;
1860 NewOne
->SetInfo
= FileInterfaceFileSetInfo
;
1861 NewOne
->Flush
= FileInterfaceFileFlush
;
1863 return ((EFI_FILE_PROTOCOL
*)NewOne
);