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