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