rpcrt4: Build the typelib proxy headers.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
57493dc224
commit
297d9cabb8
|
@ -197,7 +197,7 @@ static const struct thunk *allocate_block( unsigned int num )
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
|
BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
|
||||||
{
|
{
|
||||||
const void **entry = (const void **)(vtbl + 1);
|
const void **entry = (const void **)(vtbl + 1);
|
||||||
DWORD i, j;
|
DWORD i, j;
|
||||||
|
|
|
@ -61,5 +61,6 @@ extern const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl DECLSPEC_HIDDEN;
|
||||||
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
|
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
|
||||||
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) DECLSPEC_HIDDEN;
|
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) DECLSPEC_HIDDEN;
|
||||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) DECLSPEC_HIDDEN;
|
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) DECLSPEC_HIDDEN;
|
||||||
|
BOOL fill_stubless_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#endif /* __WINE_CPSF_H */
|
#endif /* __WINE_CPSF_H */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
#include "oaidl.h"
|
#include "oaidl.h"
|
||||||
|
#define USE_STUBLESS_PROXY
|
||||||
#include "rpcproxy.h"
|
#include "rpcproxy.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
|
@ -28,9 +29,62 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
|
static HRESULT build_format_strings(ITypeInfo *typeinfo, WORD funcs,
|
||||||
|
const unsigned char **type_ret, const unsigned char **proc_ret,
|
||||||
|
unsigned short **offset_ret)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common helper for Create{Proxy,Stub}FromTypeInfo(). */
|
||||||
|
static HRESULT get_iface_info(ITypeInfo *typeinfo, WORD *funcs, WORD *parentfuncs)
|
||||||
|
{
|
||||||
|
TYPEATTR *typeattr;
|
||||||
|
ITypeLib *typelib;
|
||||||
|
TLIBATTR *libattr;
|
||||||
|
SYSKIND syskind;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = ITypeLib_GetLibAttr(typelib, &libattr);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
ITypeLib_Release(typelib);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
syskind = libattr->syskind;
|
||||||
|
ITypeLib_ReleaseTLibAttr(typelib, libattr);
|
||||||
|
ITypeLib_Release(typelib);
|
||||||
|
|
||||||
|
hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
*funcs = typeattr->cFuncs;
|
||||||
|
*parentfuncs = typeattr->cbSizeVft / (syskind == SYS_WIN64 ? 8 : 4) - *funcs;
|
||||||
|
ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_stub_desc(MIDL_STUB_DESC *desc)
|
||||||
|
{
|
||||||
|
desc->pfnAllocate = NdrOleAllocate;
|
||||||
|
desc->pfnFree = NdrOleFree;
|
||||||
|
desc->Version = 0x50002;
|
||||||
|
/* type format string is initialized with proc format string and offset table */
|
||||||
|
}
|
||||||
|
|
||||||
struct typelib_proxy
|
struct typelib_proxy
|
||||||
{
|
{
|
||||||
StdProxyImpl proxy;
|
StdProxyImpl proxy;
|
||||||
|
IID iid;
|
||||||
|
MIDL_STUB_DESC stub_desc;
|
||||||
|
MIDL_STUBLESS_PROXY_INFO proxy_info;
|
||||||
|
CInterfaceProxyVtbl *proxy_vtbl;
|
||||||
|
unsigned short *offset_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ULONG WINAPI typelib_proxy_Release(IRpcProxyBuffer *iface)
|
static ULONG WINAPI typelib_proxy_Release(IRpcProxyBuffer *iface)
|
||||||
|
@ -42,6 +96,12 @@ static ULONG WINAPI typelib_proxy_Release(IRpcProxyBuffer *iface)
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
if (proxy->proxy.pChannel)
|
||||||
|
IRpcProxyBuffer_Disconnect(&proxy->proxy.IRpcProxyBuffer_iface);
|
||||||
|
heap_free((void *)proxy->stub_desc.pFormatTypes);
|
||||||
|
heap_free((void *)proxy->proxy_info.ProcFormatString);
|
||||||
|
heap_free(proxy->offset_table);
|
||||||
|
heap_free(proxy->proxy_vtbl);
|
||||||
heap_free(proxy);
|
heap_free(proxy);
|
||||||
}
|
}
|
||||||
return refcount;
|
return refcount;
|
||||||
|
@ -57,37 +117,81 @@ static const IRpcProxyBufferVtbl typelib_proxy_vtbl =
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT typelib_proxy_init(struct typelib_proxy *proxy, IUnknown *outer,
|
static HRESULT typelib_proxy_init(struct typelib_proxy *proxy, IUnknown *outer,
|
||||||
IRpcProxyBuffer **proxy_buffer, void **out)
|
ULONG count, IRpcProxyBuffer **proxy_buffer, void **out)
|
||||||
{
|
{
|
||||||
|
if (!fill_stubless_table((IUnknownVtbl *)proxy->proxy_vtbl->Vtbl, count))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (!outer) outer = (IUnknown *)&proxy->proxy;
|
if (!outer) outer = (IUnknown *)&proxy->proxy;
|
||||||
|
|
||||||
proxy->proxy.IRpcProxyBuffer_iface.lpVtbl = &typelib_proxy_vtbl;
|
proxy->proxy.IRpcProxyBuffer_iface.lpVtbl = &typelib_proxy_vtbl;
|
||||||
|
proxy->proxy.PVtbl = proxy->proxy_vtbl->Vtbl;
|
||||||
proxy->proxy.RefCount = 1;
|
proxy->proxy.RefCount = 1;
|
||||||
|
proxy->proxy.piid = proxy->proxy_vtbl->header.piid;
|
||||||
proxy->proxy.pUnkOuter = outer;
|
proxy->proxy.pUnkOuter = outer;
|
||||||
|
|
||||||
*proxy_buffer = &proxy->proxy.IRpcProxyBuffer_iface;
|
*proxy_buffer = &proxy->proxy.IRpcProxyBuffer_iface;
|
||||||
|
*out = &proxy->proxy.PVtbl;
|
||||||
|
IUnknown_AddRef((IUnknown *)*out);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
|
HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
|
||||||
REFIID iid, IRpcProxyBuffer **proxy_buffer, void **out)
|
REFIID iid, IRpcProxyBuffer **proxy_buffer, void **out)
|
||||||
{
|
{
|
||||||
struct typelib_proxy *proxy;
|
struct typelib_proxy *proxy;
|
||||||
|
WORD funcs, parentfuncs, i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("typeinfo %p, outer %p, iid %s, proxy %p, out %p.\n",
|
TRACE("typeinfo %p, outer %p, iid %s, proxy_buffer %p, out %p.\n",
|
||||||
typeinfo, outer, debugstr_guid(iid), proxy_buffer, out);
|
typeinfo, outer, debugstr_guid(iid), proxy_buffer, out);
|
||||||
|
|
||||||
|
hr = get_iface_info(typeinfo, &funcs, &parentfuncs);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
if (!(proxy = heap_alloc_zero(sizeof(*proxy))))
|
if (!(proxy = heap_alloc_zero(sizeof(*proxy))))
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate proxy object.\n");
|
ERR("Failed to allocate proxy object.\n");
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = typelib_proxy_init(proxy, outer, proxy_buffer, out);
|
init_stub_desc(&proxy->stub_desc);
|
||||||
if (FAILED(hr))
|
proxy->proxy_info.pStubDesc = &proxy->stub_desc;
|
||||||
|
|
||||||
|
proxy->proxy_vtbl = heap_alloc_zero(sizeof(proxy->proxy_vtbl->header) + (funcs + parentfuncs) * sizeof(void *));
|
||||||
|
if (!proxy->proxy_vtbl)
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate proxy vtbl.\n");
|
||||||
heap_free(proxy);
|
heap_free(proxy);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
proxy->proxy_vtbl->header.pStublessProxyInfo = &proxy->proxy_info;
|
||||||
|
proxy->iid = *iid;
|
||||||
|
proxy->proxy_vtbl->header.piid = &proxy->iid;
|
||||||
|
for (i = 0; i < funcs; i++)
|
||||||
|
proxy->proxy_vtbl->Vtbl[3 + i] = (void *)-1;
|
||||||
|
|
||||||
|
hr = build_format_strings(typeinfo, funcs, &proxy->stub_desc.pFormatTypes,
|
||||||
|
&proxy->proxy_info.ProcFormatString, &proxy->offset_table);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
heap_free(proxy->proxy_vtbl);
|
||||||
|
heap_free(proxy);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
proxy->proxy_info.FormatStringOffset = &proxy->offset_table[-3];
|
||||||
|
|
||||||
|
hr = typelib_proxy_init(proxy, outer, funcs + parentfuncs, proxy_buffer, out);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
heap_free((void *)proxy->stub_desc.pFormatTypes);
|
||||||
|
heap_free((void *)proxy->proxy_info.ProcFormatString);
|
||||||
|
heap_free((void *)proxy->offset_table);
|
||||||
|
heap_free(proxy->proxy_vtbl);
|
||||||
|
heap_free(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue