/** @file
  Main file for Drivers shell Driver1 function.

  (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UefiShellDriver1CommandsLib.h"

#define MAX_LEN_DRIVER_NAME 35

STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
  {L"-sfo", TypeFlag},
  {L"-l", TypeValue},
  {NULL, TypeMax}
  };

/**
  Get a device path (in text format) for a given handle.

  @param[in] TheHandle      The handle to get the device path for.

  @retval NULL    An error occured.
  @return         A pointer to the driver path as a string.  The callee must
                  free this memory.
**/
CHAR16*
GetDevicePathTextForHandle(
  IN EFI_HANDLE TheHandle
  )
{
  EFI_STATUS                Status;
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *FinalPath;
  CHAR16                    *RetVal;

  FinalPath = NULL;

  Status = gBS->OpenProtocol (
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                (VOID**)&LoadedImage,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                  LoadedImage->DeviceHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID**)&ImageDevicePath,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                 );
    if (!EFI_ERROR (Status)) {
      FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
      gBS->CloseProtocol(
        LoadedImage->DeviceHandle,
        &gEfiDevicePathProtocolGuid,
        gImageHandle,
        NULL);
    }
    gBS->CloseProtocol(
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                gImageHandle,
                NULL);
  }

  if (FinalPath == NULL) {
    return (NULL);
  }
  RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath);
  if (RetVal == NULL) {
    RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE);
  }
  FreePool(FinalPath);
  return (RetVal);
}

/**
  Determine if the given handle has Driver Configuration protocol.

  @param[in] TheHandle      The handle to the driver to test.

  @retval TRUE              The driver does have Driver Configuration.
  @retval FALSE             The driver does not have Driver Configuration.
**/
BOOLEAN
ReturnDriverConfig(
  IN CONST EFI_HANDLE TheHandle
  )
{
  EFI_STATUS                  Status;
  Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverConfigurationProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
  if (EFI_ERROR(Status)) {
    return (FALSE);
  }
  return (TRUE);
}

/**
  Determine if the given handle has DriverDiagnostics protocol.

  @param[in] TheHandle      The handle to the driver to test.

  @retval TRUE              The driver does have Driver Diasgnostics.
  @retval FALSE             The driver does not have Driver Diagnostics.
**/
BOOLEAN
ReturnDriverDiag(
  IN CONST EFI_HANDLE TheHandle
  )
{
  EFI_STATUS                  Status;
  Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
  if (EFI_ERROR(Status)) {
    Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnosticsProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
    if (EFI_ERROR(Status)) {
      return (FALSE);
    }
  }
  return (TRUE);
}

/**
  Finds and returns the version of the driver specified by TheHandle.

  @param[in] TheHandle      The driver handle to get the version of.

  @return             The version of the driver.
  @retval 0xFFFFFFFF  An error ocurred.
**/
UINT32
ReturnDriverVersion(
  IN CONST EFI_HANDLE TheHandle
  )
{
  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  EFI_STATUS                  Status;
  UINT32                      RetVal;

  RetVal = (UINT32)-1;

  Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverBindingProtocolGuid, (VOID**)&DriverBinding, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (!EFI_ERROR(Status)) {
    RetVal = DriverBinding->Version;
    gBS->CloseProtocol(TheHandle, &gEfiDriverBindingProtocolGuid, gImageHandle, NULL);
  }
  return (RetVal);
}

/**
  Get image name from Image Handle.

  @param[in] Handle      Image Handle

  @return         A pointer to the image name as a string.
**/
CHAR16 *
GetImageNameFromHandle (
  IN CONST EFI_HANDLE Handle
  )
{
  EFI_STATUS                        Status;
  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding;
  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL          *DevPathNode;
  EFI_GUID                          *NameGuid;
  CHAR16                            *ImageName;
  UINTN                             BufferSize;
  UINT32                            AuthenticationStatus;
  EFI_FIRMWARE_VOLUME2_PROTOCOL     *Fv2;

  LoadedImage   = NULL;
  DriverBinding = NULL;
  ImageName     = NULL;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiDriverBindingProtocolGuid,
                  (VOID **) &DriverBinding,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
      return NULL;
  }
  Status = gBS->OpenProtocol (
                  DriverBinding->ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID**)&LoadedImage,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    DevPathNode = LoadedImage->FilePath;
    if (DevPathNode == NULL) {
      return NULL;
    }
    while (!IsDevicePathEnd (DevPathNode)) {
      NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
      if (NameGuid != NULL) {
        Status = gBS->HandleProtocol (
                        LoadedImage->DeviceHandle,
                        &gEfiFirmwareVolume2ProtocolGuid,
                        (VOID **)&Fv2
                        );
        if (!EFI_ERROR (Status)) {
          Status = Fv2->ReadSection (
                          Fv2,
                          NameGuid,
                          EFI_SECTION_USER_INTERFACE,
                          0,
                          (VOID **)&ImageName,
                          &BufferSize,
                          &AuthenticationStatus
                          );
          if (!EFI_ERROR (Status)) {
            break;
          }
          ImageName = NULL;
        }
      }
      //
      // Next device path node
      //
      DevPathNode = NextDevicePathNode (DevPathNode);
    }
    if (ImageName == NULL) {
      ImageName = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE);
    }
  }
  return ImageName;
}

/**
  Function for 'drivers' 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
ShellCommandRunDrivers (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CHAR8               *Language;
  CONST CHAR16        *Lang;
  EFI_HANDLE          *HandleList;
  EFI_HANDLE          *HandleWalker;
  UINTN               ChildCount;
  UINTN               DeviceCount;
  CHAR16              ChildCountStr[3];
  CHAR16              DeviceCountStr[3];
  CHAR16              *Temp2;
  CONST CHAR16        *FullDriverName;
  CHAR16              *TruncatedDriverName;
  CHAR16              *ImageName;
  CHAR16              *FormatString;
  UINT32              DriverVersion;
  BOOLEAN             DriverConfig;
  BOOLEAN             DriverDiag;
  BOOLEAN             SfoFlag;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Language            = NULL;
  FormatString        = NULL;
  SfoFlag             = FALSE;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    if (ShellCommandLineGetCount(Package) > 1) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      if (ShellCommandLineGetFlag(Package, L"-l")){
        Lang = ShellCommandLineGetValue(Package, L"-l");
        if (Lang != NULL) {
          Language = AllocateZeroPool(StrSize(Lang));
          AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
        } else {
          ASSERT(Language == NULL);
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l");
          ShellCommandLineFreeVarList (Package);
          return (SHELL_INVALID_PARAMETER);
        }
      }

      if (ShellCommandLineGetFlag (Package, L"-sfo")) {
        SfoFlag = TRUE;
        FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language);
        //
        // print the SFO header
        //
        ShellPrintHiiEx (
          -1,
          -1,
          Language,
          STRING_TOKEN (STR_GEN_SFO_HEADER),
          gShellDriver1HiiHandle,
          L"drivers");
      } else {
        FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language);
        //
        // print the header row
        //
        ShellPrintHiiEx(
          -1,
          -1,
          Language,
          STRING_TOKEN (STR_DRIVERS_HEADER_LINES),
          gShellDriver1HiiHandle);
      }

      HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid);
      for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){
        ChildCount     = 0;
        DeviceCount    = 0;
        Status         = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL);
        Status         = PARSE_HANDLE_DATABASE_DEVICES      (*HandleWalker, &DeviceCount, NULL);
        Temp2          = GetDevicePathTextForHandle(*HandleWalker);
        DriverVersion  = ReturnDriverVersion(*HandleWalker);
        DriverConfig   = ReturnDriverConfig(*HandleWalker);
        DriverDiag     = ReturnDriverDiag  (*HandleWalker);
        FullDriverName = GetStringNameFromHandle(*HandleWalker, Language);
        ImageName      = GetImageNameFromHandle (*HandleWalker);

        UnicodeValueToStringS (ChildCountStr,  sizeof (ChildCountStr),  0, ChildCount,  0);
        UnicodeValueToStringS (DeviceCountStr, sizeof (DeviceCountStr), 0, DeviceCount, 0);
        TruncatedDriverName = NULL;
        if (!SfoFlag && (FullDriverName != NULL)) {
          TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16));
          StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME);
        }

        if (!SfoFlag) {
          ShellPrintEx (
            -1,
            -1,
            FormatString,
            ConvertHandleToHandleIndex (*HandleWalker),
            DriverVersion,
            ChildCount > 0 ? L'B' : (DeviceCount > 0 ? L'D' : L'?'),
            DriverConfig ? L'X' : L'-',
            DriverDiag ? L'X' : L'-',
            DeviceCount > 0 ? DeviceCountStr : L"-",
            ChildCount  > 0 ? ChildCountStr : L"-",
            TruncatedDriverName,
            ImageName == NULL ? L"" : ImageName
            );
        } else {
          ShellPrintEx (
            -1,
            -1,
            FormatString,
            ConvertHandleToHandleIndex (*HandleWalker),
            DriverVersion,
            ChildCount > 0 ? L'B' : (DeviceCount > 0 ? L'D' : L'?'),
            DriverConfig ? L'Y' : L'N',
            DriverDiag ? L'Y' : L'N',
            DeviceCount,
            ChildCount,
            FullDriverName,
            Temp2 == NULL ? L"" : Temp2
            );
        }
        if (TruncatedDriverName != NULL) {
          FreePool (TruncatedDriverName);
        }
        if (Temp2 != NULL) {
          FreePool(Temp2);
        }
        if (ImageName != NULL) {
          FreePool (ImageName);
        }

        if (ShellGetExecutionBreakFlag ()) {
          ShellStatus = SHELL_ABORTED;
          break;
        }
      }
    }
    SHELL_FREE_NON_NULL(Language);
    ShellCommandLineFreeVarList (Package);
    SHELL_FREE_NON_NULL(FormatString);
  }

  return (ShellStatus);
}
