Signed-off-by: Jactry Zeng jzeng@codeweavers.com
--- Superseded patch 191639.
v4: - Match argument names in .idl to the original. v3: - Make creation of group manager safe. v2: - Add CRITICAL_SECTION for struct group_manager; - Use DISPID_VALUE and DISPID_NEWENUM instead; - Improve tests. --- dlls/comsvcs/Makefile.in | 3 +- dlls/comsvcs/comsvcs_private.h | 38 ++++++++ dlls/comsvcs/main.c | 28 +++--- dlls/comsvcs/property.c | 163 +++++++++++++++++++++++++++++++++ dlls/comsvcs/tests/Makefile.in | 3 +- dlls/comsvcs/tests/property.c | 115 +++++++++++++++++++++++ include/comsvcs.idl | 65 +++++++++++++ 7 files changed, 401 insertions(+), 14 deletions(-) create mode 100644 dlls/comsvcs/comsvcs_private.h create mode 100644 dlls/comsvcs/property.c create mode 100644 dlls/comsvcs/tests/property.c
diff --git a/dlls/comsvcs/Makefile.in b/dlls/comsvcs/Makefile.in index 7845400cb2..b4a4244bce 100644 --- a/dlls/comsvcs/Makefile.in +++ b/dlls/comsvcs/Makefile.in @@ -5,7 +5,8 @@ IMPORTS = ole32 uuid EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ - main.c + main.c \ + property.c
IDL_SRCS = \ comsvcs_classes.idl \ diff --git a/dlls/comsvcs/comsvcs_private.h b/dlls/comsvcs/comsvcs_private.h new file mode 100644 index 0000000000..6d299d3a88 --- /dev/null +++ b/dlls/comsvcs/comsvcs_private.h @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Jactry Zeng for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _COMSVCS_PRIVATE_H_ +#define _COMSVCS_PRIVATE_H_ + +#define COBJMACROS + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "rpcproxy.h" +#include "comsvcs.h" +#include "initguid.h" + +#include "wine/heap.h" +#include "wine/debug.h" + +HRESULT WINAPI group_manager_create(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out); + +#endif diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 9ab77dfced..1d3f7db174 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -18,18 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#define COBJMACROS - -#include <stdarg.h> - -#include "windef.h" -#include "winbase.h" -#include "ole2.h" -#include "rpcproxy.h" -#include "comsvcs.h" -#include "wine/heap.h" -#include "wine/debug.h" -#include "initguid.h" +#include "comsvcs_private.h" #include "comsvcs_classes.h"
WINE_DEFAULT_DEBUG_CHANNEL(comsvcs); @@ -1027,8 +1016,18 @@ static const IClassFactoryVtbl newmoniker_cf_vtbl = comsvcscf_LockServer };
+static const IClassFactoryVtbl group_manager_cf_vtbl = +{ + comsvcscf_QueryInterface, + comsvcscf_AddRef, + comsvcscf_Release, + group_manager_create, + comsvcscf_LockServer +}; + static IClassFactory DispenserManageFactory = { &comsvcscf_vtbl }; static IClassFactory NewMonikerFactory = { &newmoniker_cf_vtbl }; +static IClassFactory GroupManagerFactory = { &group_manager_cf_vtbl };
/****************************************************************** * DllGetClassObject @@ -1045,6 +1044,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) TRACE("(CLSID_NewMoniker %s %p)\n", debugstr_guid(riid), ppv); return IClassFactory_QueryInterface(&NewMonikerFactory, riid, ppv); } + else if (IsEqualGUID(&CLSID_SharedPropertyGroupManager, rclsid)) + { + TRACE("(CLSID_SharedPropertyGroupManager %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&GroupManagerFactory, riid, ppv); + }
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/comsvcs/property.c b/dlls/comsvcs/property.c new file mode 100644 index 0000000000..3c9917c926 --- /dev/null +++ b/dlls/comsvcs/property.c @@ -0,0 +1,163 @@ +/* + * Copyright 2020 Jactry Zeng for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <comsvcs_private.h> + +WINE_DEFAULT_DEBUG_CHANNEL(comsvcs); + +struct group_manager +{ + ISharedPropertyGroupManager ISharedPropertyGroupManager_iface; + LONG refcount; +}; + +static struct group_manager *group_manager = NULL; + +static inline struct group_manager *impl_from_ISharedPropertyGroupManager(ISharedPropertyGroupManager *iface) +{ + return CONTAINING_RECORD(iface, struct group_manager, ISharedPropertyGroupManager_iface); +} + +static HRESULT WINAPI group_manager_QueryInterface(ISharedPropertyGroupManager *iface, REFIID riid, void **out) +{ + struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_ISharedPropertyGroupManager)) + { + *out = &manager->ISharedPropertyGroupManager_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + WARN("%s not implemented.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI group_manager_AddRef(ISharedPropertyGroupManager *iface) +{ + struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); + ULONG refcount = InterlockedIncrement(&manager->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI group_manager_Release(ISharedPropertyGroupManager *iface) +{ + struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); + ULONG refcount = InterlockedDecrement(&manager->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static HRESULT WINAPI group_manager_GetTypeInfoCount(ISharedPropertyGroupManager *iface, UINT *info) +{ + FIXME("iface %p, info %p: stub.\n", iface, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_GetTypeInfo(ISharedPropertyGroupManager *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + FIXME("iface %p, index %u, lcid %u, info %p: stub.\n", iface, index, lcid, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_GetIDsOfNames(ISharedPropertyGroupManager *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid) +{ + FIXME("iface %p, riid %s, names %p, count %u, lcid %u, dispid %p: stub.\n", + iface, debugstr_guid(riid), names, count, lcid, dispid); + + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_Invoke(ISharedPropertyGroupManager *iface, DISPID member, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *except, UINT *argerr) +{ + FIXME("iface %p, member %u, riid %s, lcid %u, flags %x, params %p, result %p, except %p, argerr %p: stub.\n", + iface, member, debugstr_guid(riid), lcid, flags, params, result, except, argerr); + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_CreatePropertyGroup(ISharedPropertyGroupManager *iface, BSTR name, LONG *isolation, + LONG *release, VARIANT_BOOL *exists, ISharedPropertyGroup **group) +{ + FIXME("iface %p, name %s, isolation %p, release %p, exists %p, group %p: stub.\n", + iface, debugstr_w(name), isolation, release, exists, group); + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_get_Group(ISharedPropertyGroupManager *iface, BSTR name, ISharedPropertyGroup **group) +{ + FIXME("iface %p, name %s, group %p: stub.\n", iface, debugstr_w(name), group); + return E_NOTIMPL; +} + +static HRESULT WINAPI group_manager_get__NewEnum(ISharedPropertyGroupManager *iface, IUnknown **retval) +{ + FIXME("iface %p, retval %p: stub.\n", iface, retval); + return E_NOTIMPL; +} + +static const ISharedPropertyGroupManagerVtbl group_manager_vtbl = +{ + group_manager_QueryInterface, + group_manager_AddRef, + group_manager_Release, + group_manager_GetTypeInfoCount, + group_manager_GetTypeInfo, + group_manager_GetIDsOfNames, + group_manager_Invoke, + group_manager_CreatePropertyGroup, + group_manager_get_Group, + group_manager_get__NewEnum +}; + +HRESULT WINAPI group_manager_create(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) +{ + struct group_manager *manager; + + if (outer) + return CLASS_E_NOAGGREGATION; + + if (!group_manager) + { + manager = heap_alloc(sizeof(*manager)); + if (!manager) + { + *out = NULL; + return E_OUTOFMEMORY; + } + manager->ISharedPropertyGroupManager_iface.lpVtbl = &group_manager_vtbl; + manager->refcount = 1; + + if (InterlockedCompareExchangePointer((void **)&group_manager, manager, NULL)) + { + heap_free(manager); + } + } + return ISharedPropertyGroupManager_QueryInterface(&group_manager->ISharedPropertyGroupManager_iface, riid, out); +} diff --git a/dlls/comsvcs/tests/Makefile.in b/dlls/comsvcs/tests/Makefile.in index 86da9fda66..1d9146ba5b 100644 --- a/dlls/comsvcs/tests/Makefile.in +++ b/dlls/comsvcs/tests/Makefile.in @@ -2,4 +2,5 @@ TESTDLL = comsvcs.dll IMPORTS = uuid oleaut32 ole32
C_SRCS = \ - comsvcs.c + comsvcs.c \ + property.c diff --git a/dlls/comsvcs/tests/property.c b/dlls/comsvcs/tests/property.c new file mode 100644 index 0000000000..adad7bd539 --- /dev/null +++ b/dlls/comsvcs/tests/property.c @@ -0,0 +1,115 @@ +/* + * Copyright 2020 Jactry Zeng for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "comsvcs.h" + +#include "wine/test.h" + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + ok(0, "Unexpected call.\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + ok(0, "Unexpected call.\n"); + return 1; +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + ok(0, "Unexpected call.\n"); + return 0; +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_interfaces(void) +{ + ISharedPropertyGroupManager *manager, *manager1; + ULONG refcount, expected_refcount; + IDispatch *dispatch; + IUnknown *unk; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, &test_outer, CLSCTX_INPROC_SERVER, + &IID_ISharedPropertyGroupManager, (void **)&manager); + ok(hr == CLASS_E_NOAGGREGATION, "Got hr %#x.\n", hr); + + hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, NULL, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + expected_refcount = get_refcount(unk) + 1; + hr = IUnknown_QueryInterface(unk, &IID_ISharedPropertyGroupManager, (void **)&manager); + ok(hr == S_OK, "Got hr %#x.\n", hr); + refcount = get_refcount(unk); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + expected_refcount = get_refcount(manager) + 1; + hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, NULL, CLSCTX_INPROC_SERVER, + &IID_ISharedPropertyGroupManager, (void **)&manager1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(manager1 == manager, "Got wrong pointer: %p.\n", manager1); + refcount = get_refcount(manager1); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + ISharedPropertyGroupManager_Release(manager1); + + hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void **)&dispatch); + ok(hr == S_OK, "Got hr %#x.\n", hr); + refcount = get_refcount(dispatch); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + IDispatch_Release(dispatch); + IUnknown_Release(unk); + ISharedPropertyGroupManager_Release(manager); +} + +START_TEST(property) +{ + CoInitialize(NULL); + + test_interfaces(); + + CoUninitialize(); +} diff --git a/include/comsvcs.idl b/include/comsvcs.idl index d64af1f5a8..ac50141174 100644 --- a/include/comsvcs.idl +++ b/include/comsvcs.idl @@ -37,6 +37,8 @@ typedef DWORD_PTR TRANSID; ] library COMSVCSLib { + importlib("stdole2.tlb"); + [ object, hidden, @@ -96,4 +98,67 @@ library COMSVCSLib { [default] interface IDispenserManager; }; + + [ + object, + hidden, + local, + uuid(2a005c01-a5de-11cf-9e66-00aa00a3f464), + pointer_default(unique) + ] + interface ISharedProperty : IDispatch + { + [id(DISPID_VALUE), propget] + HRESULT Value([out, retval] VARIANT *pVal); + [id(DISPID_VALUE), propput] + HRESULT Value([in] VARIANT val); + } + + [ + object, + hidden, + local, + uuid(2a005c07-a5de-11cf-9e66-00aa00a3f464), + pointer_default(unique) + ] + interface ISharedPropertyGroup : IDispatch + { + [id(0x00000001)] + HRESULT CreatePropertyByPosition([in] int Index, [out] VARIANT_BOOL *fExists, [out, retval] ISharedProperty **ppProp); + [id(0x00000002), propget] + HRESULT PropertyByPosition([in] int Index, [out, retval] ISharedProperty **ppProperty); + [id(0x00000003)] + HRESULT CreateProperty([in] BSTR Name, [out] VARIANT_BOOL *fExists, [out, retval] ISharedProperty **ppProp); + [id(0x00000004), propget] + HRESULT Property([in] BSTR Name, [out, retval] ISharedProperty **ppProperty); + } + + [ + object, + hidden, + local, + uuid(2a005c0d-a5de-11cf-9e66-00aa00a3f464), + pointer_default(unique) + ] + interface ISharedPropertyGroupManager : IDispatch + { + [id(0x00000001)] + HRESULT CreatePropertyGroup([in] BSTR Name, [in, out] LONG *dwIsoMode, [in, out] LONG *dwRelMode, + [out] VARIANT_BOOL *fExists, [out, retval] ISharedPropertyGroup **ppGroup); + [id(0x00000002), propget] + HRESULT Group([in] BSTR Name, [out, retval] ISharedPropertyGroup **ppGroup); + [id(DISPID_NEWENUM), propget] + HRESULT _NewEnum([out, retval] IUnknown **retval); + } + + [ + uuid(2a005c11-a5de-11cf-9e66-00aa00a3f464), + progid("MTxSpm.SharedPropertyGroupManager.1"), + vi_progid("MTxSpm.SharedPropertyGroupManager"), + threading(both) + ] + coclass SharedPropertyGroupManager + { + [default] interface ISharedPropertyGroupManager; + } }
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
--- Superseded patch 191640.
v4: No changes. v3: - Fix some leaks. - Test reference count of ITypeInfo. v2: No changes. --- dlls/comsvcs/Makefile.in | 2 +- dlls/comsvcs/comsvcs_private.h | 15 ++++++++ dlls/comsvcs/main.c | 68 ++++++++++++++++++++++++++++++++++ dlls/comsvcs/property.c | 45 ++++++++++++++++++---- dlls/comsvcs/tests/property.c | 59 +++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 9 deletions(-)
diff --git a/dlls/comsvcs/Makefile.in b/dlls/comsvcs/Makefile.in index b4a4244bce..82a496ea9c 100644 --- a/dlls/comsvcs/Makefile.in +++ b/dlls/comsvcs/Makefile.in @@ -1,6 +1,6 @@ MODULE = comsvcs.dll IMPORTLIB = comsvcs -IMPORTS = ole32 uuid +IMPORTS = ole32 oleaut32 uuid
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/comsvcs/comsvcs_private.h b/dlls/comsvcs/comsvcs_private.h index 6d299d3a88..8a67bcffd8 100644 --- a/dlls/comsvcs/comsvcs_private.h +++ b/dlls/comsvcs/comsvcs_private.h @@ -33,6 +33,21 @@ #include "wine/heap.h" #include "wine/debug.h"
+enum tid_t +{ + NULL_tid, + ISharedPropertyGroupManager_tid, + LAST_tid +}; + +static REFIID tid_ids[] = +{ + &IID_NULL, + &IID_ISharedPropertyGroupManager, +}; + +HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo); + HRESULT WINAPI group_manager_create(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out);
#endif diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 1d3f7db174..7d00084f8a 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -361,6 +361,71 @@ static HRESULT WINAPI dispenser_manager_cf_CreateInstance(IClassFactory *iface, return ret; }
+static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static HRESULT load_typelib(void) +{ + ITypeLib *tl; + HRESULT hr; + + if (typelib) + return S_OK; + + hr = LoadRegTypeLib(&LIBID_COMSVCSLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); + if (FAILED(hr)) + { + ERR("LoadRegTypeLib failed: %#x.\n", hr); + return hr; + } + + if (InterlockedCompareExchangePointer((void **)&typelib, tl, NULL)) + ITypeLib_Release(tl); + return hr; +} + +HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hr; + + hr = load_typelib(); + if (FAILED(hr)) + return hr; + + if (!typeinfos[tid]) + { + ITypeInfo *ti; + + hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + if (FAILED(hr)) + { + ERR("GetTypeInfoOfGuid(%s) failed: %#x.\n", debugstr_guid(tid_ids[tid]), hr); + return hr; + } + + if (InterlockedCompareExchangePointer((void **)(typeinfos + tid), ti, NULL)) + ITypeInfo_Release(ti); + } + + *typeinfo = typeinfos[tid]; + ITypeInfo_AddRef(typeinfos[tid]); + return S_OK; +} + +static void release_typelib(void) +{ + unsigned i; + + if (!typelib) + return; + + for (i = 0; i < ARRAY_SIZE(typeinfos); i++) + if (typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + + ITypeLib_Release(typelib); +} + BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID lpv) { switch(reason) @@ -371,6 +436,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID lpv) COMSVCS_hInstance = hinst; DisableThreadLibraryCalls(hinst); break; + case DLL_PROCESS_DETACH: + release_typelib(); + break; } return TRUE; } diff --git a/dlls/comsvcs/property.c b/dlls/comsvcs/property.c index 3c9917c926..44e111fe71 100644 --- a/dlls/comsvcs/property.c +++ b/dlls/comsvcs/property.c @@ -75,31 +75,60 @@ static ULONG WINAPI group_manager_Release(ISharedPropertyGroupManager *iface)
static HRESULT WINAPI group_manager_GetTypeInfoCount(ISharedPropertyGroupManager *iface, UINT *info) { - FIXME("iface %p, info %p: stub.\n", iface, info); - return E_NOTIMPL; + TRACE("iface %p, info %p.\n", iface, info); + + if (!info) + return E_INVALIDARG; + *info = 1; + return S_OK; }
static HRESULT WINAPI group_manager_GetTypeInfo(ISharedPropertyGroupManager *iface, UINT index, LCID lcid, ITypeInfo **info) { - FIXME("iface %p, index %u, lcid %u, info %p: stub.\n", iface, index, lcid, info); - return E_NOTIMPL; + TRACE("iface %p, index %u, lcid %u, info %p.\n", iface, index, lcid, info); + + if (index) + return DISP_E_BADINDEX; + + return get_typeinfo(ISharedPropertyGroupManager_tid, info); }
static HRESULT WINAPI group_manager_GetIDsOfNames(ISharedPropertyGroupManager *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid) { - FIXME("iface %p, riid %s, names %p, count %u, lcid %u, dispid %p: stub.\n", + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, riid %s, names %p, count %u, lcid %u, dispid %p.\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
- return E_NOTIMPL; + hr = get_typeinfo(ISharedPropertyGroupManager_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; }
static HRESULT WINAPI group_manager_Invoke(ISharedPropertyGroupManager *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *except, UINT *argerr) { - FIXME("iface %p, member %u, riid %s, lcid %u, flags %x, params %p, result %p, except %p, argerr %p: stub.\n", + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, member %u, riid %s, lcid %u, flags %x, params %p, result %p, except %p, argerr %p.\n", iface, member, debugstr_guid(riid), lcid, flags, params, result, except, argerr); - return E_NOTIMPL; + + hr = get_typeinfo(ISharedPropertyGroupManager_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, member, flags, params, result, except, argerr); + ITypeInfo_Release(typeinfo); + } + + return hr; }
static HRESULT WINAPI group_manager_CreatePropertyGroup(ISharedPropertyGroupManager *iface, BSTR name, LONG *isolation, diff --git a/dlls/comsvcs/tests/property.c b/dlls/comsvcs/tests/property.c index adad7bd539..2cc7ff1d44 100644 --- a/dlls/comsvcs/tests/property.c +++ b/dlls/comsvcs/tests/property.c @@ -60,6 +60,57 @@ static const IUnknownVtbl outer_vtbl =
static IUnknown test_outer = {&outer_vtbl};
+struct test_name_id +{ + const WCHAR *name; + DISPID id; +}; + +#define TEST_TYPEINFO(dispatch,test_name_ids,id_count,riid) _test_typeinfo(dispatch, test_name_ids, id_count, riid, __LINE__) +static void _test_typeinfo(IDispatch *dispatch, const struct test_name_id *test_name_ids, UINT id_count, REFIID riid, int line) +{ + static const LCID english = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + ITypeInfo *typeinfo; + TYPEATTR *typeattr; + ULONG refcount; + DISPID dispid; + UINT count; + BSTR names; + HRESULT hr; + int i; + + hr = IDispatch_GetTypeInfoCount(dispatch, NULL); + ok_(__FILE__,line)(hr == E_INVALIDARG, "GetTypeInfoCount got hr %#x.\n", hr); + + count = 0xdeadbeef; + hr = IDispatch_GetTypeInfoCount(dispatch, &count); + ok_(__FILE__,line)(hr == S_OK, "GetTypeInfoCount got hr %#x.\n", hr); + ok_(__FILE__,line)(count == 1, "Got unexpected count: %d.\n", count); + + hr = IDispatch_GetTypeInfo(dispatch, 1, english, &typeinfo); + ok_(__FILE__,line)(hr == DISP_E_BADINDEX, "GetTypeInfo got hr %#x.\n", hr); + + hr = IDispatch_GetTypeInfo(dispatch, 0, english, &typeinfo); + ok_(__FILE__,line)(hr == S_OK, "GetTypeInfo failed %#x.\n", hr); + hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr); + ok_(__FILE__,line)(hr == S_OK, "GetTypeAttr got hr %#x.\n", hr); + ok_(__FILE__,line)(IsEqualGUID(&typeattr->guid, riid), + "Got unexpected type guid: %s.\n", wine_dbgstr_guid(&typeattr->guid)); + refcount = get_refcount(typeinfo); + ok_(__FILE__,line)(refcount == 2, "Got refcount: %u.\n", refcount); + ITypeInfo_Release(typeinfo); + + for (i = 0; i < id_count; i++) + { + names = SysAllocString(test_name_ids[i].name); + dispid = 0xdeadbeef; + hr = IDispatch_GetIDsOfNames(dispatch, &IID_NULL, &names, 1, english, &dispid); + SysFreeString(names); + ok_(__FILE__,line)(hr == S_OK, "tests[%d] got hr %#x.\n", i, hr); + ok_(__FILE__,line)(dispid == test_name_ids[i].id, "tests[%d] got wrong dispid %x.\n", i, dispid); + } +} + static void test_interfaces(void) { ISharedPropertyGroupManager *manager, *manager1; @@ -67,6 +118,12 @@ static void test_interfaces(void) IDispatch *dispatch; IUnknown *unk; HRESULT hr; + static const struct test_name_id test_name_ids[] = + { + {L"CreatePropertyGroup", 0x1}, + {L"Group", 0x2}, + {L"_NewEnum", DISPID_NEWENUM}, + };
hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, &test_outer, CLSCTX_INPROC_SERVER, &IID_ISharedPropertyGroupManager, (void **)&manager); @@ -100,6 +157,8 @@ static void test_interfaces(void) refcount = get_refcount(manager); ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount);
+ TEST_TYPEINFO(dispatch, test_name_ids, ARRAY_SIZE(test_name_ids), &IID_ISharedPropertyGroupManager); + IDispatch_Release(dispatch); IUnknown_Release(unk); ISharedPropertyGroupManager_Release(manager);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79007
Your paranoid android.
=== debiant (32 bit report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit French report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (64 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040372d).
Report validation errors: comsvcs:property crashed (c0000005)
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
--- Superseded patch 191637.
v4: - Add constants for isolation and release mode. - Create property_group in a helper. - Fix a typo in CreatePropertyGroup(). v3: - Free group in ISharedPropertyGroup_Release(). - Use LIST_FOR_EACH_ENTRY instead of LIST_FOR_EACH_ENTRY_SAFE in find_propery_group(). - Add CRITICAL_SECTION for struct group_manager. - Simplify CreatePropertyGroup() and check SysAllocString() result. - Fix some leaks. - Add more tests. v2: - Storage struct group_manager * instead of ISharedPropertyGroupManager * in struct property_group; - Storage property groups to a link instead of an array; - Add more tests of ISharedPropertyGroupManager_CreatePropertyGroup(). --- dlls/comsvcs/comsvcs_private.h | 2 + dlls/comsvcs/property.c | 258 ++++++++++++++++++++++++++++++++- dlls/comsvcs/tests/property.c | 129 +++++++++++++++++ include/comsvcs.idl | 12 ++ include/winerror.h | 11 ++ 5 files changed, 408 insertions(+), 4 deletions(-)
diff --git a/dlls/comsvcs/comsvcs_private.h b/dlls/comsvcs/comsvcs_private.h index 8a67bcffd8..eee6e9938c 100644 --- a/dlls/comsvcs/comsvcs_private.h +++ b/dlls/comsvcs/comsvcs_private.h @@ -37,6 +37,7 @@ enum tid_t { NULL_tid, ISharedPropertyGroupManager_tid, + ISharedPropertyGroup_tid, LAST_tid };
@@ -44,6 +45,7 @@ static REFIID tid_ids[] = { &IID_NULL, &IID_ISharedPropertyGroupManager, + &IID_ISharedPropertyGroup, };
HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo); diff --git a/dlls/comsvcs/property.c b/dlls/comsvcs/property.c index 44e111fe71..98b6b060b9 100644 --- a/dlls/comsvcs/property.c +++ b/dlls/comsvcs/property.c @@ -17,6 +17,7 @@ */
#include <comsvcs_private.h> +#include <wine/list.h>
WINE_DEFAULT_DEBUG_CHANNEL(comsvcs);
@@ -24,6 +25,18 @@ struct group_manager { ISharedPropertyGroupManager ISharedPropertyGroupManager_iface; LONG refcount; + struct list property_groups; + CRITICAL_SECTION cs; +}; + +struct property_group +{ + ISharedPropertyGroup ISharedPropertyGroup_iface; + LONG refcount; + struct group_manager *parent; + LONG isolation, release; + struct list entry; + BSTR name; };
static struct group_manager *group_manager = NULL; @@ -33,6 +46,165 @@ static inline struct group_manager *impl_from_ISharedPropertyGroupManager(IShare return CONTAINING_RECORD(iface, struct group_manager, ISharedPropertyGroupManager_iface); }
+static inline struct property_group *impl_from_ISharedPropertyGroup(ISharedPropertyGroup *iface) +{ + return CONTAINING_RECORD(iface, struct property_group, ISharedPropertyGroup_iface); +} + +static HRESULT WINAPI property_group_QueryInterface(ISharedPropertyGroup *iface, REFIID riid, void **out) +{ + struct property_group *group = impl_from_ISharedPropertyGroup(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_ISharedPropertyGroup)) + { + *out = &group->ISharedPropertyGroup_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + WARN("%s not implemented.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI property_group_AddRef(ISharedPropertyGroup *iface) +{ + struct property_group *group = impl_from_ISharedPropertyGroup(iface); + ULONG refcount = InterlockedIncrement(&group->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI property_group_Release(ISharedPropertyGroup *iface) +{ + struct property_group *group = impl_from_ISharedPropertyGroup(iface); + ULONG refcount = InterlockedDecrement(&group->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + struct group_manager *manager = group->parent; + + SysFreeString(group->name); + + EnterCriticalSection(&manager->cs); + list_remove(&group->entry); + LeaveCriticalSection(&manager->cs); + + ISharedPropertyGroupManager_Release(&manager->ISharedPropertyGroupManager_iface); + heap_free(group); + } + + return refcount; +} + +static HRESULT WINAPI property_group_GetTypeInfoCount(ISharedPropertyGroup *iface, UINT *info) +{ + TRACE("iface %p, info %p.\n", iface, info); + + if (!info) + return E_INVALIDARG; + *info = 1; + return S_OK; +} + +static HRESULT WINAPI property_group_GetTypeInfo(ISharedPropertyGroup *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + TRACE("iface %p, index %u, lcid %u, info %p.\n", iface, index, lcid, info); + + if (index) + return DISP_E_BADINDEX; + + return get_typeinfo(ISharedPropertyGroup_tid, info); +} + +static HRESULT WINAPI property_group_GetIDsOfNames(ISharedPropertyGroup *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, riid %s, names %p, count %u, lcid %u, dispid %p.\n", + iface, debugstr_guid(riid), names, count, lcid, dispid); + + hr = get_typeinfo(ISharedPropertyGroup_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI property_group_Invoke(ISharedPropertyGroup *iface, DISPID member, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *except, UINT *argerr) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, member %u, riid %s, lcid %u, flags %x, params %p, result %p, except %p, argerr %p.\n", + iface, member, debugstr_guid(riid), lcid, flags, params, result, except, argerr); + + hr = get_typeinfo(ISharedPropertyGroup_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, member, flags, params, result, except, argerr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI property_group_CreatePropertyByPosition(ISharedPropertyGroup *iface, int index, + VARIANT_BOOL *exists, ISharedProperty **property) +{ + FIXME("iface %p, index %d, exisits %p, property %p: stub.\n", + iface, index, exists, property); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_group_get_PropertyByPosition(ISharedPropertyGroup *iface, int index, ISharedProperty **property) +{ + FIXME("iface %p, index %d, property %p: stub.\n", iface, index, property); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_group_CreateProperty(ISharedPropertyGroup *iface, BSTR name, VARIANT_BOOL *exists, + ISharedProperty **property) +{ + FIXME("iface %p, name %s, exists %p, property %p: stub.\n", iface, debugstr_w(name), exists, property); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_group_get_Property(ISharedPropertyGroup *iface, BSTR name, ISharedProperty **property) +{ + FIXME("iface %p, name %s, property %p: stub.\n", iface, debugstr_w(name), property); + return E_NOTIMPL; +} + +static const ISharedPropertyGroupVtbl property_group_vtbl = +{ + property_group_QueryInterface, + property_group_AddRef, + property_group_Release, + property_group_GetTypeInfoCount, + property_group_GetTypeInfo, + property_group_GetIDsOfNames, + property_group_Invoke, + property_group_CreatePropertyByPosition, + property_group_get_PropertyByPosition, + property_group_CreateProperty, + property_group_get_Property, +}; + static HRESULT WINAPI group_manager_QueryInterface(ISharedPropertyGroupManager *iface, REFIID riid, void **out) { struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); @@ -131,12 +303,87 @@ static HRESULT WINAPI group_manager_Invoke(ISharedPropertyGroupManager *iface, D return hr; }
-static HRESULT WINAPI group_manager_CreatePropertyGroup(ISharedPropertyGroupManager *iface, BSTR name, LONG *isolation, - LONG *release, VARIANT_BOOL *exists, ISharedPropertyGroup **group) +static struct property_group *find_propery_group(struct group_manager *manager, BSTR name) +{ + struct property_group *group; + + LIST_FOR_EACH_ENTRY(group, &group_manager->property_groups, struct property_group, entry) + { + if (!lstrcmpW(group->name, name)) + return group; + } + return NULL; +} + +struct property_group *create_property_group(struct group_manager* manager, BSTR name, LONG *isolation, + LONG *release, VARIANT_BOOL *exists) +{ + struct property_group *property_group; + + property_group = find_propery_group(manager, name); + if (property_group) + { + *exists = TRUE; + *isolation = property_group->isolation; + *release = property_group->release; + ISharedPropertyGroup_AddRef(&property_group->ISharedPropertyGroup_iface); + } + else + { + property_group = heap_alloc(sizeof(*property_group)); + if (!property_group) + return NULL; + + property_group->ISharedPropertyGroup_iface.lpVtbl = &property_group_vtbl; + property_group->parent = manager; + property_group->isolation = *isolation; + property_group->release = *release; + property_group->refcount = 1; + property_group->name = SysAllocString(name); + if (!property_group->name) + { + heap_free(property_group); + return NULL; + } + list_add_tail(&manager->property_groups, &property_group->entry); + + *exists = FALSE; + ISharedPropertyGroupManager_AddRef(&property_group->parent->ISharedPropertyGroupManager_iface); + } + return property_group; +} + +static HRESULT WINAPI group_manager_CreatePropertyGroup(ISharedPropertyGroupManager *iface, BSTR name, + LONG *isolation, LONG *release, VARIANT_BOOL *exists, ISharedPropertyGroup **group) { - FIXME("iface %p, name %s, isolation %p, release %p, exists %p, group %p: stub.\n", + struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); + struct property_group *property_group; + + TRACE("iface %p, name %s, isolation %p, release %p, exists %p, group %p.\n", iface, debugstr_w(name), isolation, release, exists, group); - return E_NOTIMPL; + + if (!name) + return E_POINTER; + + if (*isolation > 1 || *release > 1) + return E_INVALIDARG; + + if (*isolation || *release) + FIXME("Unsupported mode: (%s, %s).\n", *isolation ? "LockMethod" : "LockSetGet", *release ? "Standard" : "Process"); + + EnterCriticalSection(&manager->cs); + + property_group = create_property_group(manager, name, isolation, release, exists); + if (!property_group) + { + LeaveCriticalSection(&manager->cs); + return E_OUTOFMEMORY; + } + *group = &property_group->ISharedPropertyGroup_iface; + + LeaveCriticalSection(&manager->cs); + + return S_OK; }
static HRESULT WINAPI group_manager_get_Group(ISharedPropertyGroupManager *iface, BSTR name, ISharedPropertyGroup **group) @@ -182,9 +429,12 @@ HRESULT WINAPI group_manager_create(IClassFactory *iface, IUnknown *outer, REFII } manager->ISharedPropertyGroupManager_iface.lpVtbl = &group_manager_vtbl; manager->refcount = 1; + list_init(&manager->property_groups); + InitializeCriticalSection(&manager->cs);
if (InterlockedCompareExchangePointer((void **)&group_manager, manager, NULL)) { + DeleteCriticalSection(&manager->cs); heap_free(manager); } } diff --git a/dlls/comsvcs/tests/property.c b/dlls/comsvcs/tests/property.c index 2cc7ff1d44..8ac5e522f5 100644 --- a/dlls/comsvcs/tests/property.c +++ b/dlls/comsvcs/tests/property.c @@ -164,11 +164,140 @@ static void test_interfaces(void) ISharedPropertyGroupManager_Release(manager); }
+static void test_property_group(void) +{ + ISharedPropertyGroup *group, *group1; + ISharedPropertyGroupManager *manager; + ULONG refcount, expected_refcount; + LONG isolation, release; + VARIANT_BOOL exists; + IDispatch *dispatch; + HRESULT hr; + BSTR name; + static const struct test_name_id test_name_ids[] = + { + {L"CreatePropertyByPosition", 0x1}, + {L"PropertyByPosition", 0x2}, + {L"CreateProperty", 0x3}, + {L"Property", 0x4}, + }; + + hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, NULL, CLSCTX_INPROC_SERVER, + &IID_ISharedPropertyGroupManager, (void **)&manager); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, NULL, &isolation, &release, &exists, &group); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + name = SysAllocString(L"testgroupname"); + isolation = 2; + release = 0; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + /* Crash on Windows */ + if (0) + { + ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, NULL, &release, &exists, &group); + ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, NULL, &exists, &group); + ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, NULL, &group); + } + + isolation = 0; + release = 2; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + isolation = 1; + release = 0; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group); + todo_wine ok(hr == CONTEXT_E_NOCONTEXT, "Got hr %#x.\n", hr); + if (group) + ISharedPropertyGroup_Release(group); + + isolation = 0; + release = 0; + exists = TRUE; + expected_refcount = get_refcount(manager) + 1; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!exists, "Got unexpected value %d.\n", exists); + refcount = get_refcount(group); + ok(refcount == 1, "Got unexpected refcount: %u.\n", refcount); + + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + ISharedPropertyGroup_AddRef(group); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + ISharedPropertyGroup_Release(group); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + /* Create an existing group */ + isolation = 1; + release = 1; + expected_refcount = get_refcount(manager); + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!exists, "Got unexpected value %d.\n", exists); + ok(!isolation, "Got unexpected value %d.\n", isolation); + ok(!release, "Got unexpected value %d.\n", release); + ok(group == group1, "Got unexpected pointer: %p.\n", group1); + refcount = get_refcount(group); + ok(refcount == 2, "Got unexpected refcount: %u.\n", refcount); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + ISharedPropertyGroup_Release(group1); + refcount = get_refcount(group); + ok(refcount == 1, "Got unexpected refcount: %u.\n", refcount); + SysFreeString(name); + + name = SysAllocString(L"testgroupname2"); + isolation = 0; + release = 1; + exists = TRUE; + expected_refcount = get_refcount(manager) + 1; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!exists, "Got unexpected value %d.\n", exists); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + refcount = get_refcount(group1); + todo_wine ok(refcount == 2, "Got unexpected refcount: %u.\n", refcount); + SysFreeString(name); + + if (refcount >= 2) + { + expected_refcount = get_refcount(manager); + ISharedPropertyGroup_Release(group1); + refcount = get_refcount(manager); + todo_wine ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + expected_refcount = get_refcount(manager) - 1; + ISharedPropertyGroup_Release(group1); + refcount = get_refcount(manager); + todo_wine ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + } + + hr = ISharedPropertyGroup_QueryInterface(group, &IID_IDispatch, (void **)&dispatch); + ok(hr == S_OK, "Got hr %#x.\n", hr); + TEST_TYPEINFO(dispatch, test_name_ids, ARRAY_SIZE(test_name_ids), &IID_ISharedPropertyGroup); + IDispatch_Release(dispatch); + + expected_refcount = get_refcount(manager) - 1; + ISharedPropertyGroup_Release(group); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + ISharedPropertyGroupManager_Release(manager); +} + START_TEST(property) { CoInitialize(NULL);
test_interfaces(); + test_property_group();
CoUninitialize(); } diff --git a/include/comsvcs.idl b/include/comsvcs.idl index ac50141174..49405a6bba 100644 --- a/include/comsvcs.idl +++ b/include/comsvcs.idl @@ -31,6 +31,18 @@ typedef LPOLESTR SRESID; typedef long TIMEINSECS; typedef DWORD_PTR TRANSID;
+typedef enum _LockModes +{ + LockSetGet = 0, + LockMethod = 1 +} LockModes; + +typedef enum _ReleaseModes +{ + Standard = 0, + Process = 1 +} ReleaseModes; + [ uuid(2a005c00-a5de-11cf-9e66-00aa00a3f464), version(1.0) diff --git a/include/winerror.h b/include/winerror.h index 86f7aace68..6142ca2715 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -3037,6 +3037,17 @@ static inline HRESULT HRESULT_FROM_WIN32(unsigned int x) #define CO_E_DECODEFAILED _HRESULT_TYPEDEF_(0x8004021A) #define CO_E_ACNOTINITIALIZED _HRESULT_TYPEDEF_(0x8004021B)
+#define CONTEXT_E_ABORTED _HRESULT_TYPEDEF_(0x8004e002) +#define CONTEXT_E_ABORTING _HRESULT_TYPEDEF_(0x8004e003) +#define CONTEXT_E_NOCONTEXT _HRESULT_TYPEDEF_(0x8004e004) +#define CONTEXT_E_WOULD_DEADLOCK _HRESULT_TYPEDEF_(0x8004e005) +#define CONTEXT_E_SYNCH_TIMEOUT _HRESULT_TYPEDEF_(0x8004e006) +#define CONTEXT_E_OLDREF _HRESULT_TYPEDEF_(0x8004e007) +#define CONTEXT_E_ROLENOTFOUND _HRESULT_TYPEDEF_(0x8004e00c) +#define CONTEXT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004e00f) +#define CONTEXT_E_NOJIT _HRESULT_TYPEDEF_(0x8004e026) +#define CONTEXT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004e027) + /* Task Scheduler Service Error Codes */ #define SCHED_S_TASK_READY _HRESULT_TYPEDEF_(0x00041300) #define SCHED_S_TASK_RUNNING _HRESULT_TYPEDEF_(0x00041301)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79008
Your paranoid android.
=== debiant (32 bit report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit French report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (64 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
--- Superseded patch 191638.
v4: No changes. v3: - Add more tests. v2: No changes. --- dlls/comsvcs/property.c | 19 +++++++++++++++++-- dlls/comsvcs/tests/property.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/dlls/comsvcs/property.c b/dlls/comsvcs/property.c index 98b6b060b9..732e75681d 100644 --- a/dlls/comsvcs/property.c +++ b/dlls/comsvcs/property.c @@ -388,8 +388,23 @@ static HRESULT WINAPI group_manager_CreatePropertyGroup(ISharedPropertyGroupMana
static HRESULT WINAPI group_manager_get_Group(ISharedPropertyGroupManager *iface, BSTR name, ISharedPropertyGroup **group) { - FIXME("iface %p, name %s, group %p: stub.\n", iface, debugstr_w(name), group); - return E_NOTIMPL; + struct group_manager *manager = impl_from_ISharedPropertyGroupManager(iface); + struct property_group *property_group; + + TRACE("iface %p, name %s, group %p.\n", iface, debugstr_w(name), group); + + if (!name || !group) + return E_POINTER; + + EnterCriticalSection(&manager->cs); + property_group = find_propery_group(manager, name); + LeaveCriticalSection(&manager->cs); + + if (!property_group) + return E_INVALIDARG; + + return ISharedPropertyGroup_QueryInterface(&property_group->ISharedPropertyGroup_iface, + &IID_ISharedPropertyGroup, (void **)group); }
static HRESULT WINAPI group_manager_get__NewEnum(ISharedPropertyGroupManager *iface, IUnknown **retval) diff --git a/dlls/comsvcs/tests/property.c b/dlls/comsvcs/tests/property.c index 8ac5e522f5..7321bbcfe6 100644 --- a/dlls/comsvcs/tests/property.c +++ b/dlls/comsvcs/tests/property.c @@ -166,7 +166,7 @@ static void test_interfaces(void)
static void test_property_group(void) { - ISharedPropertyGroup *group, *group1; + ISharedPropertyGroup *group, *group1, *group2; ISharedPropertyGroupManager *manager; ULONG refcount, expected_refcount; LONG isolation, release; @@ -284,6 +284,34 @@ static void test_property_group(void) TEST_TYPEINFO(dispatch, test_name_ids, ARRAY_SIZE(test_name_ids), &IID_ISharedPropertyGroup); IDispatch_Release(dispatch);
+ hr = ISharedPropertyGroupManager_get_Group(manager, NULL, &group2); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + name = SysAllocString(L"nonexistgroup"); + hr = ISharedPropertyGroupManager_get_Group(manager, name, &group2); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + SysFreeString(name); + + name = SysAllocString(L"testgroupname"); + hr = ISharedPropertyGroupManager_get_Group(manager, name, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + expected_refcount = get_refcount(manager); + hr = ISharedPropertyGroupManager_get_Group(manager, name, &group2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(group2 == group, "Got unexpected pointer %p.\n", group2); + refcount = get_refcount(group); + ok(refcount == 2, "Got unexpected refcount: %u.\n", refcount); + refcount = get_refcount(manager); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + ISharedPropertyGroup_Release(group2); + SysFreeString(name); + + name = SysAllocString(L"Testgroupname"); + hr = ISharedPropertyGroupManager_get_Group(manager, name, &group2); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + SysFreeString(name); + expected_refcount = get_refcount(manager) - 1; ISharedPropertyGroup_Release(group); refcount = get_refcount(manager);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79009
Your paranoid android.
=== debiant (32 bit report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit French report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (64 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
Signed-off-by: Jactry Zeng jzeng@codeweavers.com
--- Superseded patch 191641.
v4: - Storage properties in a list instead of an array. v3: - Fix some leaks. - Add more tests. - Check SysAllocString() result in CreateProperty(). v2: No changes. --- dlls/comsvcs/comsvcs_private.h | 2 + dlls/comsvcs/property.c | 218 ++++++++++++++++++++++++++++++++- dlls/comsvcs/tests/property.c | 81 ++++++++++++ 3 files changed, 299 insertions(+), 2 deletions(-)
diff --git a/dlls/comsvcs/comsvcs_private.h b/dlls/comsvcs/comsvcs_private.h index eee6e9938c..3eeb9d751a 100644 --- a/dlls/comsvcs/comsvcs_private.h +++ b/dlls/comsvcs/comsvcs_private.h @@ -38,6 +38,7 @@ enum tid_t NULL_tid, ISharedPropertyGroupManager_tid, ISharedPropertyGroup_tid, + ISharedProperty_tid, LAST_tid };
@@ -46,6 +47,7 @@ static REFIID tid_ids[] = &IID_NULL, &IID_ISharedPropertyGroupManager, &IID_ISharedPropertyGroup, + &IID_ISharedProperty, };
HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo); diff --git a/dlls/comsvcs/property.c b/dlls/comsvcs/property.c index 732e75681d..7ccaa048e5 100644 --- a/dlls/comsvcs/property.c +++ b/dlls/comsvcs/property.c @@ -21,6 +21,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(comsvcs);
+struct shared_property +{ + ISharedProperty ISharedProperty_iface; + LONG refcount; + BSTR name; + struct list entry; +}; + struct group_manager { ISharedPropertyGroupManager ISharedPropertyGroupManager_iface; @@ -37,6 +45,8 @@ struct property_group LONG isolation, release; struct list entry; BSTR name; + struct list properties; + CRITICAL_SECTION cs; };
static struct group_manager *group_manager = NULL; @@ -51,6 +61,140 @@ static inline struct property_group *impl_from_ISharedPropertyGroup(ISharedPrope return CONTAINING_RECORD(iface, struct property_group, ISharedPropertyGroup_iface); }
+static inline struct shared_property *impl_from_ISharedProperty(ISharedProperty *iface) +{ + return CONTAINING_RECORD(iface, struct shared_property, ISharedProperty_iface); +} + +static HRESULT WINAPI shared_property_QueryInterface(ISharedProperty *iface, REFIID riid, void **out) +{ + struct shared_property *property = impl_from_ISharedProperty(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_ISharedProperty)) + { + *out = &property->ISharedProperty_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + WARN("%s not implemented.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI shared_property_AddRef(ISharedProperty *iface) +{ + struct shared_property *property = impl_from_ISharedProperty(iface); + ULONG refcount = InterlockedIncrement(&property->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI shared_property_Release(ISharedProperty *iface) +{ + struct shared_property *property = impl_from_ISharedProperty(iface); + ULONG refcount = InterlockedDecrement(&property->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + SysFreeString(property->name); + list_remove(&property->entry); + } + + return refcount; +} + +static HRESULT WINAPI shared_property_GetTypeInfoCount(ISharedProperty *iface, UINT *info) +{ + TRACE("iface %p, info %p.\n", iface, info); + + if (!info) + return E_INVALIDARG; + *info = 1; + return S_OK; +} + +static HRESULT WINAPI shared_property_GetTypeInfo(ISharedProperty *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + TRACE("iface %p, index %u, lcid %u, info %p.\n", iface, index, lcid, info); + + if (index) + return DISP_E_BADINDEX; + + return get_typeinfo(ISharedProperty_tid, info); +} + +static HRESULT WINAPI shared_property_GetIDsOfNames(ISharedProperty *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, riid %s, names %p, count %u, lcid %u, dispid %p.\n", + iface, debugstr_guid(riid), names, count, lcid, dispid); + + hr = get_typeinfo(ISharedProperty_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI shared_property_Invoke(ISharedProperty *iface, DISPID member, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *except, UINT *argerr) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("iface %p, member %u, riid %s, lcid %u, flags %x, params %p, result %p, except %p, argerr %p.\n", + iface, member, debugstr_guid(riid), lcid, flags, params, result, except, argerr); + + hr = get_typeinfo(ISharedProperty_tid, &typeinfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, member, flags, params, result, except, argerr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI shared_property_get_Value(ISharedProperty *iface, VARIANT *value) +{ + FIXME("iface %p, value %p: stub.\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI shared_property_put_Value(ISharedProperty *iface, VARIANT value) +{ + FIXME("iface %p, value %s: stub.\n", iface, debugstr_variant(&value)); + return E_NOTIMPL; +} + +static const ISharedPropertyVtbl shared_property_vtbl = +{ + shared_property_QueryInterface, + shared_property_AddRef, + shared_property_Release, + shared_property_GetTypeInfoCount, + shared_property_GetTypeInfo, + shared_property_GetIDsOfNames, + shared_property_Invoke, + shared_property_get_Value, + shared_property_put_Value +}; + static HRESULT WINAPI property_group_QueryInterface(ISharedPropertyGroup *iface, REFIID riid, void **out) { struct property_group *group = impl_from_ISharedPropertyGroup(iface); @@ -91,7 +235,14 @@ static ULONG WINAPI property_group_Release(ISharedPropertyGroup *iface) if (!refcount) { struct group_manager *manager = group->parent; + struct shared_property *property;
+ EnterCriticalSection(&group->cs); + LIST_FOR_EACH_ENTRY(property, &group->properties, struct shared_property, entry) + { + SysFreeString(property->name); + } + LeaveCriticalSection(&group->cs); SysFreeString(group->name);
EnterCriticalSection(&manager->cs); @@ -99,6 +250,7 @@ static ULONG WINAPI property_group_Release(ISharedPropertyGroup *iface) LeaveCriticalSection(&manager->cs);
ISharedPropertyGroupManager_Release(&manager->ISharedPropertyGroupManager_iface); + DeleteCriticalSection(&group->cs); heap_free(group); }
@@ -177,11 +329,71 @@ static HRESULT WINAPI property_group_get_PropertyByPosition(ISharedPropertyGroup return E_NOTIMPL; }
+static struct shared_property *find_shared_property(struct property_group *group, BSTR name) +{ + struct shared_property *property; + + LIST_FOR_EACH_ENTRY(property, &group->properties, struct shared_property, entry) + { + if (!lstrcmpW(property->name, name)) + return property; + } + return NULL; +} + +static struct shared_property *create_shared_property(struct property_group *group, BSTR name, VARIANT_BOOL *exists) +{ + struct shared_property *property = NULL; + BSTR property_name; + + property = find_shared_property(group, name); + if (property) + { + *exists = TRUE; + ISharedProperty_AddRef(&property->ISharedProperty_iface); + } + else + { + property_name = SysAllocString(name); + if (property_name) + { + property = heap_alloc(sizeof(*property)); + if (property) + { + property->refcount = 1; + property->name = property_name; + property->ISharedProperty_iface.lpVtbl = &shared_property_vtbl; + *exists = FALSE; + list_add_tail(&group->properties, &property->entry); + } + else + SysFreeString(property_name); + } + } + return property; +} + static HRESULT WINAPI property_group_CreateProperty(ISharedPropertyGroup *iface, BSTR name, VARIANT_BOOL *exists, ISharedProperty **property) { - FIXME("iface %p, name %s, exists %p, property %p: stub.\n", iface, debugstr_w(name), exists, property); - return E_NOTIMPL; + struct property_group *group = impl_from_ISharedPropertyGroup(iface); + struct shared_property *shared_property; + + TRACE("iface %p, name %s, exists %p, property %p.\n", iface, debugstr_w(name), exists, property); + + EnterCriticalSection(&group->cs); + + shared_property = create_shared_property(group, name, exists); + if (!shared_property) + { + LeaveCriticalSection(&group->cs); + return E_OUTOFMEMORY; + } + *property = &shared_property->ISharedProperty_iface; + + LeaveCriticalSection(&group->cs); + + return S_OK; }
static HRESULT WINAPI property_group_get_Property(ISharedPropertyGroup *iface, BSTR name, ISharedProperty **property) @@ -339,12 +551,14 @@ struct property_group *create_property_group(struct group_manager* manager, BSTR property_group->isolation = *isolation; property_group->release = *release; property_group->refcount = 1; + list_init(&property_group->properties); property_group->name = SysAllocString(name); if (!property_group->name) { heap_free(property_group); return NULL; } + InitializeCriticalSection(&property_group->cs); list_add_tail(&manager->property_groups, &property_group->entry);
*exists = FALSE; diff --git a/dlls/comsvcs/tests/property.c b/dlls/comsvcs/tests/property.c index 7321bbcfe6..1f62656e7a 100644 --- a/dlls/comsvcs/tests/property.c +++ b/dlls/comsvcs/tests/property.c @@ -320,12 +320,93 @@ static void test_property_group(void) ISharedPropertyGroupManager_Release(manager); }
+static void test_shared_property(void) +{ + ISharedProperty *property, *property1; + ISharedPropertyGroupManager *manager; + ULONG refcount, expected_refcount; + ISharedPropertyGroup *group; + BSTR name, property_name; + LONG isolation, release; + VARIANT_BOOL exists; + IDispatch *dispatch; + HRESULT hr; + static const struct test_name_id test_name_ids[] = + { + {L"Value", DISPID_VALUE}, + }; + + hr = CoCreateInstance(&CLSID_SharedPropertyGroupManager, NULL, CLSCTX_INPROC_SERVER, + &IID_ISharedPropertyGroupManager, (void **)&manager); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + name = SysAllocString(L"testgroupname"); + isolation = 0; + release = 0; + exists = FALSE; + hr = ISharedPropertyGroupManager_CreatePropertyGroup(manager, name, &isolation, &release, &exists, &group); + ok(hr == S_OK, "Got hr %#x.\n", hr); + SysFreeString(name); + + property_name = SysAllocString(L"testpropertyname"); + exists = TRUE; + expected_refcount = get_refcount(group); + hr = ISharedPropertyGroup_CreateProperty(group, property_name, &exists, &property); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!exists, "Got unexpected value: %d.\n", exists); + refcount = get_refcount(group); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + hr = ISharedPropertyGroup_get_PropertyByPosition(group, 0, &property1); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + hr = ISharedPropertyGroup_get_PropertyByPosition(group, 1, &property1); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + exists = FALSE; + expected_refcount = get_refcount(property) + 1; + hr = ISharedPropertyGroup_CreateProperty(group, property_name, &exists, &property1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!exists, "Got unexpected value: %d.\n", exists); + refcount = get_refcount(property); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + expected_refcount--; + ISharedProperty_Release(property1); + refcount = get_refcount(property); + ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + + expected_refcount = get_refcount(property) + 1; + property1 = NULL; + hr = ISharedPropertyGroup_get_Property(group, property_name, &property1); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(property1 == property, "Got wrong pointer %p.\n", property); + refcount = get_refcount(property); + todo_wine ok(refcount == expected_refcount, "Got refcount: %u, expected %u.\n", refcount, expected_refcount); + if (property1) + ISharedProperty_Release(property1); + SysFreeString(property_name); + + property_name = SysAllocString(L"Testpropertyname"); + hr = ISharedPropertyGroup_get_Property(group, property_name, &property1); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + SysFreeString(property_name); + + hr = ISharedProperty_QueryInterface(property, &IID_IDispatch, (void **)&dispatch); + ok(hr == S_OK, "Got hr %#x.\n", hr); + TEST_TYPEINFO(dispatch, test_name_ids, ARRAY_SIZE(test_name_ids), &IID_ISharedProperty); + IDispatch_Release(dispatch); + + ISharedProperty_Release(property); + ISharedPropertyGroup_Release(group); + ISharedPropertyGroupManager_Release(manager); +} + START_TEST(property) { CoInitialize(NULL);
test_interfaces(); test_property_group(); + test_shared_property();
CoUninitialize(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79010
Your paranoid android.
=== debiant (32 bit report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit French report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (64 bit WoW report) ===
comsvcs: property.c:130: Test failed: Got hr 0x80040154. property.c:134: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00403b4d).
Report validation errors: comsvcs:property crashed (c0000005)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79006
Your paranoid android.
=== debiant (32 bit report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit French report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (32 bit WoW report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)
=== debiant (64 bit WoW report) ===
comsvcs: property.c:73: Test failed: Got hr 0x80040154. property.c:77: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004036ed).
Report validation errors: comsvcs:property crashed (c0000005)