159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved.
259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Use of this source code is governed by a BSD-style license that can be
359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// found in the LICENSE file.
459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#ifndef SANDBOX_SRC_CROSSCALL_CLIENT_H_
659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define SANDBOX_SRC_CROSSCALL_CLIENT_H_
759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h>
9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stdint.h>
10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
1159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/crosscall_params.h"
1259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/sandbox.h"
1359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This header defines the CrossCall(..) family of templated functions
1559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Their purpose is to simulate the syntax of regular call but to generate
1659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// and IPC from the client-side.
1759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
1859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The basic pattern is to
1959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   1) use template argument deduction to compute the size of each
2059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      parameter and the appropriate copy method
2159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   2) pack the parameters in the appropriate ActualCallParams< > object
2259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   3) call the IPC interface IPCProvider::DoCall( )
2359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
2459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The general interface of CrossCall is:
2559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  ResultCode CrossCall(IPCProvider& ipc_provider,
26cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//                       uint32_t tag,
2759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                       const Par1& p1, const Par2& p2,...pn
2859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                       CrossCallReturn* answer)
2959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
3059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  where:
3159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//    ipc_provider: is a specific implementation of the ipc transport see
3259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                  sharedmem_ipc_server.h for an example.
3359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//    tag : is the unique id for this IPC call. Is used to route the call to
3459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//          the appropriate service.
3559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//    p1, p2,.. pn : The input parameters of the IPC. Use only simple types
3659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                   and wide strings (can add support for others).
3759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//    answer : If the IPC was successful. The server-side answer is here. The
3859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//             interpretation of the answer is private to client and server.
3959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
4059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The return value is ALL_OK if the IPC was delivered to the server, other
4159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// return codes indicate that the IPC transport failed to deliver it.
4259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace sandbox {
4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// this is the assumed channel size. This can be overridden in a given
4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// IPC implementation.
46cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst uint32_t kIPCChannelSize = 1024;
4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The copy helper uses templates to deduce the appropriate copy function to
4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// copy the input parameters in the buffer that is going to be send across the
5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// IPC. These template facility can be made more sophisticated as need arises.
5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
5259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The default copy helper. It catches the general case where no other
5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// specialized template matches better. We set the type to UINT32_TYPE, so this
5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// only works with objects whose size is 32 bits.
5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<typename T>
5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper {
5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(const T& t) : t_(t) {}
5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
6059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the pointer to the start of the input.
6159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
6259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return &t_;
6359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
6459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
6559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Update the stored value with the value in the buffer. This is not
6659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // supported for this type.
6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
6859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    // Not supported;
6959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the size of the input in bytes.
73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const { return sizeof(T); }
7459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
7559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns true if the current type is used as an In or InOut parameter.
7659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
7759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return false;
7859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
7959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
8059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns this object's type.
8159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
82cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    static_assert(sizeof(T) == sizeof(uint32_t), "specialization needed");
8359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return UINT32_TYPE;
8459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
8559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
8659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private:
8759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const T& t_;
8859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
8959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
9059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This copy helper template specialization if for the void pointer
9159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// case both 32 and 64 bit.
9259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
9359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper<void*> {
9459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
9559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(void* t) : t_(t) {}
9659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
9759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the pointer to the start of the input.
9859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
9959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return &t_;
10059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
10159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
10259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Update the stored value with the value in the buffer. This is not
10359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // supported for this type.
10459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
10559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    // Not supported;
10659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
10759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
10859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
10959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the size of the input in bytes.
110cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const { return sizeof(t_); }
11159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
11259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns true if the current type is used as an In or InOut parameter.
11359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
11459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return false;
11559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
11659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
11759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns this object's type.
11859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
11959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return VOIDPTR_TYPE;
12059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
12159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
12259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private:
12359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* t_;
12459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
12559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
12659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This copy helper template specialization catches the cases where the
12759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameter is a pointer to a string.
12859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
12959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper<const wchar_t*> {
13059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
13159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(const wchar_t* t)
13259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : t_(t) {
13359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
13459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
13559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the pointer to the start of the string.
13659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
13759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return t_;
13859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
13959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
14059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Update the stored value with the value in the buffer. This is not
14159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // supported for this type.
14259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
14359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    // Not supported;
14459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
14559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
14659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
14759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the size of the string in bytes. We define a NULL string to
14859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // be of zero length.
149cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const {
15059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    __try {
151cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return (!t_) ? 0
152cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                   : static_cast<uint32_t>(StringLength(t_) * sizeof(t_[0]));
15359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
15459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    __except(EXCEPTION_EXECUTE_HANDLER) {
155cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return UINT32_MAX;
15659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
15759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
15859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
15959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns true if the current type is used as an In or InOut parameter.
16059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
16159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return false;
16259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
16359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
16459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
16559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return WCHAR_TYPE;
16659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
16759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
16859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private:
16959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // We provide our not very optimized version of wcslen(), since we don't
17059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // want to risk having the linker use the version in the CRT since the CRT
17159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // might not be present when we do an early IPC call.
17259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  static size_t __cdecl StringLength(const wchar_t* wcs) {
17359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    const wchar_t *eos = wcs;
17459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    while (*eos++);
17559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return static_cast<size_t>(eos - wcs - 1);
17659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
17759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
17859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const wchar_t* t_;
17959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
18059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
18159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Specialization for non-const strings. We just reuse the implementation of the
18259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// const string specialization.
18359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
18459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper<wchar_t*> : public CopyHelper<const wchar_t*> {
18559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
18659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  typedef CopyHelper<const wchar_t*> Base;
18759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(wchar_t* t) : Base(t) {}
18859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
18959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
19059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::GetStart();
19159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
19259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
19359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
19459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::Update(buffer);
19559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
19659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
197cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const { return Base::GetSize(); }
19859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
19959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
20059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::IsInOut();
20159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
20259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
20359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
20459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::GetType();
20559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
20659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
20759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
20859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Specialization for wchar_t arrays strings. We just reuse the implementation
20959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// of the const string specialization.
21059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<size_t n>
21159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper<const wchar_t[n]> : public CopyHelper<const wchar_t*> {
21259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
21359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  typedef const wchar_t array[n];
21459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  typedef CopyHelper<const wchar_t*> Base;
21559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(array t) : Base(t) {}
21659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
21759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
21859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::GetStart();
21959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
22059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
22159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
22259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::Update(buffer);
22359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
22459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
225cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const { return Base::GetSize(); }
22659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
22759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
22859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::IsInOut();
22959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
23059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
23159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
23259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return Base::GetType();
23359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
23459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
23559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
23659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Generic encapsulation class containing a pointer to a buffer and the
23759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// size of the buffer. It is used by the IPC to be able to pass in/out
23859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameters.
23959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass InOutCountedBuffer : public CountedBuffer {
24059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
241cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  InOutCountedBuffer(void* buffer, uint32_t size)
242cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : CountedBuffer(buffer, size) {}
24359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
24459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
24559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This copy helper template specialization catches the cases where the
24659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameter is a an input/output buffer.
24759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
24859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CopyHelper<InOutCountedBuffer> {
24959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
25059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper(const InOutCountedBuffer t) : t_(t) {}
25159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
25259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the pointer to the start of the string.
25359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* GetStart() const {
25459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return t_.Buffer();
25559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
25659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
25759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Updates the buffer with the value from the new buffer in parameter.
25859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Update(void* buffer) {
25959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    // We are touching user memory, this has to be done from inside a try
26059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    // except.
26159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    __try {
26259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      memcpy(t_.Buffer(), buffer, t_.Size());
26359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
26459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    __except(EXCEPTION_EXECUTE_HANDLER) {
26559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      return false;
26659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
26759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
26859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
26959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
27059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns the size of the string in bytes. We define a NULL string to
27159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // be of zero length.
272cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  uint32_t GetSize() const { return t_.Size(); }
27359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
27459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Returns true if the current type is used as an In or InOut parameter.
27559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsInOut() {
27659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
27759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
27859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
27959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType GetType() {
28059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return INOUTPTR_TYPE;
28159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
28259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
28359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private:
28459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const InOutCountedBuffer t_;
28559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
28659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
28759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The following two macros make it less error prone the generation
28859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// of CrossCall functions with ever more input parameters.
28959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
29059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define XCALL_GEN_PARAMS_OBJ(num, params) \
29159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  typedef ActualCallParams<num, kIPCChannelSize> ActualParams; \
29259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  void* raw_mem = ipc_provider.GetBuffer(); \
29359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (NULL == raw_mem) \
29459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return SBOX_ERROR_NO_SPACE; \
29559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ActualParams* params = new(raw_mem) ActualParams(tag);
29659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
29759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define XCALL_GEN_COPY_PARAM(num, params) \
29859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  static_assert(kMaxIpcParams >= num, "too many parameters"); \
29959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CopyHelper<Par##num> ch##num(p##num); \
30059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (!params->CopyParamIn(num - 1, ch##num.GetStart(), ch##num.GetSize(), \
30159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat                           ch##num.IsInOut(), ch##num.GetType())) \
30259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return SBOX_ERROR_NO_SPACE;
30359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
30459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define XCALL_GEN_UPDATE_PARAM(num, params) \
30559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (!ch##num.Update(params->GetParamPtr(num-1))) {\
30659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    ipc_provider.FreeBuffer(raw_mem); \
30759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return SBOX_ERROR_BAD_PARAMS; \
30859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
30959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
31059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define XCALL_GEN_FREE_CHANNEL() \
31159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ipc_provider.FreeBuffer(raw_mem);
31259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
31359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with one input parameter
31459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename IPCProvider, typename Par1>
315cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
316cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
317cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
31859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat                     CrossCallReturn* answer) {
31959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(1, call_params);
32059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
32159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
32259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
32359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
32459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
32559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
32659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
32759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
32859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
32959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
33059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
33159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
33259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with two input parameters.
33359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename IPCProvider, typename Par1, typename Par2>
334cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
335cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
336cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
337cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
338cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     CrossCallReturn* answer) {
33959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(2, call_params);
34059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
34159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
34259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
34359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
34459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
34559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
34659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
34759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
34859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
34959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
35059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
35159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
35259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
35359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with three input parameters.
35459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename IPCProvider, typename Par1, typename Par2, typename Par3>
355cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
356cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
357cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
358cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
359cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par3& p3,
360cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     CrossCallReturn* answer) {
36159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(3, call_params);
36259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
36359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
36459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(3, call_params);
36559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
36659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
36759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
36859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
36959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
37059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
37159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(3, call_params);
37259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
37359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
37459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
37559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
37659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
37759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with four input parameters.
378cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename IPCProvider,
379cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par1,
380cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par2,
381cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par3,
38259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat          typename Par4>
383cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
384cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
385cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
386cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
387cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par3& p3,
388cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par4& p4,
38959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat                     CrossCallReturn* answer) {
39059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(4, call_params);
39159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
39259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
39359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(3, call_params);
39459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(4, call_params);
39559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
39659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
39759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
39859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
39959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
40059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
40159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(3, call_params);
40259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(4, call_params);
40359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
40459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
40559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
40659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
40759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
40859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with five input parameters.
409cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename IPCProvider,
410cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par1,
411cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par2,
412cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par3,
413cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par4,
414cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par5>
415cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
416cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
417cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
418cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
419cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par3& p3,
420cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par4& p4,
421cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par5& p5,
422cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     CrossCallReturn* answer) {
42359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(5, call_params);
42459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
42559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
42659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(3, call_params);
42759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(4, call_params);
42859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(5, call_params);
42959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
43059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
43159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
43259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
43359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
43459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
43559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(3, call_params);
43659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(4, call_params);
43759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(5, call_params);
43859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
43959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
44059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
44159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
44259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
44359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with six input parameters.
444cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename IPCProvider,
445cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par1,
446cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par2,
447cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par3,
448cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par4,
449cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par5,
450cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par6>
451cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
452cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
453cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
454cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
455cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par3& p3,
456cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par4& p4,
457cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par5& p5,
458cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par6& p6,
459cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     CrossCallReturn* answer) {
46059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(6, call_params);
46159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
46259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
46359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(3, call_params);
46459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(4, call_params);
46559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(5, call_params);
46659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(6, call_params);
46759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
46859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
46959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
47059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
47159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
47259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
47359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(3, call_params);
47459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(4, call_params);
47559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(5, call_params);
47659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(6, call_params);
47759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
47859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
47959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
48059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
48159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
48259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCall template with seven input parameters.
483cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename IPCProvider,
484cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par1,
485cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par2,
486cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par3,
487cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par4,
488cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par5,
489cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par6,
490cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          typename Par7>
491cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoResultCode CrossCall(IPCProvider& ipc_provider,
492cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     uint32_t tag,
493cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par1& p1,
494cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par2& p2,
495cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par3& p3,
496cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par4& p4,
497cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par5& p5,
498cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par6& p6,
499cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                     const Par7& p7,
50059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat                     CrossCallReturn* answer) {
50159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_PARAMS_OBJ(7, call_params);
50259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(1, call_params);
50359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(2, call_params);
50459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(3, call_params);
50559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(4, call_params);
50659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(5, call_params);
50759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(6, call_params);
50859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  XCALL_GEN_COPY_PARAM(7, call_params);
50959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
51059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ResultCode result = ipc_provider.DoCall(call_params, answer);
51159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
51259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  if (SBOX_ERROR_CHANNEL_ERROR != result) {
51359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(1, call_params);
51459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(2, call_params);
51559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(3, call_params);
51659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(4, call_params);
51759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(5, call_params);
51859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(6, call_params);
51959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_UPDATE_PARAM(7, call_params);
52059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    XCALL_GEN_FREE_CHANNEL();
52159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
52259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return result;
52359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}
52459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}  // namespace sandbox
52559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
52659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif  // SANDBOX_SRC_CROSSCALL_CLIENT_H__
527