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