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