15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_SRC_CROSSCALL_CLIENT_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_CROSSCALL_CLIENT_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_params.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This header defines the CrossCall(..) family of templated functions
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Their purpose is to simulate the syntax of regular call but to generate
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and IPC from the client-side.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The basic pattern is to
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1) use template argument deduction to compute the size of each
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      parameter and the appropriate copy method
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   2) pack the parameters in the appropriate ActualCallParams< > object
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   3) call the IPC interface IPCProvider::DoCall( )
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The general interface of CrossCall is:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  ResultCode CrossCall(IPCProvider& ipc_provider,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                       uint32 tag,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                       const Par1& p1, const Par2& p2,...pn
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                       CrossCallReturn* answer)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  where:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    ipc_provider: is a specific implementation of the ipc transport see
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                  sharedmem_ipc_server.h for an example.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    tag : is the unique id for this IPC call. Is used to route the call to
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//          the appropriate service.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    p1, p2,.. pn : The input parameters of the IPC. Use only simple types
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                   and wide strings (can add support for others).
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    answer : If the IPC was successful. The server-side answer is here. The
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//             interpretation of the answer is private to client and server.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The return value is ALL_OK if the IPC was delivered to the server, other
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return codes indicate that the IPC transport failed to deliver it.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this is the assumed channel size. This can be overridden in a given
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC implementation.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint32 kIPCChannelSize = 1024;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The copy helper uses templates to deduce the appropriate copy function to
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copy the input parameters in the buffer that is going to be send across the
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC. These template facility can be made more sophisticated as need arises.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default copy helper. It catches the general case where no other
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specialized template matches better. We set the type to ULONG_TYPE, so this
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only works with objects whose size is 32 bits.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(const T& t) : t_(t) {}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the pointer to the start of the input.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &t_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the stored value with the value in the buffer. This is not
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supported for this type.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not supported;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the size of the input in bytes.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizeof(T);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current type is used as an In or InOut parameter.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns this object's type.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPILE_ASSERT(sizeof(T) == sizeof(uint32), need_specialization);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ULONG_TYPE;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const T& t_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This copy helper template specialization if for the void pointer
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// case both 32 and 64 bit.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper<void*> {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(void* t) : t_(t) {}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the pointer to the start of the input.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &t_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the stored value with the value in the buffer. This is not
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supported for this type.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not supported;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the size of the input in bytes.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sizeof(t_);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current type is used as an In or InOut parameter.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns this object's type.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return VOIDPTR_TYPE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* t_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This copy helper template specialization catches the cases where the
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter is a pointer to a string.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper<const wchar_t*> {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(const wchar_t* t)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : t_(t) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the pointer to the start of the string.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the stored value with the value in the buffer. This is not
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supported for this type.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not supported;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the size of the string in bytes. We define a NULL string to
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be of zero length.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __try {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return (!t_) ? 0 : static_cast<uint32>(StringLength(t_) * sizeof(t_[0]));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __except(EXCEPTION_EXECUTE_HANDLER) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kuint32max;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current type is used as an In or InOut parameter.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WCHAR_TYPE;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We provide our not very optimized version of wcslen(), since we don't
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // want to risk having the linker use the version in the CRT since the CRT
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // might not be present when we do an early IPC call.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t __cdecl StringLength(const wchar_t* wcs) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const wchar_t *eos = wcs;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (*eos++);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<size_t>(eos - wcs - 1);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* t_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specialization for non-const strings. We just reuse the implementation of the
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const string specialization.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper<wchar_t*> : public CopyHelper<const wchar_t*> {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef CopyHelper<const wchar_t*> Base;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(wchar_t* t) : Base(t) {}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetStart();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::Update(buffer);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetSize();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::IsInOut();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetType();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specialization for wchar_t arrays strings. We just reuse the implementation
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the const string specialization.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<size_t n>
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper<const wchar_t[n]> : public CopyHelper<const wchar_t*> {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef const wchar_t array[n];
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef CopyHelper<const wchar_t*> Base;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(array t) : Base(t) {}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetStart();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::Update(buffer);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetSize();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::IsInOut();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Base::GetType();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generic encapsulation class containing a pointer to a buffer and the
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size of the buffer. It is used by the IPC to be able to pass in/out
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InOutCountedBuffer : public CountedBuffer {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InOutCountedBuffer(void* buffer, uint32 size) : CountedBuffer(buffer, size) {}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This copy helper template specialization catches the cases where the
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter is a an input/output buffer.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CopyHelper<InOutCountedBuffer> {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper(const InOutCountedBuffer t) : t_(t) {}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the pointer to the start of the string.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetStart() const {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t_.Buffer();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the buffer with the value from the new buffer in parameter.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Update(void* buffer) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We are touching user memory, this has to be done from inside a try
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // except.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __try {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memcpy(t_.Buffer(), buffer, t_.Size());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __except(EXCEPTION_EXECUTE_HANDLER) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the size of the string in bytes. We define a NULL string to
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be of zero length.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetSize() const {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return t_.Size();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the current type is used as an In or InOut parameter.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsInOut() {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArgType GetType() {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return INOUTPTR_TYPE;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const InOutCountedBuffer t_;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following two macros make it less error prone the generation
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of CrossCall functions with ever more input parameters.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XCALL_GEN_PARAMS_OBJ(num, params) \
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ActualCallParams<num, kIPCChannelSize> ActualParams; \
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* raw_mem = ipc_provider.GetBuffer(); \
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == raw_mem) \
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SBOX_ERROR_NO_SPACE; \
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ActualParams* params = new(raw_mem) ActualParams(tag);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XCALL_GEN_COPY_PARAM(num, params) \
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kMaxIpcParams >= num, too_many_parameters); \
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CopyHelper<Par##num> ch##num(p##num); \
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->CopyParamIn(num - 1, ch##num.GetStart(), ch##num.GetSize(), \
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ch##num.IsInOut(), ch##num.GetType())) \
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SBOX_ERROR_NO_SPACE;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XCALL_GEN_UPDATE_PARAM(num, params) \
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ch##num.Update(params->GetParamPtr(num-1))) {\
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ipc_provider.FreeBuffer(raw_mem); \
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SBOX_ERROR_BAD_PARAMS; \
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XCALL_GEN_FREE_CHANNEL() \
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_provider.FreeBuffer(raw_mem);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with one input parameter
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1>
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     CrossCallReturn* answer) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(1, call_params);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with two input parameters.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2>
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, CrossCallReturn* answer) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(2, call_params);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with three input parameters.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2, typename Par3>
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, const Par3& p3, CrossCallReturn* answer) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(3, call_params);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(3, call_params);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(3, call_params);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with four input parameters.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          typename Par4>
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, const Par3& p3, const Par4& p4,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     CrossCallReturn* answer) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(4, call_params);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(3, call_params);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(4, call_params);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(3, call_params);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(4, call_params);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with five input parameters.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          typename Par4, typename Par5>
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, const Par3& p3, const Par4& p4,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par5& p5, CrossCallReturn* answer) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(5, call_params);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(3, call_params);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(4, call_params);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(5, call_params);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(3, call_params);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(4, call_params);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(5, call_params);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with six input parameters.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          typename Par4, typename Par5, typename Par6>
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, const Par3& p3, const Par4& p4,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par5& p5, const Par6& p6, CrossCallReturn* answer) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(6, call_params);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(3, call_params);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(4, call_params);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(5, call_params);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(6, call_params);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(3, call_params);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(4, call_params);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(5, call_params);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(6, call_params);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrossCall template with seven input parameters.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          typename Par4, typename Par5, typename Par6, typename Par7>
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par2& p2, const Par3& p3, const Par4& p4,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Par5& p5, const Par6& p6, const Par7& p7,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     CrossCallReturn* answer) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_PARAMS_OBJ(7, call_params);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(1, call_params);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(2, call_params);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(3, call_params);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(4, call_params);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(5, call_params);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(6, call_params);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  XCALL_GEN_COPY_PARAM(7, call_params);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultCode result = ipc_provider.DoCall(call_params, answer);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SBOX_ERROR_CHANNEL_ERROR != result) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(1, call_params);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(2, call_params);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(3, call_params);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(4, call_params);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(5, call_params);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(6, call_params);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_UPDATE_PARAM(7, call_params);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XCALL_GEN_FREE_CHANNEL();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sandbox
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // SANDBOX_SRC_CROSSCALL_CLIENT_H__
484