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