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