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 | 205 +++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 12 +- 5 files changed, 216 insertions(+), 6 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..944555aa9f4 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")) + *factory = IPropertySet_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..85c826bc48f 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 *IPropertySet_factory; diff --git a/dlls/wintypes/propertyset.c b/dlls/wintypes/propertyset.c new file mode 100644 index 00000000000..e7025331b1c --- /dev/null +++ b/dlls/wintypes/propertyset.c @@ -0,0 +1,205 @@ +/* + * 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; + + 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/wintypes.c b/dlls/wintypes/tests/wintypes.c index 1a63e7b0952..2bb7c886ece 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -1273,19 +1273,19 @@ static void test_IPropertySet(void) ok( SUCCEEDED( hr ), "got %#lx\n", hr ); hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&factory ); WindowsDeleteString( name ); - todo_wine ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), - "RoGetActivationFactory failed, hr %#lx.\n", hr ); + 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 ) ); + 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 ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); if (FAILED( hr )) { skip("could not activate PropertySet instance.\n"); @@ -1295,7 +1295,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();