- Use memset instead of ZeroMemory, just to be consistent with Ove's
[wine] / dlls / rpcrt4 / ndr_midl.c
1 /*
2  * MIDL proxy/stub stuff
3  *
4  * Copyright 2002 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  * TODO:
21  *  - figure out whether we *really* got this right
22  *  - check for errors and throw exceptions
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <assert.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "winreg.h"
33
34 #include "wine/obj_base.h"
35 #include "wine/obj_channel.h"
36
37 #include "rpcproxy.h"
38
39 #include "wine/debug.h"
40
41 #include "cpsf.h"
42 #include "ndr_misc.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(ole);
45
46 /***********************************************************************
47  *           NdrProxyInitialize [RPCRT4.@]
48  */
49 void WINAPI NdrProxyInitialize(void *This,
50                               PRPC_MESSAGE pRpcMsg,
51                               PMIDL_STUB_MESSAGE pStubMsg,
52                               PMIDL_STUB_DESC pStubDescriptor,
53                               unsigned int ProcNum)
54 {
55   HRESULT hr;
56
57   TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
58   memset(pRpcMsg, 0, sizeof(RPC_MESSAGE));
59   memset(pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE));
60   pRpcMsg->ProcNum = ProcNum;
61   pRpcMsg->RpcInterfaceInformation = pStubDescriptor->RpcInterfaceInformation;
62   pStubMsg->RpcMsg = pRpcMsg;
63   pStubMsg->IsClient = 1;
64   pStubMsg->ReuseBuffer = 1;
65   pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
66   pStubMsg->pfnFree = pStubDescriptor->pfnFree;
67   pStubMsg->StubDesc = pStubDescriptor;
68   if (This) StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
69   if (pStubMsg->pRpcChannelBuffer) {
70     hr = IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
71                                      &pStubMsg->dwDestContext,
72                                      &pStubMsg->pvDestContext);
73   }
74   TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
75 }
76
77 /***********************************************************************
78  *           NdrProxyGetBuffer [RPCRT4.@]
79  */
80 void WINAPI NdrProxyGetBuffer(void *This,
81                              PMIDL_STUB_MESSAGE pStubMsg)
82 {
83   HRESULT hr;
84   const IID *riid = NULL;
85
86   TRACE("(%p,%p)\n", This, pStubMsg);
87   pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
88   pStubMsg->dwStubPhase = PROXY_GETBUFFER;
89   hr = StdProxy_GetIID(This, &riid);
90   hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
91                                   (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
92                                   riid);
93   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
94   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
95   pStubMsg->Buffer = pStubMsg->BufferStart;
96   pStubMsg->dwStubPhase = PROXY_MARSHAL;
97 }
98
99 /***********************************************************************
100  *           NdrProxySendReceive [RPCRT4.@]
101  */
102 void WINAPI NdrProxySendReceive(void *This,
103                                PMIDL_STUB_MESSAGE pStubMsg)
104 {
105   ULONG Status = 0;
106   HRESULT hr;
107
108   TRACE("(%p,%p)\n", This, pStubMsg);
109   pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
110   hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
111                                     (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
112                                     &Status);
113   pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
114   pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
115   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
116   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
117   pStubMsg->Buffer = pStubMsg->BufferStart;
118 }
119
120 /***********************************************************************
121  *           NdrProxyFreeBuffer [RPCRT4.@]
122  */
123 void WINAPI NdrProxyFreeBuffer(void *This,
124                               PMIDL_STUB_MESSAGE pStubMsg)
125 {
126   HRESULT hr;
127
128   TRACE("(%p,%p)\n", This, pStubMsg);
129   hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
130                                    (RPCOLEMESSAGE*)pStubMsg->RpcMsg);
131 }
132
133 /***********************************************************************
134  *           NdrStubInitialize [RPCRT4.@]
135  */
136 void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
137                              PMIDL_STUB_MESSAGE pStubMsg,
138                              PMIDL_STUB_DESC pStubDescriptor,
139                              LPRPCCHANNELBUFFER pRpcChannelBuffer)
140 {
141   TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
142   memset(pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE));
143   pStubMsg->RpcMsg = pRpcMsg;
144   pStubMsg->IsClient = 0;
145   pStubMsg->ReuseBuffer = 1;
146   pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
147   pStubMsg->pfnFree = pStubDescriptor->pfnFree;
148   pStubMsg->StubDesc = pStubDescriptor;
149   pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
150   pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
151   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
152   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
153   pStubMsg->Buffer = pStubMsg->BufferStart;
154 }
155
156 /***********************************************************************
157  *           NdrStubGetBuffer [RPCRT4.@]
158  */
159 void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER This,
160                             LPRPCCHANNELBUFFER pRpcChannelBuffer,
161                             PMIDL_STUB_MESSAGE pStubMsg)
162 {
163   TRACE("(%p,%p)\n", This, pStubMsg);
164   pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
165   pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
166   I_RpcGetBuffer(pStubMsg->RpcMsg); /* ? */
167   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
168   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
169   pStubMsg->Buffer = pStubMsg->BufferStart;
170 }
171
172 /************************************************************************
173  *             NdrClientInitializeNew [RPCRT4.@]
174  */
175 void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, 
176                                     PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
177 {
178   TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
179     pRpcMessage, pStubMsg, pStubDesc, ProcNum);
180
181   memset(pRpcMessage, 0, sizeof(RPC_MESSAGE));
182   memset(pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE));
183
184   pStubMsg->ReuseBuffer = TRUE;
185   pStubMsg->IsClient = TRUE;
186   pStubMsg->StubDesc = pStubDesc;
187   pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
188   pStubMsg->pfnFree = pStubDesc->pfnFree;
189   pStubMsg->RpcMsg = pRpcMessage;
190
191   pRpcMessage->ProcNum = ProcNum;
192   pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
193 }
194
195 /***********************************************************************
196  *           NdrGetBuffer [RPCRT4.@]
197  */
198 unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle)
199 {
200   TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle);
201   
202   assert( stubmsg && stubmsg->RpcMsg );
203
204   /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
205   stubmsg->RpcMsg->Handle = handle;
206   
207   stubmsg->RpcMsg->BufferLength = buflen;
208   if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
209     return NULL;
210
211   stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
212   stubmsg->BufferEnd = stubmsg->BufferStart = 0;
213   return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
214 }
215 /***********************************************************************
216  *           NdrFreeBuffer [RPCRT4.@]
217  */
218 void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg)
219 {
220   TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
221   I_RpcFreeBuffer(pStubMsg->RpcMsg);
222   pStubMsg->BufferLength = 0;
223   pStubMsg->Buffer = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
224 }
225
226 /************************************************************************
227  *           NdrSendReceive [RPCRT4.@]
228  */
229 unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer  )
230 {
231   TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
232
233   /* FIXME: how to handle errors? (raise exception?) */
234   if (!stubmsg) {
235     ERR("NULL stub message.  No action taken.\n");
236     return NULL;
237   }
238   if (!stubmsg->RpcMsg) {
239     ERR("RPC Message not present in stub message.  No action taken.\n");
240     return NULL;
241   }
242   if (stubmsg->RpcMsg->Buffer != buffer) {
243     ERR("Ambiguous buffer doesn't match rpc message buffer.  No action taken.\n");
244     return NULL;
245   }
246
247   if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) {
248     WARN("I_RpcSendReceive did not return success.\n");
249   }
250
251   /* FIXME: is this the right return value? */
252   return NULL;
253 }