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