]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/SerMode.c
ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / SerMode.c
1 /** @file
2 Main file for SerMode shell Debug1 function.
3
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2005 - 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 "UefiShellDebug1CommandsLib.h"
17 #include <Library/ShellLib.h>
18 #include <Protocol/SerialIo.h>
19
20 /**
21 Display information about a serial device by it's handle.
22
23 If HandleValid is FALSE, do all devices.
24
25 @param[in] HandleIdx The handle index for the device.
26 @param[in] HandleValid TRUE if HandleIdx is valid.
27
28 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
29 @retval SHELL_SUCCESS The operation was successful.
30 **/
31 SHELL_STATUS
32 DisplaySettings (
33 IN UINTN HandleIdx,
34 IN BOOLEAN HandleValid
35 )
36 {
37 EFI_SERIAL_IO_PROTOCOL *SerialIo;
38 UINTN NoHandles;
39 EFI_HANDLE *Handles;
40 EFI_STATUS Status;
41 UINTN Index;
42 CHAR16 *StopBits;
43 CHAR16 Parity;
44 SHELL_STATUS ShellStatus;
45
46 Handles = NULL;
47 StopBits = NULL;
48
49 ShellStatus = SHELL_SUCCESS;
50
51 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles);
52 if (EFI_ERROR (Status)) {
53 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode");
54 return SHELL_INVALID_PARAMETER;
55 }
56
57 for (Index = 0; Index < NoHandles; Index++) {
58 if (HandleValid) {
59 if (ConvertHandleIndexToHandle(HandleIdx) != Handles[Index]) {
60 continue;
61 }
62 }
63
64 Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo);
65 if (!EFI_ERROR (Status)) {
66 switch (SerialIo->Mode->Parity) {
67 case DefaultParity:
68
69 Parity = 'D';
70 break;
71
72 case NoParity:
73
74 Parity = 'N';
75 break;
76
77 case EvenParity:
78
79 Parity = 'E';
80 break;
81
82 case OddParity:
83
84 Parity = 'O';
85 break;
86
87 case MarkParity:
88
89 Parity = 'M';
90 break;
91
92 case SpaceParity:
93
94 Parity = 'S';
95 break;
96
97 default:
98
99 Parity = 'U';
100 }
101
102 switch (SerialIo->Mode->StopBits) {
103 case DefaultStopBits:
104
105 StopBits = L"Default";
106 break;
107
108 case OneStopBit:
109
110 StopBits = L"1";
111 break;
112
113 case TwoStopBits:
114
115 StopBits = L"2";
116 break;
117
118 case OneFiveStopBits:
119
120 StopBits = L"1.5";
121 break;
122
123 default:
124
125 StopBits = L"Unknown";
126 }
127 ShellPrintHiiEx(
128 -1,
129 -1,
130 NULL,
131 STRING_TOKEN (STR_SERMODE_DISPLAY),
132 gShellDebug1HiiHandle,
133 ConvertHandleToHandleIndex (Handles[Index]),
134 Handles[Index],
135 SerialIo->Mode->BaudRate,
136 Parity,
137 SerialIo->Mode->DataBits,
138 StopBits
139 );
140 } else {
141 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode");
142 ShellStatus = SHELL_NOT_FOUND;
143 break;
144 }
145
146 if (HandleValid) {
147 break;
148 }
149 }
150
151 if (Index == NoHandles) {
152 if ((NoHandles != 0 && HandleValid) || 0 == NoHandles) {
153 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NOT_FOUND), gShellDebug1HiiHandle, L"sermode");
154 ShellStatus = SHELL_NOT_FOUND;
155 }
156 }
157
158 return ShellStatus;
159 }
160
161 /**
162 Function for 'sermode' command.
163
164 @param[in] ImageHandle Handle to the Image (NULL if Internal).
165 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
166 **/
167 SHELL_STATUS
168 EFIAPI
169 ShellCommandRunSerMode (
170 IN EFI_HANDLE ImageHandle,
171 IN EFI_SYSTEM_TABLE *SystemTable
172 )
173 {
174 EFI_STATUS Status;
175 SHELL_STATUS ShellStatus;
176 UINTN Index;
177 UINTN NoHandles;
178 EFI_HANDLE *Handles;
179 EFI_PARITY_TYPE Parity;
180 EFI_STOP_BITS_TYPE StopBits;
181 UINTN HandleIdx;
182 UINTN BaudRate;
183 UINTN DataBits;
184 UINTN Value;
185 EFI_SERIAL_IO_PROTOCOL *SerialIo;
186 LIST_ENTRY *Package;
187 CHAR16 *ProblemParam;
188 CONST CHAR16 *Temp;
189 UINT64 Intermediate;
190
191 ShellStatus = SHELL_SUCCESS;
192 HandleIdx = 0;
193 Parity = DefaultParity;
194 Handles = NULL;
195 NoHandles = 0;
196 Index = 0;
197 Package = NULL;
198
199 Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
200 if (EFI_ERROR(Status)) {
201 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
202 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"sermode", ProblemParam);
203 FreePool(ProblemParam);
204 ShellStatus = SHELL_INVALID_PARAMETER;
205 } else {
206 ASSERT(FALSE);
207 }
208 } else {
209 if (ShellCommandLineGetCount(Package) < 6 && ShellCommandLineGetCount(Package) > 2) {
210 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"sermode");
211 ShellStatus = SHELL_INVALID_PARAMETER;
212 } else if (ShellCommandLineGetCount(Package) > 6) {
213 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"sermode");
214 ShellStatus = SHELL_INVALID_PARAMETER;
215 } else {
216 Temp = ShellCommandLineGetRawValue(Package, 1);
217 if (Temp != NULL) {
218 Status = ShellConvertStringToUint64(Temp, &Intermediate, TRUE, FALSE);
219 HandleIdx = (UINTN)Intermediate;
220 Temp = ShellCommandLineGetRawValue(Package, 2);
221 if (Temp == NULL) {
222 ShellStatus = DisplaySettings (HandleIdx, TRUE);
223 goto Done;
224 }
225 } else {
226 ShellStatus = DisplaySettings (0, FALSE);
227 goto Done;
228 }
229 Temp = ShellCommandLineGetRawValue(Package, 2);
230 if (Temp != NULL) {
231 BaudRate = ShellStrToUintn(Temp);
232 } else {
233 ASSERT(FALSE);
234 BaudRate = 0;
235 }
236 Temp = ShellCommandLineGetRawValue(Package, 3);
237 if (Temp == NULL || StrLen(Temp)>1) {
238 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp);
239 ShellStatus = SHELL_INVALID_PARAMETER;
240 } else {
241 switch(Temp[0]){
242 case 'd':
243 case 'D':
244 Parity = DefaultParity;
245 break;
246 case 'n':
247 case 'N':
248 Parity = NoParity;
249 break;
250 case 'e':
251 case 'E':
252 Parity = EvenParity;
253 break;
254 case 'o':
255 case 'O':
256 Parity = OddParity;
257 break;
258 case 'm':
259 case 'M':
260 Parity = MarkParity;
261 break;
262 case 's':
263 case 'S':
264 Parity = SpaceParity;
265 break;
266 default:
267 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp);
268 ShellStatus = SHELL_INVALID_PARAMETER;
269 goto Done;
270 }
271 }
272 Temp = ShellCommandLineGetRawValue(Package, 4);
273 if (Temp != NULL) {
274 DataBits = ShellStrToUintn(Temp);
275 } else {
276 //
277 // make sure this is some number not in the list below.
278 //
279 DataBits = 0;
280 }
281 switch (DataBits) {
282 case 4:
283 case 7:
284 case 8:
285 break;
286 default:
287 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp);
288 ShellStatus = SHELL_INVALID_PARAMETER;
289 goto Done;
290 }
291 Temp = ShellCommandLineGetRawValue(Package, 5);
292 Value = ShellStrToUintn(Temp);
293 switch (Value) {
294 case 0:
295 StopBits = DefaultStopBits;
296 break;
297
298 case 1:
299 StopBits = OneStopBit;
300 break;
301
302 case 2:
303 StopBits = TwoStopBits;
304 break;
305
306 case 15:
307 StopBits = OneFiveStopBits;
308 break;
309
310 default:
311 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp);
312 ShellStatus = SHELL_INVALID_PARAMETER;
313 goto Done;
314 }
315 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles);
316 if (EFI_ERROR (Status)) {
317 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode");
318 ShellStatus = SHELL_INVALID_PARAMETER;
319 goto Done;
320 }
321
322 for (Index = 0; Index < NoHandles; Index++) {
323 if (ConvertHandleIndexToHandle (HandleIdx) != Handles[Index]) {
324 continue;
325 }
326
327 Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo);
328 if (!EFI_ERROR (Status)) {
329 Status = SerialIo->SetAttributes (
330 SerialIo,
331 (UINT64) BaudRate,
332 SerialIo->Mode->ReceiveFifoDepth,
333 SerialIo->Mode->Timeout,
334 Parity,
335 (UINT8) DataBits,
336 StopBits
337 );
338 if (EFI_ERROR (Status)) {
339 if (Status == EFI_INVALID_PARAMETER) {
340 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_UNSUPPORTED), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index]));
341 ShellStatus = SHELL_UNSUPPORTED;
342 } else if (Status == EFI_DEVICE_ERROR) {
343 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_DEV_ERROR), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index]));
344 ShellStatus = SHELL_ACCESS_DENIED;
345 } else {
346 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_FAIL), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index]));
347 ShellStatus = SHELL_ACCESS_DENIED;
348 }
349 } else {
350 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_HANDLE), gShellDebug1HiiHandle, ConvertHandleToHandleIndex(Handles[Index]));
351 }
352 break;
353 }
354 }
355 }
356 }
357
358 if (ShellStatus == SHELL_SUCCESS && Index == NoHandles) {
359 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_BAD_HANDLE), gShellDebug1HiiHandle, L"sermode", HandleIdx);
360 ShellStatus = SHELL_INVALID_PARAMETER;
361 }
362
363 Done:
364 if (Package != NULL) {
365 ShellCommandLineFreeVarList (Package);
366 }
367 if (Handles != NULL) {
368 FreePool (Handles);
369 }
370 return ShellStatus;
371 }