push 2611c5e74b6b3f940a18cbfccd94936eddcba0c6
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob60e057fdbc6ab44cf2207cffde7513c140233f95
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
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.
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.
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
21 * TODO:
22 * - Non-conformant strings
23 * - String structs
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <limits.h>
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winerror.h"
41 #include "ndr_misc.h"
42 #include "rpcndr.h"
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ole);
51 #if defined(__i386__)
52 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
53 (*((UINT32 *)(pchar)) = (uint32))
55 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
56 (*((UINT32 *)(pchar)))
57 #else
58 /* these would work for i386 too, but less efficient */
59 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
60 (*(pchar) = LOBYTE(LOWORD(uint32)), \
61 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
62 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
63 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
64 (uint32)) /* allow as r-value */
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 (MAKELONG( \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #endif
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)), \
77 (uint32)) /* allow as r-value */
79 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 (MAKELONG( \
81 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
82 MAKEWORD(*((pchar)+1), *(pchar))))
84 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
85 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
86 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
87 # define NDR_LOCAL_UINT32_READ(pchar) \
88 BIG_ENDIAN_UINT32_READ(pchar)
89 #else
90 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
91 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
92 # define NDR_LOCAL_UINT32_READ(pchar) \
93 LITTLE_ENDIAN_UINT32_READ(pchar)
94 #endif
96 /* _Align must be the desired alignment,
97 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
98 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
99 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
100 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
101 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
102 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 do { \
104 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
105 ALIGN_POINTER(_Ptr, _Align); \
106 } while(0)
108 #define STD_OVERFLOW_CHECK(_Msg) do { \
109 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
110 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
111 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 } while (0)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
119 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
127 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 /* 0x10 */
134 NdrBaseTypeMarshall,
135 /* 0x11 */
136 NdrPointerMarshall, NdrPointerMarshall,
137 NdrPointerMarshall, NdrPointerMarshall,
138 /* 0x15 */
139 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
140 NdrConformantStructMarshall, NdrConformantStructMarshall,
141 NdrConformantVaryingStructMarshall,
142 NdrComplexStructMarshall,
143 /* 0x1b */
144 NdrConformantArrayMarshall,
145 NdrConformantVaryingArrayMarshall,
146 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
147 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
148 NdrComplexArrayMarshall,
149 /* 0x22 */
150 NdrConformantStringMarshall, 0, 0,
151 NdrConformantStringMarshall,
152 NdrNonConformantStringMarshall, 0, 0, 0,
153 /* 0x2a */
154 NdrEncapsulatedUnionMarshall,
155 NdrNonEncapsulatedUnionMarshall,
156 NdrByteCountPointerMarshall,
157 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
158 /* 0x2f */
159 NdrInterfacePointerMarshall,
160 /* 0x30 */
161 NdrContextHandleMarshall,
162 /* 0xb1 */
163 0, 0, 0,
164 NdrUserMarshalMarshall,
165 0, 0,
166 /* 0xb7 */
167 NdrRangeMarshall
169 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 /* 0x10 */
176 NdrBaseTypeUnmarshall,
177 /* 0x11 */
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 /* 0x15 */
181 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
182 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
183 NdrConformantVaryingStructUnmarshall,
184 NdrComplexStructUnmarshall,
185 /* 0x1b */
186 NdrConformantArrayUnmarshall,
187 NdrConformantVaryingArrayUnmarshall,
188 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
189 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
190 NdrComplexArrayUnmarshall,
191 /* 0x22 */
192 NdrConformantStringUnmarshall, 0, 0,
193 NdrConformantStringUnmarshall,
194 NdrNonConformantStringUnmarshall, 0, 0, 0,
195 /* 0x2a */
196 NdrEncapsulatedUnionUnmarshall,
197 NdrNonEncapsulatedUnionUnmarshall,
198 NdrByteCountPointerUnmarshall,
199 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
200 /* 0x2f */
201 NdrInterfacePointerUnmarshall,
202 /* 0x30 */
203 NdrContextHandleUnmarshall,
204 /* 0xb1 */
205 0, 0, 0,
206 NdrUserMarshalUnmarshall,
207 0, 0,
208 /* 0xb7 */
209 NdrRangeUnmarshall
211 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 /* 0x10 */
218 NdrBaseTypeBufferSize,
219 /* 0x11 */
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 NdrPointerBufferSize, NdrPointerBufferSize,
222 /* 0x15 */
223 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
224 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
225 NdrConformantVaryingStructBufferSize,
226 NdrComplexStructBufferSize,
227 /* 0x1b */
228 NdrConformantArrayBufferSize,
229 NdrConformantVaryingArrayBufferSize,
230 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
231 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
232 NdrComplexArrayBufferSize,
233 /* 0x22 */
234 NdrConformantStringBufferSize, 0, 0,
235 NdrConformantStringBufferSize,
236 NdrNonConformantStringBufferSize, 0, 0, 0,
237 /* 0x2a */
238 NdrEncapsulatedUnionBufferSize,
239 NdrNonEncapsulatedUnionBufferSize,
240 NdrByteCountPointerBufferSize,
241 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
242 /* 0x2f */
243 NdrInterfacePointerBufferSize,
244 /* 0x30 */
245 NdrContextHandleBufferSize,
246 /* 0xb1 */
247 0, 0, 0,
248 NdrUserMarshalBufferSize,
249 0, 0,
250 /* 0xb7 */
251 NdrRangeBufferSize
253 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 /* 0x10 */
260 NdrBaseTypeMemorySize,
261 /* 0x11 */
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 NdrPointerMemorySize, NdrPointerMemorySize,
264 /* 0x15 */
265 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
266 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
267 NdrConformantVaryingStructMemorySize,
268 NdrComplexStructMemorySize,
269 /* 0x1b */
270 NdrConformantArrayMemorySize,
271 NdrConformantVaryingArrayMemorySize,
272 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
273 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
274 NdrComplexArrayMemorySize,
275 /* 0x22 */
276 NdrConformantStringMemorySize, 0, 0,
277 NdrConformantStringMemorySize,
278 NdrNonConformantStringMemorySize, 0, 0, 0,
279 /* 0x2a */
280 NdrEncapsulatedUnionMemorySize,
281 NdrNonEncapsulatedUnionMemorySize,
282 NdrByteCountPointerMemorySize,
283 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
284 /* 0x2f */
285 NdrInterfacePointerMemorySize,
286 /* 0x30 */
288 /* 0xb1 */
289 0, 0, 0,
290 NdrUserMarshalMemorySize,
291 0, 0,
292 /* 0xb7 */
293 NdrRangeMemorySize
295 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 /* 0x10 */
302 NdrBaseTypeFree,
303 /* 0x11 */
304 NdrPointerFree, NdrPointerFree,
305 NdrPointerFree, NdrPointerFree,
306 /* 0x15 */
307 NdrSimpleStructFree, NdrSimpleStructFree,
308 NdrConformantStructFree, NdrConformantStructFree,
309 NdrConformantVaryingStructFree,
310 NdrComplexStructFree,
311 /* 0x1b */
312 NdrConformantArrayFree,
313 NdrConformantVaryingArrayFree,
314 NdrFixedArrayFree, NdrFixedArrayFree,
315 NdrVaryingArrayFree, NdrVaryingArrayFree,
316 NdrComplexArrayFree,
317 /* 0x22 */
318 0, 0, 0,
319 0, 0, 0, 0, 0,
320 /* 0x2a */
321 NdrEncapsulatedUnionFree,
322 NdrNonEncapsulatedUnionFree,
324 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
325 /* 0x2f */
326 NdrInterfacePointerFree,
327 /* 0x30 */
329 /* 0xb1 */
330 0, 0, 0,
331 NdrUserMarshalFree,
332 0, 0,
333 /* 0xb7 */
334 NdrRangeFree
337 typedef struct _NDR_MEMORY_LIST
339 ULONG magic;
340 ULONG size;
341 ULONG reserved;
342 struct _NDR_MEMORY_LIST *next;
343 } NDR_MEMORY_LIST;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * PARAMS
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
356 * RETURNS
357 * The memory block of size len that was allocated.
359 * NOTES
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
366 size_t aligned_len;
367 size_t adjusted_len;
368 void *p;
369 NDR_MEMORY_LIST *mem_list;
371 aligned_len = ALIGNED_LENGTH(len, 8);
372 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
373 /* check for overflow */
374 if (adjusted_len < len)
376 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA);
380 p = pStubMsg->pfnAllocate(adjusted_len);
381 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
383 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
384 mem_list->magic = MEML_MAGIC;
385 mem_list->size = aligned_len;
386 mem_list->reserved = 0;
387 mem_list->next = pStubMsg->pMemoryList;
388 pStubMsg->pMemoryList = mem_list;
390 TRACE("-- %p\n", p);
391 return p;
394 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
396 TRACE("(%p, %p)\n", pStubMsg, Pointer);
398 pStubMsg->pfnFree(Pointer);
401 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
403 return (*(const ULONG *)pFormat != -1);
406 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
408 ALIGN_POINTER(pStubMsg->Buffer, 4);
409 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
411 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
412 pStubMsg->Buffer += 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
414 if (pStubMsg->fHasNewCorrDesc)
415 return pFormat+6;
416 else
417 return pFormat+4;
420 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
422 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
424 pStubMsg->Offset = 0;
425 pStubMsg->ActualCount = pStubMsg->MaxCount;
426 goto done;
429 ALIGN_POINTER(pStubMsg->Buffer, 4);
430 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
432 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
433 pStubMsg->Buffer += 4;
434 TRACE("offset is %d\n", pStubMsg->Offset);
435 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
436 pStubMsg->Buffer += 4;
437 TRACE("variance is %d\n", pStubMsg->ActualCount);
439 if ((pStubMsg->ActualCount > MaxValue) ||
440 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
444 RpcRaiseException(RPC_S_INVALID_BOUND);
445 return NULL;
448 done:
449 if (pStubMsg->fHasNewCorrDesc)
450 return pFormat+6;
451 else
452 return pFormat+4;
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
458 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
459 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
462 pStubMsg->Buffer += 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
468 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
469 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
472 pStubMsg->Buffer += 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
474 pStubMsg->Buffer += 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
480 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
481 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA);
483 pStubMsg->BufferLength += 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
489 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
490 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
492 pStubMsg->BufferLength += 8;
495 PFORMAT_STRING ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
497 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
499 BYTE dtype = pFormat[0] & 0xf;
500 short ofs = *(const short *)&pFormat[2];
501 LPVOID ptr = NULL;
502 DWORD data = 0;
504 if (!IsConformanceOrVariancePresent(pFormat)) {
505 /* null descriptor */
506 *pCount = def;
507 goto finish_conf;
510 switch (pFormat[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE:
512 TRACE("normal conformance, ofs=%d\n", ofs);
513 ptr = pMemory;
514 break;
515 case RPC_FC_POINTER_CONFORMANCE:
516 TRACE("pointer conformance, ofs=%d\n", ofs);
517 ptr = pStubMsg->Memory;
518 break;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE:
520 TRACE("toplevel conformance, ofs=%d\n", ofs);
521 if (pStubMsg->StackTop) {
522 ptr = pStubMsg->StackTop;
524 else {
525 /* -Os mode, *pCount is already set */
526 goto finish_conf;
528 break;
529 case RPC_FC_CONSTANT_CONFORMANCE:
530 data = ofs | ((DWORD)pFormat[1] << 16);
531 TRACE("constant conformance, val=%d\n", data);
532 *pCount = data;
533 goto finish_conf;
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
536 if (pStubMsg->StackTop) {
537 ptr = pStubMsg->StackTop;
539 else {
540 /* ? */
541 goto done_conf_grab;
543 break;
544 default:
545 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
548 switch (pFormat[1]) {
549 case RPC_FC_DEREFERENCE:
550 ptr = *(LPVOID*)((char *)ptr + ofs);
551 break;
552 case RPC_FC_CALLBACK:
554 unsigned char *old_stack_top = pStubMsg->StackTop;
555 pStubMsg->StackTop = ptr;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
559 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
561 pStubMsg->StackTop = old_stack_top;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount = pStubMsg->MaxCount;
565 goto finish_conf;
567 default:
568 ptr = (char *)ptr + ofs;
569 break;
572 switch (dtype) {
573 case RPC_FC_LONG:
574 case RPC_FC_ULONG:
575 data = *(DWORD*)ptr;
576 break;
577 case RPC_FC_SHORT:
578 data = *(SHORT*)ptr;
579 break;
580 case RPC_FC_USHORT:
581 data = *(USHORT*)ptr;
582 break;
583 case RPC_FC_CHAR:
584 case RPC_FC_SMALL:
585 data = *(CHAR*)ptr;
586 break;
587 case RPC_FC_BYTE:
588 case RPC_FC_USMALL:
589 data = *(UCHAR*)ptr;
590 break;
591 default:
592 FIXME("unknown conformance data type %x\n", dtype);
593 goto done_conf_grab;
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
597 done_conf_grab:
598 switch (pFormat[1]) {
599 case RPC_FC_DEREFERENCE: /* already handled */
600 case 0: /* no op */
601 *pCount = data;
602 break;
603 case RPC_FC_ADD_1:
604 *pCount = data + 1;
605 break;
606 case RPC_FC_SUB_1:
607 *pCount = data - 1;
608 break;
609 case RPC_FC_MULT_2:
610 *pCount = data * 2;
611 break;
612 case RPC_FC_DIV_2:
613 *pCount = data / 2;
614 break;
615 default:
616 FIXME("unknown conformance op %d\n", pFormat[1]);
617 goto finish_conf;
620 finish_conf:
621 TRACE("resulting conformance is %ld\n", *pCount);
622 if (pStubMsg->fHasNewCorrDesc)
623 return pFormat+6;
624 else
625 return pFormat+4;
628 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
629 * the result overflows 32-bits */
630 static inline ULONG safe_multiply(ULONG a, ULONG b)
632 ULONGLONG ret = (ULONGLONG)a * b;
633 if (ret > 0xffffffff)
635 RpcRaiseException(RPC_S_INVALID_BOUND);
636 return 0;
638 return ret;
641 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
643 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
644 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
646 pStubMsg->Buffer += size;
649 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
651 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
653 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
654 pStubMsg->BufferLength, size);
655 RpcRaiseException(RPC_X_BAD_STUB_DATA);
657 pStubMsg->BufferLength += size;
660 /* copies data from the buffer, checking that there is enough data in the buffer
661 * to do so */
662 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
664 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
665 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
667 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
668 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
669 RpcRaiseException(RPC_X_BAD_STUB_DATA);
671 if (p == pStubMsg->Buffer)
672 ERR("pointer is the same as the buffer\n");
673 memcpy(p, pStubMsg->Buffer, size);
674 pStubMsg->Buffer += size;
677 /* copies data to the buffer, checking that there is enough space to do so */
678 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
680 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
681 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
683 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
684 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
685 size);
686 RpcRaiseException(RPC_X_BAD_STUB_DATA);
688 memcpy(pStubMsg->Buffer, p, size);
689 pStubMsg->Buffer += size;
693 * NdrConformantString:
695 * What MS calls a ConformantString is, in DCE terminology,
696 * a Varying-Conformant String.
698 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
699 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
700 * into unmarshalled string)
701 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * [
703 * data: CHARTYPE[maxlen]
704 * ]
705 * ], where CHARTYPE is the appropriate character type (specified externally)
709 /***********************************************************************
710 * NdrConformantStringMarshall [RPCRT4.@]
712 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
713 unsigned char *pszMessage, PFORMAT_STRING pFormat)
715 ULONG esize, size;
717 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
719 if (*pFormat == RPC_FC_C_CSTRING) {
720 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
721 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
722 esize = 1;
724 else if (*pFormat == RPC_FC_C_WSTRING) {
725 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
726 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
727 esize = 2;
729 else {
730 ERR("Unhandled string type: %#x\n", *pFormat);
731 /* FIXME: raise an exception. */
732 return NULL;
735 if (pFormat[1] == RPC_FC_STRING_SIZED)
736 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
737 else
738 pStubMsg->MaxCount = pStubMsg->ActualCount;
739 pStubMsg->Offset = 0;
740 WriteConformance(pStubMsg);
741 WriteVariance(pStubMsg);
743 size = safe_multiply(esize, pStubMsg->ActualCount);
744 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
746 /* success */
747 return NULL; /* is this always right? */
750 /***********************************************************************
751 * NdrConformantStringBufferSize [RPCRT4.@]
753 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
754 unsigned char* pMemory, PFORMAT_STRING pFormat)
756 ULONG esize;
758 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
760 SizeConformance(pStubMsg);
761 SizeVariance(pStubMsg);
763 if (*pFormat == RPC_FC_C_CSTRING) {
764 TRACE("string=%s\n", debugstr_a((char*)pMemory));
765 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
766 esize = 1;
768 else if (*pFormat == RPC_FC_C_WSTRING) {
769 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
770 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
771 esize = 2;
773 else {
774 ERR("Unhandled string type: %#x\n", *pFormat);
775 /* FIXME: raise an exception */
776 return;
779 if (pFormat[1] == RPC_FC_STRING_SIZED)
780 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
781 else
782 pStubMsg->MaxCount = pStubMsg->ActualCount;
784 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
787 /************************************************************************
788 * NdrConformantStringMemorySize [RPCRT4.@]
790 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
791 PFORMAT_STRING pFormat )
793 ULONG rslt = 0;
795 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
797 assert(pStubMsg && pFormat);
799 if (*pFormat == RPC_FC_C_CSTRING) {
800 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
802 else if (*pFormat == RPC_FC_C_WSTRING) {
803 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
805 else {
806 ERR("Unhandled string type: %#x\n", *pFormat);
807 /* FIXME: raise an exception */
810 if (pFormat[1] != RPC_FC_PAD) {
811 FIXME("sized string format=%d\n", pFormat[1]);
814 TRACE(" --> %u\n", rslt);
815 return rslt;
818 /************************************************************************
819 * NdrConformantStringUnmarshall [RPCRT4.@]
821 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
822 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
824 ULONG bufsize, memsize, esize, i;
826 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
827 pStubMsg, *ppMemory, pFormat, fMustAlloc);
829 assert(pFormat && ppMemory && pStubMsg);
831 ReadConformance(pStubMsg, NULL);
832 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
834 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
836 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
837 pStubMsg->ActualCount, pStubMsg->MaxCount);
838 RpcRaiseException(RPC_S_INVALID_BOUND);
839 return NULL;
841 if (pStubMsg->Offset)
843 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
844 RpcRaiseException(RPC_S_INVALID_BOUND);
845 return NULL;
848 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
849 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
850 else {
851 ERR("Unhandled string type: %#x\n", *pFormat);
852 /* FIXME: raise an exception */
853 esize = 0;
856 memsize = safe_multiply(esize, pStubMsg->MaxCount);
857 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
859 /* strings must always have null terminating bytes */
860 if (bufsize < esize)
862 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
863 RpcRaiseException(RPC_S_INVALID_BOUND);
864 return NULL;
867 /* verify the buffer is safe to access */
868 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
869 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
871 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
872 pStubMsg->BufferEnd, pStubMsg->Buffer);
873 RpcRaiseException(RPC_X_BAD_STUB_DATA);
874 return NULL;
877 for (i = bufsize - esize; i < bufsize; i++)
878 if (pStubMsg->Buffer[i] != 0)
880 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
881 i, pStubMsg->Buffer[i]);
882 RpcRaiseException(RPC_S_INVALID_BOUND);
883 return NULL;
886 if (fMustAlloc)
887 *ppMemory = NdrAllocate(pStubMsg, memsize);
888 else
890 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
891 /* if the data in the RPC buffer is big enough, we just point straight
892 * into it */
893 *ppMemory = pStubMsg->Buffer;
894 else if (!*ppMemory)
895 *ppMemory = NdrAllocate(pStubMsg, memsize);
898 if (*ppMemory == pStubMsg->Buffer)
899 safe_buffer_increment(pStubMsg, bufsize);
900 else
901 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
903 if (*pFormat == RPC_FC_C_CSTRING) {
904 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
906 else if (*pFormat == RPC_FC_C_WSTRING) {
907 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
910 return NULL; /* FIXME: is this always right? */
913 /***********************************************************************
914 * NdrNonConformantStringMarshall [RPCRT4.@]
916 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
917 unsigned char *pMemory,
918 PFORMAT_STRING pFormat)
920 FIXME("stub\n");
921 return NULL;
924 /***********************************************************************
925 * NdrNonConformantStringUnmarshall [RPCRT4.@]
927 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
928 unsigned char **ppMemory,
929 PFORMAT_STRING pFormat,
930 unsigned char fMustAlloc)
932 FIXME("stub\n");
933 return NULL;
936 /***********************************************************************
937 * NdrNonConformantStringBufferSize [RPCRT4.@]
939 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
940 unsigned char *pMemory,
941 PFORMAT_STRING pFormat)
943 FIXME("stub\n");
946 /***********************************************************************
947 * NdrNonConformantStringMemorySize [RPCRT4.@]
949 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
950 PFORMAT_STRING pFormat)
952 FIXME("stub\n");
953 return 0;
956 static inline void dump_pointer_attr(unsigned char attr)
958 if (attr & RPC_FC_P_ALLOCALLNODES)
959 TRACE(" RPC_FC_P_ALLOCALLNODES");
960 if (attr & RPC_FC_P_DONTFREE)
961 TRACE(" RPC_FC_P_DONTFREE");
962 if (attr & RPC_FC_P_ONSTACK)
963 TRACE(" RPC_FC_P_ONSTACK");
964 if (attr & RPC_FC_P_SIMPLEPOINTER)
965 TRACE(" RPC_FC_P_SIMPLEPOINTER");
966 if (attr & RPC_FC_P_DEREF)
967 TRACE(" RPC_FC_P_DEREF");
968 TRACE("\n");
971 /***********************************************************************
972 * PointerMarshall [internal]
974 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
975 unsigned char *Buffer,
976 unsigned char *Pointer,
977 PFORMAT_STRING pFormat)
979 unsigned type = pFormat[0], attr = pFormat[1];
980 PFORMAT_STRING desc;
981 NDR_MARSHALL m;
982 ULONG pointer_id;
983 int pointer_needs_marshaling;
985 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
986 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
987 pFormat += 2;
988 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
989 else desc = pFormat + *(const SHORT*)pFormat;
991 switch (type) {
992 case RPC_FC_RP: /* ref pointer (always non-null) */
993 if (!Pointer)
995 ERR("NULL ref pointer is not allowed\n");
996 RpcRaiseException(RPC_X_NULL_REF_POINTER);
998 pointer_needs_marshaling = 1;
999 break;
1000 case RPC_FC_UP: /* unique pointer */
1001 case RPC_FC_OP: /* object pointer - same as unique here */
1002 if (Pointer)
1003 pointer_needs_marshaling = 1;
1004 else
1005 pointer_needs_marshaling = 0;
1006 pointer_id = (ULONG)Pointer;
1007 TRACE("writing 0x%08x to buffer\n", pointer_id);
1008 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1009 break;
1010 case RPC_FC_FP:
1011 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1012 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1013 TRACE("writing 0x%08x to buffer\n", pointer_id);
1014 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1015 break;
1016 default:
1017 FIXME("unhandled ptr type=%02x\n", type);
1018 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1019 return;
1022 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1024 if (pointer_needs_marshaling) {
1025 if (attr & RPC_FC_P_DEREF) {
1026 Pointer = *(unsigned char**)Pointer;
1027 TRACE("deref => %p\n", Pointer);
1029 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1030 if (m) m(pStubMsg, Pointer, desc);
1031 else FIXME("no marshaller for data type=%02x\n", *desc);
1034 STD_OVERFLOW_CHECK(pStubMsg);
1037 /***********************************************************************
1038 * PointerUnmarshall [internal]
1040 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1041 unsigned char *Buffer,
1042 unsigned char **pPointer,
1043 unsigned char *pSrcPointer,
1044 PFORMAT_STRING pFormat,
1045 unsigned char fMustAlloc)
1047 unsigned type = pFormat[0], attr = pFormat[1];
1048 PFORMAT_STRING desc;
1049 NDR_UNMARSHALL m;
1050 DWORD pointer_id = 0;
1051 int pointer_needs_unmarshaling;
1053 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1054 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1055 pFormat += 2;
1056 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1057 else desc = pFormat + *(const SHORT*)pFormat;
1059 switch (type) {
1060 case RPC_FC_RP: /* ref pointer (always non-null) */
1061 pointer_needs_unmarshaling = 1;
1062 break;
1063 case RPC_FC_UP: /* unique pointer */
1064 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1065 TRACE("pointer_id is 0x%08x\n", pointer_id);
1066 if (pointer_id)
1067 pointer_needs_unmarshaling = 1;
1068 else {
1069 *pPointer = NULL;
1070 pointer_needs_unmarshaling = 0;
1072 break;
1073 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1074 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1075 TRACE("pointer_id is 0x%08x\n", pointer_id);
1076 if (!fMustAlloc && pSrcPointer)
1078 FIXME("free object pointer %p\n", pSrcPointer);
1079 fMustAlloc = TRUE;
1081 if (pointer_id)
1082 pointer_needs_unmarshaling = 1;
1083 else
1084 pointer_needs_unmarshaling = 0;
1085 break;
1086 case RPC_FC_FP:
1087 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1088 TRACE("pointer_id is 0x%08x\n", pointer_id);
1089 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1090 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1091 break;
1092 default:
1093 FIXME("unhandled ptr type=%02x\n", type);
1094 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1095 return;
1098 if (pointer_needs_unmarshaling) {
1099 unsigned char *base_ptr_val = *pPointer;
1100 unsigned char **current_ptr = pPointer;
1101 if (pStubMsg->IsClient) {
1102 TRACE("client\n");
1103 /* if we aren't forcing allocation of memory then try to use the existing
1104 * (source) pointer to unmarshall the data into so that [in,out]
1105 * parameters behave correctly. it doesn't matter if the parameter is
1106 * [out] only since in that case the pointer will be NULL. we force
1107 * allocation when the source pointer is NULL here instead of in the type
1108 * unmarshalling routine for the benefit of the deref code below */
1109 if (!fMustAlloc) {
1110 if (pSrcPointer) {
1111 TRACE("setting *pPointer to %p\n", pSrcPointer);
1112 *pPointer = base_ptr_val = pSrcPointer;
1113 } else
1114 fMustAlloc = TRUE;
1116 } else {
1117 TRACE("server\n");
1118 /* the memory in a stub is never initialised, so we have to work out here
1119 * whether we have to initialise it so we can use the optimisation of
1120 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1121 * TRUE. */
1122 if (attr & RPC_FC_P_DEREF) {
1123 fMustAlloc = TRUE;
1124 } else {
1125 base_ptr_val = NULL;
1126 *current_ptr = NULL;
1130 if (attr & RPC_FC_P_ALLOCALLNODES)
1131 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1133 if (attr & RPC_FC_P_DEREF) {
1134 if (fMustAlloc) {
1135 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1136 *pPointer = base_ptr_val;
1137 current_ptr = (unsigned char **)base_ptr_val;
1138 } else
1139 current_ptr = *(unsigned char***)current_ptr;
1140 TRACE("deref => %p\n", current_ptr);
1141 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1143 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1144 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1145 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1147 if (type == RPC_FC_FP)
1148 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1149 base_ptr_val);
1152 TRACE("pointer=%p\n", *pPointer);
1155 /***********************************************************************
1156 * PointerBufferSize [internal]
1158 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1159 unsigned char *Pointer,
1160 PFORMAT_STRING pFormat)
1162 unsigned type = pFormat[0], attr = pFormat[1];
1163 PFORMAT_STRING desc;
1164 NDR_BUFFERSIZE m;
1165 int pointer_needs_sizing;
1166 ULONG pointer_id;
1168 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1169 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1170 pFormat += 2;
1171 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1172 else desc = pFormat + *(const SHORT*)pFormat;
1174 switch (type) {
1175 case RPC_FC_RP: /* ref pointer (always non-null) */
1176 if (!Pointer)
1178 ERR("NULL ref pointer is not allowed\n");
1179 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1181 break;
1182 case RPC_FC_OP:
1183 case RPC_FC_UP:
1184 /* NULL pointer has no further representation */
1185 if (!Pointer)
1186 return;
1187 break;
1188 case RPC_FC_FP:
1189 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1190 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1191 if (!pointer_needs_sizing)
1192 return;
1193 break;
1194 default:
1195 FIXME("unhandled ptr type=%02x\n", type);
1196 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1197 return;
1200 if (attr & RPC_FC_P_DEREF) {
1201 Pointer = *(unsigned char**)Pointer;
1202 TRACE("deref => %p\n", Pointer);
1205 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1206 if (m) m(pStubMsg, Pointer, desc);
1207 else FIXME("no buffersizer for data type=%02x\n", *desc);
1210 /***********************************************************************
1211 * PointerMemorySize [internal]
1213 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1214 unsigned char *Buffer,
1215 PFORMAT_STRING pFormat)
1217 unsigned type = pFormat[0], attr = pFormat[1];
1218 PFORMAT_STRING desc;
1219 NDR_MEMORYSIZE m;
1220 DWORD pointer_id = 0;
1221 int pointer_needs_sizing;
1223 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1224 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1225 pFormat += 2;
1226 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1227 else desc = pFormat + *(const SHORT*)pFormat;
1229 switch (type) {
1230 case RPC_FC_RP: /* ref pointer (always non-null) */
1231 pointer_needs_sizing = 1;
1232 break;
1233 case RPC_FC_UP: /* unique pointer */
1234 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1235 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1236 TRACE("pointer_id is 0x%08x\n", pointer_id);
1237 if (pointer_id)
1238 pointer_needs_sizing = 1;
1239 else
1240 pointer_needs_sizing = 0;
1241 break;
1242 case RPC_FC_FP:
1244 void *pointer;
1245 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id);
1247 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1248 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1249 break;
1251 default:
1252 FIXME("unhandled ptr type=%02x\n", type);
1253 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1254 return 0;
1257 if (attr & RPC_FC_P_DEREF) {
1258 TRACE("deref\n");
1261 if (pointer_needs_sizing) {
1262 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1263 if (m) m(pStubMsg, desc);
1264 else FIXME("no memorysizer for data type=%02x\n", *desc);
1267 return pStubMsg->MemorySize;
1270 /***********************************************************************
1271 * PointerFree [internal]
1273 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1274 unsigned char *Pointer,
1275 PFORMAT_STRING pFormat)
1277 unsigned type = pFormat[0], attr = pFormat[1];
1278 PFORMAT_STRING desc;
1279 NDR_FREE m;
1280 unsigned char *current_pointer = Pointer;
1282 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1283 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1284 if (attr & RPC_FC_P_DONTFREE) return;
1285 pFormat += 2;
1286 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1287 else desc = pFormat + *(const SHORT*)pFormat;
1289 if (!Pointer) return;
1291 if (type == RPC_FC_FP) {
1292 int pointer_needs_freeing = NdrFullPointerFree(
1293 pStubMsg->FullPtrXlatTables, Pointer);
1294 if (!pointer_needs_freeing)
1295 return;
1298 if (attr & RPC_FC_P_DEREF) {
1299 current_pointer = *(unsigned char**)Pointer;
1300 TRACE("deref => %p\n", current_pointer);
1303 m = NdrFreer[*desc & NDR_TABLE_MASK];
1304 if (m) m(pStubMsg, current_pointer, desc);
1306 /* this check stops us from trying to free buffer memory. we don't have to
1307 * worry about clients, since they won't call this function.
1308 * we don't have to check for the buffer being reallocated because
1309 * BufferStart and BufferEnd won't be reset when allocating memory for
1310 * sending the response. we don't have to check for the new buffer here as
1311 * it won't be used a type memory, only for buffer memory */
1312 if (Pointer >= (unsigned char *)pStubMsg->BufferStart &&
1313 Pointer < (unsigned char *)pStubMsg->BufferEnd)
1314 goto notfree;
1316 if (attr & RPC_FC_P_ONSTACK) {
1317 TRACE("not freeing stack ptr %p\n", Pointer);
1318 return;
1320 TRACE("freeing %p\n", Pointer);
1321 NdrFree(pStubMsg, Pointer);
1322 return;
1323 notfree:
1324 TRACE("not freeing %p\n", Pointer);
1327 /***********************************************************************
1328 * EmbeddedPointerMarshall
1330 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1331 unsigned char *pMemory,
1332 PFORMAT_STRING pFormat)
1334 unsigned char *Mark = pStubMsg->BufferMark;
1335 unsigned rep, count, stride;
1336 unsigned i;
1337 unsigned char *saved_buffer = NULL;
1339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1341 if (*pFormat != RPC_FC_PP) return NULL;
1342 pFormat += 2;
1344 if (pStubMsg->PointerBufferMark)
1346 saved_buffer = pStubMsg->Buffer;
1347 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1348 pStubMsg->PointerBufferMark = NULL;
1351 while (pFormat[0] != RPC_FC_END) {
1352 switch (pFormat[0]) {
1353 default:
1354 FIXME("unknown repeat type %d\n", pFormat[0]);
1355 case RPC_FC_NO_REPEAT:
1356 rep = 1;
1357 stride = 0;
1358 count = 1;
1359 pFormat += 2;
1360 break;
1361 case RPC_FC_FIXED_REPEAT:
1362 rep = *(const WORD*)&pFormat[2];
1363 stride = *(const WORD*)&pFormat[4];
1364 count = *(const WORD*)&pFormat[8];
1365 pFormat += 10;
1366 break;
1367 case RPC_FC_VARIABLE_REPEAT:
1368 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1369 stride = *(const WORD*)&pFormat[2];
1370 count = *(const WORD*)&pFormat[6];
1371 pFormat += 8;
1372 break;
1374 for (i = 0; i < rep; i++) {
1375 PFORMAT_STRING info = pFormat;
1376 unsigned char *membase = pMemory + (i * stride);
1377 unsigned char *bufbase = Mark + (i * stride);
1378 unsigned u;
1380 for (u=0; u<count; u++,info+=8) {
1381 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1382 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1383 unsigned char *saved_memory = pStubMsg->Memory;
1385 pStubMsg->Memory = pMemory;
1386 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1387 pStubMsg->Memory = saved_memory;
1390 pFormat += 8 * count;
1393 if (saved_buffer)
1395 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1396 pStubMsg->Buffer = saved_buffer;
1399 STD_OVERFLOW_CHECK(pStubMsg);
1401 return NULL;
1404 /***********************************************************************
1405 * EmbeddedPointerUnmarshall
1407 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1408 unsigned char *pDstMemoryPtrs,
1409 unsigned char *pSrcMemoryPtrs,
1410 PFORMAT_STRING pFormat,
1411 unsigned char fMustAlloc)
1413 unsigned char *Mark = pStubMsg->BufferMark;
1414 unsigned rep, count, stride;
1415 unsigned i;
1416 unsigned char *saved_buffer = NULL;
1418 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1420 if (*pFormat != RPC_FC_PP) return NULL;
1421 pFormat += 2;
1423 if (pStubMsg->PointerBufferMark)
1425 saved_buffer = pStubMsg->Buffer;
1426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1427 pStubMsg->PointerBufferMark = NULL;
1430 while (pFormat[0] != RPC_FC_END) {
1431 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1432 switch (pFormat[0]) {
1433 default:
1434 FIXME("unknown repeat type %d\n", pFormat[0]);
1435 case RPC_FC_NO_REPEAT:
1436 rep = 1;
1437 stride = 0;
1438 count = 1;
1439 pFormat += 2;
1440 break;
1441 case RPC_FC_FIXED_REPEAT:
1442 rep = *(const WORD*)&pFormat[2];
1443 stride = *(const WORD*)&pFormat[4];
1444 count = *(const WORD*)&pFormat[8];
1445 pFormat += 10;
1446 break;
1447 case RPC_FC_VARIABLE_REPEAT:
1448 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1449 stride = *(const WORD*)&pFormat[2];
1450 count = *(const WORD*)&pFormat[6];
1451 pFormat += 8;
1452 break;
1454 for (i = 0; i < rep; i++) {
1455 PFORMAT_STRING info = pFormat;
1456 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1457 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1458 unsigned char *bufbase = Mark + (i * stride);
1459 unsigned u;
1461 for (u=0; u<count; u++,info+=8) {
1462 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1463 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1464 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1465 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1468 pFormat += 8 * count;
1471 if (saved_buffer)
1473 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1474 pStubMsg->Buffer = saved_buffer;
1477 return NULL;
1480 /***********************************************************************
1481 * EmbeddedPointerBufferSize
1483 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1484 unsigned char *pMemory,
1485 PFORMAT_STRING pFormat)
1487 unsigned rep, count, stride;
1488 unsigned i;
1489 ULONG saved_buffer_length = 0;
1491 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1493 if (pStubMsg->IgnoreEmbeddedPointers) return;
1495 if (*pFormat != RPC_FC_PP) return;
1496 pFormat += 2;
1498 if (pStubMsg->PointerLength)
1500 saved_buffer_length = pStubMsg->BufferLength;
1501 pStubMsg->BufferLength = pStubMsg->PointerLength;
1502 pStubMsg->PointerLength = 0;
1505 while (pFormat[0] != RPC_FC_END) {
1506 switch (pFormat[0]) {
1507 default:
1508 FIXME("unknown repeat type %d\n", pFormat[0]);
1509 case RPC_FC_NO_REPEAT:
1510 rep = 1;
1511 stride = 0;
1512 count = 1;
1513 pFormat += 2;
1514 break;
1515 case RPC_FC_FIXED_REPEAT:
1516 rep = *(const WORD*)&pFormat[2];
1517 stride = *(const WORD*)&pFormat[4];
1518 count = *(const WORD*)&pFormat[8];
1519 pFormat += 10;
1520 break;
1521 case RPC_FC_VARIABLE_REPEAT:
1522 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1523 stride = *(const WORD*)&pFormat[2];
1524 count = *(const WORD*)&pFormat[6];
1525 pFormat += 8;
1526 break;
1528 for (i = 0; i < rep; i++) {
1529 PFORMAT_STRING info = pFormat;
1530 unsigned char *membase = pMemory + (i * stride);
1531 unsigned u;
1533 for (u=0; u<count; u++,info+=8) {
1534 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1535 unsigned char *saved_memory = pStubMsg->Memory;
1537 pStubMsg->Memory = pMemory;
1538 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1539 pStubMsg->Memory = saved_memory;
1542 pFormat += 8 * count;
1545 if (saved_buffer_length)
1547 pStubMsg->PointerLength = pStubMsg->BufferLength;
1548 pStubMsg->BufferLength = saved_buffer_length;
1552 /***********************************************************************
1553 * EmbeddedPointerMemorySize [internal]
1555 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1556 PFORMAT_STRING pFormat)
1558 unsigned char *Mark = pStubMsg->BufferMark;
1559 unsigned rep, count, stride;
1560 unsigned i;
1561 unsigned char *saved_buffer = NULL;
1563 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1565 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1567 if (pStubMsg->PointerBufferMark)
1569 saved_buffer = pStubMsg->Buffer;
1570 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1571 pStubMsg->PointerBufferMark = NULL;
1574 if (*pFormat != RPC_FC_PP) return 0;
1575 pFormat += 2;
1577 while (pFormat[0] != RPC_FC_END) {
1578 switch (pFormat[0]) {
1579 default:
1580 FIXME("unknown repeat type %d\n", pFormat[0]);
1581 case RPC_FC_NO_REPEAT:
1582 rep = 1;
1583 stride = 0;
1584 count = 1;
1585 pFormat += 2;
1586 break;
1587 case RPC_FC_FIXED_REPEAT:
1588 rep = *(const WORD*)&pFormat[2];
1589 stride = *(const WORD*)&pFormat[4];
1590 count = *(const WORD*)&pFormat[8];
1591 pFormat += 10;
1592 break;
1593 case RPC_FC_VARIABLE_REPEAT:
1594 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1595 stride = *(const WORD*)&pFormat[2];
1596 count = *(const WORD*)&pFormat[6];
1597 pFormat += 8;
1598 break;
1600 for (i = 0; i < rep; i++) {
1601 PFORMAT_STRING info = pFormat;
1602 unsigned char *bufbase = Mark + (i * stride);
1603 unsigned u;
1604 for (u=0; u<count; u++,info+=8) {
1605 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1606 PointerMemorySize(pStubMsg, bufptr, info+4);
1609 pFormat += 8 * count;
1612 if (saved_buffer)
1614 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1615 pStubMsg->Buffer = saved_buffer;
1618 return 0;
1621 /***********************************************************************
1622 * EmbeddedPointerFree [internal]
1624 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pMemory,
1626 PFORMAT_STRING pFormat)
1628 unsigned rep, count, stride;
1629 unsigned i;
1631 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1632 if (*pFormat != RPC_FC_PP) return;
1633 pFormat += 2;
1635 while (pFormat[0] != RPC_FC_END) {
1636 switch (pFormat[0]) {
1637 default:
1638 FIXME("unknown repeat type %d\n", pFormat[0]);
1639 case RPC_FC_NO_REPEAT:
1640 rep = 1;
1641 stride = 0;
1642 count = 1;
1643 pFormat += 2;
1644 break;
1645 case RPC_FC_FIXED_REPEAT:
1646 rep = *(const WORD*)&pFormat[2];
1647 stride = *(const WORD*)&pFormat[4];
1648 count = *(const WORD*)&pFormat[8];
1649 pFormat += 10;
1650 break;
1651 case RPC_FC_VARIABLE_REPEAT:
1652 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1653 stride = *(const WORD*)&pFormat[2];
1654 count = *(const WORD*)&pFormat[6];
1655 pFormat += 8;
1656 break;
1658 for (i = 0; i < rep; i++) {
1659 PFORMAT_STRING info = pFormat;
1660 unsigned char *membase = pMemory + (i * stride);
1661 unsigned u;
1663 for (u=0; u<count; u++,info+=8) {
1664 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1665 unsigned char *saved_memory = pStubMsg->Memory;
1667 pStubMsg->Memory = pMemory;
1668 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1669 pStubMsg->Memory = saved_memory;
1672 pFormat += 8 * count;
1676 /***********************************************************************
1677 * NdrPointerMarshall [RPCRT4.@]
1679 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1680 unsigned char *pMemory,
1681 PFORMAT_STRING pFormat)
1683 unsigned char *Buffer;
1685 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1687 /* incremement the buffer here instead of in PointerMarshall,
1688 * as that is used by embedded pointers which already handle the incrementing
1689 * the buffer, and shouldn't write any additional pointer data to the wire */
1690 if (*pFormat != RPC_FC_RP)
1692 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1693 Buffer = pStubMsg->Buffer;
1694 safe_buffer_increment(pStubMsg, 4);
1696 else
1697 Buffer = pStubMsg->Buffer;
1699 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1701 return NULL;
1704 /***********************************************************************
1705 * NdrPointerUnmarshall [RPCRT4.@]
1707 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1708 unsigned char **ppMemory,
1709 PFORMAT_STRING pFormat,
1710 unsigned char fMustAlloc)
1712 unsigned char *Buffer;
1714 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1716 /* incremement the buffer here instead of in PointerUnmarshall,
1717 * as that is used by embedded pointers which already handle the incrementing
1718 * the buffer, and shouldn't read any additional pointer data from the
1719 * buffer */
1720 if (*pFormat != RPC_FC_RP)
1722 ALIGN_POINTER(pStubMsg->Buffer, 4);
1723 Buffer = pStubMsg->Buffer;
1724 safe_buffer_increment(pStubMsg, 4);
1726 else
1727 Buffer = pStubMsg->Buffer;
1729 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1731 return NULL;
1734 /***********************************************************************
1735 * NdrPointerBufferSize [RPCRT4.@]
1737 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char *pMemory,
1739 PFORMAT_STRING pFormat)
1741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1743 /* incremement the buffer length here instead of in PointerBufferSize,
1744 * as that is used by embedded pointers which already handle the buffer
1745 * length, and shouldn't write anything more to the wire */
1746 if (*pFormat != RPC_FC_RP)
1748 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1749 safe_buffer_length_increment(pStubMsg, 4);
1752 PointerBufferSize(pStubMsg, pMemory, pFormat);
1755 /***********************************************************************
1756 * NdrPointerMemorySize [RPCRT4.@]
1758 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1759 PFORMAT_STRING pFormat)
1761 /* unsigned size = *(LPWORD)(pFormat+2); */
1762 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1763 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1764 return 0;
1767 /***********************************************************************
1768 * NdrPointerFree [RPCRT4.@]
1770 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1771 unsigned char *pMemory,
1772 PFORMAT_STRING pFormat)
1774 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1775 PointerFree(pStubMsg, pMemory, pFormat);
1778 /***********************************************************************
1779 * NdrSimpleTypeMarshall [RPCRT4.@]
1781 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1782 unsigned char FormatChar )
1784 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1787 /***********************************************************************
1788 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1790 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1791 unsigned char FormatChar )
1793 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1796 /***********************************************************************
1797 * NdrSimpleStructMarshall [RPCRT4.@]
1799 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1800 unsigned char *pMemory,
1801 PFORMAT_STRING pFormat)
1803 unsigned size = *(const WORD*)(pFormat+2);
1804 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1806 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1808 pStubMsg->BufferMark = pStubMsg->Buffer;
1809 safe_copy_to_buffer(pStubMsg, pMemory, size);
1811 if (pFormat[0] != RPC_FC_STRUCT)
1812 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1814 return NULL;
1817 /***********************************************************************
1818 * NdrSimpleStructUnmarshall [RPCRT4.@]
1820 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1821 unsigned char **ppMemory,
1822 PFORMAT_STRING pFormat,
1823 unsigned char fMustAlloc)
1825 unsigned size = *(const WORD*)(pFormat+2);
1826 unsigned char *saved_buffer;
1827 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1829 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1831 if (fMustAlloc)
1832 *ppMemory = NdrAllocate(pStubMsg, size);
1833 else
1835 if (!pStubMsg->IsClient && !*ppMemory)
1836 /* for servers, we just point straight into the RPC buffer */
1837 *ppMemory = pStubMsg->Buffer;
1840 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1841 safe_buffer_increment(pStubMsg, size);
1842 if (pFormat[0] == RPC_FC_PSTRUCT)
1843 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1845 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1846 if (*ppMemory != saved_buffer)
1847 memcpy(*ppMemory, saved_buffer, size);
1849 return NULL;
1852 /***********************************************************************
1853 * NdrSimpleStructBufferSize [RPCRT4.@]
1855 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1856 unsigned char *pMemory,
1857 PFORMAT_STRING pFormat)
1859 unsigned size = *(const WORD*)(pFormat+2);
1860 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1862 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1864 safe_buffer_length_increment(pStubMsg, size);
1865 if (pFormat[0] != RPC_FC_STRUCT)
1866 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1869 /***********************************************************************
1870 * NdrSimpleStructMemorySize [RPCRT4.@]
1872 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1873 PFORMAT_STRING pFormat)
1875 unsigned short size = *(const WORD *)(pFormat+2);
1877 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1879 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1880 pStubMsg->MemorySize += size;
1881 safe_buffer_increment(pStubMsg, size);
1883 if (pFormat[0] != RPC_FC_STRUCT)
1884 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1885 return pStubMsg->MemorySize;
1888 /***********************************************************************
1889 * NdrSimpleStructFree [RPCRT4.@]
1891 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1892 unsigned char *pMemory,
1893 PFORMAT_STRING pFormat)
1895 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1896 if (pFormat[0] != RPC_FC_STRUCT)
1897 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1901 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
1902 PFORMAT_STRING pFormat)
1904 switch (*pFormat) {
1905 case RPC_FC_STRUCT:
1906 case RPC_FC_PSTRUCT:
1907 case RPC_FC_CSTRUCT:
1908 case RPC_FC_BOGUS_STRUCT:
1909 case RPC_FC_SMFARRAY:
1910 case RPC_FC_SMVARRAY:
1911 return *(const WORD*)&pFormat[2];
1912 case RPC_FC_USER_MARSHAL:
1913 return *(const WORD*)&pFormat[4];
1914 case RPC_FC_NON_ENCAPSULATED_UNION:
1915 pFormat += 2;
1916 if (pStubMsg->fHasNewCorrDesc)
1917 pFormat += 6;
1918 else
1919 pFormat += 4;
1921 pFormat += *(const SHORT*)pFormat;
1922 return *(const SHORT*)pFormat;
1923 case RPC_FC_IP:
1924 return sizeof(void *);
1925 default:
1926 FIXME("unhandled embedded type %02x\n", *pFormat);
1928 return 0;
1932 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1933 PFORMAT_STRING pFormat)
1935 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1937 if (!m)
1939 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1940 return 0;
1943 return m(pStubMsg, pFormat);
1947 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1948 unsigned char *pMemory,
1949 PFORMAT_STRING pFormat,
1950 PFORMAT_STRING pPointer)
1952 PFORMAT_STRING desc;
1953 NDR_MARSHALL m;
1954 unsigned long size;
1956 while (*pFormat != RPC_FC_END) {
1957 switch (*pFormat) {
1958 case RPC_FC_BYTE:
1959 case RPC_FC_CHAR:
1960 case RPC_FC_SMALL:
1961 case RPC_FC_USMALL:
1962 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1963 safe_copy_to_buffer(pStubMsg, pMemory, 1);
1964 pMemory += 1;
1965 break;
1966 case RPC_FC_WCHAR:
1967 case RPC_FC_SHORT:
1968 case RPC_FC_USHORT:
1969 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1970 safe_copy_to_buffer(pStubMsg, pMemory, 2);
1971 pMemory += 2;
1972 break;
1973 case RPC_FC_LONG:
1974 case RPC_FC_ULONG:
1975 case RPC_FC_ENUM32:
1976 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1977 safe_copy_to_buffer(pStubMsg, pMemory, 4);
1978 pMemory += 4;
1979 break;
1980 case RPC_FC_HYPER:
1981 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1982 safe_copy_to_buffer(pStubMsg, pMemory, 8);
1983 pMemory += 8;
1984 break;
1985 case RPC_FC_POINTER:
1987 unsigned char *saved_buffer;
1988 int pointer_buffer_mark_set = 0;
1989 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1990 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1991 saved_buffer = pStubMsg->Buffer;
1992 if (pStubMsg->PointerBufferMark)
1994 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1995 pStubMsg->PointerBufferMark = NULL;
1996 pointer_buffer_mark_set = 1;
1998 else
1999 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2000 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2001 if (pointer_buffer_mark_set)
2003 STD_OVERFLOW_CHECK(pStubMsg);
2004 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2005 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2007 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2008 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2011 pStubMsg->Buffer = saved_buffer + 4;
2013 pPointer += 4;
2014 pMemory += 4;
2015 break;
2017 case RPC_FC_ALIGNM4:
2018 ALIGN_POINTER(pMemory, 4);
2019 break;
2020 case RPC_FC_ALIGNM8:
2021 ALIGN_POINTER(pMemory, 8);
2022 break;
2023 case RPC_FC_STRUCTPAD1:
2024 case RPC_FC_STRUCTPAD2:
2025 case RPC_FC_STRUCTPAD3:
2026 case RPC_FC_STRUCTPAD4:
2027 case RPC_FC_STRUCTPAD5:
2028 case RPC_FC_STRUCTPAD6:
2029 case RPC_FC_STRUCTPAD7:
2030 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2031 break;
2032 case RPC_FC_EMBEDDED_COMPLEX:
2033 pMemory += pFormat[1];
2034 pFormat += 2;
2035 desc = pFormat + *(const SHORT*)pFormat;
2036 size = EmbeddedComplexSize(pStubMsg, desc);
2037 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2038 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2039 if (m)
2041 /* for some reason interface pointers aren't generated as
2042 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2043 * they still need the derefencing treatment that pointers are
2044 * given */
2045 if (*desc == RPC_FC_IP)
2046 m(pStubMsg, *(unsigned char **)pMemory, desc);
2047 else
2048 m(pStubMsg, pMemory, desc);
2050 else FIXME("no marshaller for embedded type %02x\n", *desc);
2051 pMemory += size;
2052 pFormat += 2;
2053 continue;
2054 case RPC_FC_PAD:
2055 break;
2056 default:
2057 FIXME("unhandled format 0x%02x\n", *pFormat);
2059 pFormat++;
2062 return pMemory;
2065 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2066 unsigned char *pMemory,
2067 PFORMAT_STRING pFormat,
2068 PFORMAT_STRING pPointer)
2070 PFORMAT_STRING desc;
2071 NDR_UNMARSHALL m;
2072 unsigned long size;
2074 while (*pFormat != RPC_FC_END) {
2075 switch (*pFormat) {
2076 case RPC_FC_BYTE:
2077 case RPC_FC_CHAR:
2078 case RPC_FC_SMALL:
2079 case RPC_FC_USMALL:
2080 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2081 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2082 pMemory += 1;
2083 break;
2084 case RPC_FC_WCHAR:
2085 case RPC_FC_SHORT:
2086 case RPC_FC_USHORT:
2087 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2088 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2089 pMemory += 2;
2090 break;
2091 case RPC_FC_LONG:
2092 case RPC_FC_ULONG:
2093 case RPC_FC_ENUM32:
2094 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2095 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2096 pMemory += 4;
2097 break;
2098 case RPC_FC_HYPER:
2099 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2100 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2101 pMemory += 8;
2102 break;
2103 case RPC_FC_POINTER:
2105 unsigned char *saved_buffer;
2106 int pointer_buffer_mark_set = 0;
2107 TRACE("pointer => %p\n", pMemory);
2108 ALIGN_POINTER(pStubMsg->Buffer, 4);
2109 saved_buffer = pStubMsg->Buffer;
2110 if (pStubMsg->PointerBufferMark)
2112 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2113 pStubMsg->PointerBufferMark = NULL;
2114 pointer_buffer_mark_set = 1;
2116 else
2117 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2119 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2120 if (pointer_buffer_mark_set)
2122 STD_OVERFLOW_CHECK(pStubMsg);
2123 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2124 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2126 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2127 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2130 pStubMsg->Buffer = saved_buffer + 4;
2132 pPointer += 4;
2133 pMemory += 4;
2134 break;
2136 case RPC_FC_ALIGNM4:
2137 ALIGN_POINTER_CLEAR(pMemory, 4);
2138 break;
2139 case RPC_FC_ALIGNM8:
2140 ALIGN_POINTER_CLEAR(pMemory, 8);
2141 break;
2142 case RPC_FC_STRUCTPAD1:
2143 case RPC_FC_STRUCTPAD2:
2144 case RPC_FC_STRUCTPAD3:
2145 case RPC_FC_STRUCTPAD4:
2146 case RPC_FC_STRUCTPAD5:
2147 case RPC_FC_STRUCTPAD6:
2148 case RPC_FC_STRUCTPAD7:
2149 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2150 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2151 break;
2152 case RPC_FC_EMBEDDED_COMPLEX:
2153 pMemory += pFormat[1];
2154 pFormat += 2;
2155 desc = pFormat + *(const SHORT*)pFormat;
2156 size = EmbeddedComplexSize(pStubMsg, desc);
2157 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2158 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2159 memset(pMemory, 0, size); /* just in case */
2160 if (m)
2162 /* for some reason interface pointers aren't generated as
2163 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2164 * they still need the derefencing treatment that pointers are
2165 * given */
2166 if (*desc == RPC_FC_IP)
2167 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2168 else
2169 m(pStubMsg, &pMemory, desc, FALSE);
2171 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2172 pMemory += size;
2173 pFormat += 2;
2174 continue;
2175 case RPC_FC_PAD:
2176 break;
2177 default:
2178 FIXME("unhandled format %d\n", *pFormat);
2180 pFormat++;
2183 return pMemory;
2186 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2187 unsigned char *pMemory,
2188 PFORMAT_STRING pFormat,
2189 PFORMAT_STRING pPointer)
2191 PFORMAT_STRING desc;
2192 NDR_BUFFERSIZE m;
2193 unsigned long size;
2195 while (*pFormat != RPC_FC_END) {
2196 switch (*pFormat) {
2197 case RPC_FC_BYTE:
2198 case RPC_FC_CHAR:
2199 case RPC_FC_SMALL:
2200 case RPC_FC_USMALL:
2201 safe_buffer_length_increment(pStubMsg, 1);
2202 pMemory += 1;
2203 break;
2204 case RPC_FC_WCHAR:
2205 case RPC_FC_SHORT:
2206 case RPC_FC_USHORT:
2207 safe_buffer_length_increment(pStubMsg, 2);
2208 pMemory += 2;
2209 break;
2210 case RPC_FC_LONG:
2211 case RPC_FC_ULONG:
2212 case RPC_FC_ENUM32:
2213 safe_buffer_length_increment(pStubMsg, 4);
2214 pMemory += 4;
2215 break;
2216 case RPC_FC_HYPER:
2217 safe_buffer_length_increment(pStubMsg, 8);
2218 pMemory += 8;
2219 break;
2220 case RPC_FC_POINTER:
2221 if (!pStubMsg->IgnoreEmbeddedPointers)
2223 int saved_buffer_length = pStubMsg->BufferLength;
2224 pStubMsg->BufferLength = pStubMsg->PointerLength;
2225 pStubMsg->PointerLength = 0;
2226 if(!pStubMsg->BufferLength)
2227 ERR("BufferLength == 0??\n");
2228 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2229 pStubMsg->PointerLength = pStubMsg->BufferLength;
2230 pStubMsg->BufferLength = saved_buffer_length;
2232 safe_buffer_length_increment(pStubMsg, 4);
2233 pPointer += 4;
2234 pMemory += 4;
2235 break;
2236 case RPC_FC_ALIGNM4:
2237 ALIGN_POINTER(pMemory, 4);
2238 break;
2239 case RPC_FC_ALIGNM8:
2240 ALIGN_POINTER(pMemory, 8);
2241 break;
2242 case RPC_FC_STRUCTPAD1:
2243 case RPC_FC_STRUCTPAD2:
2244 case RPC_FC_STRUCTPAD3:
2245 case RPC_FC_STRUCTPAD4:
2246 case RPC_FC_STRUCTPAD5:
2247 case RPC_FC_STRUCTPAD6:
2248 case RPC_FC_STRUCTPAD7:
2249 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2250 break;
2251 case RPC_FC_EMBEDDED_COMPLEX:
2252 pMemory += pFormat[1];
2253 pFormat += 2;
2254 desc = pFormat + *(const SHORT*)pFormat;
2255 size = EmbeddedComplexSize(pStubMsg, desc);
2256 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2257 if (m)
2259 /* for some reason interface pointers aren't generated as
2260 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2261 * they still need the derefencing treatment that pointers are
2262 * given */
2263 if (*desc == RPC_FC_IP)
2264 m(pStubMsg, *(unsigned char **)pMemory, desc);
2265 else
2266 m(pStubMsg, pMemory, desc);
2268 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2269 pMemory += size;
2270 pFormat += 2;
2271 continue;
2272 case RPC_FC_PAD:
2273 break;
2274 default:
2275 FIXME("unhandled format 0x%02x\n", *pFormat);
2277 pFormat++;
2280 return pMemory;
2283 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2284 unsigned char *pMemory,
2285 PFORMAT_STRING pFormat,
2286 PFORMAT_STRING pPointer)
2288 PFORMAT_STRING desc;
2289 NDR_FREE m;
2290 unsigned long size;
2292 while (*pFormat != RPC_FC_END) {
2293 switch (*pFormat) {
2294 case RPC_FC_BYTE:
2295 case RPC_FC_CHAR:
2296 case RPC_FC_SMALL:
2297 case RPC_FC_USMALL:
2298 pMemory += 1;
2299 break;
2300 case RPC_FC_WCHAR:
2301 case RPC_FC_SHORT:
2302 case RPC_FC_USHORT:
2303 pMemory += 2;
2304 break;
2305 case RPC_FC_LONG:
2306 case RPC_FC_ULONG:
2307 case RPC_FC_ENUM32:
2308 pMemory += 4;
2309 break;
2310 case RPC_FC_HYPER:
2311 pMemory += 8;
2312 break;
2313 case RPC_FC_POINTER:
2314 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2315 pPointer += 4;
2316 pMemory += 4;
2317 break;
2318 case RPC_FC_ALIGNM4:
2319 ALIGN_POINTER(pMemory, 4);
2320 break;
2321 case RPC_FC_ALIGNM8:
2322 ALIGN_POINTER(pMemory, 8);
2323 break;
2324 case RPC_FC_STRUCTPAD1:
2325 case RPC_FC_STRUCTPAD2:
2326 case RPC_FC_STRUCTPAD3:
2327 case RPC_FC_STRUCTPAD4:
2328 case RPC_FC_STRUCTPAD5:
2329 case RPC_FC_STRUCTPAD6:
2330 case RPC_FC_STRUCTPAD7:
2331 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2332 break;
2333 case RPC_FC_EMBEDDED_COMPLEX:
2334 pMemory += pFormat[1];
2335 pFormat += 2;
2336 desc = pFormat + *(const SHORT*)pFormat;
2337 size = EmbeddedComplexSize(pStubMsg, desc);
2338 m = NdrFreer[*desc & NDR_TABLE_MASK];
2339 if (m)
2341 /* for some reason interface pointers aren't generated as
2342 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2343 * they still need the derefencing treatment that pointers are
2344 * given */
2345 if (*desc == RPC_FC_IP)
2346 m(pStubMsg, *(unsigned char **)pMemory, desc);
2347 else
2348 m(pStubMsg, pMemory, desc);
2350 else FIXME("no freer for embedded type %02x\n", *desc);
2351 pMemory += size;
2352 pFormat += 2;
2353 continue;
2354 case RPC_FC_PAD:
2355 break;
2356 default:
2357 FIXME("unhandled format 0x%02x\n", *pFormat);
2359 pFormat++;
2362 return pMemory;
2365 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2366 PFORMAT_STRING pFormat)
2368 PFORMAT_STRING desc;
2369 unsigned long size = 0;
2371 while (*pFormat != RPC_FC_END) {
2372 switch (*pFormat) {
2373 case RPC_FC_BYTE:
2374 case RPC_FC_CHAR:
2375 case RPC_FC_SMALL:
2376 case RPC_FC_USMALL:
2377 size += 1;
2378 safe_buffer_increment(pStubMsg, 1);
2379 break;
2380 case RPC_FC_WCHAR:
2381 case RPC_FC_SHORT:
2382 case RPC_FC_USHORT:
2383 size += 2;
2384 safe_buffer_increment(pStubMsg, 2);
2385 break;
2386 case RPC_FC_LONG:
2387 case RPC_FC_ULONG:
2388 case RPC_FC_ENUM32:
2389 size += 4;
2390 safe_buffer_increment(pStubMsg, 4);
2391 break;
2392 case RPC_FC_HYPER:
2393 size += 8;
2394 safe_buffer_increment(pStubMsg, 8);
2395 break;
2396 case RPC_FC_POINTER:
2397 size += 4;
2398 safe_buffer_increment(pStubMsg, 4);
2399 if (!pStubMsg->IgnoreEmbeddedPointers)
2400 FIXME("embedded pointers\n");
2401 break;
2402 case RPC_FC_ALIGNM4:
2403 ALIGN_LENGTH(size, 4);
2404 ALIGN_POINTER(pStubMsg->Buffer, 4);
2405 break;
2406 case RPC_FC_ALIGNM8:
2407 ALIGN_LENGTH(size, 8);
2408 ALIGN_POINTER(pStubMsg->Buffer, 8);
2409 break;
2410 case RPC_FC_STRUCTPAD1:
2411 case RPC_FC_STRUCTPAD2:
2412 case RPC_FC_STRUCTPAD3:
2413 case RPC_FC_STRUCTPAD4:
2414 case RPC_FC_STRUCTPAD5:
2415 case RPC_FC_STRUCTPAD6:
2416 case RPC_FC_STRUCTPAD7:
2417 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2418 break;
2419 case RPC_FC_EMBEDDED_COMPLEX:
2420 size += pFormat[1];
2421 pFormat += 2;
2422 desc = pFormat + *(const SHORT*)pFormat;
2423 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2424 pFormat += 2;
2425 continue;
2426 case RPC_FC_PAD:
2427 break;
2428 default:
2429 FIXME("unhandled format 0x%02x\n", *pFormat);
2431 pFormat++;
2434 return size;
2437 /***********************************************************************
2438 * NdrComplexStructMarshall [RPCRT4.@]
2440 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2441 unsigned char *pMemory,
2442 PFORMAT_STRING pFormat)
2444 PFORMAT_STRING conf_array = NULL;
2445 PFORMAT_STRING pointer_desc = NULL;
2446 unsigned char *OldMemory = pStubMsg->Memory;
2447 int pointer_buffer_mark_set = 0;
2449 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2451 if (!pStubMsg->PointerBufferMark)
2453 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2454 /* save buffer length */
2455 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2457 /* get the buffer pointer after complex array data, but before
2458 * pointer data */
2459 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2460 pStubMsg->IgnoreEmbeddedPointers = 1;
2461 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2462 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2464 /* save it for use by embedded pointer code later */
2465 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2466 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2467 pointer_buffer_mark_set = 1;
2469 /* restore the original buffer length */
2470 pStubMsg->BufferLength = saved_buffer_length;
2473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2475 pFormat += 4;
2476 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2477 pFormat += 2;
2478 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2479 pFormat += 2;
2481 pStubMsg->Memory = pMemory;
2483 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2485 if (conf_array)
2486 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2488 pStubMsg->Memory = OldMemory;
2490 if (pointer_buffer_mark_set)
2492 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2493 pStubMsg->PointerBufferMark = NULL;
2496 STD_OVERFLOW_CHECK(pStubMsg);
2498 return NULL;
2501 /***********************************************************************
2502 * NdrComplexStructUnmarshall [RPCRT4.@]
2504 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2505 unsigned char **ppMemory,
2506 PFORMAT_STRING pFormat,
2507 unsigned char fMustAlloc)
2509 unsigned size = *(const WORD*)(pFormat+2);
2510 PFORMAT_STRING conf_array = NULL;
2511 PFORMAT_STRING pointer_desc = NULL;
2512 unsigned char *pMemory;
2513 int pointer_buffer_mark_set = 0;
2515 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2517 if (!pStubMsg->PointerBufferMark)
2519 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2520 /* save buffer pointer */
2521 unsigned char *saved_buffer = pStubMsg->Buffer;
2523 /* get the buffer pointer after complex array data, but before
2524 * pointer data */
2525 pStubMsg->IgnoreEmbeddedPointers = 1;
2526 NdrComplexStructMemorySize(pStubMsg, pFormat);
2527 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2529 /* save it for use by embedded pointer code later */
2530 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2531 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2532 pointer_buffer_mark_set = 1;
2534 /* restore the original buffer */
2535 pStubMsg->Buffer = saved_buffer;
2538 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2540 if (fMustAlloc || !*ppMemory)
2542 *ppMemory = NdrAllocate(pStubMsg, size);
2543 memset(*ppMemory, 0, size);
2546 pFormat += 4;
2547 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2548 pFormat += 2;
2549 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2550 pFormat += 2;
2552 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2554 if (conf_array)
2555 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2557 if (pointer_buffer_mark_set)
2559 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2560 pStubMsg->PointerBufferMark = NULL;
2563 return NULL;
2566 /***********************************************************************
2567 * NdrComplexStructBufferSize [RPCRT4.@]
2569 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2570 unsigned char *pMemory,
2571 PFORMAT_STRING pFormat)
2573 PFORMAT_STRING conf_array = NULL;
2574 PFORMAT_STRING pointer_desc = NULL;
2575 unsigned char *OldMemory = pStubMsg->Memory;
2576 int pointer_length_set = 0;
2578 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2580 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2582 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2584 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2585 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2587 /* get the buffer length after complex struct data, but before
2588 * pointer data */
2589 pStubMsg->IgnoreEmbeddedPointers = 1;
2590 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2591 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2593 /* save it for use by embedded pointer code later */
2594 pStubMsg->PointerLength = pStubMsg->BufferLength;
2595 pointer_length_set = 1;
2596 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2598 /* restore the original buffer length */
2599 pStubMsg->BufferLength = saved_buffer_length;
2602 pFormat += 4;
2603 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2604 pFormat += 2;
2605 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2606 pFormat += 2;
2608 pStubMsg->Memory = pMemory;
2610 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2612 if (conf_array)
2613 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2615 pStubMsg->Memory = OldMemory;
2617 if(pointer_length_set)
2619 pStubMsg->BufferLength = pStubMsg->PointerLength;
2620 pStubMsg->PointerLength = 0;
2625 /***********************************************************************
2626 * NdrComplexStructMemorySize [RPCRT4.@]
2628 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2629 PFORMAT_STRING pFormat)
2631 unsigned size = *(const WORD*)(pFormat+2);
2632 PFORMAT_STRING conf_array = NULL;
2633 PFORMAT_STRING pointer_desc = NULL;
2635 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2637 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2639 pFormat += 4;
2640 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2641 pFormat += 2;
2642 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2643 pFormat += 2;
2645 ComplexStructMemorySize(pStubMsg, pFormat);
2647 if (conf_array)
2648 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2650 return size;
2653 /***********************************************************************
2654 * NdrComplexStructFree [RPCRT4.@]
2656 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2657 unsigned char *pMemory,
2658 PFORMAT_STRING pFormat)
2660 PFORMAT_STRING conf_array = NULL;
2661 PFORMAT_STRING pointer_desc = NULL;
2662 unsigned char *OldMemory = pStubMsg->Memory;
2664 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2666 pFormat += 4;
2667 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2668 pFormat += 2;
2669 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2670 pFormat += 2;
2672 pStubMsg->Memory = pMemory;
2674 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2676 if (conf_array)
2677 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2679 pStubMsg->Memory = OldMemory;
2682 /***********************************************************************
2683 * NdrConformantArrayMarshall [RPCRT4.@]
2685 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2686 unsigned char *pMemory,
2687 PFORMAT_STRING pFormat)
2689 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2690 unsigned char alignment = pFormat[1] + 1;
2692 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2693 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2695 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2697 WriteConformance(pStubMsg);
2699 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2701 size = safe_multiply(esize, pStubMsg->MaxCount);
2702 pStubMsg->BufferMark = pStubMsg->Buffer;
2703 safe_copy_to_buffer(pStubMsg, pMemory, size);
2705 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2707 return NULL;
2710 /***********************************************************************
2711 * NdrConformantArrayUnmarshall [RPCRT4.@]
2713 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2714 unsigned char **ppMemory,
2715 PFORMAT_STRING pFormat,
2716 unsigned char fMustAlloc)
2718 DWORD size, esize = *(const WORD*)(pFormat+2);
2719 unsigned char alignment = pFormat[1] + 1;
2720 unsigned char *saved_buffer;
2722 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2723 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2725 pFormat = ReadConformance(pStubMsg, pFormat+4);
2727 size = safe_multiply(esize, pStubMsg->MaxCount);
2728 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2730 if (fMustAlloc)
2731 *ppMemory = NdrAllocate(pStubMsg, size);
2732 else
2734 if (!pStubMsg->IsClient && !*ppMemory)
2735 /* for servers, we just point straight into the RPC buffer */
2736 *ppMemory = pStubMsg->Buffer;
2739 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2740 safe_buffer_increment(pStubMsg, size);
2741 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2743 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2744 if (*ppMemory != saved_buffer)
2745 memcpy(*ppMemory, saved_buffer, size);
2747 return NULL;
2750 /***********************************************************************
2751 * NdrConformantArrayBufferSize [RPCRT4.@]
2753 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2754 unsigned char *pMemory,
2755 PFORMAT_STRING pFormat)
2757 DWORD size, esize = *(const WORD*)(pFormat+2);
2758 unsigned char alignment = pFormat[1] + 1;
2760 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2761 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2763 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2765 SizeConformance(pStubMsg);
2767 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2769 size = safe_multiply(esize, pStubMsg->MaxCount);
2770 /* conformance value plus array */
2771 safe_buffer_length_increment(pStubMsg, size);
2773 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2776 /***********************************************************************
2777 * NdrConformantArrayMemorySize [RPCRT4.@]
2779 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2780 PFORMAT_STRING pFormat)
2782 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2783 unsigned char alignment = pFormat[1] + 1;
2785 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2786 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2788 pFormat = ReadConformance(pStubMsg, pFormat+4);
2789 size = safe_multiply(esize, pStubMsg->MaxCount);
2790 pStubMsg->MemorySize += size;
2792 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2793 pStubMsg->BufferMark = pStubMsg->Buffer;
2794 safe_buffer_increment(pStubMsg, size);
2796 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2798 return pStubMsg->MemorySize;
2801 /***********************************************************************
2802 * NdrConformantArrayFree [RPCRT4.@]
2804 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2805 unsigned char *pMemory,
2806 PFORMAT_STRING pFormat)
2808 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2809 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2811 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2813 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2817 /***********************************************************************
2818 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2820 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2821 unsigned char* pMemory,
2822 PFORMAT_STRING pFormat )
2824 ULONG bufsize;
2825 unsigned char alignment = pFormat[1] + 1;
2826 DWORD esize = *(const WORD*)(pFormat+2);
2828 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2830 if (pFormat[0] != RPC_FC_CVARRAY)
2832 ERR("invalid format type %x\n", pFormat[0]);
2833 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2834 return NULL;
2837 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2838 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2840 WriteConformance(pStubMsg);
2841 WriteVariance(pStubMsg);
2843 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2845 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2847 pStubMsg->BufferMark = pStubMsg->Buffer;
2848 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
2850 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2852 return NULL;
2856 /***********************************************************************
2857 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2859 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2860 unsigned char** ppMemory,
2861 PFORMAT_STRING pFormat,
2862 unsigned char fMustAlloc )
2864 ULONG bufsize, memsize;
2865 unsigned char alignment = pFormat[1] + 1;
2866 DWORD esize = *(const WORD*)(pFormat+2);
2867 unsigned char *saved_buffer;
2868 ULONG offset;
2870 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2872 if (pFormat[0] != RPC_FC_CVARRAY)
2874 ERR("invalid format type %x\n", pFormat[0]);
2875 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2876 return NULL;
2879 pFormat = ReadConformance(pStubMsg, pFormat+4);
2880 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2882 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2884 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2885 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2886 offset = pStubMsg->Offset;
2888 if (!*ppMemory || fMustAlloc)
2889 *ppMemory = NdrAllocate(pStubMsg, memsize);
2890 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2891 safe_buffer_increment(pStubMsg, bufsize);
2893 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2895 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2897 return NULL;
2901 /***********************************************************************
2902 * NdrConformantVaryingArrayFree [RPCRT4.@]
2904 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2905 unsigned char* pMemory,
2906 PFORMAT_STRING pFormat )
2908 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2910 if (pFormat[0] != RPC_FC_CVARRAY)
2912 ERR("invalid format type %x\n", pFormat[0]);
2913 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2914 return;
2917 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2918 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2920 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2924 /***********************************************************************
2925 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2927 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2928 unsigned char* pMemory, PFORMAT_STRING pFormat )
2930 unsigned char alignment = pFormat[1] + 1;
2931 DWORD esize = *(const WORD*)(pFormat+2);
2933 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2935 if (pFormat[0] != RPC_FC_CVARRAY)
2937 ERR("invalid format type %x\n", pFormat[0]);
2938 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2939 return;
2942 /* compute size */
2943 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2944 /* compute length */
2945 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2947 SizeConformance(pStubMsg);
2948 SizeVariance(pStubMsg);
2950 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2952 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2954 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2958 /***********************************************************************
2959 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2961 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2962 PFORMAT_STRING pFormat )
2964 ULONG bufsize, memsize;
2965 unsigned char alignment = pFormat[1] + 1;
2966 DWORD esize = *(const WORD*)(pFormat+2);
2968 TRACE("(%p, %p)\n", pStubMsg, pFormat);
2970 if (pFormat[0] != RPC_FC_CVARRAY)
2972 ERR("invalid format type %x\n", pFormat[0]);
2973 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2974 return pStubMsg->MemorySize;
2977 pFormat = ReadConformance(pStubMsg, pFormat+4);
2978 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2980 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2982 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2983 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2985 safe_buffer_increment(pStubMsg, bufsize);
2986 pStubMsg->MemorySize += memsize;
2988 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2990 return pStubMsg->MemorySize;
2994 /***********************************************************************
2995 * NdrComplexArrayMarshall [RPCRT4.@]
2997 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2998 unsigned char *pMemory,
2999 PFORMAT_STRING pFormat)
3001 ULONG i, count, def;
3002 BOOL variance_present;
3003 unsigned char alignment;
3004 int pointer_buffer_mark_set = 0;
3006 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3008 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3010 ERR("invalid format type %x\n", pFormat[0]);
3011 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3012 return NULL;
3015 alignment = pFormat[1] + 1;
3017 if (!pStubMsg->PointerBufferMark)
3019 /* save buffer fields that may be changed by buffer sizer functions
3020 * and that may be needed later on */
3021 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3022 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3023 unsigned long saved_max_count = pStubMsg->MaxCount;
3024 unsigned long saved_offset = pStubMsg->Offset;
3025 unsigned long saved_actual_count = pStubMsg->ActualCount;
3027 /* get the buffer pointer after complex array data, but before
3028 * pointer data */
3029 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3030 pStubMsg->IgnoreEmbeddedPointers = 1;
3031 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3032 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3034 /* save it for use by embedded pointer code later */
3035 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3036 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3037 pointer_buffer_mark_set = 1;
3039 /* restore fields */
3040 pStubMsg->ActualCount = saved_actual_count;
3041 pStubMsg->Offset = saved_offset;
3042 pStubMsg->MaxCount = saved_max_count;
3043 pStubMsg->BufferLength = saved_buffer_length;
3046 def = *(const WORD*)&pFormat[2];
3047 pFormat += 4;
3049 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3050 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3052 variance_present = IsConformanceOrVariancePresent(pFormat);
3053 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3054 TRACE("variance = %d\n", pStubMsg->ActualCount);
3056 WriteConformance(pStubMsg);
3057 if (variance_present)
3058 WriteVariance(pStubMsg);
3060 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3062 count = pStubMsg->ActualCount;
3063 for (i = 0; i < count; i++)
3064 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3066 STD_OVERFLOW_CHECK(pStubMsg);
3068 if (pointer_buffer_mark_set)
3070 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3071 pStubMsg->PointerBufferMark = NULL;
3074 return NULL;
3077 /***********************************************************************
3078 * NdrComplexArrayUnmarshall [RPCRT4.@]
3080 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3081 unsigned char **ppMemory,
3082 PFORMAT_STRING pFormat,
3083 unsigned char fMustAlloc)
3085 ULONG i, count, size;
3086 unsigned char alignment;
3087 unsigned char *pMemory;
3088 unsigned char *saved_buffer;
3089 int pointer_buffer_mark_set = 0;
3090 int saved_ignore_embedded;
3092 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3094 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3096 ERR("invalid format type %x\n", pFormat[0]);
3097 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3098 return NULL;
3101 alignment = pFormat[1] + 1;
3103 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3104 /* save buffer pointer */
3105 saved_buffer = pStubMsg->Buffer;
3106 /* get the buffer pointer after complex array data, but before
3107 * pointer data */
3108 pStubMsg->IgnoreEmbeddedPointers = 1;
3109 pStubMsg->MemorySize = 0;
3110 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3111 size = pStubMsg->MemorySize;
3112 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3114 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3115 if (!pStubMsg->PointerBufferMark)
3117 /* save it for use by embedded pointer code later */
3118 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3119 pointer_buffer_mark_set = 1;
3121 /* restore the original buffer */
3122 pStubMsg->Buffer = saved_buffer;
3124 pFormat += 4;
3126 pFormat = ReadConformance(pStubMsg, pFormat);
3127 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3129 if (fMustAlloc || !*ppMemory)
3131 *ppMemory = NdrAllocate(pStubMsg, size);
3132 memset(*ppMemory, 0, size);
3135 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3137 pMemory = *ppMemory;
3138 count = pStubMsg->ActualCount;
3139 for (i = 0; i < count; i++)
3140 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3142 if (pointer_buffer_mark_set)
3144 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3145 pStubMsg->PointerBufferMark = NULL;
3148 return NULL;
3151 /***********************************************************************
3152 * NdrComplexArrayBufferSize [RPCRT4.@]
3154 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3155 unsigned char *pMemory,
3156 PFORMAT_STRING pFormat)
3158 ULONG i, count, def;
3159 unsigned char alignment;
3160 BOOL variance_present;
3161 int pointer_length_set = 0;
3163 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3165 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3167 ERR("invalid format type %x\n", pFormat[0]);
3168 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3169 return;
3172 alignment = pFormat[1] + 1;
3174 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3176 /* save buffer fields that may be changed by buffer sizer functions
3177 * and that may be needed later on */
3178 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3179 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3180 unsigned long saved_max_count = pStubMsg->MaxCount;
3181 unsigned long saved_offset = pStubMsg->Offset;
3182 unsigned long saved_actual_count = pStubMsg->ActualCount;
3184 /* get the buffer pointer after complex array data, but before
3185 * pointer data */
3186 pStubMsg->IgnoreEmbeddedPointers = 1;
3187 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3188 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3190 /* save it for use by embedded pointer code later */
3191 pStubMsg->PointerLength = pStubMsg->BufferLength;
3192 pointer_length_set = 1;
3194 /* restore fields */
3195 pStubMsg->ActualCount = saved_actual_count;
3196 pStubMsg->Offset = saved_offset;
3197 pStubMsg->MaxCount = saved_max_count;
3198 pStubMsg->BufferLength = saved_buffer_length;
3200 def = *(const WORD*)&pFormat[2];
3201 pFormat += 4;
3203 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3204 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3205 SizeConformance(pStubMsg);
3207 variance_present = IsConformanceOrVariancePresent(pFormat);
3208 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3209 TRACE("variance = %d\n", pStubMsg->ActualCount);
3211 if (variance_present)
3212 SizeVariance(pStubMsg);
3214 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3216 count = pStubMsg->ActualCount;
3217 for (i = 0; i < count; i++)
3218 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3220 if(pointer_length_set)
3222 pStubMsg->BufferLength = pStubMsg->PointerLength;
3223 pStubMsg->PointerLength = 0;
3227 /***********************************************************************
3228 * NdrComplexArrayMemorySize [RPCRT4.@]
3230 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3231 PFORMAT_STRING pFormat)
3233 ULONG i, count, esize, SavedMemorySize, MemorySize;
3234 unsigned char alignment;
3235 unsigned char *Buffer;
3237 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3239 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3241 ERR("invalid format type %x\n", pFormat[0]);
3242 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3243 return 0;
3246 alignment = pFormat[1] + 1;
3248 pFormat += 4;
3250 pFormat = ReadConformance(pStubMsg, pFormat);
3251 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3253 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3255 SavedMemorySize = pStubMsg->MemorySize;
3257 Buffer = pStubMsg->Buffer;
3258 pStubMsg->MemorySize = 0;
3259 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3260 pStubMsg->Buffer = Buffer;
3262 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3264 count = pStubMsg->ActualCount;
3265 for (i = 0; i < count; i++)
3266 ComplexStructMemorySize(pStubMsg, pFormat);
3268 pStubMsg->MemorySize = SavedMemorySize;
3270 pStubMsg->MemorySize += MemorySize;
3271 return MemorySize;
3274 /***********************************************************************
3275 * NdrComplexArrayFree [RPCRT4.@]
3277 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3278 unsigned char *pMemory,
3279 PFORMAT_STRING pFormat)
3281 ULONG i, count, def;
3283 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3285 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3287 ERR("invalid format type %x\n", pFormat[0]);
3288 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3289 return;
3292 def = *(const WORD*)&pFormat[2];
3293 pFormat += 4;
3295 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3296 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3298 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3299 TRACE("variance = %d\n", pStubMsg->ActualCount);
3301 count = pStubMsg->ActualCount;
3302 for (i = 0; i < count; i++)
3303 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3306 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3307 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3308 USER_MARSHAL_CB *umcb)
3310 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3311 pStubMsg->RpcMsg->DataRepresentation);
3312 umcb->pStubMsg = pStubMsg;
3313 umcb->pReserve = NULL;
3314 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3315 umcb->CBType = cbtype;
3316 umcb->pFormat = pFormat;
3317 umcb->pTypeFormat = NULL /* FIXME */;
3320 #define USER_MARSHAL_PTR_PREFIX \
3321 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3322 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3324 /***********************************************************************
3325 * NdrUserMarshalMarshall [RPCRT4.@]
3327 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3328 unsigned char *pMemory,
3329 PFORMAT_STRING pFormat)
3331 unsigned flags = pFormat[1];
3332 unsigned index = *(const WORD*)&pFormat[2];
3333 unsigned char *saved_buffer = NULL;
3334 USER_MARSHAL_CB umcb;
3336 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3337 TRACE("index=%d\n", index);
3339 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3341 if (flags & USER_MARSHAL_POINTER)
3343 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3344 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3345 pStubMsg->Buffer += 4;
3346 if (pStubMsg->PointerBufferMark)
3348 saved_buffer = pStubMsg->Buffer;
3349 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3350 pStubMsg->PointerBufferMark = NULL;
3352 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3354 else
3355 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3357 pStubMsg->Buffer =
3358 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3359 &umcb.Flags, pStubMsg->Buffer, pMemory);
3361 if (saved_buffer)
3363 STD_OVERFLOW_CHECK(pStubMsg);
3364 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3365 pStubMsg->Buffer = saved_buffer;
3368 STD_OVERFLOW_CHECK(pStubMsg);
3370 return NULL;
3373 /***********************************************************************
3374 * NdrUserMarshalUnmarshall [RPCRT4.@]
3376 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3377 unsigned char **ppMemory,
3378 PFORMAT_STRING pFormat,
3379 unsigned char fMustAlloc)
3381 unsigned flags = pFormat[1];
3382 unsigned index = *(const WORD*)&pFormat[2];
3383 DWORD memsize = *(const WORD*)&pFormat[4];
3384 unsigned char *saved_buffer = NULL;
3385 USER_MARSHAL_CB umcb;
3387 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3388 TRACE("index=%d\n", index);
3390 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3392 if (flags & USER_MARSHAL_POINTER)
3394 ALIGN_POINTER(pStubMsg->Buffer, 4);
3395 /* skip pointer prefix */
3396 pStubMsg->Buffer += 4;
3397 if (pStubMsg->PointerBufferMark)
3399 saved_buffer = pStubMsg->Buffer;
3400 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3401 pStubMsg->PointerBufferMark = NULL;
3403 ALIGN_POINTER(pStubMsg->Buffer, 8);
3405 else
3406 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3408 if (fMustAlloc || !*ppMemory)
3409 *ppMemory = NdrAllocate(pStubMsg, memsize);
3411 pStubMsg->Buffer =
3412 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3413 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3415 if (saved_buffer)
3417 STD_OVERFLOW_CHECK(pStubMsg);
3418 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3419 pStubMsg->Buffer = saved_buffer;
3422 return NULL;
3425 /***********************************************************************
3426 * NdrUserMarshalBufferSize [RPCRT4.@]
3428 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3429 unsigned char *pMemory,
3430 PFORMAT_STRING pFormat)
3432 unsigned flags = pFormat[1];
3433 unsigned index = *(const WORD*)&pFormat[2];
3434 DWORD bufsize = *(const WORD*)&pFormat[6];
3435 USER_MARSHAL_CB umcb;
3436 unsigned long saved_buffer_length = 0;
3438 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3439 TRACE("index=%d\n", index);
3441 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3443 if (flags & USER_MARSHAL_POINTER)
3445 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3446 /* skip pointer prefix */
3447 safe_buffer_length_increment(pStubMsg, 4);
3448 if (pStubMsg->IgnoreEmbeddedPointers)
3449 return;
3450 if (pStubMsg->PointerLength)
3452 saved_buffer_length = pStubMsg->BufferLength;
3453 pStubMsg->BufferLength = pStubMsg->PointerLength;
3454 pStubMsg->PointerLength = 0;
3456 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3458 else
3459 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3461 if (bufsize) {
3462 TRACE("size=%d\n", bufsize);
3463 safe_buffer_length_increment(pStubMsg, bufsize);
3465 else
3466 pStubMsg->BufferLength =
3467 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3468 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3470 if (saved_buffer_length)
3472 pStubMsg->PointerLength = pStubMsg->BufferLength;
3473 pStubMsg->BufferLength = saved_buffer_length;
3478 /***********************************************************************
3479 * NdrUserMarshalMemorySize [RPCRT4.@]
3481 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3482 PFORMAT_STRING pFormat)
3484 unsigned flags = pFormat[1];
3485 unsigned index = *(const WORD*)&pFormat[2];
3486 DWORD memsize = *(const WORD*)&pFormat[4];
3487 DWORD bufsize = *(const WORD*)&pFormat[6];
3489 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3490 TRACE("index=%d\n", index);
3492 pStubMsg->MemorySize += memsize;
3494 if (flags & USER_MARSHAL_POINTER)
3496 ALIGN_POINTER(pStubMsg->Buffer, 4);
3497 /* skip pointer prefix */
3498 pStubMsg->Buffer += 4;
3499 if (pStubMsg->IgnoreEmbeddedPointers)
3500 return pStubMsg->MemorySize;
3501 ALIGN_POINTER(pStubMsg->Buffer, 8);
3503 else
3504 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3506 if (!bufsize)
3507 FIXME("not implemented for varying buffer size\n");
3509 pStubMsg->Buffer += bufsize;
3511 return pStubMsg->MemorySize;
3514 /***********************************************************************
3515 * NdrUserMarshalFree [RPCRT4.@]
3517 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3518 unsigned char *pMemory,
3519 PFORMAT_STRING pFormat)
3521 /* unsigned flags = pFormat[1]; */
3522 unsigned index = *(const WORD*)&pFormat[2];
3523 USER_MARSHAL_CB umcb;
3525 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3526 TRACE("index=%d\n", index);
3528 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3530 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3531 &umcb.Flags, pMemory);
3534 /***********************************************************************
3535 * NdrClearOutParameters [RPCRT4.@]
3537 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3538 PFORMAT_STRING pFormat,
3539 void *ArgAddr)
3541 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3544 /***********************************************************************
3545 * NdrConvert [RPCRT4.@]
3547 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3549 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3550 /* FIXME: since this stub doesn't do any converting, the proper behavior
3551 is to raise an exception */
3554 /***********************************************************************
3555 * NdrConvert2 [RPCRT4.@]
3557 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3559 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3560 pStubMsg, pFormat, NumberParams);
3561 /* FIXME: since this stub doesn't do any converting, the proper behavior
3562 is to raise an exception */
3565 #include "pshpack1.h"
3566 typedef struct _NDR_CSTRUCT_FORMAT
3568 unsigned char type;
3569 unsigned char alignment;
3570 unsigned short memory_size;
3571 short offset_to_array_description;
3572 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3573 #include "poppack.h"
3575 /***********************************************************************
3576 * NdrConformantStructMarshall [RPCRT4.@]
3578 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3579 unsigned char *pMemory,
3580 PFORMAT_STRING pFormat)
3582 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3583 PFORMAT_STRING pCArrayFormat;
3584 ULONG esize, bufsize;
3586 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3588 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3589 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3591 ERR("invalid format type %x\n", pCStructFormat->type);
3592 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3593 return NULL;
3596 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3597 pCStructFormat->offset_to_array_description;
3598 if (*pCArrayFormat != RPC_FC_CARRAY)
3600 ERR("invalid array format type %x\n", pCStructFormat->type);
3601 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3602 return NULL;
3604 esize = *(const WORD*)(pCArrayFormat+2);
3606 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3607 pCArrayFormat + 4, 0);
3609 WriteConformance(pStubMsg);
3611 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3613 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3615 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3616 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3618 ERR("integer overflow of memory_size %u with bufsize %u\n",
3619 pCStructFormat->memory_size, bufsize);
3620 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3622 /* copy constant sized part of struct */
3623 pStubMsg->BufferMark = pStubMsg->Buffer;
3624 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3626 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3627 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3629 return NULL;
3632 /***********************************************************************
3633 * NdrConformantStructUnmarshall [RPCRT4.@]
3635 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3636 unsigned char **ppMemory,
3637 PFORMAT_STRING pFormat,
3638 unsigned char fMustAlloc)
3640 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3641 PFORMAT_STRING pCArrayFormat;
3642 ULONG esize, bufsize;
3643 unsigned char *saved_buffer;
3645 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3647 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3648 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3650 ERR("invalid format type %x\n", pCStructFormat->type);
3651 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3652 return NULL;
3654 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3655 pCStructFormat->offset_to_array_description;
3656 if (*pCArrayFormat != RPC_FC_CARRAY)
3658 ERR("invalid array format type %x\n", pCStructFormat->type);
3659 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3660 return NULL;
3662 esize = *(const WORD*)(pCArrayFormat+2);
3664 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3666 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3668 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3670 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3671 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3673 ERR("integer overflow of memory_size %u with bufsize %u\n",
3674 pCStructFormat->memory_size, bufsize);
3675 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3678 if (fMustAlloc)
3680 SIZE_T size = pCStructFormat->memory_size + bufsize;
3681 *ppMemory = NdrAllocate(pStubMsg, size);
3683 else
3685 if (!pStubMsg->IsClient && !*ppMemory)
3686 /* for servers, we just point straight into the RPC buffer */
3687 *ppMemory = pStubMsg->Buffer;
3690 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3691 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3692 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3693 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3695 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3696 if (*ppMemory != saved_buffer)
3697 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3699 return NULL;
3702 /***********************************************************************
3703 * NdrConformantStructBufferSize [RPCRT4.@]
3705 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3706 unsigned char *pMemory,
3707 PFORMAT_STRING pFormat)
3709 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3710 PFORMAT_STRING pCArrayFormat;
3711 ULONG esize;
3713 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3715 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3716 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3718 ERR("invalid format type %x\n", pCStructFormat->type);
3719 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3720 return;
3722 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3723 pCStructFormat->offset_to_array_description;
3724 if (*pCArrayFormat != RPC_FC_CARRAY)
3726 ERR("invalid array format type %x\n", pCStructFormat->type);
3727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3728 return;
3730 esize = *(const WORD*)(pCArrayFormat+2);
3732 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3733 SizeConformance(pStubMsg);
3735 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3737 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3739 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
3740 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
3742 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3743 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3746 /***********************************************************************
3747 * NdrConformantStructMemorySize [RPCRT4.@]
3749 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3750 PFORMAT_STRING pFormat)
3752 FIXME("stub\n");
3753 return 0;
3756 /***********************************************************************
3757 * NdrConformantStructFree [RPCRT4.@]
3759 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3760 unsigned char *pMemory,
3761 PFORMAT_STRING pFormat)
3763 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3764 PFORMAT_STRING pCArrayFormat;
3765 ULONG esize;
3767 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3769 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3770 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3772 ERR("invalid format type %x\n", pCStructFormat->type);
3773 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3774 return;
3777 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3778 pCStructFormat->offset_to_array_description;
3779 if (*pCArrayFormat != RPC_FC_CARRAY)
3781 ERR("invalid array format type %x\n", pCStructFormat->type);
3782 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3783 return;
3785 esize = *(const WORD*)(pCArrayFormat+2);
3787 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3788 pCArrayFormat + 4, 0);
3790 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3792 /* copy constant sized part of struct */
3793 pStubMsg->BufferMark = pStubMsg->Buffer;
3795 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3796 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3799 /***********************************************************************
3800 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3802 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3803 unsigned char *pMemory,
3804 PFORMAT_STRING pFormat)
3806 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3807 PFORMAT_STRING pCVArrayFormat;
3808 ULONG esize, bufsize;
3810 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3812 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3813 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3815 ERR("invalid format type %x\n", pCVStructFormat->type);
3816 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3817 return NULL;
3820 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3821 pCVStructFormat->offset_to_array_description;
3822 switch (*pCVArrayFormat)
3824 case RPC_FC_CVARRAY:
3825 esize = *(const WORD*)(pCVArrayFormat+2);
3827 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3828 pCVArrayFormat + 4, 0);
3829 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3830 pCVArrayFormat, 0);
3831 break;
3832 case RPC_FC_C_CSTRING:
3833 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3834 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3835 esize = sizeof(char);
3836 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3837 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3838 pCVArrayFormat + 2, 0);
3839 else
3840 pStubMsg->MaxCount = pStubMsg->ActualCount;
3841 break;
3842 case RPC_FC_C_WSTRING:
3843 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3844 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3845 esize = sizeof(WCHAR);
3846 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3847 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3848 pCVArrayFormat + 2, 0);
3849 else
3850 pStubMsg->MaxCount = pStubMsg->ActualCount;
3851 break;
3852 default:
3853 ERR("invalid array format type %x\n", *pCVArrayFormat);
3854 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3855 return NULL;
3858 WriteConformance(pStubMsg);
3860 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3862 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3864 /* write constant sized part */
3865 pStubMsg->BufferMark = pStubMsg->Buffer;
3866 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
3868 WriteVariance(pStubMsg);
3870 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3872 /* write array part */
3873 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
3875 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3877 return NULL;
3880 /***********************************************************************
3881 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3883 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3884 unsigned char **ppMemory,
3885 PFORMAT_STRING pFormat,
3886 unsigned char fMustAlloc)
3888 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3889 PFORMAT_STRING pCVArrayFormat;
3890 ULONG esize, bufsize;
3891 unsigned char cvarray_type;
3893 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3895 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3896 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3898 ERR("invalid format type %x\n", pCVStructFormat->type);
3899 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3900 return NULL;
3903 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3904 pCVStructFormat->offset_to_array_description;
3905 cvarray_type = *pCVArrayFormat;
3906 switch (cvarray_type)
3908 case RPC_FC_CVARRAY:
3909 esize = *(const WORD*)(pCVArrayFormat+2);
3910 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3911 break;
3912 case RPC_FC_C_CSTRING:
3913 esize = sizeof(char);
3914 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3915 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3916 else
3917 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3918 break;
3919 case RPC_FC_C_WSTRING:
3920 esize = sizeof(WCHAR);
3921 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3922 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3923 else
3924 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3925 break;
3926 default:
3927 ERR("invalid array format type %x\n", *pCVArrayFormat);
3928 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3929 return NULL;
3932 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3934 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3936 /* work out how much memory to allocate if we need to do so */
3937 if (!*ppMemory || fMustAlloc)
3939 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3940 *ppMemory = NdrAllocate(pStubMsg, size);
3943 /* copy the constant data */
3944 pStubMsg->BufferMark = pStubMsg->Buffer;
3945 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
3947 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3949 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3951 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3952 (cvarray_type == RPC_FC_C_WSTRING))
3954 ULONG i;
3955 /* strings must always have null terminating bytes */
3956 if (bufsize < esize)
3958 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3959 RpcRaiseException(RPC_S_INVALID_BOUND);
3960 return NULL;
3962 for (i = bufsize - esize; i < bufsize; i++)
3963 if (pStubMsg->Buffer[i] != 0)
3965 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3966 i, pStubMsg->Buffer[i]);
3967 RpcRaiseException(RPC_S_INVALID_BOUND);
3968 return NULL;
3972 /* copy the array data */
3973 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
3975 if (cvarray_type == RPC_FC_C_CSTRING)
3976 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3977 else if (cvarray_type == RPC_FC_C_WSTRING)
3978 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3980 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
3982 return NULL;
3985 /***********************************************************************
3986 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3988 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3989 unsigned char *pMemory,
3990 PFORMAT_STRING pFormat)
3992 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3993 PFORMAT_STRING pCVArrayFormat;
3994 ULONG esize;
3996 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3998 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3999 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4001 ERR("invalid format type %x\n", pCVStructFormat->type);
4002 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4003 return;
4006 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4007 pCVStructFormat->offset_to_array_description;
4008 switch (*pCVArrayFormat)
4010 case RPC_FC_CVARRAY:
4011 esize = *(const WORD*)(pCVArrayFormat+2);
4013 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4014 pCVArrayFormat + 4, 0);
4015 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4016 pCVArrayFormat, 0);
4017 break;
4018 case RPC_FC_C_CSTRING:
4019 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4020 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4021 esize = sizeof(char);
4022 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4023 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4024 pCVArrayFormat + 2, 0);
4025 else
4026 pStubMsg->MaxCount = pStubMsg->ActualCount;
4027 break;
4028 case RPC_FC_C_WSTRING:
4029 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4030 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4031 esize = sizeof(WCHAR);
4032 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4033 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4034 pCVArrayFormat + 2, 0);
4035 else
4036 pStubMsg->MaxCount = pStubMsg->ActualCount;
4037 break;
4038 default:
4039 ERR("invalid array format type %x\n", *pCVArrayFormat);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4041 return;
4044 SizeConformance(pStubMsg);
4046 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4048 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4050 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4051 SizeVariance(pStubMsg);
4052 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4054 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4057 /***********************************************************************
4058 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4060 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4061 PFORMAT_STRING pFormat)
4063 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4064 PFORMAT_STRING pCVArrayFormat;
4065 ULONG esize;
4066 unsigned char cvarray_type;
4068 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4070 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4071 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4073 ERR("invalid format type %x\n", pCVStructFormat->type);
4074 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4075 return 0;
4078 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4079 pCVStructFormat->offset_to_array_description;
4080 cvarray_type = *pCVArrayFormat;
4081 switch (cvarray_type)
4083 case RPC_FC_CVARRAY:
4084 esize = *(const WORD*)(pCVArrayFormat+2);
4085 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4086 break;
4087 case RPC_FC_C_CSTRING:
4088 esize = sizeof(char);
4089 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4090 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4091 else
4092 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4093 break;
4094 case RPC_FC_C_WSTRING:
4095 esize = sizeof(WCHAR);
4096 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4097 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4098 else
4099 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4100 break;
4101 default:
4102 ERR("invalid array format type %x\n", *pCVArrayFormat);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4104 return 0;
4107 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4109 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4111 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4112 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4113 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4115 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4117 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4119 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4122 /***********************************************************************
4123 * NdrConformantVaryingStructFree [RPCRT4.@]
4125 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4126 unsigned char *pMemory,
4127 PFORMAT_STRING pFormat)
4129 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4130 PFORMAT_STRING pCVArrayFormat;
4131 ULONG esize;
4133 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4135 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4136 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4138 ERR("invalid format type %x\n", pCVStructFormat->type);
4139 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4140 return;
4143 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4144 pCVStructFormat->offset_to_array_description;
4145 switch (*pCVArrayFormat)
4147 case RPC_FC_CVARRAY:
4148 esize = *(const WORD*)(pCVArrayFormat+2);
4150 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4151 pCVArrayFormat + 4, 0);
4152 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4153 pCVArrayFormat, 0);
4154 break;
4155 case RPC_FC_C_CSTRING:
4156 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4157 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4158 esize = sizeof(char);
4159 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4160 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4161 pCVArrayFormat + 2, 0);
4162 else
4163 pStubMsg->MaxCount = pStubMsg->ActualCount;
4164 break;
4165 case RPC_FC_C_WSTRING:
4166 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4167 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4168 esize = sizeof(WCHAR);
4169 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4170 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4171 pCVArrayFormat + 2, 0);
4172 else
4173 pStubMsg->MaxCount = pStubMsg->ActualCount;
4174 break;
4175 default:
4176 ERR("invalid array format type %x\n", *pCVArrayFormat);
4177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4178 return;
4181 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4183 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4186 #include "pshpack1.h"
4187 typedef struct
4189 unsigned char type;
4190 unsigned char alignment;
4191 unsigned short total_size;
4192 } NDR_SMFARRAY_FORMAT;
4194 typedef struct
4196 unsigned char type;
4197 unsigned char alignment;
4198 unsigned long total_size;
4199 } NDR_LGFARRAY_FORMAT;
4200 #include "poppack.h"
4202 /***********************************************************************
4203 * NdrFixedArrayMarshall [RPCRT4.@]
4205 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4206 unsigned char *pMemory,
4207 PFORMAT_STRING pFormat)
4209 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4210 unsigned long total_size;
4212 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4214 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4215 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4217 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4218 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4219 return NULL;
4222 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4224 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4226 total_size = pSmFArrayFormat->total_size;
4227 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4229 else
4231 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4232 total_size = pLgFArrayFormat->total_size;
4233 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4236 pStubMsg->BufferMark = pStubMsg->Buffer;
4237 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4239 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4241 return NULL;
4244 /***********************************************************************
4245 * NdrFixedArrayUnmarshall [RPCRT4.@]
4247 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4248 unsigned char **ppMemory,
4249 PFORMAT_STRING pFormat,
4250 unsigned char fMustAlloc)
4252 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4253 unsigned long total_size;
4254 unsigned char *saved_buffer;
4256 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4258 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4259 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4261 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4262 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4263 return NULL;
4266 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4268 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4270 total_size = pSmFArrayFormat->total_size;
4271 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4273 else
4275 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4276 total_size = pLgFArrayFormat->total_size;
4277 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4280 if (fMustAlloc)
4281 *ppMemory = NdrAllocate(pStubMsg, total_size);
4282 else
4284 if (!pStubMsg->IsClient && !*ppMemory)
4285 /* for servers, we just point straight into the RPC buffer */
4286 *ppMemory = pStubMsg->Buffer;
4289 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4290 safe_buffer_increment(pStubMsg, total_size);
4291 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4293 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4294 if (*ppMemory != saved_buffer)
4295 memcpy(*ppMemory, saved_buffer, total_size);
4297 return NULL;
4300 /***********************************************************************
4301 * NdrFixedArrayBufferSize [RPCRT4.@]
4303 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4304 unsigned char *pMemory,
4305 PFORMAT_STRING pFormat)
4307 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4308 unsigned long total_size;
4310 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4312 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4313 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4315 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4316 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4317 return;
4320 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4322 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4324 total_size = pSmFArrayFormat->total_size;
4325 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4327 else
4329 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4330 total_size = pLgFArrayFormat->total_size;
4331 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4333 safe_buffer_length_increment(pStubMsg, total_size);
4335 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4338 /***********************************************************************
4339 * NdrFixedArrayMemorySize [RPCRT4.@]
4341 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4342 PFORMAT_STRING pFormat)
4344 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4345 ULONG total_size;
4347 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4349 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4350 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4352 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4354 return 0;
4357 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4359 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4361 total_size = pSmFArrayFormat->total_size;
4362 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4364 else
4366 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4367 total_size = pLgFArrayFormat->total_size;
4368 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4370 pStubMsg->BufferMark = pStubMsg->Buffer;
4371 safe_buffer_increment(pStubMsg, total_size);
4372 pStubMsg->MemorySize += total_size;
4374 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4376 return total_size;
4379 /***********************************************************************
4380 * NdrFixedArrayFree [RPCRT4.@]
4382 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4383 unsigned char *pMemory,
4384 PFORMAT_STRING pFormat)
4386 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4388 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4390 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4391 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4393 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4394 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4395 return;
4398 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4399 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4400 else
4402 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4403 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4406 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4409 /***********************************************************************
4410 * NdrVaryingArrayMarshall [RPCRT4.@]
4412 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4413 unsigned char *pMemory,
4414 PFORMAT_STRING pFormat)
4416 unsigned char alignment;
4417 DWORD elements, esize;
4418 ULONG bufsize;
4420 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4422 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4423 (pFormat[0] != RPC_FC_LGVARRAY))
4425 ERR("invalid format type %x\n", pFormat[0]);
4426 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4427 return NULL;
4430 alignment = pFormat[1] + 1;
4432 if (pFormat[0] == RPC_FC_SMVARRAY)
4434 pFormat += 2;
4435 pFormat += sizeof(WORD);
4436 elements = *(const WORD*)pFormat;
4437 pFormat += sizeof(WORD);
4439 else
4441 pFormat += 2;
4442 pFormat += sizeof(DWORD);
4443 elements = *(const DWORD*)pFormat;
4444 pFormat += sizeof(DWORD);
4447 esize = *(const WORD*)pFormat;
4448 pFormat += sizeof(WORD);
4450 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4451 if ((pStubMsg->ActualCount > elements) ||
4452 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4454 RpcRaiseException(RPC_S_INVALID_BOUND);
4455 return NULL;
4458 WriteVariance(pStubMsg);
4460 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4462 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4463 pStubMsg->BufferMark = pStubMsg->Buffer;
4464 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4466 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4468 return NULL;
4471 /***********************************************************************
4472 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4474 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4475 unsigned char **ppMemory,
4476 PFORMAT_STRING pFormat,
4477 unsigned char fMustAlloc)
4479 unsigned char alignment;
4480 DWORD size, elements, esize;
4481 ULONG bufsize;
4482 unsigned char *saved_buffer;
4483 ULONG offset;
4485 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4487 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4488 (pFormat[0] != RPC_FC_LGVARRAY))
4490 ERR("invalid format type %x\n", pFormat[0]);
4491 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4492 return NULL;
4495 alignment = pFormat[1] + 1;
4497 if (pFormat[0] == RPC_FC_SMVARRAY)
4499 pFormat += 2;
4500 size = *(const WORD*)pFormat;
4501 pFormat += sizeof(WORD);
4502 elements = *(const WORD*)pFormat;
4503 pFormat += sizeof(WORD);
4505 else
4507 pFormat += 2;
4508 size = *(const DWORD*)pFormat;
4509 pFormat += sizeof(DWORD);
4510 elements = *(const DWORD*)pFormat;
4511 pFormat += sizeof(DWORD);
4514 esize = *(const WORD*)pFormat;
4515 pFormat += sizeof(WORD);
4517 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4519 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4521 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4522 offset = pStubMsg->Offset;
4524 if (!*ppMemory || fMustAlloc)
4525 *ppMemory = NdrAllocate(pStubMsg, size);
4526 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4527 safe_buffer_increment(pStubMsg, bufsize);
4529 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4531 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4533 return NULL;
4536 /***********************************************************************
4537 * NdrVaryingArrayBufferSize [RPCRT4.@]
4539 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4540 unsigned char *pMemory,
4541 PFORMAT_STRING pFormat)
4543 unsigned char alignment;
4544 DWORD elements, esize;
4546 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4548 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4549 (pFormat[0] != RPC_FC_LGVARRAY))
4551 ERR("invalid format type %x\n", pFormat[0]);
4552 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4553 return;
4556 alignment = pFormat[1] + 1;
4558 if (pFormat[0] == RPC_FC_SMVARRAY)
4560 pFormat += 2;
4561 pFormat += sizeof(WORD);
4562 elements = *(const WORD*)pFormat;
4563 pFormat += sizeof(WORD);
4565 else
4567 pFormat += 2;
4568 pFormat += sizeof(DWORD);
4569 elements = *(const DWORD*)pFormat;
4570 pFormat += sizeof(DWORD);
4573 esize = *(const WORD*)pFormat;
4574 pFormat += sizeof(WORD);
4576 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4577 if ((pStubMsg->ActualCount > elements) ||
4578 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4580 RpcRaiseException(RPC_S_INVALID_BOUND);
4581 return;
4584 SizeVariance(pStubMsg);
4586 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4588 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4590 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4593 /***********************************************************************
4594 * NdrVaryingArrayMemorySize [RPCRT4.@]
4596 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4597 PFORMAT_STRING pFormat)
4599 unsigned char alignment;
4600 DWORD size, elements, esize;
4602 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4604 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4605 (pFormat[0] != RPC_FC_LGVARRAY))
4607 ERR("invalid format type %x\n", pFormat[0]);
4608 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4609 return 0;
4612 alignment = pFormat[1] + 1;
4614 if (pFormat[0] == RPC_FC_SMVARRAY)
4616 pFormat += 2;
4617 size = *(const WORD*)pFormat;
4618 pFormat += sizeof(WORD);
4619 elements = *(const WORD*)pFormat;
4620 pFormat += sizeof(WORD);
4622 else
4624 pFormat += 2;
4625 size = *(const DWORD*)pFormat;
4626 pFormat += sizeof(DWORD);
4627 elements = *(const DWORD*)pFormat;
4628 pFormat += sizeof(DWORD);
4631 esize = *(const WORD*)pFormat;
4632 pFormat += sizeof(WORD);
4634 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4636 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4638 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4639 pStubMsg->MemorySize += size;
4641 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4643 return pStubMsg->MemorySize;
4646 /***********************************************************************
4647 * NdrVaryingArrayFree [RPCRT4.@]
4649 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4650 unsigned char *pMemory,
4651 PFORMAT_STRING pFormat)
4653 unsigned char alignment;
4654 DWORD elements;
4656 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4658 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4659 (pFormat[0] != RPC_FC_LGVARRAY))
4661 ERR("invalid format type %x\n", pFormat[0]);
4662 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4663 return;
4666 alignment = pFormat[1] + 1;
4668 if (pFormat[0] == RPC_FC_SMVARRAY)
4670 pFormat += 2;
4671 pFormat += sizeof(WORD);
4672 elements = *(const WORD*)pFormat;
4673 pFormat += sizeof(WORD);
4675 else
4677 pFormat += 2;
4678 pFormat += sizeof(DWORD);
4679 elements = *(const DWORD*)pFormat;
4680 pFormat += sizeof(DWORD);
4683 pFormat += sizeof(WORD);
4685 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4686 if ((pStubMsg->ActualCount > elements) ||
4687 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4689 RpcRaiseException(RPC_S_INVALID_BOUND);
4690 return;
4693 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4696 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4698 switch (fc)
4700 case RPC_FC_BYTE:
4701 case RPC_FC_CHAR:
4702 case RPC_FC_SMALL:
4703 case RPC_FC_USMALL:
4704 return *(const UCHAR *)pMemory;
4705 case RPC_FC_WCHAR:
4706 case RPC_FC_SHORT:
4707 case RPC_FC_USHORT:
4708 case RPC_FC_ENUM16:
4709 return *(const USHORT *)pMemory;
4710 case RPC_FC_LONG:
4711 case RPC_FC_ULONG:
4712 case RPC_FC_ENUM32:
4713 return *(const ULONG *)pMemory;
4714 default:
4715 FIXME("Unhandled base type: 0x%02x\n", fc);
4716 return 0;
4720 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4721 unsigned long discriminant,
4722 PFORMAT_STRING pFormat)
4724 unsigned short num_arms, arm, type;
4726 num_arms = *(const SHORT*)pFormat & 0x0fff;
4727 pFormat += 2;
4728 for(arm = 0; arm < num_arms; arm++)
4730 if(discriminant == *(const ULONG*)pFormat)
4732 pFormat += 4;
4733 break;
4735 pFormat += 6;
4738 type = *(const unsigned short*)pFormat;
4739 TRACE("type %04x\n", type);
4740 if(arm == num_arms) /* default arm extras */
4742 if(type == 0xffff)
4744 ERR("no arm for 0x%lx and no default case\n", discriminant);
4745 RpcRaiseException(RPC_S_INVALID_TAG);
4746 return NULL;
4748 if(type == 0)
4750 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4751 return NULL;
4754 return pFormat;
4757 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
4759 unsigned short type;
4761 pFormat += 2;
4763 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4764 if(!pFormat)
4765 return NULL;
4767 type = *(const unsigned short*)pFormat;
4768 if((type & 0xff00) == 0x8000)
4770 unsigned char basetype = LOBYTE(type);
4771 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4773 else
4775 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4776 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4777 if (m)
4779 unsigned char *saved_buffer = NULL;
4780 int pointer_buffer_mark_set = 0;
4781 switch(*desc)
4783 case RPC_FC_RP:
4784 case RPC_FC_UP:
4785 case RPC_FC_OP:
4786 case RPC_FC_FP:
4787 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4788 saved_buffer = pStubMsg->Buffer;
4789 if (pStubMsg->PointerBufferMark)
4791 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4792 pStubMsg->PointerBufferMark = NULL;
4793 pointer_buffer_mark_set = 1;
4795 else
4796 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
4798 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4799 if (pointer_buffer_mark_set)
4801 STD_OVERFLOW_CHECK(pStubMsg);
4802 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4803 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
4805 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4806 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
4807 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4809 pStubMsg->Buffer = saved_buffer + 4;
4811 break;
4812 default:
4813 m(pStubMsg, pMemory, desc);
4816 else FIXME("no marshaller for embedded type %02x\n", *desc);
4818 return NULL;
4821 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4822 unsigned char **ppMemory,
4823 ULONG discriminant,
4824 PFORMAT_STRING pFormat,
4825 unsigned char fMustAlloc)
4827 unsigned short type;
4829 pFormat += 2;
4831 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4832 if(!pFormat)
4833 return NULL;
4835 type = *(const unsigned short*)pFormat;
4836 if((type & 0xff00) == 0x8000)
4838 unsigned char basetype = LOBYTE(type);
4839 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
4841 else
4843 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4844 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4845 if (m)
4847 unsigned char *saved_buffer = NULL;
4848 int pointer_buffer_mark_set = 0;
4849 switch(*desc)
4851 case RPC_FC_RP:
4852 case RPC_FC_UP:
4853 case RPC_FC_OP:
4854 case RPC_FC_FP:
4855 **(void***)ppMemory = NULL;
4856 ALIGN_POINTER(pStubMsg->Buffer, 4);
4857 saved_buffer = pStubMsg->Buffer;
4858 if (pStubMsg->PointerBufferMark)
4860 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4861 pStubMsg->PointerBufferMark = NULL;
4862 pointer_buffer_mark_set = 1;
4864 else
4865 pStubMsg->Buffer += 4; /* for pointer ID */
4867 if (saved_buffer + 4 > pStubMsg->BufferEnd)
4869 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4870 saved_buffer, pStubMsg->BufferEnd);
4871 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4874 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
4875 if (pointer_buffer_mark_set)
4877 STD_OVERFLOW_CHECK(pStubMsg);
4878 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4879 pStubMsg->Buffer = saved_buffer + 4;
4881 break;
4882 default:
4883 m(pStubMsg, ppMemory, desc, fMustAlloc);
4886 else FIXME("no marshaller for embedded type %02x\n", *desc);
4888 return NULL;
4891 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
4892 unsigned char *pMemory,
4893 ULONG discriminant,
4894 PFORMAT_STRING pFormat)
4896 unsigned short type;
4898 pFormat += 2;
4900 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4901 if(!pFormat)
4902 return;
4904 type = *(const unsigned short*)pFormat;
4905 if((type & 0xff00) == 0x8000)
4907 unsigned char basetype = LOBYTE(type);
4908 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4910 else
4912 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4913 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4914 if (m)
4916 switch(*desc)
4918 case RPC_FC_RP:
4919 case RPC_FC_UP:
4920 case RPC_FC_OP:
4921 case RPC_FC_FP:
4922 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4923 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
4924 if (!pStubMsg->IgnoreEmbeddedPointers)
4926 int saved_buffer_length = pStubMsg->BufferLength;
4927 pStubMsg->BufferLength = pStubMsg->PointerLength;
4928 pStubMsg->PointerLength = 0;
4929 if(!pStubMsg->BufferLength)
4930 ERR("BufferLength == 0??\n");
4931 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4932 pStubMsg->PointerLength = pStubMsg->BufferLength;
4933 pStubMsg->BufferLength = saved_buffer_length;
4935 break;
4936 default:
4937 m(pStubMsg, pMemory, desc);
4940 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4944 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
4945 ULONG discriminant,
4946 PFORMAT_STRING pFormat)
4948 unsigned short type, size;
4950 size = *(const unsigned short*)pFormat;
4951 pStubMsg->Memory += size;
4952 pFormat += 2;
4954 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4955 if(!pFormat)
4956 return 0;
4958 type = *(const unsigned short*)pFormat;
4959 if((type & 0xff00) == 0x8000)
4961 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4963 else
4965 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4966 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4967 unsigned char *saved_buffer;
4968 if (m)
4970 switch(*desc)
4972 case RPC_FC_RP:
4973 case RPC_FC_UP:
4974 case RPC_FC_OP:
4975 case RPC_FC_FP:
4976 ALIGN_POINTER(pStubMsg->Buffer, 4);
4977 saved_buffer = pStubMsg->Buffer;
4978 safe_buffer_increment(pStubMsg, 4);
4979 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4980 pStubMsg->MemorySize += 4;
4981 if (!pStubMsg->IgnoreEmbeddedPointers)
4982 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4983 break;
4984 default:
4985 return m(pStubMsg, desc);
4988 else FIXME("no marshaller for embedded type %02x\n", *desc);
4991 TRACE("size %d\n", size);
4992 return size;
4995 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
4996 unsigned char *pMemory,
4997 ULONG discriminant,
4998 PFORMAT_STRING pFormat)
5000 unsigned short type;
5002 pFormat += 2;
5004 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5005 if(!pFormat)
5006 return;
5008 type = *(const unsigned short*)pFormat;
5009 if((type & 0xff00) != 0x8000)
5011 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5012 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5013 if (m)
5015 switch(*desc)
5017 case RPC_FC_RP:
5018 case RPC_FC_UP:
5019 case RPC_FC_OP:
5020 case RPC_FC_FP:
5021 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5022 break;
5023 default:
5024 m(pStubMsg, pMemory, desc);
5027 else FIXME("no freer for embedded type %02x\n", *desc);
5031 /***********************************************************************
5032 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5034 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5035 unsigned char *pMemory,
5036 PFORMAT_STRING pFormat)
5038 unsigned char switch_type;
5039 unsigned char increment;
5040 ULONG switch_value;
5042 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5043 pFormat++;
5045 switch_type = *pFormat & 0xf;
5046 increment = (*pFormat & 0xf0) >> 4;
5047 pFormat++;
5049 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5051 switch_value = get_discriminant(switch_type, pMemory);
5052 TRACE("got switch value 0x%x\n", switch_value);
5054 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5055 pMemory += increment;
5057 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5060 /***********************************************************************
5061 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5063 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5064 unsigned char **ppMemory,
5065 PFORMAT_STRING pFormat,
5066 unsigned char fMustAlloc)
5068 unsigned char switch_type;
5069 unsigned char increment;
5070 ULONG switch_value;
5071 unsigned short size;
5072 unsigned char *pMemoryArm;
5074 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5075 pFormat++;
5077 switch_type = *pFormat & 0xf;
5078 increment = (*pFormat & 0xf0) >> 4;
5079 pFormat++;
5081 ALIGN_POINTER(pStubMsg->Buffer, increment);
5082 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5083 TRACE("got switch value 0x%x\n", switch_value);
5085 size = *(const unsigned short*)pFormat + increment;
5086 if(!*ppMemory || fMustAlloc)
5087 *ppMemory = NdrAllocate(pStubMsg, size);
5089 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5090 pMemoryArm = *ppMemory + increment;
5092 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5095 /***********************************************************************
5096 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5098 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5099 unsigned char *pMemory,
5100 PFORMAT_STRING pFormat)
5102 unsigned char switch_type;
5103 unsigned char increment;
5104 ULONG switch_value;
5106 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5107 pFormat++;
5109 switch_type = *pFormat & 0xf;
5110 increment = (*pFormat & 0xf0) >> 4;
5111 pFormat++;
5113 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5114 switch_value = get_discriminant(switch_type, pMemory);
5115 TRACE("got switch value 0x%x\n", switch_value);
5117 /* Add discriminant size */
5118 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5119 pMemory += increment;
5121 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5124 /***********************************************************************
5125 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5127 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5128 PFORMAT_STRING pFormat)
5130 unsigned char switch_type;
5131 unsigned char increment;
5132 ULONG switch_value;
5134 switch_type = *pFormat & 0xf;
5135 increment = (*pFormat & 0xf0) >> 4;
5136 pFormat++;
5138 ALIGN_POINTER(pStubMsg->Buffer, increment);
5139 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5140 TRACE("got switch value 0x%x\n", switch_value);
5142 pStubMsg->Memory += increment;
5144 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5147 /***********************************************************************
5148 * NdrEncapsulatedUnionFree [RPCRT4.@]
5150 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5151 unsigned char *pMemory,
5152 PFORMAT_STRING pFormat)
5154 unsigned char switch_type;
5155 unsigned char increment;
5156 ULONG switch_value;
5158 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5159 pFormat++;
5161 switch_type = *pFormat & 0xf;
5162 increment = (*pFormat & 0xf0) >> 4;
5163 pFormat++;
5165 switch_value = get_discriminant(switch_type, pMemory);
5166 TRACE("got switch value 0x%x\n", switch_value);
5168 pMemory += increment;
5170 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5173 /***********************************************************************
5174 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5176 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5177 unsigned char *pMemory,
5178 PFORMAT_STRING pFormat)
5180 unsigned char switch_type;
5182 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5183 pFormat++;
5185 switch_type = *pFormat;
5186 pFormat++;
5188 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5189 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5190 /* Marshall discriminant */
5191 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5193 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5196 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5197 PFORMAT_STRING *ppFormat)
5199 long discriminant = 0;
5201 switch(**ppFormat)
5203 case RPC_FC_BYTE:
5204 case RPC_FC_CHAR:
5205 case RPC_FC_SMALL:
5206 case RPC_FC_USMALL:
5208 UCHAR d;
5209 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5210 discriminant = d;
5211 break;
5213 case RPC_FC_WCHAR:
5214 case RPC_FC_SHORT:
5215 case RPC_FC_USHORT:
5217 USHORT d;
5218 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5219 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5220 discriminant = d;
5221 break;
5223 case RPC_FC_LONG:
5224 case RPC_FC_ULONG:
5226 ULONG d;
5227 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5228 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5229 discriminant = d;
5230 break;
5232 default:
5233 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5235 (*ppFormat)++;
5237 if (pStubMsg->fHasNewCorrDesc)
5238 *ppFormat += 6;
5239 else
5240 *ppFormat += 4;
5241 return discriminant;
5244 /**********************************************************************
5245 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5247 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5248 unsigned char **ppMemory,
5249 PFORMAT_STRING pFormat,
5250 unsigned char fMustAlloc)
5252 long discriminant;
5253 unsigned short size;
5255 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5256 pFormat++;
5258 /* Unmarshall discriminant */
5259 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5260 TRACE("unmarshalled discriminant %lx\n", discriminant);
5262 pFormat += *(const SHORT*)pFormat;
5264 size = *(const unsigned short*)pFormat;
5266 if(!*ppMemory || fMustAlloc)
5267 *ppMemory = NdrAllocate(pStubMsg, size);
5269 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5272 /***********************************************************************
5273 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5275 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5276 unsigned char *pMemory,
5277 PFORMAT_STRING pFormat)
5279 unsigned char switch_type;
5281 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5282 pFormat++;
5284 switch_type = *pFormat;
5285 pFormat++;
5287 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5288 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5289 /* Add discriminant size */
5290 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5292 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5295 /***********************************************************************
5296 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5298 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5299 PFORMAT_STRING pFormat)
5301 ULONG discriminant;
5303 pFormat++;
5304 /* Unmarshall discriminant */
5305 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5306 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5308 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5311 /***********************************************************************
5312 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5314 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5315 unsigned char *pMemory,
5316 PFORMAT_STRING pFormat)
5318 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5319 pFormat++;
5320 pFormat++;
5322 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5323 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5325 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5328 /***********************************************************************
5329 * NdrByteCountPointerMarshall [RPCRT4.@]
5331 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5332 unsigned char *pMemory,
5333 PFORMAT_STRING pFormat)
5335 FIXME("stub\n");
5336 return NULL;
5339 /***********************************************************************
5340 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5342 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5343 unsigned char **ppMemory,
5344 PFORMAT_STRING pFormat,
5345 unsigned char fMustAlloc)
5347 FIXME("stub\n");
5348 return NULL;
5351 /***********************************************************************
5352 * NdrByteCountPointerBufferSize [RPCRT4.@]
5354 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5355 unsigned char *pMemory,
5356 PFORMAT_STRING pFormat)
5358 FIXME("stub\n");
5361 /***********************************************************************
5362 * NdrByteCountPointerMemorySize [RPCRT4.@]
5364 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5365 PFORMAT_STRING pFormat)
5367 FIXME("stub\n");
5368 return 0;
5371 /***********************************************************************
5372 * NdrByteCountPointerFree [RPCRT4.@]
5374 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5375 unsigned char *pMemory,
5376 PFORMAT_STRING pFormat)
5378 FIXME("stub\n");
5381 /***********************************************************************
5382 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5384 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5385 unsigned char *pMemory,
5386 PFORMAT_STRING pFormat)
5388 FIXME("stub\n");
5389 return NULL;
5392 /***********************************************************************
5393 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5395 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5396 unsigned char **ppMemory,
5397 PFORMAT_STRING pFormat,
5398 unsigned char fMustAlloc)
5400 FIXME("stub\n");
5401 return NULL;
5404 /***********************************************************************
5405 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5407 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5408 unsigned char *pMemory,
5409 PFORMAT_STRING pFormat)
5411 FIXME("stub\n");
5414 /***********************************************************************
5415 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5417 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5418 PFORMAT_STRING pFormat)
5420 FIXME("stub\n");
5421 return 0;
5424 /***********************************************************************
5425 * NdrXmitOrRepAsFree [RPCRT4.@]
5427 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5428 unsigned char *pMemory,
5429 PFORMAT_STRING pFormat)
5431 FIXME("stub\n");
5434 #include "pshpack1.h"
5435 typedef struct
5437 unsigned char type;
5438 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5439 ULONG low_value;
5440 ULONG high_value;
5441 } NDR_RANGE;
5442 #include "poppack.h"
5444 /***********************************************************************
5445 * NdrRangeMarshall [internal]
5447 unsigned char *WINAPI NdrRangeMarshall(
5448 PMIDL_STUB_MESSAGE pStubMsg,
5449 unsigned char *pMemory,
5450 PFORMAT_STRING pFormat)
5452 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5453 unsigned char base_type;
5455 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5457 if (pRange->type != RPC_FC_RANGE)
5459 ERR("invalid format type %x\n", pRange->type);
5460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5461 return NULL;
5464 base_type = pRange->flags_type & 0xf;
5466 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5469 /***********************************************************************
5470 * NdrRangeUnmarshall
5472 unsigned char *WINAPI NdrRangeUnmarshall(
5473 PMIDL_STUB_MESSAGE pStubMsg,
5474 unsigned char **ppMemory,
5475 PFORMAT_STRING pFormat,
5476 unsigned char fMustAlloc)
5478 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5479 unsigned char base_type;
5481 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5483 if (pRange->type != RPC_FC_RANGE)
5485 ERR("invalid format type %x\n", pRange->type);
5486 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5487 return NULL;
5489 base_type = pRange->flags_type & 0xf;
5491 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5492 base_type, pRange->low_value, pRange->high_value);
5494 #define RANGE_UNMARSHALL(type, format_spec) \
5495 do \
5497 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5498 if (fMustAlloc || !*ppMemory) \
5499 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5500 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5502 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5503 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5504 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5506 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5507 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5509 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5510 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5511 (type)pRange->high_value); \
5512 RpcRaiseException(RPC_S_INVALID_BOUND); \
5513 return NULL; \
5515 TRACE("*ppMemory: %p\n", *ppMemory); \
5516 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5517 pStubMsg->Buffer += sizeof(type); \
5518 } while (0)
5520 switch(base_type)
5522 case RPC_FC_CHAR:
5523 case RPC_FC_SMALL:
5524 RANGE_UNMARSHALL(UCHAR, "%d");
5525 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5526 break;
5527 case RPC_FC_BYTE:
5528 case RPC_FC_USMALL:
5529 RANGE_UNMARSHALL(CHAR, "%u");
5530 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5531 break;
5532 case RPC_FC_WCHAR: /* FIXME: valid? */
5533 case RPC_FC_USHORT:
5534 RANGE_UNMARSHALL(USHORT, "%u");
5535 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5536 break;
5537 case RPC_FC_SHORT:
5538 RANGE_UNMARSHALL(SHORT, "%d");
5539 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5540 break;
5541 case RPC_FC_LONG:
5542 RANGE_UNMARSHALL(LONG, "%d");
5543 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5544 break;
5545 case RPC_FC_ULONG:
5546 RANGE_UNMARSHALL(ULONG, "%u");
5547 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5548 break;
5549 case RPC_FC_ENUM16:
5550 case RPC_FC_ENUM32:
5551 FIXME("Unhandled enum type\n");
5552 break;
5553 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5554 case RPC_FC_FLOAT:
5555 case RPC_FC_DOUBLE:
5556 case RPC_FC_HYPER:
5557 default:
5558 ERR("invalid range base type: 0x%02x\n", base_type);
5559 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5562 return NULL;
5565 /***********************************************************************
5566 * NdrRangeBufferSize [internal]
5568 void WINAPI NdrRangeBufferSize(
5569 PMIDL_STUB_MESSAGE pStubMsg,
5570 unsigned char *pMemory,
5571 PFORMAT_STRING pFormat)
5573 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5574 unsigned char base_type;
5576 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5578 if (pRange->type != RPC_FC_RANGE)
5580 ERR("invalid format type %x\n", pRange->type);
5581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5583 base_type = pRange->flags_type & 0xf;
5585 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5588 /***********************************************************************
5589 * NdrRangeMemorySize [internal]
5591 ULONG WINAPI NdrRangeMemorySize(
5592 PMIDL_STUB_MESSAGE pStubMsg,
5593 PFORMAT_STRING pFormat)
5595 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5596 unsigned char base_type;
5598 if (pRange->type != RPC_FC_RANGE)
5600 ERR("invalid format type %x\n", pRange->type);
5601 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5602 return 0;
5604 base_type = pRange->flags_type & 0xf;
5606 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5609 /***********************************************************************
5610 * NdrRangeFree [internal]
5612 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5613 unsigned char *pMemory,
5614 PFORMAT_STRING pFormat)
5616 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5618 /* nothing to do */
5621 /***********************************************************************
5622 * NdrBaseTypeMarshall [internal]
5624 static unsigned char *WINAPI NdrBaseTypeMarshall(
5625 PMIDL_STUB_MESSAGE pStubMsg,
5626 unsigned char *pMemory,
5627 PFORMAT_STRING pFormat)
5629 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5631 switch(*pFormat)
5633 case RPC_FC_BYTE:
5634 case RPC_FC_CHAR:
5635 case RPC_FC_SMALL:
5636 case RPC_FC_USMALL:
5637 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5638 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5639 break;
5640 case RPC_FC_WCHAR:
5641 case RPC_FC_SHORT:
5642 case RPC_FC_USHORT:
5643 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5644 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5645 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5646 break;
5647 case RPC_FC_LONG:
5648 case RPC_FC_ULONG:
5649 case RPC_FC_ERROR_STATUS_T:
5650 case RPC_FC_ENUM32:
5651 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5652 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5653 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5654 break;
5655 case RPC_FC_FLOAT:
5656 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5657 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5658 break;
5659 case RPC_FC_DOUBLE:
5660 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5661 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5662 break;
5663 case RPC_FC_HYPER:
5664 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5665 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5666 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5667 break;
5668 case RPC_FC_ENUM16:
5669 /* only 16-bits on the wire, so do a sanity check */
5670 if (*(UINT *)pMemory > SHRT_MAX)
5671 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5672 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5673 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5674 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5675 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5676 pStubMsg->Buffer += sizeof(USHORT);
5677 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5678 break;
5679 case RPC_FC_IGNORE:
5680 break;
5681 default:
5682 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5685 /* FIXME: what is the correct return value? */
5686 return NULL;
5689 /***********************************************************************
5690 * NdrBaseTypeUnmarshall [internal]
5692 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5693 PMIDL_STUB_MESSAGE pStubMsg,
5694 unsigned char **ppMemory,
5695 PFORMAT_STRING pFormat,
5696 unsigned char fMustAlloc)
5698 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5700 #define BASE_TYPE_UNMARSHALL(type) \
5701 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5702 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5704 *ppMemory = pStubMsg->Buffer; \
5705 TRACE("*ppMemory: %p\n", *ppMemory); \
5707 else \
5709 if (fMustAlloc) \
5710 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5711 TRACE("*ppMemory: %p\n", *ppMemory); \
5712 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5714 pStubMsg->Buffer += sizeof(type);
5716 switch(*pFormat)
5718 case RPC_FC_BYTE:
5719 case RPC_FC_CHAR:
5720 case RPC_FC_SMALL:
5721 case RPC_FC_USMALL:
5722 BASE_TYPE_UNMARSHALL(UCHAR);
5723 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5724 break;
5725 case RPC_FC_WCHAR:
5726 case RPC_FC_SHORT:
5727 case RPC_FC_USHORT:
5728 BASE_TYPE_UNMARSHALL(USHORT);
5729 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5730 break;
5731 case RPC_FC_LONG:
5732 case RPC_FC_ULONG:
5733 case RPC_FC_ERROR_STATUS_T:
5734 case RPC_FC_ENUM32:
5735 BASE_TYPE_UNMARSHALL(ULONG);
5736 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5737 break;
5738 case RPC_FC_FLOAT:
5739 BASE_TYPE_UNMARSHALL(float);
5740 TRACE("value: %f\n", **(float **)ppMemory);
5741 break;
5742 case RPC_FC_DOUBLE:
5743 BASE_TYPE_UNMARSHALL(double);
5744 TRACE("value: %f\n", **(double **)ppMemory);
5745 break;
5746 case RPC_FC_HYPER:
5747 BASE_TYPE_UNMARSHALL(ULONGLONG);
5748 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5749 break;
5750 case RPC_FC_ENUM16:
5751 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5752 if (fMustAlloc || !*ppMemory)
5753 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5754 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
5755 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5756 TRACE("*ppMemory: %p\n", *ppMemory);
5757 /* 16-bits on the wire, but int in memory */
5758 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5759 pStubMsg->Buffer += sizeof(USHORT);
5760 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5761 break;
5762 case RPC_FC_IGNORE:
5763 break;
5764 default:
5765 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5767 #undef BASE_TYPE_UNMARSHALL
5769 /* FIXME: what is the correct return value? */
5771 return NULL;
5774 /***********************************************************************
5775 * NdrBaseTypeBufferSize [internal]
5777 static void WINAPI NdrBaseTypeBufferSize(
5778 PMIDL_STUB_MESSAGE pStubMsg,
5779 unsigned char *pMemory,
5780 PFORMAT_STRING pFormat)
5782 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5784 switch(*pFormat)
5786 case RPC_FC_BYTE:
5787 case RPC_FC_CHAR:
5788 case RPC_FC_SMALL:
5789 case RPC_FC_USMALL:
5790 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
5791 break;
5792 case RPC_FC_WCHAR:
5793 case RPC_FC_SHORT:
5794 case RPC_FC_USHORT:
5795 case RPC_FC_ENUM16:
5796 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5797 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
5798 break;
5799 case RPC_FC_LONG:
5800 case RPC_FC_ULONG:
5801 case RPC_FC_ENUM32:
5802 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5803 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
5804 break;
5805 case RPC_FC_FLOAT:
5806 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5807 safe_buffer_length_increment(pStubMsg, sizeof(float));
5808 break;
5809 case RPC_FC_DOUBLE:
5810 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5811 safe_buffer_length_increment(pStubMsg, sizeof(double));
5812 break;
5813 case RPC_FC_HYPER:
5814 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5815 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
5816 break;
5817 case RPC_FC_ERROR_STATUS_T:
5818 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5819 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
5820 break;
5821 case RPC_FC_IGNORE:
5822 break;
5823 default:
5824 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5828 /***********************************************************************
5829 * NdrBaseTypeMemorySize [internal]
5831 static ULONG WINAPI NdrBaseTypeMemorySize(
5832 PMIDL_STUB_MESSAGE pStubMsg,
5833 PFORMAT_STRING pFormat)
5835 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
5837 switch(*pFormat)
5839 case RPC_FC_BYTE:
5840 case RPC_FC_CHAR:
5841 case RPC_FC_SMALL:
5842 case RPC_FC_USMALL:
5843 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
5844 pStubMsg->MemorySize += sizeof(UCHAR);
5845 return sizeof(UCHAR);
5846 case RPC_FC_WCHAR:
5847 case RPC_FC_SHORT:
5848 case RPC_FC_USHORT:
5849 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5850 pStubMsg->MemorySize += sizeof(USHORT);
5851 return sizeof(USHORT);
5852 case RPC_FC_LONG:
5853 case RPC_FC_ULONG:
5854 case RPC_FC_ENUM32:
5855 safe_buffer_increment(pStubMsg, sizeof(ULONG));
5856 pStubMsg->MemorySize += sizeof(ULONG);
5857 return sizeof(ULONG);
5858 case RPC_FC_FLOAT:
5859 safe_buffer_increment(pStubMsg, sizeof(float));
5860 pStubMsg->MemorySize += sizeof(float);
5861 return sizeof(float);
5862 case RPC_FC_DOUBLE:
5863 safe_buffer_increment(pStubMsg, sizeof(double));
5864 pStubMsg->MemorySize += sizeof(double);
5865 return sizeof(double);
5866 case RPC_FC_HYPER:
5867 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
5868 pStubMsg->MemorySize += sizeof(ULONGLONG);
5869 return sizeof(ULONGLONG);
5870 case RPC_FC_ERROR_STATUS_T:
5871 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
5872 pStubMsg->MemorySize += sizeof(error_status_t);
5873 return sizeof(error_status_t);
5874 case RPC_FC_ENUM16:
5875 safe_buffer_increment(pStubMsg, sizeof(USHORT));
5876 pStubMsg->MemorySize += sizeof(UINT);
5877 return sizeof(UINT);
5878 case RPC_FC_IGNORE:
5879 pStubMsg->MemorySize += sizeof(void *);
5880 return sizeof(void *);
5881 default:
5882 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5883 return 0;
5887 /***********************************************************************
5888 * NdrBaseTypeFree [internal]
5890 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5891 unsigned char *pMemory,
5892 PFORMAT_STRING pFormat)
5894 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5896 /* nothing to do */
5899 /***********************************************************************
5900 * NdrContextHandleBufferSize [internal]
5902 static void WINAPI NdrContextHandleBufferSize(
5903 PMIDL_STUB_MESSAGE pStubMsg,
5904 unsigned char *pMemory,
5905 PFORMAT_STRING pFormat)
5907 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5909 if (*pFormat != RPC_FC_BIND_CONTEXT)
5911 ERR("invalid format type %x\n", *pFormat);
5912 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5914 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5915 safe_buffer_length_increment(pStubMsg, cbNDRContext);
5918 /***********************************************************************
5919 * NdrContextHandleMarshall [internal]
5921 static unsigned char *WINAPI NdrContextHandleMarshall(
5922 PMIDL_STUB_MESSAGE pStubMsg,
5923 unsigned char *pMemory,
5924 PFORMAT_STRING pFormat)
5926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5928 if (*pFormat != RPC_FC_BIND_CONTEXT)
5930 ERR("invalid format type %x\n", *pFormat);
5931 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5934 if (pFormat[1] & 0x80)
5935 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5936 else
5937 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5939 return NULL;
5942 /***********************************************************************
5943 * NdrContextHandleUnmarshall [internal]
5945 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5946 PMIDL_STUB_MESSAGE pStubMsg,
5947 unsigned char **ppMemory,
5948 PFORMAT_STRING pFormat,
5949 unsigned char fMustAlloc)
5951 if (*pFormat != RPC_FC_BIND_CONTEXT)
5953 ERR("invalid format type %x\n", *pFormat);
5954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5957 **(NDR_CCONTEXT **)ppMemory = NULL;
5958 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5960 return NULL;
5963 /***********************************************************************
5964 * NdrClientContextMarshall [RPCRT4.@]
5966 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5967 NDR_CCONTEXT ContextHandle,
5968 int fCheck)
5970 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5972 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5974 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5976 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5977 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5978 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5981 /* FIXME: what does fCheck do? */
5982 NDRCContextMarshall(ContextHandle,
5983 pStubMsg->Buffer);
5985 pStubMsg->Buffer += cbNDRContext;
5988 /***********************************************************************
5989 * NdrClientContextUnmarshall [RPCRT4.@]
5991 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5992 NDR_CCONTEXT * pContextHandle,
5993 RPC_BINDING_HANDLE BindHandle)
5995 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5997 ALIGN_POINTER(pStubMsg->Buffer, 4);
5999 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6000 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6002 NDRCContextUnmarshall(pContextHandle,
6003 BindHandle,
6004 pStubMsg->Buffer,
6005 pStubMsg->RpcMsg->DataRepresentation);
6007 pStubMsg->Buffer += cbNDRContext;
6010 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6011 NDR_SCONTEXT ContextHandle,
6012 NDR_RUNDOWN RundownRoutine )
6014 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6016 ALIGN_POINTER(pStubMsg->Buffer, 4);
6018 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6020 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6021 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6025 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6026 pStubMsg->Buffer, RundownRoutine, NULL, 0);
6027 pStubMsg->Buffer += cbNDRContext;
6030 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6032 NDR_SCONTEXT ContextHandle;
6034 TRACE("(%p)\n", pStubMsg);
6036 ALIGN_POINTER(pStubMsg->Buffer, 4);
6038 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6040 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6041 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6042 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6045 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6046 pStubMsg->Buffer,
6047 pStubMsg->RpcMsg->DataRepresentation,
6048 NULL, 0);
6049 pStubMsg->Buffer += cbNDRContext;
6051 return ContextHandle;
6054 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6055 unsigned char* pMemory,
6056 PFORMAT_STRING pFormat)
6058 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6061 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6062 PFORMAT_STRING pFormat)
6064 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6065 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6066 pStubMsg->RpcMsg->DataRepresentation, NULL, 0);
6069 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6070 NDR_SCONTEXT ContextHandle,
6071 NDR_RUNDOWN RundownRoutine,
6072 PFORMAT_STRING pFormat)
6074 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6076 ALIGN_POINTER(pStubMsg->Buffer, 4);
6078 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6080 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6081 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6082 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6085 /* FIXME: do something with pFormat */
6086 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6087 pStubMsg->Buffer, RundownRoutine, NULL, 0);
6088 pStubMsg->Buffer += cbNDRContext;
6091 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6092 PFORMAT_STRING pFormat)
6094 NDR_SCONTEXT ContextHandle;
6096 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6098 ALIGN_POINTER(pStubMsg->Buffer, 4);
6100 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6102 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6103 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6104 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6107 /* FIXME: do something with pFormat */
6108 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6109 pStubMsg->Buffer,
6110 pStubMsg->RpcMsg->DataRepresentation,
6111 NULL, 0);
6112 pStubMsg->Buffer += cbNDRContext;
6114 return ContextHandle;