]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c
pointer verification (not NULL) and buffer overrun fixes.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / TimeDate.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for time, timezone, and date shell level 2 and shell level 3 functions.\r
3\r
b54fd049 4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
a405b86d 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellLevel2CommandsLib.h"\r
16\r
b54fd049 17/**\r
18 Determine if String is a valid representation for a time or date.\r
19\r
20 @param[in] String The pointer to the string to test.\r
21 @param[in] Char The delimeter character.\r
22 @param[in] Min The minimum value allowed.\r
23 @param[in] Max The maximum value allowed.\r
24 @param[in] MinusOk Whether negative numbers are permitted.\r
a405b86d 25\r
b54fd049 26 @retval TRUE String is a valid representation.\r
27 @retval FALSE String is invalid.\r
28**/\r
a405b86d 29BOOLEAN\r
30EFIAPI\r
31InternalIsTimeLikeString (\r
32 IN CONST CHAR16 *String,\r
33 IN CONST CHAR16 Char,\r
34 IN CONST UINTN Min,\r
35 IN CONST UINTN Max,\r
36 IN CONST BOOLEAN MinusOk\r
37 )\r
38{\r
39 UINTN Count;\r
40 Count = 0;\r
41\r
42 if (MinusOk) {\r
43 //\r
44 // A single minus is ok.\r
45 //\r
46 if (*String == L'-') {\r
47 String++;\r
48 }\r
49 }\r
50\r
51 //\r
52 // the first char must be numeric.\r
53 //\r
54 if (!ShellIsDecimalDigitCharacter(*String)) {\r
55 return (FALSE);\r
56 }\r
57 //\r
58 // loop through the characters and use the lib function\r
59 //\r
60 for ( ; String != NULL && *String != CHAR_NULL ; String++){\r
61 if (*String == Char) {\r
62 Count++;\r
63 if (Count > Max) {\r
64 return (FALSE);\r
65 }\r
66 continue;\r
67 }\r
68 if (!ShellIsDecimalDigitCharacter(*String)) {\r
69 return (FALSE);\r
70 }\r
71 }\r
72 if (Count < Min) {\r
73 return (FALSE);\r
74 }\r
75 return (TRUE);\r
76}\r
77\r
b54fd049 78/**\r
79 Verify that the DateString is valid and if so set that as the current \r
80 date.\r
81\r
82 @param[in] DateString The pointer to a string representation of the date.\r
83\r
84 @retval SHELL_INVALID_PARAMETER DateString was NULL.\r
85 @retval SHELL_INVALID_PARAMETER DateString was mis-formatted.\r
86 @retval SHELL_SUCCESS The operation was successful.\r
87**/\r
a405b86d 88SHELL_STATUS\r
89EFIAPI\r
90CheckAndSetDate (\r
91 IN CONST CHAR16 *DateString\r
92 )\r
93{\r
94 EFI_TIME TheTime;\r
95 EFI_STATUS Status;\r
b54fd049 96 CHAR16 *DateStringCopy;\r
97 CHAR16 *Walker;\r
98 CHAR16 *Walker1;\r
a405b86d 99\r
100 if (!InternalIsTimeLikeString(DateString, L'/', 2, 2, FALSE)) {\r
101 return (SHELL_INVALID_PARAMETER);\r
102 }\r
103\r
104 Status = gRT->GetTime(&TheTime, NULL);\r
105 ASSERT_EFI_ERROR(Status);\r
106\r
b54fd049 107 DateStringCopy = NULL;\r
108 DateStringCopy = StrnCatGrow(&DateStringCopy, NULL, DateString, 0);\r
109 if (DateStringCopy == NULL) {\r
110 return (SHELL_OUT_OF_RESOURCES);\r
111 }\r
112 Walker = DateStringCopy;\r
a405b86d 113\r
114 TheTime.Month = 0xFF;\r
115 TheTime.Day = 0xFF;\r
116 TheTime.Year = 0xFFFF;\r
117\r
b54fd049 118 Walker1 = StrStr(Walker, L"/");\r
119 if (Walker1 != NULL && *Walker1 == L'/') {\r
120 *Walker1 = CHAR_NULL;\r
121 }\r
122\r
123 TheTime.Month = (UINT8)ShellStrToUintn (Walker);\r
124 if (Walker1 != NULL) {\r
125 Walker = Walker1 + 1;\r
126 }\r
33c031ee 127 Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
b54fd049 128 if (Walker1 != NULL && *Walker1 == L'/') {\r
129 *Walker1 = CHAR_NULL;\r
a405b86d 130 }\r
131 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
b54fd049 132 TheTime.Day = (UINT8)ShellStrToUintn (Walker);\r
133 if (Walker1 != NULL) {\r
134 Walker = Walker1 + 1;\r
135 }\r
33c031ee 136 Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
b54fd049 137 if (Walker1 != NULL && *Walker1 == L'/') {\r
138 *Walker1 = CHAR_NULL;\r
a405b86d 139 }\r
140 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
b54fd049 141 TheTime.Year = (UINT16)ShellStrToUintn (Walker);\r
a405b86d 142 }\r
143 }\r
144\r
145 if (TheTime.Year < 100) {\r
146 if (TheTime.Year >= 98) {\r
147 TheTime.Year = (UINT16)(1900 + TheTime.Year);\r
148 } else {\r
149 TheTime.Year = (UINT16)(2000 + TheTime.Year);\r
150 }\r
151 }\r
152\r
153 Status = gRT->SetTime(&TheTime);\r
154\r
155 if (!EFI_ERROR(Status)){\r
156 return (SHELL_SUCCESS);\r
157 }\r
158 return (SHELL_INVALID_PARAMETER);\r
159}\r
160\r
161/**\r
162 Function for 'date' command.\r
163\r
164 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
165 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
166**/\r
167SHELL_STATUS\r
168EFIAPI\r
169ShellCommandRunDate (\r
170 IN EFI_HANDLE ImageHandle,\r
171 IN EFI_SYSTEM_TABLE *SystemTable\r
172 )\r
173{\r
174 EFI_STATUS Status;\r
175 LIST_ENTRY *Package;\r
176 EFI_TIME TheTime;\r
177 CHAR16 *ProblemParam;\r
178 SHELL_STATUS ShellStatus;\r
179\r
180 ShellStatus = SHELL_SUCCESS;\r
181 ProblemParam = NULL;\r
182\r
183 //\r
184 // initialize the shell lib (we must be in non-auto-init...)\r
185 //\r
186 Status = ShellInitialize();\r
187 ASSERT_EFI_ERROR(Status);\r
188\r
189 //\r
190 // parse the command line\r
191 //\r
192 Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE);\r
193 if (EFI_ERROR(Status)) {\r
194 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
195 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
196 FreePool(ProblemParam);\r
197 ShellStatus = SHELL_INVALID_PARAMETER;\r
198 } else {\r
199 ASSERT(FALSE);\r
200 }\r
201 } else {\r
202 //\r
203 // check for "-?"\r
204 //\r
205 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
206 ASSERT(FALSE);\r
207 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
208 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
209 ShellStatus = SHELL_INVALID_PARAMETER;\r
210 } else {\r
211 //\r
212 // If there are 0 value parameters, then print the current date\r
213 // else If there are any value paramerers, then print error\r
214 //\r
215 if (ShellCommandLineGetRawValue(Package, 1) == NULL) {\r
216 //\r
217 // get the current date\r
218 //\r
219 Status = gRT->GetTime(&TheTime, NULL);\r
220 ASSERT_EFI_ERROR(Status);\r
221\r
222 //\r
223 // ShellPrintEx the date in SFO or regular format\r
224 //\r
225 if (ShellCommandLineGetFlag(Package, L"-sfo")) {\r
226 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);\r
227 } else {\r
228 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);\r
229 }\r
230 } else {\r
231 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
232 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
233 ShellStatus = SHELL_INVALID_PARAMETER;\r
234 } else {\r
235 //\r
236 // perform level 3 operation here.\r
237 //\r
238 ShellStatus = CheckAndSetDate(ShellCommandLineGetRawValue(Package, 1));\r
239 if (ShellStatus != SHELL_SUCCESS) {\r
240 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
241 ShellStatus = SHELL_INVALID_PARAMETER;\r
242 }\r
243 }\r
244 }\r
245 }\r
246 }\r
247 //\r
248 // free the command line package\r
249 //\r
250 ShellCommandLineFreeVarList (Package);\r
251\r
252 //\r
253 // return the status\r
254 //\r
255 return (ShellStatus);\r
256}\r
257\r
258//\r
259// Note "-tz" is invalid for this (non-interactive) version of 'time'.\r
260//\r
261STATIC CONST SHELL_PARAM_ITEM TimeParamList2[] = {\r
262 {L"-d", TypeValue},\r
263 {NULL, TypeMax}\r
264 };\r
265\r
266STATIC CONST SHELL_PARAM_ITEM TimeParamList3[] = {\r
267 {L"-d", TypeValue},\r
268 {L"-tz", TypeValue},\r
269 {NULL, TypeMax}\r
270 };\r
271\r
b54fd049 272/**\r
273 Verify that the TimeString is valid and if so set that as the current \r
274 time.\r
275\r
276 @param[in] TimeString The pointer to a string representation of the time.\r
277 @param[in] Tz The value to set for TimeZone.\r
278 @param[in] Daylight The value to set for Daylight.\r
279\r
280 @retval SHELL_INVALID_PARAMETER TimeString was NULL.\r
281 @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted.\r
282 @retval SHELL_SUCCESS The operation was successful.\r
283**/\r
a405b86d 284SHELL_STATUS\r
285EFIAPI\r
286CheckAndSetTime (\r
287 IN CONST CHAR16 *TimeString,\r
288 IN CONST INT16 Tz,\r
289 IN CONST UINT8 Daylight\r
290 )\r
291{\r
292 EFI_TIME TheTime;\r
293 EFI_STATUS Status;\r
b54fd049 294 CHAR16 *TimeStringCopy;\r
295 CHAR16 *Walker1;\r
296 CHAR16 *Walker2;\r
a405b86d 297\r
298 if (TimeString != NULL && !InternalIsTimeLikeString(TimeString, L':', 1, 2, FALSE)) {\r
299 return (SHELL_INVALID_PARAMETER);\r
300 }\r
0841f3af 301 if (((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) {\r
302 return (SHELL_INVALID_PARAMETER);\r
303 }\r
a405b86d 304\r
305 Status = gRT->GetTime(&TheTime, NULL);\r
306 ASSERT_EFI_ERROR(Status);\r
307\r
308 if (TimeString != NULL) {\r
0841f3af 309 TimeStringCopy = NULL;\r
310 TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0);\r
b54fd049 311 Walker1 = TimeStringCopy;\r
a405b86d 312 TheTime.Hour = 0xFF;\r
313 TheTime.Minute = 0xFF;\r
314\r
33c031ee 315 Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
b54fd049 316 if (Walker2 != NULL && *Walker2 == L':') {\r
317 *Walker2 = CHAR_NULL;\r
a405b86d 318 }\r
b54fd049 319 TheTime.Hour = (UINT8)ShellStrToUintn (Walker1);\r
320 if (Walker2 != NULL) {\r
321 Walker1 = Walker2 + 1;\r
322 }\r
33c031ee 323 Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
b54fd049 324 if (Walker2 != NULL && *Walker2 == L':') {\r
325 *Walker2 = CHAR_NULL;\r
326 }\r
327 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
328 TheTime.Minute = (UINT8)ShellStrToUintn (Walker1);\r
329 if (Walker2 != NULL) {\r
330 Walker1 = Walker2 + 1;\r
a405b86d 331 }\r
b54fd049 332 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
333 TheTime.Second = (UINT8)ShellStrToUintn (Walker1);\r
a405b86d 334 }\r
335 }\r
0841f3af 336 SHELL_FREE_NON_NULL(TimeStringCopy);\r
a405b86d 337 }\r
338\r
b54fd049 339\r
340 if ((Tz >= -1440 && Tz <= 1440)||(Tz == 0x7FF)) {\r
a405b86d 341 TheTime.TimeZone = Tz;\r
342 }\r
0841f3af 343\r
344 TheTime.Daylight = Daylight;\r
345\r
a405b86d 346 Status = gRT->SetTime(&TheTime);\r
347\r
348 if (!EFI_ERROR(Status)){\r
349 return (SHELL_SUCCESS);\r
350 }\r
351\r
352 return (SHELL_INVALID_PARAMETER);\r
353}\r
354\r
355/**\r
356 Function for 'time' command.\r
357\r
358 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
359 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
360**/\r
361SHELL_STATUS\r
362EFIAPI\r
363ShellCommandRunTime (\r
364 IN EFI_HANDLE ImageHandle,\r
365 IN EFI_SYSTEM_TABLE *SystemTable\r
366 )\r
367{\r
368 EFI_STATUS Status;\r
369 LIST_ENTRY *Package;\r
370 CHAR16 *Message;\r
371 EFI_TIME TheTime;\r
372 CHAR16 *ProblemParam;\r
373 SHELL_STATUS ShellStatus;\r
374 INT16 Tz;\r
375 UINT8 Daylight;\r
376 CONST CHAR16 *TempLocation;\r
377 UINTN TzMinutes;\r
378\r
379 ShellStatus = SHELL_SUCCESS;\r
380 ProblemParam = NULL;\r
381\r
382 //\r
383 // Initialize variables\r
384 //\r
385 Message = NULL;\r
386\r
387 //\r
388 // initialize the shell lib (we must be in non-auto-init...)\r
389 //\r
390 Status = ShellInitialize();\r
391 ASSERT_EFI_ERROR(Status);\r
392\r
393 //\r
394 // parse the command line\r
395 //\r
396 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
397 Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);\r
398 } else {\r
399 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
400 Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);\r
401 }\r
402 if (EFI_ERROR(Status)) {\r
403 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
404 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
405 FreePool(ProblemParam);\r
406 ShellStatus = SHELL_INVALID_PARAMETER;\r
407 } else {\r
408 ASSERT(FALSE);\r
409 }\r
410 } else {\r
411 //\r
412 // check for "-?"\r
413 //\r
414 Status = gRT->GetTime(&TheTime, NULL);\r
415 ASSERT_EFI_ERROR(Status);\r
416 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
417 ASSERT(FALSE);\r
418 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
419 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
420 ShellStatus = SHELL_INVALID_PARAMETER;\r
421 } else {\r
422 //\r
423 // If there are no parameters, then print the current time\r
424 //\r
425 if (ShellCommandLineGetRawValue(Package, 1) == NULL\r
426 && !ShellCommandLineGetFlag(Package, L"-d")\r
427 && !ShellCommandLineGetFlag(Package, L"-tz")) {\r
428 //\r
429 // ShellPrintEx the current time\r
430 //\r
431 if (TheTime.TimeZone == 2047) {\r
432 TzMinutes = 0;\r
433 } else {\r
b54fd049 434 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 435 }\r
436\r
437 ShellPrintHiiEx (\r
438 -1,\r
439 -1,\r
440 NULL,\r
441 STRING_TOKEN (STR_TIME_FORMAT),\r
442 gShellLevel2HiiHandle,\r
443 TheTime.Hour,\r
444 TheTime.Minute,\r
445 TheTime.Second,\r
446 TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 447 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 448 TzMinutes\r
449 );\r
450 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);\r
451 } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) {\r
452 if (TheTime.TimeZone == 2047) {\r
453 TzMinutes = 0;\r
454 } else {\r
b54fd049 455 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 456 }\r
457\r
458 ShellPrintHiiEx (\r
459 -1,\r
460 -1,\r
461 NULL,\r
462 STRING_TOKEN (STR_TIME_FORMAT),\r
463 gShellLevel2HiiHandle,\r
464 TheTime.Hour,\r
465 TheTime.Minute,\r
466 TheTime.Second,\r
467 TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 468 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 469 TzMinutes\r
470 );\r
471 switch (TheTime.Daylight) {\r
0841f3af 472 case 0:\r
473 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);\r
474 break;\r
a405b86d 475 case EFI_TIME_ADJUST_DAYLIGHT:\r
b54fd049 476 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);\r
a405b86d 477 break;\r
478 case EFI_TIME_IN_DAYLIGHT:\r
b54fd049 479 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);\r
480 break;\r
481 case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:\r
482 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);\r
a405b86d 483 break;\r
484 default:\r
485 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);\r
486 }\r
487 } else {\r
488 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
489 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
490 ShellStatus = SHELL_INVALID_PARAMETER;\r
491 } else {\r
492 //\r
493 // perform level 3 operation here.\r
494 //\r
495 if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {\r
496 if (TempLocation[0] == L'-') {\r
b54fd049 497 Tz = (INT16)(0 - ShellStrToUintn(++TempLocation));\r
a405b86d 498 } else {\r
b54fd049 499 Tz = (INT16)ShellStrToUintn(TempLocation);\r
a405b86d 500 }\r
501 if (!(Tz >= -1440 && Tz <= 1440) && Tz != 2047) {\r
0841f3af 502 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-tz");\r
a405b86d 503 ShellStatus = SHELL_INVALID_PARAMETER;\r
504 }\r
505 } else {\r
506 //\r
507 // intentionally out of bounds value will prevent changing it...\r
508 //\r
509 Tz = 1441;\r
510 }\r
511 TempLocation = ShellCommandLineGetValue(Package, L"-d");\r
512 if (TempLocation != NULL) {\r
b54fd049 513 Daylight = (UINT8)ShellStrToUintn(TempLocation);\r
a405b86d 514 if (Daylight != 0 && Daylight != 1 && Daylight != 3) {\r
0841f3af 515 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-d");\r
a405b86d 516 ShellStatus = SHELL_INVALID_PARAMETER;\r
517 }\r
518 } else {\r
519 //\r
520 // invalid = will not use\r
521 //\r
522 Daylight = 0xFF;\r
523 }\r
524 if (ShellStatus == SHELL_SUCCESS) {\r
525 ShellStatus = CheckAndSetTime(ShellCommandLineGetRawValue(Package, 1), Tz, Daylight);\r
526 if (ShellStatus != SHELL_SUCCESS) {\r
527 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
528 ShellStatus = SHELL_INVALID_PARAMETER;\r
529 }\r
530 }\r
531 }\r
532 }\r
533 }\r
534 }\r
535\r
536 //\r
537 // free the command line package\r
538 //\r
539 ShellCommandLineFreeVarList (Package);\r
540\r
541 //\r
542 // return the status\r
543 //\r
544 return (ShellStatus);\r
545}\r
546\r
547typedef struct {\r
548 INT16 TimeZone;\r
549 EFI_STRING_ID StringId;\r
550} TIME_ZONE_ITEM;\r
551\r
552STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList2[] = {\r
553 {L"-l", TypeFlag},\r
554 {L"-f", TypeFlag},\r
555 {NULL, TypeMax}\r
556 };\r
557STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = {\r
558 {L"-l", TypeFlag},\r
559 {L"-f", TypeFlag},\r
560 {L"-s", TypeValue},\r
561 {NULL, TypeMax}\r
562 };\r
563\r
564 STATIC CONST TIME_ZONE_ITEM TimeZoneList[] = {\r
565 {720, STRING_TOKEN (STR_TIMEZONE_M12)},\r
566 {660, STRING_TOKEN (STR_TIMEZONE_M11)},\r
567 {600, STRING_TOKEN (STR_TIMEZONE_M10)},\r
568 {540, STRING_TOKEN (STR_TIMEZONE_M9)},\r
569 {480, STRING_TOKEN (STR_TIMEZONE_M8)},\r
570 {420, STRING_TOKEN (STR_TIMEZONE_M7)},\r
571 {360, STRING_TOKEN (STR_TIMEZONE_M6)},\r
572 {300, STRING_TOKEN (STR_TIMEZONE_M5)},\r
573 {270, STRING_TOKEN (STR_TIMEZONE_M430)},\r
574 {240, STRING_TOKEN (STR_TIMEZONE_M4)},\r
575 {210, STRING_TOKEN (STR_TIMEZONE_M330)},\r
576 {180, STRING_TOKEN (STR_TIMEZONE_M3)},\r
577 {120, STRING_TOKEN (STR_TIMEZONE_M2)},\r
578 {60 , STRING_TOKEN (STR_TIMEZONE_M1)},\r
579 {0 , STRING_TOKEN (STR_TIMEZONE_0)},\r
580 {-60 , STRING_TOKEN (STR_TIMEZONE_P1)},\r
581 {-120 , STRING_TOKEN (STR_TIMEZONE_P2)},\r
582 {-180 , STRING_TOKEN (STR_TIMEZONE_P3)},\r
583 {-210 , STRING_TOKEN (STR_TIMEZONE_P330)},\r
584 {-240 , STRING_TOKEN (STR_TIMEZONE_P4)},\r
585 {-270 , STRING_TOKEN (STR_TIMEZONE_P430)},\r
586 {-300 , STRING_TOKEN (STR_TIMEZONE_P5)},\r
587 {-330 , STRING_TOKEN (STR_TIMEZONE_P530)},\r
588 {-345 , STRING_TOKEN (STR_TIMEZONE_P545)},\r
589 {-360 , STRING_TOKEN (STR_TIMEZONE_P6)},\r
590 {-390 , STRING_TOKEN (STR_TIMEZONE_P630)},\r
591 {-420 , STRING_TOKEN (STR_TIMEZONE_P7)},\r
592 {-480 , STRING_TOKEN (STR_TIMEZONE_P8)},\r
593 {-540 , STRING_TOKEN (STR_TIMEZONE_P9)},\r
594 {-570 , STRING_TOKEN (STR_TIMEZONE_P930)},\r
595 {-600 , STRING_TOKEN (STR_TIMEZONE_P10)},\r
596 {-660 , STRING_TOKEN (STR_TIMEZONE_P11)},\r
597 {-720 , STRING_TOKEN (STR_TIMEZONE_P12)},\r
598 {-780 , STRING_TOKEN (STR_TIMEZONE_P13)},\r
599 {-840 , STRING_TOKEN (STR_TIMEZONE_P14)}\r
b54fd049 600};\r
601\r
602/**\r
603 Verify that the TimeZoneString is valid and if so set that as the current \r
604 timezone.\r
a405b86d 605\r
b54fd049 606 @param[in] TimeZoneString The pointer to a string representation of the timezone.\r
607\r
608 @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL.\r
609 @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted.\r
610 @retval SHELL_SUCCESS The operation was successful.\r
611**/\r
a405b86d 612SHELL_STATUS\r
613EFIAPI\r
614CheckAndSetTimeZone (\r
615 IN CONST CHAR16 *TimeZoneString\r
616 )\r
617{\r
618 EFI_TIME TheTime;\r
619 EFI_STATUS Status;\r
b54fd049 620 CHAR16 *TimeZoneCopy;\r
621 CHAR16 *Walker;\r
622 CHAR16 *Walker2;\r
a405b86d 623 UINTN LoopVar;\r
624\r
625 if (TimeZoneString == NULL) {\r
626 return (SHELL_INVALID_PARAMETER);\r
627 }\r
628\r
629 if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) {\r
630 return (SHELL_INVALID_PARAMETER);\r
631 }\r
632\r
633 Status = gRT->GetTime(&TheTime, NULL);\r
634 ASSERT_EFI_ERROR(Status);\r
635\r
b54fd049 636 TimeZoneCopy = NULL;\r
637 TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0);\r
638 Walker = TimeZoneCopy;\r
639 Walker2 = StrStr(Walker, L":");\r
640 if (Walker2 != NULL && *Walker2 == L':') {\r
641 *Walker2 = CHAR_NULL;\r
642 }\r
a405b86d 643 if (*Walker == L'-') {\r
b54fd049 644 TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);\r
a405b86d 645 } else {\r
b54fd049 646 TheTime.TimeZone = (INT16)((ShellStrToUintn (Walker)) * -60);\r
a405b86d 647 }\r
b54fd049 648 if (Walker2 != NULL) {\r
649 Walker = Walker2 + 1;\r
a405b86d 650 }\r
651 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
652 if (TheTime.TimeZone < 0) {\r
b54fd049 653 TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));\r
a405b86d 654 } else {\r
b54fd049 655 TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));\r
a405b86d 656 }\r
657 }\r
658\r
659 Status = EFI_INVALID_PARAMETER;\r
660\r
661 for ( LoopVar = 0\r
662 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
663 ; LoopVar++\r
664 ){\r
665 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
666 Status = gRT->SetTime(&TheTime);\r
667 break;\r
668 }\r
669 }\r
670\r
b54fd049 671 FreePool(TimeZoneCopy);\r
672\r
a405b86d 673 if (!EFI_ERROR(Status)){\r
674 return (SHELL_SUCCESS);\r
675 }\r
676 return (SHELL_INVALID_PARAMETER);\r
677}\r
678\r
679\r
680/**\r
681 Function for 'timezone' command.\r
682\r
683 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
684 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
685**/\r
686SHELL_STATUS\r
687EFIAPI\r
688ShellCommandRunTimeZone (\r
689 IN EFI_HANDLE ImageHandle,\r
690 IN EFI_SYSTEM_TABLE *SystemTable\r
691 )\r
692{\r
693 //\r
694 // non interactive\r
695 //\r
696 EFI_STATUS Status;\r
697 LIST_ENTRY *Package;\r
698 CHAR16 *ProblemParam;\r
699 SHELL_STATUS ShellStatus;\r
700 UINT8 LoopVar;\r
701 EFI_TIME TheTime;\r
702 BOOLEAN Found;\r
703 UINTN TzMinutes;\r
704\r
705 ShellStatus = SHELL_SUCCESS;\r
706 ProblemParam = NULL;\r
707\r
708 //\r
709 // initialize the shell lib (we must be in non-auto-init...)\r
710 //\r
711 Status = ShellInitialize();\r
712 ASSERT_EFI_ERROR(Status);\r
713\r
714 //\r
715 // parse the command line\r
716 //\r
717 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
718 Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, FALSE);\r
719 } else {\r
720 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
721 Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, FALSE, TRUE);\r
722 }\r
723 if (EFI_ERROR(Status)) {\r
724 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
725 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
726 FreePool(ProblemParam);\r
727 ShellStatus = SHELL_INVALID_PARAMETER;\r
728 } else {\r
729 ASSERT(FALSE);\r
730 }\r
731 } else {\r
732 //\r
733 // check for "-?"\r
734 //\r
735 if (ShellCommandLineGetCount(Package) > 1) {\r
736 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
737 ShellStatus = SHELL_INVALID_PARAMETER;\r
738 } else if (ShellCommandLineGetFlag(Package, L"-?")) {\r
739 ASSERT(FALSE);\r
740 } else if (ShellCommandLineGetFlag(Package, L"-s")) {\r
741 if ((ShellCommandLineGetFlag(Package, L"-l")) || (ShellCommandLineGetFlag(Package, L"-f"))) {\r
742 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-l or -f");\r
743 ShellStatus = SHELL_INVALID_PARAMETER;\r
744 } else {\r
745 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
746 if (ShellCommandLineGetValue(Package, L"-s") == NULL) {\r
747 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-s");\r
748 ShellStatus = SHELL_INVALID_PARAMETER;\r
749 } else {\r
750 //\r
751 // Set the time zone\r
752 //\r
753 ShellStatus = CheckAndSetTimeZone(ShellCommandLineGetValue(Package, L"-s"));\r
754 if (ShellStatus != SHELL_SUCCESS) {\r
755 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetValue(Package, L"-s"));\r
756 ShellStatus = SHELL_INVALID_PARAMETER;\r
757 }\r
758 }\r
759 }\r
760 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
761 //\r
762 // Print a list of all time zones\r
763 //\r
764 for ( LoopVar = 0\r
765 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
766 ; LoopVar++\r
767 ){\r
768 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
769 }\r
770 } else {\r
771 //\r
772 // Get Current Time Zone Info\r
773 //\r
774 Status = gRT->GetTime(&TheTime, NULL);\r
775 ASSERT_EFI_ERROR(Status);\r
776\r
777 if (TheTime.TimeZone != 2047) {\r
778 Found = FALSE;\r
779 for ( LoopVar = 0\r
780 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
781 ; LoopVar++\r
782 ){\r
783 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
784 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
785 //\r
786 // Print all info about current time zone\r
787 //\r
788 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
789 } else {\r
790 //\r
791 // Print basic info only\r
792 //\r
793 if (TheTime.TimeZone == 2047) {\r
794 TzMinutes = 0;\r
795 } else {\r
b54fd049 796 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 797 }\r
798\r
799 ShellPrintHiiEx (\r
800 -1,\r
801 -1,\r
802 NULL,\r
803 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
804 gShellLevel2HiiHandle,\r
805 TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 806 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 807 TzMinutes);\r
808 }\r
809 Found = TRUE;\r
810 break;\r
811 }\r
812 }\r
813 if (!Found) {\r
814 //\r
815 // Print basic info only\r
816 //\r
817 if (TheTime.TimeZone == 2047) {\r
818 TzMinutes = 0;\r
819 } else {\r
b54fd049 820 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 821 }\r
822 ShellPrintHiiEx (\r
823 -1,\r
824 -1,\r
825 NULL,\r
826 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
827 gShellLevel2HiiHandle,\r
828 TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 829 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 830 TzMinutes);\r
831 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
832 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);\r
833 }\r
834 }\r
835 } else {\r
836 //\r
837 // TimeZone was 2047 (unknown) from GetTime()\r
838 //\r
839 }\r
840 }\r
841 }\r
842\r
843 //\r
844 // free the command line package\r
845 //\r
846 ShellCommandLineFreeVarList (Package);\r
847\r
848 return (ShellStatus);\r
849}\r