GetModuleFileName[AW] doesn't terminate the string if the buffer is
[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 <stdarg.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "winreg.h"
34
35 #include "objbase.h"
36
37 #include "rpcproxy.h"
38
39 #include "wine/debug.h"
40
41 #include "cpsf.h"
42 #include "ndr_misc.h"
43 #include "rpcndr.h"
44
45 WINE_DEFAULT_DEBUG_CHANNEL(ole);
46
47 /***********************************************************************
48  *           NdrProxyInitialize [RPCRT4.@]
49  */
50 void WINAPI NdrProxyInitialize(void *This,
51                               PRPC_MESSAGE pRpcMsg,
52                               PMIDL_STUB_MESSAGE pStubMsg,
53                               PMIDL_STUB_DESC pStubDescriptor,
54                               unsigned int ProcNum)
55 {
56   HRESULT hr;
57
58   TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
59   NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
60   if (This) StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
61   if (pStubMsg->pRpcChannelBuffer) {
62     hr = IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
63                                      &pStubMsg->dwDestContext,
64                                      &pStubMsg->pvDestContext);
65   }
66   TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
67 }
68
69 /***********************************************************************
70  *           NdrProxyGetBuffer [RPCRT4.@]
71  */
72 void WINAPI NdrProxyGetBuffer(void *This,
73                              PMIDL_STUB_MESSAGE pStubMsg)
74 {
75   HRESULT hr;
76   const IID *riid = NULL;
77
78   TRACE("(%p,%p)\n", This, pStubMsg);
79   pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
80   pStubMsg->dwStubPhase = PROXY_GETBUFFER;
81   hr = StdProxy_GetIID(This, &riid);
82   hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
83                                   (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
84                                   riid);
85   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
86   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
87   pStubMsg->Buffer = pStubMsg->BufferStart;
88   pStubMsg->dwStubPhase = PROXY_MARSHAL;
89 }
90
91 /***********************************************************************
92  *           NdrProxySendReceive [RPCRT4.@]
93  */
94 void WINAPI NdrProxySendReceive(void *This,
95                                PMIDL_STUB_MESSAGE pStubMsg)
96 {
97   ULONG Status = 0;
98   HRESULT hr;
99
100   TRACE("(%p,%p)\n", This, pStubMsg);
101   pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
102   hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
103                                     (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
104                                     &Status);
105   pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
106   pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
107   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
108   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
109   pStubMsg->Buffer = pStubMsg->BufferStart;
110
111   /* raise exception if call failed */
112   if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
113   else if (FAILED(hr)) RpcRaiseException(hr);
114 }
115
116 /***********************************************************************
117  *           NdrProxyFreeBuffer [RPCRT4.@]
118  */
119 void WINAPI NdrProxyFreeBuffer(void *This,
120                               PMIDL_STUB_MESSAGE pStubMsg)
121 {
122   HRESULT hr;
123
124   TRACE("(%p,%p)\n", This, pStubMsg);
125   hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
126                                    (RPCOLEMESSAGE*)pStubMsg->RpcMsg);
127 }
128
129 /***********************************************************************
130  *           NdrProxyErrorHandler [RPCRT4.@]
131  */
132 HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
133 {
134   FIXME("(0x%08lx): semi-stub\n", dwExceptionCode);
135   return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RPC, RPC_S_CALL_FAILED);
136 }
137
138 /***********************************************************************
139  *           NdrStubInitialize [RPCRT4.@]
140  */
141 void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
142                              PMIDL_STUB_MESSAGE pStubMsg,
143                              PMIDL_STUB_DESC pStubDescriptor,
144                              LPRPCCHANNELBUFFER pRpcChannelBuffer)
145 {
146   TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
147   NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
148   pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
149 }
150
151 /***********************************************************************
152  *           NdrStubGetBuffer [RPCRT4.@]
153  */
154 void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER This,
155                             LPRPCCHANNELBUFFER pRpcChannelBuffer,
156                             PMIDL_STUB_MESSAGE pStubMsg)
157 {
158   TRACE("(%p,%p)\n", This, pStubMsg);
159   pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
160   pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
161   I_RpcGetBuffer(pStubMsg->RpcMsg); /* ? */
162   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
163   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
164   pStubMsg->Buffer = pStubMsg->BufferStart;
165 }
166
167 /************************************************************************
168  *             NdrClientInitializeNew [RPCRT4.@]
169  */
170 void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, 
171                                     PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
172 {
173   TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
174     pRpcMessage, pStubMsg, pStubDesc, ProcNum);
175
176   assert( pRpcMessage && pStubMsg && pStubDesc );
177
178   memset(pRpcMessage, 0, sizeof(RPC_MESSAGE));
179
180   /* not everyone allocates stack space for w2kReserved */
181   memset(pStubMsg, 0, sizeof(*pStubMsg) - sizeof(pStubMsg->w2kReserved));
182
183   pStubMsg->ReuseBuffer = FALSE;
184   pStubMsg->IsClient = TRUE;
185   pStubMsg->StubDesc = pStubDesc;
186   pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
187   pStubMsg->pfnFree = pStubDesc->pfnFree;
188   pStubMsg->RpcMsg = pRpcMessage;
189
190   pRpcMessage->ProcNum = ProcNum;
191   pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
192 }
193
194 /***********************************************************************
195  *             NdrServerInitializeNew [RPCRT4.@]
196  */
197 unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
198                                               PMIDL_STUB_DESC pStubDesc )
199 {
200   TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
201
202   assert( pRpcMsg && pStubMsg && pStubDesc );
203
204   /* not everyone allocates stack space for w2kReserved */
205   memset(pStubMsg, 0, sizeof(*pStubMsg) - sizeof(pStubMsg->w2kReserved));
206
207   pStubMsg->ReuseBuffer = TRUE;
208   pStubMsg->IsClient = FALSE;
209   pStubMsg->StubDesc = pStubDesc;
210   pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
211   pStubMsg->pfnFree = pStubDesc->pfnFree;
212   pStubMsg->RpcMsg = pRpcMsg;
213   pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
214   pStubMsg->BufferLength = pRpcMsg->BufferLength;
215   pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength;
216
217   /* FIXME: determine the proper return value */
218   return NULL;
219 }
220
221 /***********************************************************************
222  *           NdrGetBuffer [RPCRT4.@]
223  */
224 unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle)
225 {
226   TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle);
227   
228   assert( stubmsg && stubmsg->RpcMsg );
229
230   /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
231   stubmsg->RpcMsg->Handle = handle;
232   
233   stubmsg->RpcMsg->BufferLength = buflen;
234   if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
235     return NULL;
236
237   stubmsg->Buffer = stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
238   stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
239   stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
240   return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
241 }
242 /***********************************************************************
243  *           NdrFreeBuffer [RPCRT4.@]
244  */
245 void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg)
246 {
247   TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
248   I_RpcFreeBuffer(pStubMsg->RpcMsg);
249   pStubMsg->BufferLength = 0;
250   pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
251 }
252
253 /************************************************************************
254  *           NdrSendReceive [RPCRT4.@]
255  */
256 unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer  )
257 {
258   TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
259
260   /* FIXME: how to handle errors? (raise exception?) */
261   if (!stubmsg) {
262     ERR("NULL stub message.  No action taken.\n");
263     return NULL;
264   }
265   if (!stubmsg->RpcMsg) {
266     ERR("RPC Message not present in stub message.  No action taken.\n");
267     return NULL;
268   }
269
270   /* FIXME: Seems wrong.  Where should this really come from, and when? */
271   stubmsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
272
273   if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) {
274     WARN("I_RpcSendReceive did not return success.\n");
275     /* FIXME: raise exception? */
276   }
277
278   /* FIXME: is this the right return value? */
279   return NULL;
280 }