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.
5 #ifndef SANDBOX_SRC_CROSSCALL_SERVER_H_
6 #define SANDBOX_SRC_CROSSCALL_SERVER_H_
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/strings/string16.h"
13 #include "sandbox/win/src/crosscall_params.h"
15 // This is the IPC server interface for CrossCall: The IPC for the Sandbox
16 // On the server, CrossCall needs two things:
17 // 1) threads: Or better said, someone to provide them, that is what the
18 // ThreadProvider interface is defined for. These thread(s) are
19 // the ones that will actually execute the IPC data retrieval.
21 // 2) a dispatcher: This interface represents the way to route and process
22 // an IPC call given the IPC tag.
24 // The other class included here CrossCallParamsEx is the server side version
25 // of the CrossCallParams class of /sandbox/crosscall_params.h The difference
26 // is that the sever version is paranoid about the correctness of the IPC
27 // message and will do all sorts of verifications.
29 // A general diagram of the interaction is as follows:
33 // ThreadProvider <--(1)Register--| IPC |
37 // IPC fired --callback ------>| |--(3)---> Dispatcher
41 // The IPC implementation sits as a middleman between the handling of the
42 // specifics of scheduling a thread to service the IPC and the multiple
43 // entities that can potentially serve each particular IPC.
46 class InterceptionManager
;
48 // This function signature is required as the callback when an IPC call fires.
49 // context: a user-defined pointer that was set using ThreadProvider
50 // reason: 0 if the callback was fired because of a timeout.
51 // 1 if the callback was fired because of an event.
52 typedef void (__stdcall
* CrossCallIPCCallback
)(void* context
,
53 unsigned char reason
);
55 // ThreadProvider models a thread factory. The idea is to decouple thread
56 // creation and lifetime from the inner guts of the IPC. The contract is
58 // - the IPC implementation calls RegisterWait with a waitable object that
59 // becomes signaled when an IPC arrives and needs to be serviced.
60 // - when the waitable object becomes signaled, the thread provider conjures
61 // a thread that calls the callback (CrossCallIPCCallback) function
62 // - the callback function tries its best not to block and return quickly
63 // and should not assume that the next callback will use the same thread
64 // - when the callback returns the ThreadProvider owns again the thread
65 // and can destroy it or keep it around.
66 class ThreadProvider
{
68 // Registers a waitable object with the thread provider.
69 // client: A number to associate with all the RegisterWait calls, typically
70 // this is the address of the caller object. This parameter cannot
72 // waitable_object : a kernel object that can be waited on
73 // callback: a function pointer which is the function that will be called
74 // when the waitable object fires
75 // context: a user-provider pointer that is passed back to the callback
77 virtual bool RegisterWait(const void* client
, HANDLE waitable_object
,
78 CrossCallIPCCallback callback
,
81 // Removes all the registrations done with the same cookie parameter.
82 // This frees internal thread pool resources.
83 virtual bool UnRegisterWaits(void* cookie
) = 0;
84 virtual ~ThreadProvider() {}
87 // Models the server-side of the original input parameters.
88 // Provides IPC buffer validation and it is capable of reading the parameters
89 // out of the IPC buffer.
90 class CrossCallParamsEx
: public CrossCallParams
{
92 // Factory constructor. Pass an IPCbuffer (and buffer size) that contains a
93 // pending IPCcall. This constructor will:
94 // 1) validate the IPC buffer. returns NULL is the IPCbuffer is malformed.
95 // 2) make a copy of the IPCbuffer (parameter capture)
96 static CrossCallParamsEx
* CreateFromBuffer(void* buffer_base
,
100 // Provides IPCinput parameter raw access:
101 // index : the parameter to read; 0 is the first parameter
102 // returns NULL if the parameter is non-existent. If it exists it also
103 // returns the size in *size
104 void* GetRawParameter(uint32 index
, uint32
* size
, ArgType
* type
);
106 // Gets a parameter that is four bytes in size.
107 // Returns false if the parameter does not exist or is not 32 bits wide.
108 bool GetParameter32(uint32 index
, uint32
* param
);
110 // Gets a parameter that is void pointer in size.
111 // Returns false if the parameter does not exist or is not void pointer sized.
112 bool GetParameterVoidPtr(uint32 index
, void** param
);
114 // Gets a parameter that is a string. Returns false if the parameter does not
116 bool GetParameterStr(uint32 index
, base::string16
* string
);
118 // Gets a parameter that is an in/out buffer. Returns false is the parameter
119 // does not exist or if the size of the actual parameter is not equal to the
121 bool GetParameterPtr(uint32 index
, uint32 expected_size
, void** pointer
);
123 // Frees the memory associated with the IPC parameters.
124 static void operator delete(void* raw_memory
) throw();
127 // Only the factory method CreateFromBuffer can construct these objects.
130 ParamInfo param_info_
[1];
131 DISALLOW_COPY_AND_ASSIGN(CrossCallParamsEx
);
134 // Simple helper function that sets the members of CrossCallReturn
135 // to the proper state to signal a basic error.
136 void SetCallError(ResultCode error
, CrossCallReturn
* call_return
);
138 // Sets the internal status of call_return to signify the that IPC call
139 // completed successfully.
140 void SetCallSuccess(CrossCallReturn
* call_return
);
142 // Represents the client process that initiated the IPC which boils down to the
143 // process handle and the job object handle that contains the client process.
150 // All IPC-related information to be passed to the IPC handler.
153 const ClientInfo
* client_info
;
154 CrossCallReturn return_info
;
157 // This structure identifies IPC signatures.
160 ArgType args
[kMaxIpcParams
];
162 bool Matches(IPCParams
* other
) const {
163 return !memcmp(this, other
, sizeof(*other
));
167 // Models an entity that can process an IPC message or it can route to another
168 // one that could handle it. When an IPC arrives the IPC implementation will:
169 // 1) call OnMessageReady() with the tag of the pending IPC. If the dispatcher
170 // returns NULL it means that it cannot handle this IPC but if it returns
171 // non-null, it must be the pointer to a dispatcher that can handle it.
172 // 2) When the IPC finally obtains a valid Dispatcher the IPC
173 // implementation creates a CrossCallParamsEx from the raw IPC buffer.
174 // 3) It calls the returned callback, with the IPC info and arguments.
177 // Called from the IPC implementation to handle a specific IPC message.
178 typedef bool (Dispatcher::*CallbackGeneric
)();
179 typedef bool (Dispatcher::*Callback0
)(IPCInfo
* ipc
);
180 typedef bool (Dispatcher::*Callback1
)(IPCInfo
* ipc
, void* p1
);
181 typedef bool (Dispatcher::*Callback2
)(IPCInfo
* ipc
, void* p1
, void* p2
);
182 typedef bool (Dispatcher::*Callback3
)(IPCInfo
* ipc
, void* p1
, void* p2
,
184 typedef bool (Dispatcher::*Callback4
)(IPCInfo
* ipc
, void* p1
, void* p2
,
186 typedef bool (Dispatcher::*Callback5
)(IPCInfo
* ipc
, void* p1
, void* p2
,
187 void* p3
, void* p4
, void* p5
);
188 typedef bool (Dispatcher::*Callback6
)(IPCInfo
* ipc
, void* p1
, void* p2
,
189 void* p3
, void* p4
, void* p5
, void* p6
);
190 typedef bool (Dispatcher::*Callback7
)(IPCInfo
* ipc
, void* p1
, void* p2
,
191 void* p3
, void* p4
, void* p5
, void* p6
,
193 typedef bool (Dispatcher::*Callback8
)(IPCInfo
* ipc
, void* p1
, void* p2
,
194 void* p3
, void* p4
, void* p5
, void* p6
,
196 typedef bool (Dispatcher::*Callback9
)(IPCInfo
* ipc
, void* p1
, void* p2
,
197 void* p3
, void* p4
, void* p5
, void* p6
,
198 void* p7
, void* p8
, void* p9
);
200 // Called from the IPC implementation when an IPC message is ready override
201 // on a derived class to handle a set of IPC messages. Return NULL if your
202 // subclass does not handle the message or return the pointer to the subclass
203 // that can handle it.
204 virtual Dispatcher
* OnMessageReady(IPCParams
* ipc
, CallbackGeneric
* callback
);
206 // Called when a target proces is created, to setup the interceptions related
207 // with the given service (IPC).
208 virtual bool SetupService(InterceptionManager
* manager
, int service
) = 0;
210 virtual ~Dispatcher() {}
213 // Structure that defines an IPC Call with all the parameters and the handler.
216 CallbackGeneric callback
;
219 // List of IPC Calls supported by the class.
220 std::vector
<IPCCall
> ipc_calls_
;
223 } // namespace sandbox
225 #endif // SANDBOX_SRC_CROSSCALL_SERVER_H_