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