2 EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
3 StdIn, StdOut, StdErr, etc...).
5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
6 Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
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 StrnCpy(TabStr
, Cwd
, (*BufferSize
)/sizeof(CHAR16
) - 1);
513 if (TabStr
[StrLen(TabStr
)-1] == L
'\\' && *(CurrentString
+ TabPos
) == L
'\\' ) {
514 TabStr
[StrLen(TabStr
)-1] = CHAR_NULL
;
516 StrnCat(TabStr
, CurrentString
+ TabPos
, (StringLen
- TabPos
) * sizeof (CHAR16
));
519 StrnCat(TabStr
, CurrentString
+ TabPos
, (StringLen
- TabPos
) * sizeof (CHAR16
));
522 StrnCpy(TabStr
, CurrentString
+ TabPos
, (*BufferSize
)/sizeof(CHAR16
) - 1);
524 StrnCat(TabStr
, L
"*", (*BufferSize
)/sizeof(CHAR16
) - 1 - StrLen(TabStr
));
525 FoundFileList
= NULL
;
526 Status
= ShellInfoObject
.NewEfiShellProtocol
->FindFiles(TabStr
, &FoundFileList
);
527 for ( TempStr
= CurrentString
529 ; TempStr
++); // note the ';'... empty for loop
531 // make sure we have a list before we do anything more...
533 if (EFI_ERROR (Status
) || FoundFileList
== NULL
) {
534 InTabScrolling
= FALSE
;
539 // enumerate through the list of files
541 for ( TempPos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&(FoundFileList
->Link
))
542 ; !IsNull(&FoundFileList
->Link
, &TempPos
->Link
)
543 ; TempPos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &(TempPos
->Link
))
546 // If "cd" is typed, only directory name will be auto-complete filled
547 // in either case . and .. will be removed.
549 if ((((TempStr
[0] == L
'c' || TempStr
[0] == L
'C') &&
550 (TempStr
[1] == L
'd' || TempStr
[1] == L
'D')
551 ) && ((ShellIsDirectory(TempPos
->FullName
) != EFI_SUCCESS
)
552 ||(StrCmp(TempPos
->FileName
, L
".") == 0)
553 ||(StrCmp(TempPos
->FileName
, L
"..") == 0)
554 )) || ((StrCmp(TempPos
->FileName
, L
".") == 0)
555 ||(StrCmp(TempPos
->FileName
, L
"..") == 0))){
556 TabLinePos
= TempPos
;
557 TempPos
= (EFI_SHELL_FILE_INFO
*)(RemoveEntryList(&(TempPos
->Link
))->BackLink
);
558 InternalFreeShellFileInfoNode(TabLinePos
);
561 if (FoundFileList
!= NULL
&& !IsListEmpty(&FoundFileList
->Link
)) {
562 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FoundFileList
->Link
);
563 InTabScrolling
= TRUE
;
565 FreePool(FoundFileList
);
566 FoundFileList
= NULL
;
573 if (Key
.UnicodeChar
>= ' ') {
575 // If we are at the buffer's end, drop the key
577 if (StringLen
== MaxStr
- 1 && (ShellInfoObject
.ViewingSettings
.InsertMode
|| StringCurPos
== StringLen
)) {
581 // If in insert mode, make space by moving each other character 1
582 // space higher in the array
584 if (ShellInfoObject
.ViewingSettings
.InsertMode
) {
585 CopyMem(CurrentString
+ StringCurPos
+ 1, CurrentString
+ StringCurPos
, (StringLen
- StringCurPos
)*sizeof(CurrentString
[0]));
588 CurrentString
[StringCurPos
] = Key
.UnicodeChar
;
589 Update
= StringCurPos
;
597 switch (Key
.ScanCode
) {
600 // Move characters behind current position one character forward
602 if (StringLen
!= 0) {
603 Update
= StringCurPos
;
605 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
611 // Prepare to print the previous command
613 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
614 if (IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
)) {
615 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
621 // Prepare to print the next command
623 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
624 if (NewPos
== (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
625 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
631 // Adjust current cursor position
633 if (StringCurPos
!= 0) {
635 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
641 // Adjust current cursor position
643 if (StringCurPos
< StringLen
) {
645 MoveCursorForward (TotalColumn
, TotalRow
, &Column
, &Row
);
651 // Move current cursor position to the beginning of the command line
653 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
654 Column
= StartColumn
;
660 // Move current cursor position to the end of the command line
662 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
663 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
666 StringCurPos
= StringLen
;
671 // Prepare to clear the current command line
673 CurrentString
[0] = 0;
676 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
677 Column
= StartColumn
;
683 // Toggle the SEnvInsertMode flag
685 ShellInfoObject
.ViewingSettings
.InsertMode
= (BOOLEAN
)!ShellInfoObject
.ViewingSettings
.InsertMode
;
690 // Print command history
692 PrintCommandHistory (TotalColumn
, TotalRow
, 4);
693 *CurrentString
= CHAR_NULL
;
704 // If we are in auto-complete mode, we are preparing to print
705 // the next file or directory name
707 if (InTabScrolling
) {
709 // Adjust the column and row to the start of TAB-completion string.
711 Column
= (StartColumn
+ TabUpdatePos
) % TotalColumn
;
712 Row
-= (StartColumn
+ StringCurPos
) / TotalColumn
- (StartColumn
+ TabUpdatePos
) / TotalColumn
;
713 OutputLength
= StrLen (TabLinePos
->FileName
);
715 // if the output string contains blank space, quotation marks L'\"'
716 // should be added to the output.
718 if (StrStr(TabLinePos
->FileName
, L
" ") != NULL
){
719 TabOutputStr
[0] = L
'\"';
720 CopyMem (TabOutputStr
+ 1, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
721 TabOutputStr
[OutputLength
+ 1] = L
'\"';
722 TabOutputStr
[OutputLength
+ 2] = CHAR_NULL
;
724 CopyMem (TabOutputStr
, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
725 TabOutputStr
[OutputLength
] = CHAR_NULL
;
727 OutputLength
= StrLen (TabOutputStr
) < MaxStr
- 1 ? StrLen (TabOutputStr
) : MaxStr
- 1;
728 CopyMem (CurrentString
+ TabUpdatePos
, TabOutputStr
, OutputLength
* sizeof (CHAR16
));
729 CurrentString
[TabUpdatePos
+ OutputLength
] = CHAR_NULL
;
730 StringCurPos
= TabUpdatePos
+ OutputLength
;
731 Update
= TabUpdatePos
;
732 if (StringLen
> TabUpdatePos
+ OutputLength
) {
733 Delete
= StringLen
- TabUpdatePos
- OutputLength
;
738 // If we have a new position, we are preparing to print a previous or
741 if (NewPos
!= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
742 Column
= StartColumn
;
743 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
746 NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
748 OutputLength
= StrLen (LinePos
->Buffer
) < MaxStr
- 1 ? StrLen (LinePos
->Buffer
) : MaxStr
- 1;
749 CopyMem (CurrentString
, LinePos
->Buffer
, OutputLength
* sizeof (CHAR16
));
750 CurrentString
[OutputLength
] = CHAR_NULL
;
752 StringCurPos
= OutputLength
;
755 // Draw new input string
758 if (StringLen
> OutputLength
) {
760 // If old string was longer, blank its tail
762 Delete
= StringLen
- OutputLength
;
766 // If we need to update the output do so now
768 if (Update
!= (UINTN
) -1) {
769 ShellPrintEx ((INT32
)Column
, (INT32
)Row
, L
"%s%.*s", CurrentString
+ Update
, Delete
, L
"");
770 StringLen
= StrLen (CurrentString
);
773 SetMem (CurrentString
+ StringLen
, Delete
* sizeof (CHAR16
), CHAR_NULL
);
776 if (StringCurPos
> StringLen
) {
777 StringCurPos
= StringLen
;
783 // After using print to reflect newly updates, if we're not using
784 // BACKSPACE and DELETE, we need to move the cursor position forward,
785 // so adjust row and column here.
787 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
789 // Calulate row and column of the tail of current string
791 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
+ OutputLength
) / TotalColumn
;
792 TailColumn
= (StringLen
- StringCurPos
+ Column
+ OutputLength
) % TotalColumn
;
795 // If the tail of string reaches screen end, screen rolls up, so if
796 // Row does not equal TailRow, Row should be decremented
798 // (if we are recalling commands using UPPER and DOWN key, and if the
799 // old command is too long to fit the screen, TailColumn must be 79.
801 if (TailColumn
== 0 && TailRow
>= TotalRow
&& Row
!= TailRow
) {
805 // Calculate the cursor position after current operation. If cursor
806 // reaches line end, update both row and column, otherwise, only
807 // column will be changed.
809 if (Column
+ OutputLength
>= TotalColumn
) {
810 SkipLength
= OutputLength
- (TotalColumn
- Column
);
812 Row
+= SkipLength
/ TotalColumn
+ 1;
813 if (Row
> TotalRow
- 1) {
817 Column
= SkipLength
% TotalColumn
;
819 Column
+= OutputLength
;
826 // Set the cursor position for this key
828 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, Column
, Row
);
831 if (CurrentString
!= NULL
&& StrLen(CurrentString
) > 0) {
833 // add the line to the history buffer
835 AddLineToCommandHistory(CurrentString
);
839 FreePool (TabOutputStr
);
841 // Return the data to the caller
843 *BufferSize
= StringLen
* sizeof (CHAR16
);
846 // if this was used it should be deallocated by now...
847 // prevent memory leaks...
849 ASSERT(FoundFileList
== NULL
);
855 // FILE sytle interfaces for StdIn/StdOut/StdErr
857 EFI_FILE_PROTOCOL FileInterfaceStdIn
= {
859 FileInterfaceOpenNotFound
,
860 FileInterfaceNopGeneric
,
861 FileInterfaceNopGeneric
,
862 FileInterfaceStdInRead
,
863 FileInterfaceStdInWrite
,
864 FileInterfaceNopGetPosition
,
865 FileInterfaceNopSetPosition
,
866 FileInterfaceNopGetInfo
,
867 FileInterfaceNopSetInfo
,
868 FileInterfaceNopGeneric
871 EFI_FILE_PROTOCOL FileInterfaceStdOut
= {
873 FileInterfaceOpenNotFound
,
874 FileInterfaceNopGeneric
,
875 FileInterfaceNopGeneric
,
876 FileInterfaceStdOutRead
,
877 FileInterfaceStdOutWrite
,
878 FileInterfaceNopGetPosition
,
879 FileInterfaceNopSetPosition
,
880 FileInterfaceNopGetInfo
,
881 FileInterfaceNopSetInfo
,
882 FileInterfaceNopGeneric
885 EFI_FILE_PROTOCOL FileInterfaceStdErr
= {
887 FileInterfaceOpenNotFound
,
888 FileInterfaceNopGeneric
,
889 FileInterfaceNopGeneric
,
890 FileInterfaceStdErrRead
,
891 FileInterfaceStdErrWrite
,
892 FileInterfaceNopGetPosition
,
893 FileInterfaceNopSetPosition
,
894 FileInterfaceNopGetInfo
,
895 FileInterfaceNopSetInfo
,
896 FileInterfaceNopGeneric
899 EFI_FILE_PROTOCOL FileInterfaceNulFile
= {
901 FileInterfaceOpenNotFound
,
902 FileInterfaceNopGeneric
,
903 FileInterfaceNopGeneric
,
904 FileInterfaceNulRead
,
905 FileInterfaceNulWrite
,
906 FileInterfaceNopGetPosition
,
907 FileInterfaceNopSetPosition
,
908 FileInterfaceNopGetInfo
,
909 FileInterfaceNopSetInfo
,
910 FileInterfaceNopGeneric
917 // This is identical to EFI_FILE_PROTOCOL except for the additional member
924 EFI_FILE_CLOSE Close
;
925 EFI_FILE_DELETE Delete
;
927 EFI_FILE_WRITE Write
;
928 EFI_FILE_GET_POSITION GetPosition
;
929 EFI_FILE_SET_POSITION SetPosition
;
930 EFI_FILE_GET_INFO GetInfo
;
931 EFI_FILE_SET_INFO SetInfo
;
932 EFI_FILE_FLUSH Flush
;
934 } EFI_FILE_PROTOCOL_ENVIRONMENT
;
935 //ANSI compliance helper to get size of the struct.
936 #define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)
939 File style interface for Environment Variable (Close).
941 Frees the memory for this object.
943 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
949 FileInterfaceEnvClose(
950 IN EFI_FILE_PROTOCOL
*This
958 // Most if not all UEFI commands will have an '\r\n' at the end of any output.
959 // Since the output was redirected to a variable, it does not make sense to
960 // keep this. So, before closing, strip the trailing '\r\n' from the variable
966 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
967 if (Status
== EFI_BUFFER_TOO_SMALL
) {
968 NewBuffer
= AllocateZeroPool(NewSize
+ sizeof(CHAR16
));
969 if (NewBuffer
== NULL
) {
970 return EFI_OUT_OF_RESOURCES
;
972 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
975 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
977 if (StrSize(NewBuffer
) > 6)
979 if ((((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 2] == CHAR_LINEFEED
)
980 && (((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] == CHAR_CARRIAGE_RETURN
)) {
981 ((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] = CHAR_NULL
;
984 if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
)) {
985 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
987 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
992 SHELL_FREE_NON_NULL(NewBuffer
);
993 FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
);
998 File style interface for Environment Variable (Delete).
1000 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1002 @retval The return value from FileInterfaceEnvClose().
1006 FileInterfaceEnvDelete(
1007 IN EFI_FILE_PROTOCOL
*This
1010 SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
);
1011 return (FileInterfaceEnvClose(This
));
1015 File style interface for Environment Variable (Read).
1017 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1018 @param[in, out] BufferSize Size in bytes of Buffer.
1019 @param[out] Buffer The pointer to the buffer to fill.
1021 @retval EFI_SUCCESS The data was read.
1025 FileInterfaceEnvRead(
1026 IN EFI_FILE_PROTOCOL
*This
,
1027 IN OUT UINTN
*BufferSize
,
1031 return (SHELL_GET_ENVIRONMENT_VARIABLE(
1032 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1038 File style interface for Volatile Environment Variable (Write).
1040 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1041 @param[in, out] BufferSize Size in bytes of Buffer.
1042 @param[in] Buffer The pointer to the buffer to write.
1044 @retval EFI_SUCCESS The data was read.
1048 FileInterfaceEnvVolWrite(
1049 IN EFI_FILE_PROTOCOL
*This
,
1050 IN OUT UINTN
*BufferSize
,
1061 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1062 if (Status
== EFI_BUFFER_TOO_SMALL
){
1063 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
+ sizeof(CHAR16
));
1064 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1066 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1067 while (((CHAR16
*)NewBuffer
)[NewSize
/2] == CHAR_NULL
) {
1069 // We want to overwrite the CHAR_NULL
1073 CopyMem((UINT8
*)NewBuffer
+ NewSize
+ 2, Buffer
, *BufferSize
);
1074 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1075 FreePool(NewBuffer
);
1078 SHELL_FREE_NON_NULL(NewBuffer
);
1079 return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, *BufferSize
, Buffer
));
1085 File style interface for Non Volatile Environment Variable (Write).
1087 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1088 @param[in, out] BufferSize Size in bytes of Buffer.
1089 @param[in] Buffer The pointer to the buffer to write.
1091 @retval EFI_SUCCESS The data was read.
1095 FileInterfaceEnvNonVolWrite(
1096 IN EFI_FILE_PROTOCOL
*This
,
1097 IN OUT UINTN
*BufferSize
,
1108 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1109 if (Status
== EFI_BUFFER_TOO_SMALL
){
1110 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
);
1111 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1113 if (!EFI_ERROR(Status
)) {
1114 CopyMem((UINT8
*)NewBuffer
+ NewSize
, Buffer
, *BufferSize
);
1115 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1116 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1117 NewSize
+ *BufferSize
,
1120 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1121 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1128 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1129 environment variables through file operations.
1131 @param EnvName The name of the Environment Variable to be operated on.
1133 @retval NULL Memory could not be allocated.
1134 @return other a pointer to an EFI_FILE_PROTOCOL structure
1138 CreateFileInterfaceEnv(
1139 IN CONST CHAR16
*EnvName
1142 EFI_FILE_PROTOCOL_ENVIRONMENT
*EnvFileInterface
;
1145 if (EnvName
== NULL
) {
1152 EnvNameSize
= StrSize(EnvName
);
1153 EnvFileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT
)+EnvNameSize
);
1154 if (EnvFileInterface
== NULL
){
1159 // Assign the generic members
1161 EnvFileInterface
->Revision
= EFI_FILE_REVISION
;
1162 EnvFileInterface
->Open
= FileInterfaceOpenNotFound
;
1163 EnvFileInterface
->Close
= FileInterfaceEnvClose
;
1164 EnvFileInterface
->GetPosition
= FileInterfaceNopGetPosition
;
1165 EnvFileInterface
->SetPosition
= FileInterfaceNopSetPosition
;
1166 EnvFileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1167 EnvFileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1168 EnvFileInterface
->Flush
= FileInterfaceNopGeneric
;
1169 EnvFileInterface
->Delete
= FileInterfaceEnvDelete
;
1170 EnvFileInterface
->Read
= FileInterfaceEnvRead
;
1172 CopyMem(EnvFileInterface
->Name
, EnvName
, EnvNameSize
);
1175 // Assign the different members for Volatile and Non-Volatile variables
1177 if (IsVolatileEnv(EnvName
)) {
1178 EnvFileInterface
->Write
= FileInterfaceEnvVolWrite
;
1180 EnvFileInterface
->Write
= FileInterfaceEnvNonVolWrite
;
1182 return ((EFI_FILE_PROTOCOL
*)EnvFileInterface
);
1186 Move the cursor position one character backward.
1188 @param[in] LineLength Length of a line. Get it by calling QueryMode
1189 @param[in, out] Column Current column of the cursor position
1190 @param[in, out] Row Current row of the cursor position
1194 MoveCursorBackward (
1195 IN UINTN LineLength
,
1196 IN OUT UINTN
*Column
,
1201 // If current column is 0, move to the last column of the previous line,
1202 // otherwise, just decrement column.
1205 *Column
= LineLength
- 1;
1215 Move the cursor position one character forward.
1217 @param[in] LineLength Length of a line.
1218 @param[in] TotalRow Total row of a screen
1219 @param[in, out] Column Current column of the cursor position
1220 @param[in, out] Row Current row of the cursor position
1225 IN UINTN LineLength
,
1227 IN OUT UINTN
*Column
,
1232 // Increment Column.
1233 // If this puts column past the end of the line, move to first column
1237 if (*Column
>= LineLength
) {
1239 if ((*Row
) < TotalRow
- 1) {
1246 Prints out each previously typed command in the command list history log.
1248 When each screen is full it will pause for a key before continuing.
1250 @param[in] TotalCols How many columns are on the screen
1251 @param[in] TotalRows How many rows are on the screen
1252 @param[in] StartColumn which column to start at
1256 PrintCommandHistory (
1257 IN CONST UINTN TotalCols
,
1258 IN CONST UINTN TotalRows
,
1259 IN CONST UINTN StartColumn
1267 ShellPrintEx (-1, -1, L
"\n");
1271 // go through history list...
1273 for ( Node
= (BUFFER_LIST
*)GetFirstNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
)
1274 ; !IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1275 ; Node
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1278 LineCount
= ((StrLen (Node
->Buffer
) + StartColumn
+ 1) / TotalCols
) + 1;
1280 if (LineNumber
+ LineCount
>= TotalRows
) {
1281 ShellPromptForResponseHii(
1282 ShellPromptResponseTypeEnterContinue
,
1283 STRING_TOKEN (STR_SHELL_ENTER_TO_CONT
),
1284 ShellInfoObject
.HiiHandle
,
1289 ShellPrintEx (-1, -1, L
"%2d. %s\n", Index
, Node
->Buffer
);
1290 LineNumber
+= LineCount
;
1300 // This is identical to EFI_FILE_PROTOCOL except for the additional members
1301 // for the buffer, size, and position.
1307 EFI_FILE_CLOSE Close
;
1308 EFI_FILE_DELETE Delete
;
1310 EFI_FILE_WRITE Write
;
1311 EFI_FILE_GET_POSITION GetPosition
;
1312 EFI_FILE_SET_POSITION SetPosition
;
1313 EFI_FILE_GET_INFO GetInfo
;
1314 EFI_FILE_SET_INFO SetInfo
;
1315 EFI_FILE_FLUSH Flush
;
1320 } EFI_FILE_PROTOCOL_MEM
;
1323 File style interface for Mem (SetPosition).
1325 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1326 @param[out] Position The position to set.
1328 @retval EFI_SUCCESS The position was successfully changed.
1329 @retval EFI_INVALID_PARAMETER The Position was invalid.
1333 FileInterfaceMemSetPosition(
1334 IN EFI_FILE_PROTOCOL
*This
,
1338 if (Position
<= ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) {
1339 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= Position
;
1340 return (EFI_SUCCESS
);
1342 return (EFI_INVALID_PARAMETER
);
1347 File style interface for Mem (GetPosition).
1349 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1350 @param[out] Position The pointer to the position.
1352 @retval EFI_SUCCESS The position was retrieved.
1356 FileInterfaceMemGetPosition(
1357 IN EFI_FILE_PROTOCOL
*This
,
1358 OUT UINT64
*Position
1361 *Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
;
1362 return (EFI_SUCCESS
);
1366 File style interface for Mem (Write).
1368 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1369 @param[in, out] BufferSize Size in bytes of Buffer.
1370 @param[in] Buffer The pointer to the buffer to write.
1372 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
1373 @retval EFI_SUCCESS The data was written.
1377 FileInterfaceMemWrite(
1378 IN EFI_FILE_PROTOCOL
*This
,
1379 IN OUT UINTN
*BufferSize
,
1384 if (((EFI_FILE_PROTOCOL_MEM
*)This
)->Unicode
) {
1388 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1389 ((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
);
1390 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= (*BufferSize
) + 10;
1392 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, Buffer
, *BufferSize
);
1393 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= (*BufferSize
);
1394 return (EFI_SUCCESS
);
1399 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1400 if (AsciiBuffer
== NULL
) {
1401 return (EFI_OUT_OF_RESOURCES
);
1403 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1404 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ AsciiStrSize(AsciiBuffer
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1405 ((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
);
1406 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= AsciiStrSize(AsciiBuffer
) + 10;
1408 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, AsciiBuffer
, AsciiStrSize(AsciiBuffer
));
1409 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= AsciiStrSize(AsciiBuffer
);
1410 FreePool(AsciiBuffer
);
1411 return (EFI_SUCCESS
);
1416 File style interface for Mem (Read).
1418 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1419 @param[in, out] BufferSize Size in bytes of Buffer.
1420 @param[in] Buffer The pointer to the buffer to fill.
1422 @retval EFI_SUCCESS The data was read.
1426 FileInterfaceMemRead(
1427 IN EFI_FILE_PROTOCOL
*This
,
1428 IN OUT UINTN
*BufferSize
,
1432 if (*BufferSize
> (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
))) {
1433 (*BufferSize
) = (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
));
1435 CopyMem(Buffer
, ((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, (*BufferSize
));
1436 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
);
1437 return (EFI_SUCCESS
);
1441 File style interface for Mem (Close).
1443 Frees all memory associated with this object.
1445 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1447 @retval EFI_SUCCESS The 'file' was closed.
1451 FileInterfaceMemClose(
1452 IN EFI_FILE_PROTOCOL
*This
1455 SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1456 SHELL_FREE_NON_NULL(This
);
1457 return (EFI_SUCCESS
);
1461 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1462 a file entirely in memory through file operations.
1464 @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.
1466 @retval NULL Memory could not be allocated.
1467 @return other A pointer to an EFI_FILE_PROTOCOL structure.
1471 CreateFileInterfaceMem(
1472 IN CONST BOOLEAN Unicode
1475 EFI_FILE_PROTOCOL_MEM
*FileInterface
;
1480 FileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM
));
1481 if (FileInterface
== NULL
){
1486 // Assign the generic members
1488 FileInterface
->Revision
= EFI_FILE_REVISION
;
1489 FileInterface
->Open
= FileInterfaceOpenNotFound
;
1490 FileInterface
->Close
= FileInterfaceMemClose
;
1491 FileInterface
->GetPosition
= FileInterfaceMemGetPosition
;
1492 FileInterface
->SetPosition
= FileInterfaceMemSetPosition
;
1493 FileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1494 FileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1495 FileInterface
->Flush
= FileInterfaceNopGeneric
;
1496 FileInterface
->Delete
= FileInterfaceNopGeneric
;
1497 FileInterface
->Read
= FileInterfaceMemRead
;
1498 FileInterface
->Write
= FileInterfaceMemWrite
;
1499 FileInterface
->Unicode
= Unicode
;
1501 ASSERT(FileInterface
->Buffer
== NULL
);
1502 ASSERT(FileInterface
->BufferSize
== 0);
1503 ASSERT(FileInterface
->Position
== 0);
1505 return ((EFI_FILE_PROTOCOL
*)FileInterface
);
1511 EFI_FILE_CLOSE Close
;
1512 EFI_FILE_DELETE Delete
;
1514 EFI_FILE_WRITE Write
;
1515 EFI_FILE_GET_POSITION GetPosition
;
1516 EFI_FILE_SET_POSITION SetPosition
;
1517 EFI_FILE_GET_INFO GetInfo
;
1518 EFI_FILE_SET_INFO SetInfo
;
1519 EFI_FILE_FLUSH Flush
;
1521 EFI_FILE_PROTOCOL
*Orig
;
1522 } EFI_FILE_PROTOCOL_FILE
;
1525 Set a files current position
1527 @param This Protocol instance pointer.
1528 @param Position Byte position from the start of the file.
1530 @retval EFI_SUCCESS Data was written.
1531 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1536 FileInterfaceFileSetPosition(
1537 IN EFI_FILE_PROTOCOL
*This
,
1541 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1545 Get a file's current position
1547 @param This Protocol instance pointer.
1548 @param Position Byte position from the start of the file.
1550 @retval EFI_SUCCESS Data was written.
1551 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1556 FileInterfaceFileGetPosition(
1557 IN EFI_FILE_PROTOCOL
*This
,
1558 OUT UINT64
*Position
1561 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1565 Get information about a file.
1567 @param This Protocol instance pointer.
1568 @param InformationType Type of information to return in Buffer.
1569 @param BufferSize On input size of buffer, on output amount of data in buffer.
1570 @param Buffer The buffer to return data.
1572 @retval EFI_SUCCESS Data was returned.
1573 @retval EFI_UNSUPPORT InformationType is not supported.
1574 @retval EFI_NO_MEDIA The device has no media.
1575 @retval EFI_DEVICE_ERROR The device reported an error.
1576 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1577 @retval EFI_WRITE_PROTECTED The device is write protected.
1578 @retval EFI_ACCESS_DENIED The file was open for read only.
1579 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1584 FileInterfaceFileGetInfo(
1585 IN EFI_FILE_PROTOCOL
*This
,
1586 IN EFI_GUID
*InformationType
,
1587 IN OUT UINTN
*BufferSize
,
1591 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1595 Set information about a file
1597 @param This Protocol instance pointer.
1598 @param InformationType Type of information in Buffer.
1599 @param BufferSize Size of buffer.
1600 @param Buffer The data to write.
1602 @retval EFI_SUCCESS Data was returned.
1603 @retval EFI_UNSUPPORT InformationType is not supported.
1604 @retval EFI_NO_MEDIA The device has no media.
1605 @retval EFI_DEVICE_ERROR The device reported an error.
1606 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1607 @retval EFI_WRITE_PROTECTED The device is write protected.
1608 @retval EFI_ACCESS_DENIED The file was open for read only.
1613 FileInterfaceFileSetInfo(
1614 IN EFI_FILE_PROTOCOL
*This
,
1615 IN EFI_GUID
*InformationType
,
1616 IN UINTN BufferSize
,
1620 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1624 Flush data back for the file handle.
1626 @param This Protocol instance pointer.
1628 @retval EFI_SUCCESS Data was written.
1629 @retval EFI_UNSUPPORT Writes to Open directory are not supported.
1630 @retval EFI_NO_MEDIA The device has no media.
1631 @retval EFI_DEVICE_ERROR The device reported an error.
1632 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1633 @retval EFI_WRITE_PROTECTED The device is write protected.
1634 @retval EFI_ACCESS_DENIED The file was open for read only.
1635 @retval EFI_VOLUME_FULL The volume is full.
1640 FileInterfaceFileFlush(
1641 IN EFI_FILE_PROTOCOL
*This
1644 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Flush(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1648 Read data from the file.
1650 @param This Protocol instance pointer.
1651 @param BufferSize On input size of buffer, on output amount of data in buffer.
1652 @param Buffer The buffer in which data is read.
1654 @retval EFI_SUCCESS Data was read.
1655 @retval EFI_NO_MEDIA The device has no media.
1656 @retval EFI_DEVICE_ERROR The device reported an error.
1657 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1658 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1663 FileInterfaceFileRead(
1664 IN EFI_FILE_PROTOCOL
*This
,
1665 IN OUT UINTN
*BufferSize
,
1672 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1676 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1681 AsciiBuffer
= AllocateZeroPool((Size
= *BufferSize
));
1682 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1683 UnicodeSPrint(Buffer
, *BufferSize
, L
"%a", AsciiBuffer
);
1684 FreePool(AsciiBuffer
);
1690 Opens a new file relative to the source file's location.
1692 @param[in] This The protocol instance pointer.
1693 @param[out] NewHandle Returns File Handle for FileName.
1694 @param[in] FileName Null terminated string. "\", ".", and ".." are supported.
1695 @param[in] OpenMode Open mode for file.
1696 @param[in] Attributes Only used for EFI_FILE_MODE_CREATE.
1698 @retval EFI_SUCCESS The device was opened.
1699 @retval EFI_NOT_FOUND The specified file could not be found on the device.
1700 @retval EFI_NO_MEDIA The device has no media.
1701 @retval EFI_MEDIA_CHANGED The media has changed.
1702 @retval EFI_DEVICE_ERROR The device reported an error.
1703 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1704 @retval EFI_ACCESS_DENIED The service denied access to the file.
1705 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
1706 @retval EFI_VOLUME_FULL The volume is full.
1710 FileInterfaceFileOpen (
1711 IN EFI_FILE_PROTOCOL
*This
,
1712 OUT EFI_FILE_PROTOCOL
**NewHandle
,
1713 IN CHAR16
*FileName
,
1715 IN UINT64 Attributes
1718 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Open(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, NewHandle
, FileName
, OpenMode
, Attributes
);
1722 Close and delete the file handle.
1724 @param This Protocol instance pointer.
1726 @retval EFI_SUCCESS The device was opened.
1727 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
1732 FileInterfaceFileDelete(
1733 IN EFI_FILE_PROTOCOL
*This
1737 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Delete(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1743 File style interface for File (Close).
1745 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1747 @retval EFI_SUCCESS The file was closed.
1751 FileInterfaceFileClose(
1752 IN EFI_FILE_PROTOCOL
*This
1756 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Close(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1762 File style interface for File (Write).
1764 If the file was opened with ASCII mode the data will be processed through
1765 AsciiSPrint before writing.
1767 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1768 @param[in, out] BufferSize Size in bytes of Buffer.
1769 @param[in] Buffer The pointer to the buffer to write.
1771 @retval EFI_SUCCESS The data was written.
1775 FileInterfaceFileWrite(
1776 IN EFI_FILE_PROTOCOL
*This
,
1777 IN OUT UINTN
*BufferSize
,
1784 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1788 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1793 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1794 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1795 Size
= AsciiStrSize(AsciiBuffer
) - 1; // (we dont need the null terminator)
1796 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1797 FreePool(AsciiBuffer
);
1803 Create a file interface with unicode information.
1805 This will create a new EFI_FILE_PROTOCOL identical to the Templace
1806 except that the new one has Unicode and Ascii knowledge.
1808 @param[in] Template A pointer to the EFI_FILE_PROTOCOL object.
1809 @param[in] Unicode TRUE for UCS-2, FALSE for ASCII.
1811 @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
1814 CreateFileInterfaceFile(
1815 IN CONST EFI_FILE_PROTOCOL
*Template
,
1816 IN CONST BOOLEAN Unicode
1819 EFI_FILE_PROTOCOL_FILE
*NewOne
;
1821 NewOne
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE
));
1822 if (NewOne
== NULL
) {
1825 CopyMem(NewOne
, Template
, sizeof(EFI_FILE_PROTOCOL_FILE
));
1826 NewOne
->Orig
= (EFI_FILE_PROTOCOL
*)Template
;
1827 NewOne
->Unicode
= Unicode
;
1828 NewOne
->Open
= FileInterfaceFileOpen
;
1829 NewOne
->Close
= FileInterfaceFileClose
;
1830 NewOne
->Delete
= FileInterfaceFileDelete
;
1831 NewOne
->Read
= FileInterfaceFileRead
;
1832 NewOne
->Write
= FileInterfaceFileWrite
;
1833 NewOne
->GetPosition
= FileInterfaceFileGetPosition
;
1834 NewOne
->SetPosition
= FileInterfaceFileSetPosition
;
1835 NewOne
->GetInfo
= FileInterfaceFileGetInfo
;
1836 NewOne
->SetInfo
= FileInterfaceFileSetInfo
;
1837 NewOne
->Flush
= FileInterfaceFileFlush
;
1839 return ((EFI_FILE_PROTOCOL
*)NewOne
);