Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenndr_marshall.c
Go to the documentation of this file.
00001 /* 00002 * NDR data marshalling 00003 * 00004 * Copyright 2002 Greg Turner 00005 * Copyright 2003-2006 CodeWeavers 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 * 00021 * TODO: 00022 * - String structs 00023 * - Byte count pointers 00024 * - transmit_as/represent as 00025 * - Multi-dimensional arrays 00026 * - Conversion functions (NdrConvert) 00027 * - Checks for integer addition overflow in user marshall functions 00028 */ 00029 00030 #include <assert.h> 00031 #include <stdarg.h> 00032 #include <stdio.h> 00033 #include <string.h> 00034 #include <limits.h> 00035 00036 #define NONAMELESSUNION 00037 #include "windef.h" 00038 #include "winbase.h" 00039 #include "winerror.h" 00040 00041 #include "ndr_misc.h" 00042 #include "rpcndr.h" 00043 #include "ndrtypes.h" 00044 00045 #include "wine/unicode.h" 00046 #include "wine/rpcfc.h" 00047 00048 #include "wine/debug.h" 00049 00050 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00051 00052 #if defined(__i386__) 00053 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ 00054 (*((UINT32 *)(pchar)) = (uint32)) 00055 00056 # define LITTLE_ENDIAN_UINT32_READ(pchar) \ 00057 (*((UINT32 *)(pchar))) 00058 #else 00059 /* these would work for i386 too, but less efficient */ 00060 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ 00061 (*(pchar) = LOBYTE(LOWORD(uint32)), \ 00062 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \ 00063 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \ 00064 *((pchar)+3) = HIBYTE(HIWORD(uint32))) 00065 00066 # define LITTLE_ENDIAN_UINT32_READ(pchar) \ 00067 (MAKELONG( \ 00068 MAKEWORD(*(pchar), *((pchar)+1)), \ 00069 MAKEWORD(*((pchar)+2), *((pchar)+3)))) 00070 #endif 00071 00072 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \ 00073 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \ 00074 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \ 00075 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \ 00076 *(pchar) = HIBYTE(HIWORD(uint32))) 00077 00078 #define BIG_ENDIAN_UINT32_READ(pchar) \ 00079 (MAKELONG( \ 00080 MAKEWORD(*((pchar)+3), *((pchar)+2)), \ 00081 MAKEWORD(*((pchar)+1), *(pchar)))) 00082 00083 #ifdef NDR_LOCAL_IS_BIG_ENDIAN 00084 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \ 00085 BIG_ENDIAN_UINT32_WRITE(pchar, uint32) 00086 # define NDR_LOCAL_UINT32_READ(pchar) \ 00087 BIG_ENDIAN_UINT32_READ(pchar) 00088 #else 00089 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \ 00090 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) 00091 # define NDR_LOCAL_UINT32_READ(pchar) \ 00092 LITTLE_ENDIAN_UINT32_READ(pchar) 00093 #endif 00094 00095 static inline void align_length( ULONG *len, unsigned int align ) 00096 { 00097 *len = (*len + align - 1) & ~(align - 1); 00098 } 00099 00100 static inline void align_pointer( unsigned char **ptr, unsigned int align ) 00101 { 00102 ULONG_PTR mask = align - 1; 00103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask); 00104 } 00105 00106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align ) 00107 { 00108 ULONG_PTR mask = align - 1; 00109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask ); 00110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask); 00111 } 00112 00113 #define STD_OVERFLOW_CHECK(_Msg) do { \ 00114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \ 00115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \ 00116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \ 00117 } while (0) 00118 00119 #define NDR_POINTER_ID_BASE 0x20000 00120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4) 00121 #define NDR_TABLE_SIZE 128 00122 #define NDR_TABLE_MASK 127 00123 00124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL)) 00125 00126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); 00128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 00131 00132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); 00135 00136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING); 00137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 00139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); 00140 00141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); 00142 00143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 00144 unsigned char *pMemory, 00145 PFORMAT_STRING pFormat, 00146 PFORMAT_STRING pPointer); 00147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, 00148 unsigned char *pMemory, 00149 PFORMAT_STRING pFormat, 00150 PFORMAT_STRING pPointer); 00151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 00152 unsigned char *pMemory, 00153 PFORMAT_STRING pFormat, 00154 PFORMAT_STRING pPointer, 00155 unsigned char fMustAlloc); 00156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 00157 PFORMAT_STRING pFormat, 00158 PFORMAT_STRING pPointer); 00159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, 00160 unsigned char *pMemory, 00161 PFORMAT_STRING pFormat, 00162 PFORMAT_STRING pPointer); 00163 00164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { 00165 0, 00166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 00167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 00168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 00169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, 00170 /* 0x10 */ 00171 NdrBaseTypeMarshall, 00172 /* 0x11 */ 00173 NdrPointerMarshall, NdrPointerMarshall, 00174 NdrPointerMarshall, NdrPointerMarshall, 00175 /* 0x15 */ 00176 NdrSimpleStructMarshall, NdrSimpleStructMarshall, 00177 NdrConformantStructMarshall, NdrConformantStructMarshall, 00178 NdrConformantVaryingStructMarshall, 00179 NdrComplexStructMarshall, 00180 /* 0x1b */ 00181 NdrConformantArrayMarshall, 00182 NdrConformantVaryingArrayMarshall, 00183 NdrFixedArrayMarshall, NdrFixedArrayMarshall, 00184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall, 00185 NdrComplexArrayMarshall, 00186 /* 0x22 */ 00187 NdrConformantStringMarshall, 0, 0, 00188 NdrConformantStringMarshall, 00189 NdrNonConformantStringMarshall, 0, 0, 0, 00190 /* 0x2a */ 00191 NdrEncapsulatedUnionMarshall, 00192 NdrNonEncapsulatedUnionMarshall, 00193 NdrByteCountPointerMarshall, 00194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall, 00195 /* 0x2f */ 00196 NdrInterfacePointerMarshall, 00197 /* 0x30 */ 00198 NdrContextHandleMarshall, 00199 /* 0xb1 */ 00200 0, 0, 0, 00201 NdrUserMarshalMarshall, 00202 0, 0, 00203 /* 0xb7 */ 00204 NdrRangeMarshall 00205 }; 00206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { 00207 0, 00208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 00209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 00210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 00211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, 00212 /* 0x10 */ 00213 NdrBaseTypeUnmarshall, 00214 /* 0x11 */ 00215 NdrPointerUnmarshall, NdrPointerUnmarshall, 00216 NdrPointerUnmarshall, NdrPointerUnmarshall, 00217 /* 0x15 */ 00218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall, 00219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall, 00220 NdrConformantVaryingStructUnmarshall, 00221 NdrComplexStructUnmarshall, 00222 /* 0x1b */ 00223 NdrConformantArrayUnmarshall, 00224 NdrConformantVaryingArrayUnmarshall, 00225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall, 00226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall, 00227 NdrComplexArrayUnmarshall, 00228 /* 0x22 */ 00229 NdrConformantStringUnmarshall, 0, 0, 00230 NdrConformantStringUnmarshall, 00231 NdrNonConformantStringUnmarshall, 0, 0, 0, 00232 /* 0x2a */ 00233 NdrEncapsulatedUnionUnmarshall, 00234 NdrNonEncapsulatedUnionUnmarshall, 00235 NdrByteCountPointerUnmarshall, 00236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall, 00237 /* 0x2f */ 00238 NdrInterfacePointerUnmarshall, 00239 /* 0x30 */ 00240 NdrContextHandleUnmarshall, 00241 /* 0xb1 */ 00242 0, 0, 0, 00243 NdrUserMarshalUnmarshall, 00244 0, 0, 00245 /* 0xb7 */ 00246 NdrRangeUnmarshall 00247 }; 00248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { 00249 0, 00250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 00251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 00252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 00253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, 00254 /* 0x10 */ 00255 NdrBaseTypeBufferSize, 00256 /* 0x11 */ 00257 NdrPointerBufferSize, NdrPointerBufferSize, 00258 NdrPointerBufferSize, NdrPointerBufferSize, 00259 /* 0x15 */ 00260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize, 00261 NdrConformantStructBufferSize, NdrConformantStructBufferSize, 00262 NdrConformantVaryingStructBufferSize, 00263 NdrComplexStructBufferSize, 00264 /* 0x1b */ 00265 NdrConformantArrayBufferSize, 00266 NdrConformantVaryingArrayBufferSize, 00267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize, 00268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize, 00269 NdrComplexArrayBufferSize, 00270 /* 0x22 */ 00271 NdrConformantStringBufferSize, 0, 0, 00272 NdrConformantStringBufferSize, 00273 NdrNonConformantStringBufferSize, 0, 0, 0, 00274 /* 0x2a */ 00275 NdrEncapsulatedUnionBufferSize, 00276 NdrNonEncapsulatedUnionBufferSize, 00277 NdrByteCountPointerBufferSize, 00278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize, 00279 /* 0x2f */ 00280 NdrInterfacePointerBufferSize, 00281 /* 0x30 */ 00282 NdrContextHandleBufferSize, 00283 /* 0xb1 */ 00284 0, 0, 0, 00285 NdrUserMarshalBufferSize, 00286 0, 0, 00287 /* 0xb7 */ 00288 NdrRangeBufferSize 00289 }; 00290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { 00291 0, 00292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 00293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 00294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 00295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, 00296 /* 0x10 */ 00297 NdrBaseTypeMemorySize, 00298 /* 0x11 */ 00299 NdrPointerMemorySize, NdrPointerMemorySize, 00300 NdrPointerMemorySize, NdrPointerMemorySize, 00301 /* 0x15 */ 00302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize, 00303 NdrConformantStructMemorySize, NdrConformantStructMemorySize, 00304 NdrConformantVaryingStructMemorySize, 00305 NdrComplexStructMemorySize, 00306 /* 0x1b */ 00307 NdrConformantArrayMemorySize, 00308 NdrConformantVaryingArrayMemorySize, 00309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize, 00310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize, 00311 NdrComplexArrayMemorySize, 00312 /* 0x22 */ 00313 NdrConformantStringMemorySize, 0, 0, 00314 NdrConformantStringMemorySize, 00315 NdrNonConformantStringMemorySize, 0, 0, 0, 00316 /* 0x2a */ 00317 NdrEncapsulatedUnionMemorySize, 00318 NdrNonEncapsulatedUnionMemorySize, 00319 NdrByteCountPointerMemorySize, 00320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize, 00321 /* 0x2f */ 00322 NdrInterfacePointerMemorySize, 00323 /* 0x30 */ 00324 0, 00325 /* 0xb1 */ 00326 0, 0, 0, 00327 NdrUserMarshalMemorySize, 00328 0, 0, 00329 /* 0xb7 */ 00330 NdrRangeMemorySize 00331 }; 00332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { 00333 0, 00334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 00335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 00336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 00337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, 00338 /* 0x10 */ 00339 NdrBaseTypeFree, 00340 /* 0x11 */ 00341 NdrPointerFree, NdrPointerFree, 00342 NdrPointerFree, NdrPointerFree, 00343 /* 0x15 */ 00344 NdrSimpleStructFree, NdrSimpleStructFree, 00345 NdrConformantStructFree, NdrConformantStructFree, 00346 NdrConformantVaryingStructFree, 00347 NdrComplexStructFree, 00348 /* 0x1b */ 00349 NdrConformantArrayFree, 00350 NdrConformantVaryingArrayFree, 00351 NdrFixedArrayFree, NdrFixedArrayFree, 00352 NdrVaryingArrayFree, NdrVaryingArrayFree, 00353 NdrComplexArrayFree, 00354 /* 0x22 */ 00355 0, 0, 0, 00356 0, 0, 0, 0, 0, 00357 /* 0x2a */ 00358 NdrEncapsulatedUnionFree, 00359 NdrNonEncapsulatedUnionFree, 00360 0, 00361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree, 00362 /* 0x2f */ 00363 NdrInterfacePointerFree, 00364 /* 0x30 */ 00365 0, 00366 /* 0xb1 */ 00367 0, 0, 0, 00368 NdrUserMarshalFree, 00369 0, 0, 00370 /* 0xb7 */ 00371 NdrRangeFree 00372 }; 00373 00374 typedef struct _NDR_MEMORY_LIST 00375 { 00376 ULONG magic; 00377 ULONG size; 00378 ULONG reserved; 00379 struct _NDR_MEMORY_LIST *next; 00380 } NDR_MEMORY_LIST; 00381 00382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L') 00383 00384 /*********************************************************************** 00385 * NdrAllocate [RPCRT4.@] 00386 * 00387 * Allocates a block of memory using pStubMsg->pfnAllocate. 00388 * 00389 * PARAMS 00390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure. 00391 * len [I] Size of memory block to allocate. 00392 * 00393 * RETURNS 00394 * The memory block of size len that was allocated. 00395 * 00396 * NOTES 00397 * The memory block is always 8-byte aligned. 00398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY 00399 * exception is raised. 00400 */ 00401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len) 00402 { 00403 SIZE_T aligned_len; 00404 SIZE_T adjusted_len; 00405 void *p; 00406 NDR_MEMORY_LIST *mem_list; 00407 00408 aligned_len = (len + 7) & ~7; 00409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST); 00410 /* check for overflow */ 00411 if (adjusted_len < len) 00412 { 00413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len); 00414 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00415 } 00416 00417 p = pStubMsg->pfnAllocate(adjusted_len); 00418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY); 00419 00420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len); 00421 mem_list->magic = MEML_MAGIC; 00422 mem_list->size = aligned_len; 00423 mem_list->reserved = 0; 00424 mem_list->next = pStubMsg->pMemoryList; 00425 pStubMsg->pMemoryList = mem_list; 00426 00427 TRACE("-- %p\n", p); 00428 return p; 00429 } 00430 00431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer) 00432 { 00433 TRACE("(%p, %p)\n", pStubMsg, Pointer); 00434 00435 pStubMsg->pfnFree(Pointer); 00436 } 00437 00438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) 00439 { 00440 return (*(const ULONG *)pFormat != -1); 00441 } 00442 00443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) 00444 { 00445 align_pointer(&pStubMsg->Buffer, 4); 00446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd) 00447 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 00449 pStubMsg->Buffer += 4; 00450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); 00451 if (pStubMsg->fHasNewCorrDesc) 00452 return pFormat+6; 00453 else 00454 return pFormat+4; 00455 } 00456 00457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue) 00458 { 00459 if (pFormat && !IsConformanceOrVariancePresent(pFormat)) 00460 { 00461 pStubMsg->Offset = 0; 00462 pStubMsg->ActualCount = pStubMsg->MaxCount; 00463 goto done; 00464 } 00465 00466 align_pointer(&pStubMsg->Buffer, 4); 00467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd) 00468 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 00470 pStubMsg->Buffer += 4; 00471 TRACE("offset is %d\n", pStubMsg->Offset); 00472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); 00473 pStubMsg->Buffer += 4; 00474 TRACE("variance is %d\n", pStubMsg->ActualCount); 00475 00476 if ((pStubMsg->ActualCount > MaxValue) || 00477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue)) 00478 { 00479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n", 00480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue); 00481 RpcRaiseException(RPC_S_INVALID_BOUND); 00482 return NULL; 00483 } 00484 00485 done: 00486 if (pStubMsg->fHasNewCorrDesc) 00487 return pFormat+6; 00488 else 00489 return pFormat+4; 00490 } 00491 00492 /* writes the conformance value to the buffer */ 00493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg) 00494 { 00495 align_pointer_clear(&pStubMsg->Buffer, 4); 00496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 00497 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); 00499 pStubMsg->Buffer += 4; 00500 } 00501 00502 /* writes the variance values to the buffer */ 00503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg) 00504 { 00505 align_pointer_clear(&pStubMsg->Buffer, 4); 00506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 00507 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); 00509 pStubMsg->Buffer += 4; 00510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); 00511 pStubMsg->Buffer += 4; 00512 } 00513 00514 /* requests buffer space for the conformance value */ 00515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg) 00516 { 00517 align_length(&pStubMsg->BufferLength, 4); 00518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength) 00519 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00520 pStubMsg->BufferLength += 4; 00521 } 00522 00523 /* requests buffer space for the variance values */ 00524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg) 00525 { 00526 align_length(&pStubMsg->BufferLength, 4); 00527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength) 00528 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00529 pStubMsg->BufferLength += 8; 00530 } 00531 00532 PFORMAT_STRING ComputeConformanceOrVariance( 00533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, 00534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount) 00535 { 00536 BYTE dtype = pFormat[0] & 0xf; 00537 short ofs = *(const short *)&pFormat[2]; 00538 LPVOID ptr = NULL; 00539 ULONG_PTR data = 0; 00540 00541 if (!IsConformanceOrVariancePresent(pFormat)) { 00542 /* null descriptor */ 00543 *pCount = def; 00544 goto finish_conf; 00545 } 00546 00547 switch (pFormat[0] & 0xf0) { 00548 case RPC_FC_NORMAL_CONFORMANCE: 00549 TRACE("normal conformance, ofs=%d\n", ofs); 00550 ptr = pMemory; 00551 break; 00552 case RPC_FC_POINTER_CONFORMANCE: 00553 TRACE("pointer conformance, ofs=%d\n", ofs); 00554 ptr = pStubMsg->Memory; 00555 break; 00556 case RPC_FC_TOP_LEVEL_CONFORMANCE: 00557 TRACE("toplevel conformance, ofs=%d\n", ofs); 00558 if (pStubMsg->StackTop) { 00559 ptr = pStubMsg->StackTop; 00560 } 00561 else { 00562 /* -Os mode, *pCount is already set */ 00563 goto finish_conf; 00564 } 00565 break; 00566 case RPC_FC_CONSTANT_CONFORMANCE: 00567 data = ofs | ((DWORD)pFormat[1] << 16); 00568 TRACE("constant conformance, val=%ld\n", data); 00569 *pCount = data; 00570 goto finish_conf; 00571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE: 00572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs); 00573 if (pStubMsg->StackTop) { 00574 ptr = pStubMsg->StackTop; 00575 } 00576 else { 00577 /* ? */ 00578 goto done_conf_grab; 00579 } 00580 break; 00581 default: 00582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0); 00583 goto finish_conf; 00584 } 00585 00586 switch (pFormat[1]) { 00587 case RPC_FC_DEREFERENCE: 00588 ptr = *(LPVOID*)((char *)ptr + ofs); 00589 break; 00590 case RPC_FC_CALLBACK: 00591 { 00592 unsigned char *old_stack_top = pStubMsg->StackTop; 00593 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount; 00594 00595 pStubMsg->StackTop = ptr; 00596 00597 /* ofs is index into StubDesc->apfnExprEval */ 00598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs); 00599 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg); 00600 00601 pStubMsg->StackTop = old_stack_top; 00602 00603 /* the callback function always stores the computed value in MaxCount */ 00604 max_count = pStubMsg->MaxCount; 00605 pStubMsg->MaxCount = old_max_count; 00606 *pCount = max_count; 00607 goto finish_conf; 00608 } 00609 default: 00610 ptr = (char *)ptr + ofs; 00611 break; 00612 } 00613 00614 switch (dtype) { 00615 case RPC_FC_LONG: 00616 case RPC_FC_ULONG: 00617 data = *(DWORD*)ptr; 00618 break; 00619 case RPC_FC_SHORT: 00620 data = *(SHORT*)ptr; 00621 break; 00622 case RPC_FC_USHORT: 00623 data = *(USHORT*)ptr; 00624 break; 00625 case RPC_FC_CHAR: 00626 case RPC_FC_SMALL: 00627 data = *(CHAR*)ptr; 00628 break; 00629 case RPC_FC_BYTE: 00630 case RPC_FC_USMALL: 00631 data = *(UCHAR*)ptr; 00632 break; 00633 case RPC_FC_HYPER: 00634 data = *(ULONGLONG *)ptr; 00635 break; 00636 default: 00637 FIXME("unknown conformance data type %x\n", dtype); 00638 goto done_conf_grab; 00639 } 00640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data); 00641 00642 done_conf_grab: 00643 switch (pFormat[1]) { 00644 case RPC_FC_DEREFERENCE: /* already handled */ 00645 case 0: /* no op */ 00646 *pCount = data; 00647 break; 00648 case RPC_FC_ADD_1: 00649 *pCount = data + 1; 00650 break; 00651 case RPC_FC_SUB_1: 00652 *pCount = data - 1; 00653 break; 00654 case RPC_FC_MULT_2: 00655 *pCount = data * 2; 00656 break; 00657 case RPC_FC_DIV_2: 00658 *pCount = data / 2; 00659 break; 00660 default: 00661 FIXME("unknown conformance op %d\n", pFormat[1]); 00662 goto finish_conf; 00663 } 00664 00665 finish_conf: 00666 TRACE("resulting conformance is %ld\n", *pCount); 00667 if (pStubMsg->fHasNewCorrDesc) 00668 return pFormat+6; 00669 else 00670 return pFormat+4; 00671 } 00672 00673 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg, 00674 PFORMAT_STRING pFormat) 00675 { 00676 if (pStubMsg->fHasNewCorrDesc) 00677 pFormat += 6; 00678 else 00679 pFormat += 4; 00680 return pFormat; 00681 } 00682 00683 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 00684 { 00685 return SkipConformance( pStubMsg, pFormat ); 00686 } 00687 00688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if 00689 * the result overflows 32-bits */ 00690 static inline ULONG safe_multiply(ULONG a, ULONG b) 00691 { 00692 ULONGLONG ret = (ULONGLONG)a * b; 00693 if (ret > 0xffffffff) 00694 { 00695 RpcRaiseException(RPC_S_INVALID_BOUND); 00696 return 0; 00697 } 00698 return ret; 00699 } 00700 00701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) 00702 { 00703 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 00704 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) 00705 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00706 pStubMsg->Buffer += size; 00707 } 00708 00709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) 00710 { 00711 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */ 00712 { 00713 ERR("buffer length overflow - BufferLength = %u, size = %u\n", 00714 pStubMsg->BufferLength, size); 00715 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00716 } 00717 pStubMsg->BufferLength += size; 00718 } 00719 00720 /* copies data from the buffer, checking that there is enough data in the buffer 00721 * to do so */ 00722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size) 00723 { 00724 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 00725 (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) 00726 { 00727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", 00728 pStubMsg->Buffer, pStubMsg->BufferEnd, size); 00729 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00730 } 00731 if (p == pStubMsg->Buffer) 00732 ERR("pointer is the same as the buffer\n"); 00733 memcpy(p, pStubMsg->Buffer, size); 00734 pStubMsg->Buffer += size; 00735 } 00736 00737 /* copies data to the buffer, checking that there is enough space to do so */ 00738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size) 00739 { 00740 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ 00741 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) 00742 { 00743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", 00744 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength, 00745 size); 00746 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00747 } 00748 memcpy(pStubMsg->Buffer, p, size); 00749 pStubMsg->Buffer += size; 00750 } 00751 00752 /* verify that string data sitting in the buffer is valid and safe to 00753 * unmarshall */ 00754 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize) 00755 { 00756 ULONG i; 00757 00758 /* verify the buffer is safe to access */ 00759 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || 00760 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) 00761 { 00762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, 00763 pStubMsg->BufferEnd, pStubMsg->Buffer); 00764 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00765 } 00766 00767 /* strings must always have null terminating bytes */ 00768 if (bufsize < esize) 00769 { 00770 ERR("invalid string length of %d\n", bufsize / esize); 00771 RpcRaiseException(RPC_S_INVALID_BOUND); 00772 } 00773 00774 for (i = bufsize - esize; i < bufsize; i++) 00775 if (pStubMsg->Buffer[i] != 0) 00776 { 00777 ERR("string not null-terminated at byte position %d, data is 0x%x\n", 00778 i, pStubMsg->Buffer[i]); 00779 RpcRaiseException(RPC_S_INVALID_BOUND); 00780 } 00781 } 00782 00783 static inline void dump_pointer_attr(unsigned char attr) 00784 { 00785 if (attr & RPC_FC_P_ALLOCALLNODES) 00786 TRACE(" RPC_FC_P_ALLOCALLNODES"); 00787 if (attr & RPC_FC_P_DONTFREE) 00788 TRACE(" RPC_FC_P_DONTFREE"); 00789 if (attr & RPC_FC_P_ONSTACK) 00790 TRACE(" RPC_FC_P_ONSTACK"); 00791 if (attr & RPC_FC_P_SIMPLEPOINTER) 00792 TRACE(" RPC_FC_P_SIMPLEPOINTER"); 00793 if (attr & RPC_FC_P_DEREF) 00794 TRACE(" RPC_FC_P_DEREF"); 00795 TRACE("\n"); 00796 } 00797 00798 /*********************************************************************** 00799 * PointerMarshall [internal] 00800 */ 00801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 00802 unsigned char *Buffer, 00803 unsigned char *Pointer, 00804 PFORMAT_STRING pFormat) 00805 { 00806 unsigned type = pFormat[0], attr = pFormat[1]; 00807 PFORMAT_STRING desc; 00808 NDR_MARSHALL m; 00809 ULONG pointer_id; 00810 int pointer_needs_marshaling; 00811 00812 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat); 00813 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 00814 pFormat += 2; 00815 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 00816 else desc = pFormat + *(const SHORT*)pFormat; 00817 00818 switch (type) { 00819 case RPC_FC_RP: /* ref pointer (always non-null) */ 00820 if (!Pointer) 00821 { 00822 ERR("NULL ref pointer is not allowed\n"); 00823 RpcRaiseException(RPC_X_NULL_REF_POINTER); 00824 } 00825 pointer_needs_marshaling = 1; 00826 break; 00827 case RPC_FC_UP: /* unique pointer */ 00828 case RPC_FC_OP: /* object pointer - same as unique here */ 00829 if (Pointer) 00830 pointer_needs_marshaling = 1; 00831 else 00832 pointer_needs_marshaling = 0; 00833 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0; 00834 TRACE("writing 0x%08x to buffer\n", pointer_id); 00835 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); 00836 break; 00837 case RPC_FC_FP: 00838 pointer_needs_marshaling = !NdrFullPointerQueryPointer( 00839 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id); 00840 TRACE("writing 0x%08x to buffer\n", pointer_id); 00841 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); 00842 break; 00843 default: 00844 FIXME("unhandled ptr type=%02x\n", type); 00845 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00846 return; 00847 } 00848 00849 TRACE("calling marshaller for type 0x%x\n", (int)*desc); 00850 00851 if (pointer_needs_marshaling) { 00852 if (attr & RPC_FC_P_DEREF) { 00853 Pointer = *(unsigned char**)Pointer; 00854 TRACE("deref => %p\n", Pointer); 00855 } 00856 m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 00857 if (m) m(pStubMsg, Pointer, desc); 00858 else FIXME("no marshaller for data type=%02x\n", *desc); 00859 } 00860 00861 STD_OVERFLOW_CHECK(pStubMsg); 00862 } 00863 00864 /*********************************************************************** 00865 * PointerUnmarshall [internal] 00866 */ 00867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 00868 unsigned char *Buffer, 00869 unsigned char **pPointer, 00870 unsigned char *pSrcPointer, 00871 PFORMAT_STRING pFormat, 00872 unsigned char fMustAlloc) 00873 { 00874 unsigned type = pFormat[0], attr = pFormat[1]; 00875 PFORMAT_STRING desc; 00876 NDR_UNMARSHALL m; 00877 DWORD pointer_id = 0; 00878 int pointer_needs_unmarshaling; 00879 00880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc); 00881 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 00882 pFormat += 2; 00883 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 00884 else desc = pFormat + *(const SHORT*)pFormat; 00885 00886 switch (type) { 00887 case RPC_FC_RP: /* ref pointer (always non-null) */ 00888 pointer_needs_unmarshaling = 1; 00889 break; 00890 case RPC_FC_UP: /* unique pointer */ 00891 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 00892 TRACE("pointer_id is 0x%08x\n", pointer_id); 00893 if (pointer_id) 00894 pointer_needs_unmarshaling = 1; 00895 else { 00896 *pPointer = NULL; 00897 pointer_needs_unmarshaling = 0; 00898 } 00899 break; 00900 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ 00901 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 00902 TRACE("pointer_id is 0x%08x\n", pointer_id); 00903 if (!fMustAlloc && pSrcPointer) 00904 { 00905 FIXME("free object pointer %p\n", pSrcPointer); 00906 fMustAlloc = TRUE; 00907 } 00908 if (pointer_id) 00909 pointer_needs_unmarshaling = 1; 00910 else 00911 { 00912 *pPointer = NULL; 00913 pointer_needs_unmarshaling = 0; 00914 } 00915 break; 00916 case RPC_FC_FP: 00917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 00918 TRACE("pointer_id is 0x%08x\n", pointer_id); 00919 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId( 00920 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer); 00921 break; 00922 default: 00923 FIXME("unhandled ptr type=%02x\n", type); 00924 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00925 return; 00926 } 00927 00928 if (pointer_needs_unmarshaling) { 00929 unsigned char **current_ptr = pPointer; 00930 if (pStubMsg->IsClient) { 00931 TRACE("client\n"); 00932 /* if we aren't forcing allocation of memory then try to use the existing 00933 * (source) pointer to unmarshall the data into so that [in,out] 00934 * parameters behave correctly. it doesn't matter if the parameter is 00935 * [out] only since in that case the pointer will be NULL. we force 00936 * allocation when the source pointer is NULL here instead of in the type 00937 * unmarshalling routine for the benefit of the deref code below */ 00938 if (!fMustAlloc) { 00939 if (pSrcPointer) { 00940 TRACE("setting *pPointer to %p\n", pSrcPointer); 00941 *pPointer = pSrcPointer; 00942 } else 00943 fMustAlloc = TRUE; 00944 } 00945 } else { 00946 TRACE("server\n"); 00947 /* the memory in a stub is never initialised, so we have to work out here 00948 * whether we have to initialise it so we can use the optimisation of 00949 * setting the pointer to the buffer, if possible, or set fMustAlloc to 00950 * TRUE. */ 00951 if (attr & RPC_FC_P_DEREF) { 00952 fMustAlloc = TRUE; 00953 } else { 00954 *current_ptr = NULL; 00955 } 00956 } 00957 00958 if (attr & RPC_FC_P_ALLOCALLNODES) 00959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n"); 00960 00961 if (attr & RPC_FC_P_DEREF) { 00962 if (fMustAlloc) { 00963 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); 00964 *pPointer = base_ptr_val; 00965 current_ptr = (unsigned char **)base_ptr_val; 00966 } else 00967 current_ptr = *(unsigned char***)current_ptr; 00968 TRACE("deref => %p\n", current_ptr); 00969 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE; 00970 } 00971 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 00972 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc); 00973 else FIXME("no unmarshaller for data type=%02x\n", *desc); 00974 00975 if (type == RPC_FC_FP) 00976 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, 00977 *pPointer); 00978 } 00979 00980 TRACE("pointer=%p\n", *pPointer); 00981 } 00982 00983 /*********************************************************************** 00984 * PointerBufferSize [internal] 00985 */ 00986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 00987 unsigned char *Pointer, 00988 PFORMAT_STRING pFormat) 00989 { 00990 unsigned type = pFormat[0], attr = pFormat[1]; 00991 PFORMAT_STRING desc; 00992 NDR_BUFFERSIZE m; 00993 int pointer_needs_sizing; 00994 ULONG pointer_id; 00995 00996 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); 00997 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 00998 pFormat += 2; 00999 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 01000 else desc = pFormat + *(const SHORT*)pFormat; 01001 01002 switch (type) { 01003 case RPC_FC_RP: /* ref pointer (always non-null) */ 01004 if (!Pointer) 01005 { 01006 ERR("NULL ref pointer is not allowed\n"); 01007 RpcRaiseException(RPC_X_NULL_REF_POINTER); 01008 } 01009 break; 01010 case RPC_FC_OP: 01011 case RPC_FC_UP: 01012 /* NULL pointer has no further representation */ 01013 if (!Pointer) 01014 return; 01015 break; 01016 case RPC_FC_FP: 01017 pointer_needs_sizing = !NdrFullPointerQueryPointer( 01018 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id); 01019 if (!pointer_needs_sizing) 01020 return; 01021 break; 01022 default: 01023 FIXME("unhandled ptr type=%02x\n", type); 01024 RpcRaiseException(RPC_X_BAD_STUB_DATA); 01025 return; 01026 } 01027 01028 if (attr & RPC_FC_P_DEREF) { 01029 Pointer = *(unsigned char**)Pointer; 01030 TRACE("deref => %p\n", Pointer); 01031 } 01032 01033 m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 01034 if (m) m(pStubMsg, Pointer, desc); 01035 else FIXME("no buffersizer for data type=%02x\n", *desc); 01036 } 01037 01038 /*********************************************************************** 01039 * PointerMemorySize [internal] 01040 */ 01041 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 01042 unsigned char *Buffer, PFORMAT_STRING pFormat) 01043 { 01044 unsigned type = pFormat[0], attr = pFormat[1]; 01045 PFORMAT_STRING desc; 01046 NDR_MEMORYSIZE m; 01047 DWORD pointer_id = 0; 01048 int pointer_needs_sizing; 01049 01050 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat); 01051 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 01052 pFormat += 2; 01053 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 01054 else desc = pFormat + *(const SHORT*)pFormat; 01055 01056 switch (type) { 01057 case RPC_FC_RP: /* ref pointer (always non-null) */ 01058 pointer_needs_sizing = 1; 01059 break; 01060 case RPC_FC_UP: /* unique pointer */ 01061 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ 01062 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 01063 TRACE("pointer_id is 0x%08x\n", pointer_id); 01064 if (pointer_id) 01065 pointer_needs_sizing = 1; 01066 else 01067 pointer_needs_sizing = 0; 01068 break; 01069 case RPC_FC_FP: 01070 { 01071 void *pointer; 01072 pointer_id = NDR_LOCAL_UINT32_READ(Buffer); 01073 TRACE("pointer_id is 0x%08x\n", pointer_id); 01074 pointer_needs_sizing = !NdrFullPointerQueryRefId( 01075 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer); 01076 break; 01077 } 01078 default: 01079 FIXME("unhandled ptr type=%02x\n", type); 01080 RpcRaiseException(RPC_X_BAD_STUB_DATA); 01081 return 0; 01082 } 01083 01084 if (attr & RPC_FC_P_DEREF) { 01085 align_length(&pStubMsg->MemorySize, sizeof(void*)); 01086 pStubMsg->MemorySize += sizeof(void*); 01087 TRACE("deref\n"); 01088 } 01089 01090 if (pointer_needs_sizing) { 01091 m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; 01092 if (m) m(pStubMsg, desc); 01093 else FIXME("no memorysizer for data type=%02x\n", *desc); 01094 } 01095 01096 return pStubMsg->MemorySize; 01097 } 01098 01099 /*********************************************************************** 01100 * PointerFree [internal] 01101 */ 01102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg, 01103 unsigned char *Pointer, 01104 PFORMAT_STRING pFormat) 01105 { 01106 unsigned type = pFormat[0], attr = pFormat[1]; 01107 PFORMAT_STRING desc; 01108 NDR_FREE m; 01109 unsigned char *current_pointer = Pointer; 01110 01111 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); 01112 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); 01113 if (attr & RPC_FC_P_DONTFREE) return; 01114 pFormat += 2; 01115 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; 01116 else desc = pFormat + *(const SHORT*)pFormat; 01117 01118 if (!Pointer) return; 01119 01120 if (type == RPC_FC_FP) { 01121 int pointer_needs_freeing = NdrFullPointerFree( 01122 pStubMsg->FullPtrXlatTables, Pointer); 01123 if (!pointer_needs_freeing) 01124 return; 01125 } 01126 01127 if (attr & RPC_FC_P_DEREF) { 01128 current_pointer = *(unsigned char**)Pointer; 01129 TRACE("deref => %p\n", current_pointer); 01130 } 01131 01132 m = NdrFreer[*desc & NDR_TABLE_MASK]; 01133 if (m) m(pStubMsg, current_pointer, desc); 01134 01135 /* this check stops us from trying to free buffer memory. we don't have to 01136 * worry about clients, since they won't call this function. 01137 * we don't have to check for the buffer being reallocated because 01138 * BufferStart and BufferEnd won't be reset when allocating memory for 01139 * sending the response. we don't have to check for the new buffer here as 01140 * it won't be used a type memory, only for buffer memory */ 01141 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd) 01142 goto notfree; 01143 01144 if (attr & RPC_FC_P_ONSTACK) { 01145 TRACE("not freeing stack ptr %p\n", Pointer); 01146 return; 01147 } 01148 TRACE("freeing %p\n", Pointer); 01149 NdrFree(pStubMsg, Pointer); 01150 return; 01151 notfree: 01152 TRACE("not freeing %p\n", Pointer); 01153 } 01154 01155 /*********************************************************************** 01156 * EmbeddedPointerMarshall 01157 */ 01158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 01159 unsigned char *pMemory, 01160 PFORMAT_STRING pFormat) 01161 { 01162 unsigned char *Mark = pStubMsg->BufferMark; 01163 unsigned rep, count, stride; 01164 unsigned i; 01165 unsigned char *saved_buffer = NULL; 01166 01167 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01168 01169 if (*pFormat != RPC_FC_PP) return NULL; 01170 pFormat += 2; 01171 01172 if (pStubMsg->PointerBufferMark) 01173 { 01174 saved_buffer = pStubMsg->Buffer; 01175 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 01176 pStubMsg->PointerBufferMark = NULL; 01177 } 01178 01179 while (pFormat[0] != RPC_FC_END) { 01180 switch (pFormat[0]) { 01181 default: 01182 FIXME("unknown repeat type %d\n", pFormat[0]); 01183 case RPC_FC_NO_REPEAT: 01184 rep = 1; 01185 stride = 0; 01186 count = 1; 01187 pFormat += 2; 01188 break; 01189 case RPC_FC_FIXED_REPEAT: 01190 rep = *(const WORD*)&pFormat[2]; 01191 stride = *(const WORD*)&pFormat[4]; 01192 count = *(const WORD*)&pFormat[8]; 01193 pFormat += 10; 01194 break; 01195 case RPC_FC_VARIABLE_REPEAT: 01196 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 01197 stride = *(const WORD*)&pFormat[2]; 01198 count = *(const WORD*)&pFormat[6]; 01199 pFormat += 8; 01200 break; 01201 } 01202 for (i = 0; i < rep; i++) { 01203 PFORMAT_STRING info = pFormat; 01204 unsigned char *membase = pMemory + (i * stride); 01205 unsigned char *bufbase = Mark + (i * stride); 01206 unsigned u; 01207 01208 for (u=0; u<count; u++,info+=8) { 01209 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 01210 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 01211 unsigned char *saved_memory = pStubMsg->Memory; 01212 01213 pStubMsg->Memory = pMemory; 01214 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); 01215 pStubMsg->Memory = saved_memory; 01216 } 01217 } 01218 pFormat += 8 * count; 01219 } 01220 01221 if (saved_buffer) 01222 { 01223 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 01224 pStubMsg->Buffer = saved_buffer; 01225 } 01226 01227 STD_OVERFLOW_CHECK(pStubMsg); 01228 01229 return NULL; 01230 } 01231 01232 /*********************************************************************** 01233 * EmbeddedPointerUnmarshall 01234 */ 01235 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 01236 unsigned char *pDstBuffer, 01237 unsigned char *pSrcMemoryPtrs, 01238 PFORMAT_STRING pFormat, 01239 unsigned char fMustAlloc) 01240 { 01241 unsigned char *Mark = pStubMsg->BufferMark; 01242 unsigned rep, count, stride; 01243 unsigned i; 01244 unsigned char *saved_buffer = NULL; 01245 01246 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc); 01247 01248 if (*pFormat != RPC_FC_PP) return NULL; 01249 pFormat += 2; 01250 01251 if (pStubMsg->PointerBufferMark) 01252 { 01253 saved_buffer = pStubMsg->Buffer; 01254 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 01255 pStubMsg->PointerBufferMark = NULL; 01256 } 01257 01258 while (pFormat[0] != RPC_FC_END) { 01259 TRACE("pFormat[0] = 0x%x\n", pFormat[0]); 01260 switch (pFormat[0]) { 01261 default: 01262 FIXME("unknown repeat type %d\n", pFormat[0]); 01263 case RPC_FC_NO_REPEAT: 01264 rep = 1; 01265 stride = 0; 01266 count = 1; 01267 pFormat += 2; 01268 break; 01269 case RPC_FC_FIXED_REPEAT: 01270 rep = *(const WORD*)&pFormat[2]; 01271 stride = *(const WORD*)&pFormat[4]; 01272 count = *(const WORD*)&pFormat[8]; 01273 pFormat += 10; 01274 break; 01275 case RPC_FC_VARIABLE_REPEAT: 01276 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 01277 stride = *(const WORD*)&pFormat[2]; 01278 count = *(const WORD*)&pFormat[6]; 01279 pFormat += 8; 01280 break; 01281 } 01282 for (i = 0; i < rep; i++) { 01283 PFORMAT_STRING info = pFormat; 01284 unsigned char *bufdstbase = pDstBuffer + (i * stride); 01285 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride); 01286 unsigned char *bufbase = Mark + (i * stride); 01287 unsigned u; 01288 01289 for (u=0; u<count; u++,info+=8) { 01290 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]); 01291 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]); 01292 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 01293 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc); 01294 } 01295 } 01296 pFormat += 8 * count; 01297 } 01298 01299 if (saved_buffer) 01300 { 01301 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 01302 pStubMsg->Buffer = saved_buffer; 01303 } 01304 01305 return NULL; 01306 } 01307 01308 /*********************************************************************** 01309 * EmbeddedPointerBufferSize 01310 */ 01311 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 01312 unsigned char *pMemory, 01313 PFORMAT_STRING pFormat) 01314 { 01315 unsigned rep, count, stride; 01316 unsigned i; 01317 ULONG saved_buffer_length = 0; 01318 01319 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01320 01321 if (pStubMsg->IgnoreEmbeddedPointers) return; 01322 01323 if (*pFormat != RPC_FC_PP) return; 01324 pFormat += 2; 01325 01326 if (pStubMsg->PointerLength) 01327 { 01328 saved_buffer_length = pStubMsg->BufferLength; 01329 pStubMsg->BufferLength = pStubMsg->PointerLength; 01330 pStubMsg->PointerLength = 0; 01331 } 01332 01333 while (pFormat[0] != RPC_FC_END) { 01334 switch (pFormat[0]) { 01335 default: 01336 FIXME("unknown repeat type %d\n", pFormat[0]); 01337 case RPC_FC_NO_REPEAT: 01338 rep = 1; 01339 stride = 0; 01340 count = 1; 01341 pFormat += 2; 01342 break; 01343 case RPC_FC_FIXED_REPEAT: 01344 rep = *(const WORD*)&pFormat[2]; 01345 stride = *(const WORD*)&pFormat[4]; 01346 count = *(const WORD*)&pFormat[8]; 01347 pFormat += 10; 01348 break; 01349 case RPC_FC_VARIABLE_REPEAT: 01350 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 01351 stride = *(const WORD*)&pFormat[2]; 01352 count = *(const WORD*)&pFormat[6]; 01353 pFormat += 8; 01354 break; 01355 } 01356 for (i = 0; i < rep; i++) { 01357 PFORMAT_STRING info = pFormat; 01358 unsigned char *membase = pMemory + (i * stride); 01359 unsigned u; 01360 01361 for (u=0; u<count; u++,info+=8) { 01362 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 01363 unsigned char *saved_memory = pStubMsg->Memory; 01364 01365 pStubMsg->Memory = pMemory; 01366 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4); 01367 pStubMsg->Memory = saved_memory; 01368 } 01369 } 01370 pFormat += 8 * count; 01371 } 01372 01373 if (saved_buffer_length) 01374 { 01375 pStubMsg->PointerLength = pStubMsg->BufferLength; 01376 pStubMsg->BufferLength = saved_buffer_length; 01377 } 01378 } 01379 01380 /*********************************************************************** 01381 * EmbeddedPointerMemorySize [internal] 01382 */ 01383 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 01384 PFORMAT_STRING pFormat) 01385 { 01386 unsigned char *Mark = pStubMsg->BufferMark; 01387 unsigned rep, count, stride; 01388 unsigned i; 01389 unsigned char *saved_buffer = NULL; 01390 01391 TRACE("(%p,%p)\n", pStubMsg, pFormat); 01392 01393 if (pStubMsg->IgnoreEmbeddedPointers) return 0; 01394 01395 if (pStubMsg->PointerBufferMark) 01396 { 01397 saved_buffer = pStubMsg->Buffer; 01398 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 01399 pStubMsg->PointerBufferMark = NULL; 01400 } 01401 01402 if (*pFormat != RPC_FC_PP) return 0; 01403 pFormat += 2; 01404 01405 while (pFormat[0] != RPC_FC_END) { 01406 switch (pFormat[0]) { 01407 default: 01408 FIXME("unknown repeat type %d\n", pFormat[0]); 01409 case RPC_FC_NO_REPEAT: 01410 rep = 1; 01411 stride = 0; 01412 count = 1; 01413 pFormat += 2; 01414 break; 01415 case RPC_FC_FIXED_REPEAT: 01416 rep = *(const WORD*)&pFormat[2]; 01417 stride = *(const WORD*)&pFormat[4]; 01418 count = *(const WORD*)&pFormat[8]; 01419 pFormat += 10; 01420 break; 01421 case RPC_FC_VARIABLE_REPEAT: 01422 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 01423 stride = *(const WORD*)&pFormat[2]; 01424 count = *(const WORD*)&pFormat[6]; 01425 pFormat += 8; 01426 break; 01427 } 01428 for (i = 0; i < rep; i++) { 01429 PFORMAT_STRING info = pFormat; 01430 unsigned char *bufbase = Mark + (i * stride); 01431 unsigned u; 01432 for (u=0; u<count; u++,info+=8) { 01433 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; 01434 PointerMemorySize(pStubMsg, bufptr, info+4); 01435 } 01436 } 01437 pFormat += 8 * count; 01438 } 01439 01440 if (saved_buffer) 01441 { 01442 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 01443 pStubMsg->Buffer = saved_buffer; 01444 } 01445 01446 return 0; 01447 } 01448 01449 /*********************************************************************** 01450 * EmbeddedPointerFree [internal] 01451 */ 01452 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 01453 unsigned char *pMemory, 01454 PFORMAT_STRING pFormat) 01455 { 01456 unsigned rep, count, stride; 01457 unsigned i; 01458 01459 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01460 if (*pFormat != RPC_FC_PP) return; 01461 pFormat += 2; 01462 01463 while (pFormat[0] != RPC_FC_END) { 01464 switch (pFormat[0]) { 01465 default: 01466 FIXME("unknown repeat type %d\n", pFormat[0]); 01467 case RPC_FC_NO_REPEAT: 01468 rep = 1; 01469 stride = 0; 01470 count = 1; 01471 pFormat += 2; 01472 break; 01473 case RPC_FC_FIXED_REPEAT: 01474 rep = *(const WORD*)&pFormat[2]; 01475 stride = *(const WORD*)&pFormat[4]; 01476 count = *(const WORD*)&pFormat[8]; 01477 pFormat += 10; 01478 break; 01479 case RPC_FC_VARIABLE_REPEAT: 01480 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; 01481 stride = *(const WORD*)&pFormat[2]; 01482 count = *(const WORD*)&pFormat[6]; 01483 pFormat += 8; 01484 break; 01485 } 01486 for (i = 0; i < rep; i++) { 01487 PFORMAT_STRING info = pFormat; 01488 unsigned char *membase = pMemory + (i * stride); 01489 unsigned u; 01490 01491 for (u=0; u<count; u++,info+=8) { 01492 unsigned char *memptr = membase + *(const SHORT*)&info[0]; 01493 unsigned char *saved_memory = pStubMsg->Memory; 01494 01495 pStubMsg->Memory = pMemory; 01496 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4); 01497 pStubMsg->Memory = saved_memory; 01498 } 01499 } 01500 pFormat += 8 * count; 01501 } 01502 } 01503 01504 /*********************************************************************** 01505 * NdrPointerMarshall [RPCRT4.@] 01506 */ 01507 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 01508 unsigned char *pMemory, 01509 PFORMAT_STRING pFormat) 01510 { 01511 unsigned char *Buffer; 01512 01513 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01514 01515 /* Increment the buffer here instead of in PointerMarshall, 01516 * as that is used by embedded pointers which already handle the incrementing 01517 * the buffer, and shouldn't write any additional pointer data to the wire */ 01518 if (*pFormat != RPC_FC_RP) 01519 { 01520 align_pointer_clear(&pStubMsg->Buffer, 4); 01521 Buffer = pStubMsg->Buffer; 01522 safe_buffer_increment(pStubMsg, 4); 01523 } 01524 else 01525 Buffer = pStubMsg->Buffer; 01526 01527 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat); 01528 01529 return NULL; 01530 } 01531 01532 /*********************************************************************** 01533 * NdrPointerUnmarshall [RPCRT4.@] 01534 */ 01535 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 01536 unsigned char **ppMemory, 01537 PFORMAT_STRING pFormat, 01538 unsigned char fMustAlloc) 01539 { 01540 unsigned char *Buffer; 01541 01542 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 01543 01544 if (*pFormat == RPC_FC_RP) 01545 { 01546 Buffer = pStubMsg->Buffer; 01547 /* Do the NULL ref pointer check here because embedded pointers can be 01548 * NULL if the type the pointer is embedded in was allocated rather than 01549 * being passed in by the client */ 01550 if (pStubMsg->IsClient && !*ppMemory) 01551 { 01552 ERR("NULL ref pointer is not allowed\n"); 01553 RpcRaiseException(RPC_X_NULL_REF_POINTER); 01554 } 01555 } 01556 else 01557 { 01558 /* Increment the buffer here instead of in PointerUnmarshall, 01559 * as that is used by embedded pointers which already handle the incrementing 01560 * the buffer, and shouldn't read any additional pointer data from the 01561 * buffer */ 01562 align_pointer(&pStubMsg->Buffer, 4); 01563 Buffer = pStubMsg->Buffer; 01564 safe_buffer_increment(pStubMsg, 4); 01565 } 01566 01567 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc); 01568 01569 return NULL; 01570 } 01571 01572 /*********************************************************************** 01573 * NdrPointerBufferSize [RPCRT4.@] 01574 */ 01575 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 01576 unsigned char *pMemory, 01577 PFORMAT_STRING pFormat) 01578 { 01579 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01580 01581 /* Increment the buffer length here instead of in PointerBufferSize, 01582 * as that is used by embedded pointers which already handle the buffer 01583 * length, and shouldn't write anything more to the wire */ 01584 if (*pFormat != RPC_FC_RP) 01585 { 01586 align_length(&pStubMsg->BufferLength, 4); 01587 safe_buffer_length_increment(pStubMsg, 4); 01588 } 01589 01590 PointerBufferSize(pStubMsg, pMemory, pFormat); 01591 } 01592 01593 /*********************************************************************** 01594 * NdrPointerMemorySize [RPCRT4.@] 01595 */ 01596 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 01597 PFORMAT_STRING pFormat) 01598 { 01599 unsigned char *Buffer = pStubMsg->Buffer; 01600 if (*pFormat != RPC_FC_RP) 01601 { 01602 align_pointer(&pStubMsg->Buffer, 4); 01603 safe_buffer_increment(pStubMsg, 4); 01604 } 01605 align_length(&pStubMsg->MemorySize, sizeof(void *)); 01606 return PointerMemorySize(pStubMsg, Buffer, pFormat); 01607 } 01608 01609 /*********************************************************************** 01610 * NdrPointerFree [RPCRT4.@] 01611 */ 01612 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 01613 unsigned char *pMemory, 01614 PFORMAT_STRING pFormat) 01615 { 01616 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01617 PointerFree(pStubMsg, pMemory, pFormat); 01618 } 01619 01620 /*********************************************************************** 01621 * NdrSimpleTypeMarshall [RPCRT4.@] 01622 */ 01623 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, 01624 unsigned char FormatChar ) 01625 { 01626 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar); 01627 } 01628 01629 /*********************************************************************** 01630 * NdrSimpleTypeUnmarshall [RPCRT4.@] 01631 * 01632 * Unmarshall a base type. 01633 * 01634 * NOTES 01635 * Doesn't check that the buffer is long enough before copying, so the caller 01636 * should do this. 01637 */ 01638 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, 01639 unsigned char FormatChar ) 01640 { 01641 #define BASE_TYPE_UNMARSHALL(type) \ 01642 align_pointer(&pStubMsg->Buffer, sizeof(type)); \ 01643 TRACE("pMemory: %p\n", pMemory); \ 01644 *(type *)pMemory = *(type *)pStubMsg->Buffer; \ 01645 pStubMsg->Buffer += sizeof(type); 01646 01647 switch(FormatChar) 01648 { 01649 case RPC_FC_BYTE: 01650 case RPC_FC_CHAR: 01651 case RPC_FC_SMALL: 01652 case RPC_FC_USMALL: 01653 BASE_TYPE_UNMARSHALL(UCHAR); 01654 TRACE("value: 0x%02x\n", *pMemory); 01655 break; 01656 case RPC_FC_WCHAR: 01657 case RPC_FC_SHORT: 01658 case RPC_FC_USHORT: 01659 BASE_TYPE_UNMARSHALL(USHORT); 01660 TRACE("value: 0x%04x\n", *(USHORT *)pMemory); 01661 break; 01662 case RPC_FC_LONG: 01663 case RPC_FC_ULONG: 01664 case RPC_FC_ERROR_STATUS_T: 01665 case RPC_FC_ENUM32: 01666 BASE_TYPE_UNMARSHALL(ULONG); 01667 TRACE("value: 0x%08x\n", *(ULONG *)pMemory); 01668 break; 01669 case RPC_FC_FLOAT: 01670 BASE_TYPE_UNMARSHALL(float); 01671 TRACE("value: %f\n", *(float *)pMemory); 01672 break; 01673 case RPC_FC_DOUBLE: 01674 BASE_TYPE_UNMARSHALL(double); 01675 TRACE("value: %f\n", *(double *)pMemory); 01676 break; 01677 case RPC_FC_HYPER: 01678 BASE_TYPE_UNMARSHALL(ULONGLONG); 01679 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory)); 01680 break; 01681 case RPC_FC_ENUM16: 01682 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 01683 TRACE("pMemory: %p\n", pMemory); 01684 /* 16-bits on the wire, but int in memory */ 01685 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer; 01686 pStubMsg->Buffer += sizeof(USHORT); 01687 TRACE("value: 0x%08x\n", *(UINT *)pMemory); 01688 break; 01689 case RPC_FC_INT3264: 01690 align_pointer(&pStubMsg->Buffer, sizeof(INT)); 01691 /* 32-bits on the wire, but int_ptr in memory */ 01692 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer; 01693 pStubMsg->Buffer += sizeof(INT); 01694 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory); 01695 break; 01696 case RPC_FC_UINT3264: 01697 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 01698 /* 32-bits on the wire, but int_ptr in memory */ 01699 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer; 01700 pStubMsg->Buffer += sizeof(UINT); 01701 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory); 01702 break; 01703 case RPC_FC_IGNORE: 01704 break; 01705 default: 01706 FIXME("Unhandled base type: 0x%02x\n", FormatChar); 01707 } 01708 #undef BASE_TYPE_UNMARSHALL 01709 } 01710 01711 /*********************************************************************** 01712 * NdrSimpleStructMarshall [RPCRT4.@] 01713 */ 01714 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 01715 unsigned char *pMemory, 01716 PFORMAT_STRING pFormat) 01717 { 01718 unsigned size = *(const WORD*)(pFormat+2); 01719 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01720 01721 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1); 01722 01723 pStubMsg->BufferMark = pStubMsg->Buffer; 01724 safe_copy_to_buffer(pStubMsg, pMemory, size); 01725 01726 if (pFormat[0] != RPC_FC_STRUCT) 01727 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4); 01728 01729 return NULL; 01730 } 01731 01732 /*********************************************************************** 01733 * NdrSimpleStructUnmarshall [RPCRT4.@] 01734 */ 01735 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 01736 unsigned char **ppMemory, 01737 PFORMAT_STRING pFormat, 01738 unsigned char fMustAlloc) 01739 { 01740 unsigned size = *(const WORD*)(pFormat+2); 01741 unsigned char *saved_buffer; 01742 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 01743 01744 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 01745 01746 if (fMustAlloc) 01747 *ppMemory = NdrAllocate(pStubMsg, size); 01748 else 01749 { 01750 if (!pStubMsg->IsClient && !*ppMemory) 01751 /* for servers, we just point straight into the RPC buffer */ 01752 *ppMemory = pStubMsg->Buffer; 01753 } 01754 01755 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 01756 safe_buffer_increment(pStubMsg, size); 01757 if (pFormat[0] == RPC_FC_PSTRUCT) 01758 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc); 01759 01760 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 01761 if (*ppMemory != saved_buffer) 01762 memcpy(*ppMemory, saved_buffer, size); 01763 01764 return NULL; 01765 } 01766 01767 /*********************************************************************** 01768 * NdrSimpleStructBufferSize [RPCRT4.@] 01769 */ 01770 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 01771 unsigned char *pMemory, 01772 PFORMAT_STRING pFormat) 01773 { 01774 unsigned size = *(const WORD*)(pFormat+2); 01775 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01776 01777 align_length(&pStubMsg->BufferLength, pFormat[1] + 1); 01778 01779 safe_buffer_length_increment(pStubMsg, size); 01780 if (pFormat[0] != RPC_FC_STRUCT) 01781 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4); 01782 } 01783 01784 /*********************************************************************** 01785 * NdrSimpleStructMemorySize [RPCRT4.@] 01786 */ 01787 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 01788 PFORMAT_STRING pFormat) 01789 { 01790 unsigned short size = *(const WORD *)(pFormat+2); 01791 01792 TRACE("(%p,%p)\n", pStubMsg, pFormat); 01793 01794 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 01795 pStubMsg->MemorySize += size; 01796 safe_buffer_increment(pStubMsg, size); 01797 01798 if (pFormat[0] != RPC_FC_STRUCT) 01799 EmbeddedPointerMemorySize(pStubMsg, pFormat+4); 01800 return pStubMsg->MemorySize; 01801 } 01802 01803 /*********************************************************************** 01804 * NdrSimpleStructFree [RPCRT4.@] 01805 */ 01806 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, 01807 unsigned char *pMemory, 01808 PFORMAT_STRING pFormat) 01809 { 01810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 01811 if (pFormat[0] != RPC_FC_STRUCT) 01812 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4); 01813 } 01814 01815 /* Array helpers */ 01816 01817 static inline void array_compute_and_size_conformance( 01818 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 01819 PFORMAT_STRING pFormat) 01820 { 01821 DWORD count; 01822 01823 switch (fc) 01824 { 01825 case RPC_FC_CARRAY: 01826 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 01827 SizeConformance(pStubMsg); 01828 break; 01829 case RPC_FC_CVARRAY: 01830 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); 01831 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 01832 SizeConformance(pStubMsg); 01833 break; 01834 case RPC_FC_C_CSTRING: 01835 case RPC_FC_C_WSTRING: 01836 if (fc == RPC_FC_C_CSTRING) 01837 { 01838 TRACE("string=%s\n", debugstr_a((const char *)pMemory)); 01839 pStubMsg->ActualCount = strlen((const char *)pMemory)+1; 01840 } 01841 else 01842 { 01843 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); 01844 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; 01845 } 01846 01847 if (pFormat[1] == RPC_FC_STRING_SIZED) 01848 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); 01849 else 01850 pStubMsg->MaxCount = pStubMsg->ActualCount; 01851 01852 SizeConformance(pStubMsg); 01853 break; 01854 case RPC_FC_BOGUS_ARRAY: 01855 count = *(const WORD *)(pFormat + 2); 01856 pFormat += 4; 01857 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg); 01858 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count); 01859 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 01860 break; 01861 default: 01862 ERR("unknown array format 0x%x\n", fc); 01863 RpcRaiseException(RPC_X_BAD_STUB_DATA); 01864 } 01865 } 01866 01867 static inline void array_buffer_size( 01868 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 01869 PFORMAT_STRING pFormat, unsigned char fHasPointers) 01870 { 01871 DWORD i, size; 01872 DWORD esize; 01873 unsigned char alignment; 01874 01875 switch (fc) 01876 { 01877 case RPC_FC_CARRAY: 01878 esize = *(const WORD*)(pFormat+2); 01879 alignment = pFormat[1] + 1; 01880 01881 pFormat = SkipConformance(pStubMsg, pFormat + 4); 01882 01883 align_length(&pStubMsg->BufferLength, alignment); 01884 01885 size = safe_multiply(esize, pStubMsg->MaxCount); 01886 /* conformance value plus array */ 01887 safe_buffer_length_increment(pStubMsg, size); 01888 01889 if (fHasPointers) 01890 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 01891 break; 01892 case RPC_FC_CVARRAY: 01893 esize = *(const WORD*)(pFormat+2); 01894 alignment = pFormat[1] + 1; 01895 01896 pFormat = SkipConformance(pStubMsg, pFormat + 4); 01897 pFormat = SkipVariance(pStubMsg, pFormat); 01898 01899 SizeVariance(pStubMsg); 01900 01901 align_length(&pStubMsg->BufferLength, alignment); 01902 01903 size = safe_multiply(esize, pStubMsg->ActualCount); 01904 safe_buffer_length_increment(pStubMsg, size); 01905 01906 if (fHasPointers) 01907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 01908 break; 01909 case RPC_FC_C_CSTRING: 01910 case RPC_FC_C_WSTRING: 01911 if (fc == RPC_FC_C_CSTRING) 01912 esize = 1; 01913 else 01914 esize = 2; 01915 01916 SizeVariance(pStubMsg); 01917 01918 size = safe_multiply(esize, pStubMsg->ActualCount); 01919 safe_buffer_length_increment(pStubMsg, size); 01920 break; 01921 case RPC_FC_BOGUS_ARRAY: 01922 alignment = pFormat[1] + 1; 01923 pFormat = SkipConformance(pStubMsg, pFormat + 4); 01924 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg); 01925 pFormat = SkipVariance(pStubMsg, pFormat); 01926 01927 align_length(&pStubMsg->BufferLength, alignment); 01928 01929 size = pStubMsg->ActualCount; 01930 for (i = 0; i < size; i++) 01931 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL); 01932 break; 01933 default: 01934 ERR("unknown array format 0x%x\n", fc); 01935 RpcRaiseException(RPC_X_BAD_STUB_DATA); 01936 } 01937 } 01938 01939 static inline void array_compute_and_write_conformance( 01940 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 01941 PFORMAT_STRING pFormat) 01942 { 01943 ULONG def; 01944 BOOL conformance_present; 01945 01946 switch (fc) 01947 { 01948 case RPC_FC_CARRAY: 01949 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 01950 WriteConformance(pStubMsg); 01951 break; 01952 case RPC_FC_CVARRAY: 01953 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); 01954 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 01955 WriteConformance(pStubMsg); 01956 break; 01957 case RPC_FC_C_CSTRING: 01958 case RPC_FC_C_WSTRING: 01959 if (fc == RPC_FC_C_CSTRING) 01960 { 01961 TRACE("string=%s\n", debugstr_a((const char *)pMemory)); 01962 pStubMsg->ActualCount = strlen((const char *)pMemory)+1; 01963 } 01964 else 01965 { 01966 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); 01967 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; 01968 } 01969 if (pFormat[1] == RPC_FC_STRING_SIZED) 01970 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); 01971 else 01972 pStubMsg->MaxCount = pStubMsg->ActualCount; 01973 pStubMsg->Offset = 0; 01974 WriteConformance(pStubMsg); 01975 break; 01976 case RPC_FC_BOGUS_ARRAY: 01977 def = *(const WORD *)(pFormat + 2); 01978 pFormat += 4; 01979 conformance_present = IsConformanceOrVariancePresent(pFormat); 01980 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); 01981 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 01982 if (conformance_present) WriteConformance(pStubMsg); 01983 break; 01984 default: 01985 ERR("unknown array format 0x%x\n", fc); 01986 RpcRaiseException(RPC_X_BAD_STUB_DATA); 01987 } 01988 } 01989 01990 static inline void array_write_variance_and_marshall( 01991 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, 01992 PFORMAT_STRING pFormat, unsigned char fHasPointers) 01993 { 01994 DWORD i, size; 01995 DWORD esize; 01996 unsigned char alignment; 01997 01998 switch (fc) 01999 { 02000 case RPC_FC_CARRAY: 02001 esize = *(const WORD*)(pFormat+2); 02002 alignment = pFormat[1] + 1; 02003 02004 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02005 02006 align_pointer_clear(&pStubMsg->Buffer, alignment); 02007 02008 size = safe_multiply(esize, pStubMsg->MaxCount); 02009 if (fHasPointers) 02010 pStubMsg->BufferMark = pStubMsg->Buffer; 02011 safe_copy_to_buffer(pStubMsg, pMemory, size); 02012 02013 if (fHasPointers) 02014 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 02015 break; 02016 case RPC_FC_CVARRAY: 02017 esize = *(const WORD*)(pFormat+2); 02018 alignment = pFormat[1] + 1; 02019 02020 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02021 pFormat = SkipVariance(pStubMsg, pFormat); 02022 02023 WriteVariance(pStubMsg); 02024 02025 align_pointer_clear(&pStubMsg->Buffer, alignment); 02026 02027 size = safe_multiply(esize, pStubMsg->ActualCount); 02028 02029 if (fHasPointers) 02030 pStubMsg->BufferMark = pStubMsg->Buffer; 02031 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size); 02032 02033 if (fHasPointers) 02034 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 02035 break; 02036 case RPC_FC_C_CSTRING: 02037 case RPC_FC_C_WSTRING: 02038 if (fc == RPC_FC_C_CSTRING) 02039 esize = 1; 02040 else 02041 esize = 2; 02042 02043 WriteVariance(pStubMsg); 02044 02045 size = safe_multiply(esize, pStubMsg->ActualCount); 02046 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ 02047 break; 02048 case RPC_FC_BOGUS_ARRAY: 02049 alignment = pFormat[1] + 1; 02050 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02051 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg); 02052 pFormat = SkipVariance(pStubMsg, pFormat); 02053 02054 align_pointer_clear(&pStubMsg->Buffer, alignment); 02055 02056 size = pStubMsg->ActualCount; 02057 for (i = 0; i < size; i++) 02058 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL); 02059 break; 02060 default: 02061 ERR("unknown array format 0x%x\n", fc); 02062 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02063 } 02064 } 02065 02066 static inline ULONG array_read_conformance( 02067 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 02068 { 02069 DWORD def, esize; 02070 02071 switch (fc) 02072 { 02073 case RPC_FC_CARRAY: 02074 esize = *(const WORD*)(pFormat+2); 02075 pFormat = ReadConformance(pStubMsg, pFormat+4); 02076 return safe_multiply(esize, pStubMsg->MaxCount); 02077 case RPC_FC_CVARRAY: 02078 esize = *(const WORD*)(pFormat+2); 02079 pFormat = ReadConformance(pStubMsg, pFormat+4); 02080 return safe_multiply(esize, pStubMsg->MaxCount); 02081 case RPC_FC_C_CSTRING: 02082 case RPC_FC_C_WSTRING: 02083 if (fc == RPC_FC_C_CSTRING) 02084 esize = 1; 02085 else 02086 esize = 2; 02087 02088 if (pFormat[1] == RPC_FC_STRING_SIZED) 02089 ReadConformance(pStubMsg, pFormat + 2); 02090 else 02091 ReadConformance(pStubMsg, NULL); 02092 return safe_multiply(esize, pStubMsg->MaxCount); 02093 case RPC_FC_BOGUS_ARRAY: 02094 def = *(const WORD *)(pFormat + 2); 02095 pFormat += 4; 02096 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat); 02097 else 02098 { 02099 pStubMsg->MaxCount = def; 02100 pFormat = SkipConformance( pStubMsg, pFormat ); 02101 } 02102 pFormat = SkipVariance( pStubMsg, pFormat ); 02103 02104 esize = ComplexStructSize(pStubMsg, pFormat); 02105 return safe_multiply(pStubMsg->MaxCount, esize); 02106 default: 02107 ERR("unknown array format 0x%x\n", fc); 02108 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02109 } 02110 } 02111 02112 static inline ULONG array_read_variance_and_unmarshall( 02113 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, 02114 PFORMAT_STRING pFormat, unsigned char fMustAlloc, 02115 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall) 02116 { 02117 ULONG bufsize, memsize; 02118 WORD esize; 02119 unsigned char alignment; 02120 unsigned char *saved_buffer, *pMemory; 02121 ULONG i, offset, count; 02122 02123 switch (fc) 02124 { 02125 case RPC_FC_CARRAY: 02126 esize = *(const WORD*)(pFormat+2); 02127 alignment = pFormat[1] + 1; 02128 02129 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); 02130 02131 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02132 02133 align_pointer(&pStubMsg->Buffer, alignment); 02134 02135 if (fUnmarshall) 02136 { 02137 if (fMustAlloc) 02138 *ppMemory = NdrAllocate(pStubMsg, memsize); 02139 else 02140 { 02141 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory) 02142 /* for servers, we just point straight into the RPC buffer */ 02143 *ppMemory = pStubMsg->Buffer; 02144 } 02145 02146 saved_buffer = pStubMsg->Buffer; 02147 safe_buffer_increment(pStubMsg, bufsize); 02148 02149 pStubMsg->BufferMark = saved_buffer; 02150 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 02151 02152 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 02153 if (*ppMemory != saved_buffer) 02154 memcpy(*ppMemory, saved_buffer, bufsize); 02155 } 02156 return bufsize; 02157 case RPC_FC_CVARRAY: 02158 esize = *(const WORD*)(pFormat+2); 02159 alignment = pFormat[1] + 1; 02160 02161 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02162 02163 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 02164 02165 align_pointer(&pStubMsg->Buffer, alignment); 02166 02167 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02168 memsize = safe_multiply(esize, pStubMsg->MaxCount); 02169 02170 if (fUnmarshall) 02171 { 02172 offset = pStubMsg->Offset; 02173 02174 if (!fMustAlloc && !*ppMemory) 02175 fMustAlloc = TRUE; 02176 if (fMustAlloc) 02177 *ppMemory = NdrAllocate(pStubMsg, memsize); 02178 saved_buffer = pStubMsg->Buffer; 02179 safe_buffer_increment(pStubMsg, bufsize); 02180 02181 pStubMsg->BufferMark = saved_buffer; 02182 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, 02183 fMustAlloc); 02184 02185 memcpy(*ppMemory + offset, saved_buffer, bufsize); 02186 } 02187 return bufsize; 02188 case RPC_FC_C_CSTRING: 02189 case RPC_FC_C_WSTRING: 02190 if (fc == RPC_FC_C_CSTRING) 02191 esize = 1; 02192 else 02193 esize = 2; 02194 02195 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); 02196 02197 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) 02198 { 02199 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", 02200 pStubMsg->ActualCount, pStubMsg->MaxCount); 02201 RpcRaiseException(RPC_S_INVALID_BOUND); 02202 } 02203 if (pStubMsg->Offset) 02204 { 02205 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 02206 RpcRaiseException(RPC_S_INVALID_BOUND); 02207 } 02208 02209 memsize = safe_multiply(esize, pStubMsg->MaxCount); 02210 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02211 02212 validate_string_data(pStubMsg, bufsize, esize); 02213 02214 if (fUnmarshall) 02215 { 02216 if (fMustAlloc) 02217 *ppMemory = NdrAllocate(pStubMsg, memsize); 02218 else 02219 { 02220 if (fUseBufferMemoryServer && !pStubMsg->IsClient && 02221 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) 02222 /* if the data in the RPC buffer is big enough, we just point 02223 * straight into it */ 02224 *ppMemory = pStubMsg->Buffer; 02225 else if (!*ppMemory) 02226 *ppMemory = NdrAllocate(pStubMsg, memsize); 02227 } 02228 02229 if (*ppMemory == pStubMsg->Buffer) 02230 safe_buffer_increment(pStubMsg, bufsize); 02231 else 02232 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); 02233 02234 if (*pFormat == RPC_FC_C_CSTRING) 02235 TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); 02236 else 02237 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); 02238 } 02239 return bufsize; 02240 02241 case RPC_FC_BOGUS_ARRAY: 02242 alignment = pFormat[1] + 1; 02243 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02244 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 02245 02246 esize = ComplexStructSize(pStubMsg, pFormat); 02247 memsize = safe_multiply(esize, pStubMsg->MaxCount); 02248 02249 assert( fUnmarshall ); 02250 02251 if (!fMustAlloc && !*ppMemory) 02252 fMustAlloc = TRUE; 02253 if (fMustAlloc) 02254 *ppMemory = NdrAllocate(pStubMsg, memsize); 02255 02256 align_pointer(&pStubMsg->Buffer, alignment); 02257 saved_buffer = pStubMsg->Buffer; 02258 02259 pMemory = *ppMemory; 02260 count = pStubMsg->ActualCount; 02261 for (i = 0; i < count; i++) 02262 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc); 02263 return pStubMsg->Buffer - saved_buffer; 02264 02265 default: 02266 ERR("unknown array format 0x%x\n", fc); 02267 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02268 } 02269 } 02270 02271 static inline void array_memory_size( 02272 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, 02273 unsigned char fHasPointers) 02274 { 02275 ULONG i, count, SavedMemorySize; 02276 ULONG bufsize, memsize; 02277 DWORD esize; 02278 unsigned char alignment; 02279 02280 switch (fc) 02281 { 02282 case RPC_FC_CARRAY: 02283 esize = *(const WORD*)(pFormat+2); 02284 alignment = pFormat[1] + 1; 02285 02286 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02287 02288 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); 02289 pStubMsg->MemorySize += memsize; 02290 02291 align_pointer(&pStubMsg->Buffer, alignment); 02292 if (fHasPointers) 02293 pStubMsg->BufferMark = pStubMsg->Buffer; 02294 safe_buffer_increment(pStubMsg, bufsize); 02295 02296 if (fHasPointers) 02297 EmbeddedPointerMemorySize(pStubMsg, pFormat); 02298 break; 02299 case RPC_FC_CVARRAY: 02300 esize = *(const WORD*)(pFormat+2); 02301 alignment = pFormat[1] + 1; 02302 02303 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02304 02305 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 02306 02307 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02308 memsize = safe_multiply(esize, pStubMsg->MaxCount); 02309 pStubMsg->MemorySize += memsize; 02310 02311 align_pointer(&pStubMsg->Buffer, alignment); 02312 if (fHasPointers) 02313 pStubMsg->BufferMark = pStubMsg->Buffer; 02314 safe_buffer_increment(pStubMsg, bufsize); 02315 02316 if (fHasPointers) 02317 EmbeddedPointerMemorySize(pStubMsg, pFormat); 02318 break; 02319 case RPC_FC_C_CSTRING: 02320 case RPC_FC_C_WSTRING: 02321 if (fc == RPC_FC_C_CSTRING) 02322 esize = 1; 02323 else 02324 esize = 2; 02325 02326 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); 02327 02328 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) 02329 { 02330 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", 02331 pStubMsg->ActualCount, pStubMsg->MaxCount); 02332 RpcRaiseException(RPC_S_INVALID_BOUND); 02333 } 02334 if (pStubMsg->Offset) 02335 { 02336 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 02337 RpcRaiseException(RPC_S_INVALID_BOUND); 02338 } 02339 02340 memsize = safe_multiply(esize, pStubMsg->MaxCount); 02341 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02342 02343 validate_string_data(pStubMsg, bufsize, esize); 02344 02345 safe_buffer_increment(pStubMsg, bufsize); 02346 pStubMsg->MemorySize += memsize; 02347 break; 02348 case RPC_FC_BOGUS_ARRAY: 02349 alignment = pFormat[1] + 1; 02350 pFormat = SkipConformance(pStubMsg, pFormat + 4); 02351 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); 02352 02353 align_pointer(&pStubMsg->Buffer, alignment); 02354 02355 SavedMemorySize = pStubMsg->MemorySize; 02356 02357 esize = ComplexStructSize(pStubMsg, pFormat); 02358 memsize = safe_multiply(pStubMsg->MaxCount, esize); 02359 02360 count = pStubMsg->ActualCount; 02361 for (i = 0; i < count; i++) 02362 ComplexStructMemorySize(pStubMsg, pFormat, NULL); 02363 02364 pStubMsg->MemorySize = SavedMemorySize + memsize; 02365 break; 02366 default: 02367 ERR("unknown array format 0x%x\n", fc); 02368 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02369 } 02370 } 02371 02372 static inline void array_free( 02373 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, 02374 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers) 02375 { 02376 DWORD i, count; 02377 02378 switch (fc) 02379 { 02380 case RPC_FC_CARRAY: 02381 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 02382 if (fHasPointers) 02383 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 02384 break; 02385 case RPC_FC_CVARRAY: 02386 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); 02387 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 02388 if (fHasPointers) 02389 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 02390 break; 02391 case RPC_FC_C_CSTRING: 02392 case RPC_FC_C_WSTRING: 02393 /* No embedded pointers so nothing to do */ 02394 break; 02395 case RPC_FC_BOGUS_ARRAY: 02396 count = *(const WORD *)(pFormat + 2); 02397 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count); 02398 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 02399 02400 count = pStubMsg->ActualCount; 02401 for (i = 0; i < count; i++) 02402 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); 02403 break; 02404 default: 02405 ERR("unknown array format 0x%x\n", fc); 02406 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02407 } 02408 } 02409 02410 /* 02411 * NdrConformantString: 02412 * 02413 * What MS calls a ConformantString is, in DCE terminology, 02414 * a Varying-Conformant String. 02415 * [ 02416 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') 02417 * offset: DWORD (actual string data begins at (offset) CHARTYPE's 02418 * into unmarshalled string) 02419 * length: DWORD (# of CHARTYPE characters, inclusive of '\0') 02420 * [ 02421 * data: CHARTYPE[maxlen] 02422 * ] 02423 * ], where CHARTYPE is the appropriate character type (specified externally) 02424 * 02425 */ 02426 02427 /*********************************************************************** 02428 * NdrConformantStringMarshall [RPCRT4.@] 02429 */ 02430 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, 02431 unsigned char *pszMessage, PFORMAT_STRING pFormat) 02432 { 02433 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); 02434 02435 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 02436 ERR("Unhandled string type: %#x\n", pFormat[0]); 02437 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02438 } 02439 02440 /* allow compiler to optimise inline function by passing constant into 02441 * these functions */ 02442 if (pFormat[0] == RPC_FC_C_CSTRING) { 02443 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage, 02444 pFormat); 02445 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage, 02446 pFormat, TRUE /* fHasPointers */); 02447 } else { 02448 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage, 02449 pFormat); 02450 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage, 02451 pFormat, TRUE /* fHasPointers */); 02452 } 02453 02454 return NULL; 02455 } 02456 02457 /*********************************************************************** 02458 * NdrConformantStringBufferSize [RPCRT4.@] 02459 */ 02460 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 02461 unsigned char* pMemory, PFORMAT_STRING pFormat) 02462 { 02463 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 02464 02465 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 02466 ERR("Unhandled string type: %#x\n", pFormat[0]); 02467 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02468 } 02469 02470 /* allow compiler to optimise inline function by passing constant into 02471 * these functions */ 02472 if (pFormat[0] == RPC_FC_C_CSTRING) { 02473 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory, 02474 pFormat); 02475 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat, 02476 TRUE /* fHasPointers */); 02477 } else { 02478 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory, 02479 pFormat); 02480 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat, 02481 TRUE /* fHasPointers */); 02482 } 02483 } 02484 02485 /************************************************************************ 02486 * NdrConformantStringMemorySize [RPCRT4.@] 02487 */ 02488 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, 02489 PFORMAT_STRING pFormat ) 02490 { 02491 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); 02492 02493 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 02494 ERR("Unhandled string type: %#x\n", pFormat[0]); 02495 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02496 } 02497 02498 /* allow compiler to optimise inline function by passing constant into 02499 * these functions */ 02500 if (pFormat[0] == RPC_FC_C_CSTRING) { 02501 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); 02502 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat, 02503 TRUE /* fHasPointers */); 02504 } else { 02505 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); 02506 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat, 02507 TRUE /* fHasPointers */); 02508 } 02509 02510 return pStubMsg->MemorySize; 02511 } 02512 02513 /************************************************************************ 02514 * NdrConformantStringUnmarshall [RPCRT4.@] 02515 */ 02516 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, 02517 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) 02518 { 02519 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", 02520 pStubMsg, *ppMemory, pFormat, fMustAlloc); 02521 02522 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { 02523 ERR("Unhandled string type: %#x\n", *pFormat); 02524 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02525 } 02526 02527 /* allow compiler to optimise inline function by passing constant into 02528 * these functions */ 02529 if (pFormat[0] == RPC_FC_C_CSTRING) { 02530 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); 02531 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory, 02532 pFormat, fMustAlloc, 02533 TRUE /* fUseBufferMemoryServer */, 02534 TRUE /* fUnmarshall */); 02535 } else { 02536 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); 02537 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory, 02538 pFormat, fMustAlloc, 02539 TRUE /* fUseBufferMemoryServer */, 02540 TRUE /* fUnmarshall */); 02541 } 02542 02543 return NULL; 02544 } 02545 02546 /*********************************************************************** 02547 * NdrNonConformantStringMarshall [RPCRT4.@] 02548 */ 02549 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, 02550 unsigned char *pMemory, 02551 PFORMAT_STRING pFormat) 02552 { 02553 ULONG esize, size, maxsize; 02554 02555 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 02556 02557 maxsize = *(const USHORT *)&pFormat[2]; 02558 02559 if (*pFormat == RPC_FC_CSTRING) 02560 { 02561 ULONG i = 0; 02562 const char *str = (const char *)pMemory; 02563 while (i < maxsize && str[i]) i++; 02564 TRACE("string=%s\n", debugstr_an(str, i)); 02565 pStubMsg->ActualCount = i + 1; 02566 esize = 1; 02567 } 02568 else if (*pFormat == RPC_FC_WSTRING) 02569 { 02570 ULONG i = 0; 02571 const WCHAR *str = (const WCHAR *)pMemory; 02572 while (i < maxsize && str[i]) i++; 02573 TRACE("string=%s\n", debugstr_wn(str, i)); 02574 pStubMsg->ActualCount = i + 1; 02575 esize = 2; 02576 } 02577 else 02578 { 02579 ERR("Unhandled string type: %#x\n", *pFormat); 02580 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02581 } 02582 02583 pStubMsg->Offset = 0; 02584 WriteVariance(pStubMsg); 02585 02586 size = safe_multiply(esize, pStubMsg->ActualCount); 02587 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ 02588 02589 return NULL; 02590 } 02591 02592 /*********************************************************************** 02593 * NdrNonConformantStringUnmarshall [RPCRT4.@] 02594 */ 02595 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 02596 unsigned char **ppMemory, 02597 PFORMAT_STRING pFormat, 02598 unsigned char fMustAlloc) 02599 { 02600 ULONG bufsize, memsize, esize, maxsize; 02601 02602 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", 02603 pStubMsg, *ppMemory, pFormat, fMustAlloc); 02604 02605 maxsize = *(const USHORT *)&pFormat[2]; 02606 02607 ReadVariance(pStubMsg, NULL, maxsize); 02608 if (pStubMsg->Offset) 02609 { 02610 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 02611 RpcRaiseException(RPC_S_INVALID_BOUND); 02612 } 02613 02614 if (*pFormat == RPC_FC_CSTRING) esize = 1; 02615 else if (*pFormat == RPC_FC_WSTRING) esize = 2; 02616 else 02617 { 02618 ERR("Unhandled string type: %#x\n", *pFormat); 02619 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02620 } 02621 02622 memsize = esize * maxsize; 02623 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02624 02625 validate_string_data(pStubMsg, bufsize, esize); 02626 02627 if (!fMustAlloc && !*ppMemory) 02628 fMustAlloc = TRUE; 02629 if (fMustAlloc) 02630 *ppMemory = NdrAllocate(pStubMsg, memsize); 02631 02632 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); 02633 02634 if (*pFormat == RPC_FC_CSTRING) { 02635 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); 02636 } 02637 else if (*pFormat == RPC_FC_WSTRING) { 02638 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); 02639 } 02640 02641 return NULL; 02642 } 02643 02644 /*********************************************************************** 02645 * NdrNonConformantStringBufferSize [RPCRT4.@] 02646 */ 02647 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 02648 unsigned char *pMemory, 02649 PFORMAT_STRING pFormat) 02650 { 02651 ULONG esize, maxsize; 02652 02653 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); 02654 02655 maxsize = *(const USHORT *)&pFormat[2]; 02656 02657 SizeVariance(pStubMsg); 02658 02659 if (*pFormat == RPC_FC_CSTRING) 02660 { 02661 ULONG i = 0; 02662 const char *str = (const char *)pMemory; 02663 while (i < maxsize && str[i]) i++; 02664 TRACE("string=%s\n", debugstr_an(str, i)); 02665 pStubMsg->ActualCount = i + 1; 02666 esize = 1; 02667 } 02668 else if (*pFormat == RPC_FC_WSTRING) 02669 { 02670 ULONG i = 0; 02671 const WCHAR *str = (const WCHAR *)pMemory; 02672 while (i < maxsize && str[i]) i++; 02673 TRACE("string=%s\n", debugstr_wn(str, i)); 02674 pStubMsg->ActualCount = i + 1; 02675 esize = 2; 02676 } 02677 else 02678 { 02679 ERR("Unhandled string type: %#x\n", *pFormat); 02680 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02681 } 02682 02683 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 02684 } 02685 02686 /*********************************************************************** 02687 * NdrNonConformantStringMemorySize [RPCRT4.@] 02688 */ 02689 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 02690 PFORMAT_STRING pFormat) 02691 { 02692 ULONG bufsize, memsize, esize, maxsize; 02693 02694 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); 02695 02696 maxsize = *(const USHORT *)&pFormat[2]; 02697 02698 ReadVariance(pStubMsg, NULL, maxsize); 02699 02700 if (pStubMsg->Offset) 02701 { 02702 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 02703 RpcRaiseException(RPC_S_INVALID_BOUND); 02704 } 02705 02706 if (*pFormat == RPC_FC_CSTRING) esize = 1; 02707 else if (*pFormat == RPC_FC_WSTRING) esize = 2; 02708 else 02709 { 02710 ERR("Unhandled string type: %#x\n", *pFormat); 02711 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02712 } 02713 02714 memsize = esize * maxsize; 02715 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 02716 02717 validate_string_data(pStubMsg, bufsize, esize); 02718 02719 safe_buffer_increment(pStubMsg, bufsize); 02720 pStubMsg->MemorySize += memsize; 02721 02722 return pStubMsg->MemorySize; 02723 } 02724 02725 /* Complex types */ 02726 02727 #include "pshpack1.h" 02728 typedef struct 02729 { 02730 unsigned char type; 02731 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ 02732 ULONG low_value; 02733 ULONG high_value; 02734 } NDR_RANGE; 02735 #include "poppack.h" 02736 02737 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg, 02738 PFORMAT_STRING pFormat) 02739 { 02740 switch (*pFormat) { 02741 case RPC_FC_STRUCT: 02742 case RPC_FC_PSTRUCT: 02743 case RPC_FC_CSTRUCT: 02744 case RPC_FC_BOGUS_STRUCT: 02745 case RPC_FC_SMFARRAY: 02746 case RPC_FC_SMVARRAY: 02747 case RPC_FC_CSTRING: 02748 return *(const WORD*)&pFormat[2]; 02749 case RPC_FC_USER_MARSHAL: 02750 return *(const WORD*)&pFormat[4]; 02751 case RPC_FC_RANGE: { 02752 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) { 02753 case RPC_FC_BYTE: 02754 case RPC_FC_CHAR: 02755 case RPC_FC_SMALL: 02756 case RPC_FC_USMALL: 02757 return sizeof(UCHAR); 02758 case RPC_FC_WCHAR: 02759 case RPC_FC_SHORT: 02760 case RPC_FC_USHORT: 02761 return sizeof(USHORT); 02762 case RPC_FC_LONG: 02763 case RPC_FC_ULONG: 02764 case RPC_FC_ENUM32: 02765 case RPC_FC_INT3264: 02766 case RPC_FC_UINT3264: 02767 return sizeof(ULONG); 02768 case RPC_FC_FLOAT: 02769 return sizeof(float); 02770 case RPC_FC_DOUBLE: 02771 return sizeof(double); 02772 case RPC_FC_HYPER: 02773 return sizeof(ULONGLONG); 02774 case RPC_FC_ENUM16: 02775 return sizeof(UINT); 02776 default: 02777 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf); 02778 RpcRaiseException(RPC_X_BAD_STUB_DATA); 02779 } 02780 } 02781 case RPC_FC_NON_ENCAPSULATED_UNION: 02782 pFormat += 2; 02783 if (pStubMsg->fHasNewCorrDesc) 02784 pFormat += 6; 02785 else 02786 pFormat += 4; 02787 02788 pFormat += *(const SHORT*)pFormat; 02789 return *(const SHORT*)pFormat; 02790 case RPC_FC_IP: 02791 return sizeof(void *); 02792 case RPC_FC_WSTRING: 02793 return *(const WORD*)&pFormat[2] * 2; 02794 default: 02795 FIXME("unhandled embedded type %02x\n", *pFormat); 02796 } 02797 return 0; 02798 } 02799 02800 02801 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 02802 PFORMAT_STRING pFormat) 02803 { 02804 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK]; 02805 02806 if (!m) 02807 { 02808 FIXME("no memorysizer for data type=%02x\n", *pFormat); 02809 return 0; 02810 } 02811 02812 return m(pStubMsg, pFormat); 02813 } 02814 02815 02816 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, 02817 unsigned char *pMemory, 02818 PFORMAT_STRING pFormat, 02819 PFORMAT_STRING pPointer) 02820 { 02821 PFORMAT_STRING desc; 02822 NDR_MARSHALL m; 02823 ULONG size; 02824 02825 while (*pFormat != RPC_FC_END) { 02826 switch (*pFormat) { 02827 case RPC_FC_BYTE: 02828 case RPC_FC_CHAR: 02829 case RPC_FC_SMALL: 02830 case RPC_FC_USMALL: 02831 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory); 02832 safe_copy_to_buffer(pStubMsg, pMemory, 1); 02833 pMemory += 1; 02834 break; 02835 case RPC_FC_WCHAR: 02836 case RPC_FC_SHORT: 02837 case RPC_FC_USHORT: 02838 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory); 02839 safe_copy_to_buffer(pStubMsg, pMemory, 2); 02840 pMemory += 2; 02841 break; 02842 case RPC_FC_ENUM16: 02843 { 02844 USHORT val = *(DWORD *)pMemory; 02845 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory); 02846 if (32767 < *(DWORD*)pMemory) 02847 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 02848 safe_copy_to_buffer(pStubMsg, &val, 2); 02849 pMemory += 4; 02850 break; 02851 } 02852 case RPC_FC_LONG: 02853 case RPC_FC_ULONG: 02854 case RPC_FC_ENUM32: 02855 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory); 02856 safe_copy_to_buffer(pStubMsg, pMemory, 4); 02857 pMemory += 4; 02858 break; 02859 case RPC_FC_INT3264: 02860 case RPC_FC_UINT3264: 02861 { 02862 UINT val = *(UINT_PTR *)pMemory; 02863 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory); 02864 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT)); 02865 pMemory += sizeof(UINT_PTR); 02866 break; 02867 } 02868 case RPC_FC_FLOAT: 02869 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory); 02870 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); 02871 pMemory += sizeof(float); 02872 break; 02873 case RPC_FC_HYPER: 02874 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); 02875 safe_copy_to_buffer(pStubMsg, pMemory, 8); 02876 pMemory += 8; 02877 break; 02878 case RPC_FC_DOUBLE: 02879 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory); 02880 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); 02881 pMemory += sizeof(double); 02882 break; 02883 case RPC_FC_RP: 02884 case RPC_FC_UP: 02885 case RPC_FC_OP: 02886 case RPC_FC_FP: 02887 case RPC_FC_POINTER: 02888 { 02889 unsigned char *saved_buffer; 02890 int pointer_buffer_mark_set = 0; 02891 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); 02892 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer); 02893 if (*pFormat != RPC_FC_POINTER) 02894 pPointer = pFormat; 02895 if (*pPointer != RPC_FC_RP) 02896 align_pointer_clear(&pStubMsg->Buffer, 4); 02897 saved_buffer = pStubMsg->Buffer; 02898 if (pStubMsg->PointerBufferMark) 02899 { 02900 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 02901 pStubMsg->PointerBufferMark = NULL; 02902 pointer_buffer_mark_set = 1; 02903 } 02904 else if (*pPointer != RPC_FC_RP) 02905 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 02906 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer); 02907 if (pointer_buffer_mark_set) 02908 { 02909 STD_OVERFLOW_CHECK(pStubMsg); 02910 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 02911 pStubMsg->Buffer = saved_buffer; 02912 if (*pPointer != RPC_FC_RP) 02913 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 02914 } 02915 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer); 02916 if (*pFormat == RPC_FC_POINTER) 02917 pPointer += 4; 02918 else 02919 pFormat += 4; 02920 pMemory += sizeof(void *); 02921 break; 02922 } 02923 case RPC_FC_ALIGNM2: 02924 align_pointer(&pMemory, 2); 02925 break; 02926 case RPC_FC_ALIGNM4: 02927 align_pointer(&pMemory, 4); 02928 break; 02929 case RPC_FC_ALIGNM8: 02930 align_pointer(&pMemory, 8); 02931 break; 02932 case RPC_FC_STRUCTPAD1: 02933 case RPC_FC_STRUCTPAD2: 02934 case RPC_FC_STRUCTPAD3: 02935 case RPC_FC_STRUCTPAD4: 02936 case RPC_FC_STRUCTPAD5: 02937 case RPC_FC_STRUCTPAD6: 02938 case RPC_FC_STRUCTPAD7: 02939 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 02940 break; 02941 case RPC_FC_EMBEDDED_COMPLEX: 02942 pMemory += pFormat[1]; 02943 pFormat += 2; 02944 desc = pFormat + *(const SHORT*)pFormat; 02945 size = EmbeddedComplexSize(pStubMsg, desc); 02946 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory); 02947 m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 02948 if (m) 02949 { 02950 /* for some reason interface pointers aren't generated as 02951 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 02952 * they still need the derefencing treatment that pointers are 02953 * given */ 02954 if (*desc == RPC_FC_IP) 02955 m(pStubMsg, *(unsigned char **)pMemory, desc); 02956 else 02957 m(pStubMsg, pMemory, desc); 02958 } 02959 else FIXME("no marshaller for embedded type %02x\n", *desc); 02960 pMemory += size; 02961 pFormat += 2; 02962 continue; 02963 case RPC_FC_PAD: 02964 break; 02965 default: 02966 FIXME("unhandled format 0x%02x\n", *pFormat); 02967 } 02968 pFormat++; 02969 } 02970 02971 return pMemory; 02972 } 02973 02974 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 02975 unsigned char *pMemory, 02976 PFORMAT_STRING pFormat, 02977 PFORMAT_STRING pPointer, 02978 unsigned char fMustAlloc) 02979 { 02980 PFORMAT_STRING desc; 02981 NDR_UNMARSHALL m; 02982 ULONG size; 02983 02984 while (*pFormat != RPC_FC_END) { 02985 switch (*pFormat) { 02986 case RPC_FC_BYTE: 02987 case RPC_FC_CHAR: 02988 case RPC_FC_SMALL: 02989 case RPC_FC_USMALL: 02990 safe_copy_from_buffer(pStubMsg, pMemory, 1); 02991 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); 02992 pMemory += 1; 02993 break; 02994 case RPC_FC_WCHAR: 02995 case RPC_FC_SHORT: 02996 case RPC_FC_USHORT: 02997 safe_copy_from_buffer(pStubMsg, pMemory, 2); 02998 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); 02999 pMemory += 2; 03000 break; 03001 case RPC_FC_ENUM16: 03002 { 03003 WORD val; 03004 safe_copy_from_buffer(pStubMsg, &val, 2); 03005 *(DWORD*)pMemory = val; 03006 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory); 03007 if (32767 < *(DWORD*)pMemory) 03008 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 03009 pMemory += 4; 03010 break; 03011 } 03012 case RPC_FC_LONG: 03013 case RPC_FC_ULONG: 03014 case RPC_FC_ENUM32: 03015 safe_copy_from_buffer(pStubMsg, pMemory, 4); 03016 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); 03017 pMemory += 4; 03018 break; 03019 case RPC_FC_INT3264: 03020 { 03021 INT val; 03022 safe_copy_from_buffer(pStubMsg, &val, 4); 03023 *(INT_PTR *)pMemory = val; 03024 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory); 03025 pMemory += sizeof(INT_PTR); 03026 break; 03027 } 03028 case RPC_FC_UINT3264: 03029 { 03030 UINT val; 03031 safe_copy_from_buffer(pStubMsg, &val, 4); 03032 *(UINT_PTR *)pMemory = val; 03033 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory); 03034 pMemory += sizeof(UINT_PTR); 03035 break; 03036 } 03037 case RPC_FC_FLOAT: 03038 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float)); 03039 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory); 03040 pMemory += sizeof(float); 03041 break; 03042 case RPC_FC_HYPER: 03043 safe_copy_from_buffer(pStubMsg, pMemory, 8); 03044 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); 03045 pMemory += 8; 03046 break; 03047 case RPC_FC_DOUBLE: 03048 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double)); 03049 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory); 03050 pMemory += sizeof(double); 03051 break; 03052 case RPC_FC_RP: 03053 case RPC_FC_UP: 03054 case RPC_FC_OP: 03055 case RPC_FC_FP: 03056 case RPC_FC_POINTER: 03057 { 03058 unsigned char *saved_buffer; 03059 int pointer_buffer_mark_set = 0; 03060 TRACE("pointer => %p\n", pMemory); 03061 if (*pFormat != RPC_FC_POINTER) 03062 pPointer = pFormat; 03063 if (*pPointer != RPC_FC_RP) 03064 align_pointer(&pStubMsg->Buffer, 4); 03065 saved_buffer = pStubMsg->Buffer; 03066 if (pStubMsg->PointerBufferMark) 03067 { 03068 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 03069 pStubMsg->PointerBufferMark = NULL; 03070 pointer_buffer_mark_set = 1; 03071 } 03072 else if (*pPointer != RPC_FC_RP) 03073 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 03074 03075 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc); 03076 if (pointer_buffer_mark_set) 03077 { 03078 STD_OVERFLOW_CHECK(pStubMsg); 03079 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 03080 pStubMsg->Buffer = saved_buffer; 03081 if (*pPointer != RPC_FC_RP) 03082 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 03083 } 03084 if (*pFormat == RPC_FC_POINTER) 03085 pPointer += 4; 03086 else 03087 pFormat += 4; 03088 pMemory += sizeof(void *); 03089 break; 03090 } 03091 case RPC_FC_ALIGNM2: 03092 align_pointer_clear(&pMemory, 2); 03093 break; 03094 case RPC_FC_ALIGNM4: 03095 align_pointer_clear(&pMemory, 4); 03096 break; 03097 case RPC_FC_ALIGNM8: 03098 align_pointer_clear(&pMemory, 8); 03099 break; 03100 case RPC_FC_STRUCTPAD1: 03101 case RPC_FC_STRUCTPAD2: 03102 case RPC_FC_STRUCTPAD3: 03103 case RPC_FC_STRUCTPAD4: 03104 case RPC_FC_STRUCTPAD5: 03105 case RPC_FC_STRUCTPAD6: 03106 case RPC_FC_STRUCTPAD7: 03107 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1); 03108 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 03109 break; 03110 case RPC_FC_EMBEDDED_COMPLEX: 03111 pMemory += pFormat[1]; 03112 pFormat += 2; 03113 desc = pFormat + *(const SHORT*)pFormat; 03114 size = EmbeddedComplexSize(pStubMsg, desc); 03115 TRACE("embedded complex (size=%d) => %p\n", size, pMemory); 03116 if (fMustAlloc) 03117 /* we can't pass fMustAlloc=TRUE into the marshaller for this type 03118 * since the type is part of the memory block that is encompassed by 03119 * the whole complex type. Memory is forced to allocate when pointers 03120 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 03121 * clearing the memory we pass in to the unmarshaller */ 03122 memset(pMemory, 0, size); 03123 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 03124 if (m) 03125 { 03126 /* for some reason interface pointers aren't generated as 03127 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 03128 * they still need the derefencing treatment that pointers are 03129 * given */ 03130 if (*desc == RPC_FC_IP) 03131 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE); 03132 else 03133 m(pStubMsg, &pMemory, desc, FALSE); 03134 } 03135 else FIXME("no unmarshaller for embedded type %02x\n", *desc); 03136 pMemory += size; 03137 pFormat += 2; 03138 continue; 03139 case RPC_FC_PAD: 03140 break; 03141 default: 03142 FIXME("unhandled format %d\n", *pFormat); 03143 } 03144 pFormat++; 03145 } 03146 03147 return pMemory; 03148 } 03149 03150 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 03151 unsigned char *pMemory, 03152 PFORMAT_STRING pFormat, 03153 PFORMAT_STRING pPointer) 03154 { 03155 PFORMAT_STRING desc; 03156 NDR_BUFFERSIZE m; 03157 ULONG size; 03158 03159 while (*pFormat != RPC_FC_END) { 03160 switch (*pFormat) { 03161 case RPC_FC_BYTE: 03162 case RPC_FC_CHAR: 03163 case RPC_FC_SMALL: 03164 case RPC_FC_USMALL: 03165 safe_buffer_length_increment(pStubMsg, 1); 03166 pMemory += 1; 03167 break; 03168 case RPC_FC_WCHAR: 03169 case RPC_FC_SHORT: 03170 case RPC_FC_USHORT: 03171 safe_buffer_length_increment(pStubMsg, 2); 03172 pMemory += 2; 03173 break; 03174 case RPC_FC_ENUM16: 03175 safe_buffer_length_increment(pStubMsg, 2); 03176 pMemory += 4; 03177 break; 03178 case RPC_FC_LONG: 03179 case RPC_FC_ULONG: 03180 case RPC_FC_ENUM32: 03181 case RPC_FC_FLOAT: 03182 safe_buffer_length_increment(pStubMsg, 4); 03183 pMemory += 4; 03184 break; 03185 case RPC_FC_INT3264: 03186 case RPC_FC_UINT3264: 03187 safe_buffer_length_increment(pStubMsg, 4); 03188 pMemory += sizeof(INT_PTR); 03189 break; 03190 case RPC_FC_HYPER: 03191 case RPC_FC_DOUBLE: 03192 safe_buffer_length_increment(pStubMsg, 8); 03193 pMemory += 8; 03194 break; 03195 case RPC_FC_RP: 03196 case RPC_FC_UP: 03197 case RPC_FC_OP: 03198 case RPC_FC_FP: 03199 case RPC_FC_POINTER: 03200 if (*pFormat != RPC_FC_POINTER) 03201 pPointer = pFormat; 03202 if (!pStubMsg->IgnoreEmbeddedPointers) 03203 { 03204 int saved_buffer_length = pStubMsg->BufferLength; 03205 pStubMsg->BufferLength = pStubMsg->PointerLength; 03206 pStubMsg->PointerLength = 0; 03207 if(!pStubMsg->BufferLength) 03208 ERR("BufferLength == 0??\n"); 03209 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer); 03210 pStubMsg->PointerLength = pStubMsg->BufferLength; 03211 pStubMsg->BufferLength = saved_buffer_length; 03212 } 03213 if (*pPointer != RPC_FC_RP) 03214 { 03215 align_length(&pStubMsg->BufferLength, 4); 03216 safe_buffer_length_increment(pStubMsg, 4); 03217 } 03218 if (*pFormat == RPC_FC_POINTER) 03219 pPointer += 4; 03220 else 03221 pFormat += 4; 03222 pMemory += sizeof(void*); 03223 break; 03224 case RPC_FC_ALIGNM2: 03225 align_pointer(&pMemory, 2); 03226 break; 03227 case RPC_FC_ALIGNM4: 03228 align_pointer(&pMemory, 4); 03229 break; 03230 case RPC_FC_ALIGNM8: 03231 align_pointer(&pMemory, 8); 03232 break; 03233 case RPC_FC_STRUCTPAD1: 03234 case RPC_FC_STRUCTPAD2: 03235 case RPC_FC_STRUCTPAD3: 03236 case RPC_FC_STRUCTPAD4: 03237 case RPC_FC_STRUCTPAD5: 03238 case RPC_FC_STRUCTPAD6: 03239 case RPC_FC_STRUCTPAD7: 03240 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 03241 break; 03242 case RPC_FC_EMBEDDED_COMPLEX: 03243 pMemory += pFormat[1]; 03244 pFormat += 2; 03245 desc = pFormat + *(const SHORT*)pFormat; 03246 size = EmbeddedComplexSize(pStubMsg, desc); 03247 m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 03248 if (m) 03249 { 03250 /* for some reason interface pointers aren't generated as 03251 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 03252 * they still need the derefencing treatment that pointers are 03253 * given */ 03254 if (*desc == RPC_FC_IP) 03255 m(pStubMsg, *(unsigned char **)pMemory, desc); 03256 else 03257 m(pStubMsg, pMemory, desc); 03258 } 03259 else FIXME("no buffersizer for embedded type %02x\n", *desc); 03260 pMemory += size; 03261 pFormat += 2; 03262 continue; 03263 case RPC_FC_PAD: 03264 break; 03265 default: 03266 FIXME("unhandled format 0x%02x\n", *pFormat); 03267 } 03268 pFormat++; 03269 } 03270 03271 return pMemory; 03272 } 03273 03274 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, 03275 unsigned char *pMemory, 03276 PFORMAT_STRING pFormat, 03277 PFORMAT_STRING pPointer) 03278 { 03279 PFORMAT_STRING desc; 03280 NDR_FREE m; 03281 ULONG size; 03282 03283 while (*pFormat != RPC_FC_END) { 03284 switch (*pFormat) { 03285 case RPC_FC_BYTE: 03286 case RPC_FC_CHAR: 03287 case RPC_FC_SMALL: 03288 case RPC_FC_USMALL: 03289 pMemory += 1; 03290 break; 03291 case RPC_FC_WCHAR: 03292 case RPC_FC_SHORT: 03293 case RPC_FC_USHORT: 03294 pMemory += 2; 03295 break; 03296 case RPC_FC_LONG: 03297 case RPC_FC_ULONG: 03298 case RPC_FC_ENUM16: 03299 case RPC_FC_ENUM32: 03300 case RPC_FC_FLOAT: 03301 pMemory += 4; 03302 break; 03303 case RPC_FC_INT3264: 03304 case RPC_FC_UINT3264: 03305 pMemory += sizeof(INT_PTR); 03306 break; 03307 case RPC_FC_HYPER: 03308 case RPC_FC_DOUBLE: 03309 pMemory += 8; 03310 break; 03311 case RPC_FC_RP: 03312 case RPC_FC_UP: 03313 case RPC_FC_OP: 03314 case RPC_FC_FP: 03315 case RPC_FC_POINTER: 03316 if (*pFormat != RPC_FC_POINTER) 03317 pPointer = pFormat; 03318 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer); 03319 if (*pFormat == RPC_FC_POINTER) 03320 pPointer += 4; 03321 else 03322 pFormat += 4; 03323 pMemory += sizeof(void *); 03324 break; 03325 case RPC_FC_ALIGNM2: 03326 align_pointer(&pMemory, 2); 03327 break; 03328 case RPC_FC_ALIGNM4: 03329 align_pointer(&pMemory, 4); 03330 break; 03331 case RPC_FC_ALIGNM8: 03332 align_pointer(&pMemory, 8); 03333 break; 03334 case RPC_FC_STRUCTPAD1: 03335 case RPC_FC_STRUCTPAD2: 03336 case RPC_FC_STRUCTPAD3: 03337 case RPC_FC_STRUCTPAD4: 03338 case RPC_FC_STRUCTPAD5: 03339 case RPC_FC_STRUCTPAD6: 03340 case RPC_FC_STRUCTPAD7: 03341 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; 03342 break; 03343 case RPC_FC_EMBEDDED_COMPLEX: 03344 pMemory += pFormat[1]; 03345 pFormat += 2; 03346 desc = pFormat + *(const SHORT*)pFormat; 03347 size = EmbeddedComplexSize(pStubMsg, desc); 03348 m = NdrFreer[*desc & NDR_TABLE_MASK]; 03349 if (m) 03350 { 03351 /* for some reason interface pointers aren't generated as 03352 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet 03353 * they still need the derefencing treatment that pointers are 03354 * given */ 03355 if (*desc == RPC_FC_IP) 03356 m(pStubMsg, *(unsigned char **)pMemory, desc); 03357 else 03358 m(pStubMsg, pMemory, desc); 03359 } 03360 pMemory += size; 03361 pFormat += 2; 03362 continue; 03363 case RPC_FC_PAD: 03364 break; 03365 default: 03366 FIXME("unhandled format 0x%02x\n", *pFormat); 03367 } 03368 pFormat++; 03369 } 03370 03371 return pMemory; 03372 } 03373 03374 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 03375 PFORMAT_STRING pFormat, 03376 PFORMAT_STRING pPointer) 03377 { 03378 PFORMAT_STRING desc; 03379 ULONG size = 0; 03380 03381 while (*pFormat != RPC_FC_END) { 03382 switch (*pFormat) { 03383 case RPC_FC_BYTE: 03384 case RPC_FC_CHAR: 03385 case RPC_FC_SMALL: 03386 case RPC_FC_USMALL: 03387 size += 1; 03388 safe_buffer_increment(pStubMsg, 1); 03389 break; 03390 case RPC_FC_WCHAR: 03391 case RPC_FC_SHORT: 03392 case RPC_FC_USHORT: 03393 size += 2; 03394 safe_buffer_increment(pStubMsg, 2); 03395 break; 03396 case RPC_FC_ENUM16: 03397 size += 4; 03398 safe_buffer_increment(pStubMsg, 2); 03399 break; 03400 case RPC_FC_LONG: 03401 case RPC_FC_ULONG: 03402 case RPC_FC_ENUM32: 03403 case RPC_FC_FLOAT: 03404 size += 4; 03405 safe_buffer_increment(pStubMsg, 4); 03406 break; 03407 case RPC_FC_INT3264: 03408 case RPC_FC_UINT3264: 03409 size += sizeof(INT_PTR); 03410 safe_buffer_increment(pStubMsg, 4); 03411 break; 03412 case RPC_FC_HYPER: 03413 case RPC_FC_DOUBLE: 03414 size += 8; 03415 safe_buffer_increment(pStubMsg, 8); 03416 break; 03417 case RPC_FC_RP: 03418 case RPC_FC_UP: 03419 case RPC_FC_OP: 03420 case RPC_FC_FP: 03421 case RPC_FC_POINTER: 03422 { 03423 unsigned char *saved_buffer; 03424 int pointer_buffer_mark_set = 0; 03425 if (*pFormat != RPC_FC_POINTER) 03426 pPointer = pFormat; 03427 if (*pPointer != RPC_FC_RP) 03428 align_pointer(&pStubMsg->Buffer, 4); 03429 saved_buffer = pStubMsg->Buffer; 03430 if (pStubMsg->PointerBufferMark) 03431 { 03432 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 03433 pStubMsg->PointerBufferMark = NULL; 03434 pointer_buffer_mark_set = 1; 03435 } 03436 else if (*pPointer != RPC_FC_RP) 03437 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 03438 03439 if (!pStubMsg->IgnoreEmbeddedPointers) 03440 PointerMemorySize(pStubMsg, saved_buffer, pPointer); 03441 if (pointer_buffer_mark_set) 03442 { 03443 STD_OVERFLOW_CHECK(pStubMsg); 03444 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 03445 pStubMsg->Buffer = saved_buffer; 03446 if (*pPointer != RPC_FC_RP) 03447 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 03448 } 03449 if (*pFormat == RPC_FC_POINTER) 03450 pPointer += 4; 03451 else 03452 pFormat += 4; 03453 size += sizeof(void *); 03454 break; 03455 } 03456 case RPC_FC_ALIGNM2: 03457 align_length(&size, 2); 03458 break; 03459 case RPC_FC_ALIGNM4: 03460 align_length(&size, 4); 03461 break; 03462 case RPC_FC_ALIGNM8: 03463 align_length(&size, 8); 03464 break; 03465 case RPC_FC_STRUCTPAD1: 03466 case RPC_FC_STRUCTPAD2: 03467 case RPC_FC_STRUCTPAD3: 03468 case RPC_FC_STRUCTPAD4: 03469 case RPC_FC_STRUCTPAD5: 03470 case RPC_FC_STRUCTPAD6: 03471 case RPC_FC_STRUCTPAD7: 03472 size += *pFormat - RPC_FC_STRUCTPAD1 + 1; 03473 break; 03474 case RPC_FC_EMBEDDED_COMPLEX: 03475 size += pFormat[1]; 03476 pFormat += 2; 03477 desc = pFormat + *(const SHORT*)pFormat; 03478 size += EmbeddedComplexMemorySize(pStubMsg, desc); 03479 pFormat += 2; 03480 continue; 03481 case RPC_FC_PAD: 03482 break; 03483 default: 03484 FIXME("unhandled format 0x%02x\n", *pFormat); 03485 } 03486 pFormat++; 03487 } 03488 03489 return size; 03490 } 03491 03492 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) 03493 { 03494 PFORMAT_STRING desc; 03495 ULONG size = 0; 03496 03497 while (*pFormat != RPC_FC_END) { 03498 switch (*pFormat) { 03499 case RPC_FC_BYTE: 03500 case RPC_FC_CHAR: 03501 case RPC_FC_SMALL: 03502 case RPC_FC_USMALL: 03503 size += 1; 03504 break; 03505 case RPC_FC_WCHAR: 03506 case RPC_FC_SHORT: 03507 case RPC_FC_USHORT: 03508 size += 2; 03509 break; 03510 case RPC_FC_LONG: 03511 case RPC_FC_ULONG: 03512 case RPC_FC_ENUM16: 03513 case RPC_FC_ENUM32: 03514 case RPC_FC_FLOAT: 03515 size += 4; 03516 break; 03517 case RPC_FC_INT3264: 03518 case RPC_FC_UINT3264: 03519 size += sizeof(INT_PTR); 03520 break; 03521 case RPC_FC_HYPER: 03522 case RPC_FC_DOUBLE: 03523 size += 8; 03524 break; 03525 case RPC_FC_RP: 03526 case RPC_FC_UP: 03527 case RPC_FC_OP: 03528 case RPC_FC_FP: 03529 case RPC_FC_POINTER: 03530 size += sizeof(void *); 03531 if (*pFormat != RPC_FC_POINTER) 03532 pFormat += 4; 03533 break; 03534 case RPC_FC_ALIGNM2: 03535 align_length(&size, 2); 03536 break; 03537 case RPC_FC_ALIGNM4: 03538 align_length(&size, 4); 03539 break; 03540 case RPC_FC_ALIGNM8: 03541 align_length(&size, 8); 03542 break; 03543 case RPC_FC_STRUCTPAD1: 03544 case RPC_FC_STRUCTPAD2: 03545 case RPC_FC_STRUCTPAD3: 03546 case RPC_FC_STRUCTPAD4: 03547 case RPC_FC_STRUCTPAD5: 03548 case RPC_FC_STRUCTPAD6: 03549 case RPC_FC_STRUCTPAD7: 03550 size += *pFormat - RPC_FC_STRUCTPAD1 + 1; 03551 break; 03552 case RPC_FC_EMBEDDED_COMPLEX: 03553 size += pFormat[1]; 03554 pFormat += 2; 03555 desc = pFormat + *(const SHORT*)pFormat; 03556 size += EmbeddedComplexSize(pStubMsg, desc); 03557 pFormat += 2; 03558 continue; 03559 case RPC_FC_PAD: 03560 break; 03561 default: 03562 FIXME("unhandled format 0x%02x\n", *pFormat); 03563 } 03564 pFormat++; 03565 } 03566 03567 return size; 03568 } 03569 03570 /*********************************************************************** 03571 * NdrComplexStructMarshall [RPCRT4.@] 03572 */ 03573 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 03574 unsigned char *pMemory, 03575 PFORMAT_STRING pFormat) 03576 { 03577 PFORMAT_STRING conf_array = NULL; 03578 PFORMAT_STRING pointer_desc = NULL; 03579 unsigned char *OldMemory = pStubMsg->Memory; 03580 int pointer_buffer_mark_set = 0; 03581 ULONG count = 0; 03582 ULONG max_count = 0; 03583 ULONG offset = 0; 03584 03585 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03586 03587 if (!pStubMsg->PointerBufferMark) 03588 { 03589 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 03590 /* save buffer length */ 03591 ULONG saved_buffer_length = pStubMsg->BufferLength; 03592 03593 /* get the buffer pointer after complex array data, but before 03594 * pointer data */ 03595 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; 03596 pStubMsg->IgnoreEmbeddedPointers = 1; 03597 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); 03598 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 03599 03600 /* save it for use by embedded pointer code later */ 03601 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; 03602 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer)); 03603 pointer_buffer_mark_set = 1; 03604 03605 /* restore the original buffer length */ 03606 pStubMsg->BufferLength = saved_buffer_length; 03607 } 03608 03609 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1); 03610 03611 pFormat += 4; 03612 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 03613 pFormat += 2; 03614 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 03615 pFormat += 2; 03616 03617 pStubMsg->Memory = pMemory; 03618 03619 if (conf_array) 03620 { 03621 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat); 03622 array_compute_and_write_conformance(conf_array[0], pStubMsg, 03623 pMemory + struct_size, conf_array); 03624 /* these could be changed in ComplexMarshall so save them for later */ 03625 max_count = pStubMsg->MaxCount; 03626 count = pStubMsg->ActualCount; 03627 offset = pStubMsg->Offset; 03628 } 03629 03630 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc); 03631 03632 if (conf_array) 03633 { 03634 pStubMsg->MaxCount = max_count; 03635 pStubMsg->ActualCount = count; 03636 pStubMsg->Offset = offset; 03637 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory, 03638 conf_array, TRUE /* fHasPointers */); 03639 } 03640 03641 pStubMsg->Memory = OldMemory; 03642 03643 if (pointer_buffer_mark_set) 03644 { 03645 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 03646 pStubMsg->PointerBufferMark = NULL; 03647 } 03648 03649 STD_OVERFLOW_CHECK(pStubMsg); 03650 03651 return NULL; 03652 } 03653 03654 /*********************************************************************** 03655 * NdrComplexStructUnmarshall [RPCRT4.@] 03656 */ 03657 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 03658 unsigned char **ppMemory, 03659 PFORMAT_STRING pFormat, 03660 unsigned char fMustAlloc) 03661 { 03662 unsigned size = *(const WORD*)(pFormat+2); 03663 PFORMAT_STRING conf_array = NULL; 03664 PFORMAT_STRING pointer_desc = NULL; 03665 unsigned char *pMemory; 03666 int pointer_buffer_mark_set = 0; 03667 ULONG count = 0; 03668 ULONG max_count = 0; 03669 ULONG offset = 0; 03670 ULONG array_size = 0; 03671 03672 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 03673 03674 if (!pStubMsg->PointerBufferMark) 03675 { 03676 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 03677 /* save buffer pointer */ 03678 unsigned char *saved_buffer = pStubMsg->Buffer; 03679 03680 /* get the buffer pointer after complex array data, but before 03681 * pointer data */ 03682 pStubMsg->IgnoreEmbeddedPointers = 1; 03683 NdrComplexStructMemorySize(pStubMsg, pFormat); 03684 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 03685 03686 /* save it for use by embedded pointer code later */ 03687 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 03688 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer)); 03689 pointer_buffer_mark_set = 1; 03690 03691 /* restore the original buffer */ 03692 pStubMsg->Buffer = saved_buffer; 03693 } 03694 03695 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 03696 03697 pFormat += 4; 03698 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 03699 pFormat += 2; 03700 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 03701 pFormat += 2; 03702 03703 if (conf_array) 03704 { 03705 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array); 03706 size += array_size; 03707 03708 /* these could be changed in ComplexMarshall so save them for later */ 03709 max_count = pStubMsg->MaxCount; 03710 count = pStubMsg->ActualCount; 03711 offset = pStubMsg->Offset; 03712 } 03713 03714 if (!fMustAlloc && !*ppMemory) 03715 fMustAlloc = TRUE; 03716 if (fMustAlloc) 03717 *ppMemory = NdrAllocate(pStubMsg, size); 03718 03719 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc); 03720 03721 if (conf_array) 03722 { 03723 pStubMsg->MaxCount = max_count; 03724 pStubMsg->ActualCount = count; 03725 pStubMsg->Offset = offset; 03726 if (fMustAlloc) 03727 memset(pMemory, 0, array_size); 03728 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory, 03729 conf_array, FALSE, 03730 FALSE /* fUseBufferMemoryServer */, 03731 TRUE /* fUnmarshall */); 03732 } 03733 03734 if (pointer_buffer_mark_set) 03735 { 03736 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 03737 pStubMsg->PointerBufferMark = NULL; 03738 } 03739 03740 return NULL; 03741 } 03742 03743 /*********************************************************************** 03744 * NdrComplexStructBufferSize [RPCRT4.@] 03745 */ 03746 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 03747 unsigned char *pMemory, 03748 PFORMAT_STRING pFormat) 03749 { 03750 PFORMAT_STRING conf_array = NULL; 03751 PFORMAT_STRING pointer_desc = NULL; 03752 unsigned char *OldMemory = pStubMsg->Memory; 03753 int pointer_length_set = 0; 03754 ULONG count = 0; 03755 ULONG max_count = 0; 03756 ULONG offset = 0; 03757 03758 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03759 03760 align_length(&pStubMsg->BufferLength, pFormat[1] + 1); 03761 03762 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) 03763 { 03764 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 03765 ULONG saved_buffer_length = pStubMsg->BufferLength; 03766 03767 /* get the buffer length after complex struct data, but before 03768 * pointer data */ 03769 pStubMsg->IgnoreEmbeddedPointers = 1; 03770 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); 03771 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 03772 03773 /* save it for use by embedded pointer code later */ 03774 pStubMsg->PointerLength = pStubMsg->BufferLength; 03775 pointer_length_set = 1; 03776 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length); 03777 03778 /* restore the original buffer length */ 03779 pStubMsg->BufferLength = saved_buffer_length; 03780 } 03781 03782 pFormat += 4; 03783 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 03784 pFormat += 2; 03785 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 03786 pFormat += 2; 03787 03788 pStubMsg->Memory = pMemory; 03789 03790 if (conf_array) 03791 { 03792 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat); 03793 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size, 03794 conf_array); 03795 03796 /* these could be changed in ComplexMarshall so save them for later */ 03797 max_count = pStubMsg->MaxCount; 03798 count = pStubMsg->ActualCount; 03799 offset = pStubMsg->Offset; 03800 } 03801 03802 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc); 03803 03804 if (conf_array) 03805 { 03806 pStubMsg->MaxCount = max_count; 03807 pStubMsg->ActualCount = count; 03808 pStubMsg->Offset = offset; 03809 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array, 03810 TRUE /* fHasPointers */); 03811 } 03812 03813 pStubMsg->Memory = OldMemory; 03814 03815 if(pointer_length_set) 03816 { 03817 pStubMsg->BufferLength = pStubMsg->PointerLength; 03818 pStubMsg->PointerLength = 0; 03819 } 03820 03821 } 03822 03823 /*********************************************************************** 03824 * NdrComplexStructMemorySize [RPCRT4.@] 03825 */ 03826 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 03827 PFORMAT_STRING pFormat) 03828 { 03829 unsigned size = *(const WORD*)(pFormat+2); 03830 PFORMAT_STRING conf_array = NULL; 03831 PFORMAT_STRING pointer_desc = NULL; 03832 ULONG count = 0; 03833 ULONG max_count = 0; 03834 ULONG offset = 0; 03835 03836 TRACE("(%p,%p)\n", pStubMsg, pFormat); 03837 03838 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1); 03839 03840 pFormat += 4; 03841 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 03842 pFormat += 2; 03843 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 03844 pFormat += 2; 03845 03846 if (conf_array) 03847 { 03848 array_read_conformance(conf_array[0], pStubMsg, conf_array); 03849 03850 /* these could be changed in ComplexStructMemorySize so save them for 03851 * later */ 03852 max_count = pStubMsg->MaxCount; 03853 count = pStubMsg->ActualCount; 03854 offset = pStubMsg->Offset; 03855 } 03856 03857 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc); 03858 03859 if (conf_array) 03860 { 03861 pStubMsg->MaxCount = max_count; 03862 pStubMsg->ActualCount = count; 03863 pStubMsg->Offset = offset; 03864 array_memory_size(conf_array[0], pStubMsg, conf_array, 03865 TRUE /* fHasPointers */); 03866 } 03867 03868 return size; 03869 } 03870 03871 /*********************************************************************** 03872 * NdrComplexStructFree [RPCRT4.@] 03873 */ 03874 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, 03875 unsigned char *pMemory, 03876 PFORMAT_STRING pFormat) 03877 { 03878 PFORMAT_STRING conf_array = NULL; 03879 PFORMAT_STRING pointer_desc = NULL; 03880 unsigned char *OldMemory = pStubMsg->Memory; 03881 03882 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03883 03884 pFormat += 4; 03885 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; 03886 pFormat += 2; 03887 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; 03888 pFormat += 2; 03889 03890 pStubMsg->Memory = pMemory; 03891 03892 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc); 03893 03894 if (conf_array) 03895 array_free(conf_array[0], pStubMsg, pMemory, conf_array, 03896 TRUE /* fHasPointers */); 03897 03898 pStubMsg->Memory = OldMemory; 03899 } 03900 03901 /*********************************************************************** 03902 * NdrConformantArrayMarshall [RPCRT4.@] 03903 */ 03904 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 03905 unsigned char *pMemory, 03906 PFORMAT_STRING pFormat) 03907 { 03908 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03909 if (pFormat[0] != RPC_FC_CARRAY) 03910 { 03911 ERR("invalid format = 0x%x\n", pFormat[0]); 03912 RpcRaiseException(RPC_X_BAD_STUB_DATA); 03913 } 03914 03915 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, 03916 pFormat); 03917 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 03918 TRUE /* fHasPointers */); 03919 03920 return NULL; 03921 } 03922 03923 /*********************************************************************** 03924 * NdrConformantArrayUnmarshall [RPCRT4.@] 03925 */ 03926 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 03927 unsigned char **ppMemory, 03928 PFORMAT_STRING pFormat, 03929 unsigned char fMustAlloc) 03930 { 03931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 03932 if (pFormat[0] != RPC_FC_CARRAY) 03933 { 03934 ERR("invalid format = 0x%x\n", pFormat[0]); 03935 RpcRaiseException(RPC_X_BAD_STUB_DATA); 03936 } 03937 03938 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); 03939 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat, 03940 fMustAlloc, 03941 TRUE /* fUseBufferMemoryServer */, 03942 TRUE /* fUnmarshall */); 03943 03944 return NULL; 03945 } 03946 03947 /*********************************************************************** 03948 * NdrConformantArrayBufferSize [RPCRT4.@] 03949 */ 03950 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 03951 unsigned char *pMemory, 03952 PFORMAT_STRING pFormat) 03953 { 03954 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03955 if (pFormat[0] != RPC_FC_CARRAY) 03956 { 03957 ERR("invalid format = 0x%x\n", pFormat[0]); 03958 RpcRaiseException(RPC_X_BAD_STUB_DATA); 03959 } 03960 03961 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat); 03962 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 03963 TRUE /* fHasPointers */); 03964 } 03965 03966 /*********************************************************************** 03967 * NdrConformantArrayMemorySize [RPCRT4.@] 03968 */ 03969 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 03970 PFORMAT_STRING pFormat) 03971 { 03972 TRACE("(%p,%p)\n", pStubMsg, pFormat); 03973 if (pFormat[0] != RPC_FC_CARRAY) 03974 { 03975 ERR("invalid format = 0x%x\n", pFormat[0]); 03976 RpcRaiseException(RPC_X_BAD_STUB_DATA); 03977 } 03978 03979 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); 03980 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */); 03981 03982 return pStubMsg->MemorySize; 03983 } 03984 03985 /*********************************************************************** 03986 * NdrConformantArrayFree [RPCRT4.@] 03987 */ 03988 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 03989 unsigned char *pMemory, 03990 PFORMAT_STRING pFormat) 03991 { 03992 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 03993 if (pFormat[0] != RPC_FC_CARRAY) 03994 { 03995 ERR("invalid format = 0x%x\n", pFormat[0]); 03996 RpcRaiseException(RPC_X_BAD_STUB_DATA); 03997 } 03998 03999 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, 04000 TRUE /* fHasPointers */); 04001 } 04002 04003 04004 /*********************************************************************** 04005 * NdrConformantVaryingArrayMarshall [RPCRT4.@] 04006 */ 04007 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg, 04008 unsigned char* pMemory, 04009 PFORMAT_STRING pFormat ) 04010 { 04011 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04012 04013 if (pFormat[0] != RPC_FC_CVARRAY) 04014 { 04015 ERR("invalid format type %x\n", pFormat[0]); 04016 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04017 return NULL; 04018 } 04019 04020 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, 04021 pFormat); 04022 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory, 04023 pFormat, TRUE /* fHasPointers */); 04024 04025 return NULL; 04026 } 04027 04028 04029 /*********************************************************************** 04030 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@] 04031 */ 04032 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, 04033 unsigned char** ppMemory, 04034 PFORMAT_STRING pFormat, 04035 unsigned char fMustAlloc ) 04036 { 04037 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 04038 04039 if (pFormat[0] != RPC_FC_CVARRAY) 04040 { 04041 ERR("invalid format type %x\n", pFormat[0]); 04042 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04043 return NULL; 04044 } 04045 04046 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); 04047 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory, 04048 pFormat, fMustAlloc, 04049 TRUE /* fUseBufferMemoryServer */, 04050 TRUE /* fUnmarshall */); 04051 04052 return NULL; 04053 } 04054 04055 04056 /*********************************************************************** 04057 * NdrConformantVaryingArrayFree [RPCRT4.@] 04058 */ 04059 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, 04060 unsigned char* pMemory, 04061 PFORMAT_STRING pFormat ) 04062 { 04063 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04064 04065 if (pFormat[0] != RPC_FC_CVARRAY) 04066 { 04067 ERR("invalid format type %x\n", pFormat[0]); 04068 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04069 return; 04070 } 04071 04072 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, 04073 TRUE /* fHasPointers */); 04074 } 04075 04076 04077 /*********************************************************************** 04078 * NdrConformantVaryingArrayBufferSize [RPCRT4.@] 04079 */ 04080 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, 04081 unsigned char* pMemory, PFORMAT_STRING pFormat ) 04082 { 04083 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04084 04085 if (pFormat[0] != RPC_FC_CVARRAY) 04086 { 04087 ERR("invalid format type %x\n", pFormat[0]); 04088 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04089 return; 04090 } 04091 04092 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, 04093 pFormat); 04094 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, 04095 TRUE /* fHasPointers */); 04096 } 04097 04098 04099 /*********************************************************************** 04100 * NdrConformantVaryingArrayMemorySize [RPCRT4.@] 04101 */ 04102 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, 04103 PFORMAT_STRING pFormat ) 04104 { 04105 TRACE("(%p, %p)\n", pStubMsg, pFormat); 04106 04107 if (pFormat[0] != RPC_FC_CVARRAY) 04108 { 04109 ERR("invalid format type %x\n", pFormat[0]); 04110 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04111 return pStubMsg->MemorySize; 04112 } 04113 04114 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); 04115 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat, 04116 TRUE /* fHasPointers */); 04117 04118 return pStubMsg->MemorySize; 04119 } 04120 04121 04122 /*********************************************************************** 04123 * NdrComplexArrayMarshall [RPCRT4.@] 04124 */ 04125 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 04126 unsigned char *pMemory, 04127 PFORMAT_STRING pFormat) 04128 { 04129 int pointer_buffer_mark_set = 0; 04130 04131 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04132 04133 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 04134 { 04135 ERR("invalid format type %x\n", pFormat[0]); 04136 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04137 return NULL; 04138 } 04139 04140 if (!pStubMsg->PointerBufferMark) 04141 { 04142 /* save buffer fields that may be changed by buffer sizer functions 04143 * and that may be needed later on */ 04144 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 04145 ULONG saved_buffer_length = pStubMsg->BufferLength; 04146 ULONG_PTR saved_max_count = pStubMsg->MaxCount; 04147 ULONG saved_offset = pStubMsg->Offset; 04148 ULONG saved_actual_count = pStubMsg->ActualCount; 04149 04150 /* get the buffer pointer after complex array data, but before 04151 * pointer data */ 04152 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; 04153 pStubMsg->IgnoreEmbeddedPointers = 1; 04154 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); 04155 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 04156 04157 /* save it for use by embedded pointer code later */ 04158 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; 04159 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer)); 04160 pointer_buffer_mark_set = 1; 04161 04162 /* restore fields */ 04163 pStubMsg->ActualCount = saved_actual_count; 04164 pStubMsg->Offset = saved_offset; 04165 pStubMsg->MaxCount = saved_max_count; 04166 pStubMsg->BufferLength = saved_buffer_length; 04167 } 04168 04169 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat); 04170 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg, 04171 pMemory, pFormat, TRUE /* fHasPointers */); 04172 04173 STD_OVERFLOW_CHECK(pStubMsg); 04174 04175 if (pointer_buffer_mark_set) 04176 { 04177 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 04178 pStubMsg->PointerBufferMark = NULL; 04179 } 04180 04181 return NULL; 04182 } 04183 04184 /*********************************************************************** 04185 * NdrComplexArrayUnmarshall [RPCRT4.@] 04186 */ 04187 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 04188 unsigned char **ppMemory, 04189 PFORMAT_STRING pFormat, 04190 unsigned char fMustAlloc) 04191 { 04192 unsigned char *saved_buffer; 04193 int pointer_buffer_mark_set = 0; 04194 int saved_ignore_embedded; 04195 04196 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 04197 04198 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 04199 { 04200 ERR("invalid format type %x\n", pFormat[0]); 04201 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04202 return NULL; 04203 } 04204 04205 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 04206 /* save buffer pointer */ 04207 saved_buffer = pStubMsg->Buffer; 04208 /* get the buffer pointer after complex array data, but before 04209 * pointer data */ 04210 pStubMsg->IgnoreEmbeddedPointers = 1; 04211 pStubMsg->MemorySize = 0; 04212 NdrComplexArrayMemorySize(pStubMsg, pFormat); 04213 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 04214 04215 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer)); 04216 if (!pStubMsg->PointerBufferMark) 04217 { 04218 /* save it for use by embedded pointer code later */ 04219 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 04220 pointer_buffer_mark_set = 1; 04221 } 04222 /* restore the original buffer */ 04223 pStubMsg->Buffer = saved_buffer; 04224 04225 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat); 04226 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc, 04227 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */); 04228 04229 if (pointer_buffer_mark_set) 04230 { 04231 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 04232 pStubMsg->PointerBufferMark = NULL; 04233 } 04234 04235 return NULL; 04236 } 04237 04238 /*********************************************************************** 04239 * NdrComplexArrayBufferSize [RPCRT4.@] 04240 */ 04241 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 04242 unsigned char *pMemory, 04243 PFORMAT_STRING pFormat) 04244 { 04245 int pointer_length_set = 0; 04246 04247 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04248 04249 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 04250 { 04251 ERR("invalid format type %x\n", pFormat[0]); 04252 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04253 return; 04254 } 04255 04256 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) 04257 { 04258 /* save buffer fields that may be changed by buffer sizer functions 04259 * and that may be needed later on */ 04260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; 04261 ULONG saved_buffer_length = pStubMsg->BufferLength; 04262 ULONG_PTR saved_max_count = pStubMsg->MaxCount; 04263 ULONG saved_offset = pStubMsg->Offset; 04264 ULONG saved_actual_count = pStubMsg->ActualCount; 04265 04266 /* get the buffer pointer after complex array data, but before 04267 * pointer data */ 04268 pStubMsg->IgnoreEmbeddedPointers = 1; 04269 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); 04270 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; 04271 04272 /* save it for use by embedded pointer code later */ 04273 pStubMsg->PointerLength = pStubMsg->BufferLength; 04274 pointer_length_set = 1; 04275 04276 /* restore fields */ 04277 pStubMsg->ActualCount = saved_actual_count; 04278 pStubMsg->Offset = saved_offset; 04279 pStubMsg->MaxCount = saved_max_count; 04280 pStubMsg->BufferLength = saved_buffer_length; 04281 } 04282 04283 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat); 04284 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */); 04285 04286 if(pointer_length_set) 04287 { 04288 pStubMsg->BufferLength = pStubMsg->PointerLength; 04289 pStubMsg->PointerLength = 0; 04290 } 04291 } 04292 04293 /*********************************************************************** 04294 * NdrComplexArrayMemorySize [RPCRT4.@] 04295 */ 04296 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 04297 PFORMAT_STRING pFormat) 04298 { 04299 TRACE("(%p,%p)\n", pStubMsg, pFormat); 04300 04301 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 04302 { 04303 ERR("invalid format type %x\n", pFormat[0]); 04304 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04305 return 0; 04306 } 04307 04308 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat); 04309 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */); 04310 return pStubMsg->MemorySize; 04311 } 04312 04313 /*********************************************************************** 04314 * NdrComplexArrayFree [RPCRT4.@] 04315 */ 04316 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 04317 unsigned char *pMemory, 04318 PFORMAT_STRING pFormat) 04319 { 04320 ULONG i, count, def; 04321 04322 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04323 04324 if (pFormat[0] != RPC_FC_BOGUS_ARRAY) 04325 { 04326 ERR("invalid format type %x\n", pFormat[0]); 04327 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04328 return; 04329 } 04330 04331 def = *(const WORD*)&pFormat[2]; 04332 pFormat += 4; 04333 04334 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); 04335 TRACE("conformance = %ld\n", pStubMsg->MaxCount); 04336 04337 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); 04338 TRACE("variance = %d\n", pStubMsg->ActualCount); 04339 04340 count = pStubMsg->ActualCount; 04341 for (i = 0; i < count; i++) 04342 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); 04343 } 04344 04345 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg, 04346 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat, 04347 USER_MARSHAL_CB *umcb) 04348 { 04349 umcb->Flags = MAKELONG(pStubMsg->dwDestContext, 04350 pStubMsg->RpcMsg->DataRepresentation); 04351 umcb->pStubMsg = pStubMsg; 04352 umcb->pReserve = NULL; 04353 umcb->Signature = USER_MARSHAL_CB_SIGNATURE; 04354 umcb->CBType = cbtype; 04355 umcb->pFormat = pFormat; 04356 umcb->pTypeFormat = NULL /* FIXME */; 04357 } 04358 04359 #define USER_MARSHAL_PTR_PREFIX \ 04360 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \ 04361 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) ) 04362 04363 /*********************************************************************** 04364 * NdrUserMarshalMarshall [RPCRT4.@] 04365 */ 04366 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg, 04367 unsigned char *pMemory, 04368 PFORMAT_STRING pFormat) 04369 { 04370 unsigned flags = pFormat[1]; 04371 unsigned index = *(const WORD*)&pFormat[2]; 04372 unsigned char *saved_buffer = NULL; 04373 USER_MARSHAL_CB umcb; 04374 04375 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04376 TRACE("index=%d\n", index); 04377 04378 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb); 04379 04380 if (flags & USER_MARSHAL_POINTER) 04381 { 04382 align_pointer_clear(&pStubMsg->Buffer, 4); 04383 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX); 04384 pStubMsg->Buffer += 4; 04385 if (pStubMsg->PointerBufferMark) 04386 { 04387 saved_buffer = pStubMsg->Buffer; 04388 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 04389 pStubMsg->PointerBufferMark = NULL; 04390 } 04391 align_pointer_clear(&pStubMsg->Buffer, 8); 04392 } 04393 else 04394 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1); 04395 04396 pStubMsg->Buffer = 04397 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall( 04398 &umcb.Flags, pStubMsg->Buffer, pMemory); 04399 04400 if (saved_buffer) 04401 { 04402 STD_OVERFLOW_CHECK(pStubMsg); 04403 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 04404 pStubMsg->Buffer = saved_buffer; 04405 } 04406 04407 STD_OVERFLOW_CHECK(pStubMsg); 04408 04409 return NULL; 04410 } 04411 04412 /*********************************************************************** 04413 * NdrUserMarshalUnmarshall [RPCRT4.@] 04414 */ 04415 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 04416 unsigned char **ppMemory, 04417 PFORMAT_STRING pFormat, 04418 unsigned char fMustAlloc) 04419 { 04420 unsigned flags = pFormat[1]; 04421 unsigned index = *(const WORD*)&pFormat[2]; 04422 DWORD memsize = *(const WORD*)&pFormat[4]; 04423 unsigned char *saved_buffer = NULL; 04424 USER_MARSHAL_CB umcb; 04425 04426 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 04427 TRACE("index=%d\n", index); 04428 04429 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb); 04430 04431 if (flags & USER_MARSHAL_POINTER) 04432 { 04433 align_pointer(&pStubMsg->Buffer, 4); 04434 /* skip pointer prefix */ 04435 pStubMsg->Buffer += 4; 04436 if (pStubMsg->PointerBufferMark) 04437 { 04438 saved_buffer = pStubMsg->Buffer; 04439 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 04440 pStubMsg->PointerBufferMark = NULL; 04441 } 04442 align_pointer(&pStubMsg->Buffer, 8); 04443 } 04444 else 04445 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1); 04446 04447 if (!fMustAlloc && !*ppMemory) 04448 fMustAlloc = TRUE; 04449 if (fMustAlloc) 04450 { 04451 *ppMemory = NdrAllocate(pStubMsg, memsize); 04452 memset(*ppMemory, 0, memsize); 04453 } 04454 04455 pStubMsg->Buffer = 04456 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall( 04457 &umcb.Flags, pStubMsg->Buffer, *ppMemory); 04458 04459 if (saved_buffer) 04460 { 04461 STD_OVERFLOW_CHECK(pStubMsg); 04462 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 04463 pStubMsg->Buffer = saved_buffer; 04464 } 04465 04466 return NULL; 04467 } 04468 04469 /*********************************************************************** 04470 * NdrUserMarshalBufferSize [RPCRT4.@] 04471 */ 04472 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 04473 unsigned char *pMemory, 04474 PFORMAT_STRING pFormat) 04475 { 04476 unsigned flags = pFormat[1]; 04477 unsigned index = *(const WORD*)&pFormat[2]; 04478 DWORD bufsize = *(const WORD*)&pFormat[6]; 04479 USER_MARSHAL_CB umcb; 04480 ULONG saved_buffer_length = 0; 04481 04482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04483 TRACE("index=%d\n", index); 04484 04485 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb); 04486 04487 if (flags & USER_MARSHAL_POINTER) 04488 { 04489 align_length(&pStubMsg->BufferLength, 4); 04490 /* skip pointer prefix */ 04491 safe_buffer_length_increment(pStubMsg, 4); 04492 if (pStubMsg->IgnoreEmbeddedPointers) 04493 return; 04494 if (pStubMsg->PointerLength) 04495 { 04496 saved_buffer_length = pStubMsg->BufferLength; 04497 pStubMsg->BufferLength = pStubMsg->PointerLength; 04498 pStubMsg->PointerLength = 0; 04499 } 04500 align_length(&pStubMsg->BufferLength, 8); 04501 } 04502 else 04503 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1); 04504 04505 if (bufsize) { 04506 TRACE("size=%d\n", bufsize); 04507 safe_buffer_length_increment(pStubMsg, bufsize); 04508 } 04509 else 04510 pStubMsg->BufferLength = 04511 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize( 04512 &umcb.Flags, pStubMsg->BufferLength, pMemory); 04513 04514 if (saved_buffer_length) 04515 { 04516 pStubMsg->PointerLength = pStubMsg->BufferLength; 04517 pStubMsg->BufferLength = saved_buffer_length; 04518 } 04519 04520 } 04521 04522 /*********************************************************************** 04523 * NdrUserMarshalMemorySize [RPCRT4.@] 04524 */ 04525 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 04526 PFORMAT_STRING pFormat) 04527 { 04528 unsigned flags = pFormat[1]; 04529 unsigned index = *(const WORD*)&pFormat[2]; 04530 DWORD memsize = *(const WORD*)&pFormat[4]; 04531 DWORD bufsize = *(const WORD*)&pFormat[6]; 04532 04533 TRACE("(%p,%p)\n", pStubMsg, pFormat); 04534 TRACE("index=%d\n", index); 04535 04536 pStubMsg->MemorySize += memsize; 04537 04538 if (flags & USER_MARSHAL_POINTER) 04539 { 04540 align_pointer(&pStubMsg->Buffer, 4); 04541 /* skip pointer prefix */ 04542 pStubMsg->Buffer += 4; 04543 if (pStubMsg->IgnoreEmbeddedPointers) 04544 return pStubMsg->MemorySize; 04545 align_pointer(&pStubMsg->Buffer, 8); 04546 } 04547 else 04548 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1); 04549 04550 if (!bufsize) 04551 FIXME("not implemented for varying buffer size\n"); 04552 04553 pStubMsg->Buffer += bufsize; 04554 04555 return pStubMsg->MemorySize; 04556 } 04557 04558 /*********************************************************************** 04559 * NdrUserMarshalFree [RPCRT4.@] 04560 */ 04561 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg, 04562 unsigned char *pMemory, 04563 PFORMAT_STRING pFormat) 04564 { 04565 /* unsigned flags = pFormat[1]; */ 04566 unsigned index = *(const WORD*)&pFormat[2]; 04567 USER_MARSHAL_CB umcb; 04568 04569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); 04570 TRACE("index=%d\n", index); 04571 04572 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb); 04573 04574 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree( 04575 &umcb.Flags, pMemory); 04576 } 04577 04578 /*********************************************************************** 04579 * NdrGetUserMarshalInfo [RPCRT4.@] 04580 */ 04581 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi) 04582 { 04583 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags); 04584 04585 TRACE("(%p,%u,%p)\n", flags, level, umi); 04586 04587 if (level != 1) 04588 return RPC_S_INVALID_ARG; 04589 04590 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1)); 04591 umi->InformationLevel = level; 04592 04593 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE) 04594 return RPC_S_INVALID_ARG; 04595 04596 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate; 04597 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree; 04598 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer; 04599 04600 switch (umcb->CBType) 04601 { 04602 case USER_MARSHAL_CB_MARSHALL: 04603 case USER_MARSHAL_CB_UNMARSHALL: 04604 { 04605 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg; 04606 unsigned char *buffer_start = msg->Buffer; 04607 unsigned char *buffer_end = 04608 (unsigned char *)msg->Buffer + msg->BufferLength; 04609 04610 if (umcb->pStubMsg->Buffer < buffer_start || 04611 umcb->pStubMsg->Buffer > buffer_end) 04612 return ERROR_INVALID_USER_BUFFER; 04613 04614 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer; 04615 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer; 04616 break; 04617 } 04618 case USER_MARSHAL_CB_BUFFER_SIZE: 04619 case USER_MARSHAL_CB_FREE: 04620 break; 04621 default: 04622 WARN("unrecognised CBType %d\n", umcb->CBType); 04623 } 04624 04625 return RPC_S_OK; 04626 } 04627 04628 /*********************************************************************** 04629 * NdrClearOutParameters [RPCRT4.@] 04630 */ 04631 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg, 04632 PFORMAT_STRING pFormat, 04633 void *ArgAddr) 04634 { 04635 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr); 04636 } 04637 04638 /*********************************************************************** 04639 * NdrConvert [RPCRT4.@] 04640 */ 04641 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) 04642 { 04643 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat); 04644 /* FIXME: since this stub doesn't do any converting, the proper behavior 04645 is to raise an exception */ 04646 } 04647 04648 /*********************************************************************** 04649 * NdrConvert2 [RPCRT4.@] 04650 */ 04651 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams ) 04652 { 04653 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n", 04654 pStubMsg, pFormat, NumberParams); 04655 /* FIXME: since this stub doesn't do any converting, the proper behavior 04656 is to raise an exception */ 04657 } 04658 04659 #include "pshpack1.h" 04660 typedef struct _NDR_CSTRUCT_FORMAT 04661 { 04662 unsigned char type; 04663 unsigned char alignment; 04664 unsigned short memory_size; 04665 short offset_to_array_description; 04666 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT; 04667 #include "poppack.h" 04668 04669 /*********************************************************************** 04670 * NdrConformantStructMarshall [RPCRT4.@] 04671 */ 04672 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 04673 unsigned char *pMemory, 04674 PFORMAT_STRING pFormat) 04675 { 04676 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 04677 PFORMAT_STRING pCArrayFormat; 04678 ULONG esize, bufsize; 04679 04680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04681 04682 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 04683 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 04684 { 04685 ERR("invalid format type %x\n", pCStructFormat->type); 04686 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04687 return NULL; 04688 } 04689 04690 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 04691 pCStructFormat->offset_to_array_description; 04692 if (*pCArrayFormat != RPC_FC_CARRAY) 04693 { 04694 ERR("invalid array format type %x\n", pCStructFormat->type); 04695 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04696 return NULL; 04697 } 04698 esize = *(const WORD*)(pCArrayFormat+2); 04699 04700 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, 04701 pCArrayFormat + 4, 0); 04702 04703 WriteConformance(pStubMsg); 04704 04705 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1); 04706 04707 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 04708 04709 bufsize = safe_multiply(esize, pStubMsg->MaxCount); 04710 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ 04711 { 04712 ERR("integer overflow of memory_size %u with bufsize %u\n", 04713 pCStructFormat->memory_size, bufsize); 04714 RpcRaiseException(RPC_X_BAD_STUB_DATA); 04715 } 04716 /* copy constant sized part of struct */ 04717 pStubMsg->BufferMark = pStubMsg->Buffer; 04718 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize); 04719 04720 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 04721 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 04722 04723 return NULL; 04724 } 04725 04726 /*********************************************************************** 04727 * NdrConformantStructUnmarshall [RPCRT4.@] 04728 */ 04729 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 04730 unsigned char **ppMemory, 04731 PFORMAT_STRING pFormat, 04732 unsigned char fMustAlloc) 04733 { 04734 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 04735 PFORMAT_STRING pCArrayFormat; 04736 ULONG esize, bufsize; 04737 unsigned char *saved_buffer; 04738 04739 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 04740 04741 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 04742 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 04743 { 04744 ERR("invalid format type %x\n", pCStructFormat->type); 04745 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04746 return NULL; 04747 } 04748 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 04749 pCStructFormat->offset_to_array_description; 04750 if (*pCArrayFormat != RPC_FC_CARRAY) 04751 { 04752 ERR("invalid array format type %x\n", pCStructFormat->type); 04753 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04754 return NULL; 04755 } 04756 esize = *(const WORD*)(pCArrayFormat+2); 04757 04758 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4); 04759 04760 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1); 04761 04762 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 04763 04764 bufsize = safe_multiply(esize, pStubMsg->MaxCount); 04765 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ 04766 { 04767 ERR("integer overflow of memory_size %u with bufsize %u\n", 04768 pCStructFormat->memory_size, bufsize); 04769 RpcRaiseException(RPC_X_BAD_STUB_DATA); 04770 } 04771 04772 if (fMustAlloc) 04773 { 04774 SIZE_T size = pCStructFormat->memory_size + bufsize; 04775 *ppMemory = NdrAllocate(pStubMsg, size); 04776 } 04777 else 04778 { 04779 if (!pStubMsg->IsClient && !*ppMemory) 04780 /* for servers, we just point straight into the RPC buffer */ 04781 *ppMemory = pStubMsg->Buffer; 04782 } 04783 04784 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 04785 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize); 04786 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 04787 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 04788 04789 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 04790 if (*ppMemory != saved_buffer) 04791 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize); 04792 04793 return NULL; 04794 } 04795 04796 /*********************************************************************** 04797 * NdrConformantStructBufferSize [RPCRT4.@] 04798 */ 04799 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 04800 unsigned char *pMemory, 04801 PFORMAT_STRING pFormat) 04802 { 04803 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 04804 PFORMAT_STRING pCArrayFormat; 04805 ULONG esize; 04806 04807 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04808 04809 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 04810 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 04811 { 04812 ERR("invalid format type %x\n", pCStructFormat->type); 04813 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04814 return; 04815 } 04816 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 04817 pCStructFormat->offset_to_array_description; 04818 if (*pCArrayFormat != RPC_FC_CARRAY) 04819 { 04820 ERR("invalid array format type %x\n", pCStructFormat->type); 04821 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04822 return; 04823 } 04824 esize = *(const WORD*)(pCArrayFormat+2); 04825 04826 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0); 04827 SizeConformance(pStubMsg); 04828 04829 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1); 04830 04831 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 04832 04833 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size); 04834 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); 04835 04836 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 04837 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 04838 } 04839 04840 /*********************************************************************** 04841 * NdrConformantStructMemorySize [RPCRT4.@] 04842 */ 04843 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 04844 PFORMAT_STRING pFormat) 04845 { 04846 FIXME("stub\n"); 04847 return 0; 04848 } 04849 04850 /*********************************************************************** 04851 * NdrConformantStructFree [RPCRT4.@] 04852 */ 04853 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, 04854 unsigned char *pMemory, 04855 PFORMAT_STRING pFormat) 04856 { 04857 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; 04858 PFORMAT_STRING pCArrayFormat; 04859 04860 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04861 04862 pFormat += sizeof(NDR_CSTRUCT_FORMAT); 04863 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) 04864 { 04865 ERR("invalid format type %x\n", pCStructFormat->type); 04866 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04867 return; 04868 } 04869 04870 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + 04871 pCStructFormat->offset_to_array_description; 04872 if (*pCArrayFormat != RPC_FC_CARRAY) 04873 { 04874 ERR("invalid array format type %x\n", pCStructFormat->type); 04875 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04876 return; 04877 } 04878 04879 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, 04880 pCArrayFormat + 4, 0); 04881 04882 TRACE("memory_size = %d\n", pCStructFormat->memory_size); 04883 04884 /* copy constant sized part of struct */ 04885 pStubMsg->BufferMark = pStubMsg->Buffer; 04886 04887 if (pCStructFormat->type == RPC_FC_CPSTRUCT) 04888 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 04889 } 04890 04891 /*********************************************************************** 04892 * NdrConformantVaryingStructMarshall [RPCRT4.@] 04893 */ 04894 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, 04895 unsigned char *pMemory, 04896 PFORMAT_STRING pFormat) 04897 { 04898 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 04899 PFORMAT_STRING pCVArrayFormat; 04900 04901 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 04902 04903 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 04904 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 04905 { 04906 ERR("invalid format type %x\n", pCVStructFormat->type); 04907 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04908 return NULL; 04909 } 04910 04911 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 04912 pCVStructFormat->offset_to_array_description; 04913 04914 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg, 04915 pMemory + pCVStructFormat->memory_size, 04916 pCVArrayFormat); 04917 04918 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 04919 04920 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 04921 04922 /* write constant sized part */ 04923 pStubMsg->BufferMark = pStubMsg->Buffer; 04924 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size); 04925 04926 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg, 04927 pMemory + pCVStructFormat->memory_size, 04928 pCVArrayFormat, FALSE /* fHasPointers */); 04929 04930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 04931 04932 return NULL; 04933 } 04934 04935 /*********************************************************************** 04936 * NdrConformantVaryingStructUnmarshall [RPCRT4.@] 04937 */ 04938 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 04939 unsigned char **ppMemory, 04940 PFORMAT_STRING pFormat, 04941 unsigned char fMustAlloc) 04942 { 04943 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 04944 PFORMAT_STRING pCVArrayFormat; 04945 ULONG memsize, bufsize; 04946 unsigned char *saved_buffer, *saved_array_buffer; 04947 ULONG offset; 04948 unsigned char *array_memory; 04949 04950 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 04951 04952 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 04953 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 04954 { 04955 ERR("invalid format type %x\n", pCVStructFormat->type); 04956 RpcRaiseException(RPC_S_INTERNAL_ERROR); 04957 return NULL; 04958 } 04959 04960 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 04961 pCVStructFormat->offset_to_array_description; 04962 04963 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg, 04964 pCVArrayFormat); 04965 04966 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 04967 04968 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 04969 04970 /* work out how much memory to allocate if we need to do so */ 04971 if (!fMustAlloc && !*ppMemory) 04972 fMustAlloc = TRUE; 04973 if (fMustAlloc) 04974 { 04975 SIZE_T size = pCVStructFormat->memory_size + memsize; 04976 *ppMemory = NdrAllocate(pStubMsg, size); 04977 } 04978 04979 /* mark the start of the constant data */ 04980 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 04981 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); 04982 04983 array_memory = *ppMemory + pCVStructFormat->memory_size; 04984 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg, 04985 &array_memory, pCVArrayFormat, 04986 FALSE /* fMustAlloc */, 04987 FALSE /* fUseServerBufferMemory */, 04988 FALSE /* fUnmarshall */); 04989 04990 /* save offset in case unmarshalling pointers changes it */ 04991 offset = pStubMsg->Offset; 04992 04993 /* mark the start of the array data */ 04994 saved_array_buffer = pStubMsg->Buffer; 04995 safe_buffer_increment(pStubMsg, bufsize); 04996 04997 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 04998 04999 /* copy the constant data */ 05000 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size); 05001 /* copy the array data */ 05002 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size); 05003 memcpy(*ppMemory + pCVStructFormat->memory_size + offset, 05004 saved_array_buffer, bufsize); 05005 05006 if (*pCVArrayFormat == RPC_FC_C_CSTRING) 05007 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); 05008 else if (*pCVArrayFormat == RPC_FC_C_WSTRING) 05009 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size))); 05010 05011 return NULL; 05012 } 05013 05014 /*********************************************************************** 05015 * NdrConformantVaryingStructBufferSize [RPCRT4.@] 05016 */ 05017 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 05018 unsigned char *pMemory, 05019 PFORMAT_STRING pFormat) 05020 { 05021 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 05022 PFORMAT_STRING pCVArrayFormat; 05023 05024 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05025 05026 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 05027 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 05028 { 05029 ERR("invalid format type %x\n", pCVStructFormat->type); 05030 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05031 return; 05032 } 05033 05034 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 05035 pCVStructFormat->offset_to_array_description; 05036 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg, 05037 pMemory + pCVStructFormat->memory_size, 05038 pCVArrayFormat); 05039 05040 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1); 05041 05042 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 05043 05044 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size); 05045 05046 array_buffer_size(*pCVArrayFormat, pStubMsg, 05047 pMemory + pCVStructFormat->memory_size, pCVArrayFormat, 05048 FALSE /* fHasPointers */); 05049 05050 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 05051 } 05052 05053 /*********************************************************************** 05054 * NdrConformantVaryingStructMemorySize [RPCRT4.@] 05055 */ 05056 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 05057 PFORMAT_STRING pFormat) 05058 { 05059 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 05060 PFORMAT_STRING pCVArrayFormat; 05061 05062 TRACE("(%p, %p)\n", pStubMsg, pFormat); 05063 05064 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 05065 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 05066 { 05067 ERR("invalid format type %x\n", pCVStructFormat->type); 05068 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05069 return 0; 05070 } 05071 05072 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 05073 pCVStructFormat->offset_to_array_description; 05074 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat); 05075 05076 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1); 05077 05078 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 05079 05080 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); 05081 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat, 05082 FALSE /* fHasPointers */); 05083 05084 pStubMsg->MemorySize += pCVStructFormat->memory_size; 05085 05086 EmbeddedPointerMemorySize(pStubMsg, pFormat); 05087 05088 return pStubMsg->MemorySize; 05089 } 05090 05091 /*********************************************************************** 05092 * NdrConformantVaryingStructFree [RPCRT4.@] 05093 */ 05094 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, 05095 unsigned char *pMemory, 05096 PFORMAT_STRING pFormat) 05097 { 05098 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; 05099 PFORMAT_STRING pCVArrayFormat; 05100 05101 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05102 05103 pFormat += sizeof(NDR_CVSTRUCT_FORMAT); 05104 if (pCVStructFormat->type != RPC_FC_CVSTRUCT) 05105 { 05106 ERR("invalid format type %x\n", pCVStructFormat->type); 05107 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05108 return; 05109 } 05110 05111 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + 05112 pCVStructFormat->offset_to_array_description; 05113 array_free(*pCVArrayFormat, pStubMsg, 05114 pMemory + pCVStructFormat->memory_size, pCVArrayFormat, 05115 FALSE /* fHasPointers */); 05116 05117 TRACE("memory_size = %d\n", pCVStructFormat->memory_size); 05118 05119 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 05120 } 05121 05122 #include "pshpack1.h" 05123 typedef struct 05124 { 05125 unsigned char type; 05126 unsigned char alignment; 05127 unsigned short total_size; 05128 } NDR_SMFARRAY_FORMAT; 05129 05130 typedef struct 05131 { 05132 unsigned char type; 05133 unsigned char alignment; 05134 ULONG total_size; 05135 } NDR_LGFARRAY_FORMAT; 05136 #include "poppack.h" 05137 05138 /*********************************************************************** 05139 * NdrFixedArrayMarshall [RPCRT4.@] 05140 */ 05141 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 05142 unsigned char *pMemory, 05143 PFORMAT_STRING pFormat) 05144 { 05145 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 05146 ULONG total_size; 05147 05148 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05149 05150 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 05151 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 05152 { 05153 ERR("invalid format type %x\n", pSmFArrayFormat->type); 05154 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05155 return NULL; 05156 } 05157 05158 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 05159 05160 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 05161 { 05162 total_size = pSmFArrayFormat->total_size; 05163 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 05164 } 05165 else 05166 { 05167 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 05168 total_size = pLgFArrayFormat->total_size; 05169 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 05170 } 05171 05172 pStubMsg->BufferMark = pStubMsg->Buffer; 05173 safe_copy_to_buffer(pStubMsg, pMemory, total_size); 05174 05175 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 05176 05177 return NULL; 05178 } 05179 05180 /*********************************************************************** 05181 * NdrFixedArrayUnmarshall [RPCRT4.@] 05182 */ 05183 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 05184 unsigned char **ppMemory, 05185 PFORMAT_STRING pFormat, 05186 unsigned char fMustAlloc) 05187 { 05188 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 05189 ULONG total_size; 05190 unsigned char *saved_buffer; 05191 05192 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 05193 05194 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 05195 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 05196 { 05197 ERR("invalid format type %x\n", pSmFArrayFormat->type); 05198 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05199 return NULL; 05200 } 05201 05202 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 05203 05204 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 05205 { 05206 total_size = pSmFArrayFormat->total_size; 05207 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 05208 } 05209 else 05210 { 05211 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 05212 total_size = pLgFArrayFormat->total_size; 05213 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 05214 } 05215 05216 if (fMustAlloc) 05217 *ppMemory = NdrAllocate(pStubMsg, total_size); 05218 else 05219 { 05220 if (!pStubMsg->IsClient && !*ppMemory) 05221 /* for servers, we just point straight into the RPC buffer */ 05222 *ppMemory = pStubMsg->Buffer; 05223 } 05224 05225 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 05226 safe_buffer_increment(pStubMsg, total_size); 05227 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 05228 05229 TRACE("copying %p to %p\n", saved_buffer, *ppMemory); 05230 if (*ppMemory != saved_buffer) 05231 memcpy(*ppMemory, saved_buffer, total_size); 05232 05233 return NULL; 05234 } 05235 05236 /*********************************************************************** 05237 * NdrFixedArrayBufferSize [RPCRT4.@] 05238 */ 05239 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 05240 unsigned char *pMemory, 05241 PFORMAT_STRING pFormat) 05242 { 05243 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 05244 ULONG total_size; 05245 05246 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05247 05248 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 05249 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 05250 { 05251 ERR("invalid format type %x\n", pSmFArrayFormat->type); 05252 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05253 return; 05254 } 05255 05256 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1); 05257 05258 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 05259 { 05260 total_size = pSmFArrayFormat->total_size; 05261 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 05262 } 05263 else 05264 { 05265 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 05266 total_size = pLgFArrayFormat->total_size; 05267 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 05268 } 05269 safe_buffer_length_increment(pStubMsg, total_size); 05270 05271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 05272 } 05273 05274 /*********************************************************************** 05275 * NdrFixedArrayMemorySize [RPCRT4.@] 05276 */ 05277 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 05278 PFORMAT_STRING pFormat) 05279 { 05280 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 05281 ULONG total_size; 05282 05283 TRACE("(%p, %p)\n", pStubMsg, pFormat); 05284 05285 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 05286 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 05287 { 05288 ERR("invalid format type %x\n", pSmFArrayFormat->type); 05289 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05290 return 0; 05291 } 05292 05293 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); 05294 05295 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 05296 { 05297 total_size = pSmFArrayFormat->total_size; 05298 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 05299 } 05300 else 05301 { 05302 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 05303 total_size = pLgFArrayFormat->total_size; 05304 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 05305 } 05306 pStubMsg->BufferMark = pStubMsg->Buffer; 05307 safe_buffer_increment(pStubMsg, total_size); 05308 pStubMsg->MemorySize += total_size; 05309 05310 EmbeddedPointerMemorySize(pStubMsg, pFormat); 05311 05312 return total_size; 05313 } 05314 05315 /*********************************************************************** 05316 * NdrFixedArrayFree [RPCRT4.@] 05317 */ 05318 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 05319 unsigned char *pMemory, 05320 PFORMAT_STRING pFormat) 05321 { 05322 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; 05323 05324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05325 05326 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && 05327 (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) 05328 { 05329 ERR("invalid format type %x\n", pSmFArrayFormat->type); 05330 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05331 return; 05332 } 05333 05334 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) 05335 pFormat = (const unsigned char *)(pSmFArrayFormat + 1); 05336 else 05337 { 05338 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; 05339 pFormat = (const unsigned char *)(pLgFArrayFormat + 1); 05340 } 05341 05342 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 05343 } 05344 05345 /*********************************************************************** 05346 * NdrVaryingArrayMarshall [RPCRT4.@] 05347 */ 05348 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, 05349 unsigned char *pMemory, 05350 PFORMAT_STRING pFormat) 05351 { 05352 unsigned char alignment; 05353 DWORD elements, esize; 05354 ULONG bufsize; 05355 05356 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05357 05358 if ((pFormat[0] != RPC_FC_SMVARRAY) && 05359 (pFormat[0] != RPC_FC_LGVARRAY)) 05360 { 05361 ERR("invalid format type %x\n", pFormat[0]); 05362 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05363 return NULL; 05364 } 05365 05366 alignment = pFormat[1] + 1; 05367 05368 if (pFormat[0] == RPC_FC_SMVARRAY) 05369 { 05370 pFormat += 2; 05371 pFormat += sizeof(WORD); 05372 elements = *(const WORD*)pFormat; 05373 pFormat += sizeof(WORD); 05374 } 05375 else 05376 { 05377 pFormat += 2; 05378 pFormat += sizeof(DWORD); 05379 elements = *(const DWORD*)pFormat; 05380 pFormat += sizeof(DWORD); 05381 } 05382 05383 esize = *(const WORD*)pFormat; 05384 pFormat += sizeof(WORD); 05385 05386 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 05387 if ((pStubMsg->ActualCount > elements) || 05388 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 05389 { 05390 RpcRaiseException(RPC_S_INVALID_BOUND); 05391 return NULL; 05392 } 05393 05394 WriteVariance(pStubMsg); 05395 05396 align_pointer_clear(&pStubMsg->Buffer, alignment); 05397 05398 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 05399 pStubMsg->BufferMark = pStubMsg->Buffer; 05400 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); 05401 05402 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); 05403 05404 return NULL; 05405 } 05406 05407 /*********************************************************************** 05408 * NdrVaryingArrayUnmarshall [RPCRT4.@] 05409 */ 05410 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 05411 unsigned char **ppMemory, 05412 PFORMAT_STRING pFormat, 05413 unsigned char fMustAlloc) 05414 { 05415 unsigned char alignment; 05416 DWORD size, elements, esize; 05417 ULONG bufsize; 05418 unsigned char *saved_buffer; 05419 ULONG offset; 05420 05421 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 05422 05423 if ((pFormat[0] != RPC_FC_SMVARRAY) && 05424 (pFormat[0] != RPC_FC_LGVARRAY)) 05425 { 05426 ERR("invalid format type %x\n", pFormat[0]); 05427 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05428 return NULL; 05429 } 05430 05431 alignment = pFormat[1] + 1; 05432 05433 if (pFormat[0] == RPC_FC_SMVARRAY) 05434 { 05435 pFormat += 2; 05436 size = *(const WORD*)pFormat; 05437 pFormat += sizeof(WORD); 05438 elements = *(const WORD*)pFormat; 05439 pFormat += sizeof(WORD); 05440 } 05441 else 05442 { 05443 pFormat += 2; 05444 size = *(const DWORD*)pFormat; 05445 pFormat += sizeof(DWORD); 05446 elements = *(const DWORD*)pFormat; 05447 pFormat += sizeof(DWORD); 05448 } 05449 05450 esize = *(const WORD*)pFormat; 05451 pFormat += sizeof(WORD); 05452 05453 pFormat = ReadVariance(pStubMsg, pFormat, elements); 05454 05455 align_pointer(&pStubMsg->Buffer, alignment); 05456 05457 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 05458 offset = pStubMsg->Offset; 05459 05460 if (!fMustAlloc && !*ppMemory) 05461 fMustAlloc = TRUE; 05462 if (fMustAlloc) 05463 *ppMemory = NdrAllocate(pStubMsg, size); 05464 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; 05465 safe_buffer_increment(pStubMsg, bufsize); 05466 05467 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); 05468 05469 memcpy(*ppMemory + offset, saved_buffer, bufsize); 05470 05471 return NULL; 05472 } 05473 05474 /*********************************************************************** 05475 * NdrVaryingArrayBufferSize [RPCRT4.@] 05476 */ 05477 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 05478 unsigned char *pMemory, 05479 PFORMAT_STRING pFormat) 05480 { 05481 unsigned char alignment; 05482 DWORD elements, esize; 05483 05484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05485 05486 if ((pFormat[0] != RPC_FC_SMVARRAY) && 05487 (pFormat[0] != RPC_FC_LGVARRAY)) 05488 { 05489 ERR("invalid format type %x\n", pFormat[0]); 05490 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05491 return; 05492 } 05493 05494 alignment = pFormat[1] + 1; 05495 05496 if (pFormat[0] == RPC_FC_SMVARRAY) 05497 { 05498 pFormat += 2; 05499 pFormat += sizeof(WORD); 05500 elements = *(const WORD*)pFormat; 05501 pFormat += sizeof(WORD); 05502 } 05503 else 05504 { 05505 pFormat += 2; 05506 pFormat += sizeof(DWORD); 05507 elements = *(const DWORD*)pFormat; 05508 pFormat += sizeof(DWORD); 05509 } 05510 05511 esize = *(const WORD*)pFormat; 05512 pFormat += sizeof(WORD); 05513 05514 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 05515 if ((pStubMsg->ActualCount > elements) || 05516 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 05517 { 05518 RpcRaiseException(RPC_S_INVALID_BOUND); 05519 return; 05520 } 05521 05522 SizeVariance(pStubMsg); 05523 05524 align_length(&pStubMsg->BufferLength, alignment); 05525 05526 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 05527 05528 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); 05529 } 05530 05531 /*********************************************************************** 05532 * NdrVaryingArrayMemorySize [RPCRT4.@] 05533 */ 05534 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 05535 PFORMAT_STRING pFormat) 05536 { 05537 unsigned char alignment; 05538 DWORD size, elements, esize; 05539 05540 TRACE("(%p, %p)\n", pStubMsg, pFormat); 05541 05542 if ((pFormat[0] != RPC_FC_SMVARRAY) && 05543 (pFormat[0] != RPC_FC_LGVARRAY)) 05544 { 05545 ERR("invalid format type %x\n", pFormat[0]); 05546 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05547 return 0; 05548 } 05549 05550 alignment = pFormat[1] + 1; 05551 05552 if (pFormat[0] == RPC_FC_SMVARRAY) 05553 { 05554 pFormat += 2; 05555 size = *(const WORD*)pFormat; 05556 pFormat += sizeof(WORD); 05557 elements = *(const WORD*)pFormat; 05558 pFormat += sizeof(WORD); 05559 } 05560 else 05561 { 05562 pFormat += 2; 05563 size = *(const DWORD*)pFormat; 05564 pFormat += sizeof(DWORD); 05565 elements = *(const DWORD*)pFormat; 05566 pFormat += sizeof(DWORD); 05567 } 05568 05569 esize = *(const WORD*)pFormat; 05570 pFormat += sizeof(WORD); 05571 05572 pFormat = ReadVariance(pStubMsg, pFormat, elements); 05573 05574 align_pointer(&pStubMsg->Buffer, alignment); 05575 05576 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); 05577 pStubMsg->MemorySize += size; 05578 05579 EmbeddedPointerMemorySize(pStubMsg, pFormat); 05580 05581 return pStubMsg->MemorySize; 05582 } 05583 05584 /*********************************************************************** 05585 * NdrVaryingArrayFree [RPCRT4.@] 05586 */ 05587 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, 05588 unsigned char *pMemory, 05589 PFORMAT_STRING pFormat) 05590 { 05591 DWORD elements; 05592 05593 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05594 05595 if ((pFormat[0] != RPC_FC_SMVARRAY) && 05596 (pFormat[0] != RPC_FC_LGVARRAY)) 05597 { 05598 ERR("invalid format type %x\n", pFormat[0]); 05599 RpcRaiseException(RPC_S_INTERNAL_ERROR); 05600 return; 05601 } 05602 05603 if (pFormat[0] == RPC_FC_SMVARRAY) 05604 { 05605 pFormat += 2; 05606 pFormat += sizeof(WORD); 05607 elements = *(const WORD*)pFormat; 05608 pFormat += sizeof(WORD); 05609 } 05610 else 05611 { 05612 pFormat += 2; 05613 pFormat += sizeof(DWORD); 05614 elements = *(const DWORD*)pFormat; 05615 pFormat += sizeof(DWORD); 05616 } 05617 05618 pFormat += sizeof(WORD); 05619 05620 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); 05621 if ((pStubMsg->ActualCount > elements) || 05622 (pStubMsg->ActualCount + pStubMsg->Offset > elements)) 05623 { 05624 RpcRaiseException(RPC_S_INVALID_BOUND); 05625 return; 05626 } 05627 05628 EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 05629 } 05630 05631 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory) 05632 { 05633 switch (fc) 05634 { 05635 case RPC_FC_BYTE: 05636 case RPC_FC_CHAR: 05637 case RPC_FC_SMALL: 05638 case RPC_FC_USMALL: 05639 return *pMemory; 05640 case RPC_FC_WCHAR: 05641 case RPC_FC_SHORT: 05642 case RPC_FC_USHORT: 05643 case RPC_FC_ENUM16: 05644 return *(const USHORT *)pMemory; 05645 case RPC_FC_LONG: 05646 case RPC_FC_ULONG: 05647 case RPC_FC_ENUM32: 05648 return *(const ULONG *)pMemory; 05649 case RPC_FC_INT3264: 05650 case RPC_FC_UINT3264: 05651 return *(const ULONG_PTR *)pMemory; 05652 default: 05653 FIXME("Unhandled base type: 0x%02x\n", fc); 05654 return 0; 05655 } 05656 } 05657 05658 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg, 05659 ULONG discriminant, 05660 PFORMAT_STRING pFormat) 05661 { 05662 unsigned short num_arms, arm, type; 05663 05664 num_arms = *(const SHORT*)pFormat & 0x0fff; 05665 pFormat += 2; 05666 for(arm = 0; arm < num_arms; arm++) 05667 { 05668 if(discriminant == *(const ULONG*)pFormat) 05669 { 05670 pFormat += 4; 05671 break; 05672 } 05673 pFormat += 6; 05674 } 05675 05676 type = *(const unsigned short*)pFormat; 05677 TRACE("type %04x\n", type); 05678 if(arm == num_arms) /* default arm extras */ 05679 { 05680 if(type == 0xffff) 05681 { 05682 ERR("no arm for 0x%x and no default case\n", discriminant); 05683 RpcRaiseException(RPC_S_INVALID_TAG); 05684 return NULL; 05685 } 05686 if(type == 0) 05687 { 05688 TRACE("falling back to empty default case for 0x%x\n", discriminant); 05689 return NULL; 05690 } 05691 } 05692 return pFormat; 05693 } 05694 05695 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat) 05696 { 05697 unsigned short type; 05698 05699 pFormat += 2; 05700 05701 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 05702 if(!pFormat) 05703 return NULL; 05704 05705 type = *(const unsigned short*)pFormat; 05706 if((type & 0xff00) == 0x8000) 05707 { 05708 unsigned char basetype = LOBYTE(type); 05709 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype); 05710 } 05711 else 05712 { 05713 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 05714 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK]; 05715 if (m) 05716 { 05717 unsigned char *saved_buffer = NULL; 05718 int pointer_buffer_mark_set = 0; 05719 switch(*desc) 05720 { 05721 case RPC_FC_RP: 05722 case RPC_FC_UP: 05723 case RPC_FC_OP: 05724 case RPC_FC_FP: 05725 align_pointer_clear(&pStubMsg->Buffer, 4); 05726 saved_buffer = pStubMsg->Buffer; 05727 if (pStubMsg->PointerBufferMark) 05728 { 05729 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 05730 pStubMsg->PointerBufferMark = NULL; 05731 pointer_buffer_mark_set = 1; 05732 } 05733 else 05734 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ 05735 05736 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc); 05737 if (pointer_buffer_mark_set) 05738 { 05739 STD_OVERFLOW_CHECK(pStubMsg); 05740 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 05741 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 05742 { 05743 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", 05744 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 05745 RpcRaiseException(RPC_X_BAD_STUB_DATA); 05746 } 05747 pStubMsg->Buffer = saved_buffer + 4; 05748 } 05749 break; 05750 default: 05751 m(pStubMsg, pMemory, desc); 05752 } 05753 } 05754 else FIXME("no marshaller for embedded type %02x\n", *desc); 05755 } 05756 return NULL; 05757 } 05758 05759 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, 05760 unsigned char **ppMemory, 05761 ULONG discriminant, 05762 PFORMAT_STRING pFormat, 05763 unsigned char fMustAlloc) 05764 { 05765 unsigned short type; 05766 05767 pFormat += 2; 05768 05769 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 05770 if(!pFormat) 05771 return NULL; 05772 05773 type = *(const unsigned short*)pFormat; 05774 if((type & 0xff00) == 0x8000) 05775 { 05776 unsigned char basetype = LOBYTE(type); 05777 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE); 05778 } 05779 else 05780 { 05781 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 05782 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; 05783 if (m) 05784 { 05785 unsigned char *saved_buffer = NULL; 05786 int pointer_buffer_mark_set = 0; 05787 switch(*desc) 05788 { 05789 case RPC_FC_RP: 05790 case RPC_FC_UP: 05791 case RPC_FC_OP: 05792 case RPC_FC_FP: 05793 align_pointer(&pStubMsg->Buffer, 4); 05794 saved_buffer = pStubMsg->Buffer; 05795 if (pStubMsg->PointerBufferMark) 05796 { 05797 pStubMsg->Buffer = pStubMsg->PointerBufferMark; 05798 pStubMsg->PointerBufferMark = NULL; 05799 pointer_buffer_mark_set = 1; 05800 } 05801 else 05802 pStubMsg->Buffer += 4; /* for pointer ID */ 05803 05804 if (saved_buffer + 4 > pStubMsg->BufferEnd) 05805 { 05806 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", 05807 saved_buffer, pStubMsg->BufferEnd); 05808 RpcRaiseException(RPC_X_BAD_STUB_DATA); 05809 } 05810 05811 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc); 05812 if (pointer_buffer_mark_set) 05813 { 05814 STD_OVERFLOW_CHECK(pStubMsg); 05815 pStubMsg->PointerBufferMark = pStubMsg->Buffer; 05816 pStubMsg->Buffer = saved_buffer + 4; 05817 } 05818 break; 05819 default: 05820 m(pStubMsg, ppMemory, desc, fMustAlloc); 05821 } 05822 } 05823 else FIXME("no marshaller for embedded type %02x\n", *desc); 05824 } 05825 return NULL; 05826 } 05827 05828 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, 05829 unsigned char *pMemory, 05830 ULONG discriminant, 05831 PFORMAT_STRING pFormat) 05832 { 05833 unsigned short type; 05834 05835 pFormat += 2; 05836 05837 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 05838 if(!pFormat) 05839 return; 05840 05841 type = *(const unsigned short*)pFormat; 05842 if((type & 0xff00) == 0x8000) 05843 { 05844 unsigned char basetype = LOBYTE(type); 05845 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype); 05846 } 05847 else 05848 { 05849 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 05850 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; 05851 if (m) 05852 { 05853 switch(*desc) 05854 { 05855 case RPC_FC_RP: 05856 case RPC_FC_UP: 05857 case RPC_FC_OP: 05858 case RPC_FC_FP: 05859 align_length(&pStubMsg->BufferLength, 4); 05860 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */ 05861 if (!pStubMsg->IgnoreEmbeddedPointers) 05862 { 05863 int saved_buffer_length = pStubMsg->BufferLength; 05864 pStubMsg->BufferLength = pStubMsg->PointerLength; 05865 pStubMsg->PointerLength = 0; 05866 if(!pStubMsg->BufferLength) 05867 ERR("BufferLength == 0??\n"); 05868 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc); 05869 pStubMsg->PointerLength = pStubMsg->BufferLength; 05870 pStubMsg->BufferLength = saved_buffer_length; 05871 } 05872 break; 05873 default: 05874 m(pStubMsg, pMemory, desc); 05875 } 05876 } 05877 else FIXME("no buffersizer for embedded type %02x\n", *desc); 05878 } 05879 } 05880 05881 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg, 05882 ULONG discriminant, 05883 PFORMAT_STRING pFormat) 05884 { 05885 unsigned short type, size; 05886 05887 size = *(const unsigned short*)pFormat; 05888 pStubMsg->Memory += size; 05889 pFormat += 2; 05890 05891 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 05892 if(!pFormat) 05893 return 0; 05894 05895 type = *(const unsigned short*)pFormat; 05896 if((type & 0xff00) == 0x8000) 05897 { 05898 return NdrBaseTypeMemorySize(pStubMsg, pFormat); 05899 } 05900 else 05901 { 05902 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 05903 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; 05904 unsigned char *saved_buffer; 05905 if (m) 05906 { 05907 switch(*desc) 05908 { 05909 case RPC_FC_RP: 05910 case RPC_FC_UP: 05911 case RPC_FC_OP: 05912 case RPC_FC_FP: 05913 align_pointer(&pStubMsg->Buffer, 4); 05914 saved_buffer = pStubMsg->Buffer; 05915 safe_buffer_increment(pStubMsg, 4); 05916 align_length(&pStubMsg->MemorySize, sizeof(void *)); 05917 pStubMsg->MemorySize += sizeof(void *); 05918 if (!pStubMsg->IgnoreEmbeddedPointers) 05919 PointerMemorySize(pStubMsg, saved_buffer, pFormat); 05920 break; 05921 default: 05922 return m(pStubMsg, desc); 05923 } 05924 } 05925 else FIXME("no marshaller for embedded type %02x\n", *desc); 05926 } 05927 05928 TRACE("size %d\n", size); 05929 return size; 05930 } 05931 05932 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, 05933 unsigned char *pMemory, 05934 ULONG discriminant, 05935 PFORMAT_STRING pFormat) 05936 { 05937 unsigned short type; 05938 05939 pFormat += 2; 05940 05941 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); 05942 if(!pFormat) 05943 return; 05944 05945 type = *(const unsigned short*)pFormat; 05946 if((type & 0xff00) != 0x8000) 05947 { 05948 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; 05949 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK]; 05950 if (m) 05951 { 05952 switch(*desc) 05953 { 05954 case RPC_FC_RP: 05955 case RPC_FC_UP: 05956 case RPC_FC_OP: 05957 case RPC_FC_FP: 05958 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); 05959 break; 05960 default: 05961 m(pStubMsg, pMemory, desc); 05962 } 05963 } 05964 } 05965 } 05966 05967 /*********************************************************************** 05968 * NdrEncapsulatedUnionMarshall [RPCRT4.@] 05969 */ 05970 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, 05971 unsigned char *pMemory, 05972 PFORMAT_STRING pFormat) 05973 { 05974 unsigned char switch_type; 05975 unsigned char increment; 05976 ULONG switch_value; 05977 05978 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 05979 pFormat++; 05980 05981 switch_type = *pFormat & 0xf; 05982 increment = (*pFormat & 0xf0) >> 4; 05983 pFormat++; 05984 05985 align_pointer_clear(&pStubMsg->Buffer, increment); 05986 05987 switch_value = get_discriminant(switch_type, pMemory); 05988 TRACE("got switch value 0x%x\n", switch_value); 05989 05990 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type); 05991 pMemory += increment; 05992 05993 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat); 05994 } 05995 05996 /*********************************************************************** 05997 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@] 05998 */ 05999 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 06000 unsigned char **ppMemory, 06001 PFORMAT_STRING pFormat, 06002 unsigned char fMustAlloc) 06003 { 06004 unsigned char switch_type; 06005 unsigned char increment; 06006 ULONG switch_value; 06007 unsigned short size; 06008 unsigned char *pMemoryArm; 06009 06010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 06011 pFormat++; 06012 06013 switch_type = *pFormat & 0xf; 06014 increment = (*pFormat & 0xf0) >> 4; 06015 pFormat++; 06016 06017 align_pointer(&pStubMsg->Buffer, increment); 06018 switch_value = get_discriminant(switch_type, pStubMsg->Buffer); 06019 TRACE("got switch value 0x%x\n", switch_value); 06020 06021 size = *(const unsigned short*)pFormat + increment; 06022 if (!fMustAlloc && !*ppMemory) 06023 fMustAlloc = TRUE; 06024 if (fMustAlloc) 06025 *ppMemory = NdrAllocate(pStubMsg, size); 06026 06027 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm 06028 * since the arm is part of the memory block that is encompassed by 06029 * the whole union. Memory is forced to allocate when pointers 06030 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 06031 * clearing the memory we pass in to the unmarshaller */ 06032 if (fMustAlloc) 06033 memset(*ppMemory, 0, size); 06034 06035 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE); 06036 pMemoryArm = *ppMemory + increment; 06037 06038 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE); 06039 } 06040 06041 /*********************************************************************** 06042 * NdrEncapsulatedUnionBufferSize [RPCRT4.@] 06043 */ 06044 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 06045 unsigned char *pMemory, 06046 PFORMAT_STRING pFormat) 06047 { 06048 unsigned char switch_type; 06049 unsigned char increment; 06050 ULONG switch_value; 06051 06052 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 06053 pFormat++; 06054 06055 switch_type = *pFormat & 0xf; 06056 increment = (*pFormat & 0xf0) >> 4; 06057 pFormat++; 06058 06059 align_length(&pStubMsg->BufferLength, increment); 06060 switch_value = get_discriminant(switch_type, pMemory); 06061 TRACE("got switch value 0x%x\n", switch_value); 06062 06063 /* Add discriminant size */ 06064 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type); 06065 pMemory += increment; 06066 06067 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat); 06068 } 06069 06070 /*********************************************************************** 06071 * NdrEncapsulatedUnionMemorySize [RPCRT4.@] 06072 */ 06073 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 06074 PFORMAT_STRING pFormat) 06075 { 06076 unsigned char switch_type; 06077 unsigned char increment; 06078 ULONG switch_value; 06079 06080 switch_type = *pFormat & 0xf; 06081 increment = (*pFormat & 0xf0) >> 4; 06082 pFormat++; 06083 06084 align_pointer(&pStubMsg->Buffer, increment); 06085 switch_value = get_discriminant(switch_type, pStubMsg->Buffer); 06086 TRACE("got switch value 0x%x\n", switch_value); 06087 06088 pStubMsg->Memory += increment; 06089 06090 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat); 06091 } 06092 06093 /*********************************************************************** 06094 * NdrEncapsulatedUnionFree [RPCRT4.@] 06095 */ 06096 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, 06097 unsigned char *pMemory, 06098 PFORMAT_STRING pFormat) 06099 { 06100 unsigned char switch_type; 06101 unsigned char increment; 06102 ULONG switch_value; 06103 06104 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 06105 pFormat++; 06106 06107 switch_type = *pFormat & 0xf; 06108 increment = (*pFormat & 0xf0) >> 4; 06109 pFormat++; 06110 06111 switch_value = get_discriminant(switch_type, pMemory); 06112 TRACE("got switch value 0x%x\n", switch_value); 06113 06114 pMemory += increment; 06115 06116 union_arm_free(pStubMsg, pMemory, switch_value, pFormat); 06117 } 06118 06119 /*********************************************************************** 06120 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@] 06121 */ 06122 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, 06123 unsigned char *pMemory, 06124 PFORMAT_STRING pFormat) 06125 { 06126 unsigned char switch_type; 06127 06128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 06129 pFormat++; 06130 06131 switch_type = *pFormat; 06132 pFormat++; 06133 06134 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 06135 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 06136 /* Marshall discriminant */ 06137 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); 06138 06139 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 06140 } 06141 06142 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg, 06143 PFORMAT_STRING *ppFormat) 06144 { 06145 LONG discriminant = 0; 06146 06147 switch(**ppFormat) 06148 { 06149 case RPC_FC_BYTE: 06150 case RPC_FC_CHAR: 06151 case RPC_FC_SMALL: 06152 case RPC_FC_USMALL: 06153 { 06154 UCHAR d; 06155 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 06156 discriminant = d; 06157 break; 06158 } 06159 case RPC_FC_WCHAR: 06160 case RPC_FC_SHORT: 06161 case RPC_FC_USHORT: 06162 case RPC_FC_ENUM16: 06163 { 06164 USHORT d; 06165 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 06166 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 06167 discriminant = d; 06168 break; 06169 } 06170 case RPC_FC_LONG: 06171 case RPC_FC_ULONG: 06172 { 06173 ULONG d; 06174 align_pointer(&pStubMsg->Buffer, sizeof(ULONG)); 06175 safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); 06176 discriminant = d; 06177 break; 06178 } 06179 default: 06180 FIXME("Unhandled base type: 0x%02x\n", **ppFormat); 06181 } 06182 (*ppFormat)++; 06183 06184 if (pStubMsg->fHasNewCorrDesc) 06185 *ppFormat += 6; 06186 else 06187 *ppFormat += 4; 06188 return discriminant; 06189 } 06190 06191 /********************************************************************** 06192 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@] 06193 */ 06194 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 06195 unsigned char **ppMemory, 06196 PFORMAT_STRING pFormat, 06197 unsigned char fMustAlloc) 06198 { 06199 LONG discriminant; 06200 unsigned short size; 06201 06202 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); 06203 pFormat++; 06204 06205 /* Unmarshall discriminant */ 06206 discriminant = unmarshall_discriminant(pStubMsg, &pFormat); 06207 TRACE("unmarshalled discriminant %x\n", discriminant); 06208 06209 pFormat += *(const SHORT*)pFormat; 06210 06211 size = *(const unsigned short*)pFormat; 06212 06213 if (!fMustAlloc && !*ppMemory) 06214 fMustAlloc = TRUE; 06215 if (fMustAlloc) 06216 *ppMemory = NdrAllocate(pStubMsg, size); 06217 06218 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm 06219 * since the arm is part of the memory block that is encompassed by 06220 * the whole union. Memory is forced to allocate when pointers 06221 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by 06222 * clearing the memory we pass in to the unmarshaller */ 06223 if (fMustAlloc) 06224 memset(*ppMemory, 0, size); 06225 06226 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE); 06227 } 06228 06229 /*********************************************************************** 06230 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@] 06231 */ 06232 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 06233 unsigned char *pMemory, 06234 PFORMAT_STRING pFormat) 06235 { 06236 unsigned char switch_type; 06237 06238 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 06239 pFormat++; 06240 06241 switch_type = *pFormat; 06242 pFormat++; 06243 06244 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 06245 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 06246 /* Add discriminant size */ 06247 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); 06248 06249 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 06250 } 06251 06252 /*********************************************************************** 06253 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@] 06254 */ 06255 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 06256 PFORMAT_STRING pFormat) 06257 { 06258 ULONG discriminant; 06259 06260 pFormat++; 06261 /* Unmarshall discriminant */ 06262 discriminant = unmarshall_discriminant(pStubMsg, &pFormat); 06263 TRACE("unmarshalled discriminant 0x%x\n", discriminant); 06264 06265 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat); 06266 } 06267 06268 /*********************************************************************** 06269 * NdrNonEncapsulatedUnionFree [RPCRT4.@] 06270 */ 06271 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, 06272 unsigned char *pMemory, 06273 PFORMAT_STRING pFormat) 06274 { 06275 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); 06276 pFormat++; 06277 pFormat++; 06278 06279 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); 06280 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); 06281 06282 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); 06283 } 06284 06285 /*********************************************************************** 06286 * NdrByteCountPointerMarshall [RPCRT4.@] 06287 */ 06288 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, 06289 unsigned char *pMemory, 06290 PFORMAT_STRING pFormat) 06291 { 06292 FIXME("stub\n"); 06293 return NULL; 06294 } 06295 06296 /*********************************************************************** 06297 * NdrByteCountPointerUnmarshall [RPCRT4.@] 06298 */ 06299 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 06300 unsigned char **ppMemory, 06301 PFORMAT_STRING pFormat, 06302 unsigned char fMustAlloc) 06303 { 06304 FIXME("stub\n"); 06305 return NULL; 06306 } 06307 06308 /*********************************************************************** 06309 * NdrByteCountPointerBufferSize [RPCRT4.@] 06310 */ 06311 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 06312 unsigned char *pMemory, 06313 PFORMAT_STRING pFormat) 06314 { 06315 FIXME("stub\n"); 06316 } 06317 06318 /*********************************************************************** 06319 * NdrByteCountPointerMemorySize [internal] 06320 */ 06321 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 06322 PFORMAT_STRING pFormat) 06323 { 06324 FIXME("stub\n"); 06325 return 0; 06326 } 06327 06328 /*********************************************************************** 06329 * NdrByteCountPointerFree [RPCRT4.@] 06330 */ 06331 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg, 06332 unsigned char *pMemory, 06333 PFORMAT_STRING pFormat) 06334 { 06335 FIXME("stub\n"); 06336 } 06337 06338 /*********************************************************************** 06339 * NdrXmitOrRepAsMarshall [RPCRT4.@] 06340 */ 06341 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg, 06342 unsigned char *pMemory, 06343 PFORMAT_STRING pFormat) 06344 { 06345 FIXME("stub\n"); 06346 return NULL; 06347 } 06348 06349 /*********************************************************************** 06350 * NdrXmitOrRepAsUnmarshall [RPCRT4.@] 06351 */ 06352 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 06353 unsigned char **ppMemory, 06354 PFORMAT_STRING pFormat, 06355 unsigned char fMustAlloc) 06356 { 06357 FIXME("stub\n"); 06358 return NULL; 06359 } 06360 06361 /*********************************************************************** 06362 * NdrXmitOrRepAsBufferSize [RPCRT4.@] 06363 */ 06364 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg, 06365 unsigned char *pMemory, 06366 PFORMAT_STRING pFormat) 06367 { 06368 FIXME("stub\n"); 06369 } 06370 06371 /*********************************************************************** 06372 * NdrXmitOrRepAsMemorySize [RPCRT4.@] 06373 */ 06374 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg, 06375 PFORMAT_STRING pFormat) 06376 { 06377 FIXME("stub\n"); 06378 return 0; 06379 } 06380 06381 /*********************************************************************** 06382 * NdrXmitOrRepAsFree [RPCRT4.@] 06383 */ 06384 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, 06385 unsigned char *pMemory, 06386 PFORMAT_STRING pFormat) 06387 { 06388 FIXME("stub\n"); 06389 } 06390 06391 /*********************************************************************** 06392 * NdrRangeMarshall [internal] 06393 */ 06394 static unsigned char *WINAPI NdrRangeMarshall( 06395 PMIDL_STUB_MESSAGE pStubMsg, 06396 unsigned char *pMemory, 06397 PFORMAT_STRING pFormat) 06398 { 06399 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 06400 unsigned char base_type; 06401 06402 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06403 06404 if (pRange->type != RPC_FC_RANGE) 06405 { 06406 ERR("invalid format type %x\n", pRange->type); 06407 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06408 return NULL; 06409 } 06410 06411 base_type = pRange->flags_type & 0xf; 06412 06413 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type); 06414 } 06415 06416 /*********************************************************************** 06417 * NdrRangeUnmarshall [RPCRT4.@] 06418 */ 06419 unsigned char *WINAPI NdrRangeUnmarshall( 06420 PMIDL_STUB_MESSAGE pStubMsg, 06421 unsigned char **ppMemory, 06422 PFORMAT_STRING pFormat, 06423 unsigned char fMustAlloc) 06424 { 06425 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 06426 unsigned char base_type; 06427 06428 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); 06429 06430 if (pRange->type != RPC_FC_RANGE) 06431 { 06432 ERR("invalid format type %x\n", pRange->type); 06433 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06434 return NULL; 06435 } 06436 base_type = pRange->flags_type & 0xf; 06437 06438 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n", 06439 base_type, pRange->low_value, pRange->high_value); 06440 06441 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \ 06442 do \ 06443 { \ 06444 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \ 06445 if (!fMustAlloc && !*ppMemory) \ 06446 fMustAlloc = TRUE; \ 06447 if (fMustAlloc) \ 06448 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \ 06449 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \ 06450 { \ 06451 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \ 06452 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \ 06453 RpcRaiseException(RPC_X_BAD_STUB_DATA); \ 06454 } \ 06455 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \ 06456 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \ 06457 { \ 06458 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \ 06459 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \ 06460 (mem_type)pRange->high_value); \ 06461 RpcRaiseException(RPC_S_INVALID_BOUND); \ 06462 return NULL; \ 06463 } \ 06464 TRACE("*ppMemory: %p\n", *ppMemory); \ 06465 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \ 06466 pStubMsg->Buffer += sizeof(wire_type); \ 06467 } while (0) 06468 06469 switch(base_type) 06470 { 06471 case RPC_FC_CHAR: 06472 case RPC_FC_SMALL: 06473 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d"); 06474 TRACE("value: 0x%02x\n", **ppMemory); 06475 break; 06476 case RPC_FC_BYTE: 06477 case RPC_FC_USMALL: 06478 RANGE_UNMARSHALL(CHAR, CHAR, "%u"); 06479 TRACE("value: 0x%02x\n", **ppMemory); 06480 break; 06481 case RPC_FC_WCHAR: /* FIXME: valid? */ 06482 case RPC_FC_USHORT: 06483 RANGE_UNMARSHALL(USHORT, USHORT, "%u"); 06484 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 06485 break; 06486 case RPC_FC_SHORT: 06487 RANGE_UNMARSHALL(SHORT, SHORT, "%d"); 06488 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 06489 break; 06490 case RPC_FC_LONG: 06491 case RPC_FC_ENUM32: 06492 RANGE_UNMARSHALL(LONG, LONG, "%d"); 06493 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 06494 break; 06495 case RPC_FC_ULONG: 06496 RANGE_UNMARSHALL(ULONG, ULONG, "%u"); 06497 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 06498 break; 06499 case RPC_FC_ENUM16: 06500 RANGE_UNMARSHALL(UINT, USHORT, "%u"); 06501 TRACE("value: 0x%08x\n", **(UINT **)ppMemory); 06502 break; 06503 case RPC_FC_FLOAT: 06504 case RPC_FC_DOUBLE: 06505 case RPC_FC_HYPER: 06506 default: 06507 ERR("invalid range base type: 0x%02x\n", base_type); 06508 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06509 } 06510 06511 return NULL; 06512 } 06513 06514 /*********************************************************************** 06515 * NdrRangeBufferSize [internal] 06516 */ 06517 static void WINAPI NdrRangeBufferSize( 06518 PMIDL_STUB_MESSAGE pStubMsg, 06519 unsigned char *pMemory, 06520 PFORMAT_STRING pFormat) 06521 { 06522 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 06523 unsigned char base_type; 06524 06525 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06526 06527 if (pRange->type != RPC_FC_RANGE) 06528 { 06529 ERR("invalid format type %x\n", pRange->type); 06530 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06531 } 06532 base_type = pRange->flags_type & 0xf; 06533 06534 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type); 06535 } 06536 06537 /*********************************************************************** 06538 * NdrRangeMemorySize [internal] 06539 */ 06540 static ULONG WINAPI NdrRangeMemorySize( 06541 PMIDL_STUB_MESSAGE pStubMsg, 06542 PFORMAT_STRING pFormat) 06543 { 06544 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat; 06545 unsigned char base_type; 06546 06547 if (pRange->type != RPC_FC_RANGE) 06548 { 06549 ERR("invalid format type %x\n", pRange->type); 06550 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06551 return 0; 06552 } 06553 base_type = pRange->flags_type & 0xf; 06554 06555 return NdrBaseTypeMemorySize(pStubMsg, &base_type); 06556 } 06557 06558 /*********************************************************************** 06559 * NdrRangeFree [internal] 06560 */ 06561 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg, 06562 unsigned char *pMemory, 06563 PFORMAT_STRING pFormat) 06564 { 06565 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06566 06567 /* nothing to do */ 06568 } 06569 06570 /*********************************************************************** 06571 * NdrBaseTypeMarshall [internal] 06572 */ 06573 static unsigned char *WINAPI NdrBaseTypeMarshall( 06574 PMIDL_STUB_MESSAGE pStubMsg, 06575 unsigned char *pMemory, 06576 PFORMAT_STRING pFormat) 06577 { 06578 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06579 06580 switch(*pFormat) 06581 { 06582 case RPC_FC_BYTE: 06583 case RPC_FC_CHAR: 06584 case RPC_FC_SMALL: 06585 case RPC_FC_USMALL: 06586 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR)); 06587 TRACE("value: 0x%02x\n", *pMemory); 06588 break; 06589 case RPC_FC_WCHAR: 06590 case RPC_FC_SHORT: 06591 case RPC_FC_USHORT: 06592 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT)); 06593 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT)); 06594 TRACE("value: 0x%04x\n", *(USHORT *)pMemory); 06595 break; 06596 case RPC_FC_LONG: 06597 case RPC_FC_ULONG: 06598 case RPC_FC_ERROR_STATUS_T: 06599 case RPC_FC_ENUM32: 06600 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG)); 06601 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG)); 06602 TRACE("value: 0x%08x\n", *(ULONG *)pMemory); 06603 break; 06604 case RPC_FC_FLOAT: 06605 align_pointer_clear(&pStubMsg->Buffer, sizeof(float)); 06606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); 06607 break; 06608 case RPC_FC_DOUBLE: 06609 align_pointer_clear(&pStubMsg->Buffer, sizeof(double)); 06610 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); 06611 break; 06612 case RPC_FC_HYPER: 06613 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG)); 06614 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG)); 06615 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); 06616 break; 06617 case RPC_FC_ENUM16: 06618 { 06619 USHORT val = *(UINT *)pMemory; 06620 /* only 16-bits on the wire, so do a sanity check */ 06621 if (*(UINT *)pMemory > SHRT_MAX) 06622 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); 06623 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT)); 06624 safe_copy_to_buffer(pStubMsg, &val, sizeof(val)); 06625 TRACE("value: 0x%04x\n", *(UINT *)pMemory); 06626 break; 06627 } 06628 case RPC_FC_INT3264: 06629 case RPC_FC_UINT3264: 06630 { 06631 UINT val = *(UINT_PTR *)pMemory; 06632 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT)); 06633 safe_copy_to_buffer(pStubMsg, &val, sizeof(val)); 06634 break; 06635 } 06636 case RPC_FC_IGNORE: 06637 break; 06638 default: 06639 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 06640 } 06641 06642 /* FIXME: what is the correct return value? */ 06643 return NULL; 06644 } 06645 06646 /*********************************************************************** 06647 * NdrBaseTypeUnmarshall [internal] 06648 */ 06649 static unsigned char *WINAPI NdrBaseTypeUnmarshall( 06650 PMIDL_STUB_MESSAGE pStubMsg, 06651 unsigned char **ppMemory, 06652 PFORMAT_STRING pFormat, 06653 unsigned char fMustAlloc) 06654 { 06655 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); 06656 06657 #define BASE_TYPE_UNMARSHALL(type) do { \ 06658 align_pointer(&pStubMsg->Buffer, sizeof(type)); \ 06659 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \ 06660 { \ 06661 *ppMemory = pStubMsg->Buffer; \ 06662 TRACE("*ppMemory: %p\n", *ppMemory); \ 06663 safe_buffer_increment(pStubMsg, sizeof(type)); \ 06664 } \ 06665 else \ 06666 { \ 06667 if (fMustAlloc) \ 06668 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ 06669 TRACE("*ppMemory: %p\n", *ppMemory); \ 06670 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \ 06671 } \ 06672 } while (0) 06673 06674 switch(*pFormat) 06675 { 06676 case RPC_FC_BYTE: 06677 case RPC_FC_CHAR: 06678 case RPC_FC_SMALL: 06679 case RPC_FC_USMALL: 06680 BASE_TYPE_UNMARSHALL(UCHAR); 06681 TRACE("value: 0x%02x\n", **ppMemory); 06682 break; 06683 case RPC_FC_WCHAR: 06684 case RPC_FC_SHORT: 06685 case RPC_FC_USHORT: 06686 BASE_TYPE_UNMARSHALL(USHORT); 06687 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); 06688 break; 06689 case RPC_FC_LONG: 06690 case RPC_FC_ULONG: 06691 case RPC_FC_ERROR_STATUS_T: 06692 case RPC_FC_ENUM32: 06693 BASE_TYPE_UNMARSHALL(ULONG); 06694 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); 06695 break; 06696 case RPC_FC_FLOAT: 06697 BASE_TYPE_UNMARSHALL(float); 06698 TRACE("value: %f\n", **(float **)ppMemory); 06699 break; 06700 case RPC_FC_DOUBLE: 06701 BASE_TYPE_UNMARSHALL(double); 06702 TRACE("value: %f\n", **(double **)ppMemory); 06703 break; 06704 case RPC_FC_HYPER: 06705 BASE_TYPE_UNMARSHALL(ULONGLONG); 06706 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); 06707 break; 06708 case RPC_FC_ENUM16: 06709 { 06710 USHORT val; 06711 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 06712 if (!fMustAlloc && !*ppMemory) 06713 fMustAlloc = TRUE; 06714 if (fMustAlloc) 06715 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT)); 06716 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT)); 06717 /* 16-bits on the wire, but int in memory */ 06718 **(UINT **)ppMemory = val; 06719 TRACE("value: 0x%08x\n", **(UINT **)ppMemory); 06720 break; 06721 } 06722 case RPC_FC_INT3264: 06723 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT); 06724 else 06725 { 06726 INT val; 06727 align_pointer(&pStubMsg->Buffer, sizeof(INT)); 06728 if (!fMustAlloc && !*ppMemory) 06729 fMustAlloc = TRUE; 06730 if (fMustAlloc) 06731 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR)); 06732 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT)); 06733 **(INT_PTR **)ppMemory = val; 06734 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory); 06735 } 06736 break; 06737 case RPC_FC_UINT3264: 06738 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT); 06739 else 06740 { 06741 UINT val; 06742 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 06743 if (!fMustAlloc && !*ppMemory) 06744 fMustAlloc = TRUE; 06745 if (fMustAlloc) 06746 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR)); 06747 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT)); 06748 **(UINT_PTR **)ppMemory = val; 06749 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory); 06750 } 06751 break; 06752 case RPC_FC_IGNORE: 06753 break; 06754 default: 06755 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 06756 } 06757 #undef BASE_TYPE_UNMARSHALL 06758 06759 /* FIXME: what is the correct return value? */ 06760 06761 return NULL; 06762 } 06763 06764 /*********************************************************************** 06765 * NdrBaseTypeBufferSize [internal] 06766 */ 06767 static void WINAPI NdrBaseTypeBufferSize( 06768 PMIDL_STUB_MESSAGE pStubMsg, 06769 unsigned char *pMemory, 06770 PFORMAT_STRING pFormat) 06771 { 06772 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06773 06774 switch(*pFormat) 06775 { 06776 case RPC_FC_BYTE: 06777 case RPC_FC_CHAR: 06778 case RPC_FC_SMALL: 06779 case RPC_FC_USMALL: 06780 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR)); 06781 break; 06782 case RPC_FC_WCHAR: 06783 case RPC_FC_SHORT: 06784 case RPC_FC_USHORT: 06785 case RPC_FC_ENUM16: 06786 align_length(&pStubMsg->BufferLength, sizeof(USHORT)); 06787 safe_buffer_length_increment(pStubMsg, sizeof(USHORT)); 06788 break; 06789 case RPC_FC_LONG: 06790 case RPC_FC_ULONG: 06791 case RPC_FC_ENUM32: 06792 case RPC_FC_INT3264: 06793 case RPC_FC_UINT3264: 06794 align_length(&pStubMsg->BufferLength, sizeof(ULONG)); 06795 safe_buffer_length_increment(pStubMsg, sizeof(ULONG)); 06796 break; 06797 case RPC_FC_FLOAT: 06798 align_length(&pStubMsg->BufferLength, sizeof(float)); 06799 safe_buffer_length_increment(pStubMsg, sizeof(float)); 06800 break; 06801 case RPC_FC_DOUBLE: 06802 align_length(&pStubMsg->BufferLength, sizeof(double)); 06803 safe_buffer_length_increment(pStubMsg, sizeof(double)); 06804 break; 06805 case RPC_FC_HYPER: 06806 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG)); 06807 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG)); 06808 break; 06809 case RPC_FC_ERROR_STATUS_T: 06810 align_length(&pStubMsg->BufferLength, sizeof(error_status_t)); 06811 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t)); 06812 break; 06813 case RPC_FC_IGNORE: 06814 break; 06815 default: 06816 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 06817 } 06818 } 06819 06820 /*********************************************************************** 06821 * NdrBaseTypeMemorySize [internal] 06822 */ 06823 static ULONG WINAPI NdrBaseTypeMemorySize( 06824 PMIDL_STUB_MESSAGE pStubMsg, 06825 PFORMAT_STRING pFormat) 06826 { 06827 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat); 06828 06829 switch(*pFormat) 06830 { 06831 case RPC_FC_BYTE: 06832 case RPC_FC_CHAR: 06833 case RPC_FC_SMALL: 06834 case RPC_FC_USMALL: 06835 safe_buffer_increment(pStubMsg, sizeof(UCHAR)); 06836 pStubMsg->MemorySize += sizeof(UCHAR); 06837 return sizeof(UCHAR); 06838 case RPC_FC_WCHAR: 06839 case RPC_FC_SHORT: 06840 case RPC_FC_USHORT: 06841 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 06842 safe_buffer_increment(pStubMsg, sizeof(USHORT)); 06843 align_length(&pStubMsg->MemorySize, sizeof(USHORT)); 06844 pStubMsg->MemorySize += sizeof(USHORT); 06845 return sizeof(USHORT); 06846 case RPC_FC_LONG: 06847 case RPC_FC_ULONG: 06848 case RPC_FC_ENUM32: 06849 align_pointer(&pStubMsg->Buffer, sizeof(ULONG)); 06850 safe_buffer_increment(pStubMsg, sizeof(ULONG)); 06851 align_length(&pStubMsg->MemorySize, sizeof(ULONG)); 06852 pStubMsg->MemorySize += sizeof(ULONG); 06853 return sizeof(ULONG); 06854 case RPC_FC_FLOAT: 06855 align_pointer(&pStubMsg->Buffer, sizeof(float)); 06856 safe_buffer_increment(pStubMsg, sizeof(float)); 06857 align_length(&pStubMsg->MemorySize, sizeof(float)); 06858 pStubMsg->MemorySize += sizeof(float); 06859 return sizeof(float); 06860 case RPC_FC_DOUBLE: 06861 align_pointer(&pStubMsg->Buffer, sizeof(double)); 06862 safe_buffer_increment(pStubMsg, sizeof(double)); 06863 align_length(&pStubMsg->MemorySize, sizeof(double)); 06864 pStubMsg->MemorySize += sizeof(double); 06865 return sizeof(double); 06866 case RPC_FC_HYPER: 06867 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG)); 06868 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG)); 06869 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG)); 06870 pStubMsg->MemorySize += sizeof(ULONGLONG); 06871 return sizeof(ULONGLONG); 06872 case RPC_FC_ERROR_STATUS_T: 06873 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t)); 06874 safe_buffer_increment(pStubMsg, sizeof(error_status_t)); 06875 align_length(&pStubMsg->MemorySize, sizeof(error_status_t)); 06876 pStubMsg->MemorySize += sizeof(error_status_t); 06877 return sizeof(error_status_t); 06878 case RPC_FC_ENUM16: 06879 align_pointer(&pStubMsg->Buffer, sizeof(USHORT)); 06880 safe_buffer_increment(pStubMsg, sizeof(USHORT)); 06881 align_length(&pStubMsg->MemorySize, sizeof(UINT)); 06882 pStubMsg->MemorySize += sizeof(UINT); 06883 return sizeof(UINT); 06884 case RPC_FC_INT3264: 06885 case RPC_FC_UINT3264: 06886 align_pointer(&pStubMsg->Buffer, sizeof(UINT)); 06887 safe_buffer_increment(pStubMsg, sizeof(UINT)); 06888 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR)); 06889 pStubMsg->MemorySize += sizeof(UINT_PTR); 06890 return sizeof(UINT_PTR); 06891 case RPC_FC_IGNORE: 06892 align_length(&pStubMsg->MemorySize, sizeof(void *)); 06893 pStubMsg->MemorySize += sizeof(void *); 06894 return sizeof(void *); 06895 default: 06896 FIXME("Unhandled base type: 0x%02x\n", *pFormat); 06897 return 0; 06898 } 06899 } 06900 06901 /*********************************************************************** 06902 * NdrBaseTypeFree [internal] 06903 */ 06904 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg, 06905 unsigned char *pMemory, 06906 PFORMAT_STRING pFormat) 06907 { 06908 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06909 06910 /* nothing to do */ 06911 } 06912 06913 /*********************************************************************** 06914 * NdrContextHandleBufferSize [internal] 06915 */ 06916 static void WINAPI NdrContextHandleBufferSize( 06917 PMIDL_STUB_MESSAGE pStubMsg, 06918 unsigned char *pMemory, 06919 PFORMAT_STRING pFormat) 06920 { 06921 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06922 06923 if (*pFormat != RPC_FC_BIND_CONTEXT) 06924 { 06925 ERR("invalid format type %x\n", *pFormat); 06926 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06927 } 06928 align_length(&pStubMsg->BufferLength, 4); 06929 safe_buffer_length_increment(pStubMsg, cbNDRContext); 06930 } 06931 06932 /*********************************************************************** 06933 * NdrContextHandleMarshall [internal] 06934 */ 06935 static unsigned char *WINAPI NdrContextHandleMarshall( 06936 PMIDL_STUB_MESSAGE pStubMsg, 06937 unsigned char *pMemory, 06938 PFORMAT_STRING pFormat) 06939 { 06940 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); 06941 06942 if (*pFormat != RPC_FC_BIND_CONTEXT) 06943 { 06944 ERR("invalid format type %x\n", *pFormat); 06945 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06946 } 06947 TRACE("flags: 0x%02x\n", pFormat[1]); 06948 06949 if (pStubMsg->IsClient) 06950 { 06951 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR) 06952 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE); 06953 else 06954 NdrClientContextMarshall(pStubMsg, pMemory, FALSE); 06955 } 06956 else 06957 { 06958 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory); 06959 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]]; 06960 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat); 06961 } 06962 06963 return NULL; 06964 } 06965 06966 /*********************************************************************** 06967 * NdrContextHandleUnmarshall [internal] 06968 */ 06969 static unsigned char *WINAPI NdrContextHandleUnmarshall( 06970 PMIDL_STUB_MESSAGE pStubMsg, 06971 unsigned char **ppMemory, 06972 PFORMAT_STRING pFormat, 06973 unsigned char fMustAlloc) 06974 { 06975 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg, 06976 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE"); 06977 06978 if (*pFormat != RPC_FC_BIND_CONTEXT) 06979 { 06980 ERR("invalid format type %x\n", *pFormat); 06981 RpcRaiseException(RPC_S_INTERNAL_ERROR); 06982 } 06983 TRACE("flags: 0x%02x\n", pFormat[1]); 06984 06985 if (pStubMsg->IsClient) 06986 { 06987 /* [out]-only or [ret] param */ 06988 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT) 06989 **(NDR_CCONTEXT **)ppMemory = NULL; 06990 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle); 06991 } 06992 else 06993 { 06994 NDR_SCONTEXT ctxt; 06995 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat); 06996 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR) 06997 *(void **)ppMemory = NDRSContextValue(ctxt); 06998 else 06999 *(void **)ppMemory = *NDRSContextValue(ctxt); 07000 } 07001 07002 return NULL; 07003 } 07004 07005 /*********************************************************************** 07006 * NdrClientContextMarshall [RPCRT4.@] 07007 */ 07008 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, 07009 NDR_CCONTEXT ContextHandle, 07010 int fCheck) 07011 { 07012 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck); 07013 07014 align_pointer_clear(&pStubMsg->Buffer, 4); 07015 07016 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 07017 { 07018 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 07019 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 07020 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07021 } 07022 07023 /* FIXME: what does fCheck do? */ 07024 NDRCContextMarshall(ContextHandle, 07025 pStubMsg->Buffer); 07026 07027 pStubMsg->Buffer += cbNDRContext; 07028 } 07029 07030 /*********************************************************************** 07031 * NdrClientContextUnmarshall [RPCRT4.@] 07032 */ 07033 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 07034 NDR_CCONTEXT * pContextHandle, 07035 RPC_BINDING_HANDLE BindHandle) 07036 { 07037 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle); 07038 07039 align_pointer(&pStubMsg->Buffer, 4); 07040 07041 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd) 07042 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07043 07044 NDRCContextUnmarshall(pContextHandle, 07045 BindHandle, 07046 pStubMsg->Buffer, 07047 pStubMsg->RpcMsg->DataRepresentation); 07048 07049 pStubMsg->Buffer += cbNDRContext; 07050 } 07051 07052 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, 07053 NDR_SCONTEXT ContextHandle, 07054 NDR_RUNDOWN RundownRoutine ) 07055 { 07056 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine); 07057 07058 align_pointer(&pStubMsg->Buffer, 4); 07059 07060 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 07061 { 07062 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 07063 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 07064 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07065 } 07066 07067 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, 07068 pStubMsg->Buffer, RundownRoutine, NULL, 07069 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS); 07070 pStubMsg->Buffer += cbNDRContext; 07071 } 07072 07073 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg) 07074 { 07075 NDR_SCONTEXT ContextHandle; 07076 07077 TRACE("(%p)\n", pStubMsg); 07078 07079 align_pointer(&pStubMsg->Buffer, 4); 07080 07081 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 07082 { 07083 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 07084 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 07085 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07086 } 07087 07088 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, 07089 pStubMsg->Buffer, 07090 pStubMsg->RpcMsg->DataRepresentation, 07091 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS); 07092 pStubMsg->Buffer += cbNDRContext; 07093 07094 return ContextHandle; 07095 } 07096 07097 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg, 07098 unsigned char* pMemory, 07099 PFORMAT_STRING pFormat) 07100 { 07101 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat); 07102 } 07103 07104 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, 07105 PFORMAT_STRING pFormat) 07106 { 07107 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 07108 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 07109 07110 TRACE("(%p, %p)\n", pStubMsg, pFormat); 07111 07112 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 07113 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 07114 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 07115 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 07116 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 07117 { 07118 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 07119 if_id = &sif->InterfaceId; 07120 } 07121 07122 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL, 07123 pStubMsg->RpcMsg->DataRepresentation, if_id, 07124 flags); 07125 } 07126 07127 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, 07128 NDR_SCONTEXT ContextHandle, 07129 NDR_RUNDOWN RundownRoutine, 07130 PFORMAT_STRING pFormat) 07131 { 07132 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 07133 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 07134 07135 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); 07136 07137 align_pointer(&pStubMsg->Buffer, 4); 07138 07139 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 07140 { 07141 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 07142 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 07143 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07144 } 07145 07146 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 07147 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 07148 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 07149 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 07150 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 07151 { 07152 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 07153 if_id = &sif->InterfaceId; 07154 } 07155 07156 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, 07157 pStubMsg->Buffer, RundownRoutine, if_id, flags); 07158 pStubMsg->Buffer += cbNDRContext; 07159 } 07160 07161 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 07162 PFORMAT_STRING pFormat) 07163 { 07164 NDR_SCONTEXT ContextHandle; 07165 RPC_SYNTAX_IDENTIFIER *if_id = NULL; 07166 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; 07167 07168 TRACE("(%p, %p)\n", pStubMsg, pFormat); 07169 07170 align_pointer(&pStubMsg->Buffer, 4); 07171 07172 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) 07173 { 07174 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", 07175 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); 07176 RpcRaiseException(RPC_X_BAD_STUB_DATA); 07177 } 07178 07179 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE) 07180 flags |= RPC_CONTEXT_HANDLE_SERIALIZE; 07181 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE) 07182 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE; 07183 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE) 07184 { 07185 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation; 07186 if_id = &sif->InterfaceId; 07187 } 07188 07189 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, 07190 pStubMsg->Buffer, 07191 pStubMsg->RpcMsg->DataRepresentation, 07192 if_id, flags); 07193 pStubMsg->Buffer += cbNDRContext; 07194 07195 return ContextHandle; 07196 } 07197 07198 /*********************************************************************** 07199 * NdrCorrelationInitialize [RPCRT4.@] 07200 * 07201 * Initializes correlation validity checking. 07202 * 07203 * PARAMS 07204 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 07205 * pMemory [I] Pointer to memory to use as a cache. 07206 * CacheSize [I] Size of the memory pointed to by pMemory. 07207 * Flags [I] Reserved. Set to zero. 07208 * 07209 * RETURNS 07210 * Nothing. 07211 */ 07212 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags) 07213 { 07214 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags); 07215 pStubMsg->fHasNewCorrDesc = TRUE; 07216 } 07217 07218 /*********************************************************************** 07219 * NdrCorrelationPass [RPCRT4.@] 07220 * 07221 * Performs correlation validity checking. 07222 * 07223 * PARAMS 07224 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 07225 * 07226 * RETURNS 07227 * Nothing. 07228 */ 07229 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg) 07230 { 07231 FIXME("(%p): stub\n", pStubMsg); 07232 } 07233 07234 /*********************************************************************** 07235 * NdrCorrelationFree [RPCRT4.@] 07236 * 07237 * Frees any resources used while unmarshalling parameters that need 07238 * correlation validity checking. 07239 * 07240 * PARAMS 07241 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling. 07242 * 07243 * RETURNS 07244 * Nothing. 07245 */ 07246 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg) 07247 { 07248 FIXME("(%p): stub\n", pStubMsg); 07249 } Generated on Mon May 28 2012 04:25:40 for ReactOS by
1.7.6.1
|