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