2 Main file for Type shell level 3 function.
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved. <BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UefiShellLevel3CommandsLib.h"
12 #include <Library/ShellLib.h>
15 Display a single file to StdOut.
17 If both Ascii and UCS2 are FALSE attempt to discover the file type.
19 @param[in] Handle The handle to the file to display.
20 @param[in] Ascii TRUE to force ASCII, FALSE othewise.
21 @param[in] UCS2 TRUE to force UCS2, FALSE othewise.
23 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
24 @retval EFI_SUCCESS The operation was successful.
28 IN SHELL_FILE_HANDLE Handle
,
35 VOID
*AllocatedBuffer
;
42 ReadSize
= PcdGet32 (PcdShellFileOperationSize
);
43 AllocatedBuffer
= AllocateZeroPool (ReadSize
);
44 if (AllocatedBuffer
== NULL
) {
45 return (EFI_OUT_OF_RESOURCES
);
48 Status
= ShellSetFilePosition (Handle
, 0);
49 ASSERT_EFI_ERROR (Status
);
51 while (ReadSize
== ((UINTN
)PcdGet32 (PcdShellFileOperationSize
))) {
52 Buffer
= AllocatedBuffer
;
53 ZeroMem (Buffer
, ReadSize
);
54 Status
= ShellReadFile (Handle
, &ReadSize
, Buffer
);
55 if (EFI_ERROR (Status
)) {
60 if (*(UINT16
*)Buffer
== gUnicodeFileTag
) {
69 for (LoopVar
= 0; LoopVar
< LoopSize
; LoopVar
++) {
71 // The valid range of ASCII characters is 0x20-0x7E.
72 // Display "." when there is an invalid character.
74 AsciiChar
= CHAR_NULL
;
75 AsciiChar
= ((CHAR8
*)Buffer
)[LoopVar
];
76 if ((AsciiChar
== '\r') || (AsciiChar
== '\n')) {
78 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)
79 // characters to be displayed as is.
81 if (((AsciiChar
== '\n') && (LoopVar
== 0)) ||
82 ((AsciiChar
== '\n') && (((CHAR8
*)Buffer
)[LoopVar
-1] != '\r')))
85 // In case file begin with single line Feed or Line Feed (0xA) is
86 // encountered & Carriage Return (0xD) was not previous character,
87 // print CR and LF. This is because Shell 2.0 requires carriage
88 // return with line feed for displaying each new line from left.
90 ShellPrintEx (-1, -1, L
"\r\n");
95 // For all other characters which are not printable, display '.'
97 if ((AsciiChar
< 0x20) || (AsciiChar
>= 0x7F)) {
102 ShellPrintEx (-1, -1, L
"%c", AsciiChar
);
105 if (*(UINT16
*)Buffer
== gUnicodeFileTag
) {
107 // For unicode files, skip displaying the byte order marker.
109 Buffer
= ((UINT16
*)Buffer
) + 1;
110 LoopSize
= (ReadSize
/ (sizeof (CHAR16
))) - 1;
112 LoopSize
= ReadSize
/ (sizeof (CHAR16
));
115 for (LoopVar
= 0; LoopVar
< LoopSize
; LoopVar
++) {
117 // An invalid range of characters is 0x0-0x1F.
118 // Display "." when there is an invalid character.
120 Ucs2Char
= CHAR_NULL
;
121 Ucs2Char
= ((CHAR16
*)Buffer
)[LoopVar
];
122 if ((Ucs2Char
== '\r') || (Ucs2Char
== '\n')) {
124 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)
125 // characters to be displayed as is.
127 if (((Ucs2Char
== '\n') && (LoopVar
== 0)) ||
128 ((Ucs2Char
== '\n') && (((CHAR16
*)Buffer
)[LoopVar
-1] != '\r')))
131 // In case file begin with single line Feed or Line Feed (0xA) is
132 // encountered & Carriage Return (0xD) was not previous character,
133 // print CR and LF. This is because Shell 2.0 requires carriage
134 // return with line feed for displaying each new line from left.
136 ShellPrintEx (-1, -1, L
"\r\n");
139 } else if (Ucs2Char
< 0x20) {
141 // For all other characters which are not printable, display '.'
146 ShellPrintEx (-1, -1, L
"%c", Ucs2Char
);
150 if (ShellGetExecutionBreakFlag ()) {
155 FreePool (AllocatedBuffer
);
156 ShellPrintEx (-1, -1, L
"\r\n");
160 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
167 Function for 'type' command.
169 @param[in] ImageHandle Handle to the Image (NULL if Internal).
170 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
174 ShellCommandRunType (
175 IN EFI_HANDLE ImageHandle
,
176 IN EFI_SYSTEM_TABLE
*SystemTable
181 CHAR16
*ProblemParam
;
183 SHELL_STATUS ShellStatus
;
185 EFI_SHELL_FILE_INFO
*FileList
;
186 EFI_SHELL_FILE_INFO
*Node
;
191 ShellStatus
= SHELL_SUCCESS
;
196 // initialize the shell lib (we must be in non-auto-init...)
198 Status
= ShellInitialize ();
199 ASSERT_EFI_ERROR (Status
);
201 Status
= CommandInit ();
202 ASSERT_EFI_ERROR (Status
);
205 // parse the command line
207 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
208 if (EFI_ERROR (Status
)) {
209 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
210 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellLevel3HiiHandle
, L
"type", ProblemParam
);
211 FreePool (ProblemParam
);
212 ShellStatus
= SHELL_INVALID_PARAMETER
;
220 if (ShellCommandLineGetFlag (Package
, L
"-?")) {
224 AsciiMode
= ShellCommandLineGetFlag (Package
, L
"-a");
225 UnicodeMode
= ShellCommandLineGetFlag (Package
, L
"-u");
227 if (AsciiMode
&& UnicodeMode
) {
228 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellLevel3HiiHandle
, L
"type", L
"-a & -u");
229 ShellStatus
= SHELL_INVALID_PARAMETER
;
230 } else if (ShellCommandLineGetRawValue (Package
, 1) == NULL
) {
232 // we insufficient parameters
234 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellLevel3HiiHandle
, L
"type");
235 ShellStatus
= SHELL_INVALID_PARAMETER
;
238 // get a list with each file specified by parameters
239 // if parameter is a directory then add all the files below it to the list
241 for ( ParamCount
= 1, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
243 ; ParamCount
++, Param
= ShellCommandLineGetRawValue (Package
, ParamCount
)
246 Status
= ShellOpenFileMetaArg ((CHAR16
*)Param
, EFI_FILE_MODE_READ
, &FileList
);
247 if (EFI_ERROR (Status
)) {
248 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel3HiiHandle
, L
"type", (CHAR16
*)Param
);
249 ShellStatus
= SHELL_NOT_FOUND
;
254 // make sure we completed the param parsing sucessfully...
255 // Also make sure that any previous action was sucessful
257 if (ShellStatus
== SHELL_SUCCESS
) {
259 // check that we have at least 1 file
261 if ((FileList
== NULL
) || IsListEmpty (&FileList
->Link
)) {
262 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_NF
), gShellLevel3HiiHandle
, L
"type", Param
);
266 // loop through the list and make sure we are not aborting...
268 for ( Node
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
)
269 ; !IsNull (&FileList
->Link
, &Node
->Link
) && !ShellGetExecutionBreakFlag ()
270 ; Node
= (EFI_SHELL_FILE_INFO
*)GetNextNode (&FileList
->Link
, &Node
->Link
)
273 if (ShellGetExecutionBreakFlag ()) {
278 // make sure the file opened ok
280 if (EFI_ERROR (Node
->Status
)) {
281 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellLevel3HiiHandle
, L
"type", Node
->FileName
);
282 ShellStatus
= SHELL_NOT_FOUND
;
287 // make sure its not a directory
289 if (FileHandleIsDirectory (Node
->Handle
) == EFI_SUCCESS
) {
290 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_IS_DIR
), gShellLevel3HiiHandle
, L
"type", Node
->FileName
);
291 ShellStatus
= SHELL_NOT_FOUND
;
298 Status
= TypeFileByHandle (Node
->Handle
, AsciiMode
, UnicodeMode
);
299 if (EFI_ERROR (Status
)) {
300 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_TYP_ERROR
), gShellLevel3HiiHandle
, L
"type", Node
->FileName
);
301 ShellStatus
= SHELL_INVALID_PARAMETER
;
304 ASSERT (ShellStatus
== SHELL_SUCCESS
);
312 if ((FileList
!= NULL
) && !IsListEmpty (&FileList
->Link
)) {
313 Status
= ShellCloseFileMetaArg (&FileList
);
316 ASSERT_EFI_ERROR (Status
);
322 // free the command line package
324 ShellCommandLineFreeVarList (Package
);
327 if (ShellGetExecutionBreakFlag ()) {
328 return (SHELL_ABORTED
);
331 return (ShellStatus
);