Implement RpcSmDestroyClientContext and RpcSsDestroyClientContext
[reactos.git] / reactos / dll / win32 / rpcrt4 / ndr_marshall.c
1 /*
2 * NDR data marshalling
3 *
4 * Copyright 2002 Greg Turner
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * TODO:
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
23 */
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <limits.h>
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winerror.h"
34 #include "winreg.h"
35
36 #include "ndr_misc.h"
37 #include "rpcndr.h"
38
39 #include "wine/unicode.h"
40 #include "wine/rpcfc.h"
41
42 #include "wine/debug.h"
43
44 #include "rpc_binding.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(ole);
47
48 #define BUFFER_PARANOIA 20
49
50 #if defined(__i386__)
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
53
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
56 #else
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
64
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 (MAKELONG( \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #endif
70
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
77
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
82
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
94
95 /* _Align must be the desired alignment minus 1,
96 * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101
102 #define STD_OVERFLOW_CHECK(_Msg) do { \
103 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
104 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
105 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
106 } while (0)
107
108 #define NDR_TABLE_SIZE 128
109 #define NDR_TABLE_MASK 127
110
111 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
112 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
113 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
114 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
115 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
116
117 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
118 0,
119 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
120 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
121 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
122 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
123 /* 0x10 */
124 NdrBaseTypeMarshall,
125 /* 0x11 */
126 NdrPointerMarshall, NdrPointerMarshall,
127 NdrPointerMarshall, NdrPointerMarshall,
128 /* 0x15 */
129 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
130 NdrConformantStructMarshall, NdrConformantStructMarshall,
131 NdrConformantVaryingStructMarshall,
132 NdrComplexStructMarshall,
133 /* 0x1b */
134 NdrConformantArrayMarshall,
135 NdrConformantVaryingArrayMarshall,
136 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
137 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
138 NdrComplexArrayMarshall,
139 /* 0x22 */
140 NdrConformantStringMarshall, 0, 0,
141 NdrConformantStringMarshall,
142 NdrNonConformantStringMarshall, 0, 0, 0,
143 /* 0x2a */
144 NdrEncapsulatedUnionMarshall,
145 NdrNonEncapsulatedUnionMarshall,
146 0,
147 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
148 /* 0x2f */
149 NdrInterfacePointerMarshall,
150 /* 0xb0 */
151 0, 0, 0, 0,
152 NdrUserMarshalMarshall
153 };
154 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
155 0,
156 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
157 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
158 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
159 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
160 /* 0x10 */
161 NdrBaseTypeUnmarshall,
162 /* 0x11 */
163 NdrPointerUnmarshall, NdrPointerUnmarshall,
164 NdrPointerUnmarshall, NdrPointerUnmarshall,
165 /* 0x15 */
166 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
167 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
168 NdrConformantVaryingStructUnmarshall,
169 NdrComplexStructUnmarshall,
170 /* 0x1b */
171 NdrConformantArrayUnmarshall,
172 NdrConformantVaryingArrayUnmarshall,
173 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
174 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
175 NdrComplexArrayUnmarshall,
176 /* 0x22 */
177 NdrConformantStringUnmarshall, 0, 0,
178 NdrConformantStringUnmarshall,
179 NdrNonConformantStringUnmarshall, 0, 0, 0,
180 /* 0x2a */
181 NdrEncapsulatedUnionUnmarshall,
182 NdrNonEncapsulatedUnionUnmarshall,
183 0,
184 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
185 /* 0x2f */
186 NdrInterfacePointerUnmarshall,
187 /* 0xb0 */
188 0, 0, 0, 0,
189 NdrUserMarshalUnmarshall
190 };
191 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
192 0,
193 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
194 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
195 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
196 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
197 /* 0x10 */
198 NdrBaseTypeBufferSize,
199 /* 0x11 */
200 NdrPointerBufferSize, NdrPointerBufferSize,
201 NdrPointerBufferSize, NdrPointerBufferSize,
202 /* 0x15 */
203 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
204 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
205 NdrConformantVaryingStructBufferSize,
206 NdrComplexStructBufferSize,
207 /* 0x1b */
208 NdrConformantArrayBufferSize,
209 NdrConformantVaryingArrayBufferSize,
210 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
211 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
212 NdrComplexArrayBufferSize,
213 /* 0x22 */
214 NdrConformantStringBufferSize, 0, 0,
215 NdrConformantStringBufferSize,
216 NdrNonConformantStringBufferSize, 0, 0, 0,
217 /* 0x2a */
218 NdrEncapsulatedUnionBufferSize,
219 NdrNonEncapsulatedUnionBufferSize,
220 0,
221 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
222 /* 0x2f */
223 NdrInterfacePointerBufferSize,
224 /* 0xb0 */
225 0, 0, 0, 0,
226 NdrUserMarshalBufferSize
227 };
228 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
229 0,
230 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
231 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
232 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
233 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
234 /* 0x10 */
235 NdrBaseTypeMemorySize,
236 /* 0x11 */
237 NdrPointerMemorySize, NdrPointerMemorySize,
238 NdrPointerMemorySize, NdrPointerMemorySize,
239 /* 0x15 */
240 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
241 0, 0, 0,
242 NdrComplexStructMemorySize,
243 /* 0x1b */
244 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
245 NdrComplexArrayMemorySize,
246 /* 0x22 */
247 NdrConformantStringMemorySize, 0, 0,
248 NdrConformantStringMemorySize,
249 NdrNonConformantStringMemorySize, 0, 0, 0,
250 /* 0x2a */
251 0, 0, 0, 0, 0,
252 /* 0x2f */
253 NdrInterfacePointerMemorySize,
254 /* 0xb0 */
255 0, 0, 0, 0,
256 NdrUserMarshalMemorySize
257 };
258 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
259 0,
260 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
261 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
262 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
263 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
264 /* 0x10 */
265 NdrBaseTypeFree,
266 /* 0x11 */
267 NdrPointerFree, NdrPointerFree,
268 NdrPointerFree, NdrPointerFree,
269 /* 0x15 */
270 NdrSimpleStructFree, NdrSimpleStructFree,
271 NdrConformantStructFree, NdrConformantStructFree,
272 NdrConformantVaryingStructFree,
273 NdrComplexStructFree,
274 /* 0x1b */
275 NdrConformantArrayFree,
276 NdrConformantVaryingArrayFree,
277 NdrFixedArrayFree, NdrFixedArrayFree,
278 NdrVaryingArrayFree, NdrVaryingArrayFree,
279 NdrComplexArrayFree,
280 /* 0x22 */
281 0, 0, 0,
282 0, 0, 0, 0, 0,
283 /* 0x2a */
284 NdrEncapsulatedUnionFree,
285 NdrNonEncapsulatedUnionFree,
286 0,
287 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
288 /* 0x2f */
289 NdrInterfacePointerFree,
290 /* 0xb0 */
291 0, 0, 0, 0,
292 NdrUserMarshalFree
293 };
294
295 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
296 {
297 /* hmm, this is probably supposed to do more? */
298 return pStubMsg->pfnAllocate(len);
299 }
300
301 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
302 {
303 pStubMsg->pfnFree(Pointer);
304 }
305
306 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
307 {
308 return (*(const ULONG *)pFormat != -1);
309 }
310
311 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
312 {
313 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
314 pStubMsg->Buffer += 4;
315 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
316 if (pStubMsg->fHasNewCorrDesc)
317 return pFormat+6;
318 else
319 return pFormat+4;
320 }
321
322 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
323 {
324 if (!IsConformanceOrVariancePresent(pFormat))
325 {
326 pStubMsg->Offset = 0;
327 pStubMsg->ActualCount = pStubMsg->MaxCount;
328 goto done;
329 }
330
331 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
332 pStubMsg->Buffer += 4;
333 TRACE("offset is %ld\n", pStubMsg->Offset);
334 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
335 pStubMsg->Buffer += 4;
336 TRACE("variance is %ld\n", pStubMsg->ActualCount);
337
338 done:
339 if (pStubMsg->fHasNewCorrDesc)
340 return pFormat+6;
341 else
342 return pFormat+4;
343 }
344
345 PFORMAT_STRING ComputeConformanceOrVariance(
346 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
347 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
348 {
349 BYTE dtype = pFormat[0] & 0xf;
350 short ofs = *(short *)&pFormat[2];
351 LPVOID ptr = NULL;
352 DWORD data = 0;
353
354 if (!IsConformanceOrVariancePresent(pFormat)) {
355 /* null descriptor */
356 *pCount = def;
357 goto finish_conf;
358 }
359
360 switch (pFormat[0] & 0xf0) {
361 case RPC_FC_NORMAL_CONFORMANCE:
362 TRACE("normal conformance, ofs=%d\n", ofs);
363 ptr = pMemory + ofs;
364 break;
365 case RPC_FC_POINTER_CONFORMANCE:
366 TRACE("pointer conformance, ofs=%d\n", ofs);
367 ptr = pStubMsg->Memory + ofs;
368 break;
369 case RPC_FC_TOP_LEVEL_CONFORMANCE:
370 TRACE("toplevel conformance, ofs=%d\n", ofs);
371 if (pStubMsg->StackTop) {
372 ptr = pStubMsg->StackTop + ofs;
373 }
374 else {
375 /* -Os mode, *pCount is already set */
376 goto finish_conf;
377 }
378 break;
379 case RPC_FC_CONSTANT_CONFORMANCE:
380 data = ofs | ((DWORD)pFormat[1] << 16);
381 TRACE("constant conformance, val=%ld\n", data);
382 *pCount = data;
383 goto finish_conf;
384 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
385 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
386 if (pStubMsg->StackTop) {
387 ptr = pStubMsg->StackTop + ofs;
388 }
389 else {
390 /* ? */
391 goto done_conf_grab;
392 }
393 break;
394 default:
395 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
396 }
397
398 switch (pFormat[1]) {
399 case RPC_FC_DEREFERENCE:
400 ptr = *(LPVOID*)ptr;
401 break;
402 case RPC_FC_CALLBACK:
403 {
404 unsigned char *old_stack_top = pStubMsg->StackTop;
405 pStubMsg->StackTop = ptr;
406
407 /* ofs is index into StubDesc->apfnExprEval */
408 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
409 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
410
411 pStubMsg->StackTop = old_stack_top;
412 goto finish_conf;
413 }
414 default:
415 break;
416 }
417
418 switch (dtype) {
419 case RPC_FC_LONG:
420 case RPC_FC_ULONG:
421 data = *(DWORD*)ptr;
422 break;
423 case RPC_FC_SHORT:
424 data = *(SHORT*)ptr;
425 break;
426 case RPC_FC_USHORT:
427 data = *(USHORT*)ptr;
428 break;
429 case RPC_FC_SMALL:
430 data = *(CHAR*)ptr;
431 break;
432 case RPC_FC_USMALL:
433 data = *(UCHAR*)ptr;
434 break;
435 default:
436 FIXME("unknown conformance data type %x\n", dtype);
437 goto done_conf_grab;
438 }
439 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
440
441 done_conf_grab:
442 switch (pFormat[1]) {
443 case 0: /* no op */
444 *pCount = data;
445 break;
446 case RPC_FC_DEREFERENCE:
447 /* already handled */
448 break;
449 default:
450 FIXME("unknown conformance op %d\n", pFormat[1]);
451 goto finish_conf;
452 }
453
454 finish_conf:
455 TRACE("resulting conformance is %ld\n", *pCount);
456 if (pStubMsg->fHasNewCorrDesc)
457 return pFormat+6;
458 else
459 return pFormat+4;
460 }
461
462
463 /*
464 * NdrConformantString:
465 *
466 * What MS calls a ConformantString is, in DCE terminology,
467 * a Varying-Conformant String.
468 * [
469 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
470 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
471 * into unmarshalled string)
472 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
473 * [
474 * data: CHARTYPE[maxlen]
475 * ]
476 * ], where CHARTYPE is the appropriate character type (specified externally)
477 *
478 */
479
480 /***********************************************************************
481 * NdrConformantStringMarshall [RPCRT4.@]
482 */
483 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
484 unsigned char *pszMessage, PFORMAT_STRING pFormat)
485 {
486 unsigned long len, esize;
487 unsigned char *c;
488
489 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
490
491 assert(pFormat);
492 if (pszMessage == NULL) {
493 TRACE("string=%s\n", debugstr_a(pszMessage));
494 len = 0;
495 esize = 0;
496 }
497 else if (*pFormat == RPC_FC_C_CSTRING) {
498 TRACE("string=%s\n", debugstr_a(pszMessage));
499 len = strlen(pszMessage)+1;
500 esize = 1;
501 }
502 else if (*pFormat == RPC_FC_C_WSTRING) {
503 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
504 len = strlenW((LPWSTR)pszMessage)+1;
505 esize = 2;
506 }
507 else {
508 ERR("Unhandled string type: %#x\n", *pFormat);
509 /* FIXME: raise an exception. */
510 return NULL;
511 }
512
513 if (pFormat[1] != RPC_FC_PAD) {
514 FIXME("sized string format=%d\n", pFormat[1]);
515 }
516
517 assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
518
519 c = pStubMsg->Buffer;
520 memset(c, 0, 12);
521 NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
522 c += 8; /* offset: 0 */
523 NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
524 c += 4;
525 if (len != 0) {
526 memcpy(c, pszMessage, len*esize); /* the string itself */
527 c += len*esize;
528 }
529 pStubMsg->Buffer = c;
530
531 STD_OVERFLOW_CHECK(pStubMsg);
532
533 /* success */
534 return NULL; /* is this always right? */
535 }
536
537 /***********************************************************************
538 * NdrConformantStringBufferSize [RPCRT4.@]
539 */
540 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
541 unsigned char* pMemory, PFORMAT_STRING pFormat)
542 {
543 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
544
545 assert(pFormat);
546 if (pMemory == NULL) {
547 /* we need 12 octets for the [maxlen, offset, len] DWORDS */
548 TRACE("string=NULL\n");
549 pStubMsg->BufferLength += 12 + BUFFER_PARANOIA;
550 }
551 else if (*pFormat == RPC_FC_C_CSTRING) {
552 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
553 TRACE("string=%s\n", debugstr_a((char*)pMemory));
554 pStubMsg->BufferLength += strlen((char*)pMemory) + 13 + BUFFER_PARANOIA;
555 }
556 else if (*pFormat == RPC_FC_C_WSTRING) {
557 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
558 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
559 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
560 }
561 else {
562 ERR("Unhandled string type: %#x\n", *pFormat);
563 /* FIXME: raise an exception */
564 }
565
566 if (pFormat[1] != RPC_FC_PAD) {
567 FIXME("sized string format=%d\n", pFormat[1]);
568 }
569 }
570
571 /************************************************************************
572 * NdrConformantStringMemorySize [RPCRT4.@]
573 */
574 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
575 PFORMAT_STRING pFormat )
576 {
577 unsigned long rslt = 0;
578
579 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
580
581 assert(pStubMsg && pFormat);
582
583 if (*pFormat == RPC_FC_C_CSTRING) {
584 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
585 }
586 else if (*pFormat == RPC_FC_C_WSTRING) {
587 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
588 }
589 else {
590 ERR("Unhandled string type: %#x\n", *pFormat);
591 /* FIXME: raise an exception */
592 }
593
594 if (pFormat[1] != RPC_FC_PAD) {
595 FIXME("sized string format=%d\n", pFormat[1]);
596 }
597
598 TRACE(" --> %lu\n", rslt);
599 return rslt;
600 }
601
602 /************************************************************************
603 * NdrConformantStringUnmarshall [RPCRT4.@]
604 */
605 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
606 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
607 {
608 unsigned long len, esize, ofs;
609
610 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
611 pStubMsg, *ppMemory, pFormat, fMustAlloc);
612
613 assert(pFormat && ppMemory && pStubMsg);
614
615 pStubMsg->Buffer += 4;
616 ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
617 pStubMsg->Buffer += 4;
618 len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
619 pStubMsg->Buffer += 4;
620
621 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
622 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
623 else {
624 ERR("Unhandled string type: %#x\n", *pFormat);
625 /* FIXME: raise an exception */
626 esize = 0;
627 }
628
629 if (pFormat[1] != RPC_FC_PAD) {
630 FIXME("sized string format=%d\n", pFormat[1]);
631 }
632
633 if (fMustAlloc || !*ppMemory)
634 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
635
636 memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
637
638 pStubMsg->Buffer += len*esize;
639
640 if (*pFormat == RPC_FC_C_CSTRING) {
641 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
642 }
643 else if (*pFormat == RPC_FC_C_WSTRING) {
644 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
645 }
646
647 return NULL; /* FIXME: is this always right? */
648 }
649
650 /***********************************************************************
651 * NdrNonConformantStringMarshall [RPCRT4.@]
652 */
653 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
654 unsigned char *pMemory,
655 PFORMAT_STRING pFormat)
656 {
657 FIXME("stub\n");
658 return NULL;
659 }
660
661 /***********************************************************************
662 * NdrNonConformantStringUnmarshall [RPCRT4.@]
663 */
664 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
665 unsigned char **ppMemory,
666 PFORMAT_STRING pFormat,
667 unsigned char fMustAlloc)
668 {
669 FIXME("stub\n");
670 return NULL;
671 }
672
673 /***********************************************************************
674 * NdrNonConformantStringBufferSize [RPCRT4.@]
675 */
676 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
677 unsigned char *pMemory,
678 PFORMAT_STRING pFormat)
679 {
680 FIXME("stub\n");
681 }
682
683 /***********************************************************************
684 * NdrNonConformantStringMemorySize [RPCRT4.@]
685 */
686 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
687 PFORMAT_STRING pFormat)
688 {
689 FIXME("stub\n");
690 return 0;
691 }
692
693 static inline void dump_pointer_attr(unsigned char attr)
694 {
695 if (attr & RPC_FC_P_ALLOCALLNODES)
696 TRACE(" RPC_FC_P_ALLOCALLNODES");
697 if (attr & RPC_FC_P_DONTFREE)
698 TRACE(" RPC_FC_P_DONTFREE");
699 if (attr & RPC_FC_P_ONSTACK)
700 TRACE(" RPC_FC_P_ONSTACK");
701 if (attr & RPC_FC_P_SIMPLEPOINTER)
702 TRACE(" RPC_FC_P_SIMPLEPOINTER");
703 if (attr & RPC_FC_P_DEREF)
704 TRACE(" RPC_FC_P_DEREF");
705 TRACE("\n");
706 }
707
708 /***********************************************************************
709 * PointerMarshall
710 */
711 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
712 unsigned char *Buffer,
713 unsigned char *Pointer,
714 PFORMAT_STRING pFormat)
715 {
716 unsigned type = pFormat[0], attr = pFormat[1];
717 PFORMAT_STRING desc;
718 NDR_MARSHALL m;
719
720 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
721 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
722 pFormat += 2;
723 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
724 else desc = pFormat + *(const SHORT*)pFormat;
725 if (attr & RPC_FC_P_DEREF) {
726 Pointer = *(unsigned char**)Pointer;
727 TRACE("deref => %p\n", Pointer);
728 }
729
730 switch (type) {
731 case RPC_FC_RP: /* ref pointer (always non-null) */
732 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
733 if (!Pointer)
734 RpcRaiseException(RPC_X_NULL_REF_POINTER);
735 #endif
736 break;
737 case RPC_FC_UP: /* unique pointer */
738 case RPC_FC_OP: /* object pointer - same as unique here */
739 TRACE("writing %p to buffer\n", Pointer);
740 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, (unsigned long)Pointer);
741 pStubMsg->Buffer += 4;
742 break;
743 case RPC_FC_FP:
744 default:
745 FIXME("unhandled ptr type=%02x\n", type);
746 RpcRaiseException(RPC_X_BAD_STUB_DATA);
747 }
748
749 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
750
751 if (Pointer) {
752 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
753 if (m) m(pStubMsg, Pointer, desc);
754 else FIXME("no marshaller for data type=%02x\n", *desc);
755 }
756
757 STD_OVERFLOW_CHECK(pStubMsg);
758 }
759
760 /***********************************************************************
761 * PointerUnmarshall
762 */
763 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
764 unsigned char *Buffer,
765 unsigned char **pPointer,
766 PFORMAT_STRING pFormat,
767 unsigned char fMustAlloc)
768 {
769 unsigned type = pFormat[0], attr = pFormat[1];
770 PFORMAT_STRING desc;
771 NDR_UNMARSHALL m;
772 DWORD pointer_id = 0;
773
774 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
775 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
776 pFormat += 2;
777 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
778 else desc = pFormat + *(const SHORT*)pFormat;
779 if (attr & RPC_FC_P_DEREF) {
780 pPointer = *(unsigned char***)pPointer;
781 TRACE("deref => %p\n", pPointer);
782 }
783
784 switch (type) {
785 case RPC_FC_RP: /* ref pointer (always non-null) */
786 pointer_id = ~0UL;
787 break;
788 case RPC_FC_UP: /* unique pointer */
789 pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
790 pStubMsg->Buffer += 4;
791 break;
792 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
793 pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
794 pStubMsg->Buffer += 4;
795 if (*pPointer)
796 FIXME("free object pointer %p\n", *pPointer);
797 break;
798 case RPC_FC_FP:
799 default:
800 FIXME("unhandled ptr type=%02x\n", type);
801 RpcRaiseException(RPC_X_BAD_STUB_DATA);
802 }
803
804 if (pointer_id) {
805 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
806 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
807 else FIXME("no unmarshaller for data type=%02x\n", *desc);
808 }
809
810 TRACE("pointer=%p\n", *pPointer);
811 }
812
813 /***********************************************************************
814 * PointerBufferSize
815 */
816 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
817 unsigned char *Pointer,
818 PFORMAT_STRING pFormat)
819 {
820 unsigned type = pFormat[0], attr = pFormat[1];
821 PFORMAT_STRING desc;
822 NDR_BUFFERSIZE m;
823
824 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
825 TRACE("type=%d, attr=%d\n", type, attr);
826 pFormat += 2;
827 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
828 else desc = pFormat + *(const SHORT*)pFormat;
829 if (attr & RPC_FC_P_DEREF) {
830 Pointer = *(unsigned char**)Pointer;
831 TRACE("deref => %p\n", Pointer);
832 }
833
834 switch (type) {
835 case RPC_FC_RP: /* ref pointer (always non-null) */
836 break;
837 case RPC_FC_OP:
838 case RPC_FC_UP:
839 pStubMsg->BufferLength += 4;
840 /* NULL pointer has no further representation */
841 if (!Pointer)
842 return;
843 break;
844 case RPC_FC_FP:
845 default:
846 FIXME("unhandled ptr type=%02x\n", type);
847 RpcRaiseException(RPC_X_BAD_STUB_DATA);
848 }
849
850 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
851 if (m) m(pStubMsg, Pointer, desc);
852 else FIXME("no buffersizer for data type=%02x\n", *desc);
853 }
854
855 /***********************************************************************
856 * PointerMemorySize [RPCRT4.@]
857 */
858 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
859 unsigned char *Buffer,
860 PFORMAT_STRING pFormat)
861 {
862 unsigned type = pFormat[0], attr = pFormat[1];
863 PFORMAT_STRING desc;
864 NDR_MEMORYSIZE m;
865
866 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
867 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
868 pFormat += 2;
869 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
870 else desc = pFormat + *(const SHORT*)pFormat;
871 if (attr & RPC_FC_P_DEREF) {
872 TRACE("deref\n");
873 }
874
875 switch (type) {
876 case RPC_FC_RP: /* ref pointer (always non-null) */
877 break;
878 default:
879 FIXME("unhandled ptr type=%02x\n", type);
880 RpcRaiseException(RPC_X_BAD_STUB_DATA);
881 }
882
883 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
884 if (m) m(pStubMsg, desc);
885 else FIXME("no memorysizer for data type=%02x\n", *desc);
886
887 return 0;
888 }
889
890 /***********************************************************************
891 * PointerFree [RPCRT4.@]
892 */
893 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
894 unsigned char *Pointer,
895 PFORMAT_STRING pFormat)
896 {
897 unsigned type = pFormat[0], attr = pFormat[1];
898 PFORMAT_STRING desc;
899 NDR_FREE m;
900
901 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
902 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
903 if (attr & RPC_FC_P_DONTFREE) return;
904 pFormat += 2;
905 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
906 else desc = pFormat + *(const SHORT*)pFormat;
907 if (attr & RPC_FC_P_DEREF) {
908 Pointer = *(unsigned char**)Pointer;
909 TRACE("deref => %p\n", Pointer);
910 }
911
912 if (!Pointer) return;
913
914 m = NdrFreer[*desc & NDR_TABLE_MASK];
915 if (m) m(pStubMsg, Pointer, desc);
916
917 /* hmm... is this sensible?
918 * perhaps we should check if the memory comes from NdrAllocate,
919 * and deallocate only if so - checking if the pointer is between
920 * BufferStart and BufferEnd is probably no good since the buffer
921 * may be reallocated when the server wants to marshal the reply */
922 switch (*desc) {
923 case RPC_FC_BOGUS_STRUCT:
924 case RPC_FC_BOGUS_ARRAY:
925 case RPC_FC_USER_MARSHAL:
926 break;
927 default:
928 FIXME("unhandled data type=%02x\n", *desc);
929 case RPC_FC_CARRAY:
930 case RPC_FC_C_CSTRING:
931 case RPC_FC_C_WSTRING:
932 if (pStubMsg->ReuseBuffer) goto notfree;
933 break;
934 case RPC_FC_IP:
935 goto notfree;
936 }
937
938 if (attr & RPC_FC_P_ONSTACK) {
939 TRACE("not freeing stack ptr %p\n", Pointer);
940 return;
941 }
942 TRACE("freeing %p\n", Pointer);
943 NdrFree(pStubMsg, Pointer);
944 return;
945 notfree:
946 TRACE("not freeing %p\n", Pointer);
947 }
948
949 /***********************************************************************
950 * EmbeddedPointerMarshall
951 */
952 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
953 unsigned char *pMemory,
954 PFORMAT_STRING pFormat)
955 {
956 unsigned char *Mark = pStubMsg->BufferMark;
957 unsigned long Offset = pStubMsg->Offset;
958 unsigned ofs, rep, count, stride, xofs;
959
960 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
961
962 if (*pFormat != RPC_FC_PP) return NULL;
963 pFormat += 2;
964
965 while (pFormat[0] != RPC_FC_END) {
966 switch (pFormat[0]) {
967 default:
968 FIXME("unknown repeat type %d\n", pFormat[0]);
969 case RPC_FC_NO_REPEAT:
970 rep = 1;
971 stride = 0;
972 ofs = 0;
973 count = 1;
974 xofs = 0;
975 pFormat += 2;
976 break;
977 case RPC_FC_FIXED_REPEAT:
978 rep = *(const WORD*)&pFormat[2];
979 stride = *(const WORD*)&pFormat[4];
980 ofs = *(const WORD*)&pFormat[6];
981 count = *(const WORD*)&pFormat[8];
982 xofs = 0;
983 pFormat += 10;
984 break;
985 case RPC_FC_VARIABLE_REPEAT:
986 rep = pStubMsg->MaxCount;
987 stride = *(const WORD*)&pFormat[2];
988 ofs = *(const WORD*)&pFormat[4];
989 count = *(const WORD*)&pFormat[6];
990 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
991 pFormat += 8;
992 break;
993 }
994 /* ofs doesn't seem to matter in this context */
995 while (rep) {
996 PFORMAT_STRING info = pFormat;
997 unsigned char *membase = pMemory + xofs;
998 unsigned u;
999 for (u=0; u<count; u++,info+=8) {
1000 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1001 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1002 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1003 }
1004 rep--;
1005 }
1006 pFormat += 8 * count;
1007 }
1008
1009 STD_OVERFLOW_CHECK(pStubMsg);
1010
1011 return NULL;
1012 }
1013
1014 /***********************************************************************
1015 * EmbeddedPointerUnmarshall
1016 */
1017 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1018 unsigned char **ppMemory,
1019 PFORMAT_STRING pFormat,
1020 unsigned char fMustAlloc)
1021 {
1022 unsigned char *Mark = pStubMsg->BufferMark;
1023 unsigned long Offset = pStubMsg->Offset;
1024 unsigned ofs, rep, count, stride, xofs;
1025
1026 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1027
1028 if (*pFormat != RPC_FC_PP) return NULL;
1029 pFormat += 2;
1030
1031 while (pFormat[0] != RPC_FC_END) {
1032 switch (pFormat[0]) {
1033 default:
1034 FIXME("unknown repeat type %d\n", pFormat[0]);
1035 case RPC_FC_NO_REPEAT:
1036 rep = 1;
1037 stride = 0;
1038 ofs = 0;
1039 count = 1;
1040 xofs = 0;
1041 pFormat += 2;
1042 break;
1043 case RPC_FC_FIXED_REPEAT:
1044 rep = *(const WORD*)&pFormat[2];
1045 stride = *(const WORD*)&pFormat[4];
1046 ofs = *(const WORD*)&pFormat[6];
1047 count = *(const WORD*)&pFormat[8];
1048 xofs = 0;
1049 pFormat += 10;
1050 break;
1051 case RPC_FC_VARIABLE_REPEAT:
1052 rep = pStubMsg->MaxCount;
1053 stride = *(const WORD*)&pFormat[2];
1054 ofs = *(const WORD*)&pFormat[4];
1055 count = *(const WORD*)&pFormat[6];
1056 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1057 pFormat += 8;
1058 break;
1059 }
1060 /* ofs doesn't seem to matter in this context */
1061 while (rep) {
1062 PFORMAT_STRING info = pFormat;
1063 unsigned char *membase = *ppMemory + xofs;
1064 unsigned u;
1065 for (u=0; u<count; u++,info+=8) {
1066 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1067 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1068 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
1069 }
1070 rep--;
1071 }
1072 pFormat += 8 * count;
1073 }
1074
1075 return NULL;
1076 }
1077
1078 /***********************************************************************
1079 * EmbeddedPointerBufferSize
1080 */
1081 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1082 unsigned char *pMemory,
1083 PFORMAT_STRING pFormat)
1084 {
1085 unsigned long Offset = pStubMsg->Offset;
1086 unsigned ofs, rep, count, stride, xofs;
1087
1088 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1089 if (*pFormat != RPC_FC_PP) return;
1090 pFormat += 2;
1091
1092 while (pFormat[0] != RPC_FC_END) {
1093 switch (pFormat[0]) {
1094 default:
1095 FIXME("unknown repeat type %d\n", pFormat[0]);
1096 case RPC_FC_NO_REPEAT:
1097 rep = 1;
1098 stride = 0;
1099 ofs = 0;
1100 count = 1;
1101 xofs = 0;
1102 pFormat += 2;
1103 break;
1104 case RPC_FC_FIXED_REPEAT:
1105 rep = *(const WORD*)&pFormat[2];
1106 stride = *(const WORD*)&pFormat[4];
1107 ofs = *(const WORD*)&pFormat[6];
1108 count = *(const WORD*)&pFormat[8];
1109 xofs = 0;
1110 pFormat += 10;
1111 break;
1112 case RPC_FC_VARIABLE_REPEAT:
1113 rep = pStubMsg->MaxCount;
1114 stride = *(const WORD*)&pFormat[2];
1115 ofs = *(const WORD*)&pFormat[4];
1116 count = *(const WORD*)&pFormat[6];
1117 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1118 pFormat += 8;
1119 break;
1120 }
1121 /* ofs doesn't seem to matter in this context */
1122 while (rep) {
1123 PFORMAT_STRING info = pFormat;
1124 unsigned char *membase = pMemory + xofs;
1125 unsigned u;
1126 for (u=0; u<count; u++,info+=8) {
1127 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1128 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1129 }
1130 rep--;
1131 }
1132 pFormat += 8 * count;
1133 }
1134 }
1135
1136 /***********************************************************************
1137 * EmbeddedPointerMemorySize
1138 */
1139 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1140 PFORMAT_STRING pFormat)
1141 {
1142 unsigned long Offset = pStubMsg->Offset;
1143 unsigned char *Mark = pStubMsg->BufferMark;
1144 unsigned ofs, rep, count, stride, xofs;
1145
1146 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1147 if (*pFormat != RPC_FC_PP) return 0;
1148 pFormat += 2;
1149
1150 while (pFormat[0] != RPC_FC_END) {
1151 switch (pFormat[0]) {
1152 default:
1153 FIXME("unknown repeat type %d\n", pFormat[0]);
1154 case RPC_FC_NO_REPEAT:
1155 rep = 1;
1156 stride = 0;
1157 ofs = 0;
1158 count = 1;
1159 xofs = 0;
1160 pFormat += 2;
1161 break;
1162 case RPC_FC_FIXED_REPEAT:
1163 rep = *(const WORD*)&pFormat[2];
1164 stride = *(const WORD*)&pFormat[4];
1165 ofs = *(const WORD*)&pFormat[6];
1166 count = *(const WORD*)&pFormat[8];
1167 xofs = 0;
1168 pFormat += 10;
1169 break;
1170 case RPC_FC_VARIABLE_REPEAT:
1171 rep = pStubMsg->MaxCount;
1172 stride = *(const WORD*)&pFormat[2];
1173 ofs = *(const WORD*)&pFormat[4];
1174 count = *(const WORD*)&pFormat[6];
1175 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1176 pFormat += 8;
1177 break;
1178 }
1179 /* ofs doesn't seem to matter in this context */
1180 while (rep) {
1181 PFORMAT_STRING info = pFormat;
1182 unsigned u;
1183 for (u=0; u<count; u++,info+=8) {
1184 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1185 PointerMemorySize(pStubMsg, bufptr, info+4);
1186 }
1187 rep--;
1188 }
1189 pFormat += 8 * count;
1190 }
1191
1192 return 0;
1193 }
1194
1195 /***********************************************************************
1196 * EmbeddedPointerFree
1197 */
1198 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1199 unsigned char *pMemory,
1200 PFORMAT_STRING pFormat)
1201 {
1202 unsigned long Offset = pStubMsg->Offset;
1203 unsigned ofs, rep, count, stride, xofs;
1204
1205 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1206 if (*pFormat != RPC_FC_PP) return;
1207 pFormat += 2;
1208
1209 while (pFormat[0] != RPC_FC_END) {
1210 switch (pFormat[0]) {
1211 default:
1212 FIXME("unknown repeat type %d\n", pFormat[0]);
1213 case RPC_FC_NO_REPEAT:
1214 rep = 1;
1215 stride = 0;
1216 ofs = 0;
1217 count = 1;
1218 xofs = 0;
1219 pFormat += 2;
1220 break;
1221 case RPC_FC_FIXED_REPEAT:
1222 rep = *(const WORD*)&pFormat[2];
1223 stride = *(const WORD*)&pFormat[4];
1224 ofs = *(const WORD*)&pFormat[6];
1225 count = *(const WORD*)&pFormat[8];
1226 xofs = 0;
1227 pFormat += 10;
1228 break;
1229 case RPC_FC_VARIABLE_REPEAT:
1230 rep = pStubMsg->MaxCount;
1231 stride = *(const WORD*)&pFormat[2];
1232 ofs = *(const WORD*)&pFormat[4];
1233 count = *(const WORD*)&pFormat[6];
1234 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1235 pFormat += 8;
1236 break;
1237 }
1238 /* ofs doesn't seem to matter in this context */
1239 while (rep) {
1240 PFORMAT_STRING info = pFormat;
1241 unsigned char *membase = pMemory + xofs;
1242 unsigned u;
1243 for (u=0; u<count; u++,info+=8) {
1244 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1245 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1246 }
1247 rep--;
1248 }
1249 pFormat += 8 * count;
1250 }
1251 }
1252
1253 /***********************************************************************
1254 * NdrPointerMarshall [RPCRT4.@]
1255 */
1256 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1257 unsigned char *pMemory,
1258 PFORMAT_STRING pFormat)
1259 {
1260 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1261
1262 pStubMsg->BufferMark = pStubMsg->Buffer;
1263 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1264
1265 STD_OVERFLOW_CHECK(pStubMsg);
1266
1267 return NULL;
1268 }
1269
1270 /***********************************************************************
1271 * NdrPointerUnmarshall [RPCRT4.@]
1272 */
1273 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1274 unsigned char **ppMemory,
1275 PFORMAT_STRING pFormat,
1276 unsigned char fMustAlloc)
1277 {
1278 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1279
1280 pStubMsg->BufferMark = pStubMsg->Buffer;
1281 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1282
1283 return NULL;
1284 }
1285
1286 /***********************************************************************
1287 * NdrPointerBufferSize [RPCRT4.@]
1288 */
1289 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1290 unsigned char *pMemory,
1291 PFORMAT_STRING pFormat)
1292 {
1293 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1294 PointerBufferSize(pStubMsg, pMemory, pFormat);
1295 }
1296
1297 /***********************************************************************
1298 * NdrPointerMemorySize [RPCRT4.@]
1299 */
1300 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1301 PFORMAT_STRING pFormat)
1302 {
1303 /* unsigned size = *(LPWORD)(pFormat+2); */
1304 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1305 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1306 return 0;
1307 }
1308
1309 /***********************************************************************
1310 * NdrPointerFree [RPCRT4.@]
1311 */
1312 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1313 unsigned char *pMemory,
1314 PFORMAT_STRING pFormat)
1315 {
1316 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1317 PointerFree(pStubMsg, pMemory, pFormat);
1318 }
1319
1320 /***********************************************************************
1321 * NdrSimpleStructMarshall [RPCRT4.@]
1322 */
1323 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1324 unsigned char *pMemory,
1325 PFORMAT_STRING pFormat)
1326 {
1327 unsigned size = *(const WORD*)(pFormat+2);
1328 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1329
1330 memcpy(pStubMsg->Buffer, pMemory, size);
1331 pStubMsg->BufferMark = pStubMsg->Buffer;
1332 pStubMsg->Buffer += size;
1333
1334 if (pFormat[0] != RPC_FC_STRUCT)
1335 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1336
1337 /*
1338 * This test does not work when NdrSimpleStructMarshall is called
1339 * by an rpc-server to marshall data to return to the client because
1340 * BufferStart and BufferEnd are bogus. MIDL does not update them
1341 * when a new buffer is allocated in order to return data to the caller.
1342 */
1343 #if 0
1344 STD_OVERFLOW_CHECK(pStubMsg);
1345 #endif
1346
1347 return NULL;
1348 }
1349
1350 /***********************************************************************
1351 * NdrSimpleStructUnmarshall [RPCRT4.@]
1352 */
1353 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1354 unsigned char **ppMemory,
1355 PFORMAT_STRING pFormat,
1356 unsigned char fMustAlloc)
1357 {
1358 unsigned size = *(const WORD*)(pFormat+2);
1359 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1360
1361 if (fMustAlloc) {
1362 *ppMemory = NdrAllocate(pStubMsg, size);
1363 memcpy(*ppMemory, pStubMsg->Buffer, size);
1364 } else {
1365 if (pStubMsg->ReuseBuffer && !*ppMemory)
1366 /* for servers, we may just point straight into the RPC buffer, I think
1367 * (I guess that's what MS does since MIDL code doesn't try to free) */
1368 *ppMemory = pStubMsg->Buffer;
1369 else
1370 /* for clients, memory should be provided by caller */
1371 memcpy(*ppMemory, pStubMsg->Buffer, size);
1372 }
1373
1374 pStubMsg->BufferMark = pStubMsg->Buffer;
1375 pStubMsg->Buffer += size;
1376
1377 if (pFormat[0] != RPC_FC_STRUCT)
1378 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1379
1380 return NULL;
1381 }
1382
1383
1384 /***********************************************************************
1385 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1386 */
1387 void WINAPI NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1388 unsigned char *pMemory,
1389 unsigned char FormatChar)
1390 {
1391 FIXME("stub\n");
1392 }
1393
1394
1395 /***********************************************************************
1396 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1397 */
1398 void WINAPI NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1399 unsigned char *pMemory,
1400 unsigned char FormatChar)
1401 {
1402 FIXME("stub\n");
1403 }
1404
1405
1406 /***********************************************************************
1407 * NdrSimpleStructBufferSize [RPCRT4.@]
1408 */
1409 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1410 unsigned char *pMemory,
1411 PFORMAT_STRING pFormat)
1412 {
1413 unsigned size = *(const WORD*)(pFormat+2);
1414 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1415 pStubMsg->BufferLength += size;
1416 if (pFormat[0] != RPC_FC_STRUCT)
1417 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1418 }
1419
1420 /***********************************************************************
1421 * NdrSimpleStructMemorySize [RPCRT4.@]
1422 */
1423 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1424 PFORMAT_STRING pFormat)
1425 {
1426 /* unsigned size = *(LPWORD)(pFormat+2); */
1427 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1428 if (pFormat[0] != RPC_FC_STRUCT)
1429 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1430 return 0;
1431 }
1432
1433 /***********************************************************************
1434 * NdrSimpleStructFree [RPCRT4.@]
1435 */
1436 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1437 unsigned char *pMemory,
1438 PFORMAT_STRING pFormat)
1439 {
1440 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1441 if (pFormat[0] != RPC_FC_STRUCT)
1442 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1443 }
1444
1445
1446 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1447 PFORMAT_STRING pFormat)
1448 {
1449 switch (*pFormat) {
1450 case RPC_FC_STRUCT:
1451 case RPC_FC_PSTRUCT:
1452 case RPC_FC_CSTRUCT:
1453 case RPC_FC_BOGUS_STRUCT:
1454 return *(const WORD*)&pFormat[2];
1455 case RPC_FC_USER_MARSHAL:
1456 return *(const WORD*)&pFormat[4];
1457 default:
1458 FIXME("unhandled embedded type %02x\n", *pFormat);
1459 }
1460 return 0;
1461 }
1462
1463
1464 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1465 unsigned char *pMemory,
1466 PFORMAT_STRING pFormat,
1467 PFORMAT_STRING pPointer)
1468 {
1469 PFORMAT_STRING desc;
1470 NDR_MARSHALL m;
1471 unsigned long size;
1472
1473 while (*pFormat != RPC_FC_END) {
1474 switch (*pFormat) {
1475 case RPC_FC_SHORT:
1476 case RPC_FC_USHORT:
1477 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1478 memcpy(pStubMsg->Buffer, pMemory, 2);
1479 pStubMsg->Buffer += 2;
1480 pMemory += 2;
1481 break;
1482 case RPC_FC_LONG:
1483 case RPC_FC_ULONG:
1484 case RPC_FC_ENUM32:
1485 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1486 memcpy(pStubMsg->Buffer, pMemory, 4);
1487 pStubMsg->Buffer += 4;
1488 pMemory += 4;
1489 break;
1490 case RPC_FC_POINTER:
1491 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1492 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1493 pPointer += 4;
1494 pMemory += 4;
1495 break;
1496 case RPC_FC_ALIGNM4:
1497 ALIGN_POINTER(pMemory, 3);
1498 break;
1499 case RPC_FC_ALIGNM8:
1500 ALIGN_POINTER(pMemory, 7);
1501 break;
1502 case RPC_FC_STRUCTPAD2:
1503 pMemory += 2;
1504 break;
1505 case RPC_FC_EMBEDDED_COMPLEX:
1506 pMemory += pFormat[1];
1507 pFormat += 2;
1508 desc = pFormat + *(const SHORT*)pFormat;
1509 size = EmbeddedComplexSize(pStubMsg, desc);
1510 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1511 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1512 if (m) m(pStubMsg, pMemory, desc);
1513 else FIXME("no marshaller for embedded type %02x\n", *desc);
1514 pMemory += size;
1515 pFormat += 2;
1516 continue;
1517 case RPC_FC_PAD:
1518 break;
1519 default:
1520 FIXME("unhandled format %02x\n", *pFormat);
1521 }
1522 pFormat++;
1523 }
1524
1525 return pMemory;
1526 }
1527
1528 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1529 unsigned char *pMemory,
1530 PFORMAT_STRING pFormat,
1531 PFORMAT_STRING pPointer,
1532 unsigned char fMustAlloc)
1533 {
1534 PFORMAT_STRING desc;
1535 NDR_UNMARSHALL m;
1536 unsigned long size;
1537
1538 while (*pFormat != RPC_FC_END) {
1539 switch (*pFormat) {
1540 case RPC_FC_SHORT:
1541 case RPC_FC_USHORT:
1542 memcpy(pMemory, pStubMsg->Buffer, 2);
1543 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1544 pStubMsg->Buffer += 2;
1545 pMemory += 2;
1546 break;
1547 case RPC_FC_LONG:
1548 case RPC_FC_ULONG:
1549 case RPC_FC_ENUM32:
1550 memcpy(pMemory, pStubMsg->Buffer, 4);
1551 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1552 pStubMsg->Buffer += 4;
1553 pMemory += 4;
1554 break;
1555 case RPC_FC_POINTER:
1556 *(unsigned char**)pMemory = NULL;
1557 TRACE("pointer => %p\n", pMemory);
1558 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1559 pPointer += 4;
1560 pMemory += 4;
1561 break;
1562 case RPC_FC_ALIGNM4:
1563 ALIGN_POINTER(pMemory, 3);
1564 break;
1565 case RPC_FC_ALIGNM8:
1566 ALIGN_POINTER(pMemory, 7);
1567 break;
1568 case RPC_FC_STRUCTPAD2:
1569 pMemory += 2;
1570 break;
1571 case RPC_FC_EMBEDDED_COMPLEX:
1572 pMemory += pFormat[1];
1573 pFormat += 2;
1574 desc = pFormat + *(const SHORT*)pFormat;
1575 size = EmbeddedComplexSize(pStubMsg, desc);
1576 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1577 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1578 memset(pMemory, 0, size); /* just in case */
1579 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1580 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1581 pMemory += size;
1582 pFormat += 2;
1583 continue;
1584 case RPC_FC_PAD:
1585 break;
1586 default:
1587 FIXME("unhandled format %d\n", *pFormat);
1588 }
1589 pFormat++;
1590 }
1591
1592 return pMemory;
1593 }
1594
1595 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1596 unsigned char *pMemory,
1597 PFORMAT_STRING pFormat,
1598 PFORMAT_STRING pPointer)
1599 {
1600 PFORMAT_STRING desc;
1601 NDR_BUFFERSIZE m;
1602 unsigned long size;
1603
1604 while (*pFormat != RPC_FC_END) {
1605 switch (*pFormat) {
1606 case RPC_FC_SHORT:
1607 case RPC_FC_USHORT:
1608 pStubMsg->BufferLength += 2;
1609 pMemory += 2;
1610 break;
1611 case RPC_FC_LONG:
1612 case RPC_FC_ULONG:
1613 case RPC_FC_ENUM32:
1614 pStubMsg->BufferLength += 4;
1615 pMemory += 4;
1616 break;
1617 case RPC_FC_POINTER:
1618 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1619 pPointer += 4;
1620 pMemory += 4;
1621 break;
1622 case RPC_FC_ALIGNM4:
1623 ALIGN_POINTER(pMemory, 3);
1624 break;
1625 case RPC_FC_ALIGNM8:
1626 ALIGN_POINTER(pMemory, 7);
1627 break;
1628 case RPC_FC_STRUCTPAD2:
1629 pMemory += 2;
1630 break;
1631 case RPC_FC_EMBEDDED_COMPLEX:
1632 pMemory += pFormat[1];
1633 pFormat += 2;
1634 desc = pFormat + *(const SHORT*)pFormat;
1635 size = EmbeddedComplexSize(pStubMsg, desc);
1636 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1637 if (m) m(pStubMsg, pMemory, desc);
1638 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1639 pMemory += size;
1640 pFormat += 2;
1641 continue;
1642 case RPC_FC_PAD:
1643 break;
1644 default:
1645 FIXME("unhandled format %d\n", *pFormat);
1646 }
1647 pFormat++;
1648 }
1649
1650 return pMemory;
1651 }
1652
1653 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1654 unsigned char *pMemory,
1655 PFORMAT_STRING pFormat,
1656 PFORMAT_STRING pPointer)
1657 {
1658 PFORMAT_STRING desc;
1659 NDR_FREE m;
1660 unsigned long size;
1661
1662 while (*pFormat != RPC_FC_END) {
1663 switch (*pFormat) {
1664 case RPC_FC_SHORT:
1665 case RPC_FC_USHORT:
1666 pMemory += 2;
1667 break;
1668 case RPC_FC_LONG:
1669 case RPC_FC_ULONG:
1670 case RPC_FC_ENUM32:
1671 pMemory += 4;
1672 break;
1673 case RPC_FC_POINTER:
1674 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1675 pPointer += 4;
1676 pMemory += 4;
1677 break;
1678 case RPC_FC_ALIGNM4:
1679 ALIGN_POINTER(pMemory, 3);
1680 break;
1681 case RPC_FC_ALIGNM8:
1682 ALIGN_POINTER(pMemory, 7);
1683 break;
1684 case RPC_FC_STRUCTPAD2:
1685 pMemory += 2;
1686 break;
1687 case RPC_FC_EMBEDDED_COMPLEX:
1688 pMemory += pFormat[1];
1689 pFormat += 2;
1690 desc = pFormat + *(const SHORT*)pFormat;
1691 size = EmbeddedComplexSize(pStubMsg, desc);
1692 m = NdrFreer[*desc & NDR_TABLE_MASK];
1693 if (m) m(pStubMsg, pMemory, desc);
1694 else FIXME("no freer for embedded type %02x\n", *desc);
1695 pMemory += size;
1696 pFormat += 2;
1697 continue;
1698 case RPC_FC_PAD:
1699 break;
1700 default:
1701 FIXME("unhandled format %d\n", *pFormat);
1702 }
1703 pFormat++;
1704 }
1705
1706 return pMemory;
1707 }
1708
1709 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1710 PFORMAT_STRING pFormat)
1711 {
1712 PFORMAT_STRING desc;
1713 unsigned long size = 0;
1714
1715 while (*pFormat != RPC_FC_END) {
1716 switch (*pFormat) {
1717 case RPC_FC_SHORT:
1718 case RPC_FC_USHORT:
1719 size += 2;
1720 break;
1721 case RPC_FC_LONG:
1722 case RPC_FC_ULONG:
1723 size += 4;
1724 break;
1725 case RPC_FC_POINTER:
1726 size += 4;
1727 break;
1728 case RPC_FC_ALIGNM4:
1729 ALIGN_LENGTH(size, 3);
1730 break;
1731 case RPC_FC_ALIGNM8:
1732 ALIGN_LENGTH(size, 7);
1733 break;
1734 case RPC_FC_STRUCTPAD2:
1735 size += 2;
1736 break;
1737 case RPC_FC_EMBEDDED_COMPLEX:
1738 size += pFormat[1];
1739 pFormat += 2;
1740 desc = pFormat + *(const SHORT*)pFormat;
1741 size += EmbeddedComplexSize(pStubMsg, desc);
1742 pFormat += 2;
1743 continue;
1744 case RPC_FC_PAD:
1745 break;
1746 default:
1747 FIXME("unhandled format %d\n", *pFormat);
1748 }
1749 pFormat++;
1750 }
1751
1752 return size;
1753 }
1754
1755 /***********************************************************************
1756 * NdrComplexStructMarshall [RPCRT4.@]
1757 */
1758 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1759 unsigned char *pMemory,
1760 PFORMAT_STRING pFormat)
1761 {
1762 PFORMAT_STRING conf_array = NULL;
1763 PFORMAT_STRING pointer_desc = NULL;
1764 unsigned char *OldMemory = pStubMsg->Memory;
1765
1766 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1767
1768 pFormat += 4;
1769 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1770 pFormat += 2;
1771 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1772 pFormat += 2;
1773
1774 pStubMsg->Memory = pMemory;
1775
1776 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1777
1778 if (conf_array)
1779 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1780
1781 pStubMsg->Memory = OldMemory;
1782
1783 STD_OVERFLOW_CHECK(pStubMsg);
1784
1785 return NULL;
1786 }
1787
1788 /***********************************************************************
1789 * NdrComplexStructUnmarshall [RPCRT4.@]
1790 */
1791 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1792 unsigned char **ppMemory,
1793 PFORMAT_STRING pFormat,
1794 unsigned char fMustAlloc)
1795 {
1796 unsigned size = *(const WORD*)(pFormat+2);
1797 PFORMAT_STRING conf_array = NULL;
1798 PFORMAT_STRING pointer_desc = NULL;
1799 unsigned char *pMemory;
1800
1801 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1802
1803 if (fMustAlloc || !*ppMemory)
1804 {
1805 *ppMemory = NdrAllocate(pStubMsg, size);
1806 memset(*ppMemory, 0, size);
1807 }
1808
1809 pFormat += 4;
1810 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1811 pFormat += 2;
1812 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1813 pFormat += 2;
1814
1815 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1816
1817 if (conf_array)
1818 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1819
1820 return NULL;
1821 }
1822
1823 /***********************************************************************
1824 * NdrComplexStructBufferSize [RPCRT4.@]
1825 */
1826 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1827 unsigned char *pMemory,
1828 PFORMAT_STRING pFormat)
1829 {
1830 PFORMAT_STRING conf_array = NULL;
1831 PFORMAT_STRING pointer_desc = NULL;
1832 unsigned char *OldMemory = pStubMsg->Memory;
1833
1834 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1835
1836 pFormat += 4;
1837 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1838 pFormat += 2;
1839 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1840 pFormat += 2;
1841
1842 pStubMsg->Memory = pMemory;
1843
1844 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1845
1846 if (conf_array)
1847 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1848
1849 pStubMsg->Memory = OldMemory;
1850 }
1851
1852 /***********************************************************************
1853 * NdrComplexStructMemorySize [RPCRT4.@]
1854 */
1855 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1856 PFORMAT_STRING pFormat)
1857 {
1858 /* unsigned size = *(LPWORD)(pFormat+2); */
1859 PFORMAT_STRING conf_array = NULL;
1860 PFORMAT_STRING pointer_desc = NULL;
1861
1862 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1863
1864 pFormat += 4;
1865 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1866 pFormat += 2;
1867 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1868 pFormat += 2;
1869
1870 return 0;
1871 }
1872
1873 /***********************************************************************
1874 * NdrComplexStructFree [RPCRT4.@]
1875 */
1876 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1877 unsigned char *pMemory,
1878 PFORMAT_STRING pFormat)
1879 {
1880 PFORMAT_STRING conf_array = NULL;
1881 PFORMAT_STRING pointer_desc = NULL;
1882 unsigned char *OldMemory = pStubMsg->Memory;
1883
1884 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1885
1886 pFormat += 4;
1887 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1888 pFormat += 2;
1889 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1890 pFormat += 2;
1891
1892 pStubMsg->Memory = pMemory;
1893
1894 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1895
1896 if (conf_array)
1897 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1898
1899 pStubMsg->Memory = OldMemory;
1900 }
1901
1902 /***********************************************************************
1903 * NdrConformantArrayMarshall [RPCRT4.@]
1904 */
1905 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1906 unsigned char *pMemory,
1907 PFORMAT_STRING pFormat)
1908 {
1909 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1910 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1911 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1912
1913 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1914 size = pStubMsg->MaxCount;
1915
1916 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1917 pStubMsg->Buffer += 4;
1918
1919 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1920 pStubMsg->BufferMark = pStubMsg->Buffer;
1921 pStubMsg->Buffer += size*esize;
1922
1923 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1924
1925 STD_OVERFLOW_CHECK(pStubMsg);
1926
1927 return NULL;
1928 }
1929
1930 /***********************************************************************
1931 * NdrConformantArrayUnmarshall [RPCRT4.@]
1932 */
1933 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1934 unsigned char **ppMemory,
1935 PFORMAT_STRING pFormat,
1936 unsigned char fMustAlloc)
1937 {
1938 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1939 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1940 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1941
1942 pFormat = ReadConformance(pStubMsg, pFormat+4);
1943 size = pStubMsg->MaxCount;
1944
1945 if (fMustAlloc || !*ppMemory)
1946 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1947
1948 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1949
1950 pStubMsg->BufferMark = pStubMsg->Buffer;
1951 pStubMsg->Buffer += size*esize;
1952
1953 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1954
1955 return NULL;
1956 }
1957
1958 /***********************************************************************
1959 * NdrConformantArrayBufferSize [RPCRT4.@]
1960 */
1961 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1962 unsigned char *pMemory,
1963 PFORMAT_STRING pFormat)
1964 {
1965 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1966 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1967 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1968
1969 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1970 size = pStubMsg->MaxCount;
1971
1972 /* conformance value plus array */
1973 pStubMsg->BufferLength += sizeof(DWORD) + size*esize;
1974
1975 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1976 }
1977
1978 /***********************************************************************
1979 * NdrConformantArrayMemorySize [RPCRT4.@]
1980 */
1981 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1982 PFORMAT_STRING pFormat)
1983 {
1984 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1985 unsigned char *buffer;
1986
1987 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1988 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1989
1990 buffer = pStubMsg->Buffer;
1991 pFormat = ReadConformance(pStubMsg, pFormat+4);
1992 pStubMsg->Buffer = buffer;
1993 size = pStubMsg->MaxCount;
1994
1995 return size*esize;
1996 }
1997
1998 /***********************************************************************
1999 * NdrConformantArrayFree [RPCRT4.@]
2000 */
2001 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2002 unsigned char *pMemory,
2003 PFORMAT_STRING pFormat)
2004 {
2005 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2006 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2007
2008 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2009 }
2010
2011
2012 /***********************************************************************
2013 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2014 */
2015 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2016 unsigned char* pMemory,
2017 PFORMAT_STRING pFormat )
2018 {
2019 DWORD esize = *(const WORD*)(pFormat+2);
2020
2021 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2022
2023 if (pFormat[0] != RPC_FC_CVARRAY)
2024 {
2025 ERR("invalid format type %x\n", pFormat[0]);
2026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2027 return NULL;
2028 }
2029
2030 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2031 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2032
2033 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
2034 pStubMsg->Buffer += 4;
2035 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
2036 pStubMsg->Buffer += 4;
2037 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
2038 pStubMsg->Buffer += 4;
2039
2040 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2041 pStubMsg->BufferMark = pStubMsg->Buffer;
2042 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2043
2044 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2045
2046 STD_OVERFLOW_CHECK(pStubMsg);
2047
2048 return NULL;
2049 }
2050
2051
2052 /***********************************************************************
2053 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2054 */
2055 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2056 unsigned char** ppMemory,
2057 PFORMAT_STRING pFormat,
2058 unsigned char fMustAlloc )
2059 {
2060 DWORD esize = *(const WORD*)(pFormat+2);
2061
2062 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2063
2064 if (pFormat[0] != RPC_FC_CVARRAY)
2065 {
2066 ERR("invalid format type %x\n", pFormat[0]);
2067 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2068 return NULL;
2069 }
2070 pFormat = ReadConformance(pStubMsg, pFormat);
2071 pFormat = ReadVariance(pStubMsg, pFormat);
2072
2073 if (!*ppMemory || fMustAlloc)
2074 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2075 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2076 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2077
2078 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2079
2080 return NULL;
2081 }
2082
2083
2084 /***********************************************************************
2085 * NdrConformantVaryingArrayFree [RPCRT4.@]
2086 */
2087 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2088 unsigned char* pMemory,
2089 PFORMAT_STRING pFormat )
2090 {
2091 FIXME( "stub\n" );
2092 }
2093
2094
2095 /***********************************************************************
2096 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2097 */
2098 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2099 unsigned char* pMemory, PFORMAT_STRING pFormat )
2100 {
2101 DWORD esize = *(const WORD*)(pFormat+2);
2102
2103 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2104
2105 if (pFormat[0] != RPC_FC_CVARRAY)
2106 {
2107 ERR("invalid format type %x\n", pFormat[0]);
2108 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2109 return;
2110 }
2111
2112 /* compute size */
2113 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2114 /* compute length */
2115 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2116
2117 /* conformance + offset + variance + array */
2118 pStubMsg->BufferLength += 3*sizeof(DWORD) + pStubMsg->ActualCount*esize;
2119
2120 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2121 }
2122
2123
2124 /***********************************************************************
2125 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2126 */
2127 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2128 PFORMAT_STRING pFormat )
2129 {
2130 FIXME( "stub\n" );
2131 return 0;
2132 }
2133
2134
2135 /***********************************************************************
2136 * NdrComplexArrayMarshall [RPCRT4.@]
2137 */
2138 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2139 unsigned char *pMemory,
2140 PFORMAT_STRING pFormat)
2141 {
2142 ULONG count, def;
2143 BOOL variance_present;
2144
2145 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2146
2147 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2148 {
2149 ERR("invalid format type %x\n", pFormat[0]);
2150 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2151 return NULL;
2152 }
2153
2154 def = *(const WORD*)&pFormat[2];
2155 pFormat += 4;
2156
2157 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2158 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2159
2160 variance_present = IsConformanceOrVariancePresent(pFormat);
2161 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2162 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2163
2164 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
2165 pStubMsg->Buffer += 4;
2166 if (variance_present)
2167 {
2168 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
2169 pStubMsg->Buffer += 4;
2170 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
2171 pStubMsg->Buffer += 4;
2172 }
2173
2174 for (count = 0; count < pStubMsg->ActualCount; count++)
2175 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2176
2177 STD_OVERFLOW_CHECK(pStubMsg);
2178
2179 return NULL;
2180 }
2181
2182 /***********************************************************************
2183 * NdrComplexArrayUnmarshall [RPCRT4.@]
2184 */
2185 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2186 unsigned char **ppMemory,
2187 PFORMAT_STRING pFormat,
2188 unsigned char fMustAlloc)
2189 {
2190 ULONG count, esize;
2191 unsigned char *pMemory;
2192
2193 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2194
2195 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2196 {
2197 ERR("invalid format type %x\n", pFormat[0]);
2198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2199 return NULL;
2200 }
2201
2202 pFormat += 4;
2203
2204 pFormat = ReadConformance(pStubMsg, pFormat);
2205 pFormat = ReadVariance(pStubMsg, pFormat);
2206
2207 esize = ComplexStructSize(pStubMsg, pFormat);
2208
2209 if (fMustAlloc || !*ppMemory)
2210 {
2211 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2212 memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2213 }
2214
2215 pMemory = *ppMemory;
2216 for (count = 0; count < pStubMsg->ActualCount; count++)
2217 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2218
2219 return NULL;
2220 }
2221
2222 /***********************************************************************
2223 * NdrComplexArrayBufferSize [RPCRT4.@]
2224 */
2225 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2226 unsigned char *pMemory,
2227 PFORMAT_STRING pFormat)
2228 {
2229 ULONG count, def;
2230 BOOL variance_present;
2231
2232 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2233
2234 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2235 {
2236 ERR("invalid format type %x\n", pFormat[0]);
2237 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2238 return;
2239 }
2240
2241 def = *(const WORD*)&pFormat[2];
2242 pFormat += 4;
2243
2244 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2245 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2246 pStubMsg->BufferLength += sizeof(ULONG);
2247
2248 variance_present = IsConformanceOrVariancePresent(pFormat);
2249 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2250 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2251
2252 if (variance_present)
2253 pStubMsg->BufferLength += 2*sizeof(ULONG);
2254
2255 for (count=0; count < pStubMsg->ActualCount; count++)
2256 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2257 }
2258
2259 /***********************************************************************
2260 * NdrComplexArrayMemorySize [RPCRT4.@]
2261 */
2262 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2263 PFORMAT_STRING pFormat)
2264 {
2265 DWORD size = 0;
2266 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2267
2268 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2269 {
2270 ERR("invalid format type %x\n", pFormat[0]);
2271 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2272 return 0;
2273 }
2274
2275 pFormat += 4;
2276
2277 pFormat = ReadConformance(pStubMsg, pFormat);
2278 size = pStubMsg->MaxCount;
2279 TRACE("conformance=%ld\n", size);
2280
2281 pFormat += 4;
2282
2283 return 0;
2284 }
2285
2286 /***********************************************************************
2287 * NdrComplexArrayFree [RPCRT4.@]
2288 */
2289 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2290 unsigned char *pMemory,
2291 PFORMAT_STRING pFormat)
2292 {
2293 ULONG count, def;
2294
2295 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2296
2297 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2298 {
2299 ERR("invalid format type %x\n", pFormat[0]);
2300 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2301 return;
2302 }
2303
2304 def = *(const WORD*)&pFormat[2];
2305 pFormat += 4;
2306
2307 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2308 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2309
2310 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2311 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2312
2313 for (count=0; count < pStubMsg->ActualCount; count++)
2314 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2315 }
2316
2317 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2318 {
2319 return MAKELONG(pStubMsg->dwDestContext,
2320 pStubMsg->RpcMsg->DataRepresentation);
2321 }
2322
2323 /***********************************************************************
2324 * NdrUserMarshalMarshall [RPCRT4.@]
2325 */
2326 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2327 unsigned char *pMemory,
2328 PFORMAT_STRING pFormat)
2329 {
2330 /* unsigned flags = pFormat[1]; */
2331 unsigned index = *(const WORD*)&pFormat[2];
2332 unsigned long uflag = UserMarshalFlags(pStubMsg);
2333 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2334 TRACE("index=%d\n", index);
2335
2336 pStubMsg->Buffer =
2337 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2338 &uflag, pStubMsg->Buffer, pMemory);
2339
2340 STD_OVERFLOW_CHECK(pStubMsg);
2341
2342 return NULL;
2343 }
2344
2345 /***********************************************************************
2346 * NdrUserMarshalUnmarshall [RPCRT4.@]
2347 */
2348 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2349 unsigned char **ppMemory,
2350 PFORMAT_STRING pFormat,
2351 unsigned char fMustAlloc)
2352 {
2353 /* unsigned flags = pFormat[1];*/
2354 unsigned index = *(const WORD*)&pFormat[2];
2355 DWORD memsize = *(const WORD*)&pFormat[4];
2356 unsigned long uflag = UserMarshalFlags(pStubMsg);
2357 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2358 TRACE("index=%d\n", index);
2359
2360 if (fMustAlloc || !*ppMemory)
2361 *ppMemory = NdrAllocate(pStubMsg, memsize);
2362
2363 pStubMsg->Buffer =
2364 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2365 &uflag, pStubMsg->Buffer, *ppMemory);
2366
2367 return NULL;
2368 }
2369
2370 /***********************************************************************
2371 * NdrUserMarshalBufferSize [RPCRT4.@]
2372 */
2373 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2374 unsigned char *pMemory,
2375 PFORMAT_STRING pFormat)
2376 {
2377 /* unsigned flags = pFormat[1];*/
2378 unsigned index = *(const WORD*)&pFormat[2];
2379 DWORD bufsize = *(const WORD*)&pFormat[6];
2380 unsigned long uflag = UserMarshalFlags(pStubMsg);
2381 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2382 TRACE("index=%d\n", index);
2383
2384 if (bufsize) {
2385 TRACE("size=%ld\n", bufsize);
2386 pStubMsg->BufferLength += bufsize;
2387 return;
2388 }
2389
2390 pStubMsg->BufferLength =
2391 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2392 &uflag, pStubMsg->BufferLength, pMemory);
2393 }
2394
2395 /***********************************************************************
2396 * NdrUserMarshalMemorySize [RPCRT4.@]
2397 */
2398 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2399 PFORMAT_STRING pFormat)
2400 {
2401 unsigned index = *(const WORD*)&pFormat[2];
2402 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2403 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2404 TRACE("index=%d\n", index);
2405
2406 return 0;
2407 }
2408
2409 /***********************************************************************
2410 * NdrUserMarshalFree [RPCRT4.@]
2411 */
2412 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2413 unsigned char *pMemory,
2414 PFORMAT_STRING pFormat)
2415 {
2416 /* unsigned flags = pFormat[1]; */
2417 unsigned index = *(const WORD*)&pFormat[2];
2418 unsigned long uflag = UserMarshalFlags(pStubMsg);
2419 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2420 TRACE("index=%d\n", index);
2421
2422 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2423 &uflag, pMemory);
2424 }
2425
2426 /***********************************************************************
2427 * NdrClearOutParameters [RPCRT4.@]
2428 */
2429 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2430 PFORMAT_STRING pFormat,
2431 void *ArgAddr)
2432 {
2433 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2434 }
2435
2436 /***********************************************************************
2437 * NdrConvert [RPCRT4.@]
2438 */
2439 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2440 {
2441 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2442 /* FIXME: since this stub doesn't do any converting, the proper behavior
2443 is to raise an exception */
2444 }
2445
2446 /***********************************************************************
2447 * NdrConvert2 [RPCRT4.@]
2448 */
2449 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2450 {
2451 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2452 pStubMsg, pFormat, NumberParams);
2453 /* FIXME: since this stub doesn't do any converting, the proper behavior
2454 is to raise an exception */
2455 }
2456
2457 typedef struct _NDR_CSTRUCT_FORMAT
2458 {
2459 unsigned char type;
2460 unsigned char alignment;
2461 unsigned short memory_size;
2462 short offset_to_array_description;
2463 } NDR_CSTRUCT_FORMAT;
2464
2465 /***********************************************************************
2466 * NdrConformantStructMarshall [RPCRT4.@]
2467 */
2468 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2469 unsigned char *pMemory,
2470 PFORMAT_STRING pFormat)
2471 {
2472 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2473 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2474
2475 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2476
2477 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2478 {
2479 ERR("invalid format type %x\n", pCStructFormat->type);
2480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2481 return NULL;
2482 }
2483
2484 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2485
2486 /* copy constant sized part of struct */
2487 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size);
2488 pStubMsg->Buffer += pCStructFormat->memory_size;
2489
2490 if (pCStructFormat->offset_to_array_description)
2491 {
2492 PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2493 pCStructFormat->offset_to_array_description;
2494 NdrConformantArrayMarshall(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat);
2495 }
2496 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2497 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2498 return NULL;
2499 }
2500
2501 /***********************************************************************
2502 * NdrConformantStructUnmarshall [RPCRT4.@]
2503 */
2504 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2505 unsigned char **ppMemory,
2506 PFORMAT_STRING pFormat,
2507 unsigned char fMustAlloc)
2508 {
2509 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2510 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2511
2512 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2513
2514 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2515 {
2516 ERR("invalid format type %x\n", pCStructFormat->type);
2517 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2518 return NULL;
2519 }
2520
2521 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2522
2523 /* work out how much memory to allocate if we need to do so */
2524 if (!*ppMemory || fMustAlloc)
2525 {
2526 SIZE_T size = pCStructFormat->memory_size;
2527
2528 if (pCStructFormat->offset_to_array_description)
2529 {
2530 unsigned char *buffer;
2531 PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2532 pCStructFormat->offset_to_array_description;
2533 buffer = pStubMsg->Buffer;
2534 pStubMsg->Buffer += pCStructFormat->memory_size;
2535 size += NdrConformantArrayMemorySize(pStubMsg, pArrayFormat);
2536 pStubMsg->Buffer = buffer;
2537 }
2538 *ppMemory = NdrAllocate(pStubMsg, size);
2539 }
2540
2541 /* now copy the data */
2542 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size);
2543 pStubMsg->Buffer += pCStructFormat->memory_size;
2544 if (pCStructFormat->offset_to_array_description)
2545 {
2546 PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2547 pCStructFormat->offset_to_array_description;
2548 unsigned char *pMemoryArray = *ppMemory + pCStructFormat->memory_size;
2549 /* note that we pass fMustAlloc as 0 as we have already allocated the
2550 * memory */
2551 NdrConformantArrayUnmarshall(pStubMsg, &pMemoryArray, pArrayFormat, 0);
2552 }
2553 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2554 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2555 return NULL;
2556 }
2557
2558 /***********************************************************************
2559 * NdrConformantStructBufferSize [RPCRT4.@]
2560 */
2561 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2562 unsigned char *pMemory,
2563 PFORMAT_STRING pFormat)
2564 {
2565 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2566 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2567 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2568
2569 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2570 {
2571 ERR("invalid format type %x\n", pCStructFormat->type);
2572 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2573 return;
2574 }
2575
2576 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2577
2578 /* add constant sized part of struct to buffer size */
2579 pStubMsg->BufferLength += pCStructFormat->memory_size;
2580
2581 if (pCStructFormat->offset_to_array_description)
2582 {
2583 PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2584 pCStructFormat->offset_to_array_description;
2585 NdrConformantArrayBufferSize(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat);
2586 }
2587 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2588 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2589 }
2590
2591 /***********************************************************************
2592 * NdrConformantStructMemorySize [RPCRT4.@]
2593 */
2594 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2595 PFORMAT_STRING pFormat)
2596 {
2597 FIXME("stub\n");
2598 return 0;
2599 }
2600
2601 /***********************************************************************
2602 * NdrConformantStructFree [RPCRT4.@]
2603 */
2604 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2605 unsigned char *pMemory,
2606 PFORMAT_STRING pFormat)
2607 {
2608 FIXME("stub\n");
2609 }
2610
2611 /***********************************************************************
2612 * NdrConformantVaryingStructMarshall [RPCRT4.@]
2613 */
2614 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2615 unsigned char *pMemory,
2616 PFORMAT_STRING pFormat)
2617 {
2618 FIXME("stub\n");
2619 return NULL;
2620 }
2621
2622 /***********************************************************************
2623 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
2624 */
2625 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2626 unsigned char **ppMemory,
2627 PFORMAT_STRING pFormat,
2628 unsigned char fMustAlloc)
2629 {
2630 FIXME("stub\n");
2631 return NULL;
2632 }
2633
2634 /***********************************************************************
2635 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
2636 */
2637 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2638 unsigned char *pMemory,
2639 PFORMAT_STRING pFormat)
2640 {
2641 FIXME("stub\n");
2642 }
2643
2644 /***********************************************************************
2645 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
2646 */
2647 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2648 PFORMAT_STRING pFormat)
2649 {
2650 FIXME("stub\n");
2651 return 0;
2652 }
2653
2654 /***********************************************************************
2655 * NdrConformantVaryingStructFree [RPCRT4.@]
2656 */
2657 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2658 unsigned char *pMemory,
2659 PFORMAT_STRING pFormat)
2660 {
2661 FIXME("stub\n");
2662 }
2663
2664 /***********************************************************************
2665 * NdrFixedArrayMarshall [RPCRT4.@]
2666 */
2667 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2668 unsigned char *pMemory,
2669 PFORMAT_STRING pFormat)
2670 {
2671 FIXME("stub\n");
2672 return NULL;
2673 }
2674
2675 /***********************************************************************
2676 * NdrFixedArrayUnmarshall [RPCRT4.@]
2677 */
2678 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2679 unsigned char **ppMemory,
2680 PFORMAT_STRING pFormat,
2681 unsigned char fMustAlloc)
2682 {
2683 FIXME("stub\n");
2684 return NULL;
2685 }
2686
2687 /***********************************************************************
2688 * NdrFixedArrayBufferSize [RPCRT4.@]
2689 */
2690 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2691 unsigned char *pMemory,
2692 PFORMAT_STRING pFormat)
2693 {
2694 FIXME("stub\n");
2695 }
2696
2697 /***********************************************************************
2698 * NdrFixedArrayMemorySize [RPCRT4.@]
2699 */
2700 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2701 PFORMAT_STRING pFormat)
2702 {
2703 FIXME("stub\n");
2704 return 0;
2705 }
2706
2707 /***********************************************************************
2708 * NdrFixedArrayFree [RPCRT4.@]
2709 */
2710 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2711 unsigned char *pMemory,
2712 PFORMAT_STRING pFormat)
2713 {
2714 FIXME("stub\n");
2715 }
2716
2717 /***********************************************************************
2718 * NdrVaryingArrayMarshall [RPCRT4.@]
2719 */
2720 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2721 unsigned char *pMemory,
2722 PFORMAT_STRING pFormat)
2723 {
2724 FIXME("stub\n");
2725 return NULL;
2726 }
2727
2728 /***********************************************************************
2729 * NdrVaryingArrayUnmarshall [RPCRT4.@]
2730 */
2731 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2732 unsigned char **ppMemory,
2733 PFORMAT_STRING pFormat,
2734 unsigned char fMustAlloc)
2735 {
2736 FIXME("stub\n");
2737 return NULL;
2738 }
2739
2740 /***********************************************************************
2741 * NdrVaryingArrayBufferSize [RPCRT4.@]
2742 */
2743 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2744 unsigned char *pMemory,
2745 PFORMAT_STRING pFormat)
2746 {
2747 FIXME("stub\n");
2748 }
2749
2750 /***********************************************************************
2751 * NdrVaryingArrayMemorySize [RPCRT4.@]
2752 */
2753 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2754 PFORMAT_STRING pFormat)
2755 {
2756 FIXME("stub\n");
2757 return 0;
2758 }
2759
2760 /***********************************************************************
2761 * NdrVaryingArrayFree [RPCRT4.@]
2762 */
2763 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2764 unsigned char *pMemory,
2765 PFORMAT_STRING pFormat)
2766 {
2767 FIXME("stub\n");
2768 }
2769
2770 /***********************************************************************
2771 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
2772 */
2773 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2774 unsigned char *pMemory,
2775 PFORMAT_STRING pFormat)
2776 {
2777 FIXME("stub\n");
2778 return NULL;
2779 }
2780
2781 /***********************************************************************
2782 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
2783 */
2784 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2785 unsigned char **ppMemory,
2786 PFORMAT_STRING pFormat,
2787 unsigned char fMustAlloc)
2788 {
2789 FIXME("stub\n");
2790 return NULL;
2791 }
2792
2793 /***********************************************************************
2794 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
2795 */
2796 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2797 unsigned char *pMemory,
2798 PFORMAT_STRING pFormat)
2799 {
2800 FIXME("stub\n");
2801 }
2802
2803 /***********************************************************************
2804 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
2805 */
2806 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2807 PFORMAT_STRING pFormat)
2808 {
2809 FIXME("stub\n");
2810 return 0;
2811 }
2812
2813 /***********************************************************************
2814 * NdrEncapsulatedUnionFree [RPCRT4.@]
2815 */
2816 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2817 unsigned char *pMemory,
2818 PFORMAT_STRING pFormat)
2819 {
2820 FIXME("stub\n");
2821 }
2822
2823 /***********************************************************************
2824 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
2825 */
2826 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2827 unsigned char *pMemory,
2828 PFORMAT_STRING pFormat)
2829 {
2830 FIXME("stub\n");
2831 return NULL;
2832 }
2833
2834 /***********************************************************************
2835 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
2836 */
2837 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2838 unsigned char **ppMemory,
2839 PFORMAT_STRING pFormat,
2840 unsigned char fMustAlloc)
2841 {
2842 FIXME("stub\n");
2843 return NULL;
2844 }
2845
2846 /***********************************************************************
2847 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
2848 */
2849 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2850 unsigned char *pMemory,
2851 PFORMAT_STRING pFormat)
2852 {
2853 FIXME("stub\n");
2854 }
2855
2856 /***********************************************************************
2857 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
2858 */
2859 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2860 PFORMAT_STRING pFormat)
2861 {
2862 FIXME("stub\n");
2863 return 0;
2864 }
2865
2866 /***********************************************************************
2867 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
2868 */
2869 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2870 unsigned char *pMemory,
2871 PFORMAT_STRING pFormat)
2872 {
2873 FIXME("stub\n");
2874 }
2875
2876 /***********************************************************************
2877 * NdrByteCountPointerMarshall [RPCRT4.@]
2878 */
2879 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2880 unsigned char *pMemory,
2881 PFORMAT_STRING pFormat)
2882 {
2883 FIXME("stub\n");
2884 return NULL;
2885 }
2886
2887 /***********************************************************************
2888 * NdrByteCountPointerUnmarshall [RPCRT4.@]
2889 */
2890 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2891 unsigned char **ppMemory,
2892 PFORMAT_STRING pFormat,
2893 unsigned char fMustAlloc)
2894 {
2895 FIXME("stub\n");
2896 return NULL;
2897 }
2898
2899 /***********************************************************************
2900 * NdrByteCountPointerBufferSize [RPCRT4.@]
2901 */
2902 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2903 unsigned char *pMemory,
2904 PFORMAT_STRING pFormat)
2905 {
2906 FIXME("stub\n");
2907 }
2908
2909 /***********************************************************************
2910 * NdrByteCountPointerMemorySize [RPCRT4.@]
2911 */
2912 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2913 PFORMAT_STRING pFormat)
2914 {
2915 FIXME("stub\n");
2916 return 0;
2917 }
2918
2919 /***********************************************************************
2920 * NdrByteCountPointerFree [RPCRT4.@]
2921 */
2922 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
2923 unsigned char *pMemory,
2924 PFORMAT_STRING pFormat)
2925 {
2926 FIXME("stub\n");
2927 }
2928
2929 /***********************************************************************
2930 * NdrXmitOrRepAsMarshall [RPCRT4.@]
2931 */
2932 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2933 unsigned char *pMemory,
2934 PFORMAT_STRING pFormat)
2935 {
2936 FIXME("stub\n");
2937 return NULL;
2938 }
2939
2940 /***********************************************************************
2941 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
2942 */
2943 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2944 unsigned char **ppMemory,
2945 PFORMAT_STRING pFormat,
2946 unsigned char fMustAlloc)
2947 {
2948 FIXME("stub\n");
2949 return NULL;
2950 }
2951
2952 /***********************************************************************
2953 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
2954 */
2955 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2956 unsigned char *pMemory,
2957 PFORMAT_STRING pFormat)
2958 {
2959 FIXME("stub\n");
2960 }
2961
2962 /***********************************************************************
2963 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
2964 */
2965 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2966 PFORMAT_STRING pFormat)
2967 {
2968 FIXME("stub\n");
2969 return 0;
2970 }
2971
2972 /***********************************************************************
2973 * NdrXmitOrRepAsFree [RPCRT4.@]
2974 */
2975 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
2976 unsigned char *pMemory,
2977 PFORMAT_STRING pFormat)
2978 {
2979 FIXME("stub\n");
2980 }
2981
2982 /***********************************************************************
2983 * NdrBaseTypeMarshall [internal]
2984 */
2985 static unsigned char *WINAPI NdrBaseTypeMarshall(
2986 PMIDL_STUB_MESSAGE pStubMsg,
2987 unsigned char *pMemory,
2988 PFORMAT_STRING pFormat)
2989 {
2990 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
2991
2992 switch(*pFormat)
2993 {
2994 case RPC_FC_BYTE:
2995 case RPC_FC_CHAR:
2996 case RPC_FC_SMALL:
2997 case RPC_FC_USMALL:
2998 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
2999 pStubMsg->Buffer += sizeof(UCHAR);
3000 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
3001 break;
3002 case RPC_FC_WCHAR:
3003 case RPC_FC_SHORT:
3004 case RPC_FC_USHORT:
3005 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
3006 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
3007 pStubMsg->Buffer += sizeof(USHORT);
3008 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
3009 break;
3010 case RPC_FC_LONG:
3011 case RPC_FC_ULONG:
3012 case RPC_FC_ERROR_STATUS_T:
3013 case RPC_FC_ENUM32:
3014 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1);
3015 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
3016 pStubMsg->Buffer += sizeof(ULONG);
3017 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
3018 break;
3019 case RPC_FC_FLOAT:
3020 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1);
3021 *(float *)pStubMsg->Buffer = *(float *)pMemory;
3022 pStubMsg->Buffer += sizeof(float);
3023 break;
3024 case RPC_FC_DOUBLE:
3025 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1);
3026 *(double *)pStubMsg->Buffer = *(double *)pMemory;
3027 pStubMsg->Buffer += sizeof(double);
3028 break;
3029 case RPC_FC_HYPER:
3030 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1);
3031 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
3032 pStubMsg->Buffer += sizeof(ULONGLONG);
3033 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
3034 break;
3035 case RPC_FC_ENUM16:
3036 /* only 16-bits on the wire, so do a sanity check */
3037 if (*(UINT *)pMemory > USHRT_MAX)
3038 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3039 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
3040 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
3041 pStubMsg->Buffer += sizeof(USHORT);
3042 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
3043 break;
3044 default:
3045 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3046 }
3047
3048 STD_OVERFLOW_CHECK(pStubMsg);
3049
3050 /* FIXME: what is the correct return value? */
3051 return NULL;
3052 }
3053
3054 /***********************************************************************
3055 * NdrBaseTypeUnmarshall [internal]
3056 */
3057 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
3058 PMIDL_STUB_MESSAGE pStubMsg,
3059 unsigned char **ppMemory,
3060 PFORMAT_STRING pFormat,
3061 unsigned char fMustAlloc)
3062 {
3063 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
3064
3065 if (fMustAlloc || !*ppMemory)
3066 *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
3067
3068 TRACE("*ppMemory: %p\n", *ppMemory);
3069
3070 switch(*pFormat)
3071 {
3072 case RPC_FC_BYTE:
3073 case RPC_FC_CHAR:
3074 case RPC_FC_SMALL:
3075 case RPC_FC_USMALL:
3076 **(UCHAR **)ppMemory = *(UCHAR *)pStubMsg->Buffer;
3077 pStubMsg->Buffer += sizeof(UCHAR);
3078 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
3079 break;
3080 case RPC_FC_WCHAR:
3081 case RPC_FC_SHORT:
3082 case RPC_FC_USHORT:
3083 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
3084 **(USHORT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
3085 pStubMsg->Buffer += sizeof(USHORT);
3086 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
3087 break;
3088 case RPC_FC_LONG:
3089 case RPC_FC_ULONG:
3090 case RPC_FC_ERROR_STATUS_T:
3091 case RPC_FC_ENUM32:
3092 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1);
3093 **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer;
3094 pStubMsg->Buffer += sizeof(ULONG);
3095 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
3096 break;
3097 case RPC_FC_FLOAT:
3098 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1);
3099 **(float **)ppMemory = *(float *)pStubMsg->Buffer;
3100 pStubMsg->Buffer += sizeof(float);
3101 TRACE("value: %f\n", **(float **)ppMemory);
3102 break;
3103 case RPC_FC_DOUBLE:
3104 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1);
3105 **(double **)ppMemory = *(double*)pStubMsg->Buffer;
3106 pStubMsg->Buffer += sizeof(double);
3107 TRACE("value: %f\n", **(double **)ppMemory);
3108 break;
3109 case RPC_FC_HYPER:
3110 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1);
3111 **(ULONGLONG **)ppMemory = *(ULONGLONG *)pStubMsg->Buffer;
3112 pStubMsg->Buffer += sizeof(ULONGLONG);
3113 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
3114 break;
3115 case RPC_FC_ENUM16:
3116 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
3117 /* 16-bits on the wire, but int in memory */
3118 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
3119 pStubMsg->Buffer += sizeof(USHORT);
3120 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
3121 break;
3122 default:
3123 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3124 }
3125
3126 /* FIXME: what is the correct return value? */
3127
3128 return NULL;
3129 }
3130
3131 /***********************************************************************
3132 * NdrBaseTypeBufferSize [internal]
3133 */
3134 static void WINAPI NdrBaseTypeBufferSize(
3135 PMIDL_STUB_MESSAGE pStubMsg,
3136 unsigned char *pMemory,
3137 PFORMAT_STRING pFormat)
3138 {
3139 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
3140
3141 switch(*pFormat)
3142 {
3143 case RPC_FC_BYTE:
3144 case RPC_FC_CHAR:
3145 case RPC_FC_SMALL:
3146 case RPC_FC_USMALL:
3147 pStubMsg->BufferLength += sizeof(UCHAR);
3148 break;
3149 case RPC_FC_WCHAR:
3150 case RPC_FC_SHORT:
3151 case RPC_FC_USHORT:
3152 case RPC_FC_ENUM16:
3153 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT) - 1);
3154 pStubMsg->BufferLength += sizeof(USHORT);
3155 break;
3156 case RPC_FC_LONG:
3157 case RPC_FC_ULONG:
3158 case RPC_FC_ENUM32:
3159 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG) - 1);
3160 pStubMsg->BufferLength += sizeof(ULONG);
3161 break;
3162 case RPC_FC_FLOAT:
3163 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float) - 1);
3164 pStubMsg->BufferLength += sizeof(float);
3165 break;
3166 case RPC_FC_DOUBLE:
3167 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double) - 1);
3168 pStubMsg->BufferLength += sizeof(double);
3169 break;
3170 case RPC_FC_HYPER:
3171 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG) - 1);
3172 pStubMsg->BufferLength += sizeof(ULONGLONG);
3173 break;
3174 case RPC_FC_ERROR_STATUS_T:
3175 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t) - 1);
3176 pStubMsg->BufferLength += sizeof(error_status_t);
3177 break;
3178 default:
3179 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3180 }
3181 }
3182
3183 /***********************************************************************
3184 * NdrBaseTypeMemorySize [internal]
3185 */
3186 static unsigned long WINAPI NdrBaseTypeMemorySize(
3187 PMIDL_STUB_MESSAGE pStubMsg,
3188 PFORMAT_STRING pFormat)
3189 {
3190 switch(*pFormat)
3191 {
3192 case RPC_FC_BYTE:
3193 case RPC_FC_CHAR:
3194 case RPC_FC_SMALL:
3195 case RPC_FC_USMALL:
3196 return sizeof(UCHAR);
3197 case RPC_FC_WCHAR:
3198 case RPC_FC_SHORT:
3199 case RPC_FC_USHORT:
3200 return sizeof(USHORT);
3201 case RPC_FC_LONG:
3202 case RPC_FC_ULONG:
3203 return sizeof(ULONG);
3204 case RPC_FC_FLOAT:
3205 return sizeof(float);
3206 case RPC_FC_DOUBLE:
3207 return sizeof(double);
3208 case RPC_FC_HYPER:
3209 return sizeof(ULONGLONG);
3210 case RPC_FC_ERROR_STATUS_T:
3211 return sizeof(error_status_t);
3212 case RPC_FC_ENUM16:
3213 case RPC_FC_ENUM32:
3214 return sizeof(INT);
3215 default:
3216 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3217 return 0;
3218 }
3219 }
3220
3221 /***********************************************************************
3222 * NdrBaseTypeFree [internal]
3223 */
3224 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
3225 unsigned char *pMemory,
3226 PFORMAT_STRING pFormat)
3227 {
3228 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
3229
3230 /* nothing to do */
3231 }
3232
3233 /***********************************************************************
3234 * NDRCContextMarshall
3235 */
3236 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff )
3237 {
3238 CContextHandle *ctx = (CContextHandle*)CContext;
3239 memcpy(pBuff, &ctx->Ndr, sizeof(ContextHandleNdr));
3240 }
3241
3242 /***********************************************************************
3243 * NdrClientContextMarshall
3244 */
3245 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3246 NDR_CCONTEXT ContextHandle,
3247 int fCheck)
3248 {
3249
3250 if(!ContextHandle)
3251 RpcRaiseException(ERROR_INVALID_HANDLE);
3252
3253 NDRCContextMarshall(ContextHandle, pStubMsg->Buffer);
3254
3255 pStubMsg->Buffer += sizeof(ContextHandleNdr);
3256
3257 }
3258
3259
3260 /***********************************************************************
3261 * NDRCContextUnmarshall
3262 */
3263 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *pCContext,
3264 RPC_BINDING_HANDLE hBinding,
3265 void *pBuff,
3266 unsigned long DataRepresentation )
3267 {
3268 CContextHandle *ctx = (CContextHandle*)*pCContext;
3269 ContextHandleNdr *ndr = (ContextHandleNdr*)pBuff;
3270 RPC_STATUS status;
3271
3272 if(UuidIsNil(&ndr->uuid, &status))
3273 {
3274 if(ctx)
3275 {
3276 RPCRT4_DestroyBinding(ctx->Binding);
3277 HeapFree(GetProcessHeap(), 0, ctx);
3278 }
3279 *pCContext = NULL;
3280 }
3281 else
3282 {
3283 ctx = HeapAlloc(GetProcessHeap(), 0, sizeof(CContextHandle));
3284 if(!ctx) RpcRaiseException(ERROR_OUTOFMEMORY);
3285
3286 status = RpcBindingCopy(hBinding, (RPC_BINDING_HANDLE*) &ctx->Binding);
3287 if(status != RPC_S_OK) RpcRaiseException(status);
3288
3289 memcpy(&ctx->Ndr, ndr, sizeof(ContextHandleNdr));
3290 *pCContext = (NDR_CCONTEXT)ctx;
3291 }
3292 }
3293
3294 /***********************************************************************
3295 * NdrClientContextUnmarshall
3296 */
3297 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3298 NDR_CCONTEXT * pContextHandle,
3299 RPC_BINDING_HANDLE BindHandle)
3300 {
3301 if(!pContextHandle)
3302 RpcRaiseException(ERROR_INVALID_HANDLE);
3303
3304 NDRCContextUnmarshall(pContextHandle,
3305 ((CContextHandle*)pContextHandle)->Binding,
3306 pStubMsg->Buffer,
3307 pStubMsg->RpcMsg->DataRepresentation);
3308
3309 pStubMsg->Buffer += sizeof(ContextHandleNdr);
3310 }
3311
3312 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3313 NDR_SCONTEXT ContextHandle,
3314 NDR_RUNDOWN RundownRoutine )
3315 {
3316 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
3317 }
3318
3319 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
3320 {
3321 FIXME("(%p): stub\n", pStubMsg);
3322 return NULL;
3323 }
3324
3325 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
3326 unsigned char* pMemory,
3327 PFORMAT_STRING pFormat)
3328 {
3329 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
3330 }
3331
3332 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
3333 PFORMAT_STRING pFormat)
3334 {
3335 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
3336 return NULL;
3337 }
3338
3339 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3340 NDR_SCONTEXT ContextHandle,
3341 NDR_RUNDOWN RundownRoutine,
3342 PFORMAT_STRING pFormat)
3343 {
3344 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
3345 }
3346
3347 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3348 PFORMAT_STRING pFormat)
3349 {
3350 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
3351 return NULL;
3352 }
3353
3354 /***********************************************************************
3355 * NDRCContextBinding
3356 */
3357 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
3358 {
3359 if(!CContext)
3360 RpcRaiseException(ERROR_INVALID_HANDLE);
3361
3362 return (RPC_BINDING_HANDLE)((CContextHandle*)CContext)->Binding;
3363 }
3364
3365 /***********************************************************************
3366 * RpcSmDestroyClientContext
3367 */
3368 RPC_STATUS WINAPI RpcSmDestroyClientContext(void** ContextHandle)
3369 {
3370 CContextHandle *ctx = (CContextHandle*)ContextHandle;
3371
3372 if(!ctx)
3373 return RPC_X_SS_CONTEXT_MISMATCH;
3374
3375 RPCRT4_DestroyBinding(ctx->Binding);
3376 HeapFree(GetProcessHeap(), 0, ctx);
3377 *ContextHandle = NULL;
3378
3379 return RPC_S_OK;
3380 }
3381
3382 /***********************************************************************
3383 * RpcSsDestroyClientContext
3384 */
3385 void WINAPI RpcSsDestroyClientContext(void** ContextHandle)
3386 {
3387 RPC_STATUS status;
3388
3389 status = RpcSmDestroyClientContext(ContextHandle);
3390
3391 if(status != RPC_S_OK)
3392 RpcRaiseException(status);
3393 }
3394
3395