[PATCH v14 0/4] MR8394: Fix Clip Studio Paint crash with Windows 10 compatibility mode
This fixes the crash when launching ClipStudioPaint.exe with Windows 10 compatiblity mode by adding the minimum required windows.ui and windows.storage definitions and stubs. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58254 -- v14: windows.storage: Add stubs for StorageFile class. include: Add Windows.Storage.StorageFile missing definitions. windows.ui: Add stubs for RadialController classes. include: Add Windows.UI.Input.RadialController definitions. https://gitlab.winehq.org/wine/wine/-/merge_requests/8394
From: Ignacy Kuchciński <ignacykuchcinski@gmail.com> --- include/Makefile.in | 1 + include/radialcontrollerinterop.idl | 39 +++++++++++++++ include/windows.ui.input.idl | 75 ++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 include/radialcontrollerinterop.idl diff --git a/include/Makefile.in b/include/Makefile.in index 9a4a00ceed8..ad11e4b6ab6 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -677,6 +677,7 @@ SOURCES = \ pstore.idl \ qedit.idl \ qos2.h \ + radialcontrollerinterop.idl \ ras.h \ rasdlg.h \ raserror.h \ diff --git a/include/radialcontrollerinterop.idl b/include/radialcontrollerinterop.idl new file mode 100644 index 00000000000..de54b5ec095 --- /dev/null +++ b/include/radialcontrollerinterop.idl @@ -0,0 +1,39 @@ +/* + * Copyright 2025 Ignacy Kuchciński + * + * 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 + */ + +import "inspectable.idl"; + +[ + uuid(1b0535c9-57ad-45c1-9d79-ad5c34360513), + object, + local +] +interface IRadialControllerInterop : IInspectable +{ + HRESULT CreateForWindow([in, annotation("__in")] HWND window, [in, annotation("__in")] REFIID riid, [out, retval, iid_is(riid), annotation("__com_outptr")] void **radialcontroller); +} + +[ + uuid(787cdaac-3186-476d-87e4-b9374a7b9970), + object, + local +] +interface IRadialControllerConfigurationInterop : IInspectable +{ + HRESULT GetForWindow([in, annotation("__in")] HWND window, [in, annotation("__in")] REFIID riid, [out, retval, iid_is(riid), annotation("__com_outptr")] void **radialcontrollerconfiguration); +} diff --git a/include/windows.ui.input.idl b/include/windows.ui.input.idl index f396a3ce8a7..bf74b650cab 100644 --- a/include/windows.ui.input.idl +++ b/include/windows.ui.input.idl @@ -27,7 +27,6 @@ import "windowscontracts.idl"; import "windows.foundation.idl"; import "windows.devices.input.idl"; import "windows.system.idl"; -import "windows.ui.core.idl"; namespace Windows.UI.Input { typedef enum PointerUpdateKind PointerUpdateKind; @@ -38,9 +37,17 @@ namespace Windows.UI.Input { interface IPointerPointStatics; interface IPointerPointTransform; + interface IRadialControllerConfigurationStatics; + interface IRadialControllerMenuItemStatics; + interface IRadialControllerStatics; + runtimeclass PointerPoint; runtimeclass PointerPointProperties; + runtimeclass RadialController; + runtimeclass RadialControllerConfiguration; + runtimeclass RadialControllerMenuItem; + declare { interface Windows.Foundation.Collections.IVectorView<Windows.UI.Input.PointerPoint *>; interface Windows.Foundation.Collections.IVector<Windows.UI.Input.PointerPoint *>; @@ -148,6 +155,38 @@ namespace Windows.UI.Input { HRESULT TransformBounds([in] Windows.Foundation.Rect rect, [out, retval] Windows.Foundation.Rect *value); } + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + exclusiveto(Windows.UI.Input.RadialControllerConfiguration), + uuid(79b6b0e5-069a-4486-a99d-8db772b9642f) + ] + interface IRadialControllerConfigurationStatics : IInspectable + { + /* HRESULT GetForCurrentView([out, retval] Windows.UI.Input.RadialControllerConfiguration **configuration); */ + } + + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + exclusiveto(Windows.UI.Input.RadialControllerMenuItem), + uuid(249e0887-d842-4524-9df8-e0d647edc887) + ] + interface IRadialControllerMenuItemStatics : IInspectable + { + /* HRESULT CreateFromIcon([in] HSTRING display_text, [in] Windows.Storage.Streams.RandomAccessStreamReference *icon, [out, retval] Windows.UI.Input.RadialControllerMenuItem **result); */ + /* HRESULT CreateFromKnownIcon([in] HSTRING display_text, [in] Windows.UI.Input.RadialControllerMenuKnownIcon value, [out, retval] Windows.UI.Input.RadialControllerMenuItem **result); */ + } + + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + exclusiveto(Windows.UI.Input.RadialController), + uuid(faded0b7-b84c-4894-87aa-8f25aa5f288b) + ] + interface IRadialControllerStatics : IInspectable + { + /* HRESULT IsSupported([out, retval] boolean *result); */ + /* HRESULT CreateForCurrentView([out, retval] Windows.UI.Input.RadialController **result); */ + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), marshaling_behavior(none), @@ -167,4 +206,38 @@ namespace Windows.UI.Input { [default] interface Windows.UI.Input.IPointerPointProperties; [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.UI.Input.IPointerPointProperties2; } + + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + marshaling_behavior(agile), + static(Windows.UI.Input.IRadialControllerStatics, Windows.Foundation.UniversalApiContract, 3.0) + ] + runtimeclass RadialController + { + /* [default] interface Windows.UI.Input.IRadialController; */ + /* [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.UI.Input.IRadialController2; */ + } + + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + marshaling_behavior(agile), + static(Windows.UI.Input.IRadialControllerConfigurationStatics, Windows.Foundation.UniversalApiContract, 3.0), + /* static(Windows.UI.Input.IRadialControllerConfigurationStatics2, Windows.Foundation.UniversalApiContract, 5.0) */ + ] + runtimeclass RadialControllerConfiguration + { + /* [default] interface Windows.UI.Input.IRadialControllerConfiguration; */ + /* [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.UI.Input.IRadialControllerConfiguration2; */ + } + + [ + contract(Windows.Foundation.UniversalApiContract, 3.0), + marshaling_behavior(agile), + static(Windows.UI.Input.IRadialControllerMenuItemStatics, Windows.Foundation.UniversalApiContract, 3.0), + /* static(Windows.UI.Input.IRadialControllerMenuItemStatics2, Windows.Foundation.UniversalApiContract, 4.0) */ + ] + runtimeclass RadialControllerMenuItem + { + /* [default] interface Windows.UI.Input.IRadialControllerMenuItem; */ + } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8394
From: Ignacy Kuchciński <ignacykuchcinski@gmail.com> --- dlls/windows.ui/Makefile.in | 2 + dlls/windows.ui/classes.idl | 6 + dlls/windows.ui/main.c | 9 + dlls/windows.ui/private.h | 5 + dlls/windows.ui/radialcontroller.c | 332 +++++++++++++++++++++ dlls/windows.ui/radialcontrollermenuitem.c | 143 +++++++++ 6 files changed, 497 insertions(+) create mode 100644 dlls/windows.ui/radialcontroller.c create mode 100644 dlls/windows.ui/radialcontrollermenuitem.c diff --git a/dlls/windows.ui/Makefile.in b/dlls/windows.ui/Makefile.in index a2eae427a74..854f393c51b 100644 --- a/dlls/windows.ui/Makefile.in +++ b/dlls/windows.ui/Makefile.in @@ -7,6 +7,8 @@ SOURCES = \ corewindow.c \ inputpane.c \ main.c \ + radialcontroller.c \ + radialcontrollermenuitem.c \ uisettings.c \ uiviewsettings.c \ weakref.c diff --git a/dlls/windows.ui/classes.idl b/dlls/windows.ui/classes.idl index 0f79fdc8f61..5b8c365a477 100644 --- a/dlls/windows.ui/classes.idl +++ b/dlls/windows.ui/classes.idl @@ -39,6 +39,12 @@ namespace Windows.UI.Core { runtimeclass CoreWindow; } +namespace Windows.UI.Input { + runtimeclass RadialController; + runtimeclass RadialControllerConfiguration; + runtimeclass RadialControllerMenuItem; +} + namespace Windows.UI.ViewManagement { runtimeclass AccessibilitySettings; runtimeclass UISettings; diff --git a/dlls/windows.ui/main.c b/dlls/windows.ui/main.c index 9c766610dd6..c0106ced45e 100644 --- a/dlls/windows.ui/main.c +++ b/dlls/windows.ui/main.c @@ -38,6 +38,15 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa *factory = NULL; + if (!wcscmp( buffer, RuntimeClass_Windows_UI_Input_RadialController )) + IActivationFactory_QueryInterface( radialcontroller_factory, &IID_IActivationFactory, (void **)factory ); + + if (!wcscmp( buffer, RuntimeClass_Windows_UI_Input_RadialControllerConfiguration )) + IActivationFactory_QueryInterface( radialcontrollerconfiguration_factory, &IID_IActivationFactory, (void **)factory ); + + if (!wcscmp( buffer, RuntimeClass_Windows_UI_Input_RadialControllerMenuItem )) + IActivationFactory_QueryInterface( radialcontrollermenuitem_factory, &IID_IActivationFactory, (void **)factory ); + if (!wcscmp( buffer, RuntimeClass_Windows_UI_ViewManagement_AccessibilitySettings )) IActivationFactory_QueryInterface( accessibilitysettings_factory, &IID_IActivationFactory, (void **)factory ); diff --git a/dlls/windows.ui/private.h b/dlls/windows.ui/private.h index 64566fd053c..9d24fdb9c15 100644 --- a/dlls/windows.ui/private.h +++ b/dlls/windows.ui/private.h @@ -33,11 +33,16 @@ #include "windows.foundation.h" #define WIDL_using_Windows_UI #include "windows.ui.h" +#define WIDL_using_Windows_UI_Input +#include "windows.ui.input.h" #define WIDL_using_Windows_UI_Core #include "windows.ui.core.h" #define WIDL_using_Windows_UI_ViewManagement #include "windows.ui.viewmanagement.h" +extern IActivationFactory *radialcontroller_factory; +extern IActivationFactory *radialcontrollerconfiguration_factory; +extern IActivationFactory *radialcontrollermenuitem_factory; extern IActivationFactory *accessibilitysettings_factory; extern IActivationFactory *uisettings_factory; extern IActivationFactory *uiviewsettings_factory; diff --git a/dlls/windows.ui/radialcontroller.c b/dlls/windows.ui/radialcontroller.c new file mode 100644 index 00000000000..6962161165c --- /dev/null +++ b/dlls/windows.ui/radialcontroller.c @@ -0,0 +1,332 @@ +/* WinRT Windows.UI Implementation + * + * Copyright (C) 2025 Ignacy Kuchciński + * + * 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 "initguid.h" +#include "radialcontrollerinterop.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ui); + +struct radialcontroller_statics +{ + IActivationFactory IActivationFactory_iface; + IRadialControllerInterop IRadialControllerInterop_iface; + IRadialControllerStatics IRadialControllerStatics_iface; + LONG ref; +}; + +static inline struct radialcontroller_statics *impl_RadialControllerStatics_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct radialcontroller_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_RadialController_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct radialcontroller_statics *impl = impl_RadialControllerStatics_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_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + else if (IsEqualGUID( iid, &IID_IRadialControllerInterop)) + { + *out = &impl->IRadialControllerInterop_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + else if (IsEqualGUID( iid, &IID_IRadialControllerStatics )) + { + *out = &impl->IRadialControllerStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_RadialController_AddRef( IActivationFactory *iface ) +{ + struct radialcontroller_statics *impl = impl_RadialControllerStatics_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_RadialController_Release( IActivationFactory *iface ) +{ + struct radialcontroller_statics *impl = impl_RadialControllerStatics_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_RadialController_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 factory_RadialController_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_RadialController_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_name %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_RadialController_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_RadialController_vtbl = +{ + factory_RadialController_QueryInterface, + factory_RadialController_AddRef, + factory_RadialController_Release, + + /* IInspectable methods */ + factory_RadialController_GetIids, + factory_RadialController_GetRuntimeClassName, + factory_RadialController_GetTrustLevel, + + /* IActivationFactory methods */ + factory_RadialController_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( radialcontroller_interop, IRadialControllerInterop, struct radialcontroller_statics, IActivationFactory_iface ); + +static HRESULT WINAPI radialcontroller_interop_CreateForWindow( IRadialControllerInterop *iface, HWND window, REFIID riid, void **radialcontroller ) +{ + struct radialcontroller_statics *impl = impl_from_IRadialControllerInterop ( iface ); + + TRACE( "(window %p, riid %s, radialcontroller %p)\n", window, debugstr_guid( riid ), radialcontroller ); + + factory_RadialController_ActivateInstance( &impl->IActivationFactory_iface, (IInspectable **)radialcontroller ); + return S_OK; +} + +static const struct IRadialControllerInteropVtbl radialcontroller_interop_vtbl = +{ + radialcontroller_interop_QueryInterface, + radialcontroller_interop_AddRef, + radialcontroller_interop_Release, + + /* IInspectable methods */ + radialcontroller_interop_GetIids, + radialcontroller_interop_GetRuntimeClassName, + radialcontroller_interop_GetTrustLevel, + + /* IRadialControllerInterop methods */ + radialcontroller_interop_CreateForWindow, +}; + +DEFINE_IINSPECTABLE( radialcontroller_statics, IRadialControllerStatics, struct radialcontroller_statics, IActivationFactory_iface ); + +static const struct IRadialControllerStaticsVtbl radialcontroller_statics_vtbl = +{ + radialcontroller_statics_QueryInterface, + radialcontroller_statics_AddRef, + radialcontroller_statics_Release, + + /* IInspectable methods */ + radialcontroller_statics_GetIids, + radialcontroller_statics_GetRuntimeClassName, + radialcontroller_statics_GetTrustLevel, + + /* IRadialControllerStatics methods */ +}; + +static struct radialcontroller_statics radialcontroller_statics = +{ + {&factory_RadialController_vtbl}, + {&radialcontroller_interop_vtbl}, + {&radialcontroller_statics_vtbl}, + 1, +}; + +IActivationFactory *radialcontroller_factory = &radialcontroller_statics.IActivationFactory_iface; + +struct radialcontrollerconfiguration_statics +{ + IActivationFactory IActivationFactory_iface; + IRadialControllerConfigurationInterop IRadialControllerConfigurationInterop_iface; + IRadialControllerConfigurationStatics IRadialControllerConfigurationStatics_iface; + LONG ref; +}; + +static inline struct radialcontrollerconfiguration_statics *impl_RadialControllerConfigurationStatics_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct radialcontrollerconfiguration_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_RadialControllerConfiguration_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct radialcontrollerconfiguration_statics *impl = impl_RadialControllerConfigurationStatics_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_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + else if (IsEqualGUID( iid, &IID_IRadialControllerConfigurationInterop )) + { + *out = &impl->IRadialControllerConfigurationInterop_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + else if (IsEqualGUID( iid, &IID_IRadialControllerConfigurationStatics )) + { + *out = &impl->IRadialControllerConfigurationStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_RadialControllerConfiguration_AddRef( IActivationFactory *iface ) +{ + struct radialcontrollerconfiguration_statics *impl = impl_RadialControllerConfigurationStatics_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_RadialControllerConfiguration_Release( IActivationFactory *iface ) +{ + struct radialcontrollerconfiguration_statics *impl = impl_RadialControllerConfigurationStatics_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_RadialControllerConfiguration_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 factory_RadialControllerConfiguration_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_RadialControllerConfiguration_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_name %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_RadialControllerConfiguration_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p.\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_RadialControllerConfiguration_vtbl = +{ + factory_RadialControllerConfiguration_QueryInterface, + factory_RadialControllerConfiguration_AddRef, + factory_RadialControllerConfiguration_Release, + + /* IInspectable methods */ + factory_RadialControllerConfiguration_GetIids, + factory_RadialControllerConfiguration_GetRuntimeClassName, + factory_RadialControllerConfiguration_GetTrustLevel, + + /* IActivationFactory methods */ + factory_RadialControllerConfiguration_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( radialcontrollerconfiguration_interop, IRadialControllerConfigurationInterop, struct radialcontrollerconfiguration_statics, IActivationFactory_iface ); + +static HRESULT WINAPI radialcontrollerconfiguration_interop_GetForWindow( IRadialControllerConfigurationInterop *iface, HWND window, REFIID riid, void **radialcontrollerconfiguration ) +{ + struct radialcontrollerconfiguration_statics *impl = impl_from_IRadialControllerConfigurationInterop ( iface ); + + TRACE( "(window %p, riid %s, radialcontrollerconfiguration %p)\n", window, debugstr_guid( riid ), radialcontrollerconfiguration ); + + factory_RadialControllerConfiguration_ActivateInstance( &impl->IActivationFactory_iface, (IInspectable **)radialcontrollerconfiguration ); + return S_OK; +} + +static const struct IRadialControllerConfigurationInteropVtbl radialcontrollerconfiguration_interop_vtbl = +{ + radialcontrollerconfiguration_interop_QueryInterface, + radialcontrollerconfiguration_interop_AddRef, + radialcontrollerconfiguration_interop_Release, + + /* IInspectable methods */ + radialcontrollerconfiguration_interop_GetIids, + radialcontrollerconfiguration_interop_GetRuntimeClassName, + radialcontrollerconfiguration_interop_GetTrustLevel, + + /* IRadialControllerConfigurationInterop methods */ + radialcontrollerconfiguration_interop_GetForWindow, +}; + +DEFINE_IINSPECTABLE( radialcontrollerconfiguration_statics, IRadialControllerConfigurationStatics, struct radialcontrollerconfiguration_statics, IActivationFactory_iface ); + +static const struct IRadialControllerConfigurationStaticsVtbl radialcontrollerconfiguration_statics_vtbl = +{ + radialcontrollerconfiguration_statics_QueryInterface, + radialcontrollerconfiguration_statics_AddRef, + radialcontrollerconfiguration_statics_Release, + + /* IInspectable methods */ + radialcontrollerconfiguration_statics_GetIids, + radialcontrollerconfiguration_statics_GetRuntimeClassName, + radialcontrollerconfiguration_statics_GetTrustLevel, + + /* IRadialControllerConfigurationStatics methods */ +}; + +static struct radialcontrollerconfiguration_statics radialcontrollerconfiguration_statics = +{ + {&factory_RadialControllerConfiguration_vtbl}, + {&radialcontrollerconfiguration_interop_vtbl}, + {&radialcontrollerconfiguration_statics_vtbl}, + 1, +}; + +IActivationFactory *radialcontrollerconfiguration_factory = &radialcontrollerconfiguration_statics.IActivationFactory_iface; diff --git a/dlls/windows.ui/radialcontrollermenuitem.c b/dlls/windows.ui/radialcontrollermenuitem.c new file mode 100644 index 00000000000..f679f975f54 --- /dev/null +++ b/dlls/windows.ui/radialcontrollermenuitem.c @@ -0,0 +1,143 @@ +/* WinRT Windows.UI Implementation + * + * Copyright (C) 2025 Ignacy Kuchciński + * + * 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 "initguid.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ui); + +struct radialcontrollermenuitem_statics +{ + IActivationFactory IActivationFactory_iface; + IRadialControllerMenuItemStatics IRadialControllerMenuItemStatics_iface; + LONG ref; +}; + +static inline struct radialcontrollermenuitem_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct radialcontrollermenuitem_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct radialcontrollermenuitem_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_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + else if (IsEqualGUID( iid, &IID_IRadialControllerMenuItemStatics )) + { + *out = &impl->IRadialControllerMenuItemStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct radialcontrollermenuitem_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct radialcontrollermenuitem_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI 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 factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_name %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( radialcontrollermenuitem_statics, IRadialControllerMenuItemStatics, struct radialcontrollermenuitem_statics, IActivationFactory_iface ); + +static const struct IRadialControllerMenuItemStaticsVtbl radialcontrollermenuitem_statics_vtbl = +{ + radialcontrollermenuitem_statics_QueryInterface, + radialcontrollermenuitem_statics_AddRef, + radialcontrollermenuitem_statics_Release, + + /* IInspectable methods */ + radialcontrollermenuitem_statics_GetIids, + radialcontrollermenuitem_statics_GetRuntimeClassName, + radialcontrollermenuitem_statics_GetTrustLevel, + + /* IRadialControllerMenuItemStatics methods */ +}; + +static struct radialcontrollermenuitem_statics radialcontrollermenuitem_statics = +{ + {&factory_vtbl}, + {&radialcontrollermenuitem_statics_vtbl}, + 1, +}; + +IActivationFactory *radialcontrollermenuitem_factory = &radialcontrollermenuitem_statics.IActivationFactory_iface; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8394
From: Ignacy Kuchciński <ignacykuchcinski@gmail.com> --- include/windows.storage.idl | 75 ++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/include/windows.storage.idl b/include/windows.storage.idl index 6f4aa6d803b..12af2350860 100644 --- a/include/windows.storage.idl +++ b/include/windows.storage.idl @@ -49,6 +49,7 @@ namespace Windows.Storage { typedef enum NameCollisionOption NameCollisionOption; typedef enum StorageDeleteOption StorageDeleteOption; typedef enum StorageItemTypes StorageItemTypes; + typedef enum StreamedFileFailureMode StreamedFileFailureMode; interface IApplicationData; interface IApplicationData2; @@ -71,12 +72,14 @@ namespace Windows.Storage { interface IStorageFolderStatics; interface IStorageFolderStatics2; interface IStorageItem; + interface IStreamedFileDataRequest; runtimeclass ApplicationData; runtimeclass ApplicationDataContainer; runtimeclass KnownFolders; runtimeclass SetVersionDeferral; runtimeclass SetVersionRequest; + runtimeclass StreamedFileDataRequest; runtimeclass StorageFolder; runtimeclass StorageFile; runtimeclass StorageStreamTransaction; @@ -242,6 +245,16 @@ namespace Windows.Storage { File = 0x1, Folder = 0x2, }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum StreamedFileFailureMode + { + Failed = 0, + CurrentlyUnavailable = 1, + Incomplete = 2 + }; #endif [ @@ -250,6 +263,12 @@ namespace Windows.Storage { ] delegate HRESULT ApplicationDataSetVersionHandler([in] Windows.Storage.SetVersionRequest *version); + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(fef6a824-2fe1-4d07-a35b-b77c50b5f4cc) + ] + delegate HRESULT StreamedFileDataRequestedHandler([in] Windows.Storage.StreamedFileDataRequest *stream); + [ contract(Windows.Foundation.UniversalApiContract, 1.0), exclusiveto(Windows.Storage.ApplicationData), @@ -474,6 +493,15 @@ namespace Windows.Storage { HRESULT GetDeferral([out, retval] Windows.Storage.SetVersionDeferral **deferral); } + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(1673fcce-dabd-4d50-beee-180b8a8191b6) + ] + interface IStreamedFileDataRequest : IInspectable + { + HRESULT FailAndClose([in] Windows.Storage.StreamedFileFailureMode failureMode); + } + #ifndef _WINDOWS_APPLICATIONDATA [ contract(Windows.Foundation.UniversalApiContract, 1.0), @@ -526,6 +554,41 @@ namespace Windows.Storage { HRESULT MoveAndReplaceAsync([in] Windows.Storage.IStorageFile *file, [out, retval] Windows.Foundation.IAsyncAction **operation); } + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Storage.StorageFile), + uuid(5984c710-daf2-43c8-8bb4-a4d3eacfd03f) + ] + interface IStorageFileStatics : IInspectable + { + HRESULT GetFileFromPathAsync( + [in] HSTRING path, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT GetFileFromApplicationUriAsync( + [in] Windows.Foundation.Uri *uri, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT CreateStreamedFileAsync( + [in] HSTRING display_name_with_extensions, + [in] Windows.Storage.StreamedFileDataRequestedHandler *data_requested, + [in] Windows.Storage.Streams.IRandomAccessStreamReference *thumbnail, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT ReplaceWithStreamedFileAsync( + [in] Windows.Storage.IStorageFile *file_to_replace, + [in] Windows.Storage.StreamedFileDataRequestedHandler *data_requested, + [in] Windows.Storage.Streams.IRandomAccessStreamReference *thumbnail, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT CreateStreamedFileFromUriAsync( + [in] HSTRING display_name_with_extension, + [in] Windows.Foundation.Uri *uri, + [in] Windows.Storage.Streams.IRandomAccessStreamReference *thumbnail, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT ReplaceWithStreamedFileFromUriAsync( + [in] Windows.Storage.IStorageFile *file_to_replace, + [in] Windows.Foundation.Uri *uri, + [in] Windows.Storage.Streams.IRandomAccessStreamReference *thumbnail, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), uuid(72d1cb78-b3ef-4f75-a80b-6fd9dae2944b) @@ -668,7 +731,17 @@ namespace Windows.Storage { [ contract(Windows.Foundation.UniversalApiContract, 1.0), - /* static(Windows.Storage.IStorageFileStatics, Windows.Foundation.UniversalApiContract, 1.0), */ + ] + runtimeclass StreamedFileDataRequest + { + [default] interface Windows.Storage.Streams.IOutputStream; + interface Windows.Foundation.IClosable; + interface Windows.Storage.IStreamedFileDataRequest; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + static(Windows.Storage.IStorageFileStatics, Windows.Foundation.UniversalApiContract, 1.0), /* static(Windows.Storage.IStorageFileStatics2, Windows.Foundation.UniversalApiContract, 10.0) */ ] runtimeclass StorageFile -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8394
From: Ignacy Kuchciński <ignacykuchcinski@gmail.com> --- dlls/windows.storage/Makefile.in | 1 + dlls/windows.storage/classes.idl | 4 + dlls/windows.storage/main.c | 3 + dlls/windows.storage/private.h | 1 + dlls/windows.storage/storagefile.c | 203 +++++++++++++++++++++++++++++ 5 files changed, 212 insertions(+) create mode 100644 dlls/windows.storage/storagefile.c diff --git a/dlls/windows.storage/Makefile.in b/dlls/windows.storage/Makefile.in index bb446a2be99..52c2d7f5ca6 100644 --- a/dlls/windows.storage/Makefile.in +++ b/dlls/windows.storage/Makefile.in @@ -4,4 +4,5 @@ IMPORTS = shell32 combase SOURCES = \ classes.idl \ main.c \ + storagefile.c \ streams.c diff --git a/dlls/windows.storage/classes.idl b/dlls/windows.storage/classes.idl index d64d1c45ec8..99457242b0a 100644 --- a/dlls/windows.storage/classes.idl +++ b/dlls/windows.storage/classes.idl @@ -29,6 +29,10 @@ import "windowscontracts.idl"; import "windows.system.idl"; import "windows.storage.idl"; +namespace Windows.Storage { + runtimeclass StorageFile; +} + namespace Windows.Storage.Streams { runtimeclass RandomAccessStreamReference; } diff --git a/dlls/windows.storage/main.c b/dlls/windows.storage/main.c index 390f2dec742..dbfe1bde20e 100644 --- a/dlls/windows.storage/main.c +++ b/dlls/windows.storage/main.c @@ -36,6 +36,9 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa *factory = NULL; + if (!wcscmp( buffer, RuntimeClass_Windows_Storage_StorageFile )) + IActivationFactory_QueryInterface( storagefile_factory, &IID_IActivationFactory, (void **)factory ); + if (!wcscmp( buffer, RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference )) IActivationFactory_QueryInterface( random_access_stream_reference_factory, &IID_IActivationFactory, (void **)factory ); diff --git a/dlls/windows.storage/private.h b/dlls/windows.storage/private.h index 62c9d226d07..48a5b3146bf 100644 --- a/dlls/windows.storage/private.h +++ b/dlls/windows.storage/private.h @@ -39,6 +39,7 @@ #include "windows.storage.h" #include "windows.storage.streams.h" +extern IActivationFactory *storagefile_factory; extern IActivationFactory *random_access_stream_reference_factory; #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ diff --git a/dlls/windows.storage/storagefile.c b/dlls/windows.storage/storagefile.c new file mode 100644 index 00000000000..73d1af0915e --- /dev/null +++ b/dlls/windows.storage/storagefile.c @@ -0,0 +1,203 @@ +/* WinRT Windows.Storage Implementation + * + * Copyright (C) 2025 Ignacy Kuchciński + * + * 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 "initguid.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(storage); + +struct storagefile_statics +{ + IActivationFactory IActivationFactory_iface; + IStorageFileStatics IStorageFileStatics_iface; + LONG ref; +}; + +static inline struct storagefile_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct storagefile_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct storagefile_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; + } + + if (IsEqualGUID( iid, &IID_IStorageFileStatics )) + { + *out = &impl->IStorageFileStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct storagefile_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 factory_Release( IActivationFactory *iface ) +{ + struct storagefile_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 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 factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( storagefile_statics, IStorageFileStatics, struct storagefile_statics, IActivationFactory_iface ) + +static HRESULT WINAPI storagefile_statics_GetFileFromPathAsync( IStorageFileStatics *iface, + HSTRING path, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, path %p, operation %p stub!\n", iface, path, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storagefile_statics_GetFileFromApplicationUriAsync( IStorageFileStatics *iface, + IUriRuntimeClass *uri, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, uri %p, operation %p stub!\n", iface, uri, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storagefile_statics_CreateStreamedFileAsync( IStorageFileStatics *iface, + HSTRING display_name_with_extensions, + IStreamedFileDataRequestedHandler *data_requested, + IRandomAccessStreamReference *thumbnail, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, display_name_with_extensions %p, data_requested %p, thumbnail %p, operation %p stub!\n", iface, display_name_with_extensions, data_requested, thumbnail, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storagefile_statics_ReplaceWithStreamedFileAsync( IStorageFileStatics *iface, + IStorageFile *file_to_replace, + IStreamedFileDataRequestedHandler *data_requested, + IRandomAccessStreamReference *thumbnail, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, file_to_replace %p, data_requested %p, thumbnail %p, operation %p stub!\n", iface, file_to_replace, data_requested, thumbnail, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storagefile_statics_CreateStreamedFileFromUriAsync( IStorageFileStatics *iface, + HSTRING display_name_with_extensions, + IUriRuntimeClass *uri, + IRandomAccessStreamReference *thumbnail, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, display_name_with_extensions %p, uri %p, thumbnail %p, operation %p stub!\n", iface, display_name_with_extensions, uri, thumbnail, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storagefile_statics_ReplaceWithStreamedFileFromUriAsync( IStorageFileStatics *iface, + IStorageFile *file_to_replace, + IUriRuntimeClass *uri, + IRandomAccessStreamReference *thumbnail, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, file_to_replace %p, uri %p, thumbnail %p, operation %p stub!\n", iface, file_to_replace, uri, thumbnail, operation ); + return E_NOTIMPL; +} + +static const struct IStorageFileStaticsVtbl storagefile_statics_vtbl = +{ + storagefile_statics_QueryInterface, + storagefile_statics_AddRef, + storagefile_statics_Release, + /* IInspectable methods */ + storagefile_statics_GetIids, + storagefile_statics_GetRuntimeClassName, + storagefile_statics_GetTrustLevel, + /* IStorageFileStatics methods */ + storagefile_statics_GetFileFromPathAsync, + storagefile_statics_GetFileFromApplicationUriAsync, + storagefile_statics_CreateStreamedFileAsync, + storagefile_statics_ReplaceWithStreamedFileAsync, + storagefile_statics_CreateStreamedFileFromUriAsync, + storagefile_statics_ReplaceWithStreamedFileFromUriAsync, +}; + +static struct storagefile_statics storagefile_statics = +{ + {&factory_vtbl}, + {&storagefile_statics_vtbl}, + 0, +}; + +IActivationFactory *storagefile_factory = &storagefile_statics.IActivationFactory_iface; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8394
On Sun Feb 1 23:13:11 2026 +0000, Ignacy Kuchciński wrote:
Found that commit https://gitlab.winehq.org/wine/wine/-/commit/26a56ddb48034258f7758d6a526b212... is the first one that causes the build failure with my changes on top Fixed by removing unnecessary "windows.ui.core.idl" import in include/windows.ui.input.idl.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8394#note_128501
participants (2)
-
Ignacy Kuchciński -
Ignacy Kuchciński (@ignapk)