]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c
ShellPkg: Verify memory allocations without ASSERT.
[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 ASSERT_EFI_ERROR(Status);
646
647 TimeZoneCopy = NULL;
648 TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0);
649 Walker = TimeZoneCopy;
650 Walker2 = StrStr(Walker, L":");
651 if (Walker2 != NULL && *Walker2 == L':') {
652 *Walker2 = CHAR_NULL;
653 }
654 if (*Walker == L'-') {
655 TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);
656 } else {
657 TheTime.TimeZone = (INT16)((ShellStrToUintn (Walker)) * -60);
658 }
659 if (Walker2 != NULL) {
660 Walker = Walker2 + 1;
661 }
662 if (Walker != NULL && Walker[0] != CHAR_NULL) {
663 if (TheTime.TimeZone < 0) {
664 TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));
665 } else {
666 TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));
667 }
668 }
669
670 Status = EFI_INVALID_PARAMETER;
671
672 for ( LoopVar = 0
673 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])
674 ; LoopVar++
675 ){
676 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
677 Status = gRT->SetTime(&TheTime);
678 break;
679 }
680 }
681
682 FreePool(TimeZoneCopy);
683
684 if (!EFI_ERROR(Status)){
685 return (SHELL_SUCCESS);
686 }
687 return (SHELL_INVALID_PARAMETER);
688 }
689
690
691 /**
692 Function for 'timezone' command.
693
694 @param[in] ImageHandle Handle to the Image (NULL if Internal).
695 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
696 **/
697 SHELL_STATUS
698 EFIAPI
699 ShellCommandRunTimeZone (
700 IN EFI_HANDLE ImageHandle,
701 IN EFI_SYSTEM_TABLE *SystemTable
702 )
703 {
704 //
705 // non interactive
706 //
707 EFI_STATUS Status;
708 LIST_ENTRY *Package;
709 CHAR16 *ProblemParam;
710 SHELL_STATUS ShellStatus;
711 UINT8 LoopVar;
712 EFI_TIME TheTime;
713 BOOLEAN Found;
714 UINTN TzMinutes;
715
716 ShellStatus = SHELL_SUCCESS;
717 ProblemParam = NULL;
718
719 //
720 // initialize the shell lib (we must be in non-auto-init...)
721 //
722 Status = ShellInitialize();
723 ASSERT_EFI_ERROR(Status);
724
725 //
726 // parse the command line
727 //
728 if (PcdGet8(PcdShellSupportLevel) == 2) {
729 Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, FALSE);
730 } else {
731 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
732 Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, FALSE, TRUE);
733 }
734 if (EFI_ERROR(Status)) {
735 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
736 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
737 FreePool(ProblemParam);
738 ShellStatus = SHELL_INVALID_PARAMETER;
739 } else {
740 ASSERT(FALSE);
741 }
742 } else {
743 //
744 // check for "-?"
745 //
746 if (ShellCommandLineGetCount(Package) > 1) {
747 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
748 ShellStatus = SHELL_INVALID_PARAMETER;
749 } else if (ShellCommandLineGetFlag(Package, L"-?")) {
750 ASSERT(FALSE);
751 } else if (ShellCommandLineGetFlag(Package, L"-s")) {
752 if ((ShellCommandLineGetFlag(Package, L"-l")) || (ShellCommandLineGetFlag(Package, L"-f"))) {
753 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-l or -f");
754 ShellStatus = SHELL_INVALID_PARAMETER;
755 } else {
756 ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
757 if (ShellCommandLineGetValue(Package, L"-s") == NULL) {
758 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-s");
759 ShellStatus = SHELL_INVALID_PARAMETER;
760 } else {
761 //
762 // Set the time zone
763 //
764 ShellStatus = CheckAndSetTimeZone(ShellCommandLineGetValue(Package, L"-s"));
765 if (ShellStatus != SHELL_SUCCESS) {
766 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetValue(Package, L"-s"));
767 ShellStatus = SHELL_INVALID_PARAMETER;
768 }
769 }
770 }
771 } else if (ShellCommandLineGetFlag(Package, L"-l")) {
772 //
773 // Print a list of all time zones
774 //
775 for ( LoopVar = 0
776 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])
777 ; LoopVar++
778 ){
779 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
780 }
781 } else {
782 //
783 // Get Current Time Zone Info
784 //
785 Status = gRT->GetTime(&TheTime, NULL);
786 ASSERT_EFI_ERROR(Status);
787
788 if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
789 Found = FALSE;
790 for ( LoopVar = 0
791 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])
792 ; LoopVar++
793 ){
794 if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
795 if (ShellCommandLineGetFlag(Package, L"-f")) {
796 //
797 // Print all info about current time zone
798 //
799 ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
800 } else {
801 //
802 // Print basic info only
803 //
804 if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
805 TzMinutes = 0;
806 } else {
807 TzMinutes = (ABS(TheTime.TimeZone)) % 60;
808 }
809
810 ShellPrintHiiEx (
811 -1,
812 -1,
813 NULL,
814 STRING_TOKEN(STR_TIMEZONE_SIMPLE),
815 gShellLevel2HiiHandle,
816 TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"),
817 TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
818 TzMinutes);
819 }
820 Found = TRUE;
821 break;
822 }
823 }
824 if (!Found) {
825 //
826 // Print basic info only
827 //
828 if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
829 TzMinutes = 0;
830 } else {
831 TzMinutes = (ABS(TheTime.TimeZone)) % 60;
832 }
833 ShellPrintHiiEx (
834 -1,
835 -1,
836 NULL,
837 STRING_TOKEN(STR_TIMEZONE_SIMPLE),
838 gShellLevel2HiiHandle,
839 TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"),
840 TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
841 TzMinutes);
842 if (ShellCommandLineGetFlag(Package, L"-f")) {
843 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);
844 }
845 }
846 } else {
847 //
848 // TimeZone was EFI_UNSPECIFIED_TIMEZONE (unknown) from GetTime()
849 //
850 }
851 }
852 }
853
854 //
855 // free the command line package
856 //
857 ShellCommandLineFreeVarList (Package);
858
859 return (ShellStatus);
860 }