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