diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index 92070ea2c33..ad67edf92eb 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ ndr_marshall.c \ ndr_ole.c \ ndr_stubless.c \ + ndr_typelib.c \ rpc_assoc.c \ rpc_async.c \ rpc_binding.c \ diff --git a/dlls/rpcrt4/cproxy.c b/dlls/rpcrt4/cproxy.c index 71ae5609290..7ca05e72483 100644 --- a/dlls/rpcrt4/cproxy.c +++ b/dlls/rpcrt4/cproxy.c @@ -42,21 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -/* I don't know what MS's std proxy structure looks like, - so this probably doesn't match, but that shouldn't matter */ -typedef struct { - IRpcProxyBuffer IRpcProxyBuffer_iface; - LPVOID *PVtbl; - LONG RefCount; - const IID* piid; - LPUNKNOWN pUnkOuter; - IUnknown *base_object; /* must be at offset 0x10 from PVtbl */ - IRpcProxyBuffer *base_proxy; - PCInterfaceName name; - LPPSFACTORYBUFFER pPSFactory; - LPRPCCHANNELBUFFER pChannel; -} StdProxyImpl; - static const IRpcProxyBufferVtbl StdProxy_Vtbl; static inline StdProxyImpl *impl_from_IRpcProxyBuffer(IRpcProxyBuffer *iface) @@ -296,9 +281,7 @@ HRESULT StdProxy_Construct(REFIID riid, return S_OK; } -static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface, - REFIID riid, - LPVOID *obj) +HRESULT WINAPI StdProxy_QueryInterface(IRpcProxyBuffer *iface, REFIID riid, void **obj) { StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface); TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); @@ -319,7 +302,7 @@ static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface, return E_NOINTERFACE; } -static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface) +ULONG WINAPI StdProxy_AddRef(IRpcProxyBuffer *iface) { StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface); TRACE("(%p)->AddRef()\n",This); @@ -349,8 +332,7 @@ static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface) return refs; } -static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, - LPRPCCHANNELBUFFER pChannel) +HRESULT WINAPI StdProxy_Connect(IRpcProxyBuffer *iface, IRpcChannelBuffer *pChannel) { StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface); TRACE("(%p)->Connect(%p)\n",This,pChannel); @@ -361,7 +343,7 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, return S_OK; } -static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) +void WINAPI StdProxy_Disconnect(IRpcProxyBuffer *iface) { StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface); TRACE("(%p)->Disconnect()\n",This); @@ -531,27 +513,6 @@ HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode) return HRESULT_FROM_WIN32(dwExceptionCode); } -HRESULT WINAPI -CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid, - LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv ) -{ - typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT); - HMODULE hUser32 = LoadLibraryA("user32"); - MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA"); - - FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv); - if (pMessageBoxA) - { - pMessageBoxA(NULL, - "The native implementation of OLEAUT32.DLL cannot be used " - "with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n", - "Wine: Unimplemented CreateProxyFromTypeInfo", - 0x10); - ExitProcess(1); - } - return E_NOTIMPL; -} - HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *pTypeInfo, REFIID riid, IUnknown *pUnkServer, IRpcStubBuffer **ppStub ) diff --git a/dlls/rpcrt4/cpsf.h b/dlls/rpcrt4/cpsf.h index 964fb4551fe..0ada0d16bb8 100644 --- a/dlls/rpcrt4/cpsf.h +++ b/dlls/rpcrt4/cpsf.h @@ -21,9 +21,29 @@ #ifndef __WINE_CPSF_H #define __WINE_CPSF_H +typedef struct +{ + IRpcProxyBuffer IRpcProxyBuffer_iface; + void **PVtbl; + LONG RefCount; + const IID *piid; + IUnknown *pUnkOuter; + /* offset of base_object from PVtbl must match assembly thunks; see + * fill_delegated_proxy_table() */ + IUnknown *base_object; + IRpcProxyBuffer *base_proxy; + PCInterfaceName name; + IPSFactoryBuffer *pPSFactory; + IRpcChannelBuffer *pChannel; +} StdProxyImpl; + HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo, int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppvObj) DECLSPEC_HIDDEN; +HRESULT WINAPI StdProxy_QueryInterface(IRpcProxyBuffer *iface, REFIID iid, void **obj) DECLSPEC_HIDDEN; +ULONG WINAPI StdProxy_AddRef(IRpcProxyBuffer *iface) DECLSPEC_HIDDEN; +HRESULT WINAPI StdProxy_Connect(IRpcProxyBuffer *iface, IRpcChannelBuffer *channel) DECLSPEC_HIDDEN; +void WINAPI StdProxy_Disconnect(IRpcProxyBuffer *iface) DECLSPEC_HIDDEN; HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory, diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c new file mode 100644 index 00000000000..13075ac571a --- /dev/null +++ b/dlls/rpcrt4/ndr_typelib.c @@ -0,0 +1,93 @@ +/* + * Type library proxy/stub implementation + * + * Copyright 2018 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#include "oaidl.h" +#include "rpcproxy.h" +#include "wine/debug.h" +#include "wine/heap.h" + +#include "cpsf.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +struct typelib_proxy +{ + StdProxyImpl proxy; +}; + +static ULONG WINAPI typelib_proxy_Release(IRpcProxyBuffer *iface) +{ + struct typelib_proxy *proxy = CONTAINING_RECORD(iface, struct typelib_proxy, proxy.IRpcProxyBuffer_iface); + ULONG refcount = InterlockedDecrement(&proxy->proxy.RefCount); + + TRACE("(%p) decreasing refs to %d\n", proxy, refcount); + + if (!refcount) + { + heap_free(proxy); + } + return refcount; +} + +static const IRpcProxyBufferVtbl typelib_proxy_vtbl = +{ + StdProxy_QueryInterface, + StdProxy_AddRef, + typelib_proxy_Release, + StdProxy_Connect, + StdProxy_Disconnect, +}; + +static HRESULT typelib_proxy_init(struct typelib_proxy *proxy, IUnknown *outer, + IRpcProxyBuffer **proxy_buffer, void **out) +{ + if (!outer) outer = (IUnknown *)&proxy->proxy; + + proxy->proxy.IRpcProxyBuffer_iface.lpVtbl = &typelib_proxy_vtbl; + proxy->proxy.RefCount = 1; + proxy->proxy.pUnkOuter = outer; + + *proxy_buffer = &proxy->proxy.IRpcProxyBuffer_iface; + + return E_NOTIMPL; +} + +HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer, + REFIID iid, IRpcProxyBuffer **proxy_buffer, void **out) +{ + struct typelib_proxy *proxy; + HRESULT hr; + + TRACE("typeinfo %p, outer %p, iid %s, proxy %p, out %p.\n", + typeinfo, outer, debugstr_guid(iid), proxy_buffer, out); + + if (!(proxy = heap_alloc_zero(sizeof(*proxy)))) + { + ERR("Failed to allocate proxy object.\n"); + return E_OUTOFMEMORY; + } + + hr = typelib_proxy_init(proxy, outer, proxy_buffer, out); + if (FAILED(hr)) + heap_free(proxy); + + return hr; +}