Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencproxy.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
1.7.6.1
|