]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c
Cd - add more input verification.
[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
127 Walker1 = StrStr(Walker, L"/");\r
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
136 Walker1 = StrStr(Walker, L"/");\r
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
301\r
302 Status = gRT->GetTime(&TheTime, NULL);\r
303 ASSERT_EFI_ERROR(Status);\r
b54fd049 304 TimeStringCopy = NULL;\r
305 TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0);\r
a405b86d 306\r
307 if (TimeString != NULL) {\r
b54fd049 308 Walker1 = TimeStringCopy;\r
a405b86d 309 TheTime.Hour = 0xFF;\r
310 TheTime.Minute = 0xFF;\r
311\r
b54fd049 312 Walker2 = StrStr(Walker1, L":");\r
313 if (Walker2 != NULL && *Walker2 == L':') {\r
314 *Walker2 = CHAR_NULL;\r
a405b86d 315 }\r
b54fd049 316 TheTime.Hour = (UINT8)ShellStrToUintn (Walker1);\r
317 if (Walker2 != NULL) {\r
318 Walker1 = Walker2 + 1;\r
319 }\r
320 Walker2 = StrStr(Walker1, L":");\r
321 if (Walker2 != NULL && *Walker2 == L':') {\r
322 *Walker2 = CHAR_NULL;\r
323 }\r
324 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
325 TheTime.Minute = (UINT8)ShellStrToUintn (Walker1);\r
326 if (Walker2 != NULL) {\r
327 Walker1 = Walker2 + 1;\r
a405b86d 328 }\r
b54fd049 329 if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
330 TheTime.Second = (UINT8)ShellStrToUintn (Walker1);\r
a405b86d 331 }\r
332 }\r
333 }\r
334\r
b54fd049 335 FreePool(TimeStringCopy);\r
336\r
337 if ((Tz >= -1440 && Tz <= 1440)||(Tz == 0x7FF)) {\r
a405b86d 338 TheTime.TimeZone = Tz;\r
339 }\r
340 if (Daylight <= 3 && Daylight != 2) {\r
341 TheTime.Daylight = Daylight;\r
342 }\r
343 Status = gRT->SetTime(&TheTime);\r
344\r
345 if (!EFI_ERROR(Status)){\r
346 return (SHELL_SUCCESS);\r
347 }\r
348\r
349 return (SHELL_INVALID_PARAMETER);\r
350}\r
351\r
352/**\r
353 Function for 'time' command.\r
354\r
355 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
356 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
357**/\r
358SHELL_STATUS\r
359EFIAPI\r
360ShellCommandRunTime (\r
361 IN EFI_HANDLE ImageHandle,\r
362 IN EFI_SYSTEM_TABLE *SystemTable\r
363 )\r
364{\r
365 EFI_STATUS Status;\r
366 LIST_ENTRY *Package;\r
367 CHAR16 *Message;\r
368 EFI_TIME TheTime;\r
369 CHAR16 *ProblemParam;\r
370 SHELL_STATUS ShellStatus;\r
371 INT16 Tz;\r
372 UINT8 Daylight;\r
373 CONST CHAR16 *TempLocation;\r
374 UINTN TzMinutes;\r
375\r
376 ShellStatus = SHELL_SUCCESS;\r
377 ProblemParam = NULL;\r
378\r
379 //\r
380 // Initialize variables\r
381 //\r
382 Message = NULL;\r
383\r
384 //\r
385 // initialize the shell lib (we must be in non-auto-init...)\r
386 //\r
387 Status = ShellInitialize();\r
388 ASSERT_EFI_ERROR(Status);\r
389\r
390 //\r
391 // parse the command line\r
392 //\r
393 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
394 Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);\r
395 } else {\r
396 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
397 Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);\r
398 }\r
399 if (EFI_ERROR(Status)) {\r
400 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
401 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
402 FreePool(ProblemParam);\r
403 ShellStatus = SHELL_INVALID_PARAMETER;\r
404 } else {\r
405 ASSERT(FALSE);\r
406 }\r
407 } else {\r
408 //\r
409 // check for "-?"\r
410 //\r
411 Status = gRT->GetTime(&TheTime, NULL);\r
412 ASSERT_EFI_ERROR(Status);\r
413 if (ShellCommandLineGetFlag(Package, L"-?")) {\r
414 ASSERT(FALSE);\r
415 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {\r
416 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
417 ShellStatus = SHELL_INVALID_PARAMETER;\r
418 } else {\r
419 //\r
420 // If there are no parameters, then print the current time\r
421 //\r
422 if (ShellCommandLineGetRawValue(Package, 1) == NULL\r
423 && !ShellCommandLineGetFlag(Package, L"-d")\r
424 && !ShellCommandLineGetFlag(Package, L"-tz")) {\r
425 //\r
426 // ShellPrintEx the current time\r
427 //\r
428 if (TheTime.TimeZone == 2047) {\r
429 TzMinutes = 0;\r
430 } else {\r
b54fd049 431 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 432 }\r
433\r
434 ShellPrintHiiEx (\r
435 -1,\r
436 -1,\r
437 NULL,\r
438 STRING_TOKEN (STR_TIME_FORMAT),\r
439 gShellLevel2HiiHandle,\r
440 TheTime.Hour,\r
441 TheTime.Minute,\r
442 TheTime.Second,\r
443 TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 444 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 445 TzMinutes\r
446 );\r
447 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);\r
448 } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) {\r
449 if (TheTime.TimeZone == 2047) {\r
450 TzMinutes = 0;\r
451 } else {\r
b54fd049 452 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 453 }\r
454\r
455 ShellPrintHiiEx (\r
456 -1,\r
457 -1,\r
458 NULL,\r
459 STRING_TOKEN (STR_TIME_FORMAT),\r
460 gShellLevel2HiiHandle,\r
461 TheTime.Hour,\r
462 TheTime.Minute,\r
463 TheTime.Second,\r
464 TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 465 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 466 TzMinutes\r
467 );\r
468 switch (TheTime.Daylight) {\r
a405b86d 469 case EFI_TIME_ADJUST_DAYLIGHT:\r
b54fd049 470 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);\r
a405b86d 471 break;\r
472 case EFI_TIME_IN_DAYLIGHT:\r
b54fd049 473 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);\r
474 break;\r
475 case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:\r
476 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);\r
a405b86d 477 break;\r
478 default:\r
479 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);\r
480 }\r
481 } else {\r
482 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
483 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
484 ShellStatus = SHELL_INVALID_PARAMETER;\r
485 } else {\r
486 //\r
487 // perform level 3 operation here.\r
488 //\r
489 if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {\r
490 if (TempLocation[0] == L'-') {\r
b54fd049 491 Tz = (INT16)(0 - ShellStrToUintn(++TempLocation));\r
a405b86d 492 } else {\r
b54fd049 493 Tz = (INT16)ShellStrToUintn(TempLocation);\r
a405b86d 494 }\r
495 if (!(Tz >= -1440 && Tz <= 1440) && Tz != 2047) {\r
496 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-d");\r
497 ShellStatus = SHELL_INVALID_PARAMETER;\r
498 }\r
499 } else {\r
500 //\r
501 // intentionally out of bounds value will prevent changing it...\r
502 //\r
503 Tz = 1441;\r
504 }\r
505 TempLocation = ShellCommandLineGetValue(Package, L"-d");\r
506 if (TempLocation != NULL) {\r
b54fd049 507 Daylight = (UINT8)ShellStrToUintn(TempLocation);\r
a405b86d 508 if (Daylight != 0 && Daylight != 1 && Daylight != 3) {\r
509 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-d");\r
510 ShellStatus = SHELL_INVALID_PARAMETER;\r
511 }\r
512 } else {\r
513 //\r
514 // invalid = will not use\r
515 //\r
516 Daylight = 0xFF;\r
517 }\r
518 if (ShellStatus == SHELL_SUCCESS) {\r
519 ShellStatus = CheckAndSetTime(ShellCommandLineGetRawValue(Package, 1), Tz, Daylight);\r
520 if (ShellStatus != SHELL_SUCCESS) {\r
521 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));\r
522 ShellStatus = SHELL_INVALID_PARAMETER;\r
523 }\r
524 }\r
525 }\r
526 }\r
527 }\r
528 }\r
529\r
530 //\r
531 // free the command line package\r
532 //\r
533 ShellCommandLineFreeVarList (Package);\r
534\r
535 //\r
536 // return the status\r
537 //\r
538 return (ShellStatus);\r
539}\r
540\r
541typedef struct {\r
542 INT16 TimeZone;\r
543 EFI_STRING_ID StringId;\r
544} TIME_ZONE_ITEM;\r
545\r
546STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList2[] = {\r
547 {L"-l", TypeFlag},\r
548 {L"-f", TypeFlag},\r
549 {NULL, TypeMax}\r
550 };\r
551STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = {\r
552 {L"-l", TypeFlag},\r
553 {L"-f", TypeFlag},\r
554 {L"-s", TypeValue},\r
555 {NULL, TypeMax}\r
556 };\r
557\r
558 STATIC CONST TIME_ZONE_ITEM TimeZoneList[] = {\r
559 {720, STRING_TOKEN (STR_TIMEZONE_M12)},\r
560 {660, STRING_TOKEN (STR_TIMEZONE_M11)},\r
561 {600, STRING_TOKEN (STR_TIMEZONE_M10)},\r
562 {540, STRING_TOKEN (STR_TIMEZONE_M9)},\r
563 {480, STRING_TOKEN (STR_TIMEZONE_M8)},\r
564 {420, STRING_TOKEN (STR_TIMEZONE_M7)},\r
565 {360, STRING_TOKEN (STR_TIMEZONE_M6)},\r
566 {300, STRING_TOKEN (STR_TIMEZONE_M5)},\r
567 {270, STRING_TOKEN (STR_TIMEZONE_M430)},\r
568 {240, STRING_TOKEN (STR_TIMEZONE_M4)},\r
569 {210, STRING_TOKEN (STR_TIMEZONE_M330)},\r
570 {180, STRING_TOKEN (STR_TIMEZONE_M3)},\r
571 {120, STRING_TOKEN (STR_TIMEZONE_M2)},\r
572 {60 , STRING_TOKEN (STR_TIMEZONE_M1)},\r
573 {0 , STRING_TOKEN (STR_TIMEZONE_0)},\r
574 {-60 , STRING_TOKEN (STR_TIMEZONE_P1)},\r
575 {-120 , STRING_TOKEN (STR_TIMEZONE_P2)},\r
576 {-180 , STRING_TOKEN (STR_TIMEZONE_P3)},\r
577 {-210 , STRING_TOKEN (STR_TIMEZONE_P330)},\r
578 {-240 , STRING_TOKEN (STR_TIMEZONE_P4)},\r
579 {-270 , STRING_TOKEN (STR_TIMEZONE_P430)},\r
580 {-300 , STRING_TOKEN (STR_TIMEZONE_P5)},\r
581 {-330 , STRING_TOKEN (STR_TIMEZONE_P530)},\r
582 {-345 , STRING_TOKEN (STR_TIMEZONE_P545)},\r
583 {-360 , STRING_TOKEN (STR_TIMEZONE_P6)},\r
584 {-390 , STRING_TOKEN (STR_TIMEZONE_P630)},\r
585 {-420 , STRING_TOKEN (STR_TIMEZONE_P7)},\r
586 {-480 , STRING_TOKEN (STR_TIMEZONE_P8)},\r
587 {-540 , STRING_TOKEN (STR_TIMEZONE_P9)},\r
588 {-570 , STRING_TOKEN (STR_TIMEZONE_P930)},\r
589 {-600 , STRING_TOKEN (STR_TIMEZONE_P10)},\r
590 {-660 , STRING_TOKEN (STR_TIMEZONE_P11)},\r
591 {-720 , STRING_TOKEN (STR_TIMEZONE_P12)},\r
592 {-780 , STRING_TOKEN (STR_TIMEZONE_P13)},\r
593 {-840 , STRING_TOKEN (STR_TIMEZONE_P14)}\r
b54fd049 594};\r
595\r
596/**\r
597 Verify that the TimeZoneString is valid and if so set that as the current \r
598 timezone.\r
a405b86d 599\r
b54fd049 600 @param[in] TimeZoneString The pointer to a string representation of the timezone.\r
601\r
602 @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL.\r
603 @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted.\r
604 @retval SHELL_SUCCESS The operation was successful.\r
605**/\r
a405b86d 606SHELL_STATUS\r
607EFIAPI\r
608CheckAndSetTimeZone (\r
609 IN CONST CHAR16 *TimeZoneString\r
610 )\r
611{\r
612 EFI_TIME TheTime;\r
613 EFI_STATUS Status;\r
b54fd049 614 CHAR16 *TimeZoneCopy;\r
615 CHAR16 *Walker;\r
616 CHAR16 *Walker2;\r
a405b86d 617 UINTN LoopVar;\r
618\r
619 if (TimeZoneString == NULL) {\r
620 return (SHELL_INVALID_PARAMETER);\r
621 }\r
622\r
623 if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) {\r
624 return (SHELL_INVALID_PARAMETER);\r
625 }\r
626\r
627 Status = gRT->GetTime(&TheTime, NULL);\r
628 ASSERT_EFI_ERROR(Status);\r
629\r
b54fd049 630 TimeZoneCopy = NULL;\r
631 TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0);\r
632 Walker = TimeZoneCopy;\r
633 Walker2 = StrStr(Walker, L":");\r
634 if (Walker2 != NULL && *Walker2 == L':') {\r
635 *Walker2 = CHAR_NULL;\r
636 }\r
a405b86d 637 if (*Walker == L'-') {\r
b54fd049 638 TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);\r
a405b86d 639 } else {\r
b54fd049 640 TheTime.TimeZone = (INT16)((ShellStrToUintn (Walker)) * -60);\r
a405b86d 641 }\r
b54fd049 642 if (Walker2 != NULL) {\r
643 Walker = Walker2 + 1;\r
a405b86d 644 }\r
645 if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
646 if (TheTime.TimeZone < 0) {\r
b54fd049 647 TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));\r
a405b86d 648 } else {\r
b54fd049 649 TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));\r
a405b86d 650 }\r
651 }\r
652\r
653 Status = EFI_INVALID_PARAMETER;\r
654\r
655 for ( LoopVar = 0\r
656 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
657 ; LoopVar++\r
658 ){\r
659 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
660 Status = gRT->SetTime(&TheTime);\r
661 break;\r
662 }\r
663 }\r
664\r
b54fd049 665 FreePool(TimeZoneCopy);\r
666\r
a405b86d 667 if (!EFI_ERROR(Status)){\r
668 return (SHELL_SUCCESS);\r
669 }\r
670 return (SHELL_INVALID_PARAMETER);\r
671}\r
672\r
673\r
674/**\r
675 Function for 'timezone' command.\r
676\r
677 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
678 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
679**/\r
680SHELL_STATUS\r
681EFIAPI\r
682ShellCommandRunTimeZone (\r
683 IN EFI_HANDLE ImageHandle,\r
684 IN EFI_SYSTEM_TABLE *SystemTable\r
685 )\r
686{\r
687 //\r
688 // non interactive\r
689 //\r
690 EFI_STATUS Status;\r
691 LIST_ENTRY *Package;\r
692 CHAR16 *ProblemParam;\r
693 SHELL_STATUS ShellStatus;\r
694 UINT8 LoopVar;\r
695 EFI_TIME TheTime;\r
696 BOOLEAN Found;\r
697 UINTN TzMinutes;\r
698\r
699 ShellStatus = SHELL_SUCCESS;\r
700 ProblemParam = NULL;\r
701\r
702 //\r
703 // initialize the shell lib (we must be in non-auto-init...)\r
704 //\r
705 Status = ShellInitialize();\r
706 ASSERT_EFI_ERROR(Status);\r
707\r
708 //\r
709 // parse the command line\r
710 //\r
711 if (PcdGet8(PcdShellSupportLevel) == 2) {\r
712 Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, FALSE);\r
713 } else {\r
714 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
715 Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, FALSE, TRUE);\r
716 }\r
717 if (EFI_ERROR(Status)) {\r
718 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
719 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);\r
720 FreePool(ProblemParam);\r
721 ShellStatus = SHELL_INVALID_PARAMETER;\r
722 } else {\r
723 ASSERT(FALSE);\r
724 }\r
725 } else {\r
726 //\r
727 // check for "-?"\r
728 //\r
729 if (ShellCommandLineGetCount(Package) > 1) {\r
730 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);\r
731 ShellStatus = SHELL_INVALID_PARAMETER;\r
732 } else if (ShellCommandLineGetFlag(Package, L"-?")) {\r
733 ASSERT(FALSE);\r
734 } else if (ShellCommandLineGetFlag(Package, L"-s")) {\r
735 if ((ShellCommandLineGetFlag(Package, L"-l")) || (ShellCommandLineGetFlag(Package, L"-f"))) {\r
736 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-l or -f");\r
737 ShellStatus = SHELL_INVALID_PARAMETER;\r
738 } else {\r
739 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);\r
740 if (ShellCommandLineGetValue(Package, L"-s") == NULL) {\r
741 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-s");\r
742 ShellStatus = SHELL_INVALID_PARAMETER;\r
743 } else {\r
744 //\r
745 // Set the time zone\r
746 //\r
747 ShellStatus = CheckAndSetTimeZone(ShellCommandLineGetValue(Package, L"-s"));\r
748 if (ShellStatus != SHELL_SUCCESS) {\r
749 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetValue(Package, L"-s"));\r
750 ShellStatus = SHELL_INVALID_PARAMETER;\r
751 }\r
752 }\r
753 }\r
754 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
755 //\r
756 // Print a list of all time zones\r
757 //\r
758 for ( LoopVar = 0\r
759 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
760 ; LoopVar++\r
761 ){\r
762 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
763 }\r
764 } else {\r
765 //\r
766 // Get Current Time Zone Info\r
767 //\r
768 Status = gRT->GetTime(&TheTime, NULL);\r
769 ASSERT_EFI_ERROR(Status);\r
770\r
771 if (TheTime.TimeZone != 2047) {\r
772 Found = FALSE;\r
773 for ( LoopVar = 0\r
774 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])\r
775 ; LoopVar++\r
776 ){\r
777 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {\r
778 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
779 //\r
780 // Print all info about current time zone\r
781 //\r
782 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);\r
783 } else {\r
784 //\r
785 // Print basic info only\r
786 //\r
787 if (TheTime.TimeZone == 2047) {\r
788 TzMinutes = 0;\r
789 } else {\r
b54fd049 790 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 791 }\r
792\r
793 ShellPrintHiiEx (\r
794 -1,\r
795 -1,\r
796 NULL,\r
797 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
798 gShellLevel2HiiHandle,\r
799 TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 800 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 801 TzMinutes);\r
802 }\r
803 Found = TRUE;\r
804 break;\r
805 }\r
806 }\r
807 if (!Found) {\r
808 //\r
809 // Print basic info only\r
810 //\r
811 if (TheTime.TimeZone == 2047) {\r
812 TzMinutes = 0;\r
813 } else {\r
b54fd049 814 TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
a405b86d 815 }\r
816 ShellPrintHiiEx (\r
817 -1,\r
818 -1,\r
819 NULL,\r
820 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
821 gShellLevel2HiiHandle,\r
822 TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
b54fd049 823 TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
a405b86d 824 TzMinutes);\r
825 if (ShellCommandLineGetFlag(Package, L"-f")) {\r
826 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);\r
827 }\r
828 }\r
829 } else {\r
830 //\r
831 // TimeZone was 2047 (unknown) from GetTime()\r
832 //\r
833 }\r
834 }\r
835 }\r
836\r
837 //\r
838 // free the command line package\r
839 //\r
840 ShellCommandLineFreeVarList (Package);\r
841\r
842 return (ShellStatus);\r
843}\r