]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel3CommandsLib/Type.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel3CommandsLib / Type.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for Type shell level 3 function.\r
3\r
c011b6c9 4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
ef236056 5 Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved. <BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 7\r
8**/\r
9\r
10#include "UefiShellLevel3CommandsLib.h"\r
11\r
12#include <Library/ShellLib.h>\r
13\r
345cd235 14/**\r
15 Display a single file to StdOut.\r
16\r
17 If both Ascii and UCS2 are FALSE attempt to discover the file type.\r
18\r
19 @param[in] Handle The handle to the file to display.\r
20 @param[in] Ascii TRUE to force ASCII, FALSE othewise.\r
21 @param[in] UCS2 TRUE to force UCS2, FALSE othewise.\r
22\r
23 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
24 @retval EFI_SUCCESS The operation was successful.\r
25**/\r
a405b86d 26EFI_STATUS\r
a405b86d 27TypeFileByHandle (\r
47d20b54
MK
28 IN SHELL_FILE_HANDLE Handle,\r
29 IN BOOLEAN Ascii,\r
30 IN BOOLEAN UCS2\r
a405b86d 31 )\r
32{\r
33 UINTN ReadSize;\r
34 VOID *Buffer;\r
a4883d4c 35 VOID *AllocatedBuffer;\r
a405b86d 36 EFI_STATUS Status;\r
37 UINTN LoopVar;\r
a4883d4c 38 UINTN LoopSize;\r
a405b86d 39 CHAR16 AsciiChar;\r
a4883d4c 40 CHAR16 Ucs2Char;\r
a405b86d 41\r
47d20b54
MK
42 ReadSize = PcdGet32 (PcdShellFileOperationSize);\r
43 AllocatedBuffer = AllocateZeroPool (ReadSize);\r
a4883d4c 44 if (AllocatedBuffer == NULL) {\r
a405b86d 45 return (EFI_OUT_OF_RESOURCES);\r
46 }\r
47\r
47d20b54
MK
48 Status = ShellSetFilePosition (Handle, 0);\r
49 ASSERT_EFI_ERROR (Status);\r
a405b86d 50\r
47d20b54 51 while (ReadSize == ((UINTN)PcdGet32 (PcdShellFileOperationSize))) {\r
a4883d4c 52 Buffer = AllocatedBuffer;\r
47d20b54
MK
53 ZeroMem (Buffer, ReadSize);\r
54 Status = ShellReadFile (Handle, &ReadSize, Buffer);\r
55 if (EFI_ERROR (Status)) {\r
a405b86d 56 break;\r
57 }\r
58\r
a4883d4c 59 if (!(Ascii|UCS2)) {\r
47d20b54 60 if (*(UINT16 *)Buffer == gUnicodeFileTag) {\r
a405b86d 61 UCS2 = TRUE;\r
a405b86d 62 } else {\r
63 Ascii = TRUE;\r
64 }\r
65 }\r
66\r
a4883d4c
CP
67 if (Ascii) {\r
68 LoopSize = ReadSize;\r
47d20b54 69 for (LoopVar = 0; LoopVar < LoopSize; LoopVar++) {\r
a4883d4c
CP
70 //\r
71 // The valid range of ASCII characters is 0x20-0x7E.\r
72 // Display "." when there is an invalid character.\r
73 //\r
74 AsciiChar = CHAR_NULL;\r
47d20b54
MK
75 AsciiChar = ((CHAR8 *)Buffer)[LoopVar];\r
76 if ((AsciiChar == '\r') || (AsciiChar == '\n')) {\r
a4883d4c
CP
77 //\r
78 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
79 // characters to be displayed as is.\r
ba0014b9 80 //\r
47d20b54
MK
81 if (((AsciiChar == '\n') && (LoopVar == 0)) ||\r
82 ((AsciiChar == '\n') && (((CHAR8 *)Buffer)[LoopVar-1] != '\r')))\r
83 {\r
a4883d4c 84 //\r
ef236056
ZG
85 // In case file begin with single line Feed or Line Feed (0xA) is\r
86 // encountered & Carriage Return (0xD) was not previous character,\r
87 // print CR and LF. This is because Shell 2.0 requires carriage\r
88 // return with line feed for displaying each new line from left.\r
a4883d4c
CP
89 //\r
90 ShellPrintEx (-1, -1, L"\r\n");\r
91 continue;\r
92 }\r
93 } else {\r
94 //\r
95 // For all other characters which are not printable, display '.'\r
96 //\r
47d20b54 97 if ((AsciiChar < 0x20) || (AsciiChar >= 0x7F)) {\r
a4883d4c
CP
98 AsciiChar = '.';\r
99 }\r
100 }\r
47d20b54 101\r
a4883d4c 102 ShellPrintEx (-1, -1, L"%c", AsciiChar);\r
a405b86d 103 }\r
104 } else {\r
47d20b54 105 if (*(UINT16 *)Buffer == gUnicodeFileTag) {\r
a4883d4c
CP
106 //\r
107 // For unicode files, skip displaying the byte order marker.\r
108 //\r
47d20b54 109 Buffer = ((UINT16 *)Buffer) + 1;\r
a4883d4c
CP
110 LoopSize = (ReadSize / (sizeof (CHAR16))) - 1;\r
111 } else {\r
112 LoopSize = ReadSize / (sizeof (CHAR16));\r
113 }\r
ba0014b9 114\r
47d20b54 115 for (LoopVar = 0; LoopVar < LoopSize; LoopVar++) {\r
a4883d4c
CP
116 //\r
117 // An invalid range of characters is 0x0-0x1F.\r
118 // Display "." when there is an invalid character.\r
119 //\r
120 Ucs2Char = CHAR_NULL;\r
47d20b54
MK
121 Ucs2Char = ((CHAR16 *)Buffer)[LoopVar];\r
122 if ((Ucs2Char == '\r') || (Ucs2Char == '\n')) {\r
a4883d4c
CP
123 //\r
124 // Allow Line Feed (LF) (0xA) & Carriage Return (CR) (0xD)\r
125 // characters to be displayed as is.\r
ba0014b9 126 //\r
47d20b54
MK
127 if (((Ucs2Char == '\n') && (LoopVar == 0)) ||\r
128 ((Ucs2Char == '\n') && (((CHAR16 *)Buffer)[LoopVar-1] != '\r')))\r
129 {\r
a4883d4c 130 //\r
ef236056
ZG
131 // In case file begin with single line Feed or Line Feed (0xA) is\r
132 // encountered & Carriage Return (0xD) was not previous character,\r
133 // print CR and LF. This is because Shell 2.0 requires carriage\r
134 // return with line feed for displaying each new line from left.\r
a4883d4c
CP
135 //\r
136 ShellPrintEx (-1, -1, L"\r\n");\r
137 continue;\r
138 }\r
47d20b54 139 } else if (Ucs2Char < 0x20) {\r
a4883d4c
CP
140 //\r
141 // For all other characters which are not printable, display '.'\r
142 //\r
143 Ucs2Char = L'.';\r
144 }\r
47d20b54 145\r
a4883d4c
CP
146 ShellPrintEx (-1, -1, L"%c", Ucs2Char);\r
147 }\r
148 }\r
149\r
47d20b54 150 if (ShellGetExecutionBreakFlag ()) {\r
a4883d4c 151 break;\r
a405b86d 152 }\r
153 }\r
47d20b54 154\r
a4883d4c
CP
155 FreePool (AllocatedBuffer);\r
156 ShellPrintEx (-1, -1, L"\r\n");\r
a405b86d 157 return (Status);\r
158}\r
159\r
47d20b54
MK
160STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
161 { L"-a", TypeFlag },\r
162 { L"-u", TypeFlag },\r
163 { NULL, TypeMax }\r
164};\r
a405b86d 165\r
166/**\r
167 Function for 'type' command.\r
168\r
169 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
170 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
171**/\r
172SHELL_STATUS\r
173EFIAPI\r
174ShellCommandRunType (\r
175 IN EFI_HANDLE ImageHandle,\r
176 IN EFI_SYSTEM_TABLE *SystemTable\r
177 )\r
178{\r
47d20b54
MK
179 EFI_STATUS Status;\r
180 LIST_ENTRY *Package;\r
181 CHAR16 *ProblemParam;\r
182 CONST CHAR16 *Param;\r
183 SHELL_STATUS ShellStatus;\r
184 UINTN ParamCount;\r
185 EFI_SHELL_FILE_INFO *FileList;\r
186 EFI_SHELL_FILE_INFO *Node;\r
187 BOOLEAN AsciiMode;\r
188 BOOLEAN UnicodeMode;\r
189\r
190 ProblemParam = NULL;\r
191 ShellStatus = SHELL_SUCCESS;\r
192 ParamCount = 0;\r
193 FileList = NULL;\r
a405b86d 194\r
195 //\r
196 // initialize the shell lib (we must be in non-auto-init...)\r
197 //\r
47d20b54
MK
198 Status = ShellInitialize ();\r
199 ASSERT_EFI_ERROR (Status);\r
a405b86d 200\r
47d20b54
MK
201 Status = CommandInit ();\r
202 ASSERT_EFI_ERROR (Status);\r
a405b86d 203\r
204 //\r
205 // parse the command line\r
206 //\r
207 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
47d20b54
MK
208 if (EFI_ERROR (Status)) {\r
209 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
210 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"type", ProblemParam);\r
211 FreePool (ProblemParam);\r
a405b86d 212 ShellStatus = SHELL_INVALID_PARAMETER;\r
213 } else {\r
47d20b54 214 ASSERT (FALSE);\r
a405b86d 215 }\r
216 } else {\r
217 //\r
218 // check for "-?"\r
219 //\r
47d20b54
MK
220 if (ShellCommandLineGetFlag (Package, L"-?")) {\r
221 ASSERT (FALSE);\r
a405b86d 222 }\r
47d20b54
MK
223\r
224 AsciiMode = ShellCommandLineGetFlag (Package, L"-a");\r
225 UnicodeMode = ShellCommandLineGetFlag (Package, L"-u");\r
a405b86d 226\r
227 if (AsciiMode && UnicodeMode) {\r
47d20b54 228 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"type", L"-a & -u");\r
a405b86d 229 ShellStatus = SHELL_INVALID_PARAMETER;\r
47d20b54 230 } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) {\r
a405b86d 231 //\r
232 // we insufficient parameters\r
233 //\r
47d20b54 234 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel3HiiHandle, L"type");\r
a405b86d 235 ShellStatus = SHELL_INVALID_PARAMETER;\r
236 } else {\r
237 //\r
238 // get a list with each file specified by parameters\r
239 // if parameter is a directory then add all the files below it to the list\r
240 //\r
47d20b54
MK
241 for ( ParamCount = 1, Param = ShellCommandLineGetRawValue (Package, ParamCount)\r
242 ; Param != NULL\r
243 ; ParamCount++, Param = ShellCommandLineGetRawValue (Package, ParamCount)\r
244 )\r
245 {\r
246 Status = ShellOpenFileMetaArg ((CHAR16 *)Param, EFI_FILE_MODE_READ, &FileList);\r
247 if (EFI_ERROR (Status)) {\r
248 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", (CHAR16 *)Param);\r
a405b86d 249 ShellStatus = SHELL_NOT_FOUND;\r
250 break;\r
251 }\r
47d20b54 252\r
a405b86d 253 //\r
254 // make sure we completed the param parsing sucessfully...\r
255 // Also make sure that any previous action was sucessful\r
256 //\r
257 if (ShellStatus == SHELL_SUCCESS) {\r
258 //\r
259 // check that we have at least 1 file\r
260 //\r
47d20b54
MK
261 if ((FileList == NULL) || IsListEmpty (&FileList->Link)) {\r
262 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel3HiiHandle, L"type", Param);\r
a405b86d 263 continue;\r
264 } else {\r
265 //\r
266 // loop through the list and make sure we are not aborting...\r
267 //\r
47d20b54
MK
268 for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link)\r
269 ; !IsNull (&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag ()\r
270 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&FileList->Link, &Node->Link)\r
271 )\r
272 {\r
273 if (ShellGetExecutionBreakFlag ()) {\r
a4883d4c
CP
274 break;\r
275 }\r
276\r
a405b86d 277 //\r
278 // make sure the file opened ok\r
279 //\r
47d20b54
MK
280 if (EFI_ERROR (Node->Status)) {\r
281 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"type", Node->FileName);\r
a405b86d 282 ShellStatus = SHELL_NOT_FOUND;\r
283 continue;\r
284 }\r
285\r
286 //\r
287 // make sure its not a directory\r
288 //\r
47d20b54
MK
289 if (FileHandleIsDirectory (Node->Handle) == EFI_SUCCESS) {\r
290 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_IS_DIR), gShellLevel3HiiHandle, L"type", Node->FileName);\r
a405b86d 291 ShellStatus = SHELL_NOT_FOUND;\r
292 continue;\r
293 }\r
294\r
295 //\r
296 // do it\r
297 //\r
a4883d4c 298 Status = TypeFileByHandle (Node->Handle, AsciiMode, UnicodeMode);\r
47d20b54
MK
299 if (EFI_ERROR (Status)) {\r
300 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_TYP_ERROR), gShellLevel3HiiHandle, L"type", Node->FileName);\r
a405b86d 301 ShellStatus = SHELL_INVALID_PARAMETER;\r
302 }\r
47d20b54
MK
303\r
304 ASSERT (ShellStatus == SHELL_SUCCESS);\r
a405b86d 305 }\r
306 }\r
307 }\r
47d20b54 308\r
a405b86d 309 //\r
310 // Free the fileList\r
311 //\r
47d20b54
MK
312 if ((FileList != NULL) && !IsListEmpty (&FileList->Link)) {\r
313 Status = ShellCloseFileMetaArg (&FileList);\r
a405b86d 314 }\r
47d20b54
MK
315\r
316 ASSERT_EFI_ERROR (Status);\r
a405b86d 317 FileList = NULL;\r
318 }\r
319 }\r
320\r
321 //\r
322 // free the command line package\r
323 //\r
324 ShellCommandLineFreeVarList (Package);\r
325 }\r
326\r
47d20b54 327 if (ShellGetExecutionBreakFlag ()) {\r
a405b86d 328 return (SHELL_ABORTED);\r
329 }\r
330\r
331 return (ShellStatus);\r
332}\r