-- v38: wintypes: Add stubs for IIterable<IKeyValuePair<HSTRING, IInspectable *>> to PropertySet. wintypes: Add stubs for IMap<HSTRING, IInspectable *> to PropertySet. wintypes: Add stubs for IObservableMap<HSTRING, IInspectable *> to PropertySet. wintypes: Add stubs for Windows.Foundation.Collections.PropertySet. wintypes/tests: Add conformance tests for Windows.Foundation.Collections.PropertySet.
From: Vibhav Pant vibhavp@gmail.com
--- include/windows.foundation.idl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl index 9e3b656d8a3..8f11da943f3 100644 --- a/include/windows.foundation.idl +++ b/include/windows.foundation.idl @@ -30,6 +30,8 @@ import "windows.foundation.collections.idl"; namespace Windows.Foundation.Collections { interface IPropertySet;
+ runtimeclass PropertySet; + declare { interface Windows.Foundation.Collections.IKeyValuePair<HSTRING, HSTRING>; interface Windows.Foundation.Collections.IKeyValuePair<HSTRING, IInspectable *>; @@ -57,6 +59,20 @@ namespace Windows.Foundation.Collections { { }
+ [ + activatable(Windows.Foundation.FoundationContract, 1.0), + contract(Windows.Foundation.FoundationContract, 1.0), + marshaling_behavior(agile), + threading(both) + ] + runtimeclass PropertySet + { + [default] interface Windows.Foundation.Collections.IPropertySet; + interface Windows.Foundation.Collections.IObservableMap<HSTRING, IInspectable *>; + interface Windows.Foundation.Collections.IMap<HSTRING, IInspectable *>; + interface Windows.Foundation.Collections.IIterable<Windows.Foundation.Collections.IKeyValuePair<HSTRING, IInspectable *> *>; + } + [ activatable(Windows.Foundation.FoundationContract, 1.0), contract(Windows.Foundation.FoundationContract, 1.0),
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/tests/Makefile.in | 1 + dlls/wintypes/tests/propertyset.c | 137 ++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 dlls/wintypes/tests/propertyset.c
diff --git a/dlls/wintypes/tests/Makefile.in b/dlls/wintypes/tests/Makefile.in index c5ae17c4694..afb4fd4a7f5 100644 --- a/dlls/wintypes/tests/Makefile.in +++ b/dlls/wintypes/tests/Makefile.in @@ -2,5 +2,6 @@ TESTDLL = wintypes.dll IMPORTS = wintypes combase uuid
SOURCES = \ + propertyset.c \ wintypes.c \ wintypes_test.idl diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c new file mode 100644 index 00000000000..14be025b6a0 --- /dev/null +++ b/dlls/wintypes/tests/propertyset.c @@ -0,0 +1,137 @@ +/* + * Copyright 2024 Vibhav Pant + * + * 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 "winstring.h" +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" + +#include "wine/test.h" + +static void test_IPropertySet(void) +{ + static const WCHAR *class_name = RuntimeClass_Windows_Foundation_Collections_PropertySet; + IActivationFactory *factory; + IInspectable *inspectable; + IPropertySet *propset; + IMap_HSTRING_IInspectable *map; + IMapView_HSTRING_IInspectable *map_view; + IIterable_IKeyValuePair_HSTRING_IInspectable *iterable; + IIterator_IKeyValuePair_HSTRING_IInspectable *iterator; + IObservableMap_HSTRING_IInspectable *observable_map; + HRESULT hr; + HSTRING name; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + + hr = WindowsCreateString( class_name, wcslen( class_name ), &name ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( name ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), + "RoGetActivationFactory failed, hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", + wine_dbgstr_w( class_name ) ); + RoUninitialize(); + return; + } + + hr = IActivationFactory_ActivateInstance( factory, &inspectable ); + IActivationFactory_Release( factory ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (FAILED( hr )) + { + skip("could not activate PropertySet instance.\n"); + RoUninitialize(); + return; + } + + hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset ); + IInspectable_Release( inspectable ); + todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + if (FAILED( hr )) + { + RoUninitialize(); + return; + } + + hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map ); + todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + if (FAILED( hr )) + { + RoUninitialize(); + return; + } + + hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable, + (void *)&observable_map ); + IPropertySet_Release( propset ); + todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + + if (map) + { + hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, + (void **)&iterable ); + todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (SUCCEEDED( hr )) + IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator ); + IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); + } + else + skip( "Could not obtain IIterable<IKeyValuePair<HSTRING, IInspectable *>> instance.\n"); + + hr = IMap_HSTRING_IInspectable_GetView( map, &map_view ); + todo_wine ok( SUCCEEDED( hr ), "GetView failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + + hr = IMapView_HSTRING_IInspectable_QueryInterface( map_view, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, + (void **)&iterable ); + todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + + hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (SUCCEEDED( hr )) + IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator ); + IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); + } + } + IMap_HSTRING_IInspectable_Release( map ); + } + + if (observable_map) + IObservableMap_HSTRING_IInspectable_Release( observable_map ); + RoUninitialize(); +} + +START_TEST(propertyset) +{ + test_IPropertySet(); +}
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/Makefile.in | 1 + dlls/wintypes/main.c | 9 +- dlls/wintypes/propertyset.c | 207 +++++++++++++++++++++++++++++ dlls/wintypes/tests/propertyset.c | 4 +- dlls/wintypes/wintypes_private.idl | 2 + 5 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 dlls/wintypes/propertyset.c
diff --git a/dlls/wintypes/Makefile.in b/dlls/wintypes/Makefile.in index b8958cdcd15..baba92dd6e3 100644 --- a/dlls/wintypes/Makefile.in +++ b/dlls/wintypes/Makefile.in @@ -5,4 +5,5 @@ IMPORTS = combase SOURCES = \ classes.idl \ main.c \ + propertyset.c \ wintypes_private.idl diff --git a/dlls/wintypes/main.c b/dlls/wintypes/main.c index ac4214b486f..8672907705f 100644 --- a/dlls/wintypes/main.c +++ b/dlls/wintypes/main.c @@ -31,6 +31,7 @@
#define WIDL_using_Windows_Foundation #define WIDL_using_Windows_Foundation_Metadata +#define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.metadata.h" #include "wintypes_private.h"
@@ -1213,8 +1214,14 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) { + const WCHAR *name; TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory); - *factory = &wintypes.IActivationFactory_iface; + + name = WindowsGetStringRawBuffer(classid, NULL); + if (!wcscmp(name, RuntimeClass_Windows_Foundation_Collections_PropertySet)) + *factory = IPropertySet_factory; + else + *factory = &wintypes.IActivationFactory_iface; IUnknown_AddRef(*factory); return S_OK; } diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c new file mode 100644 index 00000000000..a4f2be96e4a --- /dev/null +++ b/dlls/wintypes/propertyset.c @@ -0,0 +1,207 @@ +/* + * Copyright 2024 Vibhav Pant + * + * 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 <winstring.h> +#include <objbase.h> +#include <wine/debug.h> +#include <activation.h> + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "wintypes_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL( wintypes ); + +struct propertyset +{ + IPropertySet IPropertySet_iface; + LONG ref; +}; + +static inline struct propertyset *impl_from_IPropertySet( IPropertySet *iface ) +{ + return CONTAINING_RECORD( iface, struct propertyset, IPropertySet_iface ); +} + +static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface, REFIID iid, + void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + + *out = NULL; + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IPropertySet )) + { + *out = iface; + IUnknown_AddRef( (IUnknown *)*out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE propertyset_AddRef( IPropertySet *iface ) +{ + struct propertyset *impl; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IPropertySet( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE propertyset_Release( IPropertySet *iface ) +{ + struct propertyset *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IPropertySet( iface ); + ref = InterlockedDecrement( &impl->ref ); + + if (!ref) + free( impl ); + return ref; +} + +static HRESULT STDMETHODCALLTYPE propertyset_GetIids( IPropertySet *iface, ULONG *iid_count, + IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_GetRuntimeClassName( IPropertySet *iface, + HSTRING *class_name ) +{ + FIXME( "(%p, %p) stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_GetTrustLevel( IPropertySet *iface, + TrustLevel *trust_level ) +{ + FIXME( "(%p, %p) stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static const IPropertySetVtbl propertyset_vtbl = +{ + /* IUnknown */ + propertyset_QueryInterface, + propertyset_AddRef, + propertyset_Release, + /* IInspectable */ + propertyset_GetIids, + propertyset_GetRuntimeClassName, + propertyset_GetTrustLevel, +}; + +struct propertyset_factory +{ + IActivationFactory IActivationFactory_iface; +}; + +static HRESULT STDMETHODCALLTYPE factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + *out = NULL; + if (IsEqualGUID( &IID_IUnknown, iid ) || + IsEqualGUID( &IID_IInspectable, iid ) || + IsEqualGUID( &IID_IAgileObject, iid ) || + IsEqualGUID( &IID_IActivationFactory, iid )) + { + *out = iface; + IUnknown_AddRef( (IUnknown *)*out ); + return S_OK; + } + + FIXME( "%s not implemented, return E_NOINTERFACE.\n", debugstr_guid( iid ) ); + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE factory_AddRef( IActivationFactory *iface ) +{ + TRACE( "(%p)\n", iface ); + return 2; +} + +static ULONG STDMETHODCALLTYPE factory_Release( IActivationFactory *iface ) +{ + TRACE( "(%p)\n", iface ); + return 1; +} + +static HRESULT STDMETHODCALLTYPE factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "(%p, %p) stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "(%p, %p) stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + struct propertyset *impl; + + TRACE( "(%p, %p)\n", iface, instance ); + + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return E_OUTOFMEMORY; + + impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; + impl->ref = 1; + *instance = (IInspectable *)&impl->IPropertySet_iface; + return S_OK; +} + +static const IActivationFactoryVtbl propertyset_factory_vtbl = +{ + /* IUnknown */ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory */ + factory_ActivateInstance, +}; + +static struct propertyset_factory propertyset_factory = +{ + {&propertyset_factory_vtbl}, +}; + +IActivationFactory *IPropertySet_factory = &propertyset_factory.IActivationFactory_iface; diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index 14be025b6a0..666e514c10e 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -59,7 +59,7 @@ static void test_IPropertySet(void)
hr = IActivationFactory_ActivateInstance( factory, &inspectable ); IActivationFactory_Release( factory ); - todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); if (FAILED( hr )) { skip("could not activate PropertySet instance.\n"); @@ -69,7 +69,7 @@ static void test_IPropertySet(void)
hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset ); IInspectable_Release( inspectable ); - todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); if (FAILED( hr )) { RoUninitialize(); diff --git a/dlls/wintypes/wintypes_private.idl b/dlls/wintypes/wintypes_private.idl index b0d7b7d2241..d08adfebc43 100644 --- a/dlls/wintypes/wintypes_private.idl +++ b/dlls/wintypes/wintypes_private.idl @@ -66,3 +66,5 @@ cpp_quote(" }")
cpp_quote("#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \") cpp_quote(" DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface )") + +cpp_quote("extern IActivationFactory *IPropertySet_factory;")
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 44 +++++++++++++++++++++++++++++++ dlls/wintypes/tests/propertyset.c | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index a4f2be96e4a..e2ed7ee37da 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -31,6 +31,7 @@ WINE_DEFAULT_DEBUG_CHANNEL( wintypes ); struct propertyset { IPropertySet IPropertySet_iface; + IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface; LONG ref; };
@@ -42,8 +43,11 @@ static inline struct propertyset *impl_from_IPropertySet( IPropertySet *iface ) static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface, REFIID iid, void **out ) { + struct propertyset *impl; + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
+ impl = impl_from_IPropertySet( iface ); *out = NULL; if (IsEqualGUID( iid, &IID_IUnknown ) || IsEqualGUID( iid, &IID_IInspectable ) || @@ -53,6 +57,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)*out ); return S_OK; } + if (IsEqualGUID( iid, &IID_IObservableMap_HSTRING_IInspectable )) + { + *out = &impl->IObservableMap_HSTRING_IInspectable_iface; + IUnknown_AddRef( (IUnknown *)*out ); + return S_OK; + }
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); return E_NOINTERFACE; @@ -116,6 +126,39 @@ static const IPropertySetVtbl propertyset_vtbl = propertyset_GetTrustLevel, };
+DEFINE_IINSPECTABLE( propertyset_IObservableMap, IObservableMap_HSTRING_IInspectable, + struct propertyset, IPropertySet_iface ); + +static HRESULT STDMETHODCALLTYPE propertyset_IObservableMap_add_MapChanged( + IObservableMap_HSTRING_IInspectable *iface, + IMapChangedEventHandler_HSTRING_IInspectable *handler, EventRegistrationToken *token ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, handler, token ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_IObservableMap_remove_MapChanged( + IObservableMap_HSTRING_IInspectable *iface, EventRegistrationToken token ) +{ + FIXME( "(%p, %I64d) stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +const static IObservableMap_HSTRING_IInspectableVtbl propertyset_IObservableMap_vtbl = +{ + /* IUnknown */ + propertyset_IObservableMap_QueryInterface, + propertyset_IObservableMap_AddRef, + propertyset_IObservableMap_Release, + /* IInspectable */ + propertyset_IObservableMap_GetIids, + propertyset_IObservableMap_GetRuntimeClassName, + propertyset_IObservableMap_GetTrustLevel, + /* IObservableMap<HSTRING, IInspectable*> */ + propertyset_IObservableMap_add_MapChanged, + propertyset_IObservableMap_remove_MapChanged, +}; + struct propertyset_factory { IActivationFactory IActivationFactory_iface; @@ -180,6 +223,7 @@ static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *i return E_OUTOFMEMORY;
impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; + impl->IObservableMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IObservableMap_vtbl; impl->ref = 1; *instance = (IInspectable *)&impl->IPropertySet_iface; return S_OK; diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index 666e514c10e..b959c574780 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -87,7 +87,7 @@ static void test_IPropertySet(void) hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable, (void *)&observable_map ); IPropertySet_Release( propset ); - todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (map) {
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 81 +++++++++++++++++++++++++++++++ dlls/wintypes/tests/propertyset.c | 2 +- 2 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index e2ed7ee37da..2cd70087606 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -32,6 +32,7 @@ struct propertyset { IPropertySet IPropertySet_iface; IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface; + IMap_HSTRING_IInspectable IMap_HSTRING_IInspectable_iface; LONG ref; };
@@ -63,6 +64,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)*out ); return S_OK; } + if (IsEqualGUID( iid, &IID_IMap_HSTRING_IInspectable )) + { + *out = &impl->IMap_HSTRING_IInspectable_iface; + IUnknown_AddRef( (IUnknown *)iface ); + return S_OK; + }
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); return E_NOINTERFACE; @@ -159,6 +166,79 @@ const static IObservableMap_HSTRING_IInspectableVtbl propertyset_IObservableMap_ propertyset_IObservableMap_remove_MapChanged, };
+DEFINE_IINSPECTABLE( propertyset_IMap, IMap_HSTRING_IInspectable, struct propertyset, + IPropertySet_iface ); + +static HRESULT STDMETHODCALLTYPE propertyset_Lookup( IMap_HSTRING_IInspectable *iface, + HSTRING key, + IInspectable **value ) +{ + FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), value ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +propertyset_get_size( IMap_HSTRING_IInspectable *iface, UINT32 *size ) +{ + FIXME( "(%p, %p) stub!\n", iface, size ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_HasKey( IMap_HSTRING_IInspectable *iface, + HSTRING key, boolean *exists ) +{ + FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), exists ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_GetView( + IMap_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **view ) +{ + FIXME( "(%p, %p) stub!\n", iface, view ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_Insert( IMap_HSTRING_IInspectable *iface, + HSTRING key, IInspectable *value, + boolean *replaced ) +{ + FIXME( "(%p, %s, %p, %p) stub!\n", iface, debugstr_hstring( key ), value, replaced ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_Remove( IMap_HSTRING_IInspectable *iface, + HSTRING key ) +{ + FIXME( "(%p, %s) stub!\n", iface, debugstr_hstring( key ) ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_Clear( IMap_HSTRING_IInspectable *iface ) +{ + FIXME( "(%p) stub!\n", iface ); + return E_NOTIMPL; +} + +const static IMap_HSTRING_IInspectableVtbl propertyset_IMap_vtbl = +{ + /* IUnknown */ + propertyset_IMap_QueryInterface, + propertyset_IMap_AddRef, + propertyset_IMap_Release, + /* IInspectable */ + propertyset_IMap_GetIids, + propertyset_IMap_GetRuntimeClassName, + propertyset_IMap_GetTrustLevel, + /* IMap<HSTRING, IInspectable*> */ + propertyset_Lookup, + propertyset_get_size, + propertyset_HasKey, + propertyset_GetView, + propertyset_Insert, + propertyset_Remove, + propertyset_Clear, +}; + struct propertyset_factory { IActivationFactory IActivationFactory_iface; @@ -224,6 +304,7 @@ static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *i
impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; impl->IObservableMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IObservableMap_vtbl; + impl->IMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IMap_vtbl; impl->ref = 1; *instance = (IInspectable *)&impl->IPropertySet_iface; return S_OK; diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index b959c574780..95385cfc217 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -77,7 +77,7 @@ static void test_IPropertySet(void) }
hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map ); - todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); if (FAILED( hr )) { RoUninitialize();
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 36 +++++++++++++++++++++++++++++++ dlls/wintypes/tests/propertyset.c | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 2cd70087606..3aabf4d40f4 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -33,6 +33,7 @@ struct propertyset IPropertySet IPropertySet_iface; IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface; IMap_HSTRING_IInspectable IMap_HSTRING_IInspectable_iface; + IIterable_IKeyValuePair_HSTRING_IInspectable IIterable_IKeyValuePair_HSTRING_IInspectable_iface; LONG ref; };
@@ -70,6 +71,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)iface ); return S_OK; } + if (IsEqualGUID( iid, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable )) + { + *out = &impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface; + IUnknown_AddRef( (IUnknown *)iface ); + return S_OK; + }
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); return E_NOINTERFACE; @@ -239,6 +246,34 @@ const static IMap_HSTRING_IInspectableVtbl propertyset_IMap_vtbl = propertyset_Clear, };
+DEFINE_IINSPECTABLE_( iterable_kvpair_HSTRING_IInspectable, + IIterable_IKeyValuePair_HSTRING_IInspectable, struct propertyset, + impl_from_IIterable_IKeyValuePair_HSTRING_IInspectable, + IIterable_IKeyValuePair_HSTRING_IInspectable_iface, + &impl->IMap_HSTRING_IInspectable_iface ); + +static HRESULT STDMETHODCALLTYPE +iterable_kvpair_HSTRING_IInspectable_First( IIterable_IKeyValuePair_HSTRING_IInspectable *iface, + IIterator_IKeyValuePair_HSTRING_IInspectable **iter ) +{ + FIXME( "(%p, %p) stub!\n", iface, iter ); + return E_NOTIMPL; +} + +const static IIterable_IKeyValuePair_HSTRING_IInspectableVtbl iterable_kvpair_HSTRING_IInspectable_vtbl = +{ + /* IUnknown */ + iterable_kvpair_HSTRING_IInspectable_QueryInterface, + iterable_kvpair_HSTRING_IInspectable_AddRef, + iterable_kvpair_HSTRING_IInspectable_Release, + /* IInspectable */ + iterable_kvpair_HSTRING_IInspectable_GetIids, + iterable_kvpair_HSTRING_IInspectable_GetRuntimeClassName, + iterable_kvpair_HSTRING_IInspectable_GetTrustLevel, + /* IIterable<IKeyValuePair<HSTRING, IInspectable*>> */ + iterable_kvpair_HSTRING_IInspectable_First +}; + struct propertyset_factory { IActivationFactory IActivationFactory_iface; @@ -305,6 +340,7 @@ static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *i impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; impl->IObservableMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IObservableMap_vtbl; impl->IMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IMap_vtbl; + impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl = &iterable_kvpair_HSTRING_IInspectable_vtbl; impl->ref = 1; *instance = (IInspectable *)&impl->IPropertySet_iface; return S_OK; diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index 95385cfc217..7d2f214ed20 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -93,7 +93,7 @@ static void test_IPropertySet(void) { hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, (void **)&iterable ); - todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr ); if (SUCCEEDED( hr )) { hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149845
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000000A70100, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032 win.c:4070: Test failed: Expected active window 0000000004690170, got 0000000000000000. win.c:4071: Test failed: Expected focus window 0000000004690170, got 0000000000000000.
On Tue Nov 19 10:07:44 2024 +0000, Zhiyi Zhang wrote:
Let's keep it small for this MR. ~5 should be best. 8 is a bit too much. Having more patches in one MR makes it harder to review.
Okay, truncated the MR to 6 commits.
On Thu Nov 21 21:45:18 2024 +0000, Zhiyi Zhang wrote:
Add these interfaces in separate commits.
Done
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/propertyset.c:
return;
- }
- hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset );
- IInspectable_Release( inspectable );
- todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
- if (FAILED( hr ))
- {
RoUninitialize();
return;
- }
- hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map );
- todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
- if (FAILED( hr ))
- {
Leaking propset here. And you might want to use a "goto done;" to simplify failure handling.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/propertyset.c:
- }
- hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map );
- todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
- if (FAILED( hr ))
- {
RoUninitialize();
return;
- }
- hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable,
(void *)&observable_map );
- IPropertySet_Release( propset );
- todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
- if (map)
You already check that IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map ); should succeed and return directly when failed. So I don't think map can be NULL here.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/propertyset.c:
if (SUCCEEDED( hr ))
{
hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (SUCCEEDED( hr ))
IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator );
IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable );
}
else
skip( "Could not obtain IIterable<IKeyValuePair<HSTRING, IInspectable *>> instance.\n");
hr = IMap_HSTRING_IInspectable_GetView( map, &map_view );
todo_wine ok( SUCCEEDED( hr ), "GetView failed, got %#lx\n", hr );
if (SUCCEEDED( hr ))
{
Delete this empty line here.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/propertyset.c:
- todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
- if (map)
- {
hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable,
(void **)&iterable );
todo_wine ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (SUCCEEDED( hr ))
{
hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (SUCCEEDED( hr ))
IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator );
IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable );
}
else
Add curly braces for the else branch if one of the branches has them.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/main.c:
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) {
- const WCHAR *name; TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
- *factory = &wintypes.IActivationFactory_iface;
- name = WindowsGetStringRawBuffer(classid, NULL);
- if (!wcscmp(name, RuntimeClass_Windows_Foundation_Collections_PropertySet))
*factory = IPropertySet_factory;
Let's rename it to propertyset_factory.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/propertyset.c:
- propertyset_AddRef,
- propertyset_Release,
- /* IInspectable */
- propertyset_GetIids,
- propertyset_GetRuntimeClassName,
- propertyset_GetTrustLevel,
+};
+struct propertyset_factory +{
- IActivationFactory IActivationFactory_iface;
+};
+static HRESULT STDMETHODCALLTYPE factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{
- TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
Add an empty line after this.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/propertyset.c:
static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface, REFIID iid, void **out ) {
struct propertyset *impl;
TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
impl = impl_from_IPropertySet( iface );
Let's initialize it when doing the variable declaration.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/propertyset.c:
IUnknown_AddRef( (IUnknown *)*out ); return S_OK; }
- if (IsEqualGUID( iid, &IID_IMap_HSTRING_IInspectable ))
Let's use "else if" here.