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