/** @file
  This contains the business logic for the module-specific Reset Helper functions.

  Copyright (c) 2017 - 2018 Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2016 Microsoft 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 that 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 <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ResetSystemLib.h>

typedef struct {
  CHAR16 NullTerminator;
  GUID   ResetSubtype;
} RESET_UTILITY_GUID_SPECIFIC_RESET_DATA;

/**
  This is a shorthand helper function to reset with a subtype so that
  the caller doesn't have to bother with a function that has half a dozen
  parameters.

  This will generate a reset with status EFI_SUCCESS, a NULL string, and
  no custom data. The subtype will be formatted in such a way that it can be
  picked up by notification registrations and custom handlers.

  NOTE: This call will fail if the architectural ResetSystem underpinnings
        are not initialized. For DXE, you can add gEfiResetArchProtocolGuid
        to your DEPEX.

  @param[in]  ResetSubtype  GUID pointer for the reset subtype to be used.

**/
VOID
EFIAPI
ResetPlatformSpecificGuid (
  IN CONST  GUID        *ResetSubtype
  )
{
  RESET_UTILITY_GUID_SPECIFIC_RESET_DATA  ResetData;

  ResetData.NullTerminator = CHAR_NULL;
  CopyGuid (&ResetData.ResetSubtype, ResetSubtype);
  ResetPlatformSpecific (sizeof (ResetData), &ResetData);
}

/**
  This function examines the DataSize and ResetData parameters passed to
  to ResetSystem() and detemrines if the ResetData contains a Null-terminated
  Unicode string followed by a GUID specific subtype.  If the GUID specific 
  subtype is present, then a pointer to the GUID value in ResetData is returned.

  @param[in]  DataSize    The size, in bytes, of ResetData.
  @param[in]  ResetData   Pointer to the data buffer passed into ResetSystem().

  @retval     Pointer     Pointer to the GUID value in ResetData.
  @retval     NULL        ResetData is NULL.
  @retval     NULL        ResetData does not start with a Null-terminated
                          Unicode string.
  @retval     NULL        A Null-terminated Unicode string is present, but there
                          are less than sizeof (GUID) bytes after the string.
  @retval     NULL        No subtype is found.

**/
GUID *
EFIAPI
GetResetPlatformSpecificGuid (
  IN UINTN       DataSize,
  IN CONST VOID  *ResetData
  )
{
  UINTN          ResetDataStringSize;
  GUID           *ResetSubtypeGuid;

  //
  // Make sure parameters are valid
  //
  if ((ResetData == NULL) || (DataSize < sizeof (GUID))) {
    return NULL;
  }

  //
  // Determine the number of bytes in the Null-terminated Unicode string
  // at the beginning of ResetData including the Null terminator.
  //
  ResetDataStringSize = StrnSizeS (ResetData, (DataSize / sizeof (CHAR16)));

  //
  // Now, assuming that we have enough data for a GUID after the string, the
  // GUID should be immediately after the string itself.
  //
  if ((ResetDataStringSize < DataSize) && (DataSize - ResetDataStringSize) >= sizeof (GUID)) {
    ResetSubtypeGuid = (GUID *)((UINT8 *)ResetData + ResetDataStringSize);
    DEBUG ((DEBUG_VERBOSE, "%a - Detected reset subtype %g...\n", __FUNCTION__, ResetSubtypeGuid));
    return ResetSubtypeGuid;
  }
  return NULL;
}

/**
  This is a helper function that creates the reset data buffer that can be 
  passed into ResetSystem().

  The reset data buffer is returned in ResetData and contains ResetString
  followed by the ResetSubtype GUID followed by the ExtraData.

  NOTE: Strings are internally limited by MAX_UINT16.

  @param[in, out] ResetDataSize  On input, the size of the ResetData buffer. On
                                 output, either the total number of bytes
                                 copied, or the required buffer size.
  @param[in, out] ResetData      A pointer to the buffer in which to place the
                                 final structure.
  @param[in]      ResetSubtype   Pointer to the GUID specific subtype.  This
                                 parameter is optional and may be NULL.
  @param[in]      ResetString    Pointer to a Null-terminated Unicode string
                                 that describes the reset.  This parameter is
                                 optional and may be NULL.
  @param[in]      ExtraDataSize  The size, in bytes, of ExtraData buffer.
  @param[in]      ExtraData      Pointer to a buffer of extra data.  This
                                 parameter is optional and may be NULL.

  @retval     RETURN_SUCCESS             ResetDataSize and ResetData are updated.
  @retval     RETURN_INVALID_PARAMETER   ResetDataSize is NULL.
  @retval     RETURN_INVALID_PARAMETER   ResetData is NULL.
  @retval     RETURN_INVALID_PARAMETER   ExtraData was provided without a
                                         ResetSubtype. This is not supported by the
                                         UEFI spec.
  @retval     RETURN_BUFFER_TOO_SMALL    An insufficient buffer was provided.
                                         ResetDataSize is updated with minimum size
                                         required.
**/
RETURN_STATUS
EFIAPI
BuildResetData (
  IN OUT   UINTN     *ResetDataSize,
  IN OUT   VOID      *ResetData,
  IN CONST GUID      *ResetSubtype  OPTIONAL,
  IN CONST CHAR16    *ResetString   OPTIONAL,
  IN       UINTN     ExtraDataSize  OPTIONAL,
  IN CONST VOID      *ExtraData     OPTIONAL
  )
{
  UINTN  ResetStringSize;
  UINTN  ResetDataBufferSize;
  UINT8  *Data;

  //
  // If the size return pointer is NULL.
  //
  if (ResetDataSize == NULL) {
    return RETURN_INVALID_PARAMETER;
  }
  //
  // If extra data is indicated, but pointer is NULL.
  //
  if (ExtraDataSize > 0 && ExtraData == NULL) {
    return RETURN_INVALID_PARAMETER;
  }
  //
  // If extra data is indicated, but no subtype GUID is supplied.
  //
  if (ResetSubtype == NULL && ExtraDataSize > 0) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // Determine the final string.
  //
  if (ResetString == NULL) {
    ResetString = L"";     // Use an empty string.
  }
  
  //
  // Calculate the total buffer required for ResetData.
  //
  ResetStringSize     = StrnSizeS (ResetString, MAX_UINT16);
  ResetDataBufferSize = ResetStringSize + ExtraDataSize;
  if (ResetSubtype != NULL) {
    ResetDataBufferSize += sizeof (GUID);
  }

  //
  // At this point, if the buffer isn't large enough (or if
  // the buffer is NULL) we cannot proceed.
  //
  if (*ResetDataSize < ResetDataBufferSize) {
    *ResetDataSize = ResetDataBufferSize;
    return RETURN_BUFFER_TOO_SMALL;
  }
  *ResetDataSize = ResetDataBufferSize;
  if (ResetData == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // Fill in ResetData with ResetString, the ResetSubtype GUID, and extra data
  //
  Data = (UINT8 *)ResetData;
  CopyMem (Data, ResetString, ResetStringSize);
  Data += ResetStringSize;
  if (ResetSubtype != NULL) {
    CopyMem (Data, ResetSubtype, sizeof (GUID));
    Data += sizeof (GUID);
  }
  if (ExtraDataSize > 0) {
    CopyMem (Data, ExtraData, ExtraDataSize);
  }
  
  return RETURN_SUCCESS;
}
