// 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 "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 NULL 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 NULL 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 (NULL == 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__
