ReactOS 0.4.16-dev-1946-g52006dd
cproxy.c
Go to the documentation of this file.
1/*
2 * COM proxy implementation
3 *
4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2009 Alexandre Julliard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23
24#define COBJMACROS
25
26#include "windef.h"
27#include "winbase.h"
28#include "winerror.h"
29
30#include "objbase.h"
31#include "rpcproxy.h"
32
33#include "cpsf.h"
34#include "ndr_misc.h"
35#include "ndr_stubless.h"
36#include "wine/asm.h"
37#include "wine/debug.h"
38
40
41static const IRpcProxyBufferVtbl StdProxy_Vtbl;
42
44{
45 return CONTAINING_RECORD(iface, StdProxyImpl, IRpcProxyBuffer_iface);
46}
47
48static inline StdProxyImpl *impl_from_proxy_obj( void *iface )
49{
50 return CONTAINING_RECORD(iface, StdProxyImpl, PVtbl);
51}
52
53extern void ObjectStublessClient3(void);
54extern void ObjectStublessClient4(void);
55
56BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
57{
58 size_t entry_size = (char *)ObjectStublessClient4 - (char *)ObjectStublessClient3;
59 const void **entry = (const void **)(vtbl + 1);
60 DWORD i;
61
62 if (num >= NB_THUNK_ENTRIES)
63 {
64 FIXME( "%lu methods not supported\n", num );
65 return FALSE;
66 }
67 for (i = 0; i < num - 3; i++, entry++)
68 if (*entry == (void *)-1) *entry = (char *)ObjectStublessClient3 + i * entry_size;
69
70 return TRUE;
71}
72
74 LPUNKNOWN pUnkOuter,
75 const ProxyFileInfo *ProxyInfo,
76 int Index,
77 LPPSFACTORYBUFFER pPSFactory,
78 LPRPCPROXYBUFFER *ppProxy,
79 LPVOID *ppvObj)
80{
83 CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index];
84
85 TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name);
86
87 /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */
88 if (ProxyInfo->TableVersion > 1) {
90 vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1);
91 TRACE("stubless vtbl %p: count=%ld\n", vtbl->Vtbl, count );
92 fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count );
93 }
94
95 if (!IsEqualGUID(vtbl->header.piid, riid)) {
96 ERR("IID mismatch during proxy creation\n");
97 return RPC_E_UNEXPECTED;
98 }
99
100 This = calloc(1, sizeof(StdProxyImpl));
101 if (!This) return E_OUTOFMEMORY;
102
103 if (!pUnkOuter) pUnkOuter = (IUnknown *)&This->IRpcProxyBuffer_iface;
104 This->IRpcProxyBuffer_iface.lpVtbl = &StdProxy_Vtbl;
105 This->PVtbl = vtbl->Vtbl;
106 /* one reference for the proxy */
107 This->RefCount = 1;
108 This->piid = vtbl->header.piid;
109 This->base_object = NULL;
110 This->base_proxy = NULL;
111 This->pUnkOuter = pUnkOuter;
112 This->name = name;
113 This->pPSFactory = pPSFactory;
114 This->pChannel = NULL;
115
116 if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
117 {
119 &This->base_proxy, (void **)&This->base_object );
120 if (FAILED(r))
121 {
122 free( This );
123 return r;
124 }
125 }
126
127 *ppProxy = &This->IRpcProxyBuffer_iface;
128 *ppvObj = &This->PVtbl;
129 IUnknown_AddRef((IUnknown *)*ppvObj);
130 IPSFactoryBuffer_AddRef(pPSFactory);
131
132 TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n",
133 debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object );
134 return S_OK;
135}
136
138{
140 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
141
143 IsEqualGUID(This->piid,riid)) {
144 *obj = &This->PVtbl;
145 InterlockedIncrement(&This->RefCount);
146 return S_OK;
147 }
148
149 if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
150 *obj = &This->IRpcProxyBuffer_iface;
151 InterlockedIncrement(&This->RefCount);
152 return S_OK;
153 }
154
155 return E_NOINTERFACE;
156}
157
159{
161 TRACE("(%p)->AddRef()\n",This);
162
163 return InterlockedIncrement(&This->RefCount);
164}
165
167{
168 ULONG refs;
170 TRACE("(%p)->Release()\n",This);
171
172 refs = InterlockedDecrement(&This->RefCount);
173 if (!refs)
174 {
175 if (This->pChannel)
176 IRpcProxyBuffer_Disconnect(&This->IRpcProxyBuffer_iface);
177
178 if (This->base_object) IUnknown_Release( This->base_object );
179 if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy );
180
181 IPSFactoryBuffer_Release(This->pPSFactory);
182 free(This);
183 }
184
185 return refs;
186}
187
189{
191 TRACE("(%p)->Connect(%p)\n",This,pChannel);
192
193 This->pChannel = pChannel;
194 IRpcChannelBuffer_AddRef(pChannel);
195 if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel );
196 return S_OK;
197}
198
200{
202 TRACE("(%p)->Disconnect()\n",This);
203
204 if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy );
205
206 IRpcChannelBuffer_Release(This->pChannel);
207 This->pChannel = NULL;
208}
209
210static const IRpcProxyBufferVtbl StdProxy_Vtbl =
211{
217};
218
219static void StdProxy_GetChannel(LPVOID iface,
220 LPRPCCHANNELBUFFER *ppChannel)
221{
223 TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
224
225 if(This->pChannel)
226 IRpcChannelBuffer_AddRef(This->pChannel);
227
228 *ppChannel = This->pChannel;
229}
230
231static void StdProxy_GetIID(LPVOID iface,
232 const IID **ppiid)
233{
235 TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
236
237 *ppiid = This->piid;
238}
239
241 REFIID riid,
242 LPVOID *ppvObj)
243{
245 TRACE("(%p)->QueryInterface(%s,%p) %s\n",This,debugstr_guid(riid),ppvObj,This->name);
246 return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj);
247}
248
250{
252 TRACE("(%p)->AddRef() %s\n",This,This->name);
253 return IUnknown_AddRef(This->pUnkOuter);
254}
255
257{
259 TRACE("(%p)->Release() %s\n",This,This->name);
260 return IUnknown_Release(This->pUnkOuter);
261}
262
263/***********************************************************************
264 * NdrProxyInitialize [RPCRT4.@]
265 */
267 PRPC_MESSAGE pRpcMsg,
268 PMIDL_STUB_MESSAGE pStubMsg,
269 PMIDL_STUB_DESC pStubDescriptor,
270 unsigned int ProcNum)
271{
272 TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
273 NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
275 if (!pStubMsg->pRpcChannelBuffer)
277 IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
278 &pStubMsg->dwDestContext,
279 &pStubMsg->pvDestContext);
280 TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
281}
282
283/***********************************************************************
284 * NdrProxyGetBuffer [RPCRT4.@]
285 */
287 PMIDL_STUB_MESSAGE pStubMsg)
288{
289 HRESULT hr;
290 const IID *riid = NULL;
291
292 TRACE("(%p,%p)\n", This, pStubMsg);
293 pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
294 pStubMsg->dwStubPhase = PROXY_GETBUFFER;
296 hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
297 (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
298 riid);
299 if (FAILED(hr))
300 {
302 return;
303 }
304 pStubMsg->fBufferValid = TRUE;
305 pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
306 pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
307 pStubMsg->Buffer = pStubMsg->BufferStart;
308 pStubMsg->dwStubPhase = PROXY_MARSHAL;
309}
310
311/***********************************************************************
312 * NdrProxySendReceive [RPCRT4.@]
313 */
315 PMIDL_STUB_MESSAGE pStubMsg)
316{
317 ULONG Status = 0;
318 HRESULT hr;
319
320 TRACE("(%p,%p)\n", This, pStubMsg);
321
322 if (!pStubMsg->pRpcChannelBuffer)
323 {
324 WARN("Trying to use disconnected proxy %p\n", This);
326 }
327
328 pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
329 /* avoid sending uninitialised parts of the buffer on the wire */
330 pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
331 hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
332 (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
333 &Status);
334 pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
335 pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
336 pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
337 pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
338 pStubMsg->Buffer = pStubMsg->BufferStart;
339
340 /* raise exception if call failed */
341 if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
342 else if (FAILED(hr)) RpcRaiseException(hr);
343}
344
345/***********************************************************************
346 * NdrProxyFreeBuffer [RPCRT4.@]
347 */
349 PMIDL_STUB_MESSAGE pStubMsg)
350{
351 TRACE("(%p,%p)\n", This, pStubMsg);
352
353 if (pStubMsg->fBufferValid)
354 {
355 IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
356 (RPCOLEMESSAGE*)pStubMsg->RpcMsg);
357 pStubMsg->fBufferValid = FALSE;
358 }
359 IRpcChannelBuffer_Release(pStubMsg->pRpcChannelBuffer);
360 pStubMsg->pRpcChannelBuffer = NULL;
361}
362
363/***********************************************************************
364 * NdrProxyErrorHandler [RPCRT4.@]
365 */
367{
368 WARN("(0x%08lx): a proxy call failed\n", dwExceptionCode);
369
370 if (FAILED(dwExceptionCode))
371 return dwExceptionCode;
372 else
373 return HRESULT_FROM_WIN32(dwExceptionCode);
374}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
void WINAPI NdrProxyGetBuffer(void *This, PMIDL_STUB_MESSAGE pStubMsg)
Definition: cproxy.c:286
void ObjectStublessClient3(void)
ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface)
Definition: cproxy.c:249
void WINAPI NdrProxyInitialize(void *This, PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDescriptor, unsigned int ProcNum)
Definition: cproxy.c:266
ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface)
Definition: cproxy.c:256
static void StdProxy_GetIID(LPVOID iface, const IID **ppiid)
Definition: cproxy.c:231
static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
Definition: cproxy.c:166
void WINAPI NdrProxyFreeBuffer(void *This, PMIDL_STUB_MESSAGE pStubMsg)
Definition: cproxy.c:348
void WINAPI NdrProxySendReceive(void *This, PMIDL_STUB_MESSAGE pStubMsg)
Definition: cproxy.c:314
HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
Definition: cproxy.c:366
HRESULT WINAPI StdProxy_QueryInterface(IRpcProxyBuffer *iface, REFIID riid, void **obj)
Definition: cproxy.c:137
void ObjectStublessClient4(void)
static StdProxyImpl * impl_from_proxy_obj(void *iface)
Definition: cproxy.c:48
static StdProxyImpl * impl_from_IRpcProxyBuffer(IRpcProxyBuffer *iface)
Definition: cproxy.c:43
void WINAPI StdProxy_Disconnect(IRpcProxyBuffer *iface)
Definition: cproxy.c:199
HRESULT WINAPI StdProxy_Connect(IRpcProxyBuffer *iface, IRpcChannelBuffer *pChannel)
Definition: cproxy.c:188
static void StdProxy_GetChannel(LPVOID iface, LPRPCCHANNELBUFFER *ppChannel)
Definition: cproxy.c:219
HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface, REFIID riid, LPVOID *ppvObj)
Definition: cproxy.c:240
BOOL fill_stubless_table(IUnknownVtbl *vtbl, DWORD num)
Definition: cproxy.c:56
HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo, int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppvObj)
Definition: cproxy.c:73
ULONG WINAPI StdProxy_AddRef(IRpcProxyBuffer *iface)
Definition: cproxy.c:158
static const IRpcProxyBufferVtbl StdProxy_Vtbl
Definition: cproxy.c:41
#define NB_THUNK_ENTRIES
Definition: cpsf.h:74
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv)
Definition: ndr_ole.c:408
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
static LPVOID LPUNKNOWN
Definition: dinput.c:53
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
void WINAPI NdrClientInitializeNew(PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum)
interface IRpcProxyBuffer * LPRPCPROXYBUFFER
Definition: objfwd.h:40
interface IRpcChannelBuffer * LPRPCCHANNELBUFFER
Definition: objfwd.h:39
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
@ PROXY_GETBUFFER
Definition: rpcndr.h:492
@ PROXY_UNMARSHAL
Definition: rpcndr.h:495
@ PROXY_MARSHAL
Definition: rpcndr.h:493
@ PROXY_SENDRECEIVE
Definition: rpcndr.h:494
const char * PCInterfaceName
Definition: rpcproxy.h:41
void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception)
Definition: rpcrt4_main.c:213
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int fBufferValid
Definition: rpcndr.h:226
void * pvDestContext
Definition: rpcndr.h:233
DWORD dwStubPhase
Definition: rpcndr.h:242
struct IRpcChannelBuffer * pRpcChannelBuffer
Definition: rpcndr.h:236
unsigned char * Buffer
Definition: rpcndr.h:186
ULONG BufferLength
Definition: rpcndr.h:190
unsigned char * BufferEnd
Definition: rpcndr.h:188
DWORD dwDestContext
Definition: rpcndr.h:232
PRPC_MESSAGE RpcMsg
Definition: rpcndr.h:185
unsigned char * BufferStart
Definition: rpcndr.h:187
unsigned int BufferLength
Definition: rpcdcep.h:41
void * Buffer
Definition: rpcdcep.h:40
Definition: name.c:39
CInterfaceProxyHeader header
Definition: rpcproxy.h:79
CInterfaceStubHeader header
Definition: rpcproxy.h:99
unsigned short TableVersion
Definition: rpcproxy.h:53
const IID ** pDelegatedIIDs
Definition: rpcproxy.h:50
const PCInterfaceStubVtblList * pStubVtblList
Definition: rpcproxy.h:48
const PCInterfaceProxyVtblList * pProxyVtblList
Definition: rpcproxy.h:47
const PCInterfaceName * pNamesArray
Definition: rpcproxy.h:49
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
#define WINAPI
Definition: msvc.h:6
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define RPC_S_CALL_FAILED
Definition: winerror.h:1393
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CO_E_OBJNOTCONNECTED
Definition: winerror.h:3929
#define RPC_E_UNEXPECTED
Definition: winerror.h:3612
#define RPC_E_DISCONNECTED
Definition: winerror.h:3556