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_SHAREDMEM_IPC_SERVER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_params.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_server.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sharedmem_ipc_client.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC transport implementation that uses shared memory. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the server side 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The server side has knowledge about the layout of the shared memory 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the state transitions. Both are explained in sharedmem_ipc_client.h 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As opposed to SharedMemIPClient, the Server object should be one for the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entire lifetime of the target process. The server is in charge of creating 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the events (ping, pong) both for the client and for the target that are used 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to signal the IPC and also in charge of setting the initial state of the 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// channels. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When an IPC is ready, the server relies on being called by on the 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ThreadPingEventReady callback. The IPC server then retrieves the buffer, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// marshals it into a CrossCallParam object and calls the Dispatcher, who is in 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// charge of fulfilling the IPC request. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the shared memory implementation of the IPC server. There should be one 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of these objects per target (IPC client) process 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SharedMemIPCServer { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates the IPC server. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_process: handle to the target process. It must be suspended. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_process_id: process id of the target process. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_job: the job object handle associated with the target process. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread_provider: a thread provider object. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dispatcher: an object that can service IPC calls. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SharedMemIPCServer(HANDLE target_process, DWORD target_process_id, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE target_job, ThreadProvider* thread_provider, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher* dispatcher); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~SharedMemIPCServer(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the server structures, shared memory structures and 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // creates the kernels events used to signal the IPC. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(void* shared_mem, uint32 shared_size, uint32 channel_size); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to be marked DISABLED_. Note that FLAKY_ and FAILS_ prefixes 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do not work with sandbox tests. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(IPCTest, SharedMemServerTests); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When an event fires (IPC request). A thread from the ThreadProvider 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will call this function. The context parameter should be the same as 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided when ThreadProvider::RegisterWait was called. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void __stdcall ThreadPingEventReady(void* context, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Makes the client and server events. This function is called once 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // per channel. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool MakeEvents(HANDLE* server_ping, HANDLE* server_pong, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE* client_ping, HANDLE* client_pong); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A copy this structure is maintained per channel. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that a lot of the fields are just the same of what we have in the IPC 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object itself. It is better to have the copies since we can dispatch in the 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // static method without worrying about converting back to a member function 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call or about threading issues. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ServerControl { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This channel server ping event. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE ping_event; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This channel server pong event. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE pong_event; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size of this channel. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 channel_size; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The pointer to the actual channel data. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* channel_buffer; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The pointer to the base of the shared memory. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* shared_base; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pointer to this channel's client-side control structure this structure 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lives in the shared memory. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelControl* channel; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the IPC dispatcher associated with this channel. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher* dispatcher; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The target process information associated with this channel. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientInfo target_info; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Looks for the appropriate handler for this IPC and invokes it. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool InvokeCallback(const ServerControl* service_context, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* ipc_buffer, CrossCallReturn* call_result); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Points to the shared memory channel control which lives at 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the start of the shared section. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPCControl* client_control_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keeps track of the server side objects that are used to answer an IPC. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<ServerControl*> ServerContexts; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServerContexts server_contexts_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The thread provider provides the threads that call back into this object 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when the IPC events fire. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadProvider* thread_provider_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The IPC object is associated with a target process. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE target_process_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The target process id associated with the IPC object. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD target_process_id_; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The target object is inside a job too. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE target_job_object_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The dispatcher handles 'ready' IPC calls. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher* call_dispatcher_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SharedMemIPCServer); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_ 128