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