For React Native.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/windows.applicationmodel/tests/model.c | 78 ++++++++++++++++----- 1 file changed, 62 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 0bd5050432b..6df67f62b29 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -127,17 +127,29 @@ return ret; \ }
-#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) -static void check_interface_( unsigned int line, void *obj, const IID *iid ) +#define check_interface( a, b, c, d ) check_interface_( __LINE__, a, b, c, d ) +static HRESULT check_interface_( unsigned int line, void *iface, REFIID iid, BOOL supported, BOOL is_broken ) { - IUnknown *iface = obj; - IUnknown *unk; - HRESULT hr; + HRESULT hr, expected_hr, broken_hr; + IUnknown *unknown = iface, *out; + + if (supported) + { + expected_hr = S_OK; + broken_hr = E_NOINTERFACE; + } + else + { + expected_hr = E_NOINTERFACE; + broken_hr = S_OK; + }
- hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); - ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); - if (SUCCEEDED(hr)) - IUnknown_Release( unk ); + hr = IUnknown_QueryInterface( unknown, iid, (void **)&out ); + ok_(__FILE__, line)( hr == expected_hr || broken( is_broken && hr == broken_hr ), + "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr ); + if (SUCCEEDED( hr )) + IUnknown_Release( out ); + return hr; }
static void load_resource( const WCHAR *name, const WCHAR *type, const WCHAR *filename ) @@ -450,15 +462,15 @@ static void test_PackageManager(void) return; }
- check_interface( factory, &IID_IUnknown ); - check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IUnknown, TRUE, FALSE ); + check_interface( factory, &IID_IInspectable, TRUE, FALSE );
hr = IActivationFactory_ActivateInstance( factory, &inspectable ); ok( hr == S_OK, "got hr %#lx.\n", hr );
- check_interface( inspectable, &IID_IUnknown ); - check_interface( inspectable, &IID_IInspectable ); - check_interface( inspectable, &IID_IAgileObject ); + check_interface( inspectable, &IID_IUnknown, TRUE, FALSE ); + check_interface( inspectable, &IID_IInspectable, TRUE, FALSE ); + check_interface( inspectable, &IID_IAgileObject, TRUE, FALSE );
hr = IInspectable_QueryInterface( inspectable, &IID_IPackageManager, (void **)&manager ); ok( hr == S_OK, "got hr %#lx.\n", hr ); @@ -560,8 +572,8 @@ static void test_PackageStatics(void) return; }
- check_interface( factory, &IID_IUnknown ); - check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IUnknown, TRUE, FALSE ); + check_interface( factory, &IID_IInspectable, TRUE, FALSE );
hr = IActivationFactory_QueryInterface( factory, &IID_IPackageStatics, (void **)&package_statics ); ok( hr == S_OK, "got hr %#lx.\n", hr ); @@ -579,6 +591,39 @@ static void test_PackageStatics(void) ok( ref == 1, "got ref %ld.\n", ref ); }
+static void test_DesignMode(void) +{ + static const WCHAR *class_name = RuntimeClass_Windows_ApplicationModel_DesignMode; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( class_name, wcslen( class_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + todo_wine + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (FAILED( hr )) + { + todo_wine + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown, TRUE, FALSE ); + check_interface( factory, &IID_IInspectable, TRUE, FALSE ); + check_interface( factory, &IID_IAgileObject, TRUE, FALSE ); + check_interface( factory, &IID_IActivationFactory, TRUE, FALSE ); + check_interface( factory, &IID_IDesignModeStatics, TRUE, FALSE ); + check_interface( factory, &IID_IDesignModeStatics2, TRUE, TRUE ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + START_TEST(model) { HRESULT hr; @@ -588,6 +633,7 @@ START_TEST(model)
test_PackageManager(); test_PackageStatics(); + test_DesignMode();
RoUninitialize(); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/windows.applicationmodel/Makefile.in | 1 + dlls/windows.applicationmodel/designmode.c | 176 ++++++++++++++++++++ dlls/windows.applicationmodel/main.c | 2 + dlls/windows.applicationmodel/private.h | 1 + dlls/windows.applicationmodel/tests/model.c | 2 - 5 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 dlls/windows.applicationmodel/designmode.c
diff --git a/dlls/windows.applicationmodel/Makefile.in b/dlls/windows.applicationmodel/Makefile.in index 82646f4d8f4..fb6bf8e55ea 100644 --- a/dlls/windows.applicationmodel/Makefile.in +++ b/dlls/windows.applicationmodel/Makefile.in @@ -3,5 +3,6 @@ IMPORTS = combase kernelbase
SOURCES = \ classes.idl \ + designmode.c \ main.c \ package.c diff --git a/dlls/windows.applicationmodel/designmode.c b/dlls/windows.applicationmodel/designmode.c new file mode 100644 index 00000000000..fc1da5d05f7 --- /dev/null +++ b/dlls/windows.applicationmodel/designmode.c @@ -0,0 +1,176 @@ +/* WinRT Windows.ApplicationModel.DesignMode Implementation + * + * Copyright (C) 2025 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(model); + +struct design_mode_statics +{ + IActivationFactory IActivationFactory_iface; + IDesignModeStatics IDesignModeStatics_iface; + IDesignModeStatics2 IDesignModeStatics2_iface; + LONG ref; +}; + +static inline struct design_mode_statics *impl_from_IActivationFactory(IActivationFactory *iface) +{ + return CONTAINING_RECORD(iface, struct design_mode_statics, IActivationFactory_iface); +} + +static HRESULT WINAPI activation_factory_QueryInterface(IActivationFactory *iface, REFIID iid, void **out) +{ + struct design_mode_statics *impl = impl_from_IActivationFactory(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IActivationFactory)) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef(*out); + return S_OK; + } + else if (IsEqualGUID(iid, &IID_IDesignModeStatics)) + { + *out = &impl->IDesignModeStatics_iface; + IDesignModeStatics_AddRef(*out); + return S_OK; + } + else if (IsEqualGUID(iid, &IID_IDesignModeStatics2)) + { + *out = &impl->IDesignModeStatics2_iface; + IDesignModeStatics2_AddRef(*out); + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI activation_factory_AddRef(IActivationFactory *iface) +{ + struct design_mode_statics *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p increasing refcount to %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI activation_factory_Release(IActivationFactory *iface) +{ + struct design_mode_statics *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p decreasing refcount to %lu.\n", iface, ref); + return ref; +} + +static HRESULT WINAPI activation_factory_GetIids(IActivationFactory *iface, ULONG *iid_count, IID **iids) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI activation_factory_GetRuntimeClassName(IActivationFactory *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI activation_factory_GetTrustLevel(IActivationFactory *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT WINAPI activation_factory_ActivateInstance(IActivationFactory *iface, IInspectable **instance) +{ + FIXME("iface %p, instance %p stub!\n", iface, instance); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl activation_factory_vtbl = +{ + activation_factory_QueryInterface, + activation_factory_AddRef, + activation_factory_Release, + /* IInspectable methods */ + activation_factory_GetIids, + activation_factory_GetRuntimeClassName, + activation_factory_GetTrustLevel, + /* IActivationFactory methods */ + activation_factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE(design_mode_statics, IDesignModeStatics, struct design_mode_statics, IActivationFactory_iface) + +static HRESULT WINAPI design_mode_statics_DesignModeEnabled(IDesignModeStatics *iface, boolean *value) +{ + FIXME("iface %p, value %p.\n", iface, value); + + return E_NOTIMPL; +} + +static const struct IDesignModeStaticsVtbl design_mode_statics_vtbl = +{ + design_mode_statics_QueryInterface, + design_mode_statics_AddRef, + design_mode_statics_Release, + /* IInspectable methods */ + design_mode_statics_GetIids, + design_mode_statics_GetRuntimeClassName, + design_mode_statics_GetTrustLevel, + /* IDesignModeStatics methods */ + design_mode_statics_DesignModeEnabled, +}; + +DEFINE_IINSPECTABLE(design_mode_statics2, IDesignModeStatics2, struct design_mode_statics, IActivationFactory_iface) + +static HRESULT WINAPI design_mode_statics2_DesignMode2Enabled(IDesignModeStatics2 *iface, boolean *value) +{ + FIXME("iface %p, value %p.\n", iface, value); + + return E_NOTIMPL; +} + +static const struct IDesignModeStatics2Vtbl design_mode_statics2_vtbl = +{ + design_mode_statics2_QueryInterface, + design_mode_statics2_AddRef, + design_mode_statics2_Release, + /* IInspectable methods */ + design_mode_statics2_GetIids, + design_mode_statics2_GetRuntimeClassName, + design_mode_statics2_GetTrustLevel, + /* IDesignModeStatics2 methods */ + design_mode_statics2_DesignMode2Enabled, +}; + +static struct design_mode_statics design_mode_statics = +{ + {&activation_factory_vtbl}, + {&design_mode_statics_vtbl}, + {&design_mode_statics2_vtbl}, + 1, +}; + +IActivationFactory *design_mode_factory = &design_mode_statics.IActivationFactory_iface; diff --git a/dlls/windows.applicationmodel/main.c b/dlls/windows.applicationmodel/main.c index efc6dfd292f..5d1e4e2a0ee 100644 --- a/dlls/windows.applicationmodel/main.c +++ b/dlls/windows.applicationmodel/main.c @@ -40,6 +40,8 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa
if (!wcscmp( buffer, RuntimeClass_Windows_ApplicationModel_Package )) IActivationFactory_QueryInterface( package_factory, &IID_IActivationFactory, (void **)factory ); + else if (!wcscmp( buffer, RuntimeClass_Windows_ApplicationModel_DesignMode )) + IActivationFactory_QueryInterface( design_mode_factory, &IID_IActivationFactory, (void **)factory );
if (*factory) return S_OK; return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/windows.applicationmodel/private.h b/dlls/windows.applicationmodel/private.h index ef7750159d2..d2538718835 100644 --- a/dlls/windows.applicationmodel/private.h +++ b/dlls/windows.applicationmodel/private.h @@ -37,6 +37,7 @@ #include "windows.applicationmodel.h"
extern IActivationFactory *package_factory; +extern IActivationFactory *design_mode_factory;
#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 6df67f62b29..7ffe23dff6c 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -604,11 +604,9 @@ static void test_DesignMode(void)
hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); WindowsDeleteString( str ); - todo_wine ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); if (FAILED( hr )) { - todo_wine win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) ); return; }