// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SANDBOX_SRC_CROSSCALL_CLIENT_H_
#define SANDBOX_SRC_CROSSCALL_CLIENT_H_

#include <stddef.h>
#include <stdint.h>

#include "base/compiler_specific.h"
#include "sandbox/win/src/crosscall_params.h"
#include "sandbox/win/src/sandbox.h"

// This header defines the CrossCall(..) family of templated functions
// Their purpose is to simulate the syntax of regular call but to generate
// and IPC from the client-side.
//
// The basic pattern is to
//   1) use template argument deduction to compute the size of each
//      parameter and the appropriate copy method
//   2) pack the parameters in the appropriate ActualCallParams< > object
//   3) call the IPC interface IPCProvider::DoCall( )
//
// The general interface of CrossCall is:
//  ResultCode CrossCall(IPCProvider& ipc_provider,
//                       uint32_t tag,
//                       const Par1& p1, const Par2& p2,...pn
//                       CrossCallReturn* answer)
//
//  where:
//    ipc_provider: is a specific implementation of the ipc transport see
//                  sharedmem_ipc_server.h for an example.
//    tag : is the unique id for this IPC call. Is used to route the call to
//          the appropriate service.
//    p1, p2,.. pn : The input parameters of the IPC. Use only simple types
//                   and wide strings (can add support for others).
//    answer : If the IPC was successful. The server-side answer is here. The
//             interpretation of the answer is private to client and server.
//
// The return value is ALL_OK if the IPC was delivered to the server, other
// return codes indicate that the IPC transport failed to deliver it.
namespace sandbox {

// this is the assumed channel size. This can be overridden in a given
// IPC implementation.
const uint32_t kIPCChannelSize = 1024;

// The copy helper uses templates to deduce the appropriate copy function to
// copy the input parameters in the buffer that is going to be send across the
// IPC. These template facility can be made more sophisticated as need arises.

// The default copy helper. It catches the general case where no other
// specialized template matches better. We set the type to UINT32_TYPE, so this
// only works with objects whose size is 32 bits.
template <typename T>
class CopyHelper {
 public:
  CopyHelper(const T& t) : t_(t) {}

  // Returns the pointer to the start of the input.
  const void* GetStart() const { return &t_; }

  // Update the stored value with the value in the buffer. This is not
  // supported for this type.
  bool Update(void* buffer) {
    // Not supported;
    return true;
  }

  // Returns the size of the input in bytes.
  uint32_t GetSize() const { return sizeof(T); }

  // Returns true if the current type is used as an In or InOut parameter.
  bool IsInOut() { return false; }

  // Returns this object's type.
  ArgType GetType() {
    static_assert(sizeof(T) == sizeof(uint32_t), "specialization needed");
    return UINT32_TYPE;
  }

 private:
  const T& t_;
};

// This copy helper template specialization if for the void pointer
// case both 32 and 64 bit.
template <>
class CopyHelper<void*> {
 public:
  CopyHelper(void* t) : t_(t) {}

  // Returns the pointer to the start of the input.
  const void* GetStart() const { return &t_; }

  // Update the stored value with the value in the buffer. This is not
  // supported for this type.
  bool Update(void* buffer) {
    // Not supported;
    return true;
  }

  // Returns the size of the input in bytes.
  uint32_t GetSize() const { return sizeof(t_); }

  // Returns true if the current type is used as an In or InOut parameter.
  bool IsInOut() { return false; }

  // Returns this object's type.
  ArgType GetType() { return VOIDPTR_TYPE; }

 private:
  const void* t_;
};

// This copy helper template specialization catches the cases where the
// parameter is a pointer to a string.
template <>
class CopyHelper<const wchar_t*> {
 public:
  CopyHelper(const wchar_t* t) : t_(t) {}

  // Returns the pointer to the start of the string.
  const void* GetStart() const { return t_; }

  // Update the stored value with the value in the buffer. This is not
  // supported for this type.
  bool Update(void* buffer) {
    // Not supported;
    return true;
  }

  // Returns the size of the string in bytes. We define a nullptr string to
  // be of zero length.
  uint32_t GetSize() const {
    __try {
      return (!t_) ? 0
                   : static_cast<uint32_t>(StringLength(t_) * sizeof(t_[0]));
    } __except (EXCEPTION_EXECUTE_HANDLER) {
      return UINT32_MAX;
    }
  }

  // Returns true if the current type is used as an In or InOut parameter.
  bool IsInOut() { return false; }

  ArgType GetType() { return WCHAR_TYPE; }

 private:
  // We provide our not very optimized version of wcslen(), since we don't
  // want to risk having the linker use the version in the CRT since the CRT
  // might not be present when we do an early IPC call.
  static size_t CDECL StringLength(const wchar_t* wcs) {
    const wchar_t* eos = wcs;
    while (*eos++)
      ;
    return static_cast<size_t>(eos - wcs - 1);
  }

  const wchar_t* t_;
};

// Specialization for non-const strings. We just reuse the implementation of the
// const string specialization.
template <>
class CopyHelper<wchar_t*> : public CopyHelper<const wchar_t*> {
 public:
  typedef CopyHelper<const wchar_t*> Base;
  CopyHelper(wchar_t* t) : Base(t) {}

  const void* GetStart() const { return Base::GetStart(); }

  bool Update(void* buffer) { return Base::Update(buffer); }

  uint32_t GetSize() const { return Base::GetSize(); }

  bool IsInOut() { return Base::IsInOut(); }

  ArgType GetType() { return Base::GetType(); }
};

// Specialization for wchar_t arrays strings. We just reuse the implementation
// of the const string specialization.
template <size_t n>
class CopyHelper<const wchar_t[n]> : public CopyHelper<const wchar_t*> {
 public:
  typedef const wchar_t array[n];
  typedef CopyHelper<const wchar_t*> Base;
  CopyHelper(array t) : Base(t) {}

  const void* GetStart() const { return Base::GetStart(); }

  bool Update(void* buffer) { return Base::Update(buffer); }

  uint32_t GetSize() const { return Base::GetSize(); }

  bool IsInOut() { return Base::IsInOut(); }

  ArgType GetType() { return Base::GetType(); }
};

// Generic encapsulation class containing a pointer to a buffer and the
// size of the buffer. It is used by the IPC to be able to pass in/out
// parameters.
class InOutCountedBuffer : public CountedBuffer {
 public:
  InOutCountedBuffer(void* buffer, uint32_t size)
      : CountedBuffer(buffer, size) {}
};

// This copy helper template specialization catches the cases where the
// parameter is a an input/output buffer.
template <>
class CopyHelper<InOutCountedBuffer> {
 public:
  CopyHelper(const InOutCountedBuffer t) : t_(t) {}

  // Returns the pointer to the start of the string.
  const void* GetStart() const { return t_.Buffer(); }

  // Updates the buffer with the value from the new buffer in parameter.
  bool Update(void* buffer) {
    // We are touching user memory, this has to be done from inside a try
    // except.
    __try {
      memcpy(t_.Buffer(), buffer, t_.Size());
    } __except (EXCEPTION_EXECUTE_HANDLER) {
      return false;
    }
    return true;
  }

  // Returns the size of the string in bytes. We define a nullptr string to
  // be of zero length.
  uint32_t GetSize() const { return t_.Size(); }

  // Returns true if the current type is used as an In or InOut parameter.
  bool IsInOut() { return true; }

  ArgType GetType() { return INOUTPTR_TYPE; }

 private:
  const InOutCountedBuffer t_;
};

// The following two macros make it less error prone the generation
// of CrossCall functions with ever more input parameters.

#define XCALL_GEN_PARAMS_OBJ(num, params)                      \
  typedef ActualCallParams<num, kIPCChannelSize> ActualParams; \
  void* raw_mem = ipc_provider.GetBuffer();                    \
  if (!raw_mem)                                                \
    return SBOX_ERROR_NO_SPACE;                                \
  ActualParams* params = new (raw_mem) ActualParams(tag);

#define XCALL_GEN_COPY_PARAM(num, params)                                  \
  static_assert(kMaxIpcParams >= num, "too many parameters");              \
  CopyHelper<Par##num> ch##num(p##num);                                    \
  if (!params->CopyParamIn(num - 1, ch##num.GetStart(), ch##num.GetSize(), \
                           ch##num.IsInOut(), ch##num.GetType()))          \
    return SBOX_ERROR_NO_SPACE;

#define XCALL_GEN_UPDATE_PARAM(num, params)            \
  if (!ch##num.Update(params->GetParamPtr(num - 1))) { \
    ipc_provider.FreeBuffer(raw_mem);                  \
    return SBOX_ERROR_BAD_PARAMS;                      \
  }

#define XCALL_GEN_FREE_CHANNEL() ipc_provider.FreeBuffer(raw_mem);

// CrossCall template with one input parameter
template <typename IPCProvider, typename Par1>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(1, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }

  return result;
}

// CrossCall template with two input parameters.
template <typename IPCProvider, typename Par1, typename Par2>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(2, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}

// CrossCall template with three input parameters.
template <typename IPCProvider, typename Par1, typename Par2, typename Par3>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     const Par3& p3,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(3, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);
  XCALL_GEN_COPY_PARAM(3, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_UPDATE_PARAM(3, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}

// CrossCall template with four input parameters.
template <typename IPCProvider,
          typename Par1,
          typename Par2,
          typename Par3,
          typename Par4>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     const Par3& p3,
                     const Par4& p4,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(4, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);
  XCALL_GEN_COPY_PARAM(3, call_params);
  XCALL_GEN_COPY_PARAM(4, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_UPDATE_PARAM(3, call_params);
    XCALL_GEN_UPDATE_PARAM(4, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}

// CrossCall template with five input parameters.
template <typename IPCProvider,
          typename Par1,
          typename Par2,
          typename Par3,
          typename Par4,
          typename Par5>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     const Par3& p3,
                     const Par4& p4,
                     const Par5& p5,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(5, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);
  XCALL_GEN_COPY_PARAM(3, call_params);
  XCALL_GEN_COPY_PARAM(4, call_params);
  XCALL_GEN_COPY_PARAM(5, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_UPDATE_PARAM(3, call_params);
    XCALL_GEN_UPDATE_PARAM(4, call_params);
    XCALL_GEN_UPDATE_PARAM(5, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}

// CrossCall template with six input parameters.
template <typename IPCProvider,
          typename Par1,
          typename Par2,
          typename Par3,
          typename Par4,
          typename Par5,
          typename Par6>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     const Par3& p3,
                     const Par4& p4,
                     const Par5& p5,
                     const Par6& p6,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(6, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);
  XCALL_GEN_COPY_PARAM(3, call_params);
  XCALL_GEN_COPY_PARAM(4, call_params);
  XCALL_GEN_COPY_PARAM(5, call_params);
  XCALL_GEN_COPY_PARAM(6, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_UPDATE_PARAM(3, call_params);
    XCALL_GEN_UPDATE_PARAM(4, call_params);
    XCALL_GEN_UPDATE_PARAM(5, call_params);
    XCALL_GEN_UPDATE_PARAM(6, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}

// CrossCall template with seven input parameters.
template <typename IPCProvider,
          typename Par1,
          typename Par2,
          typename Par3,
          typename Par4,
          typename Par5,
          typename Par6,
          typename Par7>
ResultCode CrossCall(IPCProvider& ipc_provider,
                     uint32_t tag,
                     const Par1& p1,
                     const Par2& p2,
                     const Par3& p3,
                     const Par4& p4,
                     const Par5& p5,
                     const Par6& p6,
                     const Par7& p7,
                     CrossCallReturn* answer) {
  XCALL_GEN_PARAMS_OBJ(7, call_params);
  XCALL_GEN_COPY_PARAM(1, call_params);
  XCALL_GEN_COPY_PARAM(2, call_params);
  XCALL_GEN_COPY_PARAM(3, call_params);
  XCALL_GEN_COPY_PARAM(4, call_params);
  XCALL_GEN_COPY_PARAM(5, call_params);
  XCALL_GEN_COPY_PARAM(6, call_params);
  XCALL_GEN_COPY_PARAM(7, call_params);

  ResultCode result = ipc_provider.DoCall(call_params, answer);

  if (SBOX_ERROR_CHANNEL_ERROR != result) {
    XCALL_GEN_UPDATE_PARAM(1, call_params);
    XCALL_GEN_UPDATE_PARAM(2, call_params);
    XCALL_GEN_UPDATE_PARAM(3, call_params);
    XCALL_GEN_UPDATE_PARAM(4, call_params);
    XCALL_GEN_UPDATE_PARAM(5, call_params);
    XCALL_GEN_UPDATE_PARAM(6, call_params);
    XCALL_GEN_UPDATE_PARAM(7, call_params);
    XCALL_GEN_FREE_CHANNEL();
  }
  return result;
}
}  // namespace sandbox

#endif  // SANDBOX_SRC_CROSSCALL_CLIENT_H__
