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