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