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

cproxy.c
Go to the documentation of this file.
00001 /*
00002  * COM proxy implementation
00003  *
00004  * Copyright 2001 Ove Kåven, TransGaming Technologies
00005  * Copyright 2009 Alexandre Julliard
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: Handle non-i386 architectures
00022  */
00023 
00024 #include "config.h"
00025 #include "wine/port.h"
00026 
00027 #include <stdarg.h>
00028 
00029 #define COBJMACROS
00030 
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "winerror.h"
00034 
00035 #include "objbase.h"
00036 #include "rpcproxy.h"
00037 
00038 #include "cpsf.h"
00039 #include "ndr_misc.h"
00040 #include "ndr_stubless.h"
00041 #include "wine/debug.h"
00042 
00043 WINE_DEFAULT_DEBUG_CHANNEL(ole);
00044 
00045 /* I don't know what MS's std proxy structure looks like,
00046    so this probably doesn't match, but that shouldn't matter */
00047 typedef struct {
00048   IRpcProxyBuffer IRpcProxyBuffer_iface;
00049   LPVOID *PVtbl;
00050   LONG RefCount;
00051   const IID* piid;
00052   LPUNKNOWN pUnkOuter;
00053   IUnknown *base_object;  /* must be at offset 0x10 from PVtbl */
00054   IRpcProxyBuffer *base_proxy;
00055   PCInterfaceName name;
00056   LPPSFACTORYBUFFER pPSFactory;
00057   LPRPCCHANNELBUFFER pChannel;
00058 } StdProxyImpl;
00059 
00060 static const IRpcProxyBufferVtbl StdProxy_Vtbl;
00061 
00062 static inline StdProxyImpl *impl_from_IRpcProxyBuffer(IRpcProxyBuffer *iface)
00063 {
00064     return CONTAINING_RECORD(iface, StdProxyImpl, IRpcProxyBuffer_iface);
00065 }
00066 
00067 static inline StdProxyImpl *impl_from_proxy_obj( void *iface )
00068 {
00069     return CONTAINING_RECORD(iface, StdProxyImpl, PVtbl);
00070 }
00071 
00072 #ifdef __i386__
00073 
00074 extern void call_stubless_func(void);
00075 __ASM_GLOBAL_FUNC(call_stubless_func,
00076                   "movl 4(%esp),%ecx\n\t"         /* This pointer */
00077                   "movl (%ecx),%ecx\n\t"          /* This->lpVtbl */
00078                   "movl -8(%ecx),%ecx\n\t"        /* MIDL_STUBLESS_PROXY_INFO */
00079                   "movl 8(%ecx),%edx\n\t"         /* info->FormatStringOffset */
00080                   "movzwl (%edx,%eax,2),%edx\n\t" /* FormatStringOffset[index] */
00081                   "addl 4(%ecx),%edx\n\t"         /* info->ProcFormatString + offset */
00082                   "movzwl 8(%edx),%eax\n\t"       /* arguments size */
00083                   "pushl %eax\n\t"
00084                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
00085                   "leal 8(%esp),%eax\n\t"         /* &This */
00086                   "pushl %eax\n\t"
00087                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
00088                   "pushl %edx\n\t"                /* format string */
00089                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
00090                   "pushl (%ecx)\n\t"              /* info->pStubDesc */
00091                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
00092                   "call " __ASM_NAME("ndr_client_call") "\n\t"
00093                   "leal 12(%esp),%esp\n\t"
00094                   __ASM_CFI(".cfi_adjust_cfa_offset -12\n\t")
00095                   "popl %edx\n\t"                 /* arguments size */
00096                   __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
00097                   "movl (%esp),%ecx\n\t"  /* return address */
00098                   "addl %edx,%esp\n\t"
00099                   "jmp *%ecx" );
00100 
00101 #include "pshpack1.h"
00102 struct thunk
00103 {
00104   BYTE mov_eax;
00105   DWORD index;
00106   BYTE jmp;
00107   LONG handler;
00108 };
00109 #include "poppack.h"
00110 
00111 static inline void init_thunk( struct thunk *thunk, unsigned int index )
00112 {
00113     thunk->mov_eax = 0xb8; /* movl $n,%eax */
00114     thunk->index   = index;
00115     thunk->jmp     = 0xe9; /* jmp */
00116     thunk->handler = (char *)call_stubless_func - (char *)(&thunk->handler + 1);
00117 }
00118 
00119 #elif defined(__x86_64__)
00120 
00121 extern void call_stubless_func(void);
00122 __ASM_GLOBAL_FUNC(call_stubless_func,
00123                   "movq %rcx,0x8(%rsp)\n\t"
00124                   "movq %rdx,0x10(%rsp)\n\t"
00125                   "movq %r8,0x18(%rsp)\n\t"
00126                   "movq %r9,0x20(%rsp)\n\t"
00127                   "leaq 0x8(%rsp),%r8\n\t"        /* &This */
00128                   "movq (%rcx),%rcx\n\t"          /* This->lpVtbl */
00129                   "movq -0x10(%rcx),%rcx\n\t"     /* MIDL_STUBLESS_PROXY_INFO */
00130                   "movq 0x10(%rcx),%rdx\n\t"      /* info->FormatStringOffset */
00131                   "movzwq (%rdx,%r10,2),%rdx\n\t" /* FormatStringOffset[index] */
00132                   "addq 8(%rcx),%rdx\n\t"         /* info->ProcFormatString + offset */
00133                   "movq (%rcx),%rcx\n\t"          /* info->pStubDesc */
00134                   "subq $0x38,%rsp\n\t"
00135                   __ASM_CFI(".cfi_adjust_cfa_offset 0x38\n\t")
00136                   "movq %xmm1,0x20(%rsp)\n\t"
00137                   "movq %xmm2,0x28(%rsp)\n\t"
00138                   "movq %xmm3,0x30(%rsp)\n\t"
00139                   "leaq 0x18(%rsp),%r9\n\t"       /* fpu_args */
00140                   "call " __ASM_NAME("ndr_client_call") "\n\t"
00141                   "addq $0x38,%rsp\n\t"
00142                   __ASM_CFI(".cfi_adjust_cfa_offset -0x38\n\t")
00143                   "ret" );
00144 
00145 #include "pshpack1.h"
00146 struct thunk
00147 {
00148     BYTE mov_r10[3];
00149     DWORD index;
00150     BYTE mov_rax[2];
00151     void *call_stubless;
00152     BYTE jmp_rax[2];
00153 };
00154 #include "poppack.h"
00155 
00156 static const struct thunk thunk_template =
00157 {
00158     { 0x49, 0xc7, 0xc2 }, 0,  /* movq $index,%r10 */
00159     { 0x48, 0xb8 }, 0,        /* movq $call_stubless_func,%rax */
00160     { 0xff, 0xe0 }            /* jmp *%rax */
00161 };
00162 
00163 static inline void init_thunk( struct thunk *thunk, unsigned int index )
00164 {
00165     *thunk = thunk_template;
00166     thunk->index = index;
00167     thunk->call_stubless = call_stubless_func;
00168 }
00169 
00170 #else  /* __i386__ */
00171 
00172 #warning You must implement stubless proxies for your CPU
00173 
00174 struct thunk
00175 {
00176   DWORD index;
00177 };
00178 
00179 static inline void init_thunk( struct thunk *thunk, unsigned int index )
00180 {
00181     thunk->index = index;
00182 }
00183 
00184 #endif  /* __i386__ */
00185 
00186 #define BLOCK_SIZE 1024
00187 #define MAX_BLOCKS 64  /* 64k methods should be enough for anybody */
00188 
00189 static const struct thunk *method_blocks[MAX_BLOCKS];
00190 
00191 static const struct thunk *allocate_block( unsigned int num )
00192 {
00193     unsigned int i;
00194     struct thunk *prev, *block;
00195 
00196     block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block),
00197                           MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
00198     if (!block) return NULL;
00199 
00200     for (i = 0; i < BLOCK_SIZE; i++) init_thunk( &block[i], BLOCK_SIZE * num + i + 3 );
00201     VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL );
00202     prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
00203     if (prev) /* someone beat us to it */
00204     {
00205         VirtualFree( block, 0, MEM_RELEASE );
00206         block = prev;
00207     }
00208     return block;
00209 }
00210 
00211 static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
00212 {
00213     const void **entry = (const void **)(vtbl + 1);
00214     DWORD i, j;
00215 
00216     if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
00217     {
00218         FIXME( "%u methods not supported\n", num );
00219         return FALSE;
00220     }
00221     for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
00222     {
00223         const struct thunk *block = method_blocks[i];
00224         if (!block && !(block = allocate_block( i ))) return FALSE;
00225         for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++)
00226             if (*entry == (LPVOID)-1) *entry = &block[j];
00227     }
00228     return TRUE;
00229 }
00230 
00231 HRESULT StdProxy_Construct(REFIID riid,
00232                            LPUNKNOWN pUnkOuter,
00233                            const ProxyFileInfo *ProxyInfo,
00234                            int Index,
00235                            LPPSFACTORYBUFFER pPSFactory,
00236                            LPRPCPROXYBUFFER *ppProxy,
00237                            LPVOID *ppvObj)
00238 {
00239   StdProxyImpl *This;
00240   PCInterfaceName name = ProxyInfo->pNamesArray[Index];
00241   CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index];
00242 
00243   TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name);
00244 
00245   /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */
00246   if (ProxyInfo->TableVersion > 1) {
00247     ULONG count = ProxyInfo->pStubVtblList[Index]->header.DispatchTableCount;
00248     vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1);
00249     TRACE("stubless vtbl %p: count=%d\n", vtbl->Vtbl, count );
00250     fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count );
00251   }
00252 
00253   if (!IsEqualGUID(vtbl->header.piid, riid)) {
00254     ERR("IID mismatch during proxy creation\n");
00255     return RPC_E_UNEXPECTED;
00256   }
00257 
00258   This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl));
00259   if (!This) return E_OUTOFMEMORY;
00260 
00261   if (!pUnkOuter) pUnkOuter = (IUnknown *)This;
00262   This->IRpcProxyBuffer_iface.lpVtbl = &StdProxy_Vtbl;
00263   This->PVtbl = vtbl->Vtbl;
00264   /* one reference for the proxy */
00265   This->RefCount = 1;
00266   This->piid = vtbl->header.piid;
00267   This->base_object = NULL;
00268   This->base_proxy = NULL;
00269   This->pUnkOuter = pUnkOuter;
00270   This->name = name;
00271   This->pPSFactory = pPSFactory;
00272   This->pChannel = NULL;
00273 
00274   if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
00275   {
00276       HRESULT r = create_proxy( ProxyInfo->pDelegatedIIDs[Index], NULL,
00277                                 &This->base_proxy, (void **)&This->base_object );
00278       if (FAILED(r))
00279       {
00280           HeapFree( GetProcessHeap(), 0, This );
00281           return r;
00282       }
00283   }
00284 
00285   *ppProxy = &This->IRpcProxyBuffer_iface;
00286   *ppvObj = &This->PVtbl;
00287   IUnknown_AddRef((IUnknown *)*ppvObj);
00288   IPSFactoryBuffer_AddRef(pPSFactory);
00289 
00290   TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n",
00291          debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object );
00292   return S_OK;
00293 }
00294 
00295 static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
00296                                              REFIID riid,
00297                                              LPVOID *obj)
00298 {
00299   StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
00300   TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
00301 
00302   if (IsEqualGUID(&IID_IUnknown,riid) ||
00303       IsEqualGUID(This->piid,riid)) {
00304     *obj = &This->PVtbl;
00305     InterlockedIncrement(&This->RefCount);
00306     return S_OK;
00307   }
00308 
00309   if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
00310     *obj = &This->IRpcProxyBuffer_iface;
00311     InterlockedIncrement(&This->RefCount);
00312     return S_OK;
00313   }
00314 
00315   return E_NOINTERFACE;
00316 }
00317 
00318 static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
00319 {
00320   StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
00321   TRACE("(%p)->AddRef()\n",This);
00322 
00323   return InterlockedIncrement(&This->RefCount);
00324 }
00325 
00326 static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
00327 {
00328   ULONG refs;
00329   StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
00330   TRACE("(%p)->Release()\n",This);
00331 
00332   refs = InterlockedDecrement(&This->RefCount);
00333   if (!refs)
00334   {
00335     if (This->pChannel)
00336       IRpcProxyBuffer_Disconnect(&This->IRpcProxyBuffer_iface);
00337 
00338     if (This->base_object) IUnknown_Release( This->base_object );
00339     if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy );
00340 
00341     IPSFactoryBuffer_Release(This->pPSFactory);
00342     HeapFree(GetProcessHeap(),0,This);
00343   }
00344 
00345   return refs;
00346 }
00347 
00348 static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
00349                                       LPRPCCHANNELBUFFER pChannel)
00350 {
00351   StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
00352   TRACE("(%p)->Connect(%p)\n",This,pChannel);
00353 
00354   This->pChannel = pChannel;
00355   IRpcChannelBuffer_AddRef(pChannel);
00356   if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel );
00357   return S_OK;
00358 }
00359 
00360 static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface)
00361 {
00362   StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
00363   TRACE("(%p)->Disconnect()\n",This);
00364 
00365   if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy );
00366 
00367   IRpcChannelBuffer_Release(This->pChannel);
00368   This->pChannel = NULL;
00369 }
00370 
00371 static const IRpcProxyBufferVtbl StdProxy_Vtbl =
00372 {
00373   StdProxy_QueryInterface,
00374   StdProxy_AddRef,
00375   StdProxy_Release,
00376   StdProxy_Connect,
00377   StdProxy_Disconnect
00378 };
00379 
00380 static void StdProxy_GetChannel(LPVOID iface,
00381                                    LPRPCCHANNELBUFFER *ppChannel)
00382 {
00383   StdProxyImpl *This = impl_from_proxy_obj( iface );
00384   TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
00385 
00386   *ppChannel = This->pChannel;
00387 }
00388 
00389 static void StdProxy_GetIID(LPVOID iface,
00390                                const IID **ppiid)
00391 {
00392   StdProxyImpl *This = impl_from_proxy_obj( iface );
00393   TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
00394 
00395   *ppiid = This->piid;
00396 }
00397 
00398 HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface,
00399                                             REFIID riid,
00400                                             LPVOID *ppvObj)
00401 {
00402   StdProxyImpl *This = impl_from_proxy_obj( iface );
00403   TRACE("(%p)->QueryInterface(%s,%p) %s\n",This,debugstr_guid(riid),ppvObj,This->name);
00404   return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj);
00405 }
00406 
00407 ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface)
00408 {
00409   StdProxyImpl *This = impl_from_proxy_obj( iface );
00410   TRACE("(%p)->AddRef() %s\n",This,This->name);
00411   return IUnknown_AddRef(This->pUnkOuter);
00412 }
00413 
00414 ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface)
00415 {
00416   StdProxyImpl *This = impl_from_proxy_obj( iface );
00417   TRACE("(%p)->Release() %s\n",This,This->name);
00418   return IUnknown_Release(This->pUnkOuter);
00419 }
00420 
00421 /***********************************************************************
00422  *           NdrProxyInitialize [RPCRT4.@]
00423  */
00424 void WINAPI NdrProxyInitialize(void *This,
00425                               PRPC_MESSAGE pRpcMsg,
00426                               PMIDL_STUB_MESSAGE pStubMsg,
00427                               PMIDL_STUB_DESC pStubDescriptor,
00428                               unsigned int ProcNum)
00429 {
00430   TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
00431   NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
00432   StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
00433   IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
00434                                &pStubMsg->dwDestContext,
00435                                &pStubMsg->pvDestContext);
00436   TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
00437 }
00438 
00439 /***********************************************************************
00440  *           NdrProxyGetBuffer [RPCRT4.@]
00441  */
00442 void WINAPI NdrProxyGetBuffer(void *This,
00443                              PMIDL_STUB_MESSAGE pStubMsg)
00444 {
00445   HRESULT hr;
00446   const IID *riid = NULL;
00447 
00448   TRACE("(%p,%p)\n", This, pStubMsg);
00449   pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
00450   pStubMsg->dwStubPhase = PROXY_GETBUFFER;
00451   StdProxy_GetIID(This, &riid);
00452   hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
00453                                   (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
00454                                   riid);
00455   if (FAILED(hr))
00456   {
00457     RpcRaiseException(hr);
00458     return;
00459   }
00460   pStubMsg->fBufferValid = TRUE;
00461   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
00462   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
00463   pStubMsg->Buffer = pStubMsg->BufferStart;
00464   pStubMsg->dwStubPhase = PROXY_MARSHAL;
00465 }
00466 
00467 /***********************************************************************
00468  *           NdrProxySendReceive [RPCRT4.@]
00469  */
00470 void WINAPI NdrProxySendReceive(void *This,
00471                                PMIDL_STUB_MESSAGE pStubMsg)
00472 {
00473   ULONG Status = 0;
00474   HRESULT hr;
00475 
00476   TRACE("(%p,%p)\n", This, pStubMsg);
00477 
00478   if (!pStubMsg->pRpcChannelBuffer)
00479   {
00480     WARN("Trying to use disconnected proxy %p\n", This);
00481     RpcRaiseException(RPC_E_DISCONNECTED);
00482   }
00483 
00484   pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
00485   /* avoid sending uninitialised parts of the buffer on the wire */
00486   pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
00487   hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
00488                                     (RPCOLEMESSAGE*)pStubMsg->RpcMsg,
00489                                     &Status);
00490   pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
00491   pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
00492   pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
00493   pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
00494   pStubMsg->Buffer = pStubMsg->BufferStart;
00495 
00496   /* raise exception if call failed */
00497   if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
00498   else if (FAILED(hr)) RpcRaiseException(hr);
00499 }
00500 
00501 /***********************************************************************
00502  *           NdrProxyFreeBuffer [RPCRT4.@]
00503  */
00504 void WINAPI NdrProxyFreeBuffer(void *This,
00505                               PMIDL_STUB_MESSAGE pStubMsg)
00506 {
00507   TRACE("(%p,%p)\n", This, pStubMsg);
00508 
00509   if (pStubMsg->fBufferValid)
00510   {
00511     IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
00512                                  (RPCOLEMESSAGE*)pStubMsg->RpcMsg);
00513     pStubMsg->fBufferValid = TRUE;
00514   }
00515 }
00516 
00517 /***********************************************************************
00518  *           NdrProxyErrorHandler [RPCRT4.@]
00519  */
00520 HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
00521 {
00522   WARN("(0x%08x): a proxy call failed\n", dwExceptionCode);
00523 
00524   if (FAILED(dwExceptionCode))
00525     return dwExceptionCode;
00526   else
00527     return HRESULT_FROM_WIN32(dwExceptionCode);
00528 }
00529 
00530 HRESULT WINAPI
00531 CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid,
00532                          LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv )
00533 {
00534     typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
00535     HMODULE hUser32 = LoadLibraryA("user32");
00536     MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA");
00537 
00538     FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv);
00539     if (pMessageBoxA)
00540     {
00541         pMessageBoxA(NULL,
00542             "The native implementation of OLEAUT32.DLL cannot be used "
00543             "with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n",
00544             "Wine: Unimplemented CreateProxyFromTypeInfo",
00545             0x10);
00546         ExitProcess(1);
00547     }
00548     return E_NOTIMPL;
00549 }
00550 
00551 HRESULT WINAPI
00552 CreateStubFromTypeInfo(ITypeInfo *pTypeInfo, REFIID riid, IUnknown *pUnkServer,
00553                        IRpcStubBuffer **ppStub )
00554 {
00555     typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
00556     HMODULE hUser32 = LoadLibraryA("user32");
00557     MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA");
00558 
00559     FIXME("%p %s %p %p\n", pTypeInfo, debugstr_guid(riid), pUnkServer, ppStub);
00560     if (pMessageBoxA)
00561     {
00562         pMessageBoxA(NULL,
00563             "The native implementation of OLEAUT32.DLL cannot be used "
00564             "with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n",
00565             "Wine: Unimplemented CreateProxyFromTypeInfo",
00566             0x10);
00567         ExitProcess(1);
00568     }
00569     return E_NOTIMPL;
00570 }

Generated on Sat May 26 2012 04:24:33 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.