/** @file
  Tools of clarify the content of the smbios table.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2023 Apple Inc. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellDebug1CommandsLib.h"
#include "LibSmbiosView.h"
#include "SmbiosView.h"
#include "PrintInfo.h"
#include "QueryTable.h"

UINT8                        gShowType                    = SHOW_DETAIL;
STATIC STRUCTURE_STATISTICS  *mStatisticsTable            = NULL;
STATIC STRUCTURE_STATISTICS  *mSmbios64BitStatisticsTable = NULL;

UINT8  SmbiosMajorVersion;
UINT8  SmbiosMinorVersion;

UINTN  mNumberOfSmbios64BitStructures;
UINTN  mSmbios64BitTableLength;

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-t", TypeValue },
  { L"-h", TypeValue },
  { L"-s", TypeFlag  },
  { L"-a", TypeFlag  },
  { NULL,  TypeMax   }
};

/** Main function of the 'SmbiosView' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdSmbiosView (
  LIST_ENTRY  *Package
  )
{
  UINT8         StructType;
  UINT16        StructHandle;
  EFI_STATUS    Status;
  EFI_STATUS    Status1;
  EFI_STATUS    Status2;
  BOOLEAN       RandomView;
  SHELL_STATUS  ShellStatus;
  CONST CHAR16  *Temp;

  mStatisticsTable            = NULL;
  mSmbios64BitStatisticsTable = NULL;
  ShellStatus                 = SHELL_SUCCESS;

  if (ShellCommandLineGetCount (Package) > 1) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"smbiosview");
    ShellStatus = SHELL_INVALID_PARAMETER;
  } else if (ShellCommandLineGetFlag (Package, L"-t") && (ShellCommandLineGetValue (Package, L"-t") == NULL)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"smbiosview", L"-t");
    ShellStatus = SHELL_INVALID_PARAMETER;
  } else if (ShellCommandLineGetFlag (Package, L"-h") && (ShellCommandLineGetValue (Package, L"-h") == NULL)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"smbiosview", L"-h");
    ShellStatus = SHELL_INVALID_PARAMETER;
  } else if (
             (ShellCommandLineGetFlag (Package, L"-t") && ShellCommandLineGetFlag (Package, L"-h")) ||
             (ShellCommandLineGetFlag (Package, L"-t") && ShellCommandLineGetFlag (Package, L"-s")) ||
             (ShellCommandLineGetFlag (Package, L"-t") && ShellCommandLineGetFlag (Package, L"-a")) ||
             (ShellCommandLineGetFlag (Package, L"-h") && ShellCommandLineGetFlag (Package, L"-s")) ||
             (ShellCommandLineGetFlag (Package, L"-h") && ShellCommandLineGetFlag (Package, L"-a")) ||
             (ShellCommandLineGetFlag (Package, L"-s") && ShellCommandLineGetFlag (Package, L"-a"))
             )
  {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"smbiosview");
    ShellStatus = SHELL_INVALID_PARAMETER;
  } else {
    //
    // Init Lib
    //
    Status1 = LibSmbiosInit ();
    Status2 = LibSmbios64BitInit ();
    if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_CANNOT_GET_TABLE), gShellDebug1HiiHandle);
      ShellStatus = SHELL_NOT_FOUND;
      goto Done;
    }

    StructType = STRUCTURE_TYPE_RANDOM;
    RandomView = TRUE;

    Temp = ShellCommandLineGetValue (Package, L"-t");
    if (Temp != NULL) {
      StructType = (UINT8)ShellStrToUintn (Temp);
    }

    if (ShellCommandLineGetFlag (Package, L"-a")) {
      gShowType = SHOW_ALL;
    }

    if (!EFI_ERROR (Status1)) {
      //
      // Initialize the StructHandle to be the first handle
      //
      StructHandle = INVALID_HANDLE;
      LibGetSmbiosStructure (&StructHandle, NULL, NULL);

      Temp = ShellCommandLineGetValue (Package, L"-h");
      if (Temp != NULL) {
        RandomView   = FALSE;
        StructHandle = (UINT16)ShellStrToUintn (Temp);
      }

      //
      // build statistics table
      //
      Status = InitSmbiosTableStatistics ();
      if (EFI_ERROR (Status)) {
        ShellStatus = SHELL_NOT_FOUND;
        goto Done;
      }

      if (ShellCommandLineGetFlag (Package, L"-s")) {
        Status = DisplayStatisticsTable (SHOW_DETAIL);
        if (EFI_ERROR (Status)) {
          ShellStatus = SHELL_NOT_FOUND;
        }

        goto Show64Bit;
      }

      //
      // Show SMBIOS structure information
      //
      Status = SMBiosView (StructType, StructHandle, gShowType, RandomView);
      if (EFI_ERROR (Status)) {
        ShellStatus = SHELL_NOT_FOUND;
        goto Done;
      }
    }

Show64Bit:
    if (!EFI_ERROR (Status2)) {
      //
      // build statistics table
      //
      Status = InitSmbios64BitTableStatistics ();
      if (EFI_ERROR (Status)) {
        ShellStatus = SHELL_NOT_FOUND;
        goto Done;
      }

      //
      // Initialize the StructHandle to be the first handle
      //
      StructHandle = INVALID_HANDLE;
      LibGetSmbios64BitStructure (&StructHandle, NULL, NULL);

      Temp = ShellCommandLineGetValue (Package, L"-h");
      if (Temp != NULL) {
        RandomView   = FALSE;
        StructHandle = (UINT16)ShellStrToUintn (Temp);
      }

      if (ShellCommandLineGetFlag (Package, L"-s")) {
        Status = DisplaySmbios64BitStatisticsTable (SHOW_DETAIL);
        if (EFI_ERROR (Status)) {
          ShellStatus = SHELL_NOT_FOUND;
        }

        goto Done;
      }

      //
      // Show SMBIOS structure information
      //
      Status = SMBios64View (StructType, StructHandle, gShowType, RandomView);
      if (EFI_ERROR (Status)) {
        ShellStatus = SHELL_NOT_FOUND;
      }
    }
  }

Done:
  //
  // Release resources
  //
  if (mStatisticsTable != NULL) {
    //
    // Release statistics table
    //
    FreePool (mStatisticsTable);
    mStatisticsTable = NULL;
  }

  if (mSmbios64BitStatisticsTable != NULL) {
    //
    // Release statistics table
    //
    FreePool (mSmbios64BitStatisticsTable);
    mSmbios64BitStatisticsTable = NULL;
  }

  return ShellStatus;
}

/**
  Function for 'smbiosview' 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
ShellCommandRunSmbiosView (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  mStatisticsTable            = NULL;
  mSmbios64BitStatisticsTable = NULL;
  Package                     = NULL;
  ShellStatus                 = SHELL_SUCCESS;

  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"smbiosview", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdSmbiosView (Package);

  ShellCommandLineFreeVarList (Package);
  LibSmbiosCleanup ();
  LibSmbios64BitCleanup ();

  return ShellStatus;
}

/**
  Query all structures Data from SMBIOS table and Display
  the information to users as required display option.

  @param[in] QueryType      Structure type to view.
  @param[in] QueryHandle    Structure handle to view.
  @param[in] Option         Display option: none,outline,normal,detail.
  @param[in] RandomView     Support for -h parameter.

  @retval EFI_SUCCESS           print is successful.
  @retval EFI_BAD_BUFFER_SIZE   structure is out of the range of SMBIOS table.
**/
EFI_STATUS
SMBiosView (
  IN  UINT8    QueryType,
  IN  UINT16   QueryHandle,
  IN  UINT8    Option,
  IN  BOOLEAN  RandomView
  )
{
  UINT16  Handle;
  UINT8   *Buffer;
  UINT16  Length;
  UINTN   Index;

  SMBIOS_STRUCTURE_POINTER  SmbiosStruct;
  SMBIOS_TABLE_ENTRY_POINT  *SMBiosTable;

  SMBiosTable = NULL;
  LibSmbiosGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_BAD_BUFFER_SIZE;
  }

  if (CompareMem (SMBiosTable->AnchorString, SMBIOS_ANCHOR_STRING, SMBIOS_ANCHOR_STRING_LENGTH) == 0) {
    //
    // Have got SMBIOS table
    //
    SmbiosPrintEPSInfo (SMBiosTable, Option);

    SmbiosMajorVersion = SMBiosTable->MajorVersion;
    SmbiosMinorVersion = SMBiosTable->MinorVersion;

    ShellPrintDefaultEx (L"=========================================================\n");
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERY_STRUCT_COND), gShellDebug1HiiHandle);

    if (QueryType == STRUCTURE_TYPE_RANDOM) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE_RANDOM), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE), gShellDebug1HiiHandle, QueryType);
    }

    if (RandomView) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE_RANDOM), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE), gShellDebug1HiiHandle, QueryHandle);
    }

    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SHOWTYPE), gShellDebug1HiiHandle);
    ShellPrintDefaultEx (GetShowTypeString (gShowType));
    ShellPrintDefaultEx (L"\n\n");

    /*
        //
        // Get internal commands, such as change options.
        //
        Status = WaitEnter ();
        if (EFI_ERROR (Status)) {
          if (Status == EFI_ABORTED) {
            return EFI_SUCCESS;
          }

          return Status;
        }
    */

    //
    // Searching and display structure info
    //
    Handle = QueryHandle;
    for (Index = 0; Index < SMBiosTable->NumberOfSmbiosStructures; Index++) {
      //
      // if reach the end of table, break..
      //
      if (Handle == INVALID_HANDLE) {
        break;
      }

      //
      // handle then point to the next!
      //
      if (LibGetSmbiosStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) {
        break;
      }

      SmbiosStruct.Raw = Buffer;

      //
      // if QueryType==Random, print this structure.
      // if QueryType!=Random, but Hdr->Type==QueryType, also print it.
      // only if QueryType != Random and Hdr->Type != QueryType, skiped it.
      //
      if ((QueryType != STRUCTURE_TYPE_RANDOM) && (SmbiosStruct.Hdr->Type != QueryType)) {
        continue;
      }

      ShellPrintDefaultEx (L"\n=========================================================\n");
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE_HANDLE_DUMP_STRUCT),
        gShellDebug1HiiHandle,
        SmbiosStruct.Hdr->Type,
        SmbiosStruct.Hdr->Handle
        );
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX_LENGTH), gShellDebug1HiiHandle, Index, Length);
      //
      // Addr of structure in structure in table
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ADDR), gShellDebug1HiiHandle, (UINTN)Buffer);
      DumpHex (0, 0, Length, Buffer);

      /*
            //
            // Get internal commands, such as change options.
            //
            Status = WaitEnter ();
            if (EFI_ERROR (Status)) {
              if (Status == EFI_ABORTED) {
                return EFI_SUCCESS;
              }

              return Status;
            }
      */

      if (gShowType != SHOW_NONE) {
        //
        // Print structure information
        //
        SmbiosPrintStructure (&SmbiosStruct, gShowType);
        ShellPrintDefaultEx (L"\n");

        /*
                //
                // Get internal commands, such as change options.
                //
                Status = WaitEnter ();
                if (EFI_ERROR (Status)) {
                  if (Status == EFI_ABORTED) {
                    return EFI_SUCCESS;
                  }

                  return Status;
                }
        */
      }

      if (!RandomView) {
        break;
      }

      //
      // Support Execution Interrupt.
      //
      if (ShellGetExecutionBreakFlag ()) {
        return EFI_ABORTED;
      }
    }

    ShellPrintDefaultEx (L"\n=========================================================\n");
    return EFI_SUCCESS;
  }

  return EFI_BAD_BUFFER_SIZE;
}

/**
  Query all structures Data from SMBIOS table and Display
  the information to users as required display option.

  @param[in] QueryType      Structure type to view.
  @param[in] QueryHandle    Structure handle to view.
  @param[in] Option         Display option: none,outline,normal,detail.
  @param[in] RandomView     Support for -h parameter.

  @retval EFI_SUCCESS           print is successful.
  @retval EFI_BAD_BUFFER_SIZE   structure is out of the range of SMBIOS table.
**/
EFI_STATUS
SMBios64View (
  IN  UINT8    QueryType,
  IN  UINT16   QueryHandle,
  IN  UINT8    Option,
  IN  BOOLEAN  RandomView
  )
{
  UINT16                        Handle;
  UINT8                         *Buffer;
  UINT16                        Length;
  UINTN                         Index;
  SMBIOS_STRUCTURE_POINTER      SmbiosStruct;
  SMBIOS_TABLE_3_0_ENTRY_POINT  *SMBiosTable;

  SMBiosTable = NULL;
  LibSmbios64BitGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_BAD_BUFFER_SIZE;
  }

  if (CompareMem (SMBiosTable->AnchorString, SMBIOS_3_0_ANCHOR_STRING, SMBIOS_3_0_ANCHOR_STRING_LENGTH) == 0) {
    //
    // Have got SMBIOS table
    //
    Smbios64BitPrintEPSInfo (SMBiosTable, Option);

    SmbiosMajorVersion = SMBiosTable->MajorVersion;
    SmbiosMinorVersion = SMBiosTable->MinorVersion;

    ShellPrintDefaultEx (L"=========================================================\n");
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERY_STRUCT_COND), gShellDebug1HiiHandle);

    if (QueryType == STRUCTURE_TYPE_RANDOM) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE_RANDOM), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE), gShellDebug1HiiHandle, QueryType);
    }

    if (RandomView) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE_RANDOM), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE), gShellDebug1HiiHandle, QueryHandle);
    }

    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SHOWTYPE), gShellDebug1HiiHandle);
    ShellPrintDefaultEx (GetShowTypeString (gShowType));
    ShellPrintDefaultEx (L"\n\n");

    /*
        //
        // Get internal commands, such as change options.
        //
        Status = WaitEnter ();
        if (EFI_ERROR (Status)) {
          if (Status == EFI_ABORTED) {
            return EFI_SUCCESS;
          }

          return Status;
        }
    */

    //
    // Searching and display structure info
    //
    Handle = QueryHandle;
    for (Index = 0; Index < mNumberOfSmbios64BitStructures; Index++) {
      //
      // if reach the end of table, break..
      //
      if (Handle == INVALID_HANDLE) {
        break;
      }

      //
      // handle then point to the next!
      //
      if (LibGetSmbios64BitStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) {
        break;
      }

      SmbiosStruct.Raw = Buffer;

      //
      // if QueryType==Random, print this structure.
      // if QueryType!=Random, but Hdr->Type==QueryType, also print it.
      // only if QueryType != Random and Hdr->Type != QueryType, skiped it.
      //
      if ((QueryType != STRUCTURE_TYPE_RANDOM) && (SmbiosStruct.Hdr->Type != QueryType)) {
        continue;
      }

      ShellPrintDefaultEx (L"\n=========================================================\n");
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE_HANDLE_DUMP_STRUCT),
        gShellDebug1HiiHandle,
        SmbiosStruct.Hdr->Type,
        SmbiosStruct.Hdr->Handle
        );
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX_LENGTH), gShellDebug1HiiHandle, Index, Length);
      //
      // Addr of structure in structure in table
      //
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ADDR), gShellDebug1HiiHandle, (UINTN)Buffer);
      DumpHex (0, 0, Length, Buffer);

      /*
            //
            // Get internal commands, such as change options.
            //
            Status = WaitEnter ();
            if (EFI_ERROR (Status)) {
              if (Status == EFI_ABORTED) {
                return EFI_SUCCESS;
              }

              return Status;
            }
      */

      if (gShowType != SHOW_NONE) {
        //
        // Print structure information
        //
        SmbiosPrintStructure (&SmbiosStruct, gShowType);
        ShellPrintDefaultEx (L"\n");

        /*
                //
                // Get internal commands, such as change options.
                //
                Status = WaitEnter ();
                if (EFI_ERROR (Status)) {
                  if (Status == EFI_ABORTED) {
                    return EFI_SUCCESS;
                  }

                  return Status;
                }
        */
      }

      if (!RandomView) {
        break;
      }

      //
      // Support Execution Interrupt.
      //
      if (ShellGetExecutionBreakFlag ()) {
        return EFI_ABORTED;
      }
    }

    ShellPrintDefaultEx (L"\n=========================================================\n");
    return EFI_SUCCESS;
  }

  return EFI_BAD_BUFFER_SIZE;
}

/**
  Function to initialize the global mStatisticsTable object.

  @retval EFI_SUCCESS           print is successful.
**/
EFI_STATUS
InitSmbiosTableStatistics (
  VOID
  )
{
  UINT16  Handle;
  UINT8   *Buffer;
  UINT16  Length;
  UINT16  Offset;
  UINT16  Index;

  SMBIOS_STRUCTURE_POINTER  SmbiosStruct;
  SMBIOS_TABLE_ENTRY_POINT  *SMBiosTable;
  STRUCTURE_STATISTICS      *StatisticsPointer;

  SMBiosTable = NULL;
  LibSmbiosGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_NOT_FOUND;
  }

  if (CompareMem (SMBiosTable->AnchorString, SMBIOS_ANCHOR_STRING, SMBIOS_ANCHOR_STRING_LENGTH) != 0) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_TABLE), gShellDebug1HiiHandle);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate memory to mStatisticsTable
  //
  if (mStatisticsTable != NULL) {
    FreePool (mStatisticsTable);
    mStatisticsTable = NULL;
  }

  mStatisticsTable = (STRUCTURE_STATISTICS *)AllocateZeroPool (SMBiosTable->NumberOfSmbiosStructures * sizeof (STRUCTURE_STATISTICS));

  if (mStatisticsTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OUT_OF_MEM), gShellDebug1HiiHandle);
    return EFI_OUT_OF_RESOURCES;
  }

  Offset            = 0;
  StatisticsPointer = mStatisticsTable;

  //
  // search from the first one
  //
  Handle = INVALID_HANDLE;
  LibGetSmbiosStructure (&Handle, NULL, NULL);
  for (Index = 1; Index <= SMBiosTable->NumberOfSmbiosStructures; Index++) {
    //
    // If reach the end of table, break..
    //
    if (Handle == INVALID_HANDLE) {
      break;
    }

    //
    // After LibGetSmbiosStructure(), handle then point to the next!
    //
    if (LibGetSmbiosStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) {
      break;
    }

    SmbiosStruct.Raw = Buffer;

    //
    // general statistics
    //
    StatisticsPointer->Index  = Index;
    StatisticsPointer->Type   = SmbiosStruct.Hdr->Type;
    StatisticsPointer->Handle = SmbiosStruct.Hdr->Handle;
    StatisticsPointer->Length = Length;
    StatisticsPointer->Addr   = Offset;

    Offset = (UINT16)(Offset + Length);

    StatisticsPointer = &mStatisticsTable[Index];
  }

  return EFI_SUCCESS;
}

/**
  @param[in]  Smbios64EntryPoint          SMBIOS 64-bit entry point.
  @param[out] NumberOfSmbios64Structures  The number of structures in 64-bit SMBIOS table.
  @param[out] Smbios64TableLength         The total length of 64-bit SMBIOS table.

  @retval EFI_SUCCESS                     Calculation was successful.
**/
EFI_STATUS
CalculateSmbios64BitStructureCountAndLength (
  SMBIOS_TABLE_3_0_ENTRY_POINT  *Smbios64EntryPoint,
  UINTN                         *NumberOfSmbios64Structures,
  UINTN                         *Smbios64TableLength
  )
{
  SMBIOS_STRUCTURE_POINTER  Smbios;
  UINT8                     *Raw;

  *Smbios64TableLength        = 0;
  *NumberOfSmbios64Structures = 0;

  Smbios.Raw = (UINT8 *)(UINTN)(Smbios64EntryPoint->TableAddress);
  while (TRUE) {
    if (Smbios.Hdr->Type == 127) {
      //
      // Reach the end of table type 127
      //
      (*NumberOfSmbios64Structures)++;
      (*Smbios64TableLength) += sizeof (SMBIOS_STRUCTURE);
      return EFI_SUCCESS;
    }

    Raw = Smbios.Raw;
    //
    // Walk to next structure
    //
    LibGetSmbiosString (&Smbios, (UINT16)(-1));
    //
    // Length = Next structure head - this structure head
    //
    (*Smbios64TableLength) += ((UINTN)Smbios.Raw - (UINTN)Raw);
    if ((*Smbios64TableLength) > Smbios64EntryPoint->TableMaximumSize) {
      //
      // The actual table length exceeds maximum table size,
      // There should be something wrong with SMBIOS table.
      //
      return EFI_INVALID_PARAMETER;
    }

    (*NumberOfSmbios64Structures)++;
  }
}

/**
  Function to initialize the global mSmbios64BitStatisticsTable object.

  @retval EFI_SUCCESS           print is successful.
**/
EFI_STATUS
InitSmbios64BitTableStatistics (
  VOID
  )
{
  UINT16                        Handle;
  UINT8                         *Buffer;
  UINT16                        Length;
  UINT16                        Offset;
  UINT16                        Index;
  EFI_STATUS                    Status;
  SMBIOS_STRUCTURE_POINTER      SmbiosStruct;
  SMBIOS_TABLE_3_0_ENTRY_POINT  *SMBiosTable;
  STRUCTURE_STATISTICS          *StatisticsPointer;

  SMBiosTable = NULL;
  LibSmbios64BitGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_NOT_FOUND;
  }

  if (CompareMem (SMBiosTable->AnchorString, SMBIOS_3_0_ANCHOR_STRING, SMBIOS_3_0_ANCHOR_STRING_LENGTH) != 0) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_TABLE), gShellDebug1HiiHandle);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate memory to mSmbios64BitStatisticsTable
  //
  if (mSmbios64BitStatisticsTable != NULL) {
    FreePool (mSmbios64BitStatisticsTable);
    mSmbios64BitStatisticsTable = NULL;
  }

  //
  // Calculate number of smbios structures
  //
  Status = CalculateSmbios64BitStructureCountAndLength (SMBiosTable, &mNumberOfSmbios64BitStructures, &mSmbios64BitTableLength);
  if ((EFI_ERROR (Status)) || (mSmbios64BitTableLength > SMBiosTable->TableMaximumSize)) {
    return EFI_INVALID_PARAMETER;
  }

  mSmbios64BitStatisticsTable = (STRUCTURE_STATISTICS *)AllocateZeroPool (mNumberOfSmbios64BitStructures * sizeof (STRUCTURE_STATISTICS));

  if (mSmbios64BitStatisticsTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OUT_OF_MEM), gShellDebug1HiiHandle);
    return EFI_OUT_OF_RESOURCES;
  }

  Offset            = 0;
  StatisticsPointer = mSmbios64BitStatisticsTable;

  //
  // search from the first one
  //
  Handle = INVALID_HANDLE;
  LibGetSmbios64BitStructure (&Handle, NULL, NULL);
  for (Index = 1; (UINTN)Index <= mNumberOfSmbios64BitStructures; Index++) {
    //
    // If reach the end of table, break..
    //
    if (Handle == INVALID_HANDLE) {
      break;
    }

    //
    // After LibGetSmbios64BitStructure(), handle then point to the next!
    //
    if (LibGetSmbios64BitStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) {
      break;
    }

    SmbiosStruct.Raw = Buffer;

    //
    // general statistics
    //
    StatisticsPointer->Index  = Index;
    StatisticsPointer->Type   = SmbiosStruct.Hdr->Type;
    StatisticsPointer->Handle = SmbiosStruct.Hdr->Handle;
    StatisticsPointer->Length = Length;
    StatisticsPointer->Addr   = Offset;

    Offset = (UINT16)(Offset + Length);

    StatisticsPointer = &mSmbios64BitStatisticsTable[Index];
  }

  return EFI_SUCCESS;
}

/**
  Function to display the global mStatisticsTable object.

  @param[in] Option             ECHO, NORMAL, or DETAIL control the amount of detail displayed.

  @retval EFI_SUCCESS           print is successful.
**/
EFI_STATUS
DisplayStatisticsTable (
  IN   UINT8  Option
  )
{
  UINTN                     Index;
  UINTN                     Num;
  STRUCTURE_STATISTICS      *StatisticsPointer;
  SMBIOS_TABLE_ENTRY_POINT  *SMBiosTable;

  SMBiosTable = NULL;
  if (Option < SHOW_OUTLINE) {
    return EFI_SUCCESS;
  }

  //
  // display EPS information firstly
  //
  LibSmbiosGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_UNSUPPORTED;
  }

  ShellPrintDefaultEx (L"\n============================================================\n");
  SmbiosPrintEPSInfo (SMBiosTable, Option);

  if (Option < SHOW_NORMAL) {
    return EFI_SUCCESS;
  }

  if (mStatisticsTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_STATS), gShellDebug1HiiHandle);
    return EFI_NOT_FOUND;
  }

  ShellPrintDefaultEx (L"============================================================\n");
  StatisticsPointer = &mStatisticsTable[0];
  Num               = SMBiosTable->NumberOfSmbiosStructures;
  //
  // display statistics table content
  //
  for (Index = 1; Index <= Num; Index++) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX), gShellDebug1HiiHandle, StatisticsPointer->Index);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE), gShellDebug1HiiHandle, StatisticsPointer->Type);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE), gShellDebug1HiiHandle, StatisticsPointer->Handle);
    if (Option >= SHOW_DETAIL) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OFFSET), gShellDebug1HiiHandle, StatisticsPointer->Addr);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_LENGTH), gShellDebug1HiiHandle, StatisticsPointer->Length);
    }

    ShellPrintDefaultEx (L"\n");
    StatisticsPointer = &mStatisticsTable[Index];

    /*
        //
        // Display 20 lines and wait for a page break
        //
        if (Index % 20 == 0) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_CONTINUE), gShellDebug1HiiHandle);
          Status = WaitEnter ();
          if (EFI_ERROR (Status)) {
            if (Status == EFI_ABORTED) {
              return EFI_SUCCESS;
            }

            return Status;
          }
        }
    */
  }

  return EFI_SUCCESS;
}

/**
  Function to display the global mSmbios64BitStatisticsTable object.

  @param[in] Option             ECHO, NORMAL, or DETAIL control the amount of detail displayed.

  @retval EFI_SUCCESS           print is successful.
**/
EFI_STATUS
DisplaySmbios64BitStatisticsTable (
  IN   UINT8  Option
  )
{
  UINTN                         Index;
  UINTN                         Num;
  STRUCTURE_STATISTICS          *StatisticsPointer;
  SMBIOS_TABLE_3_0_ENTRY_POINT  *SMBiosTable;

  SMBiosTable = NULL;
  if (Option < SHOW_OUTLINE) {
    return EFI_SUCCESS;
  }

  //
  // display EPS information firstly
  //
  LibSmbios64BitGetEPS (&SMBiosTable);
  if (SMBiosTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle);
    return EFI_UNSUPPORTED;
  }

  ShellPrintDefaultEx (L"\n============================================================\n");
  Smbios64BitPrintEPSInfo (SMBiosTable, Option);

  if (Option < SHOW_NORMAL) {
    return EFI_SUCCESS;
  }

  if (mSmbios64BitStatisticsTable == NULL) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_STATS), gShellDebug1HiiHandle);
    return EFI_NOT_FOUND;
  }

  ShellPrintDefaultEx (L"============================================================\n");
  StatisticsPointer = &mSmbios64BitStatisticsTable[0];
  Num               = mNumberOfSmbios64BitStructures;
  //
  // display statistics table content
  //
  for (Index = 1; Index <= Num; Index++) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX), gShellDebug1HiiHandle, StatisticsPointer->Index);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE), gShellDebug1HiiHandle, StatisticsPointer->Type);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE), gShellDebug1HiiHandle, StatisticsPointer->Handle);
    if (Option >= SHOW_DETAIL) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OFFSET), gShellDebug1HiiHandle, StatisticsPointer->Addr);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_LENGTH), gShellDebug1HiiHandle, StatisticsPointer->Length);
    }

    ShellPrintDefaultEx (L"\n");
    StatisticsPointer = &mSmbios64BitStatisticsTable[Index];

    /*
        //
        // Display 20 lines and wait for a page break
        //
        if (Index % 20 == 0) {
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_CONTINUE), gShellDebug1HiiHandle);
          Status = WaitEnter ();
          if (EFI_ERROR (Status)) {
            if (Status == EFI_ABORTED) {
              return EFI_SUCCESS;
            }

            return Status;
          }
        }
    */
  }

  return EFI_SUCCESS;
}

/**
  function to return a string of the detail level.

  @param[in] ShowType         The detail level whose name is desired in clear text.

  @return   A pointer to a string representing the ShowType (or 'undefined type' if not known).
**/
CHAR16 *
GetShowTypeString (
  UINT8  ShowType
  )
{
  //
  // show type
  //
  switch (ShowType) {
    case SHOW_NONE:
      return L"SHOW_NONE";

    case SHOW_OUTLINE:
      return L"SHOW_OUTLINE";

    case SHOW_NORMAL:
      return L"SHOW_NORMAL";

    case SHOW_DETAIL:
      return L"SHOW_DETAIL";

    case SHOW_ALL:
      return L"SHOW_ALL";

    default:
      return L"Undefined type";
  }
}
