ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ndr_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.