oleaut32: Unify the typelib and dispatch proxy/stub factories.
Both seem to be able to handle either kind of interface on Windows.
f72f8e5c4
was not enough, since the IDispatch proxy/stub factory
delegates to the typelib proxy/stub factory if the IID is not
IDispatch.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a6ca2001eb
commit
968eda4b18
|
@ -923,7 +923,7 @@ static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo)
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
|
||||
static HRESULT WINAPI dispatch_typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
|
||||
{
|
||||
if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid, &IID_IUnknown))
|
||||
{
|
||||
|
@ -936,136 +936,122 @@ static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface)
|
||||
static ULONG WINAPI dispatch_typelib_ps_AddRef(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface)
|
||||
static ULONG WINAPI dispatch_typelib_ps_Release(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
|
||||
static HRESULT dispatch_create_proxy(IUnknown *outer, IRpcProxyBuffer **proxy, void **out)
|
||||
{
|
||||
IPSFactoryBuffer *factory;
|
||||
HRESULT hr;
|
||||
|
||||
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = IPSFactoryBuffer_CreateProxy(factory, outer, &IID_IDispatch, proxy, out);
|
||||
IPSFactoryBuffer_Release(factory);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dispatch_typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
|
||||
IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
|
||||
{
|
||||
ITypeInfo *typeinfo;
|
||||
TYPEATTR *attr;
|
||||
HRESULT hr;
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IDispatch))
|
||||
return dispatch_create_proxy(outer, proxy, out);
|
||||
|
||||
hr = get_typeinfo_for_iid(iid, &typeinfo);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
|
||||
hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ITypeInfo_Release(typeinfo);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (attr->typekind == TKIND_INTERFACE || (attr->wTypeFlags & TYPEFLAG_FDUAL))
|
||||
hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
|
||||
else
|
||||
hr = dispatch_create_proxy(outer, proxy, out);
|
||||
|
||||
if (FAILED(hr))
|
||||
ERR("Failed to create proxy, hr %#x.\n", hr);
|
||||
|
||||
ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
|
||||
ITypeInfo_Release(typeinfo);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid,
|
||||
IUnknown *server, IRpcStubBuffer **stub)
|
||||
static HRESULT dispatch_create_stub(IUnknown *server, IRpcStubBuffer **stub)
|
||||
{
|
||||
IPSFactoryBuffer *factory;
|
||||
HRESULT hr;
|
||||
|
||||
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = IPSFactoryBuffer_CreateStub(factory, &IID_IDispatch, server, stub);
|
||||
IPSFactoryBuffer_Release(factory);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dispatch_typelib_ps_CreateStub(IPSFactoryBuffer *iface,
|
||||
REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
|
||||
{
|
||||
ITypeInfo *typeinfo;
|
||||
TYPEATTR *attr;
|
||||
HRESULT hr;
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IDispatch))
|
||||
return dispatch_create_stub(server, stub);
|
||||
|
||||
hr = get_typeinfo_for_iid(iid, &typeinfo);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
|
||||
hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
|
||||
if (FAILED(hr))
|
||||
ERR("Failed to create stub, hr %#x.\n", hr);
|
||||
{
|
||||
ITypeInfo_Release(typeinfo);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (attr->typekind == TKIND_INTERFACE || (attr->wTypeFlags & TYPEFLAG_FDUAL))
|
||||
hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
|
||||
else
|
||||
hr = dispatch_create_stub(server, stub);
|
||||
|
||||
if (FAILED(hr))
|
||||
ERR("Failed to create proxy, hr %#x.\n", hr);
|
||||
|
||||
ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
|
||||
ITypeInfo_Release(typeinfo);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IPSFactoryBufferVtbl typelib_ps_vtbl =
|
||||
static const IPSFactoryBufferVtbl dispatch_typelib_ps_vtbl =
|
||||
{
|
||||
typelib_ps_QueryInterface,
|
||||
typelib_ps_AddRef,
|
||||
typelib_ps_Release,
|
||||
typelib_ps_CreateProxy,
|
||||
typelib_ps_CreateStub,
|
||||
dispatch_typelib_ps_QueryInterface,
|
||||
dispatch_typelib_ps_AddRef,
|
||||
dispatch_typelib_ps_Release,
|
||||
dispatch_typelib_ps_CreateProxy,
|
||||
dispatch_typelib_ps_CreateStub,
|
||||
};
|
||||
|
||||
static IPSFactoryBuffer typelib_ps = { &typelib_ps_vtbl };
|
||||
static IPSFactoryBuffer dispatch_typelib_ps = { &dispatch_typelib_ps_vtbl };
|
||||
|
||||
extern void _get_STDFONT_CF(LPVOID *);
|
||||
extern void _get_STDPIC_CF(LPVOID *);
|
||||
|
||||
static HRESULT WINAPI PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IPSFactoryBuffer))
|
||||
{
|
||||
IPSFactoryBuffer_AddRef(iface);
|
||||
*ppv = iface;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSDispatchFacBuf_AddRef(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface,
|
||||
IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj)
|
||||
{
|
||||
IPSFactoryBuffer *factory;
|
||||
HRESULT hr;
|
||||
|
||||
if (IsEqualIID(iid, &IID_IDispatch))
|
||||
{
|
||||
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = IPSFactoryBuffer_CreateProxy(factory, outer, iid, proxy, obj);
|
||||
IPSFactoryBuffer_Release(factory);
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
return IPSFactoryBuffer_CreateProxy(&typelib_ps, outer, iid, proxy, obj);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface,
|
||||
REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
|
||||
{
|
||||
IPSFactoryBuffer *factory;
|
||||
HRESULT hr;
|
||||
|
||||
if (IsEqualIID(iid, &IID_IDispatch))
|
||||
{
|
||||
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub);
|
||||
IPSFactoryBuffer_Release(factory);
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub);
|
||||
}
|
||||
|
||||
static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
|
||||
{
|
||||
PSDispatchFacBuf_QueryInterface,
|
||||
PSDispatchFacBuf_AddRef,
|
||||
PSDispatchFacBuf_Release,
|
||||
PSDispatchFacBuf_CreateProxy,
|
||||
PSDispatchFacBuf_CreateStub
|
||||
};
|
||||
|
||||
/* This is the whole PSFactoryBuffer object, just the vtableptr */
|
||||
static const IPSFactoryBufferVtbl *pPSDispatchFacBuf = &PSDispatchFacBuf_Vtbl;
|
||||
|
||||
/***********************************************************************
|
||||
* DllGetClassObject (OLEAUT32.@)
|
||||
*/
|
||||
|
@ -1086,14 +1072,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
|||
return S_OK;
|
||||
}
|
||||
}
|
||||
if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) && IsEqualIID(iid, &IID_IPSFactoryBuffer)) {
|
||||
*ppv = &pPSDispatchFacBuf;
|
||||
IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID(rclsid, &CLSID_PSOAInterface))
|
||||
return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv);
|
||||
if (IsEqualGUID(rclsid, &CLSID_PSDispatch) || IsEqualGUID(rclsid, &CLSID_PSOAInterface))
|
||||
return IPSFactoryBuffer_QueryInterface(&dispatch_typelib_ps, iid, ppv);
|
||||
|
||||
if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
|
||||
IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
|
||||
|
|
|
@ -410,7 +410,8 @@ static inline struct disp_obj *impl_from_ISomethingFromDispatch(ISomethingFromDi
|
|||
static HRESULT WINAPI disp_obj_QueryInterface(ISomethingFromDispatch *iface, REFIID iid, void **out)
|
||||
{
|
||||
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IDispatch)
|
||||
|| IsEqualGUID(iid, &IID_ISomethingFromDispatch))
|
||||
|| IsEqualGUID(iid, &IID_ISomethingFromDispatch)
|
||||
|| IsEqualGUID(iid, &DIID_ItestIF4))
|
||||
{
|
||||
*out = iface;
|
||||
ISomethingFromDispatch_AddRef(iface);
|
||||
|
@ -3592,6 +3593,37 @@ static void test_external_connection(void)
|
|||
IStream_Release(stream);
|
||||
}
|
||||
|
||||
static void test_marshal_dispinterface(void)
|
||||
{
|
||||
static const LARGE_INTEGER zero;
|
||||
|
||||
ISomethingFromDispatch *disp_obj = create_disp_obj();
|
||||
ITypeInfo *typeinfo = NULL;
|
||||
IDispatch *proxy_disp;
|
||||
IStream *stream;
|
||||
HANDLE thread;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
DWORD tid;
|
||||
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
tid = start_host_object(stream, &DIID_ItestIF4, (IUnknown *)disp_obj, MSHLFLAGS_NORMAL, &thread);
|
||||
IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(stream, &DIID_ItestIF4, (void **)&proxy_disp);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDispatch_GetTypeInfo(proxy_disp, 0xdeadbeef, 0, &typeinfo);
|
||||
ok(hr == 0xbeefdead, "Got hr %#x.\n", hr);
|
||||
|
||||
ref = IDispatch_Release(proxy_disp);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IStream_Release(stream);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
end_host_object(tid, thread);
|
||||
ref = ISomethingFromDispatch_Release(disp_obj);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
}
|
||||
|
||||
START_TEST(tmarshal)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -3613,6 +3645,7 @@ START_TEST(tmarshal)
|
|||
test_StaticWidget();
|
||||
test_libattr();
|
||||
test_external_connection();
|
||||
test_marshal_dispinterface();
|
||||
|
||||
hr = UnRegisterTypeLib(&LIBID_TestTypelib, 2, 5, LOCALE_NEUTRAL,
|
||||
sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32);
|
||||
|
|
Loading…
Reference in New Issue