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