/** @file
  Main file for ls shell level 2 function.

  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellLevel2CommandsLib.h"
#include <Guid/FileSystemInfo.h>

UINTN  mDayOfMonth[] = { 31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30 };

/**
  print out the list of files and directories from the LS command

  @param[in] Rec            TRUE to automatically recurse into each found directory
                            FALSE to only list the specified directory.
  @param[in] Attribs        List of required Attribute for display.
                            If 0 then all non-system and non-hidden files will be printed.
  @param[in] Sfo            TRUE to use Standard Format Output, FALSE otherwise
  @param[in] RootPath       String with starting path to search in.
  @param[in] SearchString   String with search string.
  @param[in] Found          Set to TRUE, if anyone were found.
  @param[in] Count          The count of bits enabled in Attribs.
  @param[in] ListUnfiltered TRUE to request listing the directory contents
                            unfiltered.

  @retval SHELL_SUCCESS     the printing was successful.
**/
STATIC
SHELL_STATUS
PrintLsOutput (
  IN CONST BOOLEAN  Rec,
  IN CONST UINT64   Attribs,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR16   *RootPath,
  IN CONST CHAR16   *SearchString,
  IN       BOOLEAN  *Found,
  IN CONST UINTN    Count,
  IN CONST BOOLEAN  ListUnfiltered
  );

/**
  print out the standard format output volume entry.

  @param[in] TheList           a list of files from the volume.
**/
EFI_STATUS
PrintSfoVolumeInfoTableEntry (
  IN CONST EFI_SHELL_FILE_INFO  *TheList
  )
{
  EFI_STATUS            Status;
  EFI_SHELL_FILE_INFO   *Node;
  CHAR16                *DirectoryName;
  EFI_FILE_SYSTEM_INFO  *SysInfo;
  UINTN                 SysInfoSize;
  SHELL_FILE_HANDLE     ShellFileHandle;
  EFI_FILE_PROTOCOL     *EfiFpHandle;

  //
  // Get the first valid handle (directories)
  //
  for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link)
        ; !IsNull (&TheList->Link, &Node->Link) && Node->Handle == NULL
        ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&TheList->Link, &Node->Link)
        )
  {
  }

  if (Node->Handle == NULL) {
    DirectoryName = GetFullyQualifiedPath (((EFI_SHELL_FILE_INFO *)GetFirstNode (&TheList->Link))->FullName);
    if (DirectoryName == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    //
    // We need to open something up to get system information
    //
    Status = gEfiShellProtocol->OpenFileByName (
                                  DirectoryName,
                                  &ShellFileHandle,
                                  EFI_FILE_MODE_READ
                                  );

    ASSERT_EFI_ERROR (Status);
    FreePool (DirectoryName);

    //
    // Get the Volume Info from ShellFileHandle
    //
    SysInfo     = NULL;
    SysInfoSize = 0;
    EfiFpHandle = ConvertShellHandleToEfiFileProtocol (ShellFileHandle);
    Status      = EfiFpHandle->GetInfo (
                                 EfiFpHandle,
                                 &gEfiFileSystemInfoGuid,
                                 &SysInfoSize,
                                 SysInfo
                                 );

    if (Status == EFI_BUFFER_TOO_SMALL) {
      SysInfo = AllocateZeroPool (SysInfoSize);
      if (SysInfo == NULL) {
        gEfiShellProtocol->CloseFile (ShellFileHandle);
        return (EFI_OUT_OF_RESOURCES);
      }

      Status = EfiFpHandle->GetInfo (
                              EfiFpHandle,
                              &gEfiFileSystemInfoGuid,
                              &SysInfoSize,
                              SysInfo
                              );
    }

    ASSERT_EFI_ERROR (Status);

    gEfiShellProtocol->CloseFile (ShellFileHandle);
  } else {
    //
    // Get the Volume Info from Node->Handle
    //
    SysInfo     = NULL;
    SysInfoSize = 0;
    EfiFpHandle = ConvertShellHandleToEfiFileProtocol (Node->Handle);
    Status      = EfiFpHandle->GetInfo (
                                 EfiFpHandle,
                                 &gEfiFileSystemInfoGuid,
                                 &SysInfoSize,
                                 SysInfo
                                 );

    if (Status == EFI_BUFFER_TOO_SMALL) {
      SysInfo = AllocateZeroPool (SysInfoSize);
      if (SysInfo == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }

      Status = EfiFpHandle->GetInfo (
                              EfiFpHandle,
                              &gEfiFileSystemInfoGuid,
                              &SysInfoSize,
                              SysInfo
                              );
    }

    ASSERT_EFI_ERROR (Status);
  }

  ShellPrintHiiDefaultEx (
    STRING_TOKEN (STR_GEN_SFO_HEADER),
    gShellLevel2HiiHandle,
    L"ls"
    );
  //
  // print VolumeInfo table
  //
  ASSERT (SysInfo != NULL);
  ShellPrintHiiEx (
    0,
    gST->ConOut->Mode->CursorRow,
    NULL,
    STRING_TOKEN (STR_LS_SFO_VOLINFO),
    gShellLevel2HiiHandle,
    SysInfo->VolumeLabel,
    SysInfo->VolumeSize,
    SysInfo->ReadOnly ? L"TRUE" : L"FALSE",
    SysInfo->FreeSpace,
    SysInfo->BlockSize
    );

  SHELL_FREE_NON_NULL (SysInfo);

  return (Status);
}

/**
  print out the info on a single file.

  @param[in] Sfo      TRUE if in SFO, false otherwise.
  @param[in] TheNode  the EFI_SHELL_FILE_INFO node to print out information on.
  @param[in] Files    incremented if a file is printed.
  @param[in] Size     incremented by file size.
  @param[in] Dirs     incremented if a directory is printed.

**/
VOID
PrintFileInformation (
  IN CONST BOOLEAN              Sfo,
  IN CONST EFI_SHELL_FILE_INFO  *TheNode,
  IN UINT64                     *Files,
  IN UINT64                     *Size,
  IN UINT64                     *Dirs
  )
{
  ASSERT (Files    != NULL);
  ASSERT (Size     != NULL);
  ASSERT (Dirs     != NULL);
  ASSERT (TheNode  != NULL);

  if (Sfo) {
    //
    // Print the FileInfo Table
    //
    ShellPrintHiiEx (
      0,
      gST->ConOut->Mode->CursorRow,
      NULL,
      STRING_TOKEN (STR_LS_SFO_FILEINFO),
      gShellLevel2HiiHandle,
      TheNode->FullName,
      TheNode->Info->FileSize,
      TheNode->Info->PhysicalSize,
      (TheNode->Info->Attribute & EFI_FILE_ARCHIVE)   != 0 ? L"a" : L"",
      (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"d" : L"",
      (TheNode->Info->Attribute & EFI_FILE_HIDDEN)    != 0 ? L"h" : L"",
      (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L"r" : L"",
      (TheNode->Info->Attribute & EFI_FILE_SYSTEM)    != 0 ? L"s" : L"",
      TheNode->Info->CreateTime.Hour,
      TheNode->Info->CreateTime.Minute,
      TheNode->Info->CreateTime.Second,
      TheNode->Info->CreateTime.Day,
      TheNode->Info->CreateTime.Month,
      TheNode->Info->CreateTime.Year,
      TheNode->Info->LastAccessTime.Hour,
      TheNode->Info->LastAccessTime.Minute,
      TheNode->Info->LastAccessTime.Second,
      TheNode->Info->LastAccessTime.Day,
      TheNode->Info->LastAccessTime.Month,
      TheNode->Info->LastAccessTime.Year,
      TheNode->Info->ModificationTime.Hour,
      TheNode->Info->ModificationTime.Minute,
      TheNode->Info->ModificationTime.Second,
      TheNode->Info->ModificationTime.Day,
      TheNode->Info->ModificationTime.Month,
      TheNode->Info->ModificationTime.Year
      );
  } else {
    //
    // print this one out...
    // first print the universal start, next print the type specific name format, last print the CRLF
    //
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_LS_LINE_START_ALL),
      gShellLevel2HiiHandle,
      &TheNode->Info->ModificationTime,
      (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) != 0 ? L"<DIR>" : L"",
      (TheNode->Info->Attribute & EFI_FILE_READ_ONLY) != 0 ? L'r' : L' ',
      TheNode->Info->FileSize
      );
    if (TheNode->Info->Attribute & EFI_FILE_DIRECTORY) {
      (*Dirs)++;
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_LS_LINE_END_DIR),
        gShellLevel2HiiHandle,
        TheNode->FileName
        );
    } else {
      (*Files)++;
      (*Size) += TheNode->Info->FileSize;
      if (  (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".nsh", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0)
         || (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)L".efi", (CHAR16 *)&(TheNode->FileName[StrLen (TheNode->FileName) - 4])) == 0)
            )
      {
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_LS_LINE_END_EXE),
          gShellLevel2HiiHandle,
          TheNode->FileName
          );
      } else {
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_LS_LINE_END_FILE),
          gShellLevel2HiiHandle,
          TheNode->FileName
          );
      }
    }
  }
}

/**
  print out the header when not using standard format output.

  @param[in] Path           String with starting path.
**/
VOID
PrintNonSfoHeader (
  IN CONST CHAR16  *Path
  )
{
  CHAR16  *DirectoryName;

  //
  // get directory name from path...
  //
  DirectoryName = GetFullyQualifiedPath (Path);

  if (DirectoryName != NULL) {
    //
    // print header
    //
    ShellPrintHiiEx (
      0,
      gST->ConOut->Mode->CursorRow,
      NULL,
      STRING_TOKEN (STR_LS_HEADER_LINE1),
      gShellLevel2HiiHandle,
      DirectoryName
      );

    SHELL_FREE_NON_NULL (DirectoryName);
  }
}

/**
  print out the footer when not using standard format output.

  @param[in] Files            The number of files.
  @param[in] Size             The size of files in bytes.
  @param[in] Dirs             The number of directories.
**/
VOID
PrintNonSfoFooter (
  IN UINT64  Files,
  IN UINT64  Size,
  IN UINT64  Dirs
  )
{
  //
  // print footer
  //
  ShellPrintHiiDefaultEx (
    STRING_TOKEN (STR_LS_FOOTER_LINE),
    gShellLevel2HiiHandle,
    Files,
    Size,
    Dirs
    );
}

/**
  Change the file time to local time based on the timezone.

  @param[in] Time               The file time.
  @param[in] LocalTimeZone      Local time zone.
**/
VOID
FileTimeToLocalTime (
  IN EFI_TIME  *Time,
  IN INT16     LocalTimeZone
  )
{
  INTN  MinuteDiff;
  INTN  TempMinute;
  INTN  HourNumberOfTempMinute;
  INTN  TempHour;
  INTN  DayNumberOfTempHour;
  INTN  TempDay;
  INTN  MonthNumberOfTempDay;
  INTN  TempMonth;
  INTN  YearNumberOfTempMonth;
  INTN  MonthRecord;

  ASSERT ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440));
  ASSERT ((LocalTimeZone >= -1440) && (LocalTimeZone <= 1440));
  ASSERT ((Time->Month >= 1) && (Time->Month <= 12));

  if (Time->TimeZone == LocalTimeZone) {
    //
    // if the file timezone is equal to the local timezone, there is no need to adjust the file time.
    //
    return;
  }

  if (((Time->Year % 4 == 0) && (Time->Year / 100 != 0)) || (Time->Year % 400 == 0)) {
    //
    // Day in February of leap year is 29.
    //
    mDayOfMonth[1] = 29;
  }

  MinuteDiff = Time->TimeZone - LocalTimeZone;
  TempMinute = Time->Minute + MinuteDiff;

  //
  // Calculate Time->Minute
  // TempHour will be used to calculate Time->Hour
  //
  HourNumberOfTempMinute = TempMinute / 60;
  if (TempMinute < 0) {
    HourNumberOfTempMinute--;
  }

  TempHour     = Time->Hour + HourNumberOfTempMinute;
  Time->Minute = (UINT8)(TempMinute - 60 * HourNumberOfTempMinute);

  //
  // Calculate Time->Hour
  // TempDay will be used to calculate Time->Day
  //
  DayNumberOfTempHour = TempHour / 24;
  if (TempHour < 0) {
    DayNumberOfTempHour--;
  }

  TempDay    = Time->Day + DayNumberOfTempHour;
  Time->Hour = (UINT8)(TempHour - 24 * DayNumberOfTempHour);

  //
  // Calculate Time->Day
  // TempMonth will be used to calculate Time->Month
  //
  MonthNumberOfTempDay = (TempDay - 1) / (INTN)mDayOfMonth[Time->Month - 1];
  MonthRecord          = (INTN)(Time->Month);
  if (TempDay - 1 < 0) {
    MonthNumberOfTempDay--;
    MonthRecord--;
  }

  TempMonth = Time->Month + MonthNumberOfTempDay;
  Time->Day = (UINT8)(TempDay - (INTN)mDayOfMonth[(MonthRecord - 1 + 12) % 12] * MonthNumberOfTempDay);

  //
  // Calculate Time->Month, Time->Year
  //
  YearNumberOfTempMonth = (TempMonth - 1) / 12;
  if (TempMonth - 1 < 0) {
    YearNumberOfTempMonth--;
  }

  Time->Month = (UINT8)(TempMonth - 12 * (YearNumberOfTempMonth));
  Time->Year  = (UINT16)(Time->Year + YearNumberOfTempMonth);
}

/** Update the file time to local time.

  @param[in] Node   File Node to update.
**/
STATIC
VOID
UpdateFileLocalTime (
  IN  EFI_SHELL_FILE_INFO  *Node
  )
{
  EFI_STATUS  Status;
  EFI_TIME    LocalTime;

  Status = gRT->GetTime (&LocalTime, NULL);
  if (EFI_ERROR (Status) || (LocalTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE)) {
    return;
  }

  if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
      ((Node->Info->CreateTime.Month >= 1) && (Node->Info->CreateTime.Month <= 12)))
  {
    //
    // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens.
    //
    FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone);
  }

  if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
      ((Node->Info->LastAccessTime.Month >= 1) && (Node->Info->LastAccessTime.Month <= 12)))
  {
    FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone);
  }

  if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&
      ((Node->Info->ModificationTime.Month >= 1) && (Node->Info->ModificationTime.Month <= 12)))
  {
    FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone);
  }
}

/** Get Corrected Path.

  @param[in] CorrectedPath   String with the corrected path.
  @param[in] RootPath        String with starting path to search in.
  @param[in] SearchString    String with search string.

  @return Shell Status.
**/
STATIC
SHELL_STATUS
GetCorrectedPath (
  IN            CHAR16  **CorrectedPath,
  IN      CONST CHAR16  *RootPath,
  IN      CONST CHAR16  *SearchString
  )
{
  UINTN   LongestPath;
  CHAR16  *Path;

  ASSERT (CorrectedPath != NULL);

  LongestPath    = 0;
  Path           = NULL;
  *CorrectedPath = NULL;

  Path = StrnCatGrow (&Path, &LongestPath, RootPath, 0);
  if (Path == NULL) {
    return SHELL_OUT_OF_RESOURCES;
  }

  if (  (Path[StrLen (Path)-1] != L'\\')
     && (Path[StrLen (Path)-1] != L'/'))
  {
    Path = StrnCatGrow (&Path, &LongestPath, L"\\", 0);
  }

  Path = StrnCatGrow (&Path, &LongestPath, SearchString, 0);
  if (Path == NULL) {
    return SHELL_OUT_OF_RESOURCES;
  }

  *CorrectedPath = Path;
  return SHELL_SUCCESS;
}

/**
  Print out the list of files and directories from the LS command at the current level.

  @param[in] Attribs        List of required Attribute for display.
                            If 0 then all non-system and non-hidden files will be printed.
  @param[in] Sfo            TRUE to use Standard Format Output, FALSE otherwise
  @param[in] RootPath       String with starting path to search in.
  @param[in] SearchString   String with search string.
  @param[in] Found          Set to TRUE, if anyone were found.
  @param[in] Count          The count of bits enabled in Attribs.
  @param[in] IsRecursive    TRUE if called from a recursion.

  @retval SHELL_SUCCESS     the printing was successful.
**/
STATIC
SHELL_STATUS
PrintLsOutputCurr (
  IN CONST UINT64   Attribs,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR16   *RootPath,
  IN CONST CHAR16   *SearchString,
  IN       BOOLEAN  *Found,
  IN CONST UINTN    Count,
  IN       BOOLEAN  IsRecursive
  )
{
  EFI_STATUS           Status;
  EFI_SHELL_FILE_INFO  *ListHead;
  EFI_SHELL_FILE_INFO  *Node;
  SHELL_STATUS         ShellStatus;
  UINT64               FileCount;
  UINT64               DirCount;
  UINT64               FileSize;
  CHAR16               *CorrectedPath;
  BOOLEAN              FoundOne;
  BOOLEAN              HeaderPrinted;

  ASSERT (Found != NULL);

  HeaderPrinted = FALSE;
  FileCount     = 0;
  DirCount      = 0;
  FileSize      = 0;
  ListHead      = NULL;
  ShellStatus   = SHELL_SUCCESS;
  FoundOne      = FALSE;

  ShellStatus = GetCorrectedPath (&CorrectedPath, RootPath, SearchString);
  if (ShellStatus != SHELL_SUCCESS) {
    return ShellStatus;
  }

  PathCleanUpDirectories (CorrectedPath);

  Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);
  if (!EFI_ERROR (Status)) {
    if ((ListHead == NULL) || IsListEmpty (&ListHead->Link)) {
      SHELL_FREE_NON_NULL (CorrectedPath);
      return (SHELL_SUCCESS);
    }

    if (Sfo && !IsRecursive) {
      PrintSfoVolumeInfoTableEntry (ListHead);
    }

    if (!Sfo) {
      //
      // Sort the file list by FileName, stably.
      //
      // If the call below fails, then the EFI_SHELL_FILE_INFO list anchored to
      // ListHead will not be changed in any way.
      //
      ShellSortFileList (
        &ListHead,
        NULL,                       // Duplicates
        ShellSortFileListByFileName
        );
    }

    for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link)
          ; !IsNull (&ListHead->Link, &Node->Link)
          ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)
          )
    {
      if (ShellGetExecutionBreakFlag ()) {
        ShellStatus = SHELL_ABORTED;
        break;
      }

      ASSERT (Node != NULL);

      //
      // Change the file time to local time.
      //
      UpdateFileLocalTime (Node);

      ASSERT (Node->Info != NULL);
      ASSERT ((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute);
      if (Attribs == 0) {
        //
        // NOT system & NOT hidden
        //
        if (  (Node->Info->Attribute & EFI_FILE_SYSTEM)
           || (Node->Info->Attribute & EFI_FILE_HIDDEN)
              )
        {
          continue;
        }
      } else if ((Attribs != EFI_FILE_VALID_ATTR) ||
                 (Count == 5))
      {
        //
        // Only matches the bits which "Attribs" contains, not
        // all files/directories with any of the bits.
        // Count == 5 is used to tell the difference between a user
        // specifying all bits (EX: -arhsda) and just specifying
        // -a (means display all files with any attribute).
        //
        if ((Node->Info->Attribute & Attribs) != Attribs) {
          continue;
        }
      }

      if (!Sfo && !HeaderPrinted) {
        PathRemoveLastItem (CorrectedPath);
        PrintNonSfoHeader (CorrectedPath);
      }

      PrintFileInformation (Sfo, Node, &FileCount, &FileSize, &DirCount);
      FoundOne      = TRUE;
      HeaderPrinted = TRUE;
    }

    if (!Sfo && (ShellStatus != SHELL_ABORTED) && HeaderPrinted) {
      PrintNonSfoFooter (FileCount, FileSize, DirCount);
    }

    ShellCloseFileMetaArg (&ListHead);
  }

  if (FoundOne) {
    *Found = FoundOne;
  }

  SHELL_FREE_NON_NULL (CorrectedPath);
  return ShellStatus;
}

/**
  print out the list of files and directories from the LS command

  @param[in] Rec            TRUE to automatically recurse into each found directory
                            FALSE to only list the specified directory.
  @param[in] Attribs        List of required Attribute for display.
                            If 0 then all non-system and non-hidden files will be printed.
  @param[in] Sfo            TRUE to use Standard Format Output, FALSE otherwise
  @param[in] RootPath       String with starting path to search in.
  @param[in] SearchString   String with search string.
  @param[in] Found          Set to TRUE, if anyone were found.
  @param[in] Count          The count of bits enabled in Attribs.

  @retval SHELL_SUCCESS     the printing was successful.
**/
STATIC
SHELL_STATUS
PrintLsOutputRec (
  IN CONST BOOLEAN  Rec,
  IN CONST UINT64   Attribs,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR16   *RootPath,
  IN CONST CHAR16   *SearchString,
  IN       BOOLEAN  *Found,
  IN CONST UINTN    Count
  )
{
  EFI_STATUS           Status;
  EFI_SHELL_FILE_INFO  *ListHead;
  EFI_SHELL_FILE_INFO  *Node;
  SHELL_STATUS         ShellStatus;
  CHAR16               *CorrectedPath;

  //
  // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter
  //
  ShellStatus = GetCorrectedPath (&CorrectedPath, RootPath, L"*");
  if (ShellStatus != SHELL_SUCCESS) {
    return ShellStatus;
  }

  Status = ShellOpenFileMetaArg ((CHAR16 *)CorrectedPath, EFI_FILE_MODE_READ, &ListHead);
  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (CorrectedPath);
    return ShellStatus;
  }

  for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link)
        ; !IsNull (&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS
        ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)
        )
  {
    if (ShellGetExecutionBreakFlag ()) {
      ShellStatus = SHELL_ABORTED;
      break;
    }

    //
    // recurse on any directory except the traversing ones...
    //
    if (((Node->Info->Attribute & EFI_FILE_DIRECTORY) != EFI_FILE_DIRECTORY) ||
        IsDotOrDotDot (Node->FileName))
    {
      continue;
    }

    ShellStatus = PrintLsOutput (
                    Rec,
                    Attribs,
                    Sfo,
                    Node->FullName,
                    SearchString,
                    Found,
                    Count,
                    FALSE
                    );

    //
    // Since it's running recursively, we have to break immediately when returned SHELL_ABORTED
    //
    if (ShellStatus == SHELL_ABORTED) {
      break;
    }
  }

  ShellCloseFileMetaArg (&ListHead);
  SHELL_FREE_NON_NULL (CorrectedPath);
  return ShellStatus;
}

/**
  print out the list of files and directories from the LS command

  @param[in] Rec            TRUE to automatically recurse into each found directory
                            FALSE to only list the specified directory.
  @param[in] Attribs        List of required Attribute for display.
                            If 0 then all non-system and non-hidden files will be printed.
  @param[in] Sfo            TRUE to use Standard Format Output, FALSE otherwise
  @param[in] RootPath       String with starting path to search in.
  @param[in] SearchString   String with search string.
  @param[in] Found          Set to TRUE, if anyone were found.
  @param[in] Count          The count of bits enabled in Attribs.
  @param[in] ListUnfiltered TRUE to request listing the directory contents
                            unfiltered.

  @retval SHELL_SUCCESS     the printing was successful.
**/
SHELL_STATUS
PrintLsOutput (
  IN CONST BOOLEAN  Rec,
  IN CONST UINT64   Attribs,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR16   *RootPath,
  IN CONST CHAR16   *SearchString,
  IN       BOOLEAN  *Found,
  IN CONST UINTN    Count,
  IN CONST BOOLEAN  ListUnfiltered
  )
{
  SHELL_STATUS  ShellStatus;
  BOOLEAN       FoundOne;
  BOOLEAN       IsRecursive;

  ShellStatus = SHELL_SUCCESS;
  FoundOne    = FALSE;
  IsRecursive = (Found != NULL);

  ShellStatus = PrintLsOutputCurr (
                  Attribs,
                  Sfo,
                  RootPath,
                  SearchString,
                  &FoundOne,
                  Count,
                  IsRecursive
                  );

  if (Rec && (ShellStatus != SHELL_ABORTED)) {
    ShellStatus = PrintLsOutputRec (
                    Rec,
                    Attribs,
                    Sfo,
                    RootPath,
                    SearchString,
                    &FoundOne,
                    Count
                    );
  }

  if (!IsRecursive && !FoundOne) {
    if (ListUnfiltered) {
      //
      // When running "ls" without any filtering request, avoid outputing
      // "File not found" when the directory is entirely empty, but print
      // header and footer stating "0 File(s), 0 Dir(s)".
      //
      if (!Sfo) {
        PrintNonSfoHeader (RootPath);
        if (ShellStatus != SHELL_ABORTED) {
          PrintNonSfoFooter (0, 0, 0);
        }
      }
    } else {
      return (SHELL_NOT_FOUND);
    }
  }

  if ((Found != NULL) && FoundOne) {
    *Found = FoundOne;
  }

  return (ShellStatus);
}

STATIC CONST SHELL_PARAM_ITEM  LsParamList[] = {
  { L"-r",   TypeFlag  },
  { L"-a",   TypeStart },
  { L"-sfo", TypeFlag  },
  { NULL,    TypeMax   }
};

/** Main function of the 'Ls' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdLs (
  LIST_ENTRY  *Package
  )
{
  CONST CHAR16  *Attribs;
  SHELL_STATUS  ShellStatus;
  UINT64        RequiredAttributes;
  CONST CHAR16  *PathName;
  CONST CHAR16  *CurDir;
  UINTN         Count;
  CHAR16        *FullPath;
  UINTN         Size;
  CHAR16        *SearchString;
  BOOLEAN       ListUnfiltered;

  Size               = 0;
  FullPath           = NULL;
  Attribs            = NULL;
  ShellStatus        = SHELL_SUCCESS;
  RequiredAttributes = 0;
  PathName           = NULL;
  SearchString       = NULL;
  CurDir             = NULL;
  Count              = 0;
  ListUnfiltered     = FALSE;

  //
  // check for "-?"
  //
  if (ShellCommandLineGetFlag (Package, L"-?")) {
    ASSERT (FALSE);
  }

  if (ShellCommandLineGetCount (Package) > 2) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"ls");
    return SHELL_INVALID_PARAMETER;
  }

  //
  // check for -a
  //
  if (ShellCommandLineGetFlag (Package, L"-a")) {
    for ( Attribs = ShellCommandLineGetValue (Package, L"-a")
          ; Attribs != NULL && *Attribs != CHAR_NULL && ShellStatus == SHELL_SUCCESS
          ; Attribs++
          )
    {
      switch (*Attribs) {
        case L'a':
        case L'A':
          RequiredAttributes |= EFI_FILE_ARCHIVE;
          Count++;
          continue;
        case L's':
        case L'S':
          RequiredAttributes |= EFI_FILE_SYSTEM;
          Count++;
          continue;
        case L'h':
        case L'H':
          RequiredAttributes |= EFI_FILE_HIDDEN;
          Count++;
          continue;
        case L'r':
        case L'R':
          RequiredAttributes |= EFI_FILE_READ_ONLY;
          Count++;
          continue;
        case L'd':
        case L'D':
          RequiredAttributes |= EFI_FILE_DIRECTORY;
          Count++;
          continue;
        default:
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, L"ls", ShellCommandLineGetValue (Package, L"-a"));
          ShellStatus = SHELL_INVALID_PARAMETER;
          break;
      } // switch
    } // for loop

    //
    // if nothing is specified all are specified
    //
    if (RequiredAttributes == 0) {
      RequiredAttributes = EFI_FILE_VALID_ATTR;
    }
  } // if -a present

  if (ShellStatus != SHELL_SUCCESS) {
    return ShellStatus;
  }

  PathName = ShellCommandLineGetRawValue (Package, 1);
  if (PathName == NULL) {
    //
    // Nothing specified... must start from current directory
    //
    CurDir = gEfiShellProtocol->GetCurDir (NULL);
    if (CurDir == NULL) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls");
      return SHELL_NOT_FOUND;
    }

    ListUnfiltered = TRUE;
    //
    // Copy to the 2 strings for starting path and file search string
    //
    ASSERT (SearchString == NULL);
    ASSERT (FullPath == NULL);
    StrnCatGrow (&SearchString, NULL, L"*", 0);
    StrnCatGrow (&FullPath, NULL, CurDir, 0);
    Size = FullPath != NULL ? StrSize (FullPath) : 0;
    StrnCatGrow (&FullPath, &Size, L"\\", 0);
  } else {
    if ((StrStr (PathName, L":") == NULL) && (gEfiShellProtocol->GetCurDir (NULL) == NULL)) {
      //
      // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD.
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls");
      return SHELL_NOT_FOUND;
    }

    //
    // We got a valid fully qualified path or we have a CWD
    //
    ASSERT ((FullPath == NULL && Size == 0) || (FullPath != NULL));
    if (StrStr (PathName, L":") == NULL) {
      StrnCatGrow (&FullPath, &Size, gEfiShellProtocol->GetCurDir (NULL), 0);
      if (FullPath == NULL) {
        ShellCommandLineFreeVarList (Package);
        return SHELL_OUT_OF_RESOURCES;
      }

      Size = FullPath != NULL ? StrSize (FullPath) : 0;
      StrnCatGrow (&FullPath, &Size, L"\\", 0);
    }

    StrnCatGrow (&FullPath, &Size, PathName, 0);
    if (FullPath == NULL) {
      ShellCommandLineFreeVarList (Package);
      return SHELL_OUT_OF_RESOURCES;
    }

    if (ShellIsDirectory (PathName) == EFI_SUCCESS) {
      //
      // is listing ends with a directory, then we list all files in that directory
      //
      ListUnfiltered = TRUE;
      StrnCatGrow (&SearchString, NULL, L"*", 0);
    } else {
      //
      // must split off the search part that applies to files from the end of the directory part
      //
      StrnCatGrow (&SearchString, NULL, FullPath, 0);
      if (SearchString == NULL) {
        FreePool (FullPath);
        ShellCommandLineFreeVarList (Package);
        return SHELL_OUT_OF_RESOURCES;
      }

      PathRemoveLastItem (FullPath);
      CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath)));
    }
  }

  ShellStatus = PrintLsOutput (
                  ShellCommandLineGetFlag (Package, L"-r"),
                  RequiredAttributes,
                  ShellCommandLineGetFlag (Package, L"-sfo"),
                  FullPath,
                  SearchString,
                  NULL,
                  Count,
                  ListUnfiltered
                  );
  if (ShellStatus == SHELL_NOT_FOUND) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle, L"ls", FullPath);
  } else if (ShellStatus == SHELL_INVALID_PARAMETER) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath);
  } else if (ShellStatus == SHELL_ABORTED) {
    //
    // Ignore aborting.
    //
  } else if (ShellStatus != SHELL_SUCCESS) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath);
  }

  //
  // Free memory allocated
  //
  SHELL_FREE_NON_NULL (SearchString);
  SHELL_FREE_NON_NULL (FullPath);

  return ShellStatus;
}

/**
  Function for 'ls' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunLs (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  ProblemParam = NULL;
  ShellStatus  = SHELL_SUCCESS;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  //
  // Fix local copies of the protocol pointers
  //
  Status = CommandInit ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (LsParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"ls", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdLs (Package);

  //
  // Free memory allocated
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}
