Zebediah Figura : rpcrt4: Build the typelib stub headers.

Alexandre Julliard julliard at winehq.org
Thu Nov 8 14:47:26 CST 2018


Module: wine
Branch: master
Commit: ad3e8134ac66e4b1dae685b974f0b27010432336
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ad3e8134ac66e4b1dae685b974f0b27010432336

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sat Nov  3 18:07:16 2018 -0500

rpcrt4: Build the typelib stub headers.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/rpcrt4/ndr_typelib.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 2 deletions(-)

diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index 25c4183..aa54db2 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -199,35 +199,104 @@ HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
 struct typelib_stub
 {
     CStdStubBuffer stub;
+    IID iid;
+    MIDL_STUB_DESC stub_desc;
+    MIDL_SERVER_INFO server_info;
+    CInterfaceStubVtbl stub_vtbl;
+    unsigned short *offset_table;
 };
 
+static ULONG WINAPI typelib_stub_Release(IRpcStubBuffer *iface)
+{
+    struct typelib_stub *stub = CONTAINING_RECORD(iface, struct typelib_stub, stub);
+    ULONG refcount = InterlockedDecrement(&stub->stub.RefCount);
+
+    TRACE("(%p) decreasing refs to %d\n", stub, refcount);
+
+    if (!refcount)
+    {
+        /* test_Release shows that native doesn't call Disconnect here.
+           We'll leave it in for the time being. */
+        IRpcStubBuffer_Disconnect(iface);
+
+        heap_free((void *)stub->stub_desc.pFormatTypes);
+        heap_free((void *)stub->server_info.ProcString);
+        heap_free(stub->offset_table);
+        heap_free(stub);
+    }
+
+    return refcount;
+}
+
 static HRESULT typelib_stub_init(struct typelib_stub *stub, IUnknown *server,
         IRpcStubBuffer **stub_buffer)
 {
+    HRESULT hr;
+
+    hr = IUnknown_QueryInterface(server, stub->stub_vtbl.header.piid,
+            (void **)&stub->stub.pvServerObject);
+    if (FAILED(hr))
+    {
+        WARN("Failed to get interface %s, hr %#x.\n",
+                debugstr_guid(stub->stub_vtbl.header.piid), hr);
+        stub->stub.pvServerObject = server;
+        IUnknown_AddRef(server);
+    }
+
+    stub->stub.lpVtbl = &stub->stub_vtbl.Vtbl;
     stub->stub.RefCount = 1;
-    *stub_buffer = (IRpcStubBuffer *)&stub->stub;
 
-    return E_NOTIMPL;
+    *stub_buffer = (IRpcStubBuffer *)&stub->stub;
+    return S_OK;
 }
 
 HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
         IUnknown *server, IRpcStubBuffer **stub_buffer)
 {
     struct typelib_stub *stub;
+    WORD funcs, parentfuncs;
     HRESULT hr;
 
     TRACE("typeinfo %p, iid %s, server %p, stub_buffer %p.\n",
             typeinfo, debugstr_guid(iid), server, stub_buffer);
 
+    hr = get_iface_info(typeinfo, &funcs, &parentfuncs);
+    if (FAILED(hr))
+        return hr;
+
     if (!(stub = heap_alloc_zero(sizeof(*stub))))
     {
         ERR("Failed to allocate stub object.\n");
         return E_OUTOFMEMORY;
     }
 
+    init_stub_desc(&stub->stub_desc);
+    stub->server_info.pStubDesc = &stub->stub_desc;
+
+    hr = build_format_strings(typeinfo, funcs, &stub->stub_desc.pFormatTypes,
+            &stub->server_info.ProcString, &stub->offset_table);
+    if (FAILED(hr))
+    {
+        heap_free(stub);
+        return hr;
+    }
+    stub->server_info.FmtStringOffset = &stub->offset_table[-3];
+
+    stub->iid = *iid;
+    stub->stub_vtbl.header.piid = &stub->iid;
+    stub->stub_vtbl.header.pServerInfo = &stub->server_info;
+    stub->stub_vtbl.header.DispatchTableCount = funcs + parentfuncs;
+    stub->stub_vtbl.Vtbl = CStdStubBuffer_Vtbl;
+    stub->stub_vtbl.Vtbl.Release = typelib_stub_Release;
+
     hr = typelib_stub_init(stub, server, stub_buffer);
     if (FAILED(hr))
+    {
+        heap_free((void *)stub->stub_desc.pFormatTypes);
+        heap_free((void *)stub->server_info.ProcString);
+        heap_free(stub->offset_table);
         heap_free(stub);
+    }
 
     return hr;
 }




More information about the wine-cvs mailing list