~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/rpcrt4/ndr_es.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * NDR Serialization Services
  3  *
  4  * Copyright (c) 2007 Robert Shearman for CodeWeavers
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <stdarg.h>
 22 #include <stdio.h>
 23 
 24 #include "windef.h"
 25 #include "winbase.h"
 26 #include "winerror.h"
 27 #include "rpc.h"
 28 #include "midles.h"
 29 #include "ndrtypes.h"
 30 
 31 #include "ndr_misc.h"
 32 #include "ndr_stubless.h"
 33 
 34 #include "wine/debug.h"
 35 #include "wine/rpcfc.h"
 36 
 37 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 38 
 39 static inline void init_MIDL_ES_MESSAGE(MIDL_ES_MESSAGE *pEsMsg)
 40 {
 41     memset(pEsMsg, 0, sizeof(*pEsMsg));
 42     /* even if we are unmarshalling, as we don't want pointers to be pointed
 43      * to buffer memory */
 44     pEsMsg->StubMsg.IsClient = TRUE;
 45 }
 46 
 47 /***********************************************************************
 48  *            MesEncodeIncrementalHandleCreate [RPCRT4.@]
 49  */
 50 RPC_STATUS WINAPI MesEncodeIncrementalHandleCreate(
 51     void *UserState, MIDL_ES_ALLOC AllocFn, MIDL_ES_WRITE WriteFn,
 52     handle_t *pHandle)
 53 {
 54     MIDL_ES_MESSAGE *pEsMsg;
 55 
 56     TRACE("(%p, %p, %p, %p)\n", UserState, AllocFn, WriteFn, pHandle);
 57 
 58     pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg));
 59     if (!pEsMsg)
 60         return ERROR_OUTOFMEMORY;
 61 
 62     init_MIDL_ES_MESSAGE(pEsMsg);
 63 
 64     pEsMsg->Operation = MES_ENCODE;
 65     pEsMsg->UserState = UserState;
 66     pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE;
 67     pEsMsg->Alloc = AllocFn;
 68     pEsMsg->Write = WriteFn;
 69 
 70     *pHandle = (handle_t)pEsMsg;
 71 
 72     return RPC_S_OK;
 73 }
 74 
 75 /***********************************************************************
 76  *            MesDecodeIncrementalHandleCreate [RPCRT4.@]
 77  */
 78 RPC_STATUS WINAPI MesDecodeIncrementalHandleCreate(
 79     void *UserState, MIDL_ES_READ ReadFn, handle_t *pHandle)
 80 {
 81     MIDL_ES_MESSAGE *pEsMsg;
 82 
 83     TRACE("(%p, %p, %p)\n", UserState, ReadFn, pHandle);
 84 
 85     pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg));
 86     if (!pEsMsg)
 87         return ERROR_OUTOFMEMORY;
 88 
 89     init_MIDL_ES_MESSAGE(pEsMsg);
 90 
 91     pEsMsg->Operation = MES_DECODE;
 92     pEsMsg->UserState = UserState;
 93     pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE;
 94     pEsMsg->Read = ReadFn;
 95 
 96     *pHandle = (handle_t)pEsMsg;
 97 
 98     return RPC_S_OK;
 99 }
100 
101 /***********************************************************************
102  *            MesIncrementalHandleReset [RPCRT4.@]
103  */
104 RPC_STATUS WINAPI MesIncrementalHandleReset(
105     handle_t Handle, void *UserState, MIDL_ES_ALLOC AllocFn,
106     MIDL_ES_WRITE WriteFn, MIDL_ES_READ ReadFn, MIDL_ES_CODE Operation)
107 {
108     MIDL_ES_MESSAGE *pEsMsg = Handle;
109 
110     TRACE("(%p, %p, %p, %p, %p, %d)\n", Handle, UserState, AllocFn,
111         WriteFn, ReadFn, Operation);
112 
113     init_MIDL_ES_MESSAGE(pEsMsg);
114 
115     pEsMsg->Operation = Operation;
116     pEsMsg->UserState = UserState;
117     pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE;
118     pEsMsg->Alloc = AllocFn;
119     pEsMsg->Write = WriteFn;
120     pEsMsg->Read = ReadFn;
121 
122     return RPC_S_OK;
123 }
124 
125 /***********************************************************************
126  *            MesHandleFree [RPCRT4.@]
127  */
128 RPC_STATUS WINAPI MesHandleFree(handle_t Handle)
129 {
130     TRACE("(%p)\n", Handle);
131     HeapFree(GetProcessHeap(), 0, Handle);
132     return RPC_S_OK;
133 }
134 
135 /***********************************************************************
136  *            MesEncodeFixedBufferHandleCreate [RPCRT4.@]
137  */
138 RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate(
139     char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle)
140 {
141     MIDL_ES_MESSAGE *pEsMsg;
142 
143     TRACE("(%p, %d, %p, %p)\n", Buffer, BufferSize, pEncodedSize, pHandle);
144 
145     pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg));
146     if (!pEsMsg)
147         return ERROR_OUTOFMEMORY;
148 
149     init_MIDL_ES_MESSAGE(pEsMsg);
150 
151     pEsMsg->Operation = MES_ENCODE;
152     pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE;
153     pEsMsg->Buffer = (unsigned char *)Buffer;
154     pEsMsg->BufferSize = BufferSize;
155     pEsMsg->pEncodedSize = pEncodedSize;
156 
157     *pHandle = (handle_t)pEsMsg;
158 
159     return RPC_S_OK;
160 }
161 
162 /***********************************************************************
163  *            MesEncodeDynBufferHandleCreate [RPCRT4.@]
164  */
165 RPC_STATUS RPC_ENTRY MesEncodeDynBufferHandleCreate(char **ppBuffer,
166         ULONG *pEncodedSize, handle_t *pHandle)
167 {
168     FIXME("%p %p %p stub\n", ppBuffer, pEncodedSize, pHandle);
169     return RPC_S_OK;
170 }
171 
172 /***********************************************************************
173  *            MesDecodeBufferHandleCreate [RPCRT4.@]
174  */
175 RPC_STATUS RPC_ENTRY MesDecodeBufferHandleCreate(
176     char *Buffer, ULONG BufferSize, handle_t *pHandle)
177 {
178     MIDL_ES_MESSAGE *pEsMsg;
179 
180     TRACE("(%p, %d, %p)\n", Buffer, BufferSize, pHandle);
181 
182     pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg));
183     if (!pEsMsg)
184         return ERROR_OUTOFMEMORY;
185 
186     init_MIDL_ES_MESSAGE(pEsMsg);
187 
188     pEsMsg->Operation = MES_DECODE;
189     pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE;
190     pEsMsg->Buffer = (unsigned char *)Buffer;
191     pEsMsg->BufferSize = BufferSize;
192 
193     *pHandle = (handle_t)pEsMsg;
194 
195     return RPC_S_OK;
196 }
197 
198 static void es_data_alloc(MIDL_ES_MESSAGE *pEsMsg, ULONG size)
199 {
200     if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE)
201     {
202         unsigned int tmpsize = size;
203         TRACE("%d with incremental handle\n", size);
204         pEsMsg->Alloc(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize);
205         if (tmpsize < size)
206         {
207             ERR("not enough bytes allocated - requested %d, got %d\n", size, tmpsize);
208             RpcRaiseException(ERROR_OUTOFMEMORY);
209         }
210     }
211     else if (pEsMsg->HandleStyle == MES_FIXED_BUFFER_HANDLE)
212     {
213         TRACE("%d with fixed buffer handle\n", size);
214         pEsMsg->StubMsg.Buffer = pEsMsg->Buffer;
215     }
216     pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer;
217 }
218 
219 static void es_data_read(MIDL_ES_MESSAGE *pEsMsg, ULONG size)
220 {
221     if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE)
222     {
223         unsigned int tmpsize = size;
224         TRACE("%d from incremental handle\n", size);
225         pEsMsg->Read(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize);
226         if (tmpsize < size)
227         {
228             ERR("not enough bytes read - requested %d, got %d\n", size, tmpsize);
229             RpcRaiseException(ERROR_OUTOFMEMORY);
230         }
231     }
232     else
233     {
234         TRACE("%d from fixed or dynamic buffer handle\n", size);
235         /* FIXME: validate BufferSize? */
236         pEsMsg->StubMsg.Buffer = pEsMsg->Buffer;
237         pEsMsg->Buffer += size;
238         pEsMsg->BufferSize -= size;
239     }
240     pEsMsg->StubMsg.BufferLength = size;
241     pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer;
242     pEsMsg->StubMsg.BufferEnd = pEsMsg->StubMsg.Buffer + size;
243 }
244 
245 static void es_data_write(MIDL_ES_MESSAGE *pEsMsg, ULONG size)
246 {
247     if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE)
248     {
249         TRACE("%d to incremental handle\n", size);
250         pEsMsg->Write(pEsMsg->UserState, (char *)pEsMsg->StubMsg.BufferStart, size);
251     }
252     else
253     {
254         TRACE("%d to dynamic or fixed buffer handle\n", size);
255         *pEsMsg->pEncodedSize += size;
256     }
257 }
258 
259 static inline ULONG mes_proc_header_buffer_size(void)
260 {
261     return 4 + 2*sizeof(RPC_SYNTAX_IDENTIFIER) + 12;
262 }
263 
264 static void mes_proc_header_marshal(MIDL_ES_MESSAGE *pEsMsg)
265 {
266     const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation;
267     *(WORD *)pEsMsg->StubMsg.Buffer = 0x0101;
268     pEsMsg->StubMsg.Buffer += 2;
269     *(WORD *)pEsMsg->StubMsg.Buffer = 0xcccc;
270     pEsMsg->StubMsg.Buffer += 2;
271     memcpy(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER));
272     pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
273     memcpy(pEsMsg->StubMsg.Buffer, &pEsMsg->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER));
274     pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
275     *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ProcNumber;
276     pEsMsg->StubMsg.Buffer += 4;
277     *(DWORD *)pEsMsg->StubMsg.Buffer = 0x00000001;
278     pEsMsg->StubMsg.Buffer += 4;
279     *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ByteCount;
280     pEsMsg->StubMsg.Buffer += 4;
281 }
282 
283 static void mes_proc_header_unmarshal(MIDL_ES_MESSAGE *pEsMsg)
284 {
285     const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation;
286 
287     es_data_read(pEsMsg, mes_proc_header_buffer_size());
288 
289     if (*(WORD *)pEsMsg->StubMsg.Buffer != 0x0101)
290     {
291         FIXME("unknown value at Buffer[0] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer);
292         RpcRaiseException(RPC_X_WRONG_ES_VERSION);
293     }
294     pEsMsg->StubMsg.Buffer += 2;
295     if (*(WORD *)pEsMsg->StubMsg.Buffer != 0xcccc)
296         FIXME("unknown value at Buffer[2] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer);
297     pEsMsg->StubMsg.Buffer += 2;
298     if (memcmp(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER)))
299     {
300         const RPC_SYNTAX_IDENTIFIER *AlienTransferSyntax = (const RPC_SYNTAX_IDENTIFIER *)pEsMsg->StubMsg.Buffer;
301         ERR("bad transfer syntax %s {%d.%d}\n", debugstr_guid(&AlienTransferSyntax->SyntaxGUID),
302             AlienTransferSyntax->SyntaxVersion.MajorVersion,
303             AlienTransferSyntax->SyntaxVersion.MinorVersion);
304         RpcRaiseException(RPC_S_UNSUPPORTED_TRANS_SYN);
305     }
306     pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
307     memcpy(&pEsMsg->InterfaceId, pEsMsg->StubMsg.Buffer, sizeof(RPC_SYNTAX_IDENTIFIER));
308     pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
309     pEsMsg->ProcNumber = *(DWORD *)pEsMsg->StubMsg.Buffer;
310     pEsMsg->StubMsg.Buffer += 4;
311     if (*(DWORD *)pEsMsg->StubMsg.Buffer != 0x00000001)
312         FIXME("unknown value 0x%08x, expected 0x00000001\n", *(DWORD *)pEsMsg->StubMsg.Buffer);
313     pEsMsg->StubMsg.Buffer += 4;
314     pEsMsg->ByteCount = *(DWORD *)pEsMsg->StubMsg.Buffer;
315     pEsMsg->StubMsg.Buffer += 4;
316     if (pEsMsg->ByteCount + mes_proc_header_buffer_size() < pEsMsg->ByteCount)
317         RpcRaiseException(RPC_S_INVALID_BOUND);
318 }
319 
320 /***********************************************************************
321  *            NdrMesProcEncodeDecode [RPCRT4.@]
322  */
323 void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStubDesc, PFORMAT_STRING pFormat, ...)
324 {
325     /* pointer to start of stack where arguments start */
326     RPC_MESSAGE rpcMsg;
327     MIDL_ES_MESSAGE *pEsMsg = Handle;
328     /* size of stack */
329     unsigned short stack_size;
330     /* header for procedure string */
331     const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
332     /* the value to return to the client from the remote procedure */
333     LONG_PTR RetVal = 0;
334     const RPC_CLIENT_INTERFACE *client_interface;
335 
336     TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle, pStubDesc, pFormat);
337 
338     /* Later NDR language versions probably won't be backwards compatible */
339     if (pStubDesc->Version > 0x50002)
340     {
341         FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version);
342         RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
343     }
344 
345     client_interface = pStubDesc->RpcInterfaceInformation;
346     pEsMsg->InterfaceId = client_interface->InterfaceId;
347 
348     if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
349     {
350         const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0];
351         stack_size = pProcHeader->stack_size;
352         pEsMsg->ProcNumber = pProcHeader->proc_num;
353         pFormat += sizeof(NDR_PROC_HEADER_RPC);
354     }
355     else
356     {
357         stack_size = pProcHeader->stack_size;
358         pEsMsg->ProcNumber = pProcHeader->proc_num;
359         pFormat += sizeof(NDR_PROC_HEADER);
360     }
361 
362     if (pProcHeader->handle_type == RPC_FC_BIND_EXPLICIT)
363     {
364         switch (*pFormat) /* handle_type */
365         {
366         case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
367             pFormat += sizeof(NDR_EHD_PRIMITIVE);
368             break;
369         case RPC_FC_BIND_GENERIC: /* explicit generic */
370             pFormat += sizeof(NDR_EHD_GENERIC);
371             break;
372         case RPC_FC_BIND_CONTEXT: /* explicit context */
373             pFormat += sizeof(NDR_EHD_CONTEXT);
374             break;
375         default:
376             ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
377             RpcRaiseException(RPC_X_BAD_STUB_DATA);
378         }
379     }
380 
381     TRACE("stack size: 0x%x\n", stack_size);
382     TRACE("proc num: %d\n", pEsMsg->ProcNumber);
383 
384     memset(&rpcMsg, 0, sizeof(rpcMsg));
385     pEsMsg->StubMsg.RpcMsg = &rpcMsg;
386     pEsMsg->StubMsg.StubDesc = pStubDesc;
387     pEsMsg->StubMsg.pfnAllocate = pStubDesc->pfnAllocate;
388     pEsMsg->StubMsg.pfnFree = pStubDesc->pfnFree;
389 
390     /* create the full pointer translation tables, if requested */
391     if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
392         pEsMsg->StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT);
393 
394     TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
395     TRACE("stubdesc version = 0x%x\n", pStubDesc->Version);
396     TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion);
397 
398     /* needed for conformance of top-level objects */
399 #ifdef __i386__
400     pEsMsg->StubMsg.StackTop = *(unsigned char **)(&pFormat+1);
401 #else
402 # warning Stack not retrieved for your CPU architecture
403 #endif
404 
405     switch (pEsMsg->Operation)
406     {
407     case MES_ENCODE:
408         pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size();
409 
410         client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_CALCSIZE,
411             pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
412             FALSE /* object_proc */, TRUE /* ignore_retval */);
413 
414         pEsMsg->ByteCount = pEsMsg->StubMsg.BufferLength - mes_proc_header_buffer_size();
415         es_data_alloc(pEsMsg, pEsMsg->StubMsg.BufferLength);
416 
417         mes_proc_header_marshal(pEsMsg);
418 
419         client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_MARSHAL,
420             pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
421             FALSE /* object_proc */, TRUE /* ignore_retval */);
422 
423         es_data_write(pEsMsg, pEsMsg->ByteCount);
424         break;
425     case MES_DECODE:
426         mes_proc_header_unmarshal(pEsMsg);
427 
428         es_data_read(pEsMsg, pEsMsg->ByteCount);
429 
430         client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_UNMARSHAL,
431             pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
432             FALSE /* object_proc */, TRUE /* ignore_retval */);
433         break;
434     default:
435         RpcRaiseException(RPC_S_INTERNAL_ERROR);
436         return;
437     }
438     /* free the full pointer translation tables */
439     if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
440         NdrFullPointerXlatFree(pEsMsg->StubMsg.FullPtrXlatTables);
441 }
442 
443 void RPC_ENTRY NdrMesTypeDecode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo,
444     const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject)
445 {
446     FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject);
447 }
448 
449 void RPC_ENTRY NdrMesTypeFree2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo,
450     const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject)
451 {
452     FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject);
453 }
454 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.