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
);
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 StrCpy(TabStr
, CurrentString
+ TabPos
);
524 StrCat(TabStr
, L
"*");
525 FoundFileList
= NULL
;
526 // TabStr = PathCleanUpDirectories(TabStr);
527 Status
= ShellInfoObject
.NewEfiShellProtocol
->FindFiles(TabStr
, &FoundFileList
);
528 for ( TempStr
= CurrentString
530 ; TempStr
++); // note the ';'... empty for loop
532 // make sure we have a list before we do anything more...
534 if (EFI_ERROR (Status
) || FoundFileList
== NULL
) {
535 InTabScrolling
= FALSE
;
540 // enumerate through the list of files
542 for ( TempPos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&(FoundFileList
->Link
))
543 ; !IsNull(&FoundFileList
->Link
, &TempPos
->Link
)
544 ; TempPos
= (EFI_SHELL_FILE_INFO
*)GetNextNode(&(FoundFileList
->Link
), &(TempPos
->Link
))
547 // If "cd" is typed, only directory name will be auto-complete filled
548 // in either case . and .. will be removed.
550 if ((((TempStr
[0] == L
'c' || TempStr
[0] == L
'C') &&
551 (TempStr
[1] == L
'd' || TempStr
[1] == L
'D')
552 ) && ((ShellIsDirectory(TempPos
->FullName
) != EFI_SUCCESS
)
553 ||(StrCmp(TempPos
->FileName
, L
".") == 0)
554 ||(StrCmp(TempPos
->FileName
, L
"..") == 0)
555 )) || ((StrCmp(TempPos
->FileName
, L
".") == 0)
556 ||(StrCmp(TempPos
->FileName
, L
"..") == 0))){
557 TabLinePos
= TempPos
;
558 TempPos
= (EFI_SHELL_FILE_INFO
*)(RemoveEntryList(&(TempPos
->Link
))->BackLink
);
559 InternalFreeShellFileInfoNode(TabLinePos
);
562 if (FoundFileList
!= NULL
&& !IsListEmpty(&FoundFileList
->Link
)) {
563 TabLinePos
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FoundFileList
->Link
);
564 InTabScrolling
= TRUE
;
566 FreePool(FoundFileList
);
567 FoundFileList
= NULL
;
574 if (Key
.UnicodeChar
>= ' ') {
576 // If we are at the buffer's end, drop the key
578 if (StringLen
== MaxStr
- 1 && (ShellInfoObject
.ViewingSettings
.InsertMode
|| StringCurPos
== StringLen
)) {
582 // If in insert mode, make space by moving each other character 1
583 // space higher in the array
585 if (ShellInfoObject
.ViewingSettings
.InsertMode
) {
586 CopyMem(CurrentString
+ StringCurPos
+ 1, CurrentString
+ StringCurPos
, (StringLen
- StringCurPos
)*sizeof(CurrentString
[0]));
589 CurrentString
[StringCurPos
] = Key
.UnicodeChar
;
590 Update
= StringCurPos
;
598 switch (Key
.ScanCode
) {
601 // Move characters behind current position one character forward
603 if (StringLen
!= 0) {
604 Update
= StringCurPos
;
606 CopyMem (CurrentString
+ StringCurPos
, CurrentString
+ StringCurPos
+ 1, sizeof (CHAR16
) * (StringLen
- StringCurPos
));
612 // Prepare to print the previous command
614 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
615 if (IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
)) {
616 NewPos
= (BUFFER_LIST
*)GetPreviousNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
622 // Prepare to print the next command
624 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
625 if (NewPos
== (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
626 NewPos
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &LinePos
->Link
);
632 // Adjust current cursor position
634 if (StringCurPos
!= 0) {
636 MoveCursorBackward (TotalColumn
, &Column
, &Row
);
642 // Adjust current cursor position
644 if (StringCurPos
< StringLen
) {
646 MoveCursorForward (TotalColumn
, TotalRow
, &Column
, &Row
);
652 // Move current cursor position to the beginning of the command line
654 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
655 Column
= StartColumn
;
661 // Move current cursor position to the end of the command line
663 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
) / TotalColumn
;
664 TailColumn
= (StringLen
- StringCurPos
+ Column
) % TotalColumn
;
667 StringCurPos
= StringLen
;
672 // Prepare to clear the current command line
674 CurrentString
[0] = 0;
677 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
678 Column
= StartColumn
;
684 // Toggle the SEnvInsertMode flag
686 ShellInfoObject
.ViewingSettings
.InsertMode
= (BOOLEAN
)!ShellInfoObject
.ViewingSettings
.InsertMode
;
691 // Print command history
693 PrintCommandHistory (TotalColumn
, TotalRow
, 4);
694 *CurrentString
= CHAR_NULL
;
705 // If we are in auto-complete mode, we are preparing to print
706 // the next file or directory name
708 if (InTabScrolling
) {
710 // Adjust the column and row to the start of TAB-completion string.
712 Column
= (StartColumn
+ TabUpdatePos
) % TotalColumn
;
713 Row
-= (StartColumn
+ StringCurPos
) / TotalColumn
- (StartColumn
+ TabUpdatePos
) / TotalColumn
;
714 OutputLength
= StrLen (TabLinePos
->FileName
);
716 // if the output string contains blank space, quotation marks L'\"'
717 // should be added to the output.
719 if (StrStr(TabLinePos
->FileName
, L
" ") != NULL
){
720 TabOutputStr
[0] = L
'\"';
721 CopyMem (TabOutputStr
+ 1, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
722 TabOutputStr
[OutputLength
+ 1] = L
'\"';
723 TabOutputStr
[OutputLength
+ 2] = CHAR_NULL
;
725 CopyMem (TabOutputStr
, TabLinePos
->FileName
, OutputLength
* sizeof (CHAR16
));
726 TabOutputStr
[OutputLength
] = CHAR_NULL
;
728 OutputLength
= StrLen (TabOutputStr
) < MaxStr
- 1 ? StrLen (TabOutputStr
) : MaxStr
- 1;
729 CopyMem (CurrentString
+ TabUpdatePos
, TabOutputStr
, OutputLength
* sizeof (CHAR16
));
730 CurrentString
[TabUpdatePos
+ OutputLength
] = CHAR_NULL
;
731 StringCurPos
= TabUpdatePos
+ OutputLength
;
732 Update
= TabUpdatePos
;
733 if (StringLen
> TabUpdatePos
+ OutputLength
) {
734 Delete
= StringLen
- TabUpdatePos
- OutputLength
;
739 // If we have a new position, we are preparing to print a previous or
742 if (NewPos
!= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
)) {
743 Column
= StartColumn
;
744 Row
-= (StringCurPos
+ StartColumn
) / TotalColumn
;
747 NewPos
= (BUFFER_LIST
*)(&ShellInfoObject
.ViewingSettings
.CommandHistory
);
749 OutputLength
= StrLen (LinePos
->Buffer
) < MaxStr
- 1 ? StrLen (LinePos
->Buffer
) : MaxStr
- 1;
750 CopyMem (CurrentString
, LinePos
->Buffer
, OutputLength
* sizeof (CHAR16
));
751 CurrentString
[OutputLength
] = CHAR_NULL
;
753 StringCurPos
= OutputLength
;
756 // Draw new input string
759 if (StringLen
> OutputLength
) {
761 // If old string was longer, blank its tail
763 Delete
= StringLen
- OutputLength
;
767 // If we need to update the output do so now
769 if (Update
!= (UINTN
) -1) {
770 ShellPrintEx ((INT32
)Column
, (INT32
)Row
, L
"%s%.*s", CurrentString
+ Update
, Delete
, L
"");
771 StringLen
= StrLen (CurrentString
);
774 SetMem (CurrentString
+ StringLen
, Delete
* sizeof (CHAR16
), CHAR_NULL
);
777 if (StringCurPos
> StringLen
) {
778 StringCurPos
= StringLen
;
784 // After using print to reflect newly updates, if we're not using
785 // BACKSPACE and DELETE, we need to move the cursor position forward,
786 // so adjust row and column here.
788 if (Key
.UnicodeChar
!= CHAR_BACKSPACE
&& !(Key
.UnicodeChar
== 0 && Key
.ScanCode
== SCAN_DELETE
)) {
790 // Calulate row and column of the tail of current string
792 TailRow
= Row
+ (StringLen
- StringCurPos
+ Column
+ OutputLength
) / TotalColumn
;
793 TailColumn
= (StringLen
- StringCurPos
+ Column
+ OutputLength
) % TotalColumn
;
796 // If the tail of string reaches screen end, screen rolls up, so if
797 // Row does not equal TailRow, Row should be decremented
799 // (if we are recalling commands using UPPER and DOWN key, and if the
800 // old command is too long to fit the screen, TailColumn must be 79.
802 if (TailColumn
== 0 && TailRow
>= TotalRow
&& Row
!= TailRow
) {
806 // Calculate the cursor position after current operation. If cursor
807 // reaches line end, update both row and column, otherwise, only
808 // column will be changed.
810 if (Column
+ OutputLength
>= TotalColumn
) {
811 SkipLength
= OutputLength
- (TotalColumn
- Column
);
813 Row
+= SkipLength
/ TotalColumn
+ 1;
814 if (Row
> TotalRow
- 1) {
818 Column
= SkipLength
% TotalColumn
;
820 Column
+= OutputLength
;
827 // Set the cursor position for this key
829 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, Column
, Row
);
832 if (CurrentString
!= NULL
&& StrLen(CurrentString
) > 0) {
834 // add the line to the history buffer
836 AddLineToCommandHistory(CurrentString
);
840 FreePool (TabOutputStr
);
842 // Return the data to the caller
844 *BufferSize
= StringLen
* sizeof (CHAR16
);
847 // if this was used it should be deallocated by now...
848 // prevent memory leaks...
850 ASSERT(FoundFileList
== NULL
);
856 // FILE sytle interfaces for StdIn/StdOut/StdErr
858 EFI_FILE_PROTOCOL FileInterfaceStdIn
= {
860 FileInterfaceOpenNotFound
,
861 FileInterfaceNopGeneric
,
862 FileInterfaceNopGeneric
,
863 FileInterfaceStdInRead
,
864 FileInterfaceStdInWrite
,
865 FileInterfaceNopGetPosition
,
866 FileInterfaceNopSetPosition
,
867 FileInterfaceNopGetInfo
,
868 FileInterfaceNopSetInfo
,
869 FileInterfaceNopGeneric
872 EFI_FILE_PROTOCOL FileInterfaceStdOut
= {
874 FileInterfaceOpenNotFound
,
875 FileInterfaceNopGeneric
,
876 FileInterfaceNopGeneric
,
877 FileInterfaceStdOutRead
,
878 FileInterfaceStdOutWrite
,
879 FileInterfaceNopGetPosition
,
880 FileInterfaceNopSetPosition
,
881 FileInterfaceNopGetInfo
,
882 FileInterfaceNopSetInfo
,
883 FileInterfaceNopGeneric
886 EFI_FILE_PROTOCOL FileInterfaceStdErr
= {
888 FileInterfaceOpenNotFound
,
889 FileInterfaceNopGeneric
,
890 FileInterfaceNopGeneric
,
891 FileInterfaceStdErrRead
,
892 FileInterfaceStdErrWrite
,
893 FileInterfaceNopGetPosition
,
894 FileInterfaceNopSetPosition
,
895 FileInterfaceNopGetInfo
,
896 FileInterfaceNopSetInfo
,
897 FileInterfaceNopGeneric
900 EFI_FILE_PROTOCOL FileInterfaceNulFile
= {
902 FileInterfaceOpenNotFound
,
903 FileInterfaceNopGeneric
,
904 FileInterfaceNopGeneric
,
905 FileInterfaceNulRead
,
906 FileInterfaceNulWrite
,
907 FileInterfaceNopGetPosition
,
908 FileInterfaceNopSetPosition
,
909 FileInterfaceNopGetInfo
,
910 FileInterfaceNopSetInfo
,
911 FileInterfaceNopGeneric
918 // This is identical to EFI_FILE_PROTOCOL except for the additional member
925 EFI_FILE_CLOSE Close
;
926 EFI_FILE_DELETE Delete
;
928 EFI_FILE_WRITE Write
;
929 EFI_FILE_GET_POSITION GetPosition
;
930 EFI_FILE_SET_POSITION SetPosition
;
931 EFI_FILE_GET_INFO GetInfo
;
932 EFI_FILE_SET_INFO SetInfo
;
933 EFI_FILE_FLUSH Flush
;
935 } EFI_FILE_PROTOCOL_ENVIRONMENT
;
936 //ANSI compliance helper to get size of the struct.
937 #define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)
940 File style interface for Environment Variable (Close).
942 Frees the memory for this object.
944 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
950 FileInterfaceEnvClose(
951 IN EFI_FILE_PROTOCOL
*This
959 // Most if not all UEFI commands will have an '\r\n' at the end of any output.
960 // Since the output was redirected to a variable, it does not make sense to
961 // keep this. So, before closing, strip the trailing '\r\n' from the variable
967 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
968 if (Status
== EFI_BUFFER_TOO_SMALL
) {
969 NewBuffer
= AllocateZeroPool(NewSize
+ sizeof(CHAR16
));
970 if (NewBuffer
== NULL
) {
971 return EFI_OUT_OF_RESOURCES
;
973 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
976 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
978 if (StrSize(NewBuffer
) > 6)
980 if ((((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 2] == CHAR_LINEFEED
)
981 && (((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] == CHAR_CARRIAGE_RETURN
)) {
982 ((CHAR16
*)NewBuffer
)[(StrSize(NewBuffer
)/2) - 3] = CHAR_NULL
;
985 if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
)) {
986 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
988 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
993 SHELL_FREE_NON_NULL(NewBuffer
);
994 FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
);
999 File style interface for Environment Variable (Delete).
1001 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1003 @retval The return value from FileInterfaceEnvClose().
1007 FileInterfaceEnvDelete(
1008 IN EFI_FILE_PROTOCOL
*This
1011 SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
);
1012 return (FileInterfaceEnvClose(This
));
1016 File style interface for Environment Variable (Read).
1018 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1019 @param[in, out] BufferSize Size in bytes of Buffer.
1020 @param[out] Buffer The pointer to the buffer to fill.
1022 @retval EFI_SUCCESS The data was read.
1026 FileInterfaceEnvRead(
1027 IN EFI_FILE_PROTOCOL
*This
,
1028 IN OUT UINTN
*BufferSize
,
1032 return (SHELL_GET_ENVIRONMENT_VARIABLE(
1033 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1039 File style interface for Volatile Environment Variable (Write).
1041 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1042 @param[in, out] BufferSize Size in bytes of Buffer.
1043 @param[in] Buffer The pointer to the buffer to write.
1045 @retval EFI_SUCCESS The data was read.
1049 FileInterfaceEnvVolWrite(
1050 IN EFI_FILE_PROTOCOL
*This
,
1051 IN OUT UINTN
*BufferSize
,
1062 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1063 if (Status
== EFI_BUFFER_TOO_SMALL
){
1064 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
+ sizeof(CHAR16
));
1065 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1067 if (!EFI_ERROR(Status
) && NewBuffer
!= NULL
) {
1068 while (((CHAR16
*)NewBuffer
)[NewSize
/2] == CHAR_NULL
) {
1070 // We want to overwrite the CHAR_NULL
1074 CopyMem((UINT8
*)NewBuffer
+ NewSize
+ 2, Buffer
, *BufferSize
);
1075 Status
= SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, StrSize(NewBuffer
), NewBuffer
);
1076 FreePool(NewBuffer
);
1079 SHELL_FREE_NON_NULL(NewBuffer
);
1080 return (SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, *BufferSize
, Buffer
));
1086 File style interface for Non Volatile Environment Variable (Write).
1088 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1089 @param[in, out] BufferSize Size in bytes of Buffer.
1090 @param[in] Buffer The pointer to the buffer to write.
1092 @retval EFI_SUCCESS The data was read.
1096 FileInterfaceEnvNonVolWrite(
1097 IN EFI_FILE_PROTOCOL
*This
,
1098 IN OUT UINTN
*BufferSize
,
1109 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1110 if (Status
== EFI_BUFFER_TOO_SMALL
){
1111 NewBuffer
= AllocateZeroPool(NewSize
+ *BufferSize
);
1112 Status
= SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
, &NewSize
, NewBuffer
);
1114 if (!EFI_ERROR(Status
)) {
1115 CopyMem((UINT8
*)NewBuffer
+ NewSize
, Buffer
, *BufferSize
);
1116 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1117 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1118 NewSize
+ *BufferSize
,
1121 return (SHELL_SET_ENVIRONMENT_VARIABLE_NV(
1122 ((EFI_FILE_PROTOCOL_ENVIRONMENT
*)This
)->Name
,
1129 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1130 environment variables through file operations.
1132 @param EnvName The name of the Environment Variable to be operated on.
1134 @retval NULL Memory could not be allocated.
1135 @return other a pointer to an EFI_FILE_PROTOCOL structure
1139 CreateFileInterfaceEnv(
1140 IN CONST CHAR16
*EnvName
1143 EFI_FILE_PROTOCOL_ENVIRONMENT
*EnvFileInterface
;
1145 if (EnvName
== NULL
) {
1152 EnvFileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT
)+StrSize(EnvName
));
1153 if (EnvFileInterface
== NULL
){
1158 // Assign the generic members
1160 EnvFileInterface
->Revision
= EFI_FILE_REVISION
;
1161 EnvFileInterface
->Open
= FileInterfaceOpenNotFound
;
1162 EnvFileInterface
->Close
= FileInterfaceEnvClose
;
1163 EnvFileInterface
->GetPosition
= FileInterfaceNopGetPosition
;
1164 EnvFileInterface
->SetPosition
= FileInterfaceNopSetPosition
;
1165 EnvFileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1166 EnvFileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1167 EnvFileInterface
->Flush
= FileInterfaceNopGeneric
;
1168 EnvFileInterface
->Delete
= FileInterfaceEnvDelete
;
1169 EnvFileInterface
->Read
= FileInterfaceEnvRead
;
1171 StrCpy(EnvFileInterface
->Name
, EnvName
);
1174 // Assign the different members for Volatile and Non-Volatile variables
1176 if (IsVolatileEnv(EnvName
)) {
1177 EnvFileInterface
->Write
= FileInterfaceEnvVolWrite
;
1179 EnvFileInterface
->Write
= FileInterfaceEnvNonVolWrite
;
1181 return ((EFI_FILE_PROTOCOL
*)EnvFileInterface
);
1185 Move the cursor position one character backward.
1187 @param[in] LineLength Length of a line. Get it by calling QueryMode
1188 @param[in, out] Column Current column of the cursor position
1189 @param[in, out] Row Current row of the cursor position
1193 MoveCursorBackward (
1194 IN UINTN LineLength
,
1195 IN OUT UINTN
*Column
,
1200 // If current column is 0, move to the last column of the previous line,
1201 // otherwise, just decrement column.
1204 *Column
= LineLength
- 1;
1214 Move the cursor position one character forward.
1216 @param[in] LineLength Length of a line.
1217 @param[in] TotalRow Total row of a screen
1218 @param[in, out] Column Current column of the cursor position
1219 @param[in, out] Row Current row of the cursor position
1224 IN UINTN LineLength
,
1226 IN OUT UINTN
*Column
,
1231 // Increment Column.
1232 // If this puts column past the end of the line, move to first column
1236 if (*Column
>= LineLength
) {
1238 if ((*Row
) < TotalRow
- 1) {
1245 Prints out each previously typed command in the command list history log.
1247 When each screen is full it will pause for a key before continuing.
1249 @param[in] TotalCols How many columns are on the screen
1250 @param[in] TotalRows How many rows are on the screen
1251 @param[in] StartColumn which column to start at
1255 PrintCommandHistory (
1256 IN CONST UINTN TotalCols
,
1257 IN CONST UINTN TotalRows
,
1258 IN CONST UINTN StartColumn
1266 ShellPrintEx (-1, -1, L
"\n");
1270 // go through history list...
1272 for ( Node
= (BUFFER_LIST
*)GetFirstNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
)
1273 ; !IsNull(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1274 ; Node
= (BUFFER_LIST
*)GetNextNode(&ShellInfoObject
.ViewingSettings
.CommandHistory
.Link
, &Node
->Link
)
1277 LineCount
= ((StrLen (Node
->Buffer
) + StartColumn
+ 1) / TotalCols
) + 1;
1279 if (LineNumber
+ LineCount
>= TotalRows
) {
1280 ShellPromptForResponseHii(
1281 ShellPromptResponseTypeEnterContinue
,
1282 STRING_TOKEN (STR_SHELL_ENTER_TO_CONT
),
1283 ShellInfoObject
.HiiHandle
,
1288 ShellPrintEx (-1, -1, L
"%2d. %s\n", Index
, Node
->Buffer
);
1289 LineNumber
+= LineCount
;
1299 // This is identical to EFI_FILE_PROTOCOL except for the additional members
1300 // for the buffer, size, and position.
1306 EFI_FILE_CLOSE Close
;
1307 EFI_FILE_DELETE Delete
;
1309 EFI_FILE_WRITE Write
;
1310 EFI_FILE_GET_POSITION GetPosition
;
1311 EFI_FILE_SET_POSITION SetPosition
;
1312 EFI_FILE_GET_INFO GetInfo
;
1313 EFI_FILE_SET_INFO SetInfo
;
1314 EFI_FILE_FLUSH Flush
;
1319 } EFI_FILE_PROTOCOL_MEM
;
1322 File style interface for Mem (SetPosition).
1324 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1325 @param[out] Position The position to set.
1327 @retval EFI_SUCCESS The position was successfully changed.
1328 @retval EFI_INVALID_PARAMETER The Position was invalid.
1332 FileInterfaceMemSetPosition(
1333 IN EFI_FILE_PROTOCOL
*This
,
1337 if (Position
<= ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) {
1338 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= Position
;
1339 return (EFI_SUCCESS
);
1341 return (EFI_INVALID_PARAMETER
);
1346 File style interface for Mem (GetPosition).
1348 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1349 @param[out] Position The pointer to the position.
1351 @retval EFI_SUCCESS The position was retrieved.
1355 FileInterfaceMemGetPosition(
1356 IN EFI_FILE_PROTOCOL
*This
,
1357 OUT UINT64
*Position
1360 *Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
;
1361 return (EFI_SUCCESS
);
1365 File style interface for Mem (Write).
1367 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1368 @param[in, out] BufferSize Size in bytes of Buffer.
1369 @param[in] Buffer The pointer to the buffer to write.
1371 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
1372 @retval EFI_SUCCESS The data was written.
1376 FileInterfaceMemWrite(
1377 IN EFI_FILE_PROTOCOL
*This
,
1378 IN OUT UINTN
*BufferSize
,
1383 if (((EFI_FILE_PROTOCOL_MEM
*)This
)->Unicode
) {
1387 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1388 ((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
);
1389 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= (*BufferSize
) + 10;
1391 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, Buffer
, *BufferSize
);
1392 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= (*BufferSize
);
1393 return (EFI_SUCCESS
);
1398 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1399 if (AsciiBuffer
== NULL
) {
1400 return (EFI_OUT_OF_RESOURCES
);
1402 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1403 if ((UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ AsciiStrSize(AsciiBuffer
)) > (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
)) {
1404 ((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
);
1405 ((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
+= AsciiStrSize(AsciiBuffer
) + 10;
1407 CopyMem(((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, AsciiBuffer
, AsciiStrSize(AsciiBuffer
));
1408 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+= AsciiStrSize(AsciiBuffer
);
1409 FreePool(AsciiBuffer
);
1410 return (EFI_SUCCESS
);
1415 File style interface for Mem (Read).
1417 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1418 @param[in, out] BufferSize Size in bytes of Buffer.
1419 @param[in] Buffer The pointer to the buffer to fill.
1421 @retval EFI_SUCCESS The data was read.
1425 FileInterfaceMemRead(
1426 IN EFI_FILE_PROTOCOL
*This
,
1427 IN OUT UINTN
*BufferSize
,
1431 if (*BufferSize
> (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
))) {
1432 (*BufferSize
) = (UINTN
)((((EFI_FILE_PROTOCOL_MEM
*)This
)->BufferSize
) - (UINTN
)(((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
));
1434 CopyMem(Buffer
, ((UINT8
*)((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
) + ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
, (*BufferSize
));
1435 ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
= ((EFI_FILE_PROTOCOL_MEM
*)This
)->Position
+ (*BufferSize
);
1436 return (EFI_SUCCESS
);
1440 File style interface for Mem (Close).
1442 Frees all memory associated with this object.
1444 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1446 @retval EFI_SUCCESS The 'file' was closed.
1450 FileInterfaceMemClose(
1451 IN EFI_FILE_PROTOCOL
*This
1454 SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM
*)This
)->Buffer
);
1455 SHELL_FREE_NON_NULL(This
);
1456 return (EFI_SUCCESS
);
1460 Creates a EFI_FILE_PROTOCOL (almost) object for using to access
1461 a file entirely in memory through file operations.
1463 @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.
1465 @retval NULL Memory could not be allocated.
1466 @return other A pointer to an EFI_FILE_PROTOCOL structure.
1470 CreateFileInterfaceMem(
1471 IN CONST BOOLEAN Unicode
1474 EFI_FILE_PROTOCOL_MEM
*FileInterface
;
1479 FileInterface
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM
));
1480 if (FileInterface
== NULL
){
1485 // Assign the generic members
1487 FileInterface
->Revision
= EFI_FILE_REVISION
;
1488 FileInterface
->Open
= FileInterfaceOpenNotFound
;
1489 FileInterface
->Close
= FileInterfaceMemClose
;
1490 FileInterface
->GetPosition
= FileInterfaceMemGetPosition
;
1491 FileInterface
->SetPosition
= FileInterfaceMemSetPosition
;
1492 FileInterface
->GetInfo
= FileInterfaceNopGetInfo
;
1493 FileInterface
->SetInfo
= FileInterfaceNopSetInfo
;
1494 FileInterface
->Flush
= FileInterfaceNopGeneric
;
1495 FileInterface
->Delete
= FileInterfaceNopGeneric
;
1496 FileInterface
->Read
= FileInterfaceMemRead
;
1497 FileInterface
->Write
= FileInterfaceMemWrite
;
1498 FileInterface
->Unicode
= Unicode
;
1500 ASSERT(FileInterface
->Buffer
== NULL
);
1501 ASSERT(FileInterface
->BufferSize
== 0);
1502 ASSERT(FileInterface
->Position
== 0);
1504 return ((EFI_FILE_PROTOCOL
*)FileInterface
);
1510 EFI_FILE_CLOSE Close
;
1511 EFI_FILE_DELETE Delete
;
1513 EFI_FILE_WRITE Write
;
1514 EFI_FILE_GET_POSITION GetPosition
;
1515 EFI_FILE_SET_POSITION SetPosition
;
1516 EFI_FILE_GET_INFO GetInfo
;
1517 EFI_FILE_SET_INFO SetInfo
;
1518 EFI_FILE_FLUSH Flush
;
1520 EFI_FILE_PROTOCOL
*Orig
;
1521 } EFI_FILE_PROTOCOL_FILE
;
1524 Set a files current position
1526 @param This Protocol instance pointer.
1527 @param Position Byte position from the start of the file.
1529 @retval EFI_SUCCESS Data was written.
1530 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1535 FileInterfaceFileSetPosition(
1536 IN EFI_FILE_PROTOCOL
*This
,
1540 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1544 Get a file's current position
1546 @param This Protocol instance pointer.
1547 @param Position Byte position from the start of the file.
1549 @retval EFI_SUCCESS Data was written.
1550 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1555 FileInterfaceFileGetPosition(
1556 IN EFI_FILE_PROTOCOL
*This
,
1557 OUT UINT64
*Position
1560 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetPosition(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, Position
);
1564 Get information about a file.
1566 @param This Protocol instance pointer.
1567 @param InformationType Type of information to return in Buffer.
1568 @param BufferSize On input size of buffer, on output amount of data in buffer.
1569 @param Buffer The buffer to return data.
1571 @retval EFI_SUCCESS Data was returned.
1572 @retval EFI_UNSUPPORT InformationType is not supported.
1573 @retval EFI_NO_MEDIA The device has no media.
1574 @retval EFI_DEVICE_ERROR The device reported an error.
1575 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1576 @retval EFI_WRITE_PROTECTED The device is write protected.
1577 @retval EFI_ACCESS_DENIED The file was open for read only.
1578 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1583 FileInterfaceFileGetInfo(
1584 IN EFI_FILE_PROTOCOL
*This
,
1585 IN EFI_GUID
*InformationType
,
1586 IN OUT UINTN
*BufferSize
,
1590 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->GetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1594 Set information about a file
1596 @param This Protocol instance pointer.
1597 @param InformationType Type of information in Buffer.
1598 @param BufferSize Size of buffer.
1599 @param Buffer The data to write.
1601 @retval EFI_SUCCESS Data was returned.
1602 @retval EFI_UNSUPPORT InformationType is not supported.
1603 @retval EFI_NO_MEDIA The device has no media.
1604 @retval EFI_DEVICE_ERROR The device reported an error.
1605 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1606 @retval EFI_WRITE_PROTECTED The device is write protected.
1607 @retval EFI_ACCESS_DENIED The file was open for read only.
1612 FileInterfaceFileSetInfo(
1613 IN EFI_FILE_PROTOCOL
*This
,
1614 IN EFI_GUID
*InformationType
,
1615 IN UINTN BufferSize
,
1619 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->SetInfo(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, InformationType
, BufferSize
, Buffer
);
1623 Flush data back for the file handle.
1625 @param This Protocol instance pointer.
1627 @retval EFI_SUCCESS Data was written.
1628 @retval EFI_UNSUPPORT Writes to Open directory are not supported.
1629 @retval EFI_NO_MEDIA The device has no media.
1630 @retval EFI_DEVICE_ERROR The device reported an error.
1631 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1632 @retval EFI_WRITE_PROTECTED The device is write protected.
1633 @retval EFI_ACCESS_DENIED The file was open for read only.
1634 @retval EFI_VOLUME_FULL The volume is full.
1639 FileInterfaceFileFlush(
1640 IN EFI_FILE_PROTOCOL
*This
1643 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Flush(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1647 Read data from the file.
1649 @param This Protocol instance pointer.
1650 @param BufferSize On input size of buffer, on output amount of data in buffer.
1651 @param Buffer The buffer in which data is read.
1653 @retval EFI_SUCCESS Data was read.
1654 @retval EFI_NO_MEDIA The device has no media.
1655 @retval EFI_DEVICE_ERROR The device reported an error.
1656 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1657 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1662 FileInterfaceFileRead(
1663 IN EFI_FILE_PROTOCOL
*This
,
1664 IN OUT UINTN
*BufferSize
,
1671 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1675 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1680 AsciiBuffer
= AllocateZeroPool((Size
= *BufferSize
));
1681 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Read(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1682 UnicodeSPrint(Buffer
, *BufferSize
, L
"%a", AsciiBuffer
);
1683 FreePool(AsciiBuffer
);
1689 Opens a new file relative to the source file's location.
1691 @param[in] This The protocol instance pointer.
1692 @param[out] NewHandle Returns File Handle for FileName.
1693 @param[in] FileName Null terminated string. "\", ".", and ".." are supported.
1694 @param[in] OpenMode Open mode for file.
1695 @param[in] Attributes Only used for EFI_FILE_MODE_CREATE.
1697 @retval EFI_SUCCESS The device was opened.
1698 @retval EFI_NOT_FOUND The specified file could not be found on the device.
1699 @retval EFI_NO_MEDIA The device has no media.
1700 @retval EFI_MEDIA_CHANGED The media has changed.
1701 @retval EFI_DEVICE_ERROR The device reported an error.
1702 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1703 @retval EFI_ACCESS_DENIED The service denied access to the file.
1704 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
1705 @retval EFI_VOLUME_FULL The volume is full.
1709 FileInterfaceFileOpen (
1710 IN EFI_FILE_PROTOCOL
*This
,
1711 OUT EFI_FILE_PROTOCOL
**NewHandle
,
1712 IN CHAR16
*FileName
,
1714 IN UINT64 Attributes
1717 return ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Open(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, NewHandle
, FileName
, OpenMode
, Attributes
);
1721 Close and delete the file handle.
1723 @param This Protocol instance pointer.
1725 @retval EFI_SUCCESS The device was opened.
1726 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
1731 FileInterfaceFileDelete(
1732 IN EFI_FILE_PROTOCOL
*This
1736 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Delete(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1742 File style interface for File (Close).
1744 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1746 @retval EFI_SUCCESS The file was closed.
1750 FileInterfaceFileClose(
1751 IN EFI_FILE_PROTOCOL
*This
1755 Status
= ((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Close(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
);
1761 File style interface for File (Write).
1763 If the file was opened with ASCII mode the data will be processed through
1764 AsciiSPrint before writing.
1766 @param[in] This The pointer to the EFI_FILE_PROTOCOL object.
1767 @param[in, out] BufferSize Size in bytes of Buffer.
1768 @param[in] Buffer The pointer to the buffer to write.
1770 @retval EFI_SUCCESS The data was written.
1774 FileInterfaceFileWrite(
1775 IN EFI_FILE_PROTOCOL
*This
,
1776 IN OUT UINTN
*BufferSize
,
1783 if (((EFI_FILE_PROTOCOL_FILE
*)This
)->Unicode
) {
1787 return (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, BufferSize
, Buffer
));
1792 AsciiBuffer
= AllocateZeroPool(*BufferSize
);
1793 AsciiSPrint(AsciiBuffer
, *BufferSize
, "%S", Buffer
);
1794 Size
= AsciiStrSize(AsciiBuffer
) - 1; // (we dont need the null terminator)
1795 Status
= (((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
->Write(((EFI_FILE_PROTOCOL_FILE
*)This
)->Orig
, &Size
, AsciiBuffer
));
1796 FreePool(AsciiBuffer
);
1802 Create a file interface with unicode information.
1804 This will create a new EFI_FILE_PROTOCOL identical to the Templace
1805 except that the new one has Unicode and Ascii knowledge.
1807 @param[in] Template A pointer to the EFI_FILE_PROTOCOL object.
1808 @param[in] Unicode TRUE for UCS-2, FALSE for ASCII.
1810 @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
1813 CreateFileInterfaceFile(
1814 IN CONST EFI_FILE_PROTOCOL
*Template
,
1815 IN CONST BOOLEAN Unicode
1818 EFI_FILE_PROTOCOL_FILE
*NewOne
;
1820 NewOne
= AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE
));
1821 if (NewOne
== NULL
) {
1824 CopyMem(NewOne
, Template
, sizeof(EFI_FILE_PROTOCOL_FILE
));
1825 NewOne
->Orig
= (EFI_FILE_PROTOCOL
*)Template
;
1826 NewOne
->Unicode
= Unicode
;
1827 NewOne
->Open
= FileInterfaceFileOpen
;
1828 NewOne
->Close
= FileInterfaceFileClose
;
1829 NewOne
->Delete
= FileInterfaceFileDelete
;
1830 NewOne
->Read
= FileInterfaceFileRead
;
1831 NewOne
->Write
= FileInterfaceFileWrite
;
1832 NewOne
->GetPosition
= FileInterfaceFileGetPosition
;
1833 NewOne
->SetPosition
= FileInterfaceFileSetPosition
;
1834 NewOne
->GetInfo
= FileInterfaceFileGetInfo
;
1835 NewOne
->SetInfo
= FileInterfaceFileSetInfo
;
1836 NewOne
->Flush
= FileInterfaceFileFlush
;
1838 return ((EFI_FILE_PROTOCOL
*)NewOne
);