Give SetErrorMode the right argument to suppress crash dialogs.
[wine] / dlls / rpcrt4 / cstub.c
1 /*
2  * COM stub (CStdStubBuffer) implementation
3  *
4  * Copyright 2001 Ove Kåven, TransGaming Technologies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26
27 #include "objbase.h"
28
29 #include "rpcproxy.h"
30
31 #include "wine/debug.h"
32
33 #include "cpsf.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(ole);
36
37 #define STUB_HEADER(This) (((CInterfaceStubHeader*)((This)->lpVtbl))[-1])
38
39 HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
40                                        LPUNKNOWN pUnkServer,
41                                        PCInterfaceName name,
42                                        CInterfaceStubVtbl *vtbl,
43                                        LPPSFACTORYBUFFER pPSFactory,
44                                        LPRPCSTUBBUFFER *ppStub)
45 {
46   CStdStubBuffer *This;
47
48   TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name);
49   TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid));
50   TRACE("vtbl=%p\n", &vtbl->Vtbl);
51
52   if (!IsEqualGUID(vtbl->header.piid, riid)) {
53     ERR("IID mismatch during stub creation\n");
54     return RPC_E_UNEXPECTED;
55   }
56
57   This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer));
58   if (!This) return E_OUTOFMEMORY;
59
60   This->lpVtbl = &vtbl->Vtbl;
61   This->RefCount = 1;
62   This->pvServerObject = pUnkServer;
63   This->pPSFactory = pPSFactory;
64   *ppStub = (LPRPCSTUBBUFFER)This;
65
66   IUnknown_AddRef(This->pvServerObject);
67   IPSFactoryBuffer_AddRef(pPSFactory);
68   return S_OK;
69 }
70
71 HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface,
72                                             REFIID riid,
73                                             LPVOID *obj)
74 {
75   ICOM_THIS(CStdStubBuffer,iface);
76   TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
77
78   if (IsEqualGUID(&IID_IUnknown,riid) ||
79       IsEqualGUID(&IID_IRpcStubBuffer,riid)) {
80     *obj = This;
81     This->RefCount++;
82     return S_OK;
83   }
84   return E_NOINTERFACE;
85 }
86
87 ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface)
88 {
89   ICOM_THIS(CStdStubBuffer,iface);
90   TRACE("(%p)->AddRef()\n",This);
91   return ++(This->RefCount);
92 }
93
94 ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface,
95                                       LPPSFACTORYBUFFER pPSF)
96 {
97   ICOM_THIS(CStdStubBuffer,iface);
98   TRACE("(%p)->Release()\n",This);
99
100   if (!--(This->RefCount)) {
101     if(This->pvServerObject)
102         IUnknown_Release(This->pvServerObject);
103     if(This->pPSFactory)
104         IPSFactoryBuffer_Release(This->pPSFactory);
105     HeapFree(GetProcessHeap(),0,This);
106     return 0;
107   }
108   return This->RefCount;
109 }
110
111 HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface,
112                                      LPUNKNOWN lpUnkServer)
113 {
114   ICOM_THIS(CStdStubBuffer,iface);
115   TRACE("(%p)->Connect(%p)\n",This,lpUnkServer);
116   This->pvServerObject = lpUnkServer;
117   return S_OK;
118 }
119
120 void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface)
121 {
122   ICOM_THIS(CStdStubBuffer,iface);
123   TRACE("(%p)->Disconnect()\n",This);
124   This->pvServerObject = NULL;
125 }
126
127 HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface,
128                                     PRPCOLEMESSAGE pMsg,
129                                     LPRPCCHANNELBUFFER pChannel)
130 {
131   ICOM_THIS(CStdStubBuffer,iface);
132   DWORD dwPhase = STUB_UNMARSHAL;
133   TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel);
134
135   STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
136   return S_OK;
137 }
138
139 LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface,
140                                                     REFIID riid)
141 {
142   ICOM_THIS(CStdStubBuffer,iface);
143   TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid));
144   return IsEqualGUID(STUB_HEADER(This).piid, riid) ? iface : NULL;
145 }
146
147 ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface)
148 {
149   ICOM_THIS(CStdStubBuffer,iface);
150   TRACE("(%p)->CountRefs()\n",This);
151   return This->RefCount;
152 }
153
154 HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface,
155                                                        LPVOID *ppv)
156 {
157   ICOM_THIS(CStdStubBuffer,iface);
158   TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv);
159   return S_OK;
160 }
161
162 void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface,
163                                              LPVOID pv)
164 {
165   ICOM_THIS(CStdStubBuffer,iface);
166   TRACE("(%p)->DebugServerRelease(%p)\n",This,pv);
167 }