1 /* 2 * NDR data marshalling 3 * 4 * Copyright 2002 Greg Turner 5 * Copyright 2003-2006 CodeWeavers 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 * 21 * TODO: 22 * - String structs 23 * - Byte count pointers 24 * - transmit_as/represent as 25 * - Multi-dimensional arrays 26 * - Conversion functions (NdrConvert) 27 * - Checks for integer addition overflow in user marshall functions 28 */ 29 30 #include <assert.h> 31 #include <stdarg.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <limits.h> 35 36 #define NONAMELESSUNION 37 #include "windef.h" 38 #include "winbase.h" 39 #include "winerror.h" 40 41 #include "ndr_misc.h" 42 #include "rpcndr.h" 43 #include "ndrtypes.h" 44 45 #include "wine/unicode.h" 46 #include "wine/rpcfc.h" 47 48 #include "wine/debug.h" 49 50 WINE_DEFAULT_DEBUG_CHANNEL(ole); 51 52 #if defined(__i386__) 53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ 54 (*((UINT32 *)(pchar)) = (uint32)) 55 56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \ 57 (*((UINT32 *)(pchar))) 58 #else 59 /* these would work for i386 too, but less efficient */ 60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ 61 (*(pchar) = LOBYTE(LOWORD(uint32)), \ 62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \ 63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \ 64 *((pchar)+3) = HIBYTE(HIWORD(uint32))) 65 66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \ 67 (MAKELONG( \ 68 MAKEWORD(*(pchar), *((pchar)+1)), \ 69 MAKEWORD(*((pchar)+2), *((pchar)+3)))) 70 #endif 71 72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \ 73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \ 74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \ 75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \ 76 *(pchar) = HIBYTE(HIWORD(uint32))) 77 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 static inline void align_length( ULONG *len, unsigned int align ) 96 { 97 *len = (*len + align - 1) & ~(align - 1); 98 } 99 100 static inline void align_pointer( unsigned char **ptr, unsigned int align ) 101 { 102 ULONG_PTR mask = align - 1; 103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask); 104 } 105 106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align ) 107 { 108 ULONG_PTR mask = align - 1; 109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask ); 110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask); 111 } 112 113 #define STD_OVERFLOW_CHECK(_Msg) do { \ 114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \ 115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \ 116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \ 117 } while (0) 118 119 #define NDR_POINTER_ID_BASE 0x20000 120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4) 121 #define NDR_TABLE_SIZE 128 122 #define NDR_TABLE_MASK 127 123 124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL)) 125 126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); 128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 131 132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); 135 136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING); 137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 140 141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 142 143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 144 unsigned char *pMemory, 145 PFORMAT_STRING pFormat, 146 PFORMAT_STRING pPointer); 147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, 148 unsigned char *pMemory, 149 PFORMAT_STRING pFormat, 150 PFORMAT_STRING pPointer); 151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 152 unsigned char *pMemory, 153 PFORMAT_STRING pFormat, 154 PFORMAT_STRING pPointer, 155 unsigned char fMustAlloc); 156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 157 PFORMAT_STRING pFormat, 158 PFORMAT_STRING pPointer); 159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, 160 unsigned char *pMemory, 161 PFORMAT_STRING pFormat, 162 PFORMAT_STRING pPointer); 163 164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { 165 0, 166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 170 /* 0x10 */ 171 NdrBaseTypeMarshall, 172 /* 0x11 */ 173 NdrPointerMarshall, NdrPointerMarshall, 174 NdrPointerMarshall, NdrPointerMarshall, 175 /* 0x15 */ 176 NdrSimpleStructMarshall, NdrSimpleStructMarshall, 177 NdrConformantStructMarshall, NdrConformantStructMarshall, 178 NdrConformantVaryingStructMarshall, 179 NdrComplexStructMarshall, 180 /* 0x1b */ 181 NdrConformantArrayMarshall, 182 NdrConformantVaryingArrayMarshall, 183 NdrFixedArrayMarshall, NdrFixedArrayMarshall, 184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall, 185 NdrComplexArrayMarshall, 186 /* 0x22 */ 187 NdrConformantStringMarshall, 0, 0, 188 NdrConformantStringMarshall, 189 NdrNonConformantStringMarshall, 0, 0, 0, 190 /* 0x2a */ 191 NdrEncapsulatedUnionMarshall, 192 NdrNonEncapsulatedUnionMarshall, 193 NdrByteCountPointerMarshall, 194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall, 195 /* 0x2f */ 196 NdrInterfacePointerMarshall, 197 /* 0x30 */ 198 NdrContextHandleMarshall, 199 /* 0xb1 */ 200 0, 0, 0, 201 NdrUserMarshalMarshall, 202 0, 0, 203 /* 0xb7 */ 204 NdrRangeMarshall, 205 NdrBaseTypeMarshall, 206 NdrBaseTypeMarshall 207 }; 208 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { 209 0, 210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 212 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 213 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 214 /* 0x10 */ 215 NdrBaseTypeUnmarshall, 216 /* 0x11 */ 217 NdrPointerUnmarshall, NdrPointerUnmarshall, 218 NdrPointerUnmarshall, NdrPointerUnmarshall, 219 /* 0x15 */ 220 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall, 221 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall, 222 NdrConformantVaryingStructUnmarshall, 223 NdrComplexStructUnmarshall, 224 /* 0x1b */ 225 NdrConformantArrayUnmarshall, 226 NdrConformantVaryingArrayUnmarshall, 227 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall, 228 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall, 229 NdrComplexArrayUnmarshall, 230 /* 0x22 */ 231 NdrConformantStringUnmarshall, 0, 0, 232 NdrConformantStringUnmarshall, 233 NdrNonConformantStringUnmarshall, 0, 0, 0, 234 /* 0x2a */ 235 NdrEncapsulatedUnionUnmarshall, 236 NdrNonEncapsulatedUnionUnmarshall, 237 NdrByteCountPointerUnmarshall, 238 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall, 239 /* 0x2f */ 240 NdrInterfacePointerUnmarshall, 241 /* 0x30 */ 242 NdrContextHandleUnmarshall, 243 /* 0xb1 */ 244 0, 0, 0, 245 NdrUserMarshalUnmarshall, 246 0, 0, 247 /* 0xb7 */ 248 NdrRangeUnmarshall, 249 NdrBaseTypeUnmarshall, 250 NdrBaseTypeUnmarshall 251 }; 252 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { 253 0, 254 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 255 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 256 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 257 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 258 /* 0x10 */ 259 NdrBaseTypeBufferSize, 260 /* 0x11 */ 261 NdrPointerBufferSize, NdrPointerBufferSize, 262 NdrPointerBufferSize, NdrPointerBufferSize, 263 /* 0x15 */ 264 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize, 265 NdrConformantStructBufferSize, NdrConformantStructBufferSize, 266 NdrConformantVaryingStructBufferSize, 267 NdrComplexStructBufferSize, 268 /* 0x1b */ 269 NdrConformantArrayBufferSize, 270 NdrConformantVaryingArrayBufferSize, 271 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize, 272 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize, 273 NdrComplexArrayBufferSize, 274 /* 0x22 */ 275 NdrConformantStringBufferSize, 0, 0, 276 NdrConformantStringBufferSize, 277 NdrNonConformantStringBufferSize, 0, 0, 0, 278 /* 0x2a */ 279 NdrEncapsulatedUnionBufferSize, 280 NdrNonEncapsulatedUnionBufferSize, 281 NdrByteCountPointerBufferSize, 282 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize, 283 /* 0x2f */ 284 NdrInterfacePointerBufferSize, 285 /* 0x30 */ 286 NdrContextHandleBufferSize, 287 /* 0xb1 */ 288 0, 0, 0, 289 NdrUserMarshalBufferSize, 290 0, 0, 291 /* 0xb7 */ 292 NdrRangeBufferSize, 293 NdrBaseTypeBufferSize, 294 NdrBaseTypeBufferSize 295 }; 296 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { 297 0, 298 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 299 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 300 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 301 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 302 /* 0x10 */ 303 NdrBaseTypeMemorySize, 304 /* 0x11 */ 305 NdrPointerMemorySize, NdrPointerMemorySize, 306 NdrPointerMemorySize, NdrPointerMemorySize, 307 /* 0x15 */ 308 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize, 309 NdrConformantStructMemorySize, NdrConformantStructMemorySize, 310 NdrConformantVaryingStructMemorySize, 311 NdrComplexStructMemorySize, 312 /* 0x1b */ 313 NdrConformantArrayMemorySize, 314 NdrConformantVaryingArrayMemorySize, 315 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize, 316 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize, 317 NdrComplexArrayMemorySize, 318 /* 0x22 */ 319 NdrConformantStringMemorySize, 0, 0, 320 NdrConformantStringMemorySize, 321 NdrNonConformantStringMemorySize, 0, 0, 0, 322 /* 0x2a */ 323 NdrEncapsulatedUnionMemorySize, 324 NdrNonEncapsulatedUnionMemorySize, 325 NdrByteCountPointerMemorySize, 326 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize, 327 /* 0x2f */ 328 NdrInterfacePointerMemorySize, 329 /* 0x30 */ 330 0, 331 /* 0xb1 */ 332 0, 0, 0, 333 NdrUserMarshalMemorySize, 334 0, 0, 335 /* 0xb7 */ 336 NdrRangeMemorySize, 337 NdrBaseTypeMemorySize, 338 NdrBaseTypeMemorySize 339 }; 340 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { 341 0, 342 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 343 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 344 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 345 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 346 /* 0x10 */ 347 NdrBaseTypeFree, 348 /* 0x11 */ 349 NdrPointerFree, NdrPointerFree, 350 NdrPointerFree, NdrPointerFree, 351 /* 0x15 */ 352 NdrSimpleStructFree, NdrSimpleStructFree, 353 NdrConformantStructFree, NdrConformantStructFree, 354 NdrConformantVaryingStructFree, 355 NdrComplexStructFree, 356 /* 0x1b */ 357 NdrConformantArrayFree, 358 NdrConformantVaryingArrayFree, 359 NdrFixedArrayFree, NdrFixedArrayFree, 360 NdrVaryingArrayFree, NdrVaryingArrayFree, 361 NdrComplexArrayFree, 362 /* 0x22 */ 363 0, 0, 0, 364 0, 0, 0, 0, 0, 365 /* 0x2a */ 366 NdrEncapsulatedUnionFree, 367 NdrNonEncapsulatedUnionFree, 368 0, 369 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree, 370 /* 0x2f */ 371 NdrInterfacePointerFree, 372 /* 0x30 */ 373 0, 374 /* 0xb1 */ 375 0, 0, 0, 376 NdrUserMarshalFree, 377 0, 0, 378 /* 0xb7 */ 379 NdrRangeFree, 380 NdrBaseTypeFree, 381 NdrBaseTypeFree 382 }; 383 384 typedef struct _NDR_MEMORY_LIST 385 { 386 ULONG magic; 387 ULONG size; 388 ULONG reserved; 389 struct _NDR_MEMORY_LIST *next; 390 } NDR_MEMORY_LIST; 391 392 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L') 393 394 /*********************************************************************** 395 * NdrAllocate [RPCRT4.@] 396 * 397 * Allocates a block of memory using pStubMsg->pfnAllocate. 398 * 399 * PARAMS 400 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure. 401 * len [I] Size of memory block to allocate. 402 * 403 * RETURNS 404 * The memory block of size len that was allocated. 405 * 406 * NOTES 407 * The memory block is always 8-byte aligned. 408 * If the function is unable to allocate memory an RPC_X_NO_MEMORY 409 * exception is raised. 410 */ 411 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len) 412 { 413 SIZE_T aligned_len; 414 SIZE_T adjusted_len; 415 void *p; 416 NDR_MEMORY_LIST *mem_list; 417 418 aligned_len = (len + 7) & ~7; 419 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST); 420 /* check for overflow */ 421 if (adjusted_len < len) 422 { 423 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len); 424 RpcRaiseException(RPC_X_BAD_STUB_DATA); 425 } 426 427 p = pStubMsg->pfnAllocate(adjusted_len); 428 if (!p) RpcRaiseException(RPC_X_NO_MEMORY); 429 430 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len); 431 mem_list->magic = MEML_MAGIC; 432 mem_list->size = aligned_len; 433 mem_list->reserved = 0; 434 mem_list->next = pStubMsg->pMemoryList; 435 pStubMsg->pMemoryList = mem_list; 436 437 TRACE("-- %p\n", p); 438 return p; 439 } 440 441 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer) 442 { 443 TRACE("(%p, %p)\n", pStubMsg, Pointer); 444 445 pStubMsg->pfnFree(Pointer); 446 } 447 448 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) 449 { 450 return (*(const ULONG *)pFormat != -1); 451 } 452 453 static inline PFORMAT_STRING SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg, const PFORMAT_STRING pFormat) 454 { 455 return pFormat + 4 + pStubMsg->CorrDespIncrement; 456 } 457 458 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) 459 { 460 align_pointer(&pStubMsg->Buffer, 4); 461 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd) 462 RpcRaiseException(RPC_X_BAD_STUB_DATA); 463 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 464 pStubMsg->Buffer += 4; 465 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); 466 return SkipConformance(pStubMsg, pFormat); 467 } 468 469 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue) 470 { 471 if (pFormat && !IsConformanceOrVariancePresent(pFormat)) 472 { 473 pStubMsg->Offset = 0; 474 pStubMsg->ActualCount = pStubMsg->MaxCount; 475 goto done; 476 } 477 478 align_pointer(&pStubMsg->Buffer, 4); 479 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd) 480 RpcRaiseException(RPC_X_BAD_STUB_DATA); 481 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 482 pStubMsg->Buffer += 4; 483 TRACE("offset is %d\n", pStubMsg->Offset); 484 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 485 pStubMsg->Buffer += 4; 486 TRACE("variance is %d\n", pStubMsg->ActualCount); 487 488 if ((pStubMsg->ActualCount > MaxValue) || 489 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue)) 490 { 491 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n", 492 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue); 493 RpcRaiseException(RPC_S_INVALID_BOUND); 494 return NULL; 495 } 496 497 done: 498 return SkipConformance(pStubMsg, pFormat); 499 } 500 501 /* writes the conformance value to the buffer */ 502 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg) 503 { 504 align_pointer_clear(&pStubMsg->Buffer, 4); 505 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 506 RpcRaiseException(RPC_X_BAD_STUB_DATA); 507 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); 508 pStubMsg->Buffer += 4; 509 } 510 511 /* writes the variance values to the buffer */ 512 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg) 513 { 514 align_pointer_clear(&pStubMsg->Buffer, 4); 515 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 516 RpcRaiseException(RPC_X_BAD_STUB_DATA); 517 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); 518 pStubMsg->Buffer += 4; 519 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); 520 pStubMsg->Buffer += 4; 521 } 522 523 /* requests buffer space for the conformance value */ 524 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg) 525 { 526 align_length(&pStubMsg->BufferLength, 4); 527 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength) 528 RpcRaiseException(RPC_X_BAD_STUB_DATA); 529 pStubMsg->BufferLength += 4; 530 } 531 532 /* requests buffer space for the variance values */ 533 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg) 534 { 535 align_length(&pStubMsg->BufferLength, 4); 536 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength) 537 RpcRaiseException(RPC_X_BAD_STUB_DATA); 538 pStubMsg->BufferLength += 8; 539 } 540 541 PFORMAT_STRING ComputeConformanceOrVariance( 542 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, 543 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount) 544 { 545 BYTE dtype = pFormat[0] & 0xf; 546 short ofs = *(const short *)&pFormat[2]; 547 LPVOID ptr = NULL; 548 ULONG_PTR data = 0; 549 550 if (!IsConformanceOrVariancePresent(pFormat)) { 551 /* null descriptor */ 552 *pCount = def; 553 goto finish_conf; 554 } 555 556 switch (pFormat[0] & 0xf0) { 557 case RPC_FC_NORMAL_CONFORMANCE: 558 TRACE("normal conformance, ofs=%d\n", ofs); 559 ptr = pMemory; 560 break; 561 case RPC_FC_POINTER_CONFORMANCE: 562 TRACE("pointer conformance, ofs=%d\n", ofs); 563 ptr = pStubMsg->Memory; 564 break; 565 case RPC_FC_TOP_LEVEL_CONFORMANCE: 566 TRACE("toplevel conformance, ofs=%d\n", ofs); 567 if (pStubMsg->StackTop) { 568 ptr = pStubMsg->StackTop; 569 } 570 else { 571 /* -Os mode, *pCount is already set */ 572 goto finish_conf; 573 } 574 break; 575 case RPC_FC_CONSTANT_CONFORMANCE: 576 data = ofs | ((DWORD)pFormat[1] << 16); 577 TRACE("constant conformance, val=%ld\n", data); 578 *pCount = data; 579 goto finish_conf; 580 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE: 581 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs); 582 if (pStubMsg->StackTop) { 583 ptr = pStubMsg->StackTop; 584 } 585 else { 586 /* ? */ 587 goto done_conf_grab; 588 } 589 break; 590 default: 591 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0); 592 goto finish_conf; 593 } 594 595 switch (pFormat[1]) { 596 case RPC_FC_DEREFERENCE: 597 ptr = *(LPVOID*)((char *)ptr + ofs); 598 break; 599 case RPC_FC_CALLBACK: 600 { 601 unsigned char *old_stack_top = pStubMsg->StackTop; 602 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount; 603 604 pStubMsg->StackTop = ptr; 605 606 /* ofs is index into StubDesc->apfnExprEval */ 607 TRACE("callback conformance into apfnExprEval[%d]\n", ofs); 608 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg); 609 610 pStubMsg->StackTop = old_stack_top; 611 612 /* the callback function always stores the computed value in MaxCount */ 613 max_count = pStubMsg->MaxCount; 614 pStubMsg->MaxCount = old_max_count; 615 *pCount = max_count; 616 goto finish_conf; 617 } 618 default: 619 ptr = (char *)ptr + ofs; 620 break; 621 } 622 623 switch (dtype) { 624 case RPC_FC_LONG: 625 case RPC_FC_ULONG: 626 data = *(DWORD*)ptr; 627 break; 628 case RPC_FC_SHORT: 629 data = *(SHORT*)ptr; 630 break; 631 case RPC_FC_USHORT: 632 data = *(USHORT*)ptr; 633 break; 634 case RPC_FC_CHAR: 635 case RPC_FC_SMALL: 636 data = *(CHAR*)ptr; 637 break; 638 case RPC_FC_BYTE: 639 case RPC_FC_USMALL: 640 data = *(UCHAR*)ptr; 641 break; 642 case RPC_FC_HYPER: 643 data = *(ULONGLONG *)ptr; 644 break; 645 default: 646 FIXME("unknown conformance data type %x\n", dtype); 647 goto done_conf_grab; 648 } 649 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data); 650 651 done_conf_grab: 652 switch (pFormat[1]) { 653 case RPC_FC_DEREFERENCE: /* already handled */ 654 case 0: /* no op */ 655 *pCount = data; 656 break; 657 case RPC_FC_ADD_1: 658 *pCount = data + 1; 659 break; 660 case RPC_FC_SUB_1: 661 *pCount = data - 1; 662 break; 663 case RPC_FC_MULT_2: 664 *pCount = data * 2; 665 break; 666 case RPC_FC_DIV_2: 667 *pCount = data / 2; 668 break; 669 default: 670 FIXME("unknown conformance op %d\n", pFormat[1]); 671 goto finish_conf; 672 } 673 674 finish_conf: 675 TRACE("resulting conformance is %ld\n", *pCount); 676 677 return SkipConformance(pStubMsg, pFormat); 678 } 679 680 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 681 { 682 return SkipConformance( pStubMsg, pFormat ); 683 } 684 685 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if 686 * the result overflows 32-bits */ 687 static inline ULONG safe_multiply(ULONG a, ULONG b) 688 { 689 ULONGLONG ret = (ULONGLONG)a * b; 690 if (ret > 0xffffffff) 691 { 692 RpcRaiseException(RPC_S_INVALID_BOUND); 693 return 0; 694 } 695 return ret; 696 } 697 698 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) 699 { 700 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 701 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) 702 RpcRaiseException(RPC_X_BAD_STUB_DATA); 703 pStubMsg->Buffer += size; 704 } 705 706 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) 707 { 708 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */ 709 { 710 ERR("buffer length overflow - BufferLength = %u, size = %u\n", 711 pStubMsg->BufferLength, size); 712 RpcRaiseException(RPC_X_BAD_STUB_DATA); 713 } 714 pStubMsg->BufferLength += size; 715 } 716 717 /* copies data from the buffer, checking that there is enough data in the buffer 718 * to do so */ 719 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size) 720 { 721 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 722 (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) 723 { 724 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", 725 pStubMsg->Buffer, pStubMsg->BufferEnd, size); 726 RpcRaiseException(RPC_X_BAD_STUB_DATA); 727 } 728 if (p == pStubMsg->Buffer) 729 ERR("pointer is the same as the buffer\n"); 730 memcpy(p, pStubMsg->Buffer, size); 731 pStubMsg->Buffer += size; 732 } 733 734 /* copies data to the buffer, checking that there is enough space to do so */ 735 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size) 736 { 737 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 738 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) 739 { 740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", 741 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength, 742 size); 743 RpcRaiseException(RPC_X_BAD_STUB_DATA); 744 } 745 memcpy(pStubMsg->Buffer, p, size); 746 pStubMsg->Buffer += size; 747 } 748 749 /* verify that string data sitting in the buffer is valid and safe to 750 * unmarshall */ 751 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize) 752 { 753 ULONG i; 754 755 /* verify the buffer is safe to access */ 756 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || 757 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) 758 { 759 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, 760 pStubMsg->BufferEnd, pStubMsg->Buffer); 761 RpcRaiseException(RPC_X_BAD_STUB_DATA); 762 } 763 764 /* strings must always have null terminating bytes */ 765 if (bufsize < esize) 766 { 767 ERR("invalid string length of %d\n", bufsize / esize); 768 RpcRaiseException(RPC_S_INVALID_BOUND); 769 } 770 771 for (i = bufsize - esize; i < bufsize; i++) 772 if (pStubMsg->Buffer[i] != 0) 773 { 774 ERR("string not null-terminated at byte position %d, data is 0x%x\n", 775 i, pStubMsg->Buffer[i]); 776 RpcRaiseException(RPC_S_INVALID_BOUND); 777 } 778 } 779 780 static inline void dump_pointer_attr(unsigned char attr) 781 { 782 if (attr & RPC_FC_P_ALLOCALLNODES) 783 TRACE(" RPC_FC_P_ALLOCALLNODES"); 784 if (attr & RPC_FC_P_DONTFREE) 785 TRACE(" RPC_FC_P_DONTFREE"); 786 if (attr & RPC_FC_P_ONSTACK) 787 TRACE(" RPC_FC_P_ONSTACK"); 788 if (attr & RPC_FC_P_SIMPLEPOINTER) 789 TRACE(" RPC_FC_P_SIMPLEPOINTER"); 790 if (attr & RPC_FC_P_DEREF) 791 TRACE(" RPC_FC_P_DEREF"); 792 TRACE("\n"); 793 } 794 795 /*********************************************************************** 796 * PointerMarshall [internal] 797 */ 798 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 799 unsigned char *Buffer, 800 unsigned char *Pointer, 801 PFORMAT_STRING pFormat) 802 { 803 unsigned type = pFormat[0], attr = pFormat[1]; 804 PFORMAT_STRING desc; 805 NDR_MARSHALL m; 806 ULONG pointer_id; 807 BOOL pointer_needs_marshaling; 808 809 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat); 810 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 811 pFormat += 2; 812 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 813 else desc = pFormat + *(const SHORT*)pFormat; 814 815 switch (type) { 816 case RPC_FC_RP: /* ref pointer (always non-null) */ 817 if (!Pointer) 818 { 819 ERR("NULL ref pointer is not allowed\n"); 820 RpcRaiseException(RPC_X_NULL_REF_POINTER); 821 } 822 pointer_needs_marshaling = TRUE; 823 break; 824 case RPC_FC_UP: /* unique pointer */ 825 case RPC_FC_OP: /* object pointer - same as unique here */ 826 if (Pointer) 827 pointer_needs_marshaling = TRUE; 828 else 829 pointer_needs_marshaling = FALSE; 830 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0; 831 TRACE("writing 0x%08x to buffer\n", pointer_id); 832 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); 833 break; 834 case RPC_FC_FP: 835 pointer_needs_marshaling = !NdrFullPointerQueryPointer( 836 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id); 837 TRACE("writing 0x%08x to buffer\n", pointer_id); 838 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); 839 break; 840 default: 841 FIXME("unhandled ptr type=%02x\n", type); 842 RpcRaiseException(RPC_X_BAD_STUB_DATA); 843 return; 844 } 845 846 TRACE("calling marshaller for type 0x%x\n", (int)*desc); 847 848 if (pointer_needs_marshaling) { 849 if (attr & RPC_FC_P_DEREF) { 850 Pointer = *(unsigned char**)Pointer; 851 TRACE("deref => %p\n", Pointer); 852 } 853 m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 854 if (m) m(pStubMsg, Pointer, desc); 855 else FIXME("no marshaller for data type=%02x\n", *desc); 856 } 857 858 STD_OVERFLOW_CHECK(pStubMsg); 859 } 860 861 /*********************************************************************** 862 * PointerUnmarshall [internal] 863 */ 864 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 865 unsigned char *Buffer, 866 unsigned char **pPointer, 867 unsigned char *pSrcPointer, 868 PFORMAT_STRING pFormat, 869 unsigned char fMustAlloc) 870 { 871 unsigned type = pFormat[0], attr = pFormat[1]; 872 PFORMAT_STRING desc; 873 NDR_UNMARSHALL m; 874 DWORD pointer_id = 0; 875 BOOL pointer_needs_unmarshaling; 876 877 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc); 878 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 879 pFormat += 2; 880 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 881 else desc = pFormat + *(const SHORT*)pFormat; 882 883 switch (type) { 884 case RPC_FC_RP: /* ref pointer (always non-null) */ 885 pointer_needs_unmarshaling = TRUE; 886 break; 887 case RPC_FC_UP: /* unique pointer */ 888 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 889 TRACE("pointer_id is 0x%08x\n", pointer_id); 890 if (pointer_id) 891 pointer_needs_unmarshaling = TRUE; 892 else { 893 *pPointer = NULL; 894 pointer_needs_unmarshaling = FALSE; 895 } 896 break; 897 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ 898 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 899 TRACE("pointer_id is 0x%08x\n", pointer_id); 900 if (!fMustAlloc && pSrcPointer) 901 { 902 FIXME("free object pointer %p\n", pSrcPointer); 903 fMustAlloc = TRUE; 904 } 905 if (pointer_id) 906 pointer_needs_unmarshaling = TRUE; 907 else 908 { 909 *pPointer = NULL; 910 pointer_needs_unmarshaling = FALSE; 911 } 912 break; 913 case RPC_FC_FP: 914 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 915 TRACE("pointer_id is 0x%08x\n", pointer_id); 916 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId( 917 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer); 918 break; 919 default: 920 FIXME("unhandled ptr type=%02x\n", type); 921 RpcRaiseException(RPC_X_BAD_STUB_DATA); 922 return; 923 } 924 925 if (pointer_needs_unmarshaling) { 926 unsigned char **current_ptr = pPointer; 927 if (pStubMsg->IsClient) { 928 TRACE("client\n"); 929 /* if we aren't forcing allocation of memory then try to use the existing 930 * (source) pointer to unmarshall the data into so that [in,out] 931 * parameters behave correctly. it doesn't matter if the parameter is 932 * [out] only since in that case the pointer will be NULL. we force 933 * allocation when the source pointer is NULL here instead of in the type 934 * unmarshalling routine for the benefit of the deref code below */ 935 if (!fMustAlloc) { 936 if (pSrcPointer) { 937 TRACE("setting *pPointer to %p\n", pSrcPointer); 938 *pPointer = pSrcPointer; 939 } else 940 fMustAlloc = TRUE; 941 } 942 } else { 943 TRACE("server\n"); 944 /* the memory in a stub is never initialised, so we have to work out here 945 * whether we have to initialise it so we can use the optimisation of 946 * setting the pointer to the buffer, if possible, or set fMustAlloc to 947 * TRUE. */ 948 if (attr & RPC_FC_P_DEREF) { 949 fMustAlloc = TRUE; 950 } else { 951 *current_ptr = NULL; 952 } 953 } 954 955 if (attr & RPC_FC_P_ALLOCALLNODES) 956 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n"); 957 958 if (attr & RPC_FC_P_DEREF) { 959 if (fMustAlloc) { 960 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); 961 *pPointer = base_ptr_val; 962 current_ptr = (unsigned char **)base_ptr_val; 963 } else 964 current_ptr = *(unsigned char***)current_ptr; 965 TRACE("deref => %p\n", current_ptr); 966 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE; 967 } 968 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 969 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc); 970 else FIXME("no unmarshaller for data type=%02x\n", *desc); 971 972 if (type == RPC_FC_FP) 973 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, 974 *pPointer); 975 } 976 977 TRACE("pointer=%p\n", *pPointer); 978 } 979 980 /*********************************************************************** 981 * PointerBufferSize [internal] 982 */ 983 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 984 unsigned char *Pointer, 985 PFORMAT_STRING pFormat) 986 { 987 unsigned type = pFormat[0], attr = pFormat[1]; 988 PFORMAT_STRING desc; 989 NDR_BUFFERSIZE m; 990 BOOL pointer_needs_sizing; 991 ULONG pointer_id; 992 993 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); 994 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 995 pFormat += 2; 996 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 997 else desc = pFormat + *(const SHORT*)pFormat; 998 999 switch (type) { 1000 case RPC_FC_RP: /* ref pointer (always non-null) */ 1001 if (!Pointer) 1002 { 1003 ERR("NULL ref pointer is not allowed\n"); 1004 RpcRaiseException(RPC_X_NULL_REF_POINTER); 1005 } 1006 break; 1007 case RPC_FC_OP: 1008 case RPC_FC_UP: 1009 /* NULL pointer has no further representation */ 1010 if (!Pointer) 1011 return; 1012 break; 1013 case RPC_FC_FP: 1014 pointer_needs_sizing = !NdrFullPointerQueryPointer( 1015 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id); 1016 if (!pointer_needs_sizing) 1017 return; 1018 break; 1019 default: 1020 FIXME("unhandled ptr type=%02x\n", type); 1021 RpcRaiseException(RPC_X_BAD_STUB_DATA); 1022 return; 1023 } 1024 1025 if (attr & RPC_FC_P_DEREF) { 1026 Pointer = *(unsigned char**)Pointer; 1027 TRACE("deref => %p\n", Pointer); 1028 } 1029 1030 m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 1031 if (m) m(pStubMsg, Pointer, desc); 1032 else FIXME("no buffersizer for data type=%02x\n", *desc); 1033 } 1034 1035 /*********************************************************************** 1036 * PointerMemorySize [internal] 1037 */ 1038 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 1039 unsigned char *Buffer, PFORMAT_STRING pFormat) 1040 { 1041 unsigned type = pFormat[0], attr = pFormat[1]; 1042 PFORMAT_STRING desc; 1043 NDR_MEMORYSIZE m; 1044 DWORD pointer_id = 0; 1045 BOOL pointer_needs_sizing; 1046 1047 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat); 1048 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 1049 pFormat += 2; 1050 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 1051 else desc = pFormat + *(const SHORT*)pFormat; 1052 1053 switch (type) { 1054 case RPC_FC_RP: /* ref pointer (always non-null) */ 1055 pointer_needs_sizing = TRUE; 1056 break; 1057 case RPC_FC_UP: /* unique pointer */ 1058 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ 1059 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 1060 TRACE("pointer_id is 0x%08x\n", pointer_id); 1061 if (pointer_id) 1062 pointer_needs_sizing = TRUE; 1063 else 1064 pointer_needs_sizing = FALSE; 1065 break; 1066 case RPC_FC_FP: 1067 { 1068 void *pointer; 1069 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 1070 TRACE("pointer_id is 0x%08x\n", pointer_id); 1071 pointer_needs_sizing = !NdrFullPointerQueryRefId( 1072 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer); 1073 break; 1074 } 1075 default: 1076 FIXME("unhandled ptr type=%02x\n", type); 1077 RpcRaiseException(RPC_X_BAD_STUB_DATA); 1078 return 0; 1079 } 1080 1081 if (attr & RPC_FC_P_DEREF) { 1082 align_length(&pStubMsg->MemorySize, sizeof(void*)); 1083 pStubMsg->MemorySize += sizeof(void*); 1084 TRACE("deref\n"); 1085 } 1086 1087 if (pointer_needs_sizing) { 1088 m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; 1089 if (m) m(pStubMsg, desc); 1090 else FIXME("no memorysizer for data type=%02x\n", *desc); 1091 } 1092 1093 return pStubMsg->MemorySize; 1094 } 1095 1096 /*********************************************************************** 1097 * PointerFree [internal] 1098 */ 1099 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg, 1100 unsigned char *Pointer, 1101 PFORMAT_STRING pFormat) 1102 { 1103 unsigned type = pFormat[0], attr = pFormat[1]; 1104 PFORMAT_STRING desc; 1105 NDR_FREE m; 1106 unsigned char *current_pointer = Pointer; 1107 1108 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); 1109 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 1110 if (attr & RPC_FC_P_DONTFREE) return; 1111 pFormat += 2; 1112 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 1113 else desc = pFormat + *(const SHORT*)pFormat; 1114 1115 if (!Pointer) return; 1116 1117 if (type == RPC_FC_FP) { 1118 int pointer_needs_freeing = NdrFullPointerFree( 1119 pStubMsg->FullPtrXlatTables, Pointer); 1120 if (!pointer_needs_freeing) 1121 return; 1122 } 1123 1124 if (attr & RPC_FC_P_DEREF) { 1125 current_pointer = *(unsigned char**)Pointer; 1126 TRACE("deref => %p\n", current_pointer); 1127 } 1128 1129 m = NdrFreer[*desc & NDR_TABLE_MASK]; 1130 if (m) m(pStubMsg, current_pointer, desc); 1131 1132 /* this check stops us from trying to free buffer memory. we don't have to 1133 * worry about clients, since they won't call this function. 1134 * we don't have to check for the buffer being reallocated because 1135 * BufferStart and BufferEnd won't be reset when allocating memory for 1136 * sending the response. we don't have to check for the new buffer here as 1137 * it won't be used a type memory, only for buffer memory */ 1138 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd) 1139 goto notfree; 1140 1141 if (attr & RPC_FC_P_ONSTACK) { 1142 TRACE("not freeing stack ptr %p\n", Pointer); 1143 return; 1144 } 1145 TRACE("freeing %p\n", Pointer); 1146 NdrFree(pStubMsg, Pointer); 1147 return; 1148 notfree: 1149 TRACE("not freeing %p\n", Pointer); 1150 } 1151 1152 /*********************************************************************** 1153 * EmbeddedPointerMarshall 1154 */ 1155 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 1156 unsigned char *pMemory, 1157 PFORMAT_STRING pFormat) 1158 { 1159 unsigned char *Mark = pStubMsg->BufferMark; 1160 unsigned rep, count, stride; 1161 unsigned i; 1162 unsigned char *saved_buffer = NULL; 1163 1164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1165 1166 if (*pFormat != RPC_FC_PP) return NULL; 1167 pFormat += 2; 1168 1169 if (pStubMsg->PointerBufferMark) 1170 { 1171 saved_buffer = pStubMsg->Buffer; 1172 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 1173 pStubMsg->PointerBufferMark = NULL; 1174 } 1175 1176 while (pFormat[0] != RPC_FC_END) { 1177 switch (pFormat[0]) { 1178 default: 1179 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]); 1180 /* fallthrough */ 1181 case RPC_FC_NO_REPEAT: 1182 rep = 1; 1183 stride = 0; 1184 count = 1; 1185 pFormat += 2; 1186 break; 1187 case RPC_FC_FIXED_REPEAT: 1188 rep = *(const WORD*)&pFormat[2]; 1189 stride = *(const WORD*)&pFormat[4]; 1190 count = *(const WORD*)&pFormat[8]; 1191 pFormat += 10; 1192 break; 1193 case RPC_FC_VARIABLE_REPEAT: 1194 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 1195 stride = *(const WORD*)&pFormat[2]; 1196 count = *(const WORD*)&pFormat[6]; 1197 pFormat += 8; 1198 break; 1199 } 1200 for (i = 0; i < rep; i++) { 1201 PFORMAT_STRING info = pFormat; 1202 unsigned char *membase = pMemory + (i * stride); 1203 unsigned char *bufbase = Mark + (i * stride); 1204 unsigned u; 1205 1206 for (u=0; u<count; u++,info+=8) { 1207 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 1208 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 1209 unsigned char *saved_memory = pStubMsg->Memory; 1210 1211 pStubMsg->Memory = membase; 1212 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); 1213 pStubMsg->Memory = saved_memory; 1214 } 1215 } 1216 pFormat += 8 * count; 1217 } 1218 1219 if (saved_buffer) 1220 { 1221 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 1222 pStubMsg->Buffer = saved_buffer; 1223 } 1224 1225 STD_OVERFLOW_CHECK(pStubMsg); 1226 1227 return NULL; 1228 } 1229 1230 /*********************************************************************** 1231 * EmbeddedPointerUnmarshall 1232 */ 1233 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 1234 unsigned char *pDstBuffer, 1235 unsigned char *pSrcMemoryPtrs, 1236 PFORMAT_STRING pFormat, 1237 unsigned char fMustAlloc) 1238 { 1239 unsigned char *Mark = pStubMsg->BufferMark; 1240 unsigned rep, count, stride; 1241 unsigned i; 1242 unsigned char *saved_buffer = NULL; 1243 1244 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc); 1245 1246 if (*pFormat != RPC_FC_PP) return NULL; 1247 pFormat += 2; 1248 1249 if (pStubMsg->PointerBufferMark) 1250 { 1251 saved_buffer = pStubMsg->Buffer; 1252 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 1253 pStubMsg->PointerBufferMark = NULL; 1254 } 1255 1256 while (pFormat[0] != RPC_FC_END) { 1257 TRACE("pFormat[0] = 0x%x\n", pFormat[0]); 1258 switch (pFormat[0]) { 1259 default: 1260 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]); 1261 /* fallthrough */ 1262 case RPC_FC_NO_REPEAT: 1263 rep = 1; 1264 stride = 0; 1265 count = 1; 1266 pFormat += 2; 1267 break; 1268 case RPC_FC_FIXED_REPEAT: 1269 rep = *(const WORD*)&pFormat[2]; 1270 stride = *(const WORD*)&pFormat[4]; 1271 count = *(const WORD*)&pFormat[8]; 1272 pFormat += 10; 1273 break; 1274 case RPC_FC_VARIABLE_REPEAT: 1275 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 1276 stride = *(const WORD*)&pFormat[2]; 1277 count = *(const WORD*)&pFormat[6]; 1278 pFormat += 8; 1279 break; 1280 } 1281 for (i = 0; i < rep; i++) { 1282 PFORMAT_STRING info = pFormat; 1283 unsigned char *bufdstbase = pDstBuffer + (i * stride); 1284 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride); 1285 unsigned char *bufbase = Mark + (i * stride); 1286 unsigned u; 1287 1288 for (u=0; u<count; u++,info+=8) { 1289 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]); 1290 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]); 1291 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 1292 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc); 1293 } 1294 } 1295 pFormat += 8 * count; 1296 } 1297 1298 if (saved_buffer) 1299 { 1300 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 1301 pStubMsg->Buffer = saved_buffer; 1302 } 1303 1304 return NULL; 1305 } 1306 1307 /*********************************************************************** 1308 * EmbeddedPointerBufferSize 1309 */ 1310 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 1311 unsigned char *pMemory, 1312 PFORMAT_STRING pFormat) 1313 { 1314 unsigned rep, count, stride; 1315 unsigned i; 1316 ULONG saved_buffer_length = 0; 1317 1318 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1319 1320 if (pStubMsg->IgnoreEmbeddedPointers) return; 1321 1322 if (*pFormat != RPC_FC_PP) return; 1323 pFormat += 2; 1324 1325 if (pStubMsg->PointerLength) 1326 { 1327 saved_buffer_length = pStubMsg->BufferLength; 1328 pStubMsg->BufferLength = pStubMsg->PointerLength; 1329 pStubMsg->PointerLength = 0; 1330 } 1331 1332 while (pFormat[0] != RPC_FC_END) { 1333 switch (pFormat[0]) { 1334 default: 1335 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]); 1336 /* fallthrough */ 1337 case RPC_FC_NO_REPEAT: 1338 rep = 1; 1339 stride = 0; 1340 count = 1; 1341 pFormat += 2; 1342 break; 1343 case RPC_FC_FIXED_REPEAT: 1344 rep = *(const WORD*)&pFormat[2]; 1345 stride = *(const WORD*)&pFormat[4]; 1346 count = *(const WORD*)&pFormat[8]; 1347 pFormat += 10; 1348 break; 1349 case RPC_FC_VARIABLE_REPEAT: 1350 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 1351 stride = *(const WORD*)&pFormat[2]; 1352 count = *(const WORD*)&pFormat[6]; 1353 pFormat += 8; 1354 break; 1355 } 1356 for (i = 0; i < rep; i++) { 1357 PFORMAT_STRING info = pFormat; 1358 unsigned char *membase = pMemory + (i * stride); 1359 unsigned u; 1360 1361 for (u=0; u<count; u++,info+=8) { 1362 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 1363 unsigned char *saved_memory = pStubMsg->Memory; 1364 1365 pStubMsg->Memory = membase; 1366 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4); 1367 pStubMsg->Memory = saved_memory; 1368 } 1369 } 1370 pFormat += 8 * count; 1371 } 1372 1373 if (saved_buffer_length) 1374 { 1375 pStubMsg->PointerLength = pStubMsg->BufferLength; 1376 pStubMsg->BufferLength = saved_buffer_length; 1377 } 1378 } 1379 1380 /*********************************************************************** 1381 * EmbeddedPointerMemorySize [internal] 1382 */ 1383 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 1384 PFORMAT_STRING pFormat) 1385 { 1386 unsigned char *Mark = pStubMsg->BufferMark; 1387 unsigned rep, count, stride; 1388 unsigned i; 1389 unsigned char *saved_buffer = NULL; 1390 1391 TRACE("(%p,%p)\n", pStubMsg, pFormat); 1392 1393 if (pStubMsg->IgnoreEmbeddedPointers) return 0; 1394 1395 if (pStubMsg->PointerBufferMark) 1396 { 1397 saved_buffer = pStubMsg->Buffer; 1398 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 1399 pStubMsg->PointerBufferMark = NULL; 1400 } 1401 1402 if (*pFormat != RPC_FC_PP) return 0; 1403 pFormat += 2; 1404 1405 while (pFormat[0] != RPC_FC_END) { 1406 switch (pFormat[0]) { 1407 default: 1408 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]); 1409 /* fallthrough */ 1410 case RPC_FC_NO_REPEAT: 1411 rep = 1; 1412 stride = 0; 1413 count = 1; 1414 pFormat += 2; 1415 break; 1416 case RPC_FC_FIXED_REPEAT: 1417 rep = *(const WORD*)&pFormat[2]; 1418 stride = *(const WORD*)&pFormat[4]; 1419 count = *(const WORD*)&pFormat[8]; 1420 pFormat += 10; 1421 break; 1422 case RPC_FC_VARIABLE_REPEAT: 1423 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 1424 stride = *(const WORD*)&pFormat[2]; 1425 count = *(const WORD*)&pFormat[6]; 1426 pFormat += 8; 1427 break; 1428 } 1429 for (i = 0; i < rep; i++) { 1430 PFORMAT_STRING info = pFormat; 1431 unsigned char *bufbase = Mark + (i * stride); 1432 unsigned u; 1433 for (u=0; u<count; u++,info+=8) { 1434 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 1435 PointerMemorySize(pStubMsg, bufptr, info+4); 1436 } 1437 } 1438 pFormat += 8 * count; 1439 } 1440 1441 if (saved_buffer) 1442 { 1443 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 1444 pStubMsg->Buffer = saved_buffer; 1445 } 1446 1447 return 0; 1448 } 1449 1450 /*********************************************************************** 1451 * EmbeddedPointerFree [internal] 1452 */ 1453 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 1454 unsigned char *pMemory, 1455 PFORMAT_STRING pFormat) 1456 { 1457 unsigned rep, count, stride; 1458 unsigned i; 1459 1460 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1461 if (*pFormat != RPC_FC_PP) return; 1462 pFormat += 2; 1463 1464 while (pFormat[0] != RPC_FC_END) { 1465 switch (pFormat[0]) { 1466 default: 1467 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]); 1468 /* fallthrough */ 1469 case RPC_FC_NO_REPEAT: 1470 rep = 1; 1471 stride = 0; 1472 count = 1; 1473 pFormat += 2; 1474 break; 1475 case RPC_FC_FIXED_REPEAT: 1476 rep = *(const WORD*)&pFormat[2]; 1477 stride = *(const WORD*)&pFormat[4]; 1478 count = *(const WORD*)&pFormat[8]; 1479 pFormat += 10; 1480 break; 1481 case RPC_FC_VARIABLE_REPEAT: 1482 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 1483 stride = *(const WORD*)&pFormat[2]; 1484 count = *(const WORD*)&pFormat[6]; 1485 pFormat += 8; 1486 break; 1487 } 1488 for (i = 0; i < rep; i++) { 1489 PFORMAT_STRING info = pFormat; 1490 unsigned char *membase = pMemory + (i * stride); 1491 unsigned u; 1492 1493 for (u=0; u<count; u++,info+=8) { 1494 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 1495 unsigned char *saved_memory = pStubMsg->Memory; 1496 1497 pStubMsg->Memory = membase; 1498 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4); 1499 pStubMsg->Memory = saved_memory; 1500 } 1501 } 1502 pFormat += 8 * count; 1503 } 1504 } 1505 1506 /*********************************************************************** 1507 * NdrPointerMarshall [RPCRT4.@] 1508 */ 1509 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 1510 unsigned char *pMemory, 1511 PFORMAT_STRING pFormat) 1512 { 1513 unsigned char *Buffer; 1514 1515 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1516 1517 /* Increment the buffer here instead of in PointerMarshall, 1518 * as that is used by embedded pointers which already handle the incrementing 1519 * the buffer, and shouldn't write any additional pointer data to the wire */ 1520 if (*pFormat != RPC_FC_RP) 1521 { 1522 align_pointer_clear(&pStubMsg->Buffer, 4); 1523 Buffer = pStubMsg->Buffer; 1524 safe_buffer_increment(pStubMsg, 4); 1525 } 1526 else 1527 Buffer = pStubMsg->Buffer; 1528 1529 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat); 1530 1531 return NULL; 1532 } 1533 1534 /*********************************************************************** 1535 * NdrPointerUnmarshall [RPCRT4.@] 1536 */ 1537 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 1538 unsigned char **ppMemory, 1539 PFORMAT_STRING pFormat, 1540 unsigned char fMustAlloc) 1541 { 1542 unsigned char *Buffer; 1543 1544 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 1545 1546 if (*pFormat == RPC_FC_RP) 1547 { 1548 Buffer = pStubMsg->Buffer; 1549 /* Do the NULL ref pointer check here because embedded pointers can be 1550 * NULL if the type the pointer is embedded in was allocated rather than 1551 * being passed in by the client */ 1552 if (pStubMsg->IsClient && !*ppMemory) 1553 { 1554 ERR("NULL ref pointer is not allowed\n"); 1555 RpcRaiseException(RPC_X_NULL_REF_POINTER); 1556 } 1557 } 1558 else 1559 { 1560 /* Increment the buffer here instead of in PointerUnmarshall, 1561 * as that is used by embedded pointers which already handle the incrementing 1562 * the buffer, and shouldn't read any additional pointer data from the 1563 * buffer */ 1564 align_pointer(&pStubMsg->Buffer, 4); 1565 Buffer = pStubMsg->Buffer; 1566 safe_buffer_increment(pStubMsg, 4); 1567 } 1568 1569 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc); 1570 1571 return NULL; 1572 } 1573 1574 /*********************************************************************** 1575 * NdrPointerBufferSize [RPCRT4.@] 1576 */ 1577 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 1578 unsigned char *pMemory, 1579 PFORMAT_STRING pFormat) 1580 { 1581 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1582 1583 /* Increment the buffer length here instead of in PointerBufferSize, 1584 * as that is used by embedded pointers which already handle the buffer 1585 * length, and shouldn't write anything more to the wire */ 1586 if (*pFormat != RPC_FC_RP) 1587 { 1588 align_length(&pStubMsg->BufferLength, 4); 1589 safe_buffer_length_increment(pStubMsg, 4); 1590 } 1591 1592 PointerBufferSize(pStubMsg, pMemory, pFormat); 1593 } 1594 1595 /*********************************************************************** 1596 * NdrPointerMemorySize [RPCRT4.@] 1597 */ 1598 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 1599 PFORMAT_STRING pFormat) 1600 { 1601 unsigned char *Buffer = pStubMsg->Buffer; 1602 if (*pFormat != RPC_FC_RP) 1603 { 1604 align_pointer(&pStubMsg->Buffer, 4); 1605 safe_buffer_increment(pStubMsg, 4); 1606 } 1607 align_length(&pStubMsg->MemorySize, sizeof(void *)); 1608 return PointerMemorySize(pStubMsg, Buffer, pFormat); 1609 } 1610 1611 /*********************************************************************** 1612 * NdrPointerFree [RPCRT4.@] 1613 */ 1614 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 1615 unsigned char *pMemory, 1616 PFORMAT_STRING pFormat) 1617 { 1618 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1619 PointerFree(pStubMsg, pMemory, pFormat); 1620 } 1621 1622 /*********************************************************************** 1623 * NdrSimpleTypeMarshall [RPCRT4.@] 1624 */ 1625 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, 1626 unsigned char FormatChar ) 1627 { 1628 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar); 1629 } 1630 1631 /*********************************************************************** 1632 * NdrSimpleTypeUnmarshall [RPCRT4.@] 1633 * 1634 * Unmarshall a base type. 1635 * 1636 * NOTES 1637 * Doesn't check that the buffer is long enough before copying, so the caller 1638 * should do this. 1639 */ 1640 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, 1641 unsigned char FormatChar ) 1642 { 1643 #define BASE_TYPE_UNMARSHALL(type) \ 1644 align_pointer(&pStubMsg->Buffer, sizeof(type)); \ 1645 TRACE("pMemory: %p\n", pMemory); \ 1646 *(type *)pMemory = *(type *)pStubMsg->Buffer; \ 1647 pStubMsg->Buffer += sizeof(type); 1648 1649 switch(FormatChar) 1650 { 1651 case RPC_FC_BYTE: 1652 case RPC_FC_CHAR: 1653 case RPC_FC_SMALL: 1654 case RPC_FC_USMALL: 1655 BASE_TYPE_UNMARSHALL(UCHAR); 1656 TRACE("value: 0x%02x\n", *pMemory); 1657 break; 1658 case RPC_FC_WCHAR: 1659 case RPC_FC_SHORT: 1660 case RPC_FC_USHORT: 1661 BASE_TYPE_UNMARSHALL(USHORT); 1662 TRACE("value: 0x%04x\n", *(USHORT *)pMemory); 1663 break; 1664 case RPC_FC_LONG: 1665 case RPC_FC_ULONG: 1666 case RPC_FC_ERROR_STATUS_T: 1667 case RPC_FC_ENUM32: 1668 BASE_TYPE_UNMARSHALL(ULONG); 1669 TRACE("value: 0x%08x\n", *(ULONG *)pMemory); 1670 break; 1671 case RPC_FC_FLOAT: 1672 BASE_TYPE_UNMARSHALL(float); 1673 TRACE("value: %f\n", *(float *)pMemory); 1674 break; 1675 case RPC_FC_DOUBLE: 1676 BASE_TYPE_UNMARSHALL(double); 1677 TRACE("value: %f\n", *(double *)pMemory); 1678 break; 1679 case RPC_FC_HYPER: 1680 BASE_TYPE_UNMARSHALL(ULONGLONG); 1681 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory)); 1682 break; 1683 case RPC_FC_ENUM16: 1684 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 1685 TRACE("pMemory: %p\n", pMemory); 1686 /* 16-bits on the wire, but int in memory */ 1687 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer; 1688 pStubMsg->Buffer += sizeof(USHORT); 1689 TRACE("value: 0x%08x\n", *(UINT *)pMemory); 1690 break; 1691 case RPC_FC_INT3264: 1692 align_pointer(&pStubMsg->Buffer, sizeof(INT)); 1693 /* 32-bits on the wire, but int_ptr in memory */ 1694 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer; 1695 pStubMsg->Buffer += sizeof(INT); 1696 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory); 1697 break; 1698 case RPC_FC_UINT3264: 1699 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 1700 /* 32-bits on the wire, but int_ptr in memory */ 1701 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer; 1702 pStubMsg->Buffer += sizeof(UINT); 1703 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory); 1704 break; 1705 case RPC_FC_IGNORE: 1706 break; 1707 default: 1708 FIXME("Unhandled base type: 0x%02x\n", FormatChar); 1709 } 1710 #undef BASE_TYPE_UNMARSHALL 1711 } 1712 1713 /*********************************************************************** 1714 * NdrSimpleStructMarshall [RPCRT4.@] 1715 */ 1716 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 1717 unsigned char *pMemory, 1718 PFORMAT_STRING pFormat) 1719 { 1720 unsigned size = *(const WORD*)(pFormat+2); 1721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1722 1723 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1); 1724 1725 pStubMsg->BufferMark = pStubMsg->Buffer; 1726 safe_copy_to_buffer(pStubMsg, pMemory, size); 1727 1728 if (pFormat[0] != RPC_FC_STRUCT) 1729 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4); 1730 1731 return NULL; 1732 } 1733 1734 /*********************************************************************** 1735 * NdrSimpleStructUnmarshall [RPCRT4.@] 1736 */ 1737 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 1738 unsigned char **ppMemory, 1739 PFORMAT_STRING pFormat, 1740 unsigned char fMustAlloc) 1741 { 1742 unsigned size = *(const WORD*)(pFormat+2); 1743 unsigned char *saved_buffer; 1744 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 1745 1746 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 1747 1748 if (fMustAlloc) 1749 *ppMemory = NdrAllocate(pStubMsg, size); 1750 else 1751 { 1752 if (!pStubMsg->IsClient && !*ppMemory) 1753 /* for servers, we just point straight into the RPC buffer */ 1754 *ppMemory = pStubMsg->Buffer; 1755 } 1756 1757 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 1758 safe_buffer_increment(pStubMsg, size); 1759 if (pFormat[0] == RPC_FC_PSTRUCT) 1760 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc); 1761 1762 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 1763 if (*ppMemory != saved_buffer) 1764 memcpy(*ppMemory, saved_buffer, size); 1765 1766 return NULL; 1767 } 1768 1769 /*********************************************************************** 1770 * NdrSimpleStructBufferSize [RPCRT4.@] 1771 */ 1772 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 1773 unsigned char *pMemory, 1774 PFORMAT_STRING pFormat) 1775 { 1776 unsigned size = *(const WORD*)(pFormat+2); 1777 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1778 1779 align_length(&pStubMsg->BufferLength, pFormat[1] + 1); 1780 1781 safe_buffer_length_increment(pStubMsg, size); 1782 if (pFormat[0] != RPC_FC_STRUCT) 1783 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4); 1784 } 1785 1786 /*********************************************************************** 1787 * NdrSimpleStructMemorySize [RPCRT4.@] 1788 */ 1789 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 1790 PFORMAT_STRING pFormat) 1791 { 1792 unsigned short size = *(const WORD *)(pFormat+2); 1793 1794 TRACE("(%p,%p)\n", pStubMsg, pFormat); 1795 1796 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 1797 pStubMsg->MemorySize += size; 1798 safe_buffer_increment(pStubMsg, size); 1799 1800 if (pFormat[0] != RPC_FC_STRUCT) 1801 EmbeddedPointerMemorySize(pStubMsg, pFormat+4); 1802 return pStubMsg->MemorySize; 1803 } 1804 1805 /*********************************************************************** 1806 * NdrSimpleStructFree [RPCRT4.@] 1807 */ 1808 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, 1809 unsigned char *pMemory, 1810 PFORMAT_STRING pFormat) 1811 { 1812 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 1813 if (pFormat[0] != RPC_FC_STRUCT) 1814 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4); 1815 } 1816 1817 /* Array helpers */ 1818 1819 static inline void array_compute_and_size_conformance( 1820 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 1821 PFORMAT_STRING pFormat) 1822 { 1823 DWORD count; 1824 1825 switch (fc) 1826 { 1827 case RPC_FC_CARRAY: 1828 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 1829 SizeConformance(pStubMsg); 1830 break; 1831 case RPC_FC_CVARRAY: 1832 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); 1833 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 1834 SizeConformance(pStubMsg); 1835 break; 1836 case RPC_FC_C_CSTRING: 1837 case RPC_FC_C_WSTRING: 1838 if (fc == RPC_FC_C_CSTRING) 1839 { 1840 TRACE("string=%s\n", debugstr_a((const char *)pMemory)); 1841 pStubMsg->ActualCount = strlen((const char *)pMemory)+1; 1842 } 1843 else 1844 { 1845 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); 1846 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; 1847 } 1848 1849 if (pFormat[1] == RPC_FC_STRING_SIZED) 1850 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); 1851 else 1852 pStubMsg->MaxCount = pStubMsg->ActualCount; 1853 1854 SizeConformance(pStubMsg); 1855 break; 1856 case RPC_FC_BOGUS_ARRAY: 1857 count = *(const WORD *)(pFormat + 2); 1858 pFormat += 4; 1859 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg); 1860 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count); 1861 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 1862 break; 1863 default: 1864 ERR("unknown array format 0x%x\n", fc); 1865 RpcRaiseException(RPC_X_BAD_STUB_DATA); 1866 } 1867 } 1868 1869 static inline void array_buffer_size( 1870 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 1871 PFORMAT_STRING pFormat, unsigned char fHasPointers) 1872 { 1873 DWORD i, size; 1874 DWORD esize; 1875 unsigned char alignment; 1876 1877 switch (fc) 1878 { 1879 case RPC_FC_CARRAY: 1880 esize = *(const WORD*)(pFormat+2); 1881 alignment = pFormat[1] + 1; 1882 1883 pFormat = SkipConformance(pStubMsg, pFormat + 4); 1884 1885 align_length(&pStubMsg->BufferLength, alignment); 1886 1887 size = safe_multiply(esize, pStubMsg->MaxCount); 1888 /* conformance value plus array */ 1889 safe_buffer_length_increment(pStubMsg, size); 1890 1891 if (fHasPointers) 1892 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 1893 break; 1894 case RPC_FC_CVARRAY: 1895 esize = *(const WORD*)(pFormat+2); 1896 alignment = pFormat[1] + 1; 1897 1898 pFormat = SkipConformance(pStubMsg, pFormat + 4); 1899 pFormat = SkipVariance(pStubMsg, pFormat); 1900 1901 SizeVariance(pStubMsg); 1902 1903 align_length(&pStubMsg->BufferLength, alignment); 1904 1905 size = safe_multiply(esize, pStubMsg->ActualCount); 1906 safe_buffer_length_increment(pStubMsg, size); 1907 1908 if (fHasPointers) 1909 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 1910 break; 1911 case RPC_FC_C_CSTRING: 1912 case RPC_FC_C_WSTRING: 1913 if (fc == RPC_FC_C_CSTRING) 1914 esize = 1; 1915 else 1916 esize = 2; 1917 1918 SizeVariance(pStubMsg); 1919 1920 size = safe_multiply(esize, pStubMsg->ActualCount); 1921 safe_buffer_length_increment(pStubMsg, size); 1922 break; 1923 case RPC_FC_BOGUS_ARRAY: 1924 alignment = pFormat[1] + 1; 1925 pFormat = SkipConformance(pStubMsg, pFormat + 4); 1926 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg); 1927 pFormat = SkipVariance(pStubMsg, pFormat); 1928 1929 align_length(&pStubMsg->BufferLength, alignment); 1930 1931 size = pStubMsg->ActualCount; 1932 for (i = 0; i < size; i++) 1933 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL); 1934 break; 1935 default: 1936 ERR("unknown array format 0x%x\n", fc); 1937 RpcRaiseException(RPC_X_BAD_STUB_DATA); 1938 } 1939 } 1940 1941 static inline void array_compute_and_write_conformance( 1942 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 1943 PFORMAT_STRING pFormat) 1944 { 1945 ULONG def; 1946 BOOL conformance_present; 1947 1948 switch (fc) 1949 { 1950 case RPC_FC_CARRAY: 1951 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 1952 WriteConformance(pStubMsg); 1953 break; 1954 case RPC_FC_CVARRAY: 1955 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); 1956 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 1957 WriteConformance(pStubMsg); 1958 break; 1959 case RPC_FC_C_CSTRING: 1960 case RPC_FC_C_WSTRING: 1961 if (fc == RPC_FC_C_CSTRING) 1962 { 1963 TRACE("string=%s\n", debugstr_a((const char *)pMemory)); 1964 pStubMsg->ActualCount = strlen((const char *)pMemory)+1; 1965 } 1966 else 1967 { 1968 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); 1969 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; 1970 } 1971 if (pFormat[1] == RPC_FC_STRING_SIZED) 1972 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); 1973 else 1974 pStubMsg->MaxCount = pStubMsg->ActualCount; 1975 pStubMsg->Offset = 0; 1976 WriteConformance(pStubMsg); 1977 break; 1978 case RPC_FC_BOGUS_ARRAY: 1979 def = *(const WORD *)(pFormat + 2); 1980 pFormat += 4; 1981 conformance_present = IsConformanceOrVariancePresent(pFormat); 1982 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); 1983 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 1984 if (conformance_present) WriteConformance(pStubMsg); 1985 break; 1986 default: 1987 ERR("unknown array format 0x%x\n", fc); 1988 RpcRaiseException(RPC_X_BAD_STUB_DATA); 1989 } 1990 } 1991 1992 static inline void array_write_variance_and_marshall( 1993 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 1994 PFORMAT_STRING pFormat, unsigned char fHasPointers) 1995 { 1996 DWORD i, size; 1997 DWORD esize; 1998 unsigned char alignment; 1999 2000 switch (fc) 2001 { 2002 case RPC_FC_CARRAY: 2003 esize = *(const WORD*)(pFormat+2); 2004 alignment = pFormat[1] + 1; 2005 2006 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2007 2008 align_pointer_clear(&pStubMsg->Buffer, alignment); 2009 2010 size = safe_multiply(esize, pStubMsg->MaxCount); 2011 if (fHasPointers) 2012 pStubMsg->BufferMark = pStubMsg->Buffer; 2013 safe_copy_to_buffer(pStubMsg, pMemory, size); 2014 2015 if (fHasPointers) 2016 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 2017 break; 2018 case RPC_FC_CVARRAY: 2019 esize = *(const WORD*)(pFormat+2); 2020 alignment = pFormat[1] + 1; 2021 2022 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2023 pFormat = SkipVariance(pStubMsg, pFormat); 2024 2025 WriteVariance(pStubMsg); 2026 2027 align_pointer_clear(&pStubMsg->Buffer, alignment); 2028 2029 size = safe_multiply(esize, pStubMsg->ActualCount); 2030 2031 if (fHasPointers) 2032 pStubMsg->BufferMark = pStubMsg->Buffer; 2033 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size); 2034 2035 if (fHasPointers) 2036 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 2037 break; 2038 case RPC_FC_C_CSTRING: 2039 case RPC_FC_C_WSTRING: 2040 if (fc == RPC_FC_C_CSTRING) 2041 esize = 1; 2042 else 2043 esize = 2; 2044 2045 WriteVariance(pStubMsg); 2046 2047 size = safe_multiply(esize, pStubMsg->ActualCount); 2048 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ 2049 break; 2050 case RPC_FC_BOGUS_ARRAY: 2051 alignment = pFormat[1] + 1; 2052 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2053 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg); 2054 pFormat = SkipVariance(pStubMsg, pFormat); 2055 2056 align_pointer_clear(&pStubMsg->Buffer, alignment); 2057 2058 size = pStubMsg->ActualCount; 2059 for (i = 0; i < size; i++) 2060 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL); 2061 break; 2062 default: 2063 ERR("unknown array format 0x%x\n", fc); 2064 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2065 } 2066 } 2067 2068 static inline ULONG array_read_conformance( 2069 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 2070 { 2071 DWORD def, esize; 2072 2073 switch (fc) 2074 { 2075 case RPC_FC_CARRAY: 2076 esize = *(const WORD*)(pFormat+2); 2077 pFormat = ReadConformance(pStubMsg, pFormat+4); 2078 return safe_multiply(esize, pStubMsg->MaxCount); 2079 case RPC_FC_CVARRAY: 2080 esize = *(const WORD*)(pFormat+2); 2081 pFormat = ReadConformance(pStubMsg, pFormat+4); 2082 return safe_multiply(esize, pStubMsg->MaxCount); 2083 case RPC_FC_C_CSTRING: 2084 case RPC_FC_C_WSTRING: 2085 if (fc == RPC_FC_C_CSTRING) 2086 esize = 1; 2087 else 2088 esize = 2; 2089 2090 if (pFormat[1] == RPC_FC_STRING_SIZED) 2091 ReadConformance(pStubMsg, pFormat + 2); 2092 else 2093 ReadConformance(pStubMsg, NULL); 2094 return safe_multiply(esize, pStubMsg->MaxCount); 2095 case RPC_FC_BOGUS_ARRAY: 2096 def = *(const WORD *)(pFormat + 2); 2097 pFormat += 4; 2098 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat); 2099 else 2100 { 2101 pStubMsg->MaxCount = def; 2102 pFormat = SkipConformance( pStubMsg, pFormat ); 2103 } 2104 pFormat = SkipVariance( pStubMsg, pFormat ); 2105 2106 esize = ComplexStructSize(pStubMsg, pFormat); 2107 return safe_multiply(pStubMsg->MaxCount, esize); 2108 default: 2109 ERR("unknown array format 0x%x\n", fc); 2110 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2111 } 2112 } 2113 2114 static inline ULONG array_read_variance_and_unmarshall( 2115 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, 2116 PFORMAT_STRING pFormat, unsigned char fMustAlloc, 2117 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall) 2118 { 2119 ULONG bufsize, memsize; 2120 WORD esize; 2121 unsigned char alignment; 2122 unsigned char *saved_buffer, *pMemory; 2123 ULONG i, offset, count; 2124 2125 switch (fc) 2126 { 2127 case RPC_FC_CARRAY: 2128 esize = *(const WORD*)(pFormat+2); 2129 alignment = pFormat[1] + 1; 2130 2131 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); 2132 2133 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2134 2135 align_pointer(&pStubMsg->Buffer, alignment); 2136 2137 if (fUnmarshall) 2138 { 2139 if (fMustAlloc) 2140 *ppMemory = NdrAllocate(pStubMsg, memsize); 2141 else 2142 { 2143 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory) 2144 /* for servers, we just point straight into the RPC buffer */ 2145 *ppMemory = pStubMsg->Buffer; 2146 } 2147 2148 saved_buffer = pStubMsg->Buffer; 2149 safe_buffer_increment(pStubMsg, bufsize); 2150 2151 pStubMsg->BufferMark = saved_buffer; 2152 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 2153 2154 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 2155 if (*ppMemory != saved_buffer) 2156 memcpy(*ppMemory, saved_buffer, bufsize); 2157 } 2158 return bufsize; 2159 case RPC_FC_CVARRAY: 2160 esize = *(const WORD*)(pFormat+2); 2161 alignment = pFormat[1] + 1; 2162 2163 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2164 2165 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 2166 2167 align_pointer(&pStubMsg->Buffer, alignment); 2168 2169 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2170 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2171 2172 if (fUnmarshall) 2173 { 2174 offset = pStubMsg->Offset; 2175 2176 if (!fMustAlloc && !*ppMemory) 2177 fMustAlloc = TRUE; 2178 if (fMustAlloc) 2179 *ppMemory = NdrAllocate(pStubMsg, memsize); 2180 saved_buffer = pStubMsg->Buffer; 2181 safe_buffer_increment(pStubMsg, bufsize); 2182 2183 pStubMsg->BufferMark = saved_buffer; 2184 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, 2185 fMustAlloc); 2186 2187 memcpy(*ppMemory + offset, saved_buffer, bufsize); 2188 } 2189 return bufsize; 2190 case RPC_FC_C_CSTRING: 2191 case RPC_FC_C_WSTRING: 2192 if (fc == RPC_FC_C_CSTRING) 2193 esize = 1; 2194 else 2195 esize = 2; 2196 2197 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); 2198 2199 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) 2200 { 2201 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", 2202 pStubMsg->ActualCount, pStubMsg->MaxCount); 2203 RpcRaiseException(RPC_S_INVALID_BOUND); 2204 } 2205 if (pStubMsg->Offset) 2206 { 2207 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 2208 RpcRaiseException(RPC_S_INVALID_BOUND); 2209 } 2210 2211 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2212 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2213 2214 validate_string_data(pStubMsg, bufsize, esize); 2215 2216 if (fUnmarshall) 2217 { 2218 if (fMustAlloc) 2219 *ppMemory = NdrAllocate(pStubMsg, memsize); 2220 else 2221 { 2222 if (fUseBufferMemoryServer && !pStubMsg->IsClient && 2223 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) 2224 /* if the data in the RPC buffer is big enough, we just point 2225 * straight into it */ 2226 *ppMemory = pStubMsg->Buffer; 2227 else if (!*ppMemory) 2228 *ppMemory = NdrAllocate(pStubMsg, memsize); 2229 } 2230 2231 if (*ppMemory == pStubMsg->Buffer) 2232 safe_buffer_increment(pStubMsg, bufsize); 2233 else 2234 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); 2235 2236 if (*pFormat == RPC_FC_C_CSTRING) 2237 TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); 2238 else 2239 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); 2240 } 2241 return bufsize; 2242 2243 case RPC_FC_BOGUS_ARRAY: 2244 alignment = pFormat[1] + 1; 2245 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2246 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 2247 2248 esize = ComplexStructSize(pStubMsg, pFormat); 2249 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2250 2251 assert( fUnmarshall ); 2252 2253 if (!fMustAlloc && !*ppMemory) 2254 fMustAlloc = TRUE; 2255 if (fMustAlloc) 2256 *ppMemory = NdrAllocate(pStubMsg, memsize); 2257 2258 align_pointer(&pStubMsg->Buffer, alignment); 2259 saved_buffer = pStubMsg->Buffer; 2260 2261 pMemory = *ppMemory; 2262 count = pStubMsg->ActualCount; 2263 for (i = 0; i < count; i++) 2264 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc); 2265 return pStubMsg->Buffer - saved_buffer; 2266 2267 default: 2268 ERR("unknown array format 0x%x\n", fc); 2269 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2270 } 2271 } 2272 2273 static inline void array_memory_size( 2274 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, 2275 unsigned char fHasPointers) 2276 { 2277 ULONG i, count, SavedMemorySize; 2278 ULONG bufsize, memsize; 2279 DWORD esize; 2280 unsigned char alignment; 2281 2282 switch (fc) 2283 { 2284 case RPC_FC_CARRAY: 2285 esize = *(const WORD*)(pFormat+2); 2286 alignment = pFormat[1] + 1; 2287 2288 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2289 2290 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); 2291 pStubMsg->MemorySize += memsize; 2292 2293 align_pointer(&pStubMsg->Buffer, alignment); 2294 if (fHasPointers) 2295 pStubMsg->BufferMark = pStubMsg->Buffer; 2296 safe_buffer_increment(pStubMsg, bufsize); 2297 2298 if (fHasPointers) 2299 EmbeddedPointerMemorySize(pStubMsg, pFormat); 2300 break; 2301 case RPC_FC_CVARRAY: 2302 esize = *(const WORD*)(pFormat+2); 2303 alignment = pFormat[1] + 1; 2304 2305 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2306 2307 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 2308 2309 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2310 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2311 pStubMsg->MemorySize += memsize; 2312 2313 align_pointer(&pStubMsg->Buffer, alignment); 2314 if (fHasPointers) 2315 pStubMsg->BufferMark = pStubMsg->Buffer; 2316 safe_buffer_increment(pStubMsg, bufsize); 2317 2318 if (fHasPointers) 2319 EmbeddedPointerMemorySize(pStubMsg, pFormat); 2320 break; 2321 case RPC_FC_C_CSTRING: 2322 case RPC_FC_C_WSTRING: 2323 if (fc == RPC_FC_C_CSTRING) 2324 esize = 1; 2325 else 2326 esize = 2; 2327 2328 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); 2329 2330 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) 2331 { 2332 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", 2333 pStubMsg->ActualCount, pStubMsg->MaxCount); 2334 RpcRaiseException(RPC_S_INVALID_BOUND); 2335 } 2336 if (pStubMsg->Offset) 2337 { 2338 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 2339 RpcRaiseException(RPC_S_INVALID_BOUND); 2340 } 2341 2342 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2343 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2344 2345 validate_string_data(pStubMsg, bufsize, esize); 2346 2347 safe_buffer_increment(pStubMsg, bufsize); 2348 pStubMsg->MemorySize += memsize; 2349 break; 2350 case RPC_FC_BOGUS_ARRAY: 2351 alignment = pFormat[1] + 1; 2352 pFormat = SkipConformance(pStubMsg, pFormat + 4); 2353 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 2354 2355 align_pointer(&pStubMsg->Buffer, alignment); 2356 2357 SavedMemorySize = pStubMsg->MemorySize; 2358 2359 esize = ComplexStructSize(pStubMsg, pFormat); 2360 memsize = safe_multiply(pStubMsg->MaxCount, esize); 2361 2362 count = pStubMsg->ActualCount; 2363 for (i = 0; i < count; i++) 2364 ComplexStructMemorySize(pStubMsg, pFormat, NULL); 2365 2366 pStubMsg->MemorySize = SavedMemorySize + memsize; 2367 break; 2368 default: 2369 ERR("unknown array format 0x%x\n", fc); 2370 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2371 } 2372 } 2373 2374 static inline void array_free( 2375 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, 2376 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers) 2377 { 2378 DWORD i, count; 2379 2380 switch (fc) 2381 { 2382 case RPC_FC_CARRAY: 2383 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 2384 if (fHasPointers) 2385 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 2386 break; 2387 case RPC_FC_CVARRAY: 2388 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 2389 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 2390 if (fHasPointers) 2391 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 2392 break; 2393 case RPC_FC_C_CSTRING: 2394 case RPC_FC_C_WSTRING: 2395 /* No embedded pointers so nothing to do */ 2396 break; 2397 case RPC_FC_BOGUS_ARRAY: 2398 count = *(const WORD *)(pFormat + 2); 2399 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count); 2400 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 2401 2402 count = pStubMsg->ActualCount; 2403 for (i = 0; i < count; i++) 2404 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); 2405 break; 2406 default: 2407 ERR("unknown array format 0x%x\n", fc); 2408 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2409 } 2410 } 2411 2412 /* 2413 * NdrConformantString: 2414 * 2415 * What MS calls a ConformantString is, in DCE terminology, 2416 * a Varying-Conformant String. 2417 * [ 2418 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') 2419 * offset: DWORD (actual string data begins at (offset) CHARTYPE's 2420 * into unmarshalled string) 2421 * length: DWORD (# of CHARTYPE characters, inclusive of '\0') 2422 * [ 2423 * data: CHARTYPE[maxlen] 2424 * ] 2425 * ], where CHARTYPE is the appropriate character type (specified externally) 2426 * 2427 */ 2428 2429 /*********************************************************************** 2430 * NdrConformantStringMarshall [RPCRT4.@] 2431 */ 2432 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, 2433 unsigned char *pszMessage, PFORMAT_STRING pFormat) 2434 { 2435 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); 2436 2437 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 2438 ERR("Unhandled string type: %#x\n", pFormat[0]); 2439 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2440 } 2441 2442 /* allow compiler to optimise inline function by passing constant into 2443 * these functions */ 2444 if (pFormat[0] == RPC_FC_C_CSTRING) { 2445 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage, 2446 pFormat); 2447 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage, 2448 pFormat, TRUE /* fHasPointers */); 2449 } else { 2450 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage, 2451 pFormat); 2452 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage, 2453 pFormat, TRUE /* fHasPointers */); 2454 } 2455 2456 return NULL; 2457 } 2458 2459 /*********************************************************************** 2460 * NdrConformantStringBufferSize [RPCRT4.@] 2461 */ 2462 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 2463 unsigned char* pMemory, PFORMAT_STRING pFormat) 2464 { 2465 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 2466 2467 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 2468 ERR("Unhandled string type: %#x\n", pFormat[0]); 2469 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2470 } 2471 2472 /* allow compiler to optimise inline function by passing constant into 2473 * these functions */ 2474 if (pFormat[0] == RPC_FC_C_CSTRING) { 2475 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory, 2476 pFormat); 2477 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat, 2478 TRUE /* fHasPointers */); 2479 } else { 2480 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory, 2481 pFormat); 2482 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat, 2483 TRUE /* fHasPointers */); 2484 } 2485 } 2486 2487 /************************************************************************ 2488 * NdrConformantStringMemorySize [RPCRT4.@] 2489 */ 2490 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, 2491 PFORMAT_STRING pFormat ) 2492 { 2493 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); 2494 2495 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 2496 ERR("Unhandled string type: %#x\n", pFormat[0]); 2497 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2498 } 2499 2500 /* allow compiler to optimise inline function by passing constant into 2501 * these functions */ 2502 if (pFormat[0] == RPC_FC_C_CSTRING) { 2503 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); 2504 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat, 2505 TRUE /* fHasPointers */); 2506 } else { 2507 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); 2508 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat, 2509 TRUE /* fHasPointers */); 2510 } 2511 2512 return pStubMsg->MemorySize; 2513 } 2514 2515 /************************************************************************ 2516 * NdrConformantStringUnmarshall [RPCRT4.@] 2517 */ 2518 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, 2519 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) 2520 { 2521 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", 2522 pStubMsg, *ppMemory, pFormat, fMustAlloc); 2523 2524 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 2525 ERR("Unhandled string type: %#x\n", *pFormat); 2526 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2527 } 2528 2529 /* allow compiler to optimise inline function by passing constant into 2530 * these functions */ 2531 if (pFormat[0] == RPC_FC_C_CSTRING) { 2532 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); 2533 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory, 2534 pFormat, fMustAlloc, 2535 TRUE /* fUseBufferMemoryServer */, 2536 TRUE /* fUnmarshall */); 2537 } else { 2538 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); 2539 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory, 2540 pFormat, fMustAlloc, 2541 TRUE /* fUseBufferMemoryServer */, 2542 TRUE /* fUnmarshall */); 2543 } 2544 2545 return NULL; 2546 } 2547 2548 /*********************************************************************** 2549 * NdrNonConformantStringMarshall [RPCRT4.@] 2550 */ 2551 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, 2552 unsigned char *pMemory, 2553 PFORMAT_STRING pFormat) 2554 { 2555 ULONG esize, size, maxsize; 2556 2557 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 2558 2559 maxsize = *(const USHORT *)&pFormat[2]; 2560 2561 if (*pFormat == RPC_FC_CSTRING) 2562 { 2563 ULONG i = 0; 2564 const char *str = (const char *)pMemory; 2565 while (i < maxsize && str[i]) i++; 2566 TRACE("string=%s\n", debugstr_an(str, i)); 2567 pStubMsg->ActualCount = i + 1; 2568 esize = 1; 2569 } 2570 else if (*pFormat == RPC_FC_WSTRING) 2571 { 2572 ULONG i = 0; 2573 const WCHAR *str = (const WCHAR *)pMemory; 2574 while (i < maxsize && str[i]) i++; 2575 TRACE("string=%s\n", debugstr_wn(str, i)); 2576 pStubMsg->ActualCount = i + 1; 2577 esize = 2; 2578 } 2579 else 2580 { 2581 ERR("Unhandled string type: %#x\n", *pFormat); 2582 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2583 } 2584 2585 pStubMsg->Offset = 0; 2586 WriteVariance(pStubMsg); 2587 2588 size = safe_multiply(esize, pStubMsg->ActualCount); 2589 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ 2590 2591 return NULL; 2592 } 2593 2594 /*********************************************************************** 2595 * NdrNonConformantStringUnmarshall [RPCRT4.@] 2596 */ 2597 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 2598 unsigned char **ppMemory, 2599 PFORMAT_STRING pFormat, 2600 unsigned char fMustAlloc) 2601 { 2602 ULONG bufsize, memsize, esize, maxsize; 2603 2604 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", 2605 pStubMsg, *ppMemory, pFormat, fMustAlloc); 2606 2607 maxsize = *(const USHORT *)&pFormat[2]; 2608 2609 ReadVariance(pStubMsg, NULL, maxsize); 2610 if (pStubMsg->Offset) 2611 { 2612 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 2613 RpcRaiseException(RPC_S_INVALID_BOUND); 2614 } 2615 2616 if (*pFormat == RPC_FC_CSTRING) esize = 1; 2617 else if (*pFormat == RPC_FC_WSTRING) esize = 2; 2618 else 2619 { 2620 ERR("Unhandled string type: %#x\n", *pFormat); 2621 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2622 } 2623 2624 memsize = esize * maxsize; 2625 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2626 2627 validate_string_data(pStubMsg, bufsize, esize); 2628 2629 if (!fMustAlloc && !*ppMemory) 2630 fMustAlloc = TRUE; 2631 if (fMustAlloc) 2632 *ppMemory = NdrAllocate(pStubMsg, memsize); 2633 2634 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); 2635 2636 if (*pFormat == RPC_FC_CSTRING) { 2637 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); 2638 } 2639 else if (*pFormat == RPC_FC_WSTRING) { 2640 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); 2641 } 2642 2643 return NULL; 2644 } 2645 2646 /*********************************************************************** 2647 * NdrNonConformantStringBufferSize [RPCRT4.@] 2648 */ 2649 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 2650 unsigned char *pMemory, 2651 PFORMAT_STRING pFormat) 2652 { 2653 ULONG esize, maxsize; 2654 2655 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 2656 2657 maxsize = *(const USHORT *)&pFormat[2]; 2658 2659 SizeVariance(pStubMsg); 2660 2661 if (*pFormat == RPC_FC_CSTRING) 2662 { 2663 ULONG i = 0; 2664 const char *str = (const char *)pMemory; 2665 while (i < maxsize && str[i]) i++; 2666 TRACE("string=%s\n", debugstr_an(str, i)); 2667 pStubMsg->ActualCount = i + 1; 2668 esize = 1; 2669 } 2670 else if (*pFormat == RPC_FC_WSTRING) 2671 { 2672 ULONG i = 0; 2673 const WCHAR *str = (const WCHAR *)pMemory; 2674 while (i < maxsize && str[i]) i++; 2675 TRACE("string=%s\n", debugstr_wn(str, i)); 2676 pStubMsg->ActualCount = i + 1; 2677 esize = 2; 2678 } 2679 else 2680 { 2681 ERR("Unhandled string type: %#x\n", *pFormat); 2682 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2683 } 2684 2685 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 2686 } 2687 2688 /*********************************************************************** 2689 * NdrNonConformantStringMemorySize [RPCRT4.@] 2690 */ 2691 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 2692 PFORMAT_STRING pFormat) 2693 { 2694 ULONG bufsize, memsize, esize, maxsize; 2695 2696 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); 2697 2698 maxsize = *(const USHORT *)&pFormat[2]; 2699 2700 ReadVariance(pStubMsg, NULL, maxsize); 2701 2702 if (pStubMsg->Offset) 2703 { 2704 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 2705 RpcRaiseException(RPC_S_INVALID_BOUND); 2706 } 2707 2708 if (*pFormat == RPC_FC_CSTRING) esize = 1; 2709 else if (*pFormat == RPC_FC_WSTRING) esize = 2; 2710 else 2711 { 2712 ERR("Unhandled string type: %#x\n", *pFormat); 2713 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2714 } 2715 2716 memsize = esize * maxsize; 2717 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2718 2719 validate_string_data(pStubMsg, bufsize, esize); 2720 2721 safe_buffer_increment(pStubMsg, bufsize); 2722 pStubMsg->MemorySize += memsize; 2723 2724 return pStubMsg->MemorySize; 2725 } 2726 2727 /* Complex types */ 2728 2729 #include "pshpack1.h" 2730 typedef struct 2731 { 2732 unsigned char type; 2733 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ 2734 ULONG low_value; 2735 ULONG high_value; 2736 } NDR_RANGE; 2737 #include "poppack.h" 2738 2739 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg, 2740 PFORMAT_STRING pFormat) 2741 { 2742 switch (*pFormat) { 2743 case RPC_FC_STRUCT: 2744 case RPC_FC_PSTRUCT: 2745 case RPC_FC_CSTRUCT: 2746 case RPC_FC_BOGUS_STRUCT: 2747 case RPC_FC_SMFARRAY: 2748 case RPC_FC_SMVARRAY: 2749 case RPC_FC_CSTRING: 2750 return *(const WORD*)&pFormat[2]; 2751 case RPC_FC_USER_MARSHAL: 2752 return *(const WORD*)&pFormat[4]; 2753 case RPC_FC_RANGE: { 2754 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) { 2755 case RPC_FC_BYTE: 2756 case RPC_FC_CHAR: 2757 case RPC_FC_SMALL: 2758 case RPC_FC_USMALL: 2759 return sizeof(UCHAR); 2760 case RPC_FC_WCHAR: 2761 case RPC_FC_SHORT: 2762 case RPC_FC_USHORT: 2763 return sizeof(USHORT); 2764 case RPC_FC_LONG: 2765 case RPC_FC_ULONG: 2766 case RPC_FC_ENUM32: 2767 case RPC_FC_INT3264: 2768 case RPC_FC_UINT3264: 2769 return sizeof(ULONG); 2770 case RPC_FC_FLOAT: 2771 return sizeof(float); 2772 case RPC_FC_DOUBLE: 2773 return sizeof(double); 2774 case RPC_FC_HYPER: 2775 return sizeof(ULONGLONG); 2776 case RPC_FC_ENUM16: 2777 return sizeof(UINT); 2778 default: 2779 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf); 2780 RpcRaiseException(RPC_X_BAD_STUB_DATA); 2781 } 2782 } 2783 case RPC_FC_NON_ENCAPSULATED_UNION: 2784 pFormat += 2; 2785 pFormat = SkipConformance(pStubMsg, pFormat); 2786 pFormat += *(const SHORT*)pFormat; 2787 return *(const SHORT*)pFormat; 2788 case RPC_FC_IP: 2789 return sizeof(void *); 2790 case RPC_FC_WSTRING: 2791 return *(const WORD*)&pFormat[2] * 2; 2792 default: 2793 FIXME("unhandled embedded type %02x\n", *pFormat); 2794 } 2795 return 0; 2796 } 2797 2798 2799 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 2800 PFORMAT_STRING pFormat) 2801 { 2802 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK]; 2803 2804 if (!m) 2805 { 2806 FIXME("no memorysizer for data type=%02x\n", *pFormat); 2807 return 0; 2808 } 2809 2810 return m(pStubMsg, pFormat); 2811 } 2812 2813 2814 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, 2815 unsigned char *pMemory, 2816 PFORMAT_STRING pFormat, 2817 PFORMAT_STRING pPointer) 2818 { 2819 PFORMAT_STRING desc; 2820 NDR_MARSHALL m; 2821 ULONG size; 2822 2823 while (*pFormat != RPC_FC_END) { 2824 switch (*pFormat) { 2825 case RPC_FC_BYTE: 2826 case RPC_FC_CHAR: 2827 case RPC_FC_SMALL: 2828 case RPC_FC_USMALL: 2829 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory); 2830 safe_copy_to_buffer(pStubMsg, pMemory, 1); 2831 pMemory += 1; 2832 break; 2833 case RPC_FC_WCHAR: 2834 case RPC_FC_SHORT: 2835 case RPC_FC_USHORT: 2836 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory); 2837 safe_copy_to_buffer(pStubMsg, pMemory, 2); 2838 pMemory += 2; 2839 break; 2840 case RPC_FC_ENUM16: 2841 { 2842 USHORT val = *(DWORD *)pMemory; 2843 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory); 2844 if (32767 < *(DWORD*)pMemory) 2845 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 2846 safe_copy_to_buffer(pStubMsg, &val, 2); 2847 pMemory += 4; 2848 break; 2849 } 2850 case RPC_FC_LONG: 2851 case RPC_FC_ULONG: 2852 case RPC_FC_ENUM32: 2853 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory); 2854 safe_copy_to_buffer(pStubMsg, pMemory, 4); 2855 pMemory += 4; 2856 break; 2857 case RPC_FC_INT3264: 2858 case RPC_FC_UINT3264: 2859 { 2860 UINT val = *(UINT_PTR *)pMemory; 2861 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory); 2862 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT)); 2863 pMemory += sizeof(UINT_PTR); 2864 break; 2865 } 2866 case RPC_FC_FLOAT: 2867 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory); 2868 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); 2869 pMemory += sizeof(float); 2870 break; 2871 case RPC_FC_HYPER: 2872 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); 2873 safe_copy_to_buffer(pStubMsg, pMemory, 8); 2874 pMemory += 8; 2875 break; 2876 case RPC_FC_DOUBLE: 2877 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory); 2878 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); 2879 pMemory += sizeof(double); 2880 break; 2881 case RPC_FC_RP: 2882 case RPC_FC_UP: 2883 case RPC_FC_OP: 2884 case RPC_FC_FP: 2885 case RPC_FC_POINTER: 2886 { 2887 unsigned char *saved_buffer; 2888 BOOL pointer_buffer_mark_set = FALSE; 2889 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); 2890 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer); 2891 if (*pFormat != RPC_FC_POINTER) 2892 pPointer = pFormat; 2893 if (*pPointer != RPC_FC_RP) 2894 align_pointer_clear(&pStubMsg->Buffer, 4); 2895 saved_buffer = pStubMsg->Buffer; 2896 if (pStubMsg->PointerBufferMark) 2897 { 2898 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 2899 pStubMsg->PointerBufferMark = NULL; 2900 pointer_buffer_mark_set = TRUE; 2901 } 2902 else if (*pPointer != RPC_FC_RP) 2903 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 2904 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer); 2905 if (pointer_buffer_mark_set) 2906 { 2907 STD_OVERFLOW_CHECK(pStubMsg); 2908 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 2909 pStubMsg->Buffer = saved_buffer; 2910 if (*pPointer != RPC_FC_RP) 2911 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 2912 } 2913 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer); 2914 if (*pFormat == RPC_FC_POINTER) 2915 pPointer += 4; 2916 else 2917 pFormat += 4; 2918 pMemory += sizeof(void *); 2919 break; 2920 } 2921 case RPC_FC_ALIGNM2: 2922 align_pointer(&pMemory, 2); 2923 break; 2924 case RPC_FC_ALIGNM4: 2925 align_pointer(&pMemory, 4); 2926 break; 2927 case RPC_FC_ALIGNM8: 2928 align_pointer(&pMemory, 8); 2929 break; 2930 case RPC_FC_STRUCTPAD1: 2931 case RPC_FC_STRUCTPAD2: 2932 case RPC_FC_STRUCTPAD3: 2933 case RPC_FC_STRUCTPAD4: 2934 case RPC_FC_STRUCTPAD5: 2935 case RPC_FC_STRUCTPAD6: 2936 case RPC_FC_STRUCTPAD7: 2937 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 2938 break; 2939 case RPC_FC_EMBEDDED_COMPLEX: 2940 pMemory += pFormat[1]; 2941 pFormat += 2; 2942 desc = pFormat + *(const SHORT*)pFormat; 2943 size = EmbeddedComplexSize(pStubMsg, desc); 2944 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory); 2945 m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 2946 if (m) 2947 { 2948 /* for some reason interface pointers aren't generated as 2949 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 2950 * they still need the dereferencing treatment that pointers are 2951 * given */ 2952 if (*desc == RPC_FC_IP) 2953 m(pStubMsg, *(unsigned char **)pMemory, desc); 2954 else 2955 m(pStubMsg, pMemory, desc); 2956 } 2957 else FIXME("no marshaller for embedded type %02x\n", *desc); 2958 pMemory += size; 2959 pFormat += 2; 2960 continue; 2961 case RPC_FC_PAD: 2962 break; 2963 default: 2964 FIXME("unhandled format 0x%02x\n", *pFormat); 2965 } 2966 pFormat++; 2967 } 2968 2969 return pMemory; 2970 } 2971 2972 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 2973 unsigned char *pMemory, 2974 PFORMAT_STRING pFormat, 2975 PFORMAT_STRING pPointer, 2976 unsigned char fMustAlloc) 2977 { 2978 PFORMAT_STRING desc; 2979 NDR_UNMARSHALL m; 2980 ULONG size; 2981 2982 while (*pFormat != RPC_FC_END) { 2983 switch (*pFormat) { 2984 case RPC_FC_BYTE: 2985 case RPC_FC_CHAR: 2986 case RPC_FC_SMALL: 2987 case RPC_FC_USMALL: 2988 safe_copy_from_buffer(pStubMsg, pMemory, 1); 2989 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); 2990 pMemory += 1; 2991 break; 2992 case RPC_FC_WCHAR: 2993 case RPC_FC_SHORT: 2994 case RPC_FC_USHORT: 2995 safe_copy_from_buffer(pStubMsg, pMemory, 2); 2996 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); 2997 pMemory += 2; 2998 break; 2999 case RPC_FC_ENUM16: 3000 { 3001 WORD val; 3002 safe_copy_from_buffer(pStubMsg, &val, 2); 3003 *(DWORD*)pMemory = val; 3004 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory); 3005 if (32767 < *(DWORD*)pMemory) 3006 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 3007 pMemory += 4; 3008 break; 3009 } 3010 case RPC_FC_LONG: 3011 case RPC_FC_ULONG: 3012 case RPC_FC_ENUM32: 3013 safe_copy_from_buffer(pStubMsg, pMemory, 4); 3014 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); 3015 pMemory += 4; 3016 break; 3017 case RPC_FC_INT3264: 3018 { 3019 INT val; 3020 safe_copy_from_buffer(pStubMsg, &val, 4); 3021 *(INT_PTR *)pMemory = val; 3022 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory); 3023 pMemory += sizeof(INT_PTR); 3024 break; 3025 } 3026 case RPC_FC_UINT3264: 3027 { 3028 UINT val; 3029 safe_copy_from_buffer(pStubMsg, &val, 4); 3030 *(UINT_PTR *)pMemory = val; 3031 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory); 3032 pMemory += sizeof(UINT_PTR); 3033 break; 3034 } 3035 case RPC_FC_FLOAT: 3036 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float)); 3037 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory); 3038 pMemory += sizeof(float); 3039 break; 3040 case RPC_FC_HYPER: 3041 safe_copy_from_buffer(pStubMsg, pMemory, 8); 3042 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); 3043 pMemory += 8; 3044 break; 3045 case RPC_FC_DOUBLE: 3046 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double)); 3047 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory); 3048 pMemory += sizeof(double); 3049 break; 3050 case RPC_FC_RP: 3051 case RPC_FC_UP: 3052 case RPC_FC_OP: 3053 case RPC_FC_FP: 3054 case RPC_FC_POINTER: 3055 { 3056 unsigned char *saved_buffer; 3057 BOOL pointer_buffer_mark_set = FALSE; 3058 TRACE("pointer => %p\n", pMemory); 3059 if (*pFormat != RPC_FC_POINTER) 3060 pPointer = pFormat; 3061 if (*pPointer != RPC_FC_RP) 3062 align_pointer(&pStubMsg->Buffer, 4); 3063 saved_buffer = pStubMsg->Buffer; 3064 if (pStubMsg->PointerBufferMark) 3065 { 3066 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 3067 pStubMsg->PointerBufferMark = NULL; 3068 pointer_buffer_mark_set = TRUE; 3069 } 3070 else if (*pPointer != RPC_FC_RP) 3071 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 3072 3073 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc); 3074 if (pointer_buffer_mark_set) 3075 { 3076 STD_OVERFLOW_CHECK(pStubMsg); 3077 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 3078 pStubMsg->Buffer = saved_buffer; 3079 if (*pPointer != RPC_FC_RP) 3080 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 3081 } 3082 if (*pFormat == RPC_FC_POINTER) 3083 pPointer += 4; 3084 else 3085 pFormat += 4; 3086 pMemory += sizeof(void *); 3087 break; 3088 } 3089 case RPC_FC_ALIGNM2: 3090 align_pointer_clear(&pMemory, 2); 3091 break; 3092 case RPC_FC_ALIGNM4: 3093 align_pointer_clear(&pMemory, 4); 3094 break; 3095 case RPC_FC_ALIGNM8: 3096 align_pointer_clear(&pMemory, 8); 3097 break; 3098 case RPC_FC_STRUCTPAD1: 3099 case RPC_FC_STRUCTPAD2: 3100 case RPC_FC_STRUCTPAD3: 3101 case RPC_FC_STRUCTPAD4: 3102 case RPC_FC_STRUCTPAD5: 3103 case RPC_FC_STRUCTPAD6: 3104 case RPC_FC_STRUCTPAD7: 3105 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1); 3106 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 3107 break; 3108 case RPC_FC_EMBEDDED_COMPLEX: 3109 pMemory += pFormat[1]; 3110 pFormat += 2; 3111 desc = pFormat + *(const SHORT*)pFormat; 3112 size = EmbeddedComplexSize(pStubMsg, desc); 3113 TRACE("embedded complex (size=%d) => %p\n", size, pMemory); 3114 if (fMustAlloc) 3115 /* we can't pass fMustAlloc=TRUE into the marshaller for this type 3116 * since the type is part of the memory block that is encompassed by 3117 * the whole complex type. Memory is forced to allocate when pointers 3118 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 3119 * clearing the memory we pass in to the unmarshaller */ 3120 memset(pMemory, 0, size); 3121 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 3122 if (m) 3123 { 3124 /* for some reason interface pointers aren't generated as 3125 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 3126 * they still need the dereferencing treatment that pointers are 3127 * given */ 3128 if (*desc == RPC_FC_IP) 3129 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE); 3130 else 3131 m(pStubMsg, &pMemory, desc, FALSE); 3132 } 3133 else FIXME("no unmarshaller for embedded type %02x\n", *desc); 3134 pMemory += size; 3135 pFormat += 2; 3136 continue; 3137 case RPC_FC_PAD: 3138 break; 3139 default: 3140 FIXME("unhandled format %d\n", *pFormat); 3141 } 3142 pFormat++; 3143 } 3144 3145 return pMemory; 3146 } 3147 3148 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 3149 unsigned char *pMemory, 3150 PFORMAT_STRING pFormat, 3151 PFORMAT_STRING pPointer) 3152 { 3153 PFORMAT_STRING desc; 3154 NDR_BUFFERSIZE m; 3155 ULONG size; 3156 3157 while (*pFormat != RPC_FC_END) { 3158 switch (*pFormat) { 3159 case RPC_FC_BYTE: 3160 case RPC_FC_CHAR: 3161 case RPC_FC_SMALL: 3162 case RPC_FC_USMALL: 3163 safe_buffer_length_increment(pStubMsg, 1); 3164 pMemory += 1; 3165 break; 3166 case RPC_FC_WCHAR: 3167 case RPC_FC_SHORT: 3168 case RPC_FC_USHORT: 3169 safe_buffer_length_increment(pStubMsg, 2); 3170 pMemory += 2; 3171 break; 3172 case RPC_FC_ENUM16: 3173 safe_buffer_length_increment(pStubMsg, 2); 3174 pMemory += 4; 3175 break; 3176 case RPC_FC_LONG: 3177 case RPC_FC_ULONG: 3178 case RPC_FC_ENUM32: 3179 case RPC_FC_FLOAT: 3180 safe_buffer_length_increment(pStubMsg, 4); 3181 pMemory += 4; 3182 break; 3183 case RPC_FC_INT3264: 3184 case RPC_FC_UINT3264: 3185 safe_buffer_length_increment(pStubMsg, 4); 3186 pMemory += sizeof(INT_PTR); 3187 break; 3188 case RPC_FC_HYPER: 3189 case RPC_FC_DOUBLE: 3190 safe_buffer_length_increment(pStubMsg, 8); 3191 pMemory += 8; 3192 break; 3193 case RPC_FC_RP: 3194 case RPC_FC_UP: 3195 case RPC_FC_OP: 3196 case RPC_FC_FP: 3197 case RPC_FC_POINTER: 3198 if (*pFormat != RPC_FC_POINTER) 3199 pPointer = pFormat; 3200 if (!pStubMsg->IgnoreEmbeddedPointers) 3201 { 3202 int saved_buffer_length = pStubMsg->BufferLength; 3203 pStubMsg->BufferLength = pStubMsg->PointerLength; 3204 pStubMsg->PointerLength = 0; 3205 if(!pStubMsg->BufferLength) 3206 ERR("BufferLength == 0??\n"); 3207 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer); 3208 pStubMsg->PointerLength = pStubMsg->BufferLength; 3209 pStubMsg->BufferLength = saved_buffer_length; 3210 } 3211 if (*pPointer != RPC_FC_RP) 3212 { 3213 align_length(&pStubMsg->BufferLength, 4); 3214 safe_buffer_length_increment(pStubMsg, 4); 3215 } 3216 if (*pFormat == RPC_FC_POINTER) 3217 pPointer += 4; 3218 else 3219 pFormat += 4; 3220 pMemory += sizeof(void*); 3221 break; 3222 case RPC_FC_ALIGNM2: 3223 align_pointer(&pMemory, 2); 3224 break; 3225 case RPC_FC_ALIGNM4: 3226 align_pointer(&pMemory, 4); 3227 break; 3228 case RPC_FC_ALIGNM8: 3229 align_pointer(&pMemory, 8); 3230 break; 3231 case RPC_FC_STRUCTPAD1: 3232 case RPC_FC_STRUCTPAD2: 3233 case RPC_FC_STRUCTPAD3: 3234 case RPC_FC_STRUCTPAD4: 3235 case RPC_FC_STRUCTPAD5: 3236 case RPC_FC_STRUCTPAD6: 3237 case RPC_FC_STRUCTPAD7: 3238 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 3239 break; 3240 case RPC_FC_EMBEDDED_COMPLEX: 3241 pMemory += pFormat[1]; 3242 pFormat += 2; 3243 desc = pFormat + *(const SHORT*)pFormat; 3244 size = EmbeddedComplexSize(pStubMsg, desc); 3245 m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 3246 if (m) 3247 { 3248 /* for some reason interface pointers aren't generated as 3249 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 3250 * they still need the dereferencing treatment that pointers are 3251 * given */ 3252 if (*desc == RPC_FC_IP) 3253 m(pStubMsg, *(unsigned char **)pMemory, desc); 3254 else 3255 m(pStubMsg, pMemory, desc); 3256 } 3257 else FIXME("no buffersizer for embedded type %02x\n", *desc); 3258 pMemory += size; 3259 pFormat += 2; 3260 continue; 3261 case RPC_FC_PAD: 3262 break; 3263 default: 3264 FIXME("unhandled format 0x%02x\n", *pFormat); 3265 } 3266 pFormat++; 3267 } 3268 3269 return pMemory; 3270 } 3271 3272 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, 3273 unsigned char *pMemory, 3274 PFORMAT_STRING pFormat, 3275 PFORMAT_STRING pPointer) 3276 { 3277 PFORMAT_STRING desc; 3278 NDR_FREE m; 3279 ULONG size; 3280 3281 while (*pFormat != RPC_FC_END) { 3282 switch (*pFormat) { 3283 case RPC_FC_BYTE: 3284 case RPC_FC_CHAR: 3285 case RPC_FC_SMALL: 3286 case RPC_FC_USMALL: 3287 pMemory += 1; 3288 break; 3289 case RPC_FC_WCHAR: 3290 case RPC_FC_SHORT: 3291 case RPC_FC_USHORT: 3292 pMemory += 2; 3293 break; 3294 case RPC_FC_LONG: 3295 case RPC_FC_ULONG: 3296 case RPC_FC_ENUM16: 3297 case RPC_FC_ENUM32: 3298 case RPC_FC_FLOAT: 3299 pMemory += 4; 3300 break; 3301 case RPC_FC_INT3264: 3302 case RPC_FC_UINT3264: 3303 pMemory += sizeof(INT_PTR); 3304 break; 3305 case RPC_FC_HYPER: 3306 case RPC_FC_DOUBLE: 3307 pMemory += 8; 3308 break; 3309 case RPC_FC_RP: 3310 case RPC_FC_UP: 3311 case RPC_FC_OP: 3312 case RPC_FC_FP: 3313 case RPC_FC_POINTER: 3314 if (*pFormat != RPC_FC_POINTER) 3315 pPointer = pFormat; 3316 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer); 3317 if (*pFormat == RPC_FC_POINTER) 3318 pPointer += 4; 3319 else 3320 pFormat += 4; 3321 pMemory += sizeof(void *); 3322 break; 3323 case RPC_FC_ALIGNM2: 3324 align_pointer(&pMemory, 2); 3325 break; 3326 case RPC_FC_ALIGNM4: 3327 align_pointer(&pMemory, 4); 3328 break; 3329 case RPC_FC_ALIGNM8: 3330 align_pointer(&pMemory, 8); 3331 break; 3332 case RPC_FC_STRUCTPAD1: 3333 case RPC_FC_STRUCTPAD2: 3334 case RPC_FC_STRUCTPAD3: 3335 case RPC_FC_STRUCTPAD4: 3336 case RPC_FC_STRUCTPAD5: 3337 case RPC_FC_STRUCTPAD6: 3338 case RPC_FC_STRUCTPAD7: 3339 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 3340 break; 3341 case RPC_FC_EMBEDDED_COMPLEX: 3342 pMemory += pFormat[1]; 3343 pFormat += 2; 3344 desc = pFormat + *(const SHORT*)pFormat; 3345 size = EmbeddedComplexSize(pStubMsg, desc); 3346 m = NdrFreer[*desc & NDR_TABLE_MASK]; 3347 if (m) 3348 { 3349 /* for some reason interface pointers aren't generated as 3350 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 3351 * they still need the dereferencing treatment that pointers are 3352 * given */ 3353 if (*desc == RPC_FC_IP) 3354 m(pStubMsg, *(unsigned char **)pMemory, desc); 3355 else 3356 m(pStubMsg, pMemory, desc); 3357 } 3358 pMemory += size; 3359 pFormat += 2; 3360 continue; 3361 case RPC_FC_PAD: 3362 break; 3363 default: 3364 FIXME("unhandled format 0x%02x\n", *pFormat); 3365 } 3366 pFormat++; 3367 } 3368 3369 return pMemory; 3370 } 3371 3372 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 3373 PFORMAT_STRING pFormat, 3374 PFORMAT_STRING pPointer) 3375 { 3376 PFORMAT_STRING desc; 3377 ULONG size = 0; 3378 3379 while (*pFormat != RPC_FC_END) { 3380 switch (*pFormat) { 3381 case RPC_FC_BYTE: 3382 case RPC_FC_CHAR: 3383 case RPC_FC_SMALL: 3384 case RPC_FC_USMALL: 3385 size += 1; 3386 safe_buffer_increment(pStubMsg, 1); 3387 break; 3388 case RPC_FC_WCHAR: 3389 case RPC_FC_SHORT: 3390 case RPC_FC_USHORT: 3391 size += 2; 3392 safe_buffer_increment(pStubMsg, 2); 3393 break; 3394 case RPC_FC_ENUM16: 3395 size += 4; 3396 safe_buffer_increment(pStubMsg, 2); 3397 break; 3398 case RPC_FC_LONG: 3399 case RPC_FC_ULONG: 3400 case RPC_FC_ENUM32: 3401 case RPC_FC_FLOAT: 3402 size += 4; 3403 safe_buffer_increment(pStubMsg, 4); 3404 break; 3405 case RPC_FC_INT3264: 3406 case RPC_FC_UINT3264: 3407 size += sizeof(INT_PTR); 3408 safe_buffer_increment(pStubMsg, 4); 3409 break; 3410 case RPC_FC_HYPER: 3411 case RPC_FC_DOUBLE: 3412 size += 8; 3413 safe_buffer_increment(pStubMsg, 8); 3414 break; 3415 case RPC_FC_RP: 3416 case RPC_FC_UP: 3417 case RPC_FC_OP: 3418 case RPC_FC_FP: 3419 case RPC_FC_POINTER: 3420 { 3421 unsigned char *saved_buffer; 3422 BOOL pointer_buffer_mark_set = FALSE; 3423 if (*pFormat != RPC_FC_POINTER) 3424 pPointer = pFormat; 3425 if (*pPointer != RPC_FC_RP) 3426 align_pointer(&pStubMsg->Buffer, 4); 3427 saved_buffer = pStubMsg->Buffer; 3428 if (pStubMsg->PointerBufferMark) 3429 { 3430 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 3431 pStubMsg->PointerBufferMark = NULL; 3432 pointer_buffer_mark_set = TRUE; 3433 } 3434 else if (*pPointer != RPC_FC_RP) 3435 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 3436 3437 if (!pStubMsg->IgnoreEmbeddedPointers) 3438 PointerMemorySize(pStubMsg, saved_buffer, pPointer); 3439 if (pointer_buffer_mark_set) 3440 { 3441 STD_OVERFLOW_CHECK(pStubMsg); 3442 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 3443 pStubMsg->Buffer = saved_buffer; 3444 if (*pPointer != RPC_FC_RP) 3445 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 3446 } 3447 if (*pFormat == RPC_FC_POINTER) 3448 pPointer += 4; 3449 else 3450 pFormat += 4; 3451 size += sizeof(void *); 3452 break; 3453 } 3454 case RPC_FC_ALIGNM2: 3455 align_length(&size, 2); 3456 break; 3457 case RPC_FC_ALIGNM4: 3458 align_length(&size, 4); 3459 break; 3460 case RPC_FC_ALIGNM8: 3461 align_length(&size, 8); 3462 break; 3463 case RPC_FC_STRUCTPAD1: 3464 case RPC_FC_STRUCTPAD2: 3465 case RPC_FC_STRUCTPAD3: 3466 case RPC_FC_STRUCTPAD4: 3467 case RPC_FC_STRUCTPAD5: 3468 case RPC_FC_STRUCTPAD6: 3469 case RPC_FC_STRUCTPAD7: 3470 size += *pFormat - RPC_FC_STRUCTPAD1 + 1; 3471 break; 3472 case RPC_FC_EMBEDDED_COMPLEX: 3473 size += pFormat[1]; 3474 pFormat += 2; 3475 desc = pFormat + *(const SHORT*)pFormat; 3476 size += EmbeddedComplexMemorySize(pStubMsg, desc); 3477 pFormat += 2; 3478 continue; 3479 case RPC_FC_PAD: 3480 break; 3481 default: 3482 FIXME("unhandled format 0x%02x\n", *pFormat); 3483 } 3484 pFormat++; 3485 } 3486 3487 return size; 3488 } 3489 3490 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 3491 { 3492 PFORMAT_STRING desc; 3493 ULONG size = 0; 3494 3495 while (*pFormat != RPC_FC_END) { 3496 switch (*pFormat) { 3497 case RPC_FC_BYTE: 3498 case RPC_FC_CHAR: 3499 case RPC_FC_SMALL: 3500 case RPC_FC_USMALL: 3501 size += 1; 3502 break; 3503 case RPC_FC_WCHAR: 3504 case RPC_FC_SHORT: 3505 case RPC_FC_USHORT: 3506 size += 2; 3507 break; 3508 case RPC_FC_LONG: 3509 case RPC_FC_ULONG: 3510 case RPC_FC_ENUM16: 3511 case RPC_FC_ENUM32: 3512 case RPC_FC_FLOAT: 3513 size += 4; 3514 break; 3515 case RPC_FC_INT3264: 3516 case RPC_FC_UINT3264: 3517 size += sizeof(INT_PTR); 3518 break; 3519 case RPC_FC_HYPER: 3520 case RPC_FC_DOUBLE: 3521 size += 8; 3522 break; 3523 case RPC_FC_RP: 3524 case RPC_FC_UP: 3525 case RPC_FC_OP: 3526 case RPC_FC_FP: 3527 case RPC_FC_POINTER: 3528 size += sizeof(void *); 3529 if (*pFormat != RPC_FC_POINTER) 3530 pFormat += 4; 3531 break; 3532 case RPC_FC_ALIGNM2: 3533 align_length(&size, 2); 3534 break; 3535 case RPC_FC_ALIGNM4: 3536 align_length(&size, 4); 3537 break; 3538 case RPC_FC_ALIGNM8: 3539 align_length(&size, 8); 3540 break; 3541 case RPC_FC_STRUCTPAD1: 3542 case RPC_FC_STRUCTPAD2: 3543 case RPC_FC_STRUCTPAD3: 3544 case RPC_FC_STRUCTPAD4: 3545 case RPC_FC_STRUCTPAD5: 3546 case RPC_FC_STRUCTPAD6: 3547 case RPC_FC_STRUCTPAD7: 3548 size += *pFormat - RPC_FC_STRUCTPAD1 + 1; 3549 break; 3550 case RPC_FC_EMBEDDED_COMPLEX: 3551 size += pFormat[1]; 3552 pFormat += 2; 3553 desc = pFormat + *(const SHORT*)pFormat; 3554 size += EmbeddedComplexSize(pStubMsg, desc); 3555 pFormat += 2; 3556 continue; 3557 case RPC_FC_PAD: 3558 break; 3559 default: 3560 FIXME("unhandled format 0x%02x\n", *pFormat); 3561 } 3562 pFormat++; 3563 } 3564 3565 return size; 3566 } 3567 3568 /*********************************************************************** 3569 * NdrComplexStructMarshall [RPCRT4.@] 3570 */ 3571 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 3572 unsigned char *pMemory, 3573 PFORMAT_STRING pFormat) 3574 { 3575 PFORMAT_STRING conf_array = NULL; 3576 PFORMAT_STRING pointer_desc = NULL; 3577 unsigned char *OldMemory = pStubMsg->Memory; 3578 BOOL pointer_buffer_mark_set = FALSE; 3579 ULONG count = 0; 3580 ULONG max_count = 0; 3581 ULONG offset = 0; 3582 3583 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3584 3585 if (!pStubMsg->PointerBufferMark) 3586 { 3587 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 3588 /* save buffer length */ 3589 ULONG saved_buffer_length = pStubMsg->BufferLength; 3590 3591 /* get the buffer pointer after complex array data, but before 3592 * pointer data */ 3593 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; 3594 pStubMsg->IgnoreEmbeddedPointers = 1; 3595 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); 3596 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 3597 3598 /* save it for use by embedded pointer code later */ 3599 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; 3600 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer)); 3601 pointer_buffer_mark_set = TRUE; 3602 3603 /* restore the original buffer length */ 3604 pStubMsg->BufferLength = saved_buffer_length; 3605 } 3606 3607 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1); 3608 3609 pFormat += 4; 3610 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 3611 pFormat += 2; 3612 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 3613 pFormat += 2; 3614 3615 pStubMsg->Memory = pMemory; 3616 3617 if (conf_array) 3618 { 3619 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat); 3620 array_compute_and_write_conformance(conf_array[0], pStubMsg, 3621 pMemory + struct_size, conf_array); 3622 /* these could be changed in ComplexMarshall so save them for later */ 3623 max_count = pStubMsg->MaxCount; 3624 count = pStubMsg->ActualCount; 3625 offset = pStubMsg->Offset; 3626 } 3627 3628 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc); 3629 3630 if (conf_array) 3631 { 3632 pStubMsg->MaxCount = max_count; 3633 pStubMsg->ActualCount = count; 3634 pStubMsg->Offset = offset; 3635 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory, 3636 conf_array, TRUE /* fHasPointers */); 3637 } 3638 3639 pStubMsg->Memory = OldMemory; 3640 3641 if (pointer_buffer_mark_set) 3642 { 3643 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 3644 pStubMsg->PointerBufferMark = NULL; 3645 } 3646 3647 STD_OVERFLOW_CHECK(pStubMsg); 3648 3649 return NULL; 3650 } 3651 3652 /*********************************************************************** 3653 * NdrComplexStructUnmarshall [RPCRT4.@] 3654 */ 3655 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 3656 unsigned char **ppMemory, 3657 PFORMAT_STRING pFormat, 3658 unsigned char fMustAlloc) 3659 { 3660 unsigned size = *(const WORD*)(pFormat+2); 3661 PFORMAT_STRING conf_array = NULL; 3662 PFORMAT_STRING pointer_desc = NULL; 3663 unsigned char *pMemory; 3664 BOOL pointer_buffer_mark_set = FALSE; 3665 ULONG count = 0; 3666 ULONG max_count = 0; 3667 ULONG offset = 0; 3668 ULONG array_size = 0; 3669 3670 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 3671 3672 if (!pStubMsg->PointerBufferMark) 3673 { 3674 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 3675 /* save buffer pointer */ 3676 unsigned char *saved_buffer = pStubMsg->Buffer; 3677 3678 /* get the buffer pointer after complex array data, but before 3679 * pointer data */ 3680 pStubMsg->IgnoreEmbeddedPointers = 1; 3681 NdrComplexStructMemorySize(pStubMsg, pFormat); 3682 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 3683 3684 /* save it for use by embedded pointer code later */ 3685 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 3686 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer)); 3687 pointer_buffer_mark_set = TRUE; 3688 3689 /* restore the original buffer */ 3690 pStubMsg->Buffer = saved_buffer; 3691 } 3692 3693 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 3694 3695 pFormat += 4; 3696 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 3697 pFormat += 2; 3698 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 3699 pFormat += 2; 3700 3701 if (conf_array) 3702 { 3703 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array); 3704 size += array_size; 3705 3706 /* these could be changed in ComplexMarshall so save them for later */ 3707 max_count = pStubMsg->MaxCount; 3708 count = pStubMsg->ActualCount; 3709 offset = pStubMsg->Offset; 3710 } 3711 3712 if (!fMustAlloc && !*ppMemory) 3713 fMustAlloc = TRUE; 3714 if (fMustAlloc) 3715 *ppMemory = NdrAllocate(pStubMsg, size); 3716 3717 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc); 3718 3719 if (conf_array) 3720 { 3721 pStubMsg->MaxCount = max_count; 3722 pStubMsg->ActualCount = count; 3723 pStubMsg->Offset = offset; 3724 if (fMustAlloc) 3725 memset(pMemory, 0, array_size); 3726 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory, 3727 conf_array, FALSE, 3728 FALSE /* fUseBufferMemoryServer */, 3729 TRUE /* fUnmarshall */); 3730 } 3731 3732 if (pointer_buffer_mark_set) 3733 { 3734 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 3735 pStubMsg->PointerBufferMark = NULL; 3736 } 3737 3738 return NULL; 3739 } 3740 3741 /*********************************************************************** 3742 * NdrComplexStructBufferSize [RPCRT4.@] 3743 */ 3744 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 3745 unsigned char *pMemory, 3746 PFORMAT_STRING pFormat) 3747 { 3748 PFORMAT_STRING conf_array = NULL; 3749 PFORMAT_STRING pointer_desc = NULL; 3750 unsigned char *OldMemory = pStubMsg->Memory; 3751 int pointer_length_set = 0; 3752 ULONG count = 0; 3753 ULONG max_count = 0; 3754 ULONG offset = 0; 3755 3756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3757 3758 align_length(&pStubMsg->BufferLength, pFormat[1] + 1); 3759 3760 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) 3761 { 3762 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 3763 ULONG saved_buffer_length = pStubMsg->BufferLength; 3764 3765 /* get the buffer length after complex struct data, but before 3766 * pointer data */ 3767 pStubMsg->IgnoreEmbeddedPointers = 1; 3768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); 3769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 3770 3771 /* save it for use by embedded pointer code later */ 3772 pStubMsg->PointerLength = pStubMsg->BufferLength; 3773 pointer_length_set = 1; 3774 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length); 3775 3776 /* restore the original buffer length */ 3777 pStubMsg->BufferLength = saved_buffer_length; 3778 } 3779 3780 pFormat += 4; 3781 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 3782 pFormat += 2; 3783 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 3784 pFormat += 2; 3785 3786 pStubMsg->Memory = pMemory; 3787 3788 if (conf_array) 3789 { 3790 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat); 3791 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size, 3792 conf_array); 3793 3794 /* these could be changed in ComplexMarshall so save them for later */ 3795 max_count = pStubMsg->MaxCount; 3796 count = pStubMsg->ActualCount; 3797 offset = pStubMsg->Offset; 3798 } 3799 3800 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc); 3801 3802 if (conf_array) 3803 { 3804 pStubMsg->MaxCount = max_count; 3805 pStubMsg->ActualCount = count; 3806 pStubMsg->Offset = offset; 3807 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array, 3808 TRUE /* fHasPointers */); 3809 } 3810 3811 pStubMsg->Memory = OldMemory; 3812 3813 if(pointer_length_set) 3814 { 3815 pStubMsg->BufferLength = pStubMsg->PointerLength; 3816 pStubMsg->PointerLength = 0; 3817 } 3818 3819 } 3820 3821 /*********************************************************************** 3822 * NdrComplexStructMemorySize [RPCRT4.@] 3823 */ 3824 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 3825 PFORMAT_STRING pFormat) 3826 { 3827 unsigned size = *(const WORD*)(pFormat+2); 3828 PFORMAT_STRING conf_array = NULL; 3829 PFORMAT_STRING pointer_desc = NULL; 3830 ULONG count = 0; 3831 ULONG max_count = 0; 3832 ULONG offset = 0; 3833 3834 TRACE("(%p,%p)\n", pStubMsg, pFormat); 3835 3836 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 3837 3838 pFormat += 4; 3839 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 3840 pFormat += 2; 3841 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 3842 pFormat += 2; 3843 3844 if (conf_array) 3845 { 3846 array_read_conformance(conf_array[0], pStubMsg, conf_array); 3847 3848 /* these could be changed in ComplexStructMemorySize so save them for 3849 * later */ 3850 max_count = pStubMsg->MaxCount; 3851 count = pStubMsg->ActualCount; 3852 offset = pStubMsg->Offset; 3853 } 3854 3855 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc); 3856 3857 if (conf_array) 3858 { 3859 pStubMsg->MaxCount = max_count; 3860 pStubMsg->ActualCount = count; 3861 pStubMsg->Offset = offset; 3862 array_memory_size(conf_array[0], pStubMsg, conf_array, 3863 TRUE /* fHasPointers */); 3864 } 3865 3866 return size; 3867 } 3868 3869 /*********************************************************************** 3870 * NdrComplexStructFree [RPCRT4.@] 3871 */ 3872 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, 3873 unsigned char *pMemory, 3874 PFORMAT_STRING pFormat) 3875 { 3876 PFORMAT_STRING conf_array = NULL; 3877 PFORMAT_STRING pointer_desc = NULL; 3878 unsigned char *OldMemory = pStubMsg->Memory; 3879 3880 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3881 3882 pFormat += 4; 3883 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 3884 pFormat += 2; 3885 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 3886 pFormat += 2; 3887 3888 pStubMsg->Memory = pMemory; 3889 3890 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc); 3891 3892 if (conf_array) 3893 array_free(conf_array[0], pStubMsg, pMemory, conf_array, 3894 TRUE /* fHasPointers */); 3895 3896 pStubMsg->Memory = OldMemory; 3897 } 3898 3899 /*********************************************************************** 3900 * NdrConformantArrayMarshall [RPCRT4.@] 3901 */ 3902 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 3903 unsigned char *pMemory, 3904 PFORMAT_STRING pFormat) 3905 { 3906 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3907 if (pFormat[0] != RPC_FC_CARRAY) 3908 { 3909 ERR("invalid format = 0x%x\n", pFormat[0]); 3910 RpcRaiseException(RPC_X_BAD_STUB_DATA); 3911 } 3912 3913 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, 3914 pFormat); 3915 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 3916 TRUE /* fHasPointers */); 3917 3918 return NULL; 3919 } 3920 3921 /*********************************************************************** 3922 * NdrConformantArrayUnmarshall [RPCRT4.@] 3923 */ 3924 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 3925 unsigned char **ppMemory, 3926 PFORMAT_STRING pFormat, 3927 unsigned char fMustAlloc) 3928 { 3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 3930 if (pFormat[0] != RPC_FC_CARRAY) 3931 { 3932 ERR("invalid format = 0x%x\n", pFormat[0]); 3933 RpcRaiseException(RPC_X_BAD_STUB_DATA); 3934 } 3935 3936 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); 3937 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat, 3938 fMustAlloc, 3939 TRUE /* fUseBufferMemoryServer */, 3940 TRUE /* fUnmarshall */); 3941 3942 return NULL; 3943 } 3944 3945 /*********************************************************************** 3946 * NdrConformantArrayBufferSize [RPCRT4.@] 3947 */ 3948 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 3949 unsigned char *pMemory, 3950 PFORMAT_STRING pFormat) 3951 { 3952 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3953 if (pFormat[0] != RPC_FC_CARRAY) 3954 { 3955 ERR("invalid format = 0x%x\n", pFormat[0]); 3956 RpcRaiseException(RPC_X_BAD_STUB_DATA); 3957 } 3958 3959 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat); 3960 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 3961 TRUE /* fHasPointers */); 3962 } 3963 3964 /*********************************************************************** 3965 * NdrConformantArrayMemorySize [RPCRT4.@] 3966 */ 3967 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 3968 PFORMAT_STRING pFormat) 3969 { 3970 TRACE("(%p,%p)\n", pStubMsg, pFormat); 3971 if (pFormat[0] != RPC_FC_CARRAY) 3972 { 3973 ERR("invalid format = 0x%x\n", pFormat[0]); 3974 RpcRaiseException(RPC_X_BAD_STUB_DATA); 3975 } 3976 3977 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); 3978 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */); 3979 3980 return pStubMsg->MemorySize; 3981 } 3982 3983 /*********************************************************************** 3984 * NdrConformantArrayFree [RPCRT4.@] 3985 */ 3986 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 3987 unsigned char *pMemory, 3988 PFORMAT_STRING pFormat) 3989 { 3990 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 3991 if (pFormat[0] != RPC_FC_CARRAY) 3992 { 3993 ERR("invalid format = 0x%x\n", pFormat[0]); 3994 RpcRaiseException(RPC_X_BAD_STUB_DATA); 3995 } 3996 3997 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 3998 TRUE /* fHasPointers */); 3999 } 4000 4001 4002 /*********************************************************************** 4003 * NdrConformantVaryingArrayMarshall [RPCRT4.@] 4004 */ 4005 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg, 4006 unsigned char* pMemory, 4007 PFORMAT_STRING pFormat ) 4008 { 4009 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4010 4011 if (pFormat[0] != RPC_FC_CVARRAY) 4012 { 4013 ERR("invalid format type %x\n", pFormat[0]); 4014 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4015 return NULL; 4016 } 4017 4018 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, 4019 pFormat); 4020 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory, 4021 pFormat, TRUE /* fHasPointers */); 4022 4023 return NULL; 4024 } 4025 4026 4027 /*********************************************************************** 4028 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@] 4029 */ 4030 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, 4031 unsigned char** ppMemory, 4032 PFORMAT_STRING pFormat, 4033 unsigned char fMustAlloc ) 4034 { 4035 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 4036 4037 if (pFormat[0] != RPC_FC_CVARRAY) 4038 { 4039 ERR("invalid format type %x\n", pFormat[0]); 4040 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4041 return NULL; 4042 } 4043 4044 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); 4045 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory, 4046 pFormat, fMustAlloc, 4047 TRUE /* fUseBufferMemoryServer */, 4048 TRUE /* fUnmarshall */); 4049 4050 return NULL; 4051 } 4052 4053 4054 /*********************************************************************** 4055 * NdrConformantVaryingArrayFree [RPCRT4.@] 4056 */ 4057 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, 4058 unsigned char* pMemory, 4059 PFORMAT_STRING pFormat ) 4060 { 4061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4062 4063 if (pFormat[0] != RPC_FC_CVARRAY) 4064 { 4065 ERR("invalid format type %x\n", pFormat[0]); 4066 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4067 return; 4068 } 4069 4070 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, 4071 TRUE /* fHasPointers */); 4072 } 4073 4074 4075 /*********************************************************************** 4076 * NdrConformantVaryingArrayBufferSize [RPCRT4.@] 4077 */ 4078 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, 4079 unsigned char* pMemory, PFORMAT_STRING pFormat ) 4080 { 4081 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4082 4083 if (pFormat[0] != RPC_FC_CVARRAY) 4084 { 4085 ERR("invalid format type %x\n", pFormat[0]); 4086 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4087 return; 4088 } 4089 4090 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, 4091 pFormat); 4092 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, 4093 TRUE /* fHasPointers */); 4094 } 4095 4096 4097 /*********************************************************************** 4098 * NdrConformantVaryingArrayMemorySize [RPCRT4.@] 4099 */ 4100 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, 4101 PFORMAT_STRING pFormat ) 4102 { 4103 TRACE("(%p, %p)\n", pStubMsg, pFormat); 4104 4105 if (pFormat[0] != RPC_FC_CVARRAY) 4106 { 4107 ERR("invalid format type %x\n", pFormat[0]); 4108 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4109 return pStubMsg->MemorySize; 4110 } 4111 4112 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); 4113 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat, 4114 TRUE /* fHasPointers */); 4115 4116 return pStubMsg->MemorySize; 4117 } 4118 4119 4120 /*********************************************************************** 4121 * NdrComplexArrayMarshall [RPCRT4.@] 4122 */ 4123 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 4124 unsigned char *pMemory, 4125 PFORMAT_STRING pFormat) 4126 { 4127 BOOL pointer_buffer_mark_set = FALSE; 4128 4129 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4130 4131 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 4132 { 4133 ERR("invalid format type %x\n", pFormat[0]); 4134 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4135 return NULL; 4136 } 4137 4138 if (!pStubMsg->PointerBufferMark) 4139 { 4140 /* save buffer fields that may be changed by buffer sizer functions 4141 * and that may be needed later on */ 4142 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 4143 ULONG saved_buffer_length = pStubMsg->BufferLength; 4144 ULONG_PTR saved_max_count = pStubMsg->MaxCount; 4145 ULONG saved_offset = pStubMsg->Offset; 4146 ULONG saved_actual_count = pStubMsg->ActualCount; 4147 4148 /* get the buffer pointer after complex array data, but before 4149 * pointer data */ 4150 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; 4151 pStubMsg->IgnoreEmbeddedPointers = 1; 4152 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); 4153 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 4154 4155 /* save it for use by embedded pointer code later */ 4156 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; 4157 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer)); 4158 pointer_buffer_mark_set = TRUE; 4159 4160 /* restore fields */ 4161 pStubMsg->ActualCount = saved_actual_count; 4162 pStubMsg->Offset = saved_offset; 4163 pStubMsg->MaxCount = saved_max_count; 4164 pStubMsg->BufferLength = saved_buffer_length; 4165 } 4166 4167 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat); 4168 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg, 4169 pMemory, pFormat, TRUE /* fHasPointers */); 4170 4171 STD_OVERFLOW_CHECK(pStubMsg); 4172 4173 if (pointer_buffer_mark_set) 4174 { 4175 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 4176 pStubMsg->PointerBufferMark = NULL; 4177 } 4178 4179 return NULL; 4180 } 4181 4182 /*********************************************************************** 4183 * NdrComplexArrayUnmarshall [RPCRT4.@] 4184 */ 4185 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 4186 unsigned char **ppMemory, 4187 PFORMAT_STRING pFormat, 4188 unsigned char fMustAlloc) 4189 { 4190 unsigned char *saved_buffer; 4191 BOOL pointer_buffer_mark_set = FALSE; 4192 int saved_ignore_embedded; 4193 4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 4195 4196 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 4197 { 4198 ERR("invalid format type %x\n", pFormat[0]); 4199 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4200 return NULL; 4201 } 4202 4203 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 4204 /* save buffer pointer */ 4205 saved_buffer = pStubMsg->Buffer; 4206 /* get the buffer pointer after complex array data, but before 4207 * pointer data */ 4208 pStubMsg->IgnoreEmbeddedPointers = 1; 4209 pStubMsg->MemorySize = 0; 4210 NdrComplexArrayMemorySize(pStubMsg, pFormat); 4211 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 4212 4213 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer)); 4214 if (!pStubMsg->PointerBufferMark) 4215 { 4216 /* save it for use by embedded pointer code later */ 4217 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 4218 pointer_buffer_mark_set = TRUE; 4219 } 4220 /* restore the original buffer */ 4221 pStubMsg->Buffer = saved_buffer; 4222 4223 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat); 4224 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc, 4225 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */); 4226 4227 if (pointer_buffer_mark_set) 4228 { 4229 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 4230 pStubMsg->PointerBufferMark = NULL; 4231 } 4232 4233 return NULL; 4234 } 4235 4236 /*********************************************************************** 4237 * NdrComplexArrayBufferSize [RPCRT4.@] 4238 */ 4239 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 4240 unsigned char *pMemory, 4241 PFORMAT_STRING pFormat) 4242 { 4243 int pointer_length_set = 0; 4244 4245 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4246 4247 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 4248 { 4249 ERR("invalid format type %x\n", pFormat[0]); 4250 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4251 return; 4252 } 4253 4254 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) 4255 { 4256 /* save buffer fields that may be changed by buffer sizer functions 4257 * and that may be needed later on */ 4258 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 4259 ULONG saved_buffer_length = pStubMsg->BufferLength; 4260 ULONG_PTR saved_max_count = pStubMsg->MaxCount; 4261 ULONG saved_offset = pStubMsg->Offset; 4262 ULONG saved_actual_count = pStubMsg->ActualCount; 4263 4264 /* get the buffer pointer after complex array data, but before 4265 * pointer data */ 4266 pStubMsg->IgnoreEmbeddedPointers = 1; 4267 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); 4268 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 4269 4270 /* save it for use by embedded pointer code later */ 4271 pStubMsg->PointerLength = pStubMsg->BufferLength; 4272 pointer_length_set = 1; 4273 4274 /* restore fields */ 4275 pStubMsg->ActualCount = saved_actual_count; 4276 pStubMsg->Offset = saved_offset; 4277 pStubMsg->MaxCount = saved_max_count; 4278 pStubMsg->BufferLength = saved_buffer_length; 4279 } 4280 4281 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat); 4282 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */); 4283 4284 if(pointer_length_set) 4285 { 4286 pStubMsg->BufferLength = pStubMsg->PointerLength; 4287 pStubMsg->PointerLength = 0; 4288 } 4289 } 4290 4291 /*********************************************************************** 4292 * NdrComplexArrayMemorySize [RPCRT4.@] 4293 */ 4294 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 4295 PFORMAT_STRING pFormat) 4296 { 4297 TRACE("(%p,%p)\n", pStubMsg, pFormat); 4298 4299 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 4300 { 4301 ERR("invalid format type %x\n", pFormat[0]); 4302 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4303 return 0; 4304 } 4305 4306 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat); 4307 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */); 4308 return pStubMsg->MemorySize; 4309 } 4310 4311 /*********************************************************************** 4312 * NdrComplexArrayFree [RPCRT4.@] 4313 */ 4314 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 4315 unsigned char *pMemory, 4316 PFORMAT_STRING pFormat) 4317 { 4318 ULONG i, count, def; 4319 4320 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4321 4322 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 4323 { 4324 ERR("invalid format type %x\n", pFormat[0]); 4325 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4326 return; 4327 } 4328 4329 def = *(const WORD*)&pFormat[2]; 4330 pFormat += 4; 4331 4332 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); 4333 TRACE("conformance = %ld\n", pStubMsg->MaxCount); 4334 4335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 4336 TRACE("variance = %d\n", pStubMsg->ActualCount); 4337 4338 count = pStubMsg->ActualCount; 4339 for (i = 0; i < count; i++) 4340 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); 4341 } 4342 4343 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg, 4344 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat, 4345 USER_MARSHAL_CB *umcb) 4346 { 4347 umcb->Flags = MAKELONG(pStubMsg->dwDestContext, 4348 pStubMsg->RpcMsg->DataRepresentation); 4349 umcb->pStubMsg = pStubMsg; 4350 umcb->pReserve = NULL; 4351 umcb->Signature = USER_MARSHAL_CB_SIGNATURE; 4352 umcb->CBType = cbtype; 4353 umcb->pFormat = pFormat; 4354 umcb->pTypeFormat = NULL /* FIXME */; 4355 } 4356 4357 #define USER_MARSHAL_PTR_PREFIX \ 4358 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \ 4359 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) ) 4360 4361 /*********************************************************************** 4362 * NdrUserMarshalMarshall [RPCRT4.@] 4363 */ 4364 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg, 4365 unsigned char *pMemory, 4366 PFORMAT_STRING pFormat) 4367 { 4368 unsigned flags = pFormat[1]; 4369 unsigned index = *(const WORD*)&pFormat[2]; 4370 unsigned char *saved_buffer = NULL; 4371 USER_MARSHAL_CB umcb; 4372 4373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4374 TRACE("index=%d\n", index); 4375 4376 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb); 4377 4378 if (flags & USER_MARSHAL_POINTER) 4379 { 4380 align_pointer_clear(&pStubMsg->Buffer, 4); 4381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX); 4382 pStubMsg->Buffer += 4; 4383 if (pStubMsg->PointerBufferMark) 4384 { 4385 saved_buffer = pStubMsg->Buffer; 4386 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 4387 pStubMsg->PointerBufferMark = NULL; 4388 } 4389 align_pointer_clear(&pStubMsg->Buffer, 8); 4390 } 4391 else 4392 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1); 4393 4394 pStubMsg->Buffer = 4395 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall( 4396 &umcb.Flags, pStubMsg->Buffer, pMemory); 4397 4398 if (saved_buffer) 4399 { 4400 STD_OVERFLOW_CHECK(pStubMsg); 4401 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 4402 pStubMsg->Buffer = saved_buffer; 4403 } 4404 4405 STD_OVERFLOW_CHECK(pStubMsg); 4406 4407 return NULL; 4408 } 4409 4410 /*********************************************************************** 4411 * NdrUserMarshalUnmarshall [RPCRT4.@] 4412 */ 4413 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 4414 unsigned char **ppMemory, 4415 PFORMAT_STRING pFormat, 4416 unsigned char fMustAlloc) 4417 { 4418 unsigned flags = pFormat[1]; 4419 unsigned index = *(const WORD*)&pFormat[2]; 4420 DWORD memsize = *(const WORD*)&pFormat[4]; 4421 unsigned char *saved_buffer = NULL; 4422 USER_MARSHAL_CB umcb; 4423 4424 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 4425 TRACE("index=%d\n", index); 4426 4427 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb); 4428 4429 if (flags & USER_MARSHAL_POINTER) 4430 { 4431 align_pointer(&pStubMsg->Buffer, 4); 4432 /* skip pointer prefix */ 4433 pStubMsg->Buffer += 4; 4434 if (pStubMsg->PointerBufferMark) 4435 { 4436 saved_buffer = pStubMsg->Buffer; 4437 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 4438 pStubMsg->PointerBufferMark = NULL; 4439 } 4440 align_pointer(&pStubMsg->Buffer, 8); 4441 } 4442 else 4443 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1); 4444 4445 if (!fMustAlloc && !*ppMemory) 4446 fMustAlloc = TRUE; 4447 if (fMustAlloc) 4448 { 4449 *ppMemory = NdrAllocate(pStubMsg, memsize); 4450 memset(*ppMemory, 0, memsize); 4451 } 4452 4453 pStubMsg->Buffer = 4454 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall( 4455 &umcb.Flags, pStubMsg->Buffer, *ppMemory); 4456 4457 if (saved_buffer) 4458 { 4459 STD_OVERFLOW_CHECK(pStubMsg); 4460 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 4461 pStubMsg->Buffer = saved_buffer; 4462 } 4463 4464 return NULL; 4465 } 4466 4467 /*********************************************************************** 4468 * NdrUserMarshalBufferSize [RPCRT4.@] 4469 */ 4470 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 4471 unsigned char *pMemory, 4472 PFORMAT_STRING pFormat) 4473 { 4474 unsigned flags = pFormat[1]; 4475 unsigned index = *(const WORD*)&pFormat[2]; 4476 DWORD bufsize = *(const WORD*)&pFormat[6]; 4477 USER_MARSHAL_CB umcb; 4478 ULONG saved_buffer_length = 0; 4479 4480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4481 TRACE("index=%d\n", index); 4482 4483 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb); 4484 4485 if (flags & USER_MARSHAL_POINTER) 4486 { 4487 align_length(&pStubMsg->BufferLength, 4); 4488 /* skip pointer prefix */ 4489 safe_buffer_length_increment(pStubMsg, 4); 4490 if (pStubMsg->IgnoreEmbeddedPointers) 4491 return; 4492 if (pStubMsg->PointerLength) 4493 { 4494 saved_buffer_length = pStubMsg->BufferLength; 4495 pStubMsg->BufferLength = pStubMsg->PointerLength; 4496 pStubMsg->PointerLength = 0; 4497 } 4498 align_length(&pStubMsg->BufferLength, 8); 4499 } 4500 else 4501 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1); 4502 4503 if (bufsize) { 4504 TRACE("size=%d\n", bufsize); 4505 safe_buffer_length_increment(pStubMsg, bufsize); 4506 } 4507 else 4508 pStubMsg->BufferLength = 4509 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize( 4510 &umcb.Flags, pStubMsg->BufferLength, pMemory); 4511 4512 if (saved_buffer_length) 4513 { 4514 pStubMsg->PointerLength = pStubMsg->BufferLength; 4515 pStubMsg->BufferLength = saved_buffer_length; 4516 } 4517 4518 } 4519 4520 /*********************************************************************** 4521 * NdrUserMarshalMemorySize [RPCRT4.@] 4522 */ 4523 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 4524 PFORMAT_STRING pFormat) 4525 { 4526 unsigned flags = pFormat[1]; 4527 unsigned index = *(const WORD*)&pFormat[2]; 4528 DWORD memsize = *(const WORD*)&pFormat[4]; 4529 DWORD bufsize = *(const WORD*)&pFormat[6]; 4530 4531 TRACE("(%p,%p)\n", pStubMsg, pFormat); 4532 TRACE("index=%d\n", index); 4533 4534 pStubMsg->MemorySize += memsize; 4535 4536 if (flags & USER_MARSHAL_POINTER) 4537 { 4538 align_pointer(&pStubMsg->Buffer, 4); 4539 /* skip pointer prefix */ 4540 pStubMsg->Buffer += 4; 4541 if (pStubMsg->IgnoreEmbeddedPointers) 4542 return pStubMsg->MemorySize; 4543 align_pointer(&pStubMsg->Buffer, 8); 4544 } 4545 else 4546 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1); 4547 4548 if (!bufsize) 4549 FIXME("not implemented for varying buffer size\n"); 4550 4551 pStubMsg->Buffer += bufsize; 4552 4553 return pStubMsg->MemorySize; 4554 } 4555 4556 /*********************************************************************** 4557 * NdrUserMarshalFree [RPCRT4.@] 4558 */ 4559 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg, 4560 unsigned char *pMemory, 4561 PFORMAT_STRING pFormat) 4562 { 4563 /* unsigned flags = pFormat[1]; */ 4564 unsigned index = *(const WORD*)&pFormat[2]; 4565 USER_MARSHAL_CB umcb; 4566 4567 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 4568 TRACE("index=%d\n", index); 4569 4570 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb); 4571 4572 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree( 4573 &umcb.Flags, pMemory); 4574 } 4575 4576 /*********************************************************************** 4577 * NdrGetUserMarshalInfo [RPCRT4.@] 4578 */ 4579 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi) 4580 { 4581 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags); 4582 4583 TRACE("(%p,%u,%p)\n", flags, level, umi); 4584 4585 if (level != 1) 4586 return RPC_S_INVALID_ARG; 4587 4588 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1)); 4589 umi->InformationLevel = level; 4590 4591 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE) 4592 return RPC_S_INVALID_ARG; 4593 4594 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate; 4595 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree; 4596 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer; 4597 4598 switch (umcb->CBType) 4599 { 4600 case USER_MARSHAL_CB_MARSHALL: 4601 case USER_MARSHAL_CB_UNMARSHALL: 4602 { 4603 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg; 4604 unsigned char *buffer_start = msg->Buffer; 4605 unsigned char *buffer_end = 4606 (unsigned char *)msg->Buffer + msg->BufferLength; 4607 4608 if (umcb->pStubMsg->Buffer < buffer_start || 4609 umcb->pStubMsg->Buffer > buffer_end) 4610 return RPC_X_INVALID_BUFFER; 4611 4612 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer; 4613 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer; 4614 break; 4615 } 4616 case USER_MARSHAL_CB_BUFFER_SIZE: 4617 case USER_MARSHAL_CB_FREE: 4618 break; 4619 default: 4620 WARN("unrecognised CBType %d\n", umcb->CBType); 4621 } 4622 4623 return RPC_S_OK; 4624 } 4625 4626 /*********************************************************************** 4627 * NdrClearOutParameters [RPCRT4.@] 4628 */ 4629 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg, 4630 PFORMAT_STRING pFormat, 4631 void *ArgAddr) 4632 { 4633 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr); 4634 } 4635 4636 /*********************************************************************** 4637 * NdrConvert [RPCRT4.@] 4638 */ 4639 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) 4640 { 4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat); 4642 /* FIXME: since this stub doesn't do any converting, the proper behavior 4643 is to raise an exception */ 4644 } 4645 4646 /*********************************************************************** 4647 * NdrConvert2 [RPCRT4.@] 4648 */ 4649 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams ) 4650 { 4651 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n", 4652 pStubMsg, pFormat, NumberParams); 4653 /* FIXME: since this stub doesn't do any converting, the proper behavior 4654 is to raise an exception */ 4655 } 4656 4657 #include "pshpack1.h" 4658 typedef struct _NDR_CSTRUCT_FORMAT 4659 { 4660 unsigned char type; 4661 unsigned char alignment; 4662 unsigned short memory_size; 4663 short offset_to_array_description; 4664 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT; 4665 #include "poppack.h" 4666 4667 /*********************************************************************** 4668 * NdrConformantStructMarshall [RPCRT4.@] 4669 */ 4670 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 4671 unsigned char *pMemory, 4672 PFORMAT_STRING pFormat) 4673 { 4674 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 4675 PFORMAT_STRING pCArrayFormat; 4676 ULONG esize, bufsize; 4677 4678 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4679 4680 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 4681 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 4682 { 4683 ERR("invalid format type %x\n", pCStructFormat->type); 4684 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4685 return NULL; 4686 } 4687 4688 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 4689 pCStructFormat->offset_to_array_description; 4690 if (*pCArrayFormat != RPC_FC_CARRAY) 4691 { 4692 ERR("invalid array format type %x\n", pCStructFormat->type); 4693 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4694 return NULL; 4695 } 4696 esize = *(const WORD*)(pCArrayFormat+2); 4697 4698 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, 4699 pCArrayFormat + 4, 0); 4700 4701 WriteConformance(pStubMsg); 4702 4703 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1); 4704 4705 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 4706 4707 bufsize = safe_multiply(esize, pStubMsg->MaxCount); 4708 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ 4709 { 4710 ERR("integer overflow of memory_size %u with bufsize %u\n", 4711 pCStructFormat->memory_size, bufsize); 4712 RpcRaiseException(RPC_X_BAD_STUB_DATA); 4713 } 4714 /* copy constant sized part of struct */ 4715 pStubMsg->BufferMark = pStubMsg->Buffer; 4716 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize); 4717 4718 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 4719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 4720 4721 return NULL; 4722 } 4723 4724 /*********************************************************************** 4725 * NdrConformantStructUnmarshall [RPCRT4.@] 4726 */ 4727 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 4728 unsigned char **ppMemory, 4729 PFORMAT_STRING pFormat, 4730 unsigned char fMustAlloc) 4731 { 4732 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 4733 PFORMAT_STRING pCArrayFormat; 4734 ULONG esize, bufsize; 4735 unsigned char *saved_buffer; 4736 4737 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 4738 4739 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 4740 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 4741 { 4742 ERR("invalid format type %x\n", pCStructFormat->type); 4743 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4744 return NULL; 4745 } 4746 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 4747 pCStructFormat->offset_to_array_description; 4748 if (*pCArrayFormat != RPC_FC_CARRAY) 4749 { 4750 ERR("invalid array format type %x\n", pCStructFormat->type); 4751 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4752 return NULL; 4753 } 4754 esize = *(const WORD*)(pCArrayFormat+2); 4755 4756 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4); 4757 4758 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1); 4759 4760 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 4761 4762 bufsize = safe_multiply(esize, pStubMsg->MaxCount); 4763 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ 4764 { 4765 ERR("integer overflow of memory_size %u with bufsize %u\n", 4766 pCStructFormat->memory_size, bufsize); 4767 RpcRaiseException(RPC_X_BAD_STUB_DATA); 4768 } 4769 4770 if (fMustAlloc) 4771 { 4772 SIZE_T size = pCStructFormat->memory_size + bufsize; 4773 *ppMemory = NdrAllocate(pStubMsg, size); 4774 } 4775 else 4776 { 4777 if (!pStubMsg->IsClient && !*ppMemory) 4778 /* for servers, we just point straight into the RPC buffer */ 4779 *ppMemory = pStubMsg->Buffer; 4780 } 4781 4782 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 4783 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize); 4784 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 4785 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 4786 4787 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 4788 if (*ppMemory != saved_buffer) 4789 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize); 4790 4791 return NULL; 4792 } 4793 4794 /*********************************************************************** 4795 * NdrConformantStructBufferSize [RPCRT4.@] 4796 */ 4797 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 4798 unsigned char *pMemory, 4799 PFORMAT_STRING pFormat) 4800 { 4801 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 4802 PFORMAT_STRING pCArrayFormat; 4803 ULONG esize; 4804 4805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4806 4807 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 4808 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 4809 { 4810 ERR("invalid format type %x\n", pCStructFormat->type); 4811 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4812 return; 4813 } 4814 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 4815 pCStructFormat->offset_to_array_description; 4816 if (*pCArrayFormat != RPC_FC_CARRAY) 4817 { 4818 ERR("invalid array format type %x\n", pCStructFormat->type); 4819 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4820 return; 4821 } 4822 esize = *(const WORD*)(pCArrayFormat+2); 4823 4824 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0); 4825 SizeConformance(pStubMsg); 4826 4827 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1); 4828 4829 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 4830 4831 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size); 4832 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); 4833 4834 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 4835 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 4836 } 4837 4838 /*********************************************************************** 4839 * NdrConformantStructMemorySize [RPCRT4.@] 4840 */ 4841 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 4842 PFORMAT_STRING pFormat) 4843 { 4844 FIXME("stub\n"); 4845 return 0; 4846 } 4847 4848 /*********************************************************************** 4849 * NdrConformantStructFree [RPCRT4.@] 4850 */ 4851 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, 4852 unsigned char *pMemory, 4853 PFORMAT_STRING pFormat) 4854 { 4855 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 4856 PFORMAT_STRING pCArrayFormat; 4857 4858 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4859 4860 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 4861 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 4862 { 4863 ERR("invalid format type %x\n", pCStructFormat->type); 4864 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4865 return; 4866 } 4867 4868 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 4869 pCStructFormat->offset_to_array_description; 4870 if (*pCArrayFormat != RPC_FC_CARRAY) 4871 { 4872 ERR("invalid array format type %x\n", pCStructFormat->type); 4873 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4874 return; 4875 } 4876 4877 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, 4878 pCArrayFormat + 4, 0); 4879 4880 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 4881 4882 /* copy constant sized part of struct */ 4883 pStubMsg->BufferMark = pStubMsg->Buffer; 4884 4885 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 4886 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 4887 } 4888 4889 /*********************************************************************** 4890 * NdrConformantVaryingStructMarshall [RPCRT4.@] 4891 */ 4892 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 4893 unsigned char *pMemory, 4894 PFORMAT_STRING pFormat) 4895 { 4896 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 4897 PFORMAT_STRING pCVArrayFormat; 4898 4899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 4900 4901 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 4902 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 4903 { 4904 ERR("invalid format type %x\n", pCVStructFormat->type); 4905 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4906 return NULL; 4907 } 4908 4909 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 4910 pCVStructFormat->offset_to_array_description; 4911 4912 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg, 4913 pMemory + pCVStructFormat->memory_size, 4914 pCVArrayFormat); 4915 4916 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 4917 4918 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 4919 4920 /* write constant sized part */ 4921 pStubMsg->BufferMark = pStubMsg->Buffer; 4922 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size); 4923 4924 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg, 4925 pMemory + pCVStructFormat->memory_size, 4926 pCVArrayFormat, FALSE /* fHasPointers */); 4927 4928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 4929 4930 return NULL; 4931 } 4932 4933 /*********************************************************************** 4934 * NdrConformantVaryingStructUnmarshall [RPCRT4.@] 4935 */ 4936 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 4937 unsigned char **ppMemory, 4938 PFORMAT_STRING pFormat, 4939 unsigned char fMustAlloc) 4940 { 4941 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 4942 PFORMAT_STRING pCVArrayFormat; 4943 ULONG memsize, bufsize; 4944 unsigned char *saved_buffer, *saved_array_buffer; 4945 ULONG offset; 4946 unsigned char *array_memory; 4947 4948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 4949 4950 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 4951 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 4952 { 4953 ERR("invalid format type %x\n", pCVStructFormat->type); 4954 RpcRaiseException(RPC_S_INTERNAL_ERROR); 4955 return NULL; 4956 } 4957 4958 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 4959 pCVStructFormat->offset_to_array_description; 4960 4961 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg, 4962 pCVArrayFormat); 4963 4964 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 4965 4966 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 4967 4968 /* work out how much memory to allocate if we need to do so */ 4969 if (!fMustAlloc && !*ppMemory) 4970 fMustAlloc = TRUE; 4971 if (fMustAlloc) 4972 { 4973 SIZE_T size = pCVStructFormat->memory_size + memsize; 4974 *ppMemory = NdrAllocate(pStubMsg, size); 4975 } 4976 4977 /* mark the start of the constant data */ 4978 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 4979 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); 4980 4981 array_memory = *ppMemory + pCVStructFormat->memory_size; 4982 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg, 4983 &array_memory, pCVArrayFormat, 4984 FALSE /* fMustAlloc */, 4985 FALSE /* fUseServerBufferMemory */, 4986 FALSE /* fUnmarshall */); 4987 4988 /* save offset in case unmarshalling pointers changes it */ 4989 offset = pStubMsg->Offset; 4990 4991 /* mark the start of the array data */ 4992 saved_array_buffer = pStubMsg->Buffer; 4993 safe_buffer_increment(pStubMsg, bufsize); 4994 4995 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 4996 4997 /* copy the constant data */ 4998 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size); 4999 /* copy the array data */ 5000 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size); 5001 memcpy(*ppMemory + pCVStructFormat->memory_size + offset, 5002 saved_array_buffer, bufsize); 5003 5004 if (*pCVArrayFormat == RPC_FC_C_CSTRING) 5005 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); 5006 else if (*pCVArrayFormat == RPC_FC_C_WSTRING) 5007 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size))); 5008 5009 return NULL; 5010 } 5011 5012 /*********************************************************************** 5013 * NdrConformantVaryingStructBufferSize [RPCRT4.@] 5014 */ 5015 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 5016 unsigned char *pMemory, 5017 PFORMAT_STRING pFormat) 5018 { 5019 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 5020 PFORMAT_STRING pCVArrayFormat; 5021 5022 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5023 5024 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 5025 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 5026 { 5027 ERR("invalid format type %x\n", pCVStructFormat->type); 5028 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5029 return; 5030 } 5031 5032 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 5033 pCVStructFormat->offset_to_array_description; 5034 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg, 5035 pMemory + pCVStructFormat->memory_size, 5036 pCVArrayFormat); 5037 5038 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1); 5039 5040 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 5041 5042 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size); 5043 5044 array_buffer_size(*pCVArrayFormat, pStubMsg, 5045 pMemory + pCVStructFormat->memory_size, pCVArrayFormat, 5046 FALSE /* fHasPointers */); 5047 5048 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 5049 } 5050 5051 /*********************************************************************** 5052 * NdrConformantVaryingStructMemorySize [RPCRT4.@] 5053 */ 5054 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 5055 PFORMAT_STRING pFormat) 5056 { 5057 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 5058 PFORMAT_STRING pCVArrayFormat; 5059 5060 TRACE("(%p, %p)\n", pStubMsg, pFormat); 5061 5062 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 5063 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 5064 { 5065 ERR("invalid format type %x\n", pCVStructFormat->type); 5066 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5067 return 0; 5068 } 5069 5070 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 5071 pCVStructFormat->offset_to_array_description; 5072 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat); 5073 5074 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 5075 5076 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 5077 5078 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); 5079 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat, 5080 FALSE /* fHasPointers */); 5081 5082 pStubMsg->MemorySize += pCVStructFormat->memory_size; 5083 5084 EmbeddedPointerMemorySize(pStubMsg, pFormat); 5085 5086 return pStubMsg->MemorySize; 5087 } 5088 5089 /*********************************************************************** 5090 * NdrConformantVaryingStructFree [RPCRT4.@] 5091 */ 5092 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, 5093 unsigned char *pMemory, 5094 PFORMAT_STRING pFormat) 5095 { 5096 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 5097 PFORMAT_STRING pCVArrayFormat; 5098 5099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5100 5101 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 5102 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 5103 { 5104 ERR("invalid format type %x\n", pCVStructFormat->type); 5105 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5106 return; 5107 } 5108 5109 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 5110 pCVStructFormat->offset_to_array_description; 5111 array_free(*pCVArrayFormat, pStubMsg, 5112 pMemory + pCVStructFormat->memory_size, pCVArrayFormat, 5113 FALSE /* fHasPointers */); 5114 5115 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 5116 5117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 5118 } 5119 5120 #include "pshpack1.h" 5121 typedef struct 5122 { 5123 unsigned char type; 5124 unsigned char alignment; 5125 unsigned short total_size; 5126 } NDR_SMFARRAY_FORMAT; 5127 5128 typedef struct 5129 { 5130 unsigned char type; 5131 unsigned char alignment; 5132 ULONG total_size; 5133 } NDR_LGFARRAY_FORMAT; 5134 #include "poppack.h" 5135 5136 /*********************************************************************** 5137 * NdrFixedArrayMarshall [RPCRT4.@] 5138 */ 5139 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 5140 unsigned char *pMemory, 5141 PFORMAT_STRING pFormat) 5142 { 5143 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 5144 ULONG total_size; 5145 5146 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5147 5148 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 5149 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 5150 { 5151 ERR("invalid format type %x\n", pSmFArrayFormat->type); 5152 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5153 return NULL; 5154 } 5155 5156 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 5157 5158 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 5159 { 5160 total_size = pSmFArrayFormat->total_size; 5161 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 5162 } 5163 else 5164 { 5165 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 5166 total_size = pLgFArrayFormat->total_size; 5167 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 5168 } 5169 5170 pStubMsg->BufferMark = pStubMsg->Buffer; 5171 safe_copy_to_buffer(pStubMsg, pMemory, total_size); 5172 5173 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 5174 5175 return NULL; 5176 } 5177 5178 /*********************************************************************** 5179 * NdrFixedArrayUnmarshall [RPCRT4.@] 5180 */ 5181 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 5182 unsigned char **ppMemory, 5183 PFORMAT_STRING pFormat, 5184 unsigned char fMustAlloc) 5185 { 5186 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 5187 ULONG total_size; 5188 unsigned char *saved_buffer; 5189 5190 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 5191 5192 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 5193 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 5194 { 5195 ERR("invalid format type %x\n", pSmFArrayFormat->type); 5196 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5197 return NULL; 5198 } 5199 5200 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 5201 5202 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 5203 { 5204 total_size = pSmFArrayFormat->total_size; 5205 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 5206 } 5207 else 5208 { 5209 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 5210 total_size = pLgFArrayFormat->total_size; 5211 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 5212 } 5213 5214 if (fMustAlloc) 5215 *ppMemory = NdrAllocate(pStubMsg, total_size); 5216 else 5217 { 5218 if (!pStubMsg->IsClient && !*ppMemory) 5219 /* for servers, we just point straight into the RPC buffer */ 5220 *ppMemory = pStubMsg->Buffer; 5221 } 5222 5223 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 5224 safe_buffer_increment(pStubMsg, total_size); 5225 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 5226 5227 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 5228 if (*ppMemory != saved_buffer) 5229 memcpy(*ppMemory, saved_buffer, total_size); 5230 5231 return NULL; 5232 } 5233 5234 /*********************************************************************** 5235 * NdrFixedArrayBufferSize [RPCRT4.@] 5236 */ 5237 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 5238 unsigned char *pMemory, 5239 PFORMAT_STRING pFormat) 5240 { 5241 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 5242 ULONG total_size; 5243 5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5245 5246 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 5247 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 5248 { 5249 ERR("invalid format type %x\n", pSmFArrayFormat->type); 5250 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5251 return; 5252 } 5253 5254 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1); 5255 5256 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 5257 { 5258 total_size = pSmFArrayFormat->total_size; 5259 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 5260 } 5261 else 5262 { 5263 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 5264 total_size = pLgFArrayFormat->total_size; 5265 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 5266 } 5267 safe_buffer_length_increment(pStubMsg, total_size); 5268 5269 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 5270 } 5271 5272 /*********************************************************************** 5273 * NdrFixedArrayMemorySize [RPCRT4.@] 5274 */ 5275 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 5276 PFORMAT_STRING pFormat) 5277 { 5278 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 5279 ULONG total_size; 5280 5281 TRACE("(%p, %p)\n", pStubMsg, pFormat); 5282 5283 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 5284 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 5285 { 5286 ERR("invalid format type %x\n", pSmFArrayFormat->type); 5287 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5288 return 0; 5289 } 5290 5291 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 5292 5293 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 5294 { 5295 total_size = pSmFArrayFormat->total_size; 5296 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 5297 } 5298 else 5299 { 5300 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 5301 total_size = pLgFArrayFormat->total_size; 5302 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 5303 } 5304 pStubMsg->BufferMark = pStubMsg->Buffer; 5305 safe_buffer_increment(pStubMsg, total_size); 5306 pStubMsg->MemorySize += total_size; 5307 5308 EmbeddedPointerMemorySize(pStubMsg, pFormat); 5309 5310 return total_size; 5311 } 5312 5313 /*********************************************************************** 5314 * NdrFixedArrayFree [RPCRT4.@] 5315 */ 5316 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 5317 unsigned char *pMemory, 5318 PFORMAT_STRING pFormat) 5319 { 5320 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 5321 5322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5323 5324 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 5325 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 5326 { 5327 ERR("invalid format type %x\n", pSmFArrayFormat->type); 5328 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5329 return; 5330 } 5331 5332 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 5333 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 5334 else 5335 { 5336 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 5337 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 5338 } 5339 5340 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 5341 } 5342 5343 /*********************************************************************** 5344 * NdrVaryingArrayMarshall [RPCRT4.@] 5345 */ 5346 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 5347 unsigned char *pMemory, 5348 PFORMAT_STRING pFormat) 5349 { 5350 unsigned char alignment; 5351 DWORD elements, esize; 5352 ULONG bufsize; 5353 5354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5355 5356 if ((pFormat[0] != RPC_FC_SMVARRAY) && 5357 (pFormat[0] != RPC_FC_LGVARRAY)) 5358 { 5359 ERR("invalid format type %x\n", pFormat[0]); 5360 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5361 return NULL; 5362 } 5363 5364 alignment = pFormat[1] + 1; 5365 5366 if (pFormat[0] == RPC_FC_SMVARRAY) 5367 { 5368 pFormat += 2; 5369 pFormat += sizeof(WORD); 5370 elements = *(const WORD*)pFormat; 5371 pFormat += sizeof(WORD); 5372 } 5373 else 5374 { 5375 pFormat += 2; 5376 pFormat += sizeof(DWORD); 5377 elements = *(const DWORD*)pFormat; 5378 pFormat += sizeof(DWORD); 5379 } 5380 5381 esize = *(const WORD*)pFormat; 5382 pFormat += sizeof(WORD); 5383 5384 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 5385 if ((pStubMsg->ActualCount > elements) || 5386 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 5387 { 5388 RpcRaiseException(RPC_S_INVALID_BOUND); 5389 return NULL; 5390 } 5391 5392 WriteVariance(pStubMsg); 5393 5394 align_pointer_clear(&pStubMsg->Buffer, alignment); 5395 5396 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 5397 pStubMsg->BufferMark = pStubMsg->Buffer; 5398 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); 5399 5400 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 5401 5402 return NULL; 5403 } 5404 5405 /*********************************************************************** 5406 * NdrVaryingArrayUnmarshall [RPCRT4.@] 5407 */ 5408 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 5409 unsigned char **ppMemory, 5410 PFORMAT_STRING pFormat, 5411 unsigned char fMustAlloc) 5412 { 5413 unsigned char alignment; 5414 DWORD size, elements, esize; 5415 ULONG bufsize; 5416 unsigned char *saved_buffer; 5417 ULONG offset; 5418 5419 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 5420 5421 if ((pFormat[0] != RPC_FC_SMVARRAY) && 5422 (pFormat[0] != RPC_FC_LGVARRAY)) 5423 { 5424 ERR("invalid format type %x\n", pFormat[0]); 5425 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5426 return NULL; 5427 } 5428 5429 alignment = pFormat[1] + 1; 5430 5431 if (pFormat[0] == RPC_FC_SMVARRAY) 5432 { 5433 pFormat += 2; 5434 size = *(const WORD*)pFormat; 5435 pFormat += sizeof(WORD); 5436 elements = *(const WORD*)pFormat; 5437 pFormat += sizeof(WORD); 5438 } 5439 else 5440 { 5441 pFormat += 2; 5442 size = *(const DWORD*)pFormat; 5443 pFormat += sizeof(DWORD); 5444 elements = *(const DWORD*)pFormat; 5445 pFormat += sizeof(DWORD); 5446 } 5447 5448 esize = *(const WORD*)pFormat; 5449 pFormat += sizeof(WORD); 5450 5451 pFormat = ReadVariance(pStubMsg, pFormat, elements); 5452 5453 align_pointer(&pStubMsg->Buffer, alignment); 5454 5455 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 5456 offset = pStubMsg->Offset; 5457 5458 if (!fMustAlloc && !*ppMemory) 5459 fMustAlloc = TRUE; 5460 if (fMustAlloc) 5461 *ppMemory = NdrAllocate(pStubMsg, size); 5462 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 5463 safe_buffer_increment(pStubMsg, bufsize); 5464 5465 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 5466 5467 memcpy(*ppMemory + offset, saved_buffer, bufsize); 5468 5469 return NULL; 5470 } 5471 5472 /*********************************************************************** 5473 * NdrVaryingArrayBufferSize [RPCRT4.@] 5474 */ 5475 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 5476 unsigned char *pMemory, 5477 PFORMAT_STRING pFormat) 5478 { 5479 unsigned char alignment; 5480 DWORD elements, esize; 5481 5482 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5483 5484 if ((pFormat[0] != RPC_FC_SMVARRAY) && 5485 (pFormat[0] != RPC_FC_LGVARRAY)) 5486 { 5487 ERR("invalid format type %x\n", pFormat[0]); 5488 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5489 return; 5490 } 5491 5492 alignment = pFormat[1] + 1; 5493 5494 if (pFormat[0] == RPC_FC_SMVARRAY) 5495 { 5496 pFormat += 2; 5497 pFormat += sizeof(WORD); 5498 elements = *(const WORD*)pFormat; 5499 pFormat += sizeof(WORD); 5500 } 5501 else 5502 { 5503 pFormat += 2; 5504 pFormat += sizeof(DWORD); 5505 elements = *(const DWORD*)pFormat; 5506 pFormat += sizeof(DWORD); 5507 } 5508 5509 esize = *(const WORD*)pFormat; 5510 pFormat += sizeof(WORD); 5511 5512 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 5513 if ((pStubMsg->ActualCount > elements) || 5514 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 5515 { 5516 RpcRaiseException(RPC_S_INVALID_BOUND); 5517 return; 5518 } 5519 5520 SizeVariance(pStubMsg); 5521 5522 align_length(&pStubMsg->BufferLength, alignment); 5523 5524 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 5525 5526 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 5527 } 5528 5529 /*********************************************************************** 5530 * NdrVaryingArrayMemorySize [RPCRT4.@] 5531 */ 5532 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 5533 PFORMAT_STRING pFormat) 5534 { 5535 unsigned char alignment; 5536 DWORD size, elements, esize; 5537 5538 TRACE("(%p, %p)\n", pStubMsg, pFormat); 5539 5540 if ((pFormat[0] != RPC_FC_SMVARRAY) && 5541 (pFormat[0] != RPC_FC_LGVARRAY)) 5542 { 5543 ERR("invalid format type %x\n", pFormat[0]); 5544 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5545 return 0; 5546 } 5547 5548 alignment = pFormat[1] + 1; 5549 5550 if (pFormat[0] == RPC_FC_SMVARRAY) 5551 { 5552 pFormat += 2; 5553 size = *(const WORD*)pFormat; 5554 pFormat += sizeof(WORD); 5555 elements = *(const WORD*)pFormat; 5556 pFormat += sizeof(WORD); 5557 } 5558 else 5559 { 5560 pFormat += 2; 5561 size = *(const DWORD*)pFormat; 5562 pFormat += sizeof(DWORD); 5563 elements = *(const DWORD*)pFormat; 5564 pFormat += sizeof(DWORD); 5565 } 5566 5567 esize = *(const WORD*)pFormat; 5568 pFormat += sizeof(WORD); 5569 5570 pFormat = ReadVariance(pStubMsg, pFormat, elements); 5571 5572 align_pointer(&pStubMsg->Buffer, alignment); 5573 5574 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 5575 pStubMsg->MemorySize += size; 5576 5577 EmbeddedPointerMemorySize(pStubMsg, pFormat); 5578 5579 return pStubMsg->MemorySize; 5580 } 5581 5582 /*********************************************************************** 5583 * NdrVaryingArrayFree [RPCRT4.@] 5584 */ 5585 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 5586 unsigned char *pMemory, 5587 PFORMAT_STRING pFormat) 5588 { 5589 DWORD elements; 5590 5591 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5592 5593 if ((pFormat[0] != RPC_FC_SMVARRAY) && 5594 (pFormat[0] != RPC_FC_LGVARRAY)) 5595 { 5596 ERR("invalid format type %x\n", pFormat[0]); 5597 RpcRaiseException(RPC_S_INTERNAL_ERROR); 5598 return; 5599 } 5600 5601 if (pFormat[0] == RPC_FC_SMVARRAY) 5602 { 5603 pFormat += 2; 5604 pFormat += sizeof(WORD); 5605 elements = *(const WORD*)pFormat; 5606 pFormat += sizeof(WORD); 5607 } 5608 else 5609 { 5610 pFormat += 2; 5611 pFormat += sizeof(DWORD); 5612 elements = *(const DWORD*)pFormat; 5613 pFormat += sizeof(DWORD); 5614 } 5615 5616 pFormat += sizeof(WORD); 5617 5618 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 5619 if ((pStubMsg->ActualCount > elements) || 5620 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 5621 { 5622 RpcRaiseException(RPC_S_INVALID_BOUND); 5623 return; 5624 } 5625 5626 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 5627 } 5628 5629 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory) 5630 { 5631 switch (fc) 5632 { 5633 case RPC_FC_BYTE: 5634 case RPC_FC_CHAR: 5635 case RPC_FC_SMALL: 5636 case RPC_FC_USMALL: 5637 return *pMemory; 5638 case RPC_FC_WCHAR: 5639 case RPC_FC_SHORT: 5640 case RPC_FC_USHORT: 5641 case RPC_FC_ENUM16: 5642 return *(const USHORT *)pMemory; 5643 case RPC_FC_LONG: 5644 case RPC_FC_ULONG: 5645 case RPC_FC_ENUM32: 5646 return *(const ULONG *)pMemory; 5647 case RPC_FC_INT3264: 5648 case RPC_FC_UINT3264: 5649 return *(const ULONG_PTR *)pMemory; 5650 default: 5651 FIXME("Unhandled base type: 0x%02x\n", fc); 5652 return 0; 5653 } 5654 } 5655 5656 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg, 5657 ULONG discriminant, 5658 PFORMAT_STRING pFormat) 5659 { 5660 unsigned short num_arms, arm, type; 5661 5662 num_arms = *(const SHORT*)pFormat & 0x0fff; 5663 pFormat += 2; 5664 for(arm = 0; arm < num_arms; arm++) 5665 { 5666 if(discriminant == *(const ULONG*)pFormat) 5667 { 5668 pFormat += 4; 5669 break; 5670 } 5671 pFormat += 6; 5672 } 5673 5674 type = *(const unsigned short*)pFormat; 5675 TRACE("type %04x\n", type); 5676 if(arm == num_arms) /* default arm extras */ 5677 { 5678 if(type == 0xffff) 5679 { 5680 ERR("no arm for 0x%x and no default case\n", discriminant); 5681 RpcRaiseException(RPC_S_INVALID_TAG); 5682 return NULL; 5683 } 5684 if(type == 0) 5685 { 5686 TRACE("falling back to empty default case for 0x%x\n", discriminant); 5687 return NULL; 5688 } 5689 } 5690 return pFormat; 5691 } 5692 5693 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat) 5694 { 5695 unsigned short type; 5696 5697 pFormat += 2; 5698 5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 5700 if(!pFormat) 5701 return NULL; 5702 5703 type = *(const unsigned short*)pFormat; 5704 if((type & 0xff00) == 0x8000) 5705 { 5706 unsigned char basetype = LOBYTE(type); 5707 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype); 5708 } 5709 else 5710 { 5711 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 5712 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 5713 if (m) 5714 { 5715 unsigned char *saved_buffer = NULL; 5716 BOOL pointer_buffer_mark_set = FALSE; 5717 switch(*desc) 5718 { 5719 case RPC_FC_RP: 5720 case RPC_FC_UP: 5721 case RPC_FC_OP: 5722 case RPC_FC_FP: 5723 align_pointer_clear(&pStubMsg->Buffer, 4); 5724 saved_buffer = pStubMsg->Buffer; 5725 if (pStubMsg->PointerBufferMark) 5726 { 5727 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 5728 pStubMsg->PointerBufferMark = NULL; 5729 pointer_buffer_mark_set = TRUE; 5730 } 5731 else 5732 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 5733 5734 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc); 5735 if (pointer_buffer_mark_set) 5736 { 5737 STD_OVERFLOW_CHECK(pStubMsg); 5738 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 5739 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 5740 { 5741 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", 5742 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 5743 RpcRaiseException(RPC_X_BAD_STUB_DATA); 5744 } 5745 pStubMsg->Buffer = saved_buffer + 4; 5746 } 5747 break; 5748 default: 5749 m(pStubMsg, pMemory, desc); 5750 } 5751 } 5752 else FIXME("no marshaller for embedded type %02x\n", *desc); 5753 } 5754 return NULL; 5755 } 5756 5757 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, 5758 unsigned char **ppMemory, 5759 ULONG discriminant, 5760 PFORMAT_STRING pFormat, 5761 unsigned char fMustAlloc) 5762 { 5763 unsigned short type; 5764 5765 pFormat += 2; 5766 5767 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 5768 if(!pFormat) 5769 return NULL; 5770 5771 type = *(const unsigned short*)pFormat; 5772 if((type & 0xff00) == 0x8000) 5773 { 5774 unsigned char basetype = LOBYTE(type); 5775 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE); 5776 } 5777 else 5778 { 5779 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 5780 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 5781 if (m) 5782 { 5783 unsigned char *saved_buffer = NULL; 5784 BOOL pointer_buffer_mark_set = FALSE; 5785 switch(*desc) 5786 { 5787 case RPC_FC_RP: 5788 case RPC_FC_UP: 5789 case RPC_FC_OP: 5790 case RPC_FC_FP: 5791 align_pointer(&pStubMsg->Buffer, 4); 5792 saved_buffer = pStubMsg->Buffer; 5793 if (pStubMsg->PointerBufferMark) 5794 { 5795 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 5796 pStubMsg->PointerBufferMark = NULL; 5797 pointer_buffer_mark_set = TRUE; 5798 } 5799 else 5800 pStubMsg->Buffer += 4; /* for pointer ID */ 5801 5802 if (saved_buffer + 4 > pStubMsg->BufferEnd) 5803 { 5804 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", 5805 saved_buffer, pStubMsg->BufferEnd); 5806 RpcRaiseException(RPC_X_BAD_STUB_DATA); 5807 } 5808 5809 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc); 5810 if (pointer_buffer_mark_set) 5811 { 5812 STD_OVERFLOW_CHECK(pStubMsg); 5813 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 5814 pStubMsg->Buffer = saved_buffer + 4; 5815 } 5816 break; 5817 default: 5818 m(pStubMsg, ppMemory, desc, fMustAlloc); 5819 } 5820 } 5821 else FIXME("no marshaller for embedded type %02x\n", *desc); 5822 } 5823 return NULL; 5824 } 5825 5826 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, 5827 unsigned char *pMemory, 5828 ULONG discriminant, 5829 PFORMAT_STRING pFormat) 5830 { 5831 unsigned short type; 5832 5833 pFormat += 2; 5834 5835 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 5836 if(!pFormat) 5837 return; 5838 5839 type = *(const unsigned short*)pFormat; 5840 if((type & 0xff00) == 0x8000) 5841 { 5842 unsigned char basetype = LOBYTE(type); 5843 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype); 5844 } 5845 else 5846 { 5847 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 5848 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 5849 if (m) 5850 { 5851 switch(*desc) 5852 { 5853 case RPC_FC_RP: 5854 case RPC_FC_UP: 5855 case RPC_FC_OP: 5856 case RPC_FC_FP: 5857 align_length(&pStubMsg->BufferLength, 4); 5858 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */ 5859 if (!pStubMsg->IgnoreEmbeddedPointers) 5860 { 5861 int saved_buffer_length = pStubMsg->BufferLength; 5862 pStubMsg->BufferLength = pStubMsg->PointerLength; 5863 pStubMsg->PointerLength = 0; 5864 if(!pStubMsg->BufferLength) 5865 ERR("BufferLength == 0??\n"); 5866 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc); 5867 pStubMsg->PointerLength = pStubMsg->BufferLength; 5868 pStubMsg->BufferLength = saved_buffer_length; 5869 } 5870 break; 5871 default: 5872 m(pStubMsg, pMemory, desc); 5873 } 5874 } 5875 else FIXME("no buffersizer for embedded type %02x\n", *desc); 5876 } 5877 } 5878 5879 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg, 5880 ULONG discriminant, 5881 PFORMAT_STRING pFormat) 5882 { 5883 unsigned short type, size; 5884 5885 size = *(const unsigned short*)pFormat; 5886 pStubMsg->Memory += size; 5887 pFormat += 2; 5888 5889 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 5890 if(!pFormat) 5891 return 0; 5892 5893 type = *(const unsigned short*)pFormat; 5894 if((type & 0xff00) == 0x8000) 5895 { 5896 return NdrBaseTypeMemorySize(pStubMsg, pFormat); 5897 } 5898 else 5899 { 5900 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 5901 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; 5902 unsigned char *saved_buffer; 5903 if (m) 5904 { 5905 switch(*desc) 5906 { 5907 case RPC_FC_RP: 5908 case RPC_FC_UP: 5909 case RPC_FC_OP: 5910 case RPC_FC_FP: 5911 align_pointer(&pStubMsg->Buffer, 4); 5912 saved_buffer = pStubMsg->Buffer; 5913 safe_buffer_increment(pStubMsg, 4); 5914 align_length(&pStubMsg->MemorySize, sizeof(void *)); 5915 pStubMsg->MemorySize += sizeof(void *); 5916 if (!pStubMsg->IgnoreEmbeddedPointers) 5917 PointerMemorySize(pStubMsg, saved_buffer, pFormat); 5918 break; 5919 default: 5920 return m(pStubMsg, desc); 5921 } 5922 } 5923 else FIXME("no marshaller for embedded type %02x\n", *desc); 5924 } 5925 5926 TRACE("size %d\n", size); 5927 return size; 5928 } 5929 5930 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, 5931 unsigned char *pMemory, 5932 ULONG discriminant, 5933 PFORMAT_STRING pFormat) 5934 { 5935 unsigned short type; 5936 5937 pFormat += 2; 5938 5939 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 5940 if(!pFormat) 5941 return; 5942 5943 type = *(const unsigned short*)pFormat; 5944 if((type & 0xff00) != 0x8000) 5945 { 5946 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 5947 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK]; 5948 if (m) 5949 { 5950 switch(*desc) 5951 { 5952 case RPC_FC_RP: 5953 case RPC_FC_UP: 5954 case RPC_FC_OP: 5955 case RPC_FC_FP: 5956 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); 5957 break; 5958 default: 5959 m(pStubMsg, pMemory, desc); 5960 } 5961 } 5962 } 5963 } 5964 5965 /*********************************************************************** 5966 * NdrEncapsulatedUnionMarshall [RPCRT4.@] 5967 */ 5968 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, 5969 unsigned char *pMemory, 5970 PFORMAT_STRING pFormat) 5971 { 5972 unsigned char switch_type; 5973 unsigned char increment; 5974 ULONG switch_value; 5975 5976 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 5977 pFormat++; 5978 5979 switch_type = *pFormat & 0xf; 5980 increment = (*pFormat & 0xf0) >> 4; 5981 pFormat++; 5982 5983 align_pointer_clear(&pStubMsg->Buffer, increment); 5984 5985 switch_value = get_discriminant(switch_type, pMemory); 5986 TRACE("got switch value 0x%x\n", switch_value); 5987 5988 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type); 5989 pMemory += increment; 5990 5991 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat); 5992 } 5993 5994 /*********************************************************************** 5995 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@] 5996 */ 5997 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 5998 unsigned char **ppMemory, 5999 PFORMAT_STRING pFormat, 6000 unsigned char fMustAlloc) 6001 { 6002 unsigned char switch_type; 6003 unsigned char increment; 6004 ULONG switch_value; 6005 unsigned short size; 6006 unsigned char *pMemoryArm; 6007 6008 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 6009 pFormat++; 6010 6011 switch_type = *pFormat & 0xf; 6012 increment = (*pFormat & 0xf0) >> 4; 6013 pFormat++; 6014 6015 align_pointer(&pStubMsg->Buffer, increment); 6016 switch_value = get_discriminant(switch_type, pStubMsg->Buffer); 6017 TRACE("got switch value 0x%x\n", switch_value); 6018 6019 size = *(const unsigned short*)pFormat + increment; 6020 if (!fMustAlloc && !*ppMemory) 6021 fMustAlloc = TRUE; 6022 if (fMustAlloc) 6023 *ppMemory = NdrAllocate(pStubMsg, size); 6024 6025 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm 6026 * since the arm is part of the memory block that is encompassed by 6027 * the whole union. Memory is forced to allocate when pointers 6028 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 6029 * clearing the memory we pass in to the unmarshaller */ 6030 if (fMustAlloc) 6031 memset(*ppMemory, 0, size); 6032 6033 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE); 6034 pMemoryArm = *ppMemory + increment; 6035 6036 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE); 6037 } 6038 6039 /*********************************************************************** 6040 * NdrEncapsulatedUnionBufferSize [RPCRT4.@] 6041 */ 6042 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 6043 unsigned char *pMemory, 6044 PFORMAT_STRING pFormat) 6045 { 6046 unsigned char switch_type; 6047 unsigned char increment; 6048 ULONG switch_value; 6049 6050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 6051 pFormat++; 6052 6053 switch_type = *pFormat & 0xf; 6054 increment = (*pFormat & 0xf0) >> 4; 6055 pFormat++; 6056 6057 align_length(&pStubMsg->BufferLength, increment); 6058 switch_value = get_discriminant(switch_type, pMemory); 6059 TRACE("got switch value 0x%x\n", switch_value); 6060 6061 /* Add discriminant size */ 6062 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type); 6063 pMemory += increment; 6064 6065 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat); 6066 } 6067 6068 /*********************************************************************** 6069 * NdrEncapsulatedUnionMemorySize [RPCRT4.@] 6070 */ 6071 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 6072 PFORMAT_STRING pFormat) 6073 { 6074 unsigned char switch_type; 6075 unsigned char increment; 6076 ULONG switch_value; 6077 6078 switch_type = *pFormat & 0xf; 6079 increment = (*pFormat & 0xf0) >> 4; 6080 pFormat++; 6081 6082 align_pointer(&pStubMsg->Buffer, increment); 6083 switch_value = get_discriminant(switch_type, pStubMsg->Buffer); 6084 TRACE("got switch value 0x%x\n", switch_value); 6085 6086 pStubMsg->Memory += increment; 6087 6088 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat); 6089 } 6090 6091 /*********************************************************************** 6092 * NdrEncapsulatedUnionFree [RPCRT4.@] 6093 */ 6094 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, 6095 unsigned char *pMemory, 6096 PFORMAT_STRING pFormat) 6097 { 6098 unsigned char switch_type; 6099 unsigned char increment; 6100 ULONG switch_value; 6101 6102 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 6103 pFormat++; 6104 6105 switch_type = *pFormat & 0xf; 6106 increment = (*pFormat & 0xf0) >> 4; 6107 pFormat++; 6108 6109 switch_value = get_discriminant(switch_type, pMemory); 6110 TRACE("got switch value 0x%x\n", switch_value); 6111 6112 pMemory += increment; 6113 6114 union_arm_free(pStubMsg, pMemory, switch_value, pFormat); 6115 } 6116 6117 /*********************************************************************** 6118 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@] 6119 */ 6120 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, 6121 unsigned char *pMemory, 6122 PFORMAT_STRING pFormat) 6123 { 6124 unsigned char switch_type; 6125 6126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 6127 pFormat++; 6128 6129 switch_type = *pFormat; 6130 pFormat++; 6131 6132 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 6133 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 6134 /* Marshall discriminant */ 6135 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); 6136 6137 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 6138 } 6139 6140 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg, 6141 PFORMAT_STRING *ppFormat) 6142 { 6143 LONG discriminant = 0; 6144 6145 switch(**ppFormat) 6146 { 6147 case RPC_FC_BYTE: 6148 case RPC_FC_CHAR: 6149 case RPC_FC_SMALL: 6150 case RPC_FC_USMALL: 6151 { 6152 UCHAR d; 6153 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 6154 discriminant = d; 6155 break; 6156 } 6157 case RPC_FC_WCHAR: 6158 case RPC_FC_SHORT: 6159 case RPC_FC_USHORT: 6160 case RPC_FC_ENUM16: 6161 { 6162 USHORT d; 6163 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 6164 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 6165 discriminant = d; 6166 break; 6167 } 6168 case RPC_FC_LONG: 6169 case RPC_FC_ULONG: 6170 { 6171 ULONG d; 6172 align_pointer(&pStubMsg->Buffer, sizeof(ULONG)); 6173 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 6174 discriminant = d; 6175 break; 6176 } 6177 default: 6178 FIXME("Unhandled base type: 0x%02x\n", **ppFormat); 6179 } 6180 (*ppFormat)++; 6181 6182 *ppFormat = SkipConformance(pStubMsg, *ppFormat); 6183 return discriminant; 6184 } 6185 6186 /********************************************************************** 6187 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@] 6188 */ 6189 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 6190 unsigned char **ppMemory, 6191 PFORMAT_STRING pFormat, 6192 unsigned char fMustAlloc) 6193 { 6194 LONG discriminant; 6195 unsigned short size; 6196 6197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 6198 pFormat++; 6199 6200 /* Unmarshall discriminant */ 6201 discriminant = unmarshall_discriminant(pStubMsg, &pFormat); 6202 TRACE("unmarshalled discriminant %x\n", discriminant); 6203 6204 pFormat += *(const SHORT*)pFormat; 6205 6206 size = *(const unsigned short*)pFormat; 6207 6208 if (!fMustAlloc && !*ppMemory) 6209 fMustAlloc = TRUE; 6210 if (fMustAlloc) 6211 *ppMemory = NdrAllocate(pStubMsg, size); 6212 6213 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm 6214 * since the arm is part of the memory block that is encompassed by 6215 * the whole union. Memory is forced to allocate when pointers 6216 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 6217 * clearing the memory we pass in to the unmarshaller */ 6218 if (fMustAlloc) 6219 memset(*ppMemory, 0, size); 6220 6221 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE); 6222 } 6223 6224 /*********************************************************************** 6225 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@] 6226 */ 6227 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 6228 unsigned char *pMemory, 6229 PFORMAT_STRING pFormat) 6230 { 6231 unsigned char switch_type; 6232 6233 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 6234 pFormat++; 6235 6236 switch_type = *pFormat; 6237 pFormat++; 6238 6239 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 6240 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 6241 /* Add discriminant size */ 6242 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); 6243 6244 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 6245 } 6246 6247 /*********************************************************************** 6248 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@] 6249 */ 6250 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 6251 PFORMAT_STRING pFormat) 6252 { 6253 ULONG discriminant; 6254 6255 pFormat++; 6256 /* Unmarshall discriminant */ 6257 discriminant = unmarshall_discriminant(pStubMsg, &pFormat); 6258 TRACE("unmarshalled discriminant 0x%x\n", discriminant); 6259 6260 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat); 6261 } 6262 6263 /*********************************************************************** 6264 * NdrNonEncapsulatedUnionFree [RPCRT4.@] 6265 */ 6266 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, 6267 unsigned char *pMemory, 6268 PFORMAT_STRING pFormat) 6269 { 6270 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 6271 pFormat++; 6272 pFormat++; 6273 6274 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 6275 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 6276 6277 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 6278 } 6279 6280 /*********************************************************************** 6281 * NdrByteCountPointerMarshall [RPCRT4.@] 6282 */ 6283 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 6284 unsigned char *pMemory, 6285 PFORMAT_STRING pFormat) 6286 { 6287 FIXME("stub\n"); 6288 return NULL; 6289 } 6290 6291 /*********************************************************************** 6292 * NdrByteCountPointerUnmarshall [RPCRT4.@] 6293 */ 6294 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 6295 unsigned char **ppMemory, 6296 PFORMAT_STRING pFormat, 6297 unsigned char fMustAlloc) 6298 { 6299 FIXME("stub\n"); 6300 return NULL; 6301 } 6302 6303 /*********************************************************************** 6304 * NdrByteCountPointerBufferSize [RPCRT4.@] 6305 */ 6306 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 6307 unsigned char *pMemory, 6308 PFORMAT_STRING pFormat) 6309 { 6310 FIXME("stub\n"); 6311 } 6312 6313 /*********************************************************************** 6314 * NdrByteCountPointerMemorySize [internal] 6315 */ 6316 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 6317 PFORMAT_STRING pFormat) 6318 { 6319 FIXME("stub\n"); 6320 return 0; 6321 } 6322 6323 /*********************************************************************** 6324 * NdrByteCountPointerFree [RPCRT4.@] 6325 */ 6326 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 6327 unsigned char *pMemory, 6328 PFORMAT_STRING pFormat) 6329 { 6330 FIXME("stub\n"); 6331 } 6332 6333 /*********************************************************************** 6334 * NdrXmitOrRepAsMarshall [RPCRT4.@] 6335 */ 6336 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg, 6337 unsigned char *pMemory, 6338 PFORMAT_STRING pFormat) 6339 { 6340 FIXME("stub\n"); 6341 return NULL; 6342 } 6343 6344 /*********************************************************************** 6345 * NdrXmitOrRepAsUnmarshall [RPCRT4.@] 6346 */ 6347 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 6348 unsigned char **ppMemory, 6349 PFORMAT_STRING pFormat, 6350 unsigned char fMustAlloc) 6351 { 6352 FIXME("stub\n"); 6353 return NULL; 6354 } 6355 6356 /*********************************************************************** 6357 * NdrXmitOrRepAsBufferSize [RPCRT4.@] 6358 */ 6359 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 6360 unsigned char *pMemory, 6361 PFORMAT_STRING pFormat) 6362 { 6363 FIXME("stub\n"); 6364 } 6365 6366 /*********************************************************************** 6367 * NdrXmitOrRepAsMemorySize [RPCRT4.@] 6368 */ 6369 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 6370 PFORMAT_STRING pFormat) 6371 { 6372 FIXME("stub\n"); 6373 return 0; 6374 } 6375 6376 /*********************************************************************** 6377 * NdrXmitOrRepAsFree [RPCRT4.@] 6378 */ 6379 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, 6380 unsigned char *pMemory, 6381 PFORMAT_STRING pFormat) 6382 { 6383 FIXME("stub\n"); 6384 } 6385 6386 /*********************************************************************** 6387 * NdrRangeMarshall [internal] 6388 */ 6389 static unsigned char *WINAPI NdrRangeMarshall( 6390 PMIDL_STUB_MESSAGE pStubMsg, 6391 unsigned char *pMemory, 6392 PFORMAT_STRING pFormat) 6393 { 6394 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 6395 unsigned char base_type; 6396 6397 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6398 6399 if (pRange->type != RPC_FC_RANGE) 6400 { 6401 ERR("invalid format type %x\n", pRange->type); 6402 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6403 return NULL; 6404 } 6405 6406 base_type = pRange->flags_type & 0xf; 6407 6408 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type); 6409 } 6410 6411 /*********************************************************************** 6412 * NdrRangeUnmarshall [RPCRT4.@] 6413 */ 6414 unsigned char *WINAPI NdrRangeUnmarshall( 6415 PMIDL_STUB_MESSAGE pStubMsg, 6416 unsigned char **ppMemory, 6417 PFORMAT_STRING pFormat, 6418 unsigned char fMustAlloc) 6419 { 6420 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 6421 unsigned char base_type; 6422 6423 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); 6424 6425 if (pRange->type != RPC_FC_RANGE) 6426 { 6427 ERR("invalid format type %x\n", pRange->type); 6428 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6429 return NULL; 6430 } 6431 base_type = pRange->flags_type & 0xf; 6432 6433 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n", 6434 base_type, pRange->low_value, pRange->high_value); 6435 6436 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \ 6437 do \ 6438 { \ 6439 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \ 6440 if (!fMustAlloc && !*ppMemory) \ 6441 fMustAlloc = TRUE; \ 6442 if (fMustAlloc) \ 6443 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \ 6444 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \ 6445 { \ 6446 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \ 6447 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \ 6448 RpcRaiseException(RPC_X_BAD_STUB_DATA); \ 6449 } \ 6450 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \ 6451 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \ 6452 { \ 6453 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \ 6454 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \ 6455 (mem_type)pRange->high_value); \ 6456 RpcRaiseException(RPC_S_INVALID_BOUND); \ 6457 return NULL; \ 6458 } \ 6459 TRACE("*ppMemory: %p\n", *ppMemory); \ 6460 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \ 6461 pStubMsg->Buffer += sizeof(wire_type); \ 6462 } while (0) 6463 6464 switch(base_type) 6465 { 6466 case RPC_FC_CHAR: 6467 case RPC_FC_SMALL: 6468 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d"); 6469 TRACE("value: 0x%02x\n", **ppMemory); 6470 break; 6471 case RPC_FC_BYTE: 6472 case RPC_FC_USMALL: 6473 RANGE_UNMARSHALL(CHAR, CHAR, "%u"); 6474 TRACE("value: 0x%02x\n", **ppMemory); 6475 break; 6476 case RPC_FC_WCHAR: /* FIXME: valid? */ 6477 case RPC_FC_USHORT: 6478 RANGE_UNMARSHALL(USHORT, USHORT, "%u"); 6479 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 6480 break; 6481 case RPC_FC_SHORT: 6482 RANGE_UNMARSHALL(SHORT, SHORT, "%d"); 6483 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 6484 break; 6485 case RPC_FC_LONG: 6486 case RPC_FC_ENUM32: 6487 RANGE_UNMARSHALL(LONG, LONG, "%d"); 6488 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 6489 break; 6490 case RPC_FC_ULONG: 6491 RANGE_UNMARSHALL(ULONG, ULONG, "%u"); 6492 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 6493 break; 6494 case RPC_FC_ENUM16: 6495 RANGE_UNMARSHALL(UINT, USHORT, "%u"); 6496 TRACE("value: 0x%08x\n", **(UINT **)ppMemory); 6497 break; 6498 case RPC_FC_FLOAT: 6499 case RPC_FC_DOUBLE: 6500 case RPC_FC_HYPER: 6501 default: 6502 ERR("invalid range base type: 0x%02x\n", base_type); 6503 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6504 } 6505 6506 return NULL; 6507 } 6508 6509 /*********************************************************************** 6510 * NdrRangeBufferSize [internal] 6511 */ 6512 static void WINAPI NdrRangeBufferSize( 6513 PMIDL_STUB_MESSAGE pStubMsg, 6514 unsigned char *pMemory, 6515 PFORMAT_STRING pFormat) 6516 { 6517 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 6518 unsigned char base_type; 6519 6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6521 6522 if (pRange->type != RPC_FC_RANGE) 6523 { 6524 ERR("invalid format type %x\n", pRange->type); 6525 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6526 } 6527 base_type = pRange->flags_type & 0xf; 6528 6529 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type); 6530 } 6531 6532 /*********************************************************************** 6533 * NdrRangeMemorySize [internal] 6534 */ 6535 static ULONG WINAPI NdrRangeMemorySize( 6536 PMIDL_STUB_MESSAGE pStubMsg, 6537 PFORMAT_STRING pFormat) 6538 { 6539 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 6540 unsigned char base_type; 6541 6542 if (pRange->type != RPC_FC_RANGE) 6543 { 6544 ERR("invalid format type %x\n", pRange->type); 6545 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6546 return 0; 6547 } 6548 base_type = pRange->flags_type & 0xf; 6549 6550 return NdrBaseTypeMemorySize(pStubMsg, &base_type); 6551 } 6552 6553 /*********************************************************************** 6554 * NdrRangeFree [internal] 6555 */ 6556 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg, 6557 unsigned char *pMemory, 6558 PFORMAT_STRING pFormat) 6559 { 6560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6561 6562 /* nothing to do */ 6563 } 6564 6565 /*********************************************************************** 6566 * NdrBaseTypeMarshall [internal] 6567 */ 6568 static unsigned char *WINAPI NdrBaseTypeMarshall( 6569 PMIDL_STUB_MESSAGE pStubMsg, 6570 unsigned char *pMemory, 6571 PFORMAT_STRING pFormat) 6572 { 6573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6574 6575 switch(*pFormat) 6576 { 6577 case RPC_FC_BYTE: 6578 case RPC_FC_CHAR: 6579 case RPC_FC_SMALL: 6580 case RPC_FC_USMALL: 6581 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR)); 6582 TRACE("value: 0x%02x\n", *pMemory); 6583 break; 6584 case RPC_FC_WCHAR: 6585 case RPC_FC_SHORT: 6586 case RPC_FC_USHORT: 6587 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT)); 6588 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT)); 6589 TRACE("value: 0x%04x\n", *(USHORT *)pMemory); 6590 break; 6591 case RPC_FC_LONG: 6592 case RPC_FC_ULONG: 6593 case RPC_FC_ERROR_STATUS_T: 6594 case RPC_FC_ENUM32: 6595 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG)); 6596 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG)); 6597 TRACE("value: 0x%08x\n", *(ULONG *)pMemory); 6598 break; 6599 case RPC_FC_FLOAT: 6600 align_pointer_clear(&pStubMsg->Buffer, sizeof(float)); 6601 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); 6602 break; 6603 case RPC_FC_DOUBLE: 6604 align_pointer_clear(&pStubMsg->Buffer, sizeof(double)); 6605 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); 6606 break; 6607 case RPC_FC_HYPER: 6608 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG)); 6609 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG)); 6610 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); 6611 break; 6612 case RPC_FC_ENUM16: 6613 { 6614 USHORT val = *(UINT *)pMemory; 6615 /* only 16-bits on the wire, so do a sanity check */ 6616 if (*(UINT *)pMemory > SHRT_MAX) 6617 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 6618 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT)); 6619 safe_copy_to_buffer(pStubMsg, &val, sizeof(val)); 6620 TRACE("value: 0x%04x\n", *(UINT *)pMemory); 6621 break; 6622 } 6623 case RPC_FC_INT3264: 6624 case RPC_FC_UINT3264: 6625 { 6626 UINT val = *(UINT_PTR *)pMemory; 6627 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT)); 6628 safe_copy_to_buffer(pStubMsg, &val, sizeof(val)); 6629 break; 6630 } 6631 case RPC_FC_IGNORE: 6632 break; 6633 default: 6634 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 6635 } 6636 6637 /* FIXME: what is the correct return value? */ 6638 return NULL; 6639 } 6640 6641 /*********************************************************************** 6642 * NdrBaseTypeUnmarshall [internal] 6643 */ 6644 static unsigned char *WINAPI NdrBaseTypeUnmarshall( 6645 PMIDL_STUB_MESSAGE pStubMsg, 6646 unsigned char **ppMemory, 6647 PFORMAT_STRING pFormat, 6648 unsigned char fMustAlloc) 6649 { 6650 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); 6651 6652 #define BASE_TYPE_UNMARSHALL(type) do { \ 6653 align_pointer(&pStubMsg->Buffer, sizeof(type)); \ 6654 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \ 6655 { \ 6656 *ppMemory = pStubMsg->Buffer; \ 6657 TRACE("*ppMemory: %p\n", *ppMemory); \ 6658 safe_buffer_increment(pStubMsg, sizeof(type)); \ 6659 } \ 6660 else \ 6661 { \ 6662 if (fMustAlloc) \ 6663 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ 6664 TRACE("*ppMemory: %p\n", *ppMemory); \ 6665 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \ 6666 } \ 6667 } while (0) 6668 6669 switch(*pFormat) 6670 { 6671 case RPC_FC_BYTE: 6672 case RPC_FC_CHAR: 6673 case RPC_FC_SMALL: 6674 case RPC_FC_USMALL: 6675 BASE_TYPE_UNMARSHALL(UCHAR); 6676 TRACE("value: 0x%02x\n", **ppMemory); 6677 break; 6678 case RPC_FC_WCHAR: 6679 case RPC_FC_SHORT: 6680 case RPC_FC_USHORT: 6681 BASE_TYPE_UNMARSHALL(USHORT); 6682 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 6683 break; 6684 case RPC_FC_LONG: 6685 case RPC_FC_ULONG: 6686 case RPC_FC_ERROR_STATUS_T: 6687 case RPC_FC_ENUM32: 6688 BASE_TYPE_UNMARSHALL(ULONG); 6689 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 6690 break; 6691 case RPC_FC_FLOAT: 6692 BASE_TYPE_UNMARSHALL(float); 6693 TRACE("value: %f\n", **(float **)ppMemory); 6694 break; 6695 case RPC_FC_DOUBLE: 6696 BASE_TYPE_UNMARSHALL(double); 6697 TRACE("value: %f\n", **(double **)ppMemory); 6698 break; 6699 case RPC_FC_HYPER: 6700 BASE_TYPE_UNMARSHALL(ULONGLONG); 6701 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); 6702 break; 6703 case RPC_FC_ENUM16: 6704 { 6705 USHORT val; 6706 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 6707 if (!fMustAlloc && !*ppMemory) 6708 fMustAlloc = TRUE; 6709 if (fMustAlloc) 6710 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT)); 6711 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT)); 6712 /* 16-bits on the wire, but int in memory */ 6713 **(UINT **)ppMemory = val; 6714 TRACE("value: 0x%08x\n", **(UINT **)ppMemory); 6715 break; 6716 } 6717 case RPC_FC_INT3264: 6718 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT); 6719 else 6720 { 6721 INT val; 6722 align_pointer(&pStubMsg->Buffer, sizeof(INT)); 6723 if (!fMustAlloc && !*ppMemory) 6724 fMustAlloc = TRUE; 6725 if (fMustAlloc) 6726 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR)); 6727 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT)); 6728 **(INT_PTR **)ppMemory = val; 6729 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory); 6730 } 6731 break; 6732 case RPC_FC_UINT3264: 6733 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT); 6734 else 6735 { 6736 UINT val; 6737 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 6738 if (!fMustAlloc && !*ppMemory) 6739 fMustAlloc = TRUE; 6740 if (fMustAlloc) 6741 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR)); 6742 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT)); 6743 **(UINT_PTR **)ppMemory = val; 6744 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory); 6745 } 6746 break; 6747 case RPC_FC_IGNORE: 6748 break; 6749 default: 6750 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 6751 } 6752 #undef BASE_TYPE_UNMARSHALL 6753 6754 /* FIXME: what is the correct return value? */ 6755 6756 return NULL; 6757 } 6758 6759 /*********************************************************************** 6760 * NdrBaseTypeBufferSize [internal] 6761 */ 6762 static void WINAPI NdrBaseTypeBufferSize( 6763 PMIDL_STUB_MESSAGE pStubMsg, 6764 unsigned char *pMemory, 6765 PFORMAT_STRING pFormat) 6766 { 6767 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6768 6769 switch(*pFormat) 6770 { 6771 case RPC_FC_BYTE: 6772 case RPC_FC_CHAR: 6773 case RPC_FC_SMALL: 6774 case RPC_FC_USMALL: 6775 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR)); 6776 break; 6777 case RPC_FC_WCHAR: 6778 case RPC_FC_SHORT: 6779 case RPC_FC_USHORT: 6780 case RPC_FC_ENUM16: 6781 align_length(&pStubMsg->BufferLength, sizeof(USHORT)); 6782 safe_buffer_length_increment(pStubMsg, sizeof(USHORT)); 6783 break; 6784 case RPC_FC_LONG: 6785 case RPC_FC_ULONG: 6786 case RPC_FC_ENUM32: 6787 case RPC_FC_INT3264: 6788 case RPC_FC_UINT3264: 6789 align_length(&pStubMsg->BufferLength, sizeof(ULONG)); 6790 safe_buffer_length_increment(pStubMsg, sizeof(ULONG)); 6791 break; 6792 case RPC_FC_FLOAT: 6793 align_length(&pStubMsg->BufferLength, sizeof(float)); 6794 safe_buffer_length_increment(pStubMsg, sizeof(float)); 6795 break; 6796 case RPC_FC_DOUBLE: 6797 align_length(&pStubMsg->BufferLength, sizeof(double)); 6798 safe_buffer_length_increment(pStubMsg, sizeof(double)); 6799 break; 6800 case RPC_FC_HYPER: 6801 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG)); 6802 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG)); 6803 break; 6804 case RPC_FC_ERROR_STATUS_T: 6805 align_length(&pStubMsg->BufferLength, sizeof(error_status_t)); 6806 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t)); 6807 break; 6808 case RPC_FC_IGNORE: 6809 break; 6810 default: 6811 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 6812 } 6813 } 6814 6815 /*********************************************************************** 6816 * NdrBaseTypeMemorySize [internal] 6817 */ 6818 static ULONG WINAPI NdrBaseTypeMemorySize( 6819 PMIDL_STUB_MESSAGE pStubMsg, 6820 PFORMAT_STRING pFormat) 6821 { 6822 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat); 6823 6824 switch(*pFormat) 6825 { 6826 case RPC_FC_BYTE: 6827 case RPC_FC_CHAR: 6828 case RPC_FC_SMALL: 6829 case RPC_FC_USMALL: 6830 safe_buffer_increment(pStubMsg, sizeof(UCHAR)); 6831 pStubMsg->MemorySize += sizeof(UCHAR); 6832 return sizeof(UCHAR); 6833 case RPC_FC_WCHAR: 6834 case RPC_FC_SHORT: 6835 case RPC_FC_USHORT: 6836 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 6837 safe_buffer_increment(pStubMsg, sizeof(USHORT)); 6838 align_length(&pStubMsg->MemorySize, sizeof(USHORT)); 6839 pStubMsg->MemorySize += sizeof(USHORT); 6840 return sizeof(USHORT); 6841 case RPC_FC_LONG: 6842 case RPC_FC_ULONG: 6843 case RPC_FC_ENUM32: 6844 align_pointer(&pStubMsg->Buffer, sizeof(ULONG)); 6845 safe_buffer_increment(pStubMsg, sizeof(ULONG)); 6846 align_length(&pStubMsg->MemorySize, sizeof(ULONG)); 6847 pStubMsg->MemorySize += sizeof(ULONG); 6848 return sizeof(ULONG); 6849 case RPC_FC_FLOAT: 6850 align_pointer(&pStubMsg->Buffer, sizeof(float)); 6851 safe_buffer_increment(pStubMsg, sizeof(float)); 6852 align_length(&pStubMsg->MemorySize, sizeof(float)); 6853 pStubMsg->MemorySize += sizeof(float); 6854 return sizeof(float); 6855 case RPC_FC_DOUBLE: 6856 align_pointer(&pStubMsg->Buffer, sizeof(double)); 6857 safe_buffer_increment(pStubMsg, sizeof(double)); 6858 align_length(&pStubMsg->MemorySize, sizeof(double)); 6859 pStubMsg->MemorySize += sizeof(double); 6860 return sizeof(double); 6861 case RPC_FC_HYPER: 6862 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG)); 6863 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG)); 6864 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG)); 6865 pStubMsg->MemorySize += sizeof(ULONGLONG); 6866 return sizeof(ULONGLONG); 6867 case RPC_FC_ERROR_STATUS_T: 6868 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t)); 6869 safe_buffer_increment(pStubMsg, sizeof(error_status_t)); 6870 align_length(&pStubMsg->MemorySize, sizeof(error_status_t)); 6871 pStubMsg->MemorySize += sizeof(error_status_t); 6872 return sizeof(error_status_t); 6873 case RPC_FC_ENUM16: 6874 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 6875 safe_buffer_increment(pStubMsg, sizeof(USHORT)); 6876 align_length(&pStubMsg->MemorySize, sizeof(UINT)); 6877 pStubMsg->MemorySize += sizeof(UINT); 6878 return sizeof(UINT); 6879 case RPC_FC_INT3264: 6880 case RPC_FC_UINT3264: 6881 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 6882 safe_buffer_increment(pStubMsg, sizeof(UINT)); 6883 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR)); 6884 pStubMsg->MemorySize += sizeof(UINT_PTR); 6885 return sizeof(UINT_PTR); 6886 case RPC_FC_IGNORE: 6887 align_length(&pStubMsg->MemorySize, sizeof(void *)); 6888 pStubMsg->MemorySize += sizeof(void *); 6889 return sizeof(void *); 6890 default: 6891 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 6892 return 0; 6893 } 6894 } 6895 6896 /*********************************************************************** 6897 * NdrBaseTypeFree [internal] 6898 */ 6899 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg, 6900 unsigned char *pMemory, 6901 PFORMAT_STRING pFormat) 6902 { 6903 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6904 6905 /* nothing to do */ 6906 } 6907 6908 /*********************************************************************** 6909 * NdrContextHandleBufferSize [internal] 6910 */ 6911 static void WINAPI NdrContextHandleBufferSize( 6912 PMIDL_STUB_MESSAGE pStubMsg, 6913 unsigned char *pMemory, 6914 PFORMAT_STRING pFormat) 6915 { 6916 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6917 6918 if (*pFormat != RPC_FC_BIND_CONTEXT) 6919 { 6920 ERR("invalid format type %x\n", *pFormat); 6921 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6922 } 6923 align_length(&pStubMsg->BufferLength, 4); 6924 safe_buffer_length_increment(pStubMsg, cbNDRContext); 6925 } 6926 6927 /*********************************************************************** 6928 * NdrContextHandleMarshall [internal] 6929 */ 6930 static unsigned char *WINAPI NdrContextHandleMarshall( 6931 PMIDL_STUB_MESSAGE pStubMsg, 6932 unsigned char *pMemory, 6933 PFORMAT_STRING pFormat) 6934 { 6935 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 6936 6937 if (*pFormat != RPC_FC_BIND_CONTEXT) 6938 { 6939 ERR("invalid format type %x\n", *pFormat); 6940 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6941 } 6942 TRACE("flags: 0x%02x\n", pFormat[1]); 6943 6944 if (pStubMsg->IsClient) 6945 { 6946 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR) 6947 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE); 6948 else 6949 NdrClientContextMarshall(pStubMsg, pMemory, FALSE); 6950 } 6951 else 6952 { 6953 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory); 6954 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]]; 6955 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat); 6956 } 6957 6958 return NULL; 6959 } 6960 6961 /*********************************************************************** 6962 * NdrContextHandleUnmarshall [internal] 6963 */ 6964 static unsigned char *WINAPI NdrContextHandleUnmarshall( 6965 PMIDL_STUB_MESSAGE pStubMsg, 6966 unsigned char **ppMemory, 6967 PFORMAT_STRING pFormat, 6968 unsigned char fMustAlloc) 6969 { 6970 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg, 6971 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE"); 6972 6973 if (*pFormat != RPC_FC_BIND_CONTEXT) 6974 { 6975 ERR("invalid format type %x\n", *pFormat); 6976 RpcRaiseException(RPC_S_INTERNAL_ERROR); 6977 } 6978 TRACE("flags: 0x%02x\n", pFormat[1]); 6979 6980 if (pStubMsg->IsClient) 6981 { 6982 /* [out]-only or [ret] param */ 6983 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT) 6984 **(NDR_CCONTEXT **)ppMemory = NULL; 6985 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle); 6986 } 6987 else 6988 { 6989 NDR_SCONTEXT ctxt; 6990 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat); 6991 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR) 6992 *(void **)ppMemory = NDRSContextValue(ctxt); 6993 else 6994 *(void **)ppMemory = *NDRSContextValue(ctxt); 6995 } 6996 6997 return NULL; 6998 } 6999 7000 /*********************************************************************** 7001 * NdrClientContextMarshall [RPCRT4.@] 7002 */ 7003 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, 7004 NDR_CCONTEXT ContextHandle, 7005 int fCheck) 7006 { 7007 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck); 7008 7009 align_pointer_clear(&pStubMsg->Buffer, 4); 7010 7011 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 7012 { 7013 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 7014 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 7015 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7016 } 7017 7018 /* FIXME: what does fCheck do? */ 7019 NDRCContextMarshall(ContextHandle, 7020 pStubMsg->Buffer); 7021 7022 pStubMsg->Buffer += cbNDRContext; 7023 } 7024 7025 /*********************************************************************** 7026 * NdrClientContextUnmarshall [RPCRT4.@] 7027 */ 7028 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 7029 NDR_CCONTEXT * pContextHandle, 7030 RPC_BINDING_HANDLE BindHandle) 7031 { 7032 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle); 7033 7034 align_pointer(&pStubMsg->Buffer, 4); 7035 7036 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd) 7037 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7038 7039 NDRCContextUnmarshall(pContextHandle, 7040 BindHandle, 7041 pStubMsg->Buffer, 7042 pStubMsg->RpcMsg->DataRepresentation); 7043 7044 pStubMsg->Buffer += cbNDRContext; 7045 } 7046 7047 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, 7048 NDR_SCONTEXT ContextHandle, 7049 NDR_RUNDOWN RundownRoutine ) 7050 { 7051 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine); 7052 7053 align_pointer(&pStubMsg->Buffer, 4); 7054 7055 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 7056 { 7057 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 7058 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 7059 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7060 } 7061 7062 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, 7063 pStubMsg->Buffer, RundownRoutine, NULL, 7064 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS); 7065 pStubMsg->Buffer += cbNDRContext; 7066 } 7067 7068 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg) 7069 { 7070 NDR_SCONTEXT ContextHandle; 7071 7072 TRACE("(%p)\n", pStubMsg); 7073 7074 align_pointer(&pStubMsg->Buffer, 4); 7075 7076 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 7077 { 7078 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 7079 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 7080 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7081 } 7082 7083 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, 7084 pStubMsg->Buffer, 7085 pStubMsg->RpcMsg->DataRepresentation, 7086 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS); 7087 pStubMsg->Buffer += cbNDRContext; 7088 7089 return ContextHandle; 7090 } 7091 7092 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg, 7093 unsigned char* pMemory, 7094 PFORMAT_STRING pFormat) 7095 { 7096 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat); 7097 } 7098 7099 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, 7100 PFORMAT_STRING pFormat) 7101 { 7102 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 7103 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 7104 7105 TRACE("(%p, %p)\n", pStubMsg, pFormat); 7106 7107 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 7108 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 7109 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 7110 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 7111 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 7112 { 7113 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 7114 if_id = &sif->InterfaceId; 7115 } 7116 7117 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL, 7118 pStubMsg->RpcMsg->DataRepresentation, if_id, 7119 flags); 7120 } 7121 7122 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, 7123 NDR_SCONTEXT ContextHandle, 7124 NDR_RUNDOWN RundownRoutine, 7125 PFORMAT_STRING pFormat) 7126 { 7127 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 7128 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 7129 7130 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); 7131 7132 align_pointer(&pStubMsg->Buffer, 4); 7133 7134 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 7135 { 7136 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 7137 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 7138 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7139 } 7140 7141 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 7142 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 7143 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 7144 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 7145 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 7146 { 7147 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 7148 if_id = &sif->InterfaceId; 7149 } 7150 7151 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, 7152 pStubMsg->Buffer, RundownRoutine, if_id, flags); 7153 pStubMsg->Buffer += cbNDRContext; 7154 } 7155 7156 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 7157 PFORMAT_STRING pFormat) 7158 { 7159 NDR_SCONTEXT ContextHandle; 7160 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 7161 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 7162 7163 TRACE("(%p, %p)\n", pStubMsg, pFormat); 7164 7165 align_pointer(&pStubMsg->Buffer, 4); 7166 7167 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 7168 { 7169 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 7170 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 7171 RpcRaiseException(RPC_X_BAD_STUB_DATA); 7172 } 7173 7174 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 7175 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 7176 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 7177 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 7178 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 7179 { 7180 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 7181 if_id = &sif->InterfaceId; 7182 } 7183 7184 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, 7185 pStubMsg->Buffer, 7186 pStubMsg->RpcMsg->DataRepresentation, 7187 if_id, flags); 7188 pStubMsg->Buffer += cbNDRContext; 7189 7190 return ContextHandle; 7191 } 7192 7193 /*********************************************************************** 7194 * NdrCorrelationInitialize [RPCRT4.@] 7195 * 7196 * Initializes correlation validity checking. 7197 * 7198 * PARAMS 7199 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 7200 * pMemory [I] Pointer to memory to use as a cache. 7201 * CacheSize [I] Size of the memory pointed to by pMemory. 7202 * Flags [I] Reserved. Set to zero. 7203 * 7204 * RETURNS 7205 * Nothing. 7206 */ 7207 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags) 7208 { 7209 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg, pMemory, CacheSize, Flags); 7210 7211 if (pStubMsg->CorrDespIncrement == 0) 7212 pStubMsg->CorrDespIncrement = 2; /* size of the normal (non-range) /robust payload */ 7213 7214 pStubMsg->fHasNewCorrDesc = TRUE; 7215 } 7216 7217 /*********************************************************************** 7218 * NdrCorrelationPass [RPCRT4.@] 7219 * 7220 * Performs correlation validity checking. 7221 * 7222 * PARAMS 7223 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 7224 * 7225 * RETURNS 7226 * Nothing. 7227 */ 7228 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg) 7229 { 7230 FIXME("(%p): stub\n", pStubMsg); 7231 } 7232 7233 /*********************************************************************** 7234 * NdrCorrelationFree [RPCRT4.@] 7235 * 7236 * Frees any resources used while unmarshalling parameters that need 7237 * correlation validity checking. 7238 * 7239 * PARAMS 7240 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 7241 * 7242 * RETURNS 7243 * Nothing. 7244 */ 7245 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg) 7246 { 7247 FIXME("(%p): stub\n", pStubMsg); 7248 } 7249