-- v23: wintypes: Add stubs for IKeyValuePair<HSTRING, IInspectable *>. wintypes: Add stubs for IIterator<IKeyValuePair<HSTRING, IInspectable *>>. wintypes: Add stubs for IMapView<HSTRING, IInspectable *>. wintypes: Add stubs for IMap<HSTRING, IInspectable *>, IObservableMap<HSTRING, IInspectable *>, IIterable<IKeyValuePair<HSTRING, IInspectable *>> to PropertySet implementation. wintypes: Add stub for Windows.Foundation.Collections.PropertySet. wintypes/test: Add conformance tests for Windows.Foundation.Collections.PropertySet.
From: Vibhav Pant vibhavp@gmail.com
--- include/windows.foundation.idl | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl index 9e3b656d8a3..c6c4c491236 100644 --- a/include/windows.foundation.idl +++ b/include/windows.foundation.idl @@ -57,6 +57,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 | 153 ++++++++++++++++++++++++++++++ 2 files changed, 154 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..aff3aee465b --- /dev/null +++ b/dlls/wintypes/tests/propertyset.c @@ -0,0 +1,153 @@ +/* + * 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 "wintypes_test.h" + +#include "wine/test.h" + +static void test_IPropertySet(void) +{ + static const WCHAR *class_name = RuntimeClass_Windows_Foundation_Collections_PropertySet; + IActivationFactory *factory; + IInspectable *inspectable; + IPropertyValueStatics *statics; + 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 ); + 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 ) ); + WindowsDeleteString( name ); + RoUninitialize(); + return; + } + WindowsDeleteString( name ); + class_name = RuntimeClass_Windows_Foundation_PropertyValue; + hr = WindowsCreateString( class_name, wcslen( class_name ), &name ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + hr = RoGetActivationFactory( name, &IID_IPropertyValueStatics, (void **)&statics ); + 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 ) ); + WindowsDeleteString( name ); + RoUninitialize(); + return; + } + WindowsDeleteString( name ); + + 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"); + IPropertyValueStatics_Release( statics ); + 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 )) + { + IPropertyValueStatics_Release( statics ); + 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 )) + { + IPropertyValueStatics_Release( statics ); + 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); + + 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 ); + IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator ); + } + 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 ), "QuerInterface failed, got %#lx\n", hr ); + if (iterable) + { + hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); + IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + if (iterator) + IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator ); + + } + } + + IObservableMap_HSTRING_IInspectable_Release( observable_map ); + IMap_HSTRING_IInspectable_Release( map ); + IPropertyValueStatics_Release( statics ); + RoUninitialize(); +} + +START_TEST(propertyset) +{ + test_IPropertySet(); +}
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/Makefile.in | 1 + dlls/wintypes/main.c | 32 ++++++- dlls/wintypes/propertyset.c | 136 +++++++++++++++++++++++++++++ dlls/wintypes/tests/propertyset.c | 4 +- dlls/wintypes/wintypes_private.idl | 2 + 5 files changed, 172 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..44606e57bd4 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"
@@ -60,6 +61,7 @@ static BOOLEAN is_api_contract_present( const HSTRING hname, unsigned int versio struct wintypes { IActivationFactory IActivationFactory_iface; + IActivationFactory IPropertySet_IActivationFactory_iface; IApiInformationStatics IApiInformationStatics_iface; IPropertyValueStatics IPropertyValueStatics_iface; LONG ref; @@ -150,6 +152,13 @@ static HRESULT STDMETHODCALLTYPE wintypes_ActivateInstance(IActivationFactory *i return E_NOTIMPL; }
+static HRESULT STDMETHODCALLTYPE propertyset_factory_ActivateInstance(IActivationFactory *iface, + IInspectable **instance) +{ + TRACE("iface %p, instance %p\n", iface, instance); + return propertyset_create((IPropertySet **)instance); +} + static const struct IActivationFactoryVtbl activation_factory_vtbl = { wintypes_QueryInterface, @@ -163,6 +172,19 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl = wintypes_ActivateInstance, };
+static const struct IActivationFactoryVtbl propertyset_factory_vtbl = +{ + wintypes_QueryInterface, + wintypes_AddRef, + wintypes_Release, + /* IInspectable methods */ + wintypes_GetIids, + wintypes_GetRuntimeClassName, + wintypes_GetTrustLevel, + /* IActivationFactory methods */ + propertyset_factory_ActivateInstance, +}; + DEFINE_IINSPECTABLE(api_information_statics, IApiInformationStatics, struct wintypes, IActivationFactory_iface)
static HRESULT STDMETHODCALLTYPE api_information_statics_IsTypePresent( @@ -1200,6 +1222,7 @@ static const struct IPropertyValueStaticsVtbl property_value_statics_vtbl = static struct wintypes wintypes = { {&activation_factory_vtbl}, + {&propertyset_factory_vtbl}, {&api_information_statics_vtbl}, {&property_value_statics_vtbl}, 1 @@ -1213,8 +1236,15 @@ 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 = &wintypes.IPropertySet_IActivationFactory_iface; + 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..74c5b37be1f --- /dev/null +++ b/dlls/wintypes/propertyset.c @@ -0,0 +1,136 @@ +/* + * 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( iface ); + 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; +} + +const static IPropertySetVtbl propertyset_vtbl = +{ + /* IUnknown */ + propertyset_QueryInterface, + propertyset_AddRef, + propertyset_Release, + /* IInspectable */ + propertyset_GetIids, + propertyset_GetRuntimeClassName, + propertyset_GetTrustLevel, +}; + +HRESULT propertyset_create( IPropertySet **iface ) +{ + struct propertyset *impl; + + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return E_OUTOFMEMORY; + + impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; + impl->ref = 1; + + *iface = &impl->IPropertySet_iface; + return S_OK; +} diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index aff3aee465b..fca885a0303 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -77,7 +77,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"); @@ -88,7 +88,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 )) { IPropertyValueStatics_Release( statics ); diff --git a/dlls/wintypes/wintypes_private.idl b/dlls/wintypes/wintypes_private.idl index b0d7b7d2241..fea76193c2c 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("HRESULT propertyset_create(IPropertySet **);")
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 169 +++++++++++++++++++++++++++++- dlls/wintypes/tests/propertyset.c | 6 +- 2 files changed, 171 insertions(+), 4 deletions(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 74c5b37be1f..ccbe30010fd 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -33,6 +33,9 @@ WINE_DEFAULT_DEBUG_CHANNEL( wintypes ); 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; }; @@ -46,8 +49,11 @@ 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 ) || @@ -57,6 +63,24 @@ static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface IUnknown_AddRef( iface ); return S_OK; } + if (IsEqualGUID( iid, &IID_IObservableMap_HSTRING_IInspectable )) + { + *out = &impl->IObservableMap_HSTRING_IInspectable_iface; + IUnknown_AddRef( iface ); + return S_OK; + } + if (IsEqualGUID( iid, &IID_IMap_HSTRING_IInspectable )) + { + *out = &impl->IMap_HSTRING_IInspectable_iface; + IUnknown_AddRef( iface ); + return S_OK; + } + if (IsEqualGUID( iid, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable )) + { + *out = &impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface; + IUnknown_AddRef( iface ); + return S_OK; + }
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); return E_NOINTERFACE; @@ -84,6 +108,7 @@ static ULONG STDMETHODCALLTYPE propertyset_Release( IPropertySet *iface )
if (!ref) free( impl ); + return ref; }
@@ -120,6 +145,144 @@ const static 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, +}; + +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 ); + *value = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +propertyset_get_size( IMap_HSTRING_IInspectable *iface, UINT32 *size ) +{ + FIXME( "(%p, %p) stub!\n", iface, size ); + *size = 0; + 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 ); + *exists = 0; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE propertyset_GetView( + IMap_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **view ) +{ + FIXME( "(%p, %p) stub!\n", iface, view ); + *view = NULL; + 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 ); + *replaced = 0; + 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, +}; + +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 ) +{ + 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 +}; + HRESULT propertyset_create( IPropertySet **iface ) { struct propertyset *impl; @@ -129,8 +292,12 @@ HRESULT propertyset_create( IPropertySet **iface ) return E_OUTOFMEMORY;
impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl; - impl->ref = 1; + 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; *iface = &impl->IPropertySet_iface; return S_OK; } diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index fca885a0303..9b8235192a6 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -97,7 +97,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 )) { IPropertyValueStatics_Release( statics ); @@ -108,11 +108,11 @@ 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);
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 );
From: Vibhav Pant vibhavp@gmail.com
Implement GetView() for Windows.Foundation.Collections.PropertySet using an instance of this stub. --- dlls/wintypes/propertyset.c | 187 +++++++++++++++++++++++++++++- dlls/wintypes/tests/propertyset.c | 4 +- 2 files changed, 187 insertions(+), 4 deletions(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index ccbe30010fd..00736812730 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -30,6 +30,176 @@
WINE_DEFAULT_DEBUG_CHANNEL( wintypes );
+struct mapview_HSTRING_IInspectable +{ + IMapView_HSTRING_IInspectable IMapView_HSTRING_IInspectable_iface; + IIterable_IKeyValuePair_HSTRING_IInspectable IIterable_IKeyValuePair_HSTRING_IInspectable_iface; + + LONG ref; +}; + +static inline struct mapview_HSTRING_IInspectable * +impl_from_IMapView_HSTRING_IInspectable( IMapView_HSTRING_IInspectable *iface ) +{ + return CONTAINING_RECORD( iface, struct mapview_HSTRING_IInspectable, + IMapView_HSTRING_IInspectable_iface ); +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_QueryInterface( + IMapView_HSTRING_IInspectable *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_IMapView_HSTRING_IInspectable )) + { + *out = iface; + IUnknown_AddRef( iface ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable )) + { + struct mapview_HSTRING_IInspectable *impl = + impl_from_IMapView_HSTRING_IInspectable( iface ); + *out = &impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface; + IUnknown_AddRef( iface ); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE +mapview_HSTRING_IInspectable_AddRef( IMapView_HSTRING_IInspectable *iface ) +{ + struct mapview_HSTRING_IInspectable *impl; + + TRACE( "(%p)\n", iface ); + impl = impl_from_IMapView_HSTRING_IInspectable( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE +mapview_HSTRING_IInspectable_Release( IMapView_HSTRING_IInspectable *iface ) +{ + struct mapview_HSTRING_IInspectable *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + impl = impl_from_IMapView_HSTRING_IInspectable( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + { + free( impl ); + } + + return ref; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetIids( + IMapView_HSTRING_IInspectable *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetRuntimeClassName( + IMapView_HSTRING_IInspectable *iface, HSTRING *class_name ) +{ + FIXME( "(%p, %p) stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetTrustLevel( + IMapView_HSTRING_IInspectable *iface, TrustLevel *trust_level ) +{ + FIXME( "(%p, %p) stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +mapview_HSTRING_IInspectable_get_Size( IMapView_HSTRING_IInspectable *iface, UINT32 *size ) +{ + FIXME( "(%p, %p) stub!\n", iface, size ); + *size = 0; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_HaKey( + IMapView_HSTRING_IInspectable *iface, HSTRING key, boolean *exists ) +{ + FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), exists ); + *exists = 0; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_Lookup( + IMapView_HSTRING_IInspectable *iface, HSTRING key, IInspectable **value ) +{ + FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), value ); + *value = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_Split( + IMapView_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **first, + IMapView_HSTRING_IInspectable **second ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, first, second ); + *first = NULL; + *second = NULL; + return E_NOTIMPL; +} + +const static IMapView_HSTRING_IInspectableVtbl mapview_HSTRING_IInspectable_vtbl = +{ + /* IUnknown */ + mapview_HSTRING_IInspectable_QueryInterface, + mapview_HSTRING_IInspectable_AddRef, + mapview_HSTRING_IInspectable_Release, + /* IInspectable */ + mapview_HSTRING_IInspectable_GetIids, + mapview_HSTRING_IInspectable_GetRuntimeClassName, + mapview_HSTRING_IInspectable_GetTrustLevel, + /* IMapView<HSTRING, IInspectable*> */ + mapview_HSTRING_IInspectable_Lookup, + mapview_HSTRING_IInspectable_get_Size, + mapview_HSTRING_IInspectable_HaKey, + mapview_HSTRING_IInspectable_Split, +}; + +DEFINE_IINSPECTABLE_( mapview_iterable_kvpair_HSTRING_IInspectable, + IIterable_IKeyValuePair_HSTRING_IInspectable, + struct mapview_HSTRING_IInspectable, + mapview_impl_from_IIterable_IKeyValuePair_HSTRING_IInspectable, + IIterable_IKeyValuePair_HSTRING_IInspectable_iface, + &impl->IMapView_HSTRING_IInspectable_iface ); + +static HRESULT STDMETHODCALLTYPE mapview_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 + mapview_iterable_kvpair_HSTRING_IInspectable_vtbl = +{ + /* IUnknown */ + mapview_iterable_kvpair_HSTRING_IInspectable_QueryInterface, + mapview_iterable_kvpair_HSTRING_IInspectable_AddRef, + mapview_iterable_kvpair_HSTRING_IInspectable_Release, + /* IInspectable */ + mapview_iterable_kvpair_HSTRING_IInspectable_GetIids, + mapview_iterable_kvpair_HSTRING_IInspectable_GetRuntimeClassName, + mapview_iterable_kvpair_HSTRING_IInspectable_GetTrustLevel, + /* IIterable<IKeyValuePair<HSTRING, IInspectable*>> */ + mapview_iterable_kvpair_HSTRING_IInspectable_First +}; + struct propertyset { IPropertySet IPropertySet_iface; @@ -209,9 +379,22 @@ static HRESULT STDMETHODCALLTYPE propertyset_HasKey( IMap_HSTRING_IInspectable * static HRESULT STDMETHODCALLTYPE propertyset_GetView( IMap_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **view ) { - FIXME( "(%p, %p) stub!\n", iface, view ); + struct mapview_HSTRING_IInspectable *view_impl; + + FIXME( "(%p, %p) semi-stub!\n", iface, view ); *view = NULL; - return E_NOTIMPL; + view_impl = calloc( 1, sizeof( *view_impl ) ); + if (!view_impl) + return E_OUTOFMEMORY; + + view_impl->IMapView_HSTRING_IInspectable_iface.lpVtbl = &mapview_HSTRING_IInspectable_vtbl; + view_impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl = + &mapview_iterable_kvpair_HSTRING_IInspectable_vtbl; + + view_impl->ref = 1; + *view = &view_impl->IMapView_HSTRING_IInspectable_iface; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE propertyset_Insert( IMap_HSTRING_IInspectable *iface, diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index 9b8235192a6..b91cc0ed46d 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -124,12 +124,12 @@ static void test_IPropertySet(void) 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 ); + 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 ), "QuerInterface failed, got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "QuerInterface failed, got %#lx\n", hr ); if (iterable) { hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 172 +++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 3 deletions(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 00736812730..343fe597cf6 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -30,6 +30,171 @@
WINE_DEFAULT_DEBUG_CHANNEL( wintypes );
+struct iterator_kvpair_HSTRING_IInspectable +{ + IIterator_IKeyValuePair_HSTRING_IInspectable iface; + + LONG ref; +}; + +static inline struct iterator_kvpair_HSTRING_IInspectable * +impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface ) +{ + return CONTAINING_RECORD( iface, struct iterator_kvpair_HSTRING_IInspectable, iface ); +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_QueryInterface( + IIterator_IKeyValuePair_HSTRING_IInspectable *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_IIterator_IKeyValuePair_HSTRING_IInspectable )) + { + *out = iface; + IUnknown_AddRef( iface ); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE +iterator_kvpair_HSTRING_IInspectable_AddRef( IIterator_IKeyValuePair_HSTRING_IInspectable *iface ) +{ + struct iterator_kvpair_HSTRING_IInspectable *impl; + + TRACE( "(%p)\n", iface ); + impl = impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE +iterator_kvpair_HSTRING_IInspectable_Release( IIterator_IKeyValuePair_HSTRING_IInspectable *iface ) +{ + struct iterator_kvpair_HSTRING_IInspectable *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + impl = impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetIids( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetRuntimeClassName( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, HSTRING *class_name ) +{ + FIXME( "(%p, %p) stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetTrustLevel( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, TrustLevel *trust_level ) +{ + FIXME( "(%p, %p) stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +iterator_kvpair_HSTRING_IInspectable_get_Current( IIterator_IKeyValuePair_HSTRING_IInspectable *iface, + IKeyValuePair_HSTRING_IInspectable **kvpair ) +{ + FIXME( "(%p, %p) stub!\n", iface, kvpair ); + *kvpair = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_HasCurrent( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, boolean *exists ) +{ + FIXME( "(%p, %p) stub!\n", iface, exists ); + *exists = 0; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_MoveNext( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, boolean *valid ) +{ + FIXME( "(%p, %p) stub!\n", iface, valid ); + *valid = 0; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetMany( + IIterator_IKeyValuePair_HSTRING_IInspectable *iface, UINT32 count, + IKeyValuePair_HSTRING_IInspectable **items, UINT32 *value ) +{ + boolean end = 0; + HRESULT hr; + + TRACE( "(%p, %u, %p, %p)\n", iface, count, items, value ); + + for (*value = 0; *value < count && !end; *value += 1) + { + hr = IIterator_IKeyValuePair_HSTRING_IInspectable_get_Current( iface, &items[*value] ); + if (FAILED( hr )) + { + *value += 1; + return hr; + } + + hr = IIterator_IKeyValuePair_HSTRING_IInspectable_MoveNext( iface, &end ); + if (FAILED( hr )) + { + *value += 1; + return hr; + } + } + + return S_OK; +} + +const static IIterator_IKeyValuePair_HSTRING_IInspectableVtbl iterator_kvpair_HSTRING_IInspectable_vtbl = +{ + /* IUnknown */ + iterator_kvpair_HSTRING_IInspectable_QueryInterface, + iterator_kvpair_HSTRING_IInspectable_AddRef, + iterator_kvpair_HSTRING_IInspectable_Release, + /* IInspectable */ + iterator_kvpair_HSTRING_IInspectable_GetIids, + iterator_kvpair_HSTRING_IInspectable_GetRuntimeClassName, + iterator_kvpair_HSTRING_IInspectable_GetTrustLevel, + /* IIterator<IKeyValuePair<HSTRING,IInspectable*>> */ + iterator_kvpair_HSTRING_IInspectable_get_Current, + iterator_kvpair_HSTRING_IInspectable_HasCurrent, + iterator_kvpair_HSTRING_IInspectable_MoveNext, + iterator_kvpair_HSTRING_IInspectable_GetMany, +}; + +static HRESULT +iterator_kvpair_HSTRING_IInspectable_create( IIterator_IKeyValuePair_HSTRING_IInspectable **iface ) +{ + struct iterator_kvpair_HSTRING_IInspectable *impl_iter; + + TRACE( "(%p)\n", iface ); + + impl_iter = calloc( 1, sizeof( *impl_iter ) ); + if (!impl_iter) + return E_OUTOFMEMORY; + + impl_iter->iface.lpVtbl = &iterator_kvpair_HSTRING_IInspectable_vtbl; + impl_iter->ref = 1; + *iface = &impl_iter->iface; + return S_OK; +} + struct mapview_HSTRING_IInspectable { IMapView_HSTRING_IInspectable IMapView_HSTRING_IInspectable_iface; @@ -181,8 +346,8 @@ static HRESULT STDMETHODCALLTYPE mapview_iterable_kvpair_HSTRING_IInspectable_Fi IIterable_IKeyValuePair_HSTRING_IInspectable *iface, IIterator_IKeyValuePair_HSTRING_IInspectable **iter ) { - FIXME( "(%p, %p) stub!\n", iface, iter ); - return E_NOTIMPL; + FIXME( "(%p, %p) semi-stub!\n", iface, iter ); + return iterator_kvpair_HSTRING_IInspectable_create( iter ); }
const static IIterable_IKeyValuePair_HSTRING_IInspectableVtbl @@ -449,7 +614,8 @@ static HRESULT STDMETHODCALLTYPE iterable_kvpair_HSTRING_IInspectable_First( IIterable_IKeyValuePair_HSTRING_IInspectable *iface, IIterator_IKeyValuePair_HSTRING_IInspectable **iter ) { - return E_NOTIMPL; + FIXME( "(%p, %p) semi-stub!\n", iface, iter ); + return iterator_kvpair_HSTRING_IInspectable_create( iter ); }
const static IIterable_IKeyValuePair_HSTRING_IInspectableVtbl iterable_kvpair_HSTRING_IInspectable_vtbl =
From: Vibhav Pant vibhavp@gmail.com
--- dlls/wintypes/propertyset.c | 126 +++++++++++++++++++++++++++++- dlls/wintypes/tests/propertyset.c | 2 +- 2 files changed, 124 insertions(+), 4 deletions(-)
diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c index 343fe597cf6..d60ed5f264e 100644 --- a/dlls/wintypes/propertyset.c +++ b/dlls/wintypes/propertyset.c @@ -30,6 +30,127 @@
WINE_DEFAULT_DEBUG_CHANNEL( wintypes );
+struct kvpair +{ + IKeyValuePair_HSTRING_IInspectable iface; + + LONG ref; +}; + +static inline struct kvpair * +impl_from_IKeyValuePair_HSTRING_IInspectable( IKeyValuePair_HSTRING_IInspectable *iface ) +{ + return CONTAINING_RECORD( iface, struct kvpair, iface ); +} + +static HRESULT STDMETHODCALLTYPE kvpair_QueryInterface( IKeyValuePair_HSTRING_IInspectable *iface, + REFIID iid, void **out ) +{ + TRACE( "(%p, %p, %p)\n", iface, debugstr_guid( iid ), out ); + *out = NULL; + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IKeyValuePair_HSTRING_IInspectable )) + { + *out = iface; + IUnknown_AddRef( iface ); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE kvpair_AddRef( IKeyValuePair_HSTRING_IInspectable *iface ) +{ + struct kvpair *impl; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IKeyValuePair_HSTRING_IInspectable( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG STDMETHODCALLTYPE kvpair_Release( IKeyValuePair_HSTRING_IInspectable *iface ) +{ + struct kvpair *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IKeyValuePair_HSTRING_IInspectable( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE kvpair_GetIIDs( IKeyValuePair_HSTRING_IInspectable *iface, + ULONG *iid_count, IID **iids ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +kvpair_GetRuntimeClassName( IKeyValuePair_HSTRING_IInspectable *iface, HSTRING *class_name ) +{ + FIXME( "(%p, %p) stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE kvpair_GetTrustLevel( IKeyValuePair_HSTRING_IInspectable *iface, + TrustLevel *trust_level ) +{ + FIXME( "(%p, %p) stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE kvpair_get_Key( IKeyValuePair_HSTRING_IInspectable *iface, + HSTRING *key ) +{ + FIXME( "(%p, %p) stub!\n", iface, key ); + *key = NULL; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE kvpair_get_Value( IKeyValuePair_HSTRING_IInspectable *iface, + IInspectable **value ) +{ + FIXME( "(%p, %p) stub!\n", iface, value ); + *value = NULL; + return E_NOTIMPL; +} + +const static IKeyValuePair_HSTRING_IInspectableVtbl kvpair_vtbl = +{ + kvpair_QueryInterface, + kvpair_AddRef, + kvpair_Release, + kvpair_GetIIDs, + kvpair_GetRuntimeClassName, + kvpair_GetTrustLevel, + kvpair_get_Key, + kvpair_get_Value, +}; + +static HRESULT kvpair_create( IKeyValuePair_HSTRING_IInspectable **kvpair ) +{ + struct kvpair *impl; + + TRACE( "(%p)\n", kvpair ); + + *kvpair = NULL; + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return E_OUTOFMEMORY; + + impl->iface.lpVtbl = &kvpair_vtbl; + impl->ref = 1; + *kvpair = &impl->iface; + return S_OK; +} + struct iterator_kvpair_HSTRING_IInspectable { IIterator_IKeyValuePair_HSTRING_IInspectable iface; @@ -111,9 +232,8 @@ static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_get_Current( IIterator_IKeyValuePair_HSTRING_IInspectable *iface, IKeyValuePair_HSTRING_IInspectable **kvpair ) { - FIXME( "(%p, %p) stub!\n", iface, kvpair ); - *kvpair = NULL; - return E_NOTIMPL; + FIXME( "(%p, %p) semi-stub!\n", iface, kvpair ); + return kvpair_create( kvpair ); }
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_HasCurrent( diff --git a/dlls/wintypes/tests/propertyset.c b/dlls/wintypes/tests/propertyset.c index b91cc0ed46d..9106884bd99 100644 --- a/dlls/wintypes/tests/propertyset.c +++ b/dlls/wintypes/tests/propertyset.c @@ -134,7 +134,7 @@ static void test_IPropertySet(void) { hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator ); IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable ); - todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); if (iterator) IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator );