[PATCH 03/14] rpcrt4: Build the typelib proxy headers.

Zebediah Figura z.figura12 at gmail.com
Sat Nov 3 18:07:15 CDT 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/rpcrt4/cproxy.c      |   2 +-
 dlls/rpcrt4/cpsf.h        |   1 +
 dlls/rpcrt4/ndr_typelib.c | 112 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/dlls/rpcrt4/cproxy.c b/dlls/rpcrt4/cproxy.c
index 6f15ed564d..ab24b816a3 100644
--- a/dlls/rpcrt4/cproxy.c
+++ b/dlls/rpcrt4/cproxy.c
@@ -197,7 +197,7 @@ static const struct thunk *allocate_block( unsigned int num )
     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);
     DWORD i, j;
diff --git a/dlls/rpcrt4/cpsf.h b/dlls/rpcrt4/cpsf.h
index 0ada0d16bb..c8980e526d 100644
--- a/dlls/rpcrt4/cpsf.h
+++ b/dlls/rpcrt4/cpsf.h
@@ -61,5 +61,6 @@ extern const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl 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_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) DECLSPEC_HIDDEN;
+BOOL fill_stubless_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
 
 #endif  /* __WINE_CPSF_H */
diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index c0db6b78ff..25c4183ab4 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -20,6 +20,7 @@
 
 #define COBJMACROS
 #include "oaidl.h"
+#define USE_STUBLESS_PROXY
 #include "rpcproxy.h"
 #include "wine/debug.h"
 #include "wine/heap.h"
@@ -28,9 +29,62 @@
 
 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
 {
     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)
@@ -42,6 +96,12 @@ static ULONG WINAPI typelib_proxy_Release(IRpcProxyBuffer *iface)
 
     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);
     }
     return refcount;
@@ -57,37 +117,81 @@ static const IRpcProxyBufferVtbl typelib_proxy_vtbl =
 };
 
 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;
 
     proxy->proxy.IRpcProxyBuffer_iface.lpVtbl = &typelib_proxy_vtbl;
+    proxy->proxy.PVtbl = proxy->proxy_vtbl->Vtbl;
     proxy->proxy.RefCount = 1;
+    proxy->proxy.piid = proxy->proxy_vtbl->header.piid;
     proxy->proxy.pUnkOuter = outer;
 
     *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,
         REFIID iid, IRpcProxyBuffer **proxy_buffer, void **out)
 {
     struct typelib_proxy *proxy;
+    WORD funcs, parentfuncs, i;
     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);
 
+    hr = get_iface_info(typeinfo, &funcs, &parentfuncs);
+    if (FAILED(hr))
+        return hr;
+
     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);
+    init_stub_desc(&proxy->stub_desc);
+    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);
+        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;
 }
-- 
2.19.1




More information about the wine-devel mailing list