]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
ShellPkg/map: Recognize CDROM change
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Ls.c
index 0b8019516f83a53abf44e00d1f483735274fea14..7d2e15f5206b334ff79bedde2871f5f558335836 100644 (file)
@@ -2,7 +2,7 @@
   Main file for ls shell level 2 function.\r
 \r
   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include "UefiShellLevel2CommandsLib.h"\r
 #include <Guid/FileSystemInfo.h>\r
 \r
+UINTN     mDayOfMonth[] = {31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30};\r
+\r
 /**\r
   print out the standard format output volume entry.\r
 \r
   @param[in] TheList           a list of files from the volume.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 PrintSfoVolumeInfoTableEntry(\r
   IN CONST EFI_SHELL_FILE_INFO *TheList\r
   )\r
@@ -152,7 +153,6 @@ PrintSfoVolumeInfoTableEntry(
 \r
 **/\r
 VOID\r
-EFIAPI\r
 PrintFileInformation(\r
   IN CONST BOOLEAN              Sfo, \r
   IN CONST EFI_SHELL_FILE_INFO  *TheNode, \r
@@ -263,7 +263,6 @@ PrintFileInformation(
   @param[in] Path           String with starting path.\r
 **/\r
 VOID\r
-EFIAPI\r
 PrintNonSfoHeader(\r
   IN CONST CHAR16 *Path\r
   )\r
@@ -300,7 +299,6 @@ PrintNonSfoHeader(
   @param[in] Dirs             The number of directories.\r
 **/\r
 VOID\r
-EFIAPI\r
 PrintNonSfoFooter(\r
   IN UINT64                     Files, \r
   IN UINT64                     Size, \r
@@ -322,6 +320,96 @@ PrintNonSfoFooter(
    );\r
 }\r
 \r
+/**\r
+  Change the file time to local time based on the timezone.\r
+\r
+  @param[in] Time               The file time.\r
+  @param[in] LocalTimeZone      Local time zone.\r
+**/\r
+VOID\r
+FileTimeToLocalTime (\r
+  IN EFI_TIME             *Time,\r
+  IN INT16                LocalTimeZone\r
+  )\r
+{\r
+  INTN                    MinuteDiff;\r
+  INTN                    TempMinute;\r
+  INTN                    HourNumberOfTempMinute;\r
+  INTN                    TempHour;\r
+  INTN                    DayNumberOfTempHour;\r
+  INTN                    TempDay;\r
+  INTN                    MonthNumberOfTempDay;\r
+  INTN                    TempMonth;\r
+  INTN                    YearNumberOfTempMonth;\r
+  INTN                    MonthRecord;\r
+\r
+  ASSERT ((Time->TimeZone >= -1440) && (Time->TimeZone <=1440));\r
+  ASSERT ((LocalTimeZone >= -1440) && (LocalTimeZone <=1440));\r
+  ASSERT ((Time->Month >= 1) && (Time->Month <= 12));\r
+\r
+  if(Time->TimeZone == LocalTimeZone) {\r
+    //\r
+    //if the file timezone is equal to the local timezone, there is no need to adjust the file time.\r
+    //\r
+    return;\r
+  }\r
+\r
+  if((Time->Year % 4 == 0 && Time->Year / 100 != 0)||(Time->Year % 400 == 0)) {\r
+    //\r
+    // Day in February of leap year is 29.\r
+    //\r
+    mDayOfMonth[1] = 29;\r
+  }\r
+\r
+  MinuteDiff = Time->TimeZone - LocalTimeZone;\r
+  TempMinute = Time->Minute + MinuteDiff;\r
+\r
+  //\r
+  // Calculate Time->Minute\r
+  // TempHour will be used to calculate Time->Hour\r
+  //\r
+  HourNumberOfTempMinute = TempMinute / 60;\r
+  if(TempMinute < 0) {\r
+    HourNumberOfTempMinute --; \r
+  }\r
+  TempHour = Time->Hour + HourNumberOfTempMinute;\r
+  Time->Minute = (UINT8)(TempMinute - 60 * HourNumberOfTempMinute);\r
+\r
+  //\r
+  // Calculate Time->Hour\r
+  // TempDay will be used to calculate Time->Day\r
+  //\r
+  DayNumberOfTempHour = TempHour / 24 ;\r
+  if(TempHour < 0){\r
+    DayNumberOfTempHour--;\r
+  }\r
+  TempDay = Time->Day + DayNumberOfTempHour;\r
+  Time->Hour = (UINT8)(TempHour - 24 * DayNumberOfTempHour);\r
+\r
+  //\r
+  // Calculate Time->Day\r
+  // TempMonth will be used to calculate Time->Month\r
+  //\r
+  MonthNumberOfTempDay = (TempDay - 1) / (INTN)mDayOfMonth[Time->Month - 1];\r
+  MonthRecord = (INTN)(Time->Month) ;\r
+  if(TempDay - 1 < 0){\r
+    MonthNumberOfTempDay -- ;\r
+    MonthRecord -- ;\r
+  }\r
+  TempMonth = Time->Month + MonthNumberOfTempDay;\r
+  Time->Day = (UINT8)(TempDay - (INTN)mDayOfMonth[(MonthRecord - 1 + 12) % 12] * MonthNumberOfTempDay);\r
+\r
+  //\r
+  // Calculate Time->Month, Time->Year\r
+  //\r
+  YearNumberOfTempMonth = (TempMonth - 1) / 12;\r
+  if(TempMonth - 1 < 0){\r
+    YearNumberOfTempMonth --;\r
+  }\r
+  Time->Month = (UINT8)(TempMonth - 12 * (YearNumberOfTempMonth));\r
+  Time->Year = (UINT16)(Time->Year + YearNumberOfTempMonth);\r
+}\r
+\r
 /**\r
   print out the list of files and directories from the LS command\r
 \r
@@ -339,7 +427,6 @@ PrintNonSfoFooter(
   @retval SHELL_SUCCESS     the printing was sucessful.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 PrintLsOutput(\r
   IN CONST BOOLEAN Rec,\r
   IN CONST UINT64  Attribs,\r
@@ -362,6 +449,7 @@ PrintLsOutput(
   CHAR16                *CorrectedPath;\r
   BOOLEAN               FoundOne;\r
   BOOLEAN               HeaderPrinted;\r
+  EFI_TIME              LocalTime;\r
 \r
   HeaderPrinted = FALSE;\r
   FileCount     = 0;\r
@@ -413,6 +501,29 @@ PrintLsOutput(
         break;\r
       }\r
       ASSERT(Node != NULL);\r
+\r
+      //\r
+      // Change the file time to local time.\r
+      //\r
+      Status = gRT->GetTime(&LocalTime, NULL);\r
+      if (!EFI_ERROR (Status)) {\r
+        if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&\r
+            (Node->Info->CreateTime.Month >= 1 && Node->Info->CreateTime.Month <= 12)) {\r
+          //\r
+          // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens.\r
+          //\r
+          FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone);\r
+        }\r
+        if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&\r
+            (Node->Info->LastAccessTime.Month >= 1 && Node->Info->LastAccessTime.Month <= 12)) {\r
+          FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone);\r
+        }\r
+        if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&\r
+            (Node->Info->ModificationTime.Month >= 1 && Node->Info->ModificationTime.Month <= 12)) {\r
+          FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone);\r
+        }\r
+      }\r
+\r
       if (LongestPath < StrSize(Node->FullName)) {\r
         LongestPath = StrSize(Node->FullName);\r
       }\r
@@ -709,6 +820,11 @@ ShellCommandRunLs (
               // must split off the search part that applies to files from the end of the directory part\r
               //\r
               StrnCatGrow(&SearchString, NULL, FullPath, 0);\r
+              if (SearchString == NULL) {\r
+                FreePool (FullPath);\r
+                ShellCommandLineFreeVarList (Package);\r
+                return SHELL_OUT_OF_RESOURCES;\r
+              }\r
               PathRemoveLastItem (FullPath);\r
               CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath)));\r
             }\r