Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenndr_es.c
Go to the documentation of this file.
00001 /* 00002 * NDR Serialization Services 00003 * 00004 * Copyright (c) 2007 Robert Shearman for CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <stdarg.h> 00022 #include <stdio.h> 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winerror.h" 00027 #include "rpc.h" 00028 #include "midles.h" 00029 #include "ndrtypes.h" 00030 00031 #include "ndr_misc.h" 00032 #include "ndr_stubless.h" 00033 00034 #include "wine/debug.h" 00035 #include "wine/rpcfc.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00038 00039 static inline void init_MIDL_ES_MESSAGE(MIDL_ES_MESSAGE *pEsMsg) 00040 { 00041 memset(pEsMsg, 0, sizeof(*pEsMsg)); 00042 /* even if we are unmarshalling, as we don't want pointers to be pointed 00043 * to buffer memory */ 00044 pEsMsg->StubMsg.IsClient = TRUE; 00045 } 00046 00047 /*********************************************************************** 00048 * MesEncodeIncrementalHandleCreate [RPCRT4.@] 00049 */ 00050 RPC_STATUS WINAPI MesEncodeIncrementalHandleCreate( 00051 void *UserState, MIDL_ES_ALLOC AllocFn, MIDL_ES_WRITE WriteFn, 00052 handle_t *pHandle) 00053 { 00054 MIDL_ES_MESSAGE *pEsMsg; 00055 00056 TRACE("(%p, %p, %p, %p)\n", UserState, AllocFn, WriteFn, pHandle); 00057 00058 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 00059 if (!pEsMsg) 00060 return ERROR_OUTOFMEMORY; 00061 00062 init_MIDL_ES_MESSAGE(pEsMsg); 00063 00064 pEsMsg->Operation = MES_ENCODE; 00065 pEsMsg->UserState = UserState; 00066 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 00067 pEsMsg->Alloc = AllocFn; 00068 pEsMsg->Write = WriteFn; 00069 00070 *pHandle = (handle_t)pEsMsg; 00071 00072 return RPC_S_OK; 00073 } 00074 00075 /*********************************************************************** 00076 * MesDecodeIncrementalHandleCreate [RPCRT4.@] 00077 */ 00078 RPC_STATUS WINAPI MesDecodeIncrementalHandleCreate( 00079 void *UserState, MIDL_ES_READ ReadFn, handle_t *pHandle) 00080 { 00081 MIDL_ES_MESSAGE *pEsMsg; 00082 00083 TRACE("(%p, %p, %p)\n", UserState, ReadFn, pHandle); 00084 00085 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 00086 if (!pEsMsg) 00087 return ERROR_OUTOFMEMORY; 00088 00089 init_MIDL_ES_MESSAGE(pEsMsg); 00090 00091 pEsMsg->Operation = MES_DECODE; 00092 pEsMsg->UserState = UserState; 00093 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 00094 pEsMsg->Read = ReadFn; 00095 00096 *pHandle = (handle_t)pEsMsg; 00097 00098 return RPC_S_OK; 00099 } 00100 00101 /*********************************************************************** 00102 * MesIncrementalHandleReset [RPCRT4.@] 00103 */ 00104 RPC_STATUS WINAPI MesIncrementalHandleReset( 00105 handle_t Handle, void *UserState, MIDL_ES_ALLOC AllocFn, 00106 MIDL_ES_WRITE WriteFn, MIDL_ES_READ ReadFn, MIDL_ES_CODE Operation) 00107 { 00108 MIDL_ES_MESSAGE *pEsMsg = Handle; 00109 00110 TRACE("(%p, %p, %p, %p, %p, %d)\n", Handle, UserState, AllocFn, 00111 WriteFn, ReadFn, Operation); 00112 00113 init_MIDL_ES_MESSAGE(pEsMsg); 00114 00115 pEsMsg->Operation = Operation; 00116 pEsMsg->UserState = UserState; 00117 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 00118 pEsMsg->Alloc = AllocFn; 00119 pEsMsg->Write = WriteFn; 00120 pEsMsg->Read = ReadFn; 00121 00122 return RPC_S_OK; 00123 } 00124 00125 /*********************************************************************** 00126 * MesHandleFree [RPCRT4.@] 00127 */ 00128 RPC_STATUS WINAPI MesHandleFree(handle_t Handle) 00129 { 00130 TRACE("(%p)\n", Handle); 00131 HeapFree(GetProcessHeap(), 0, Handle); 00132 return RPC_S_OK; 00133 } 00134 00135 /*********************************************************************** 00136 * MesEncodeFixedBufferHandleCreate [RPCRT4.@] 00137 */ 00138 RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate( 00139 char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle) 00140 { 00141 MIDL_ES_MESSAGE *pEsMsg; 00142 00143 TRACE("(%p, %d, %p, %p)\n", Buffer, BufferSize, pEncodedSize, pHandle); 00144 00145 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 00146 if (!pEsMsg) 00147 return ERROR_OUTOFMEMORY; 00148 00149 init_MIDL_ES_MESSAGE(pEsMsg); 00150 00151 pEsMsg->Operation = MES_ENCODE; 00152 pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; 00153 pEsMsg->Buffer = (unsigned char *)Buffer; 00154 pEsMsg->BufferSize = BufferSize; 00155 pEsMsg->pEncodedSize = pEncodedSize; 00156 00157 *pHandle = (handle_t)pEsMsg; 00158 00159 return RPC_S_OK; 00160 } 00161 00162 /*********************************************************************** 00163 * MesEncodeDynBufferHandleCreate [RPCRT4.@] 00164 */ 00165 RPC_STATUS RPC_ENTRY MesEncodeDynBufferHandleCreate(char **ppBuffer, 00166 ULONG *pEncodedSize, handle_t *pHandle) 00167 { 00168 FIXME("%p %p %p stub\n", ppBuffer, pEncodedSize, pHandle); 00169 return RPC_S_OK; 00170 } 00171 00172 /*********************************************************************** 00173 * MesDecodeBufferHandleCreate [RPCRT4.@] 00174 */ 00175 RPC_STATUS RPC_ENTRY MesDecodeBufferHandleCreate( 00176 char *Buffer, ULONG BufferSize, handle_t *pHandle) 00177 { 00178 MIDL_ES_MESSAGE *pEsMsg; 00179 00180 TRACE("(%p, %d, %p)\n", Buffer, BufferSize, pHandle); 00181 00182 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 00183 if (!pEsMsg) 00184 return ERROR_OUTOFMEMORY; 00185 00186 init_MIDL_ES_MESSAGE(pEsMsg); 00187 00188 pEsMsg->Operation = MES_DECODE; 00189 pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; 00190 pEsMsg->Buffer = (unsigned char *)Buffer; 00191 pEsMsg->BufferSize = BufferSize; 00192 00193 *pHandle = (handle_t)pEsMsg; 00194 00195 return RPC_S_OK; 00196 } 00197 00198 static void es_data_alloc(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 00199 { 00200 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 00201 { 00202 unsigned int tmpsize = size; 00203 TRACE("%d with incremental handle\n", size); 00204 pEsMsg->Alloc(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); 00205 if (tmpsize < size) 00206 { 00207 ERR("not enough bytes allocated - requested %d, got %d\n", size, tmpsize); 00208 RpcRaiseException(ERROR_OUTOFMEMORY); 00209 } 00210 } 00211 else if (pEsMsg->HandleStyle == MES_FIXED_BUFFER_HANDLE) 00212 { 00213 TRACE("%d with fixed buffer handle\n", size); 00214 pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; 00215 } 00216 pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; 00217 } 00218 00219 static void es_data_read(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 00220 { 00221 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 00222 { 00223 unsigned int tmpsize = size; 00224 TRACE("%d from incremental handle\n", size); 00225 pEsMsg->Read(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); 00226 if (tmpsize < size) 00227 { 00228 ERR("not enough bytes read - requested %d, got %d\n", size, tmpsize); 00229 RpcRaiseException(ERROR_OUTOFMEMORY); 00230 } 00231 } 00232 else 00233 { 00234 TRACE("%d from fixed or dynamic buffer handle\n", size); 00235 /* FIXME: validate BufferSize? */ 00236 pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; 00237 pEsMsg->Buffer += size; 00238 pEsMsg->BufferSize -= size; 00239 } 00240 pEsMsg->StubMsg.BufferLength = size; 00241 pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; 00242 pEsMsg->StubMsg.BufferEnd = pEsMsg->StubMsg.Buffer + size; 00243 } 00244 00245 static void es_data_write(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 00246 { 00247 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 00248 { 00249 TRACE("%d to incremental handle\n", size); 00250 pEsMsg->Write(pEsMsg->UserState, (char *)pEsMsg->StubMsg.BufferStart, size); 00251 } 00252 else 00253 { 00254 TRACE("%d to dynamic or fixed buffer handle\n", size); 00255 *pEsMsg->pEncodedSize += size; 00256 } 00257 } 00258 00259 static inline ULONG mes_proc_header_buffer_size(void) 00260 { 00261 return 4 + 2*sizeof(RPC_SYNTAX_IDENTIFIER) + 12; 00262 } 00263 00264 static void mes_proc_header_marshal(MIDL_ES_MESSAGE *pEsMsg) 00265 { 00266 const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; 00267 *(WORD *)pEsMsg->StubMsg.Buffer = 0x0101; 00268 pEsMsg->StubMsg.Buffer += 2; 00269 *(WORD *)pEsMsg->StubMsg.Buffer = 0xcccc; 00270 pEsMsg->StubMsg.Buffer += 2; 00271 memcpy(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER)); 00272 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 00273 memcpy(pEsMsg->StubMsg.Buffer, &pEsMsg->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)); 00274 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 00275 *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ProcNumber; 00276 pEsMsg->StubMsg.Buffer += 4; 00277 *(DWORD *)pEsMsg->StubMsg.Buffer = 0x00000001; 00278 pEsMsg->StubMsg.Buffer += 4; 00279 *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ByteCount; 00280 pEsMsg->StubMsg.Buffer += 4; 00281 } 00282 00283 static void mes_proc_header_unmarshal(MIDL_ES_MESSAGE *pEsMsg) 00284 { 00285 const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; 00286 00287 es_data_read(pEsMsg, mes_proc_header_buffer_size()); 00288 00289 if (*(WORD *)pEsMsg->StubMsg.Buffer != 0x0101) 00290 { 00291 FIXME("unknown value at Buffer[0] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); 00292 RpcRaiseException(RPC_X_WRONG_ES_VERSION); 00293 } 00294 pEsMsg->StubMsg.Buffer += 2; 00295 if (*(WORD *)pEsMsg->StubMsg.Buffer != 0xcccc) 00296 FIXME("unknown value at Buffer[2] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); 00297 pEsMsg->StubMsg.Buffer += 2; 00298 if (memcmp(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER))) 00299 { 00300 const RPC_SYNTAX_IDENTIFIER *AlienTransferSyntax = (const RPC_SYNTAX_IDENTIFIER *)pEsMsg->StubMsg.Buffer; 00301 ERR("bad transfer syntax %s {%d.%d}\n", debugstr_guid(&AlienTransferSyntax->SyntaxGUID), 00302 AlienTransferSyntax->SyntaxVersion.MajorVersion, 00303 AlienTransferSyntax->SyntaxVersion.MinorVersion); 00304 RpcRaiseException(RPC_S_UNSUPPORTED_TRANS_SYN); 00305 } 00306 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 00307 memcpy(&pEsMsg->InterfaceId, pEsMsg->StubMsg.Buffer, sizeof(RPC_SYNTAX_IDENTIFIER)); 00308 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 00309 pEsMsg->ProcNumber = *(DWORD *)pEsMsg->StubMsg.Buffer; 00310 pEsMsg->StubMsg.Buffer += 4; 00311 if (*(DWORD *)pEsMsg->StubMsg.Buffer != 0x00000001) 00312 FIXME("unknown value 0x%08x, expected 0x00000001\n", *(DWORD *)pEsMsg->StubMsg.Buffer); 00313 pEsMsg->StubMsg.Buffer += 4; 00314 pEsMsg->ByteCount = *(DWORD *)pEsMsg->StubMsg.Buffer; 00315 pEsMsg->StubMsg.Buffer += 4; 00316 if (pEsMsg->ByteCount + mes_proc_header_buffer_size() < pEsMsg->ByteCount) 00317 RpcRaiseException(RPC_S_INVALID_BOUND); 00318 } 00319 00320 /*********************************************************************** 00321 * NdrMesProcEncodeDecode [RPCRT4.@] 00322 */ 00323 void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStubDesc, PFORMAT_STRING pFormat, ...) 00324 { 00325 /* pointer to start of stack where arguments start */ 00326 RPC_MESSAGE rpcMsg; 00327 MIDL_ES_MESSAGE *pEsMsg = Handle; 00328 /* size of stack */ 00329 unsigned short stack_size; 00330 /* header for procedure string */ 00331 const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; 00332 const RPC_CLIENT_INTERFACE *client_interface; 00333 __ms_va_list args; 00334 unsigned int number_of_params; 00335 ULONG_PTR arg_buffer[256]; 00336 00337 TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle, pStubDesc, pFormat); 00338 00339 /* Later NDR language versions probably won't be backwards compatible */ 00340 if (pStubDesc->Version > 0x50002) 00341 { 00342 FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); 00343 RpcRaiseException(RPC_X_WRONG_STUB_VERSION); 00344 } 00345 00346 client_interface = pStubDesc->RpcInterfaceInformation; 00347 pEsMsg->InterfaceId = client_interface->InterfaceId; 00348 00349 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) 00350 { 00351 const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; 00352 stack_size = pProcHeader->stack_size; 00353 pEsMsg->ProcNumber = pProcHeader->proc_num; 00354 pFormat += sizeof(NDR_PROC_HEADER_RPC); 00355 } 00356 else 00357 { 00358 stack_size = pProcHeader->stack_size; 00359 pEsMsg->ProcNumber = pProcHeader->proc_num; 00360 pFormat += sizeof(NDR_PROC_HEADER); 00361 } 00362 00363 if (pProcHeader->handle_type == RPC_FC_BIND_EXPLICIT) 00364 { 00365 switch (*pFormat) /* handle_type */ 00366 { 00367 case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ 00368 pFormat += sizeof(NDR_EHD_PRIMITIVE); 00369 break; 00370 case RPC_FC_BIND_GENERIC: /* explicit generic */ 00371 pFormat += sizeof(NDR_EHD_GENERIC); 00372 break; 00373 case RPC_FC_BIND_CONTEXT: /* explicit context */ 00374 pFormat += sizeof(NDR_EHD_CONTEXT); 00375 break; 00376 default: 00377 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); 00378 RpcRaiseException(RPC_X_BAD_STUB_DATA); 00379 } 00380 } 00381 00382 TRACE("stack size: 0x%x\n", stack_size); 00383 TRACE("proc num: %d\n", pEsMsg->ProcNumber); 00384 00385 memset(&rpcMsg, 0, sizeof(rpcMsg)); 00386 pEsMsg->StubMsg.RpcMsg = &rpcMsg; 00387 pEsMsg->StubMsg.StubDesc = pStubDesc; 00388 pEsMsg->StubMsg.pfnAllocate = pStubDesc->pfnAllocate; 00389 pEsMsg->StubMsg.pfnFree = pStubDesc->pfnFree; 00390 00391 /* create the full pointer translation tables, if requested */ 00392 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) 00393 pEsMsg->StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); 00394 00395 TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); 00396 TRACE("stubdesc version = 0x%x\n", pStubDesc->Version); 00397 TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); 00398 00399 /* needed for conformance of top-level objects */ 00400 __ms_va_start( args, pFormat ); 00401 pEsMsg->StubMsg.StackTop = va_arg( args, unsigned char * ); 00402 __ms_va_end( args ); 00403 00404 pFormat = convert_old_args( &pEsMsg->StubMsg, pFormat, stack_size, FALSE, 00405 arg_buffer, sizeof(arg_buffer), &number_of_params ); 00406 00407 switch (pEsMsg->Operation) 00408 { 00409 case MES_ENCODE: 00410 pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size(); 00411 00412 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_CALCSIZE, NULL, number_of_params, NULL ); 00413 00414 pEsMsg->ByteCount = pEsMsg->StubMsg.BufferLength - mes_proc_header_buffer_size(); 00415 es_data_alloc(pEsMsg, pEsMsg->StubMsg.BufferLength); 00416 00417 mes_proc_header_marshal(pEsMsg); 00418 00419 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_MARSHAL, NULL, number_of_params, NULL ); 00420 00421 es_data_write(pEsMsg, pEsMsg->ByteCount); 00422 break; 00423 case MES_DECODE: 00424 mes_proc_header_unmarshal(pEsMsg); 00425 00426 es_data_read(pEsMsg, pEsMsg->ByteCount); 00427 00428 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_UNMARSHAL, NULL, number_of_params, NULL ); 00429 break; 00430 default: 00431 RpcRaiseException(RPC_S_INTERNAL_ERROR); 00432 return; 00433 } 00434 /* free the full pointer translation tables */ 00435 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) 00436 NdrFullPointerXlatFree(pEsMsg->StubMsg.FullPtrXlatTables); 00437 } 00438 00439 void RPC_ENTRY NdrMesTypeDecode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 00440 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) 00441 { 00442 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 00443 } 00444 00445 void RPC_ENTRY NdrMesTypeEncode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 00446 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, const void *pObject) 00447 { 00448 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 00449 } 00450 00451 void RPC_ENTRY NdrMesTypeFree2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 00452 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) 00453 { 00454 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 00455 } Generated on Sat May 26 2012 04:24:34 for ReactOS by
1.7.6.1
|