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