|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #ifndef SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_ |
|
6 #define SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_ |
|
7 |
|
8 #include <list> |
|
9 |
|
10 #include "base/basictypes.h" |
|
11 #include "base/gtest_prod_util.h" |
|
12 #include "sandbox/win/src/crosscall_params.h" |
|
13 #include "sandbox/win/src/crosscall_server.h" |
|
14 #include "sandbox/win/src/sharedmem_ipc_client.h" |
|
15 |
|
16 // IPC transport implementation that uses shared memory. |
|
17 // This is the server side |
|
18 // |
|
19 // The server side has knowledge about the layout of the shared memory |
|
20 // and the state transitions. Both are explained in sharedmem_ipc_client.h |
|
21 // |
|
22 // As opposed to SharedMemIPClient, the Server object should be one for the |
|
23 // entire lifetime of the target process. The server is in charge of creating |
|
24 // the events (ping, pong) both for the client and for the target that are used |
|
25 // to signal the IPC and also in charge of setting the initial state of the |
|
26 // channels. |
|
27 // |
|
28 // When an IPC is ready, the server relies on being called by on the |
|
29 // ThreadPingEventReady callback. The IPC server then retrieves the buffer, |
|
30 // marshals it into a CrossCallParam object and calls the Dispatcher, who is in |
|
31 // charge of fulfilling the IPC request. |
|
32 namespace sandbox { |
|
33 |
|
34 // the shared memory implementation of the IPC server. There should be one |
|
35 // of these objects per target (IPC client) process |
|
36 class SharedMemIPCServer { |
|
37 public: |
|
38 // Creates the IPC server. |
|
39 // target_process: handle to the target process. It must be suspended. |
|
40 // target_process_id: process id of the target process. |
|
41 // target_job: the job object handle associated with the target process. |
|
42 // thread_provider: a thread provider object. |
|
43 // dispatcher: an object that can service IPC calls. |
|
44 SharedMemIPCServer(HANDLE target_process, DWORD target_process_id, |
|
45 HANDLE target_job, ThreadProvider* thread_provider, |
|
46 Dispatcher* dispatcher); |
|
47 |
|
48 ~SharedMemIPCServer(); |
|
49 |
|
50 // Initializes the server structures, shared memory structures and |
|
51 // creates the kernels events used to signal the IPC. |
|
52 bool Init(void* shared_mem, uint32 shared_size, uint32 channel_size); |
|
53 |
|
54 private: |
|
55 // Allow tests to be marked DISABLED_. Note that FLAKY_ and FAILS_ prefixes |
|
56 // do not work with sandbox tests. |
|
57 FRIEND_TEST_ALL_PREFIXES(IPCTest, SharedMemServerTests); |
|
58 // When an event fires (IPC request). A thread from the ThreadProvider |
|
59 // will call this function. The context parameter should be the same as |
|
60 // provided when ThreadProvider::RegisterWait was called. |
|
61 static void __stdcall ThreadPingEventReady(void* context, |
|
62 unsigned char); |
|
63 |
|
64 // Makes the client and server events. This function is called once |
|
65 // per channel. |
|
66 bool MakeEvents(HANDLE* server_ping, HANDLE* server_pong, |
|
67 HANDLE* client_ping, HANDLE* client_pong); |
|
68 |
|
69 // A copy this structure is maintained per channel. |
|
70 // Note that a lot of the fields are just the same of what we have in the IPC |
|
71 // object itself. It is better to have the copies since we can dispatch in the |
|
72 // static method without worrying about converting back to a member function |
|
73 // call or about threading issues. |
|
74 struct ServerControl { |
|
75 // This channel server ping event. |
|
76 HANDLE ping_event; |
|
77 // This channel server pong event. |
|
78 HANDLE pong_event; |
|
79 // The size of this channel. |
|
80 uint32 channel_size; |
|
81 // The pointer to the actual channel data. |
|
82 char* channel_buffer; |
|
83 // The pointer to the base of the shared memory. |
|
84 char* shared_base; |
|
85 // A pointer to this channel's client-side control structure this structure |
|
86 // lives in the shared memory. |
|
87 ChannelControl* channel; |
|
88 // the IPC dispatcher associated with this channel. |
|
89 Dispatcher* dispatcher; |
|
90 // The target process information associated with this channel. |
|
91 ClientInfo target_info; |
|
92 }; |
|
93 |
|
94 // Looks for the appropriate handler for this IPC and invokes it. |
|
95 static bool InvokeCallback(const ServerControl* service_context, |
|
96 void* ipc_buffer, CrossCallReturn* call_result); |
|
97 |
|
98 // Points to the shared memory channel control which lives at |
|
99 // the start of the shared section. |
|
100 IPCControl* client_control_; |
|
101 |
|
102 // Keeps track of the server side objects that are used to answer an IPC. |
|
103 typedef std::list<ServerControl*> ServerContexts; |
|
104 ServerContexts server_contexts_; |
|
105 |
|
106 // The thread provider provides the threads that call back into this object |
|
107 // when the IPC events fire. |
|
108 ThreadProvider* thread_provider_; |
|
109 |
|
110 // The IPC object is associated with a target process. |
|
111 HANDLE target_process_; |
|
112 |
|
113 // The target process id associated with the IPC object. |
|
114 DWORD target_process_id_; |
|
115 |
|
116 // The target object is inside a job too. |
|
117 HANDLE target_job_object_; |
|
118 |
|
119 // The dispatcher handles 'ready' IPC calls. |
|
120 Dispatcher* call_dispatcher_; |
|
121 |
|
122 DISALLOW_COPY_AND_ASSIGN(SharedMemIPCServer); |
|
123 }; |
|
124 |
|
125 } // namespace sandbox |
|
126 |
|
127 #endif // SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_ |