-- v43: 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/wintypes.c | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+)
diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 1ab3f4b9af8..4137db56562 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -28,7 +28,9 @@ #include "rometadataresolution.h"
#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections #define WIDL_using_Windows_Foundation_Metadata +#include "windows.foundation.h" #include "windows.foundation.metadata.h" #include "wintypes_test.h"
@@ -1250,6 +1252,109 @@ static void test_RoParseTypeName(void) } }
+static void test_IPropertySet(void) +{ + static const WCHAR *class_name = RuntimeClass_Windows_Foundation_Collections_PropertySet; + IActivationFactory *propset_factory; + IInspectable *inspectable; + IPropertySet *propset; + IMap_HSTRING_IInspectable *map; + IMapView_HSTRING_IInspectable *map_view; + IObservableMap_HSTRING_IInspectable *observable_map; + IIterable_IKeyValuePair_HSTRING_IInspectable *iterable; + IIterator_IKeyValuePair_HSTRING_IInspectable *iterator; + HRESULT hr; + HSTRING name; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "got %#lx\n", hr ); + + hr = WindowsCreateString( class_name, wcslen( class_name ), &name ); + ok( hr == S_OK, "got %#lx\n", hr ); + hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&propset_factory ); + WindowsDeleteString( name ); + todo_wine + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory failed, hr %#lx.\n", hr ); + if (hr != S_OK) + { + todo_wine + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); + goto done; + } + + hr = IActivationFactory_ActivateInstance( propset_factory, &inspectable ); + IActivationFactory_Release( propset_factory ); + todo_wine + ok( hr == S_OK, "got %#lx\n", hr ); + if (FAILED( hr )) + { + skip("could not activate PropertySet instance.\n"); + goto done; + } + + hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset ); + IInspectable_Release( inspectable ); + todo_wine + ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); + if (FAILED( hr )) + goto done; + + hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable, (void **)&observable_map ); + todo_wine + ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + IObservableMap_HSTRING_IInspectable_Release( observable_map ); + + hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map ); + IPropertySet_Release( propset ); + todo_wine + ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); + if (FAILED( hr )) + goto done; + + hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, + (void **)&iterable ); + todo_wine + ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); + todo_wine + ok( hr == S_OK, "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( hr == S_OK, "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( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); + if (SUCCEEDED( hr )) + { + hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); + todo_wine + ok( hr == S_OK, "got %#lx\n", hr ); + if (SUCCEEDED( hr )) + IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator ); + IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); + } + IMapView_HSTRING_IInspectable_Release( map_view ); + } + IMap_HSTRING_IInspectable_Release( map ); +done: + RoUninitialize(); +} + START_TEST(wintypes) { IsWow64Process(GetCurrentProcess(), &is_wow64); @@ -1260,4 +1365,5 @@ START_TEST(wintypes) test_IPropertyValueStatics(); test_RoParseTypeName(); test_RoResolveNamespace(); + test_IPropertySet(); }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/Makefile.in | 1 + dlls/wintypes/main.c | 2 + dlls/wintypes/private.h | 2 + dlls/wintypes/propertyset.c | 207 +++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 4 - 5 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 dlls/wintypes/propertyset.c
diff --git a/dlls/wintypes/Makefile.in b/dlls/wintypes/Makefile.in index a512d3fec63..fd370133cf8 100644 --- a/dlls/wintypes/Makefile.in +++ b/dlls/wintypes/Makefile.in @@ -6,5 +6,6 @@ SOURCES = \ buffer.c \ classes.idl \ main.c \ + propertyset.c \ storage.c \ wintypes_private.idl diff --git a/dlls/wintypes/main.c b/dlls/wintypes/main.c index cb0a9b6fab0..d99c2157cf4 100644 --- a/dlls/wintypes/main.c +++ b/dlls/wintypes/main.c @@ -1720,6 +1720,8 @@ HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **fac IActivationFactory_AddRef((*factory = &api_information_statics.IActivationFactory_iface)); if (!wcscmp(buffer, L"Windows.Foundation.PropertyValue")) IActivationFactory_AddRef((*factory = &property_value_statics.IActivationFactory_iface)); + if (!wcscmp(buffer, L"Windows.Foundation.Collections.PropertySet")) + IActivationFactory_AddRef((*factory = property_set_factory)); if (!wcscmp(buffer, L"Windows.Storage.Streams.Buffer")) IActivationFactory_AddRef((*factory = buffer_activation_factory)); if (!wcscmp(buffer, L"Windows.Storage.Streams.DataWriter")) diff --git a/dlls/wintypes/private.h b/dlls/wintypes/private.h index f8d8b4e2eef..fe9e8cb951c 100644 --- a/dlls/wintypes/private.h +++ b/dlls/wintypes/private.h @@ -30,6 +30,7 @@ #include "rometadataresolution.h"
#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections #define WIDL_using_Windows_Foundation_Metadata #include "windows.foundation.metadata.h" #define WIDL_using_Windows_Storage @@ -40,3 +41,4 @@
extern IActivationFactory *data_writer_activation_factory; extern IActivationFactory *buffer_activation_factory; +extern IActivationFactory *property_set_factory; diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c new file mode 100644 index 00000000000..2f45840e9a4 --- /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> + +#include "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 = impl_from_IPropertySet( iface ); + + TRACE( "(%p)\n", iface ); + + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE propertyset_Release( IPropertySet *iface ) +{ + struct propertyset *impl = impl_from_IPropertySet( iface ); + ULONG ref; + + TRACE( "(%p)\n", 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; + LONG ref; +}; + +static inline struct propertyset_factory *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct propertyset_factory, 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 ) +{ + struct propertyset_factory *impl = impl_from_IActivationFactory( iface ); + TRACE( "(%p)\n", iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE factory_Release( IActivationFactory *iface ) +{ + struct propertyset_factory *impl = impl_from_IActivationFactory( iface ); + TRACE( "(%p)\n", iface ); + return InterlockedDecrement( &impl->ref ); +} + +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}, + 1 +}; + +IActivationFactory *property_set_factory = &propertyset_factory.IActivationFactory_iface; diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 4137db56562..71d7f10f99b 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -1273,18 +1273,15 @@ static void test_IPropertySet(void) ok( hr == S_OK, "got %#lx\n", hr ); hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&propset_factory ); WindowsDeleteString( name ); - todo_wine ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory failed, hr %#lx.\n", hr ); if (hr != S_OK) { - todo_wine win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); goto done; }
hr = IActivationFactory_ActivateInstance( propset_factory, &inspectable ); IActivationFactory_Release( propset_factory ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); if (FAILED( hr )) { @@ -1294,7 +1291,6 @@ static void test_IPropertySet(void)
hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset ); IInspectable_Release( inspectable ); - todo_wine ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); if (FAILED( hr )) goto done;
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 41 ++++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 1 - 2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 2f45840e9a4..5d96c7bb2e9 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL( wintypes ); struct propertyset { IPropertySet IPropertySet_iface; + IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface; LONG ref; };
@@ -39,6 +40,8 @@ static inline struct propertyset *impl_from_IPropertySet( IPropertySet *iface )
static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface, REFIID iid, void **out ) { + struct propertyset *impl = impl_from_IPropertySet( iface ); + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
*out = NULL; @@ -50,6 +53,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)*out ); return S_OK; } + else 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; @@ -107,6 +116,37 @@ 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; @@ -179,6 +219,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/wintypes.c b/dlls/wintypes/tests/wintypes.c index 71d7f10f99b..5908d148640 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -1296,7 +1296,6 @@ static void test_IPropertySet(void) goto done;
hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable, (void **)&observable_map ); - todo_wine ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); if (SUCCEEDED( hr )) IObservableMap_HSTRING_IInspectable_Release( observable_map );
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 73 ++++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 1 - 2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 5d96c7bb2e9..eeadb5d2435 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -30,6 +30,7 @@ struct propertyset { IPropertySet IPropertySet_iface; IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface; + IMap_HSTRING_IInspectable IMap_HSTRING_IInspectable_iface; LONG ref; };
@@ -59,6 +60,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)*out ); return S_OK; } + else 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; @@ -147,6 +154,71 @@ 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; @@ -220,6 +292,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/wintypes.c b/dlls/wintypes/tests/wintypes.c index 5908d148640..6c9f0f22ef6 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -1302,7 +1302,6 @@ static void test_IPropertySet(void)
hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map ); IPropertySet_Release( propset ); - todo_wine ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); if (FAILED( hr )) goto done;
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 33 +++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 1 - 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index eeadb5d2435..6a0ccc30c2b 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -31,6 +31,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; };
@@ -66,6 +67,12 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( (IUnknown *)iface ); return S_OK; } + else 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; @@ -219,6 +226,31 @@ 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; @@ -293,6 +325,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/wintypes.c b/dlls/wintypes/tests/wintypes.c index 6c9f0f22ef6..e480a15dcb1 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -1308,7 +1308,6 @@ static void test_IPropertySet(void)
hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, (void **)&iterable ); - todo_wine ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); if (SUCCEEDED( hr )) {
On Fri Jul 18 08:59:03 2025 +0000, Zhiyi Zhang wrote:
Did you forget to release `map_view`?
Oops, forgot about this one, thanks.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/wintypes.c:
hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&propset_factory ); WindowsDeleteString( name );
todo_wine ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "RoGetActivationFactory failed, hr %#lx.\n", hr ); if (hr != S_OK) {
todo_wine win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); goto done;
}
hr = IActivationFactory_ActivateInstance( propset_factory, &inspectable ); IActivationFactory_Release( propset_factory );
todo_wine ok( hr == S_OK, "got %#lx\n", hr ); if (FAILED( hr ))
There is no error on Windows for this test, right? So you can delete the "if (FAILED( hr ))" branch after you add the stubs. This will make the tests cleaner. Same for other places and patches.
Zhiyi Zhang (@zhiyi) commented about dlls/wintypes/tests/wintypes.c:
hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable, (void **)&iterable );
- todo_wine ok( hr == S_OK, "QueryInterface failed, got %#lx\n", hr ); if (SUCCEEDED( hr ))
Ditto for the "`if (SUCCEEDED( hr ))`"