Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665
I'm unsure how to add tests for this given it requires an app to be installed via MSIX to get a package ID in Windows otherwise `IPackageStatics::get_Current()` returns `0x80073d54`.
-- v3: windows.applicationmodel: Implement IStorageItem::get_Path(). windows.applicationmodel/tests: Add IStorageItem::get_Path() tests. windows.applicationmodel: Add IStorageItem stub interface. windows.applicationmodel: Implement IPackage::get_InstalledLocation(). include: Add IStorageFolder interface definition. include: Add windows.storage.search.idl file. include: Add IStorageItem interface definition. include: Add windows.storage.fileproperties.idl file. include: Add IStorageFile interface definition. include: Add IRandomAccessStream interface definition. windows.applicationmodel: Implement IPackageStatics::get_Current(). windows.applicationmodel: Add IPackageStatics stub interface. include: Add IPackageStatics interface definition. windows.applicationmodel: Add stub DLL.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + dlls/windows.applicationmodel/Makefile.in | 9 ++ dlls/windows.applicationmodel/classes.idl | 23 ++++ dlls/windows.applicationmodel/main.c | 46 +++++++ dlls/windows.applicationmodel/package.c | 116 ++++++++++++++++++ dlls/windows.applicationmodel/private.h | 40 ++++++ .../tests/Makefile.in | 5 + dlls/windows.applicationmodel/tests/model.c | 88 +++++++++++++ .../windows.applicationmodel.spec | 3 + 9 files changed, 332 insertions(+) create mode 100644 dlls/windows.applicationmodel/Makefile.in create mode 100644 dlls/windows.applicationmodel/classes.idl create mode 100644 dlls/windows.applicationmodel/main.c create mode 100644 dlls/windows.applicationmodel/package.c create mode 100644 dlls/windows.applicationmodel/private.h create mode 100644 dlls/windows.applicationmodel/tests/Makefile.in create mode 100644 dlls/windows.applicationmodel/tests/model.c create mode 100644 dlls/windows.applicationmodel/windows.applicationmodel.spec
diff --git a/configure.ac b/configure.ac index 38e61526a06..69593012f5f 100644 --- a/configure.ac +++ b/configure.ac @@ -3154,6 +3154,8 @@ WINE_CONFIG_MAKEFILE(dlls/win32u/tests) WINE_CONFIG_MAKEFILE(dlls/win87em.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winaspi.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/windebug.dll16,enable_win16) +WINE_CONFIG_MAKEFILE(dlls/windows.applicationmodel) +WINE_CONFIG_MAKEFILE(dlls/windows.applicationmodel/tests) WINE_CONFIG_MAKEFILE(dlls/windows.devices.bluetooth) WINE_CONFIG_MAKEFILE(dlls/windows.devices.bluetooth/tests) WINE_CONFIG_MAKEFILE(dlls/windows.devices.enumeration) diff --git a/dlls/windows.applicationmodel/Makefile.in b/dlls/windows.applicationmodel/Makefile.in new file mode 100644 index 00000000000..7404721796e --- /dev/null +++ b/dlls/windows.applicationmodel/Makefile.in @@ -0,0 +1,9 @@ +MODULE = windows.applicationmodel.dll +IMPORTS = combase + +C_SRCS = \ + main.c \ + package.c + +IDL_SRCS = \ + classes.idl diff --git a/dlls/windows.applicationmodel/classes.idl b/dlls/windows.applicationmodel/classes.idl new file mode 100644 index 00000000000..f79d32558ef --- /dev/null +++ b/dlls/windows.applicationmodel/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.applicationmodel.dll + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 + */ + +#pragma makedep register + +#include "windows.applicationmodel.idl" diff --git a/dlls/windows.applicationmodel/main.c b/dlls/windows.applicationmodel/main.c new file mode 100644 index 00000000000..efc6dfd292f --- /dev/null +++ b/dlls/windows.applicationmodel/main.c @@ -0,0 +1,46 @@ +/* WinRT Windows.ApplicationModel Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(model); + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring(classid), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_ApplicationModel_Package )) + IActivationFactory_QueryInterface( package_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c new file mode 100644 index 00000000000..087d96b5ec8 --- /dev/null +++ b/dlls/windows.applicationmodel/package.c @@ -0,0 +1,116 @@ +/* WinRT Windows.ApplicationModel Package Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 package_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct package_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct package_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct package_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; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct package_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 package_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, +}; + +static struct package_statics package_statics = +{ + {&factory_vtbl}, + 1, +}; + +IActivationFactory *package_factory = &package_statics.IActivationFactory_iface; diff --git a/dlls/windows.applicationmodel/private.h b/dlls/windows.applicationmodel/private.h new file mode 100644 index 00000000000..df4b3721a13 --- /dev/null +++ b/dlls/windows.applicationmodel/private.h @@ -0,0 +1,40 @@ +/* WinRT Windows.ApplicationModel Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 + */ + +#ifndef __WINE_WINDOWS_APPLICATIONMODEL_PRIVATE_H +#define __WINE_WINDOWS_APPLICATIONMODEL_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_ApplicationModel +#include "windows.applicationmodel.h" + +extern IActivationFactory *package_factory; + +#endif diff --git a/dlls/windows.applicationmodel/tests/Makefile.in b/dlls/windows.applicationmodel/tests/Makefile.in new file mode 100644 index 00000000000..265144f097c --- /dev/null +++ b/dlls/windows.applicationmodel/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.applicationmodel.dll +IMPORTS = combase + +C_SRCS = \ + model.c diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c new file mode 100644 index 00000000000..a86da0e84ad --- /dev/null +++ b/dlls/windows.applicationmodel/tests/model.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_ApplicationModel +#include "windows.applicationmodel.h" + +#include "wine/test.h" + +#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) +static void check_interface_( unsigned int line, void *obj, const IID *iid ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK || broken( hr == E_NOINTERFACE ) , "got hr %#lx.\n", hr ); + if (SUCCEEDED(hr)) + IUnknown_Release( unk ); +} + +static void test_PackageStatics(void) +{ + static const WCHAR *package_statics_name = L"Windows.ApplicationModel.Package"; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( package_statics_name, wcslen( package_statics_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( package_statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(model) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_PackageStatics(); + + RoUninitialize(); +} diff --git a/dlls/windows.applicationmodel/windows.applicationmodel.spec b/dlls/windows.applicationmodel/windows.applicationmodel.spec new file mode 100644 index 00000000000..20a8bfa98ea --- /dev/null +++ b/dlls/windows.applicationmodel/windows.applicationmodel.spec @@ -0,0 +1,3 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr)
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/windows.applicationmodel.idl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/include/windows.applicationmodel.idl b/include/windows.applicationmodel.idl index cea2c9423d8..9514c06a60e 100644 --- a/include/windows.applicationmodel.idl +++ b/include/windows.applicationmodel.idl @@ -93,6 +93,16 @@ namespace Windows.ApplicationModel { [propget] HRESULT Author([out, retval] HSTRING *value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.ApplicationModel.Package), + uuid(4e534bdf-2960-4878-97a4-9624deb72f2d) + ] + interface IPackageStatics : IInspectable + { + [propget] HRESULT Current([out, retval] Windows.ApplicationModel.Package **value); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), marshaling_behavior(agile), @@ -102,6 +112,14 @@ namespace Windows.ApplicationModel { runtimeclass Package { [default] interface Windows.ApplicationModel.IPackage; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.ApplicationModel.IPackage2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.ApplicationModel.IPackage3; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.ApplicationModel.IPackageWithMetadata; + [contract(Windows.Foundation.UniversalApiContract, 3.0)] interface Windows.ApplicationModel.IPackage4; + [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.ApplicationModel.IPackage5; + [contract(Windows.Foundation.UniversalApiContract, 7.0)] interface Windows.ApplicationModel.IPackage6; + [contract(Windows.Foundation.UniversalApiContract, 8.0)] interface Windows.ApplicationModel.IPackage7; + [contract(Windows.Foundation.UniversalApiContract, 10.0)] interface Windows.ApplicationModel.IPackage8; }
[
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.applicationmodel/package.c | 30 ++++++++++++++++ dlls/windows.applicationmodel/private.h | 38 +++++++++++++++++++++ dlls/windows.applicationmodel/tests/model.c | 6 ++++ 3 files changed, 74 insertions(+)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index 087d96b5ec8..d894897b504 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(model); struct package_statics { IActivationFactory IActivationFactory_iface; + IPackageStatics IPackageStatics_iface; LONG ref; };
@@ -49,6 +50,13 @@ static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID return S_OK; }
+ if (IsEqualGUID( iid, &IID_IPackageStatics )) + { + *out = &impl->IPackageStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -107,9 +115,31 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+DEFINE_IINSPECTABLE( package_statics, IPackageStatics, struct package_statics, IActivationFactory_iface ) + +static HRESULT WINAPI package_statics_get_Current( IPackageStatics *iface, IPackage **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IPackageStaticsVtbl package_statics_vtbl = +{ + package_statics_QueryInterface, + package_statics_AddRef, + package_statics_Release, + /* IInspectable methods */ + package_statics_GetIids, + package_statics_GetRuntimeClassName, + package_statics_GetTrustLevel, + /* IPackageStatics methods */ + package_statics_get_Current, +}; + static struct package_statics package_statics = { {&factory_vtbl}, + {&package_statics_vtbl}, 1, };
diff --git a/dlls/windows.applicationmodel/private.h b/dlls/windows.applicationmodel/private.h index df4b3721a13..0ca3c8931bb 100644 --- a/dlls/windows.applicationmodel/private.h +++ b/dlls/windows.applicationmodel/private.h @@ -37,4 +37,42 @@
extern IActivationFactory *package_factory;
+#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ + static inline impl_type *impl_from( iface_type *iface ) \ + { \ + return CONTAINING_RECORD( iface, impl_type, iface_mem ); \ + } \ + static HRESULT WINAPI pfx##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_QueryInterface( (IInspectable *)(expr), iid, out ); \ + } \ + static ULONG WINAPI pfx##_AddRef( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_AddRef( (IInspectable *)(expr) ); \ + } \ + static ULONG WINAPI pfx##_Release( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_Release( (IInspectable *)(expr) ); \ + } \ + static HRESULT WINAPI pfx##_GetIids( iface_type *iface, ULONG *iid_count, IID **iids ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetIids( (IInspectable *)(expr), iid_count, iids ); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName( iface_type *iface, HSTRING *class_name ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetRuntimeClassName( (IInspectable *)(expr), class_name ); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel( iface_type *iface, TrustLevel *trust_level ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetTrustLevel( (IInspectable *)(expr), trust_level ); \ + } +#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface ) + #endif diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index a86da0e84ad..bbf820379f0 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -50,6 +50,7 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) static void test_PackageStatics(void) { static const WCHAR *package_statics_name = L"Windows.ApplicationModel.Package"; + IPackageStatics *package_statics; IActivationFactory *factory; HSTRING str; HRESULT hr; @@ -71,6 +72,11 @@ static void test_PackageStatics(void) check_interface( factory, &IID_IInspectable ); check_interface( factory, &IID_IAgileObject );
+ hr = IActivationFactory_QueryInterface( factory, &IID_IPackageStatics, (void **)&package_statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = IPackageStatics_Release( package_statics ); + ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665 --- dlls/windows.applicationmodel/package.c | 124 +++++++++++++++++++- dlls/windows.applicationmodel/tests/model.c | 22 ++++ 2 files changed, 144 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index d894897b504..f7f6573526e 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -115,14 +115,134 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
-DEFINE_IINSPECTABLE( package_statics, IPackageStatics, struct package_statics, IActivationFactory_iface ) +struct package +{ + IPackage IPackage_iface; + LONG ref; +};
-static HRESULT WINAPI package_statics_get_Current( IPackageStatics *iface, IPackage **value ) +static inline struct package *impl_from_IPackage( IPackage *iface ) +{ + return CONTAINING_RECORD( iface, struct package, IPackage_iface ); +} + +static HRESULT WINAPI package_QueryInterface( IPackage *iface, REFIID iid, void **out ) +{ + struct package *impl = impl_from_IPackage( 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_IPackage )) + { + *out = &impl->IPackage_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 package_AddRef( IPackage *iface ) +{ + struct package *impl = impl_from_IPackage( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI package_Release( IPackage *iface ) +{ + struct package *impl = impl_from_IPackage( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI package_GetIids( IPackage *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 package_GetRuntimeClassName( IPackage *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI package_GetTrustLevel( IPackage *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI package_get_Id( IPackage *iface, IPackageId **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI package_get_InstalledLocation( IPackage *iface, IStorageFolder **value ) { FIXME( "iface %p, value %p stub!\n", iface, value ); return E_NOTIMPL; }
+static HRESULT WINAPI package_get_IsFramework( IPackage *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI package_get_Dependencies( IPackage *iface, IVectorView_Package **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IPackageVtbl package_vtbl = +{ + package_QueryInterface, + package_AddRef, + package_Release, + /* IInspectable methods */ + package_GetIids, + package_GetRuntimeClassName, + package_GetTrustLevel, + /* IPackage methods */ + package_get_Id, + package_get_InstalledLocation, + package_get_IsFramework, + package_get_Dependencies, +}; + +DEFINE_IINSPECTABLE( package_statics, IPackageStatics, struct package_statics, IActivationFactory_iface ) + +static HRESULT WINAPI package_statics_get_Current( IPackageStatics *iface, IPackage **value ) +{ + struct package *impl; + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!value) return E_INVALIDARG; + if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + + impl->IPackage_iface.lpVtbl = &package_vtbl; + impl->ref = 1; + + *value = &impl->IPackage_iface; + TRACE( "created IPackage %p.\n", *value ); + return S_OK; +} + static const struct IPackageStaticsVtbl package_statics_vtbl = { package_statics_QueryInterface, diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index bbf820379f0..14040f92f0e 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -52,6 +52,7 @@ static void test_PackageStatics(void) static const WCHAR *package_statics_name = L"Windows.ApplicationModel.Package"; IPackageStatics *package_statics; IActivationFactory *factory; + IPackage *package; HSTRING str; HRESULT hr; LONG ref; @@ -75,6 +76,27 @@ static void test_PackageStatics(void) hr = IActivationFactory_QueryInterface( factory, &IID_IPackageStatics, (void **)&package_statics ); ok( hr == S_OK, "got hr %#lx.\n", hr );
+ hr = IPackageStatics_get_Current( package_statics, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = IPackageStatics_get_Current( package_statics, &package ); + ok( hr == S_OK || broken( hr == 0x80073d54 ), "got hr %#lx.\n", hr ); + if (hr == 0x80073d54) + { + ok( package == NULL, "got package %p.\n", package ); + win_skip( "An app needs to be installed via MSIX to get a package ID in Windows, skipping IPackageStatics tests\n" ); + goto done; + } + + ok( package != NULL, "got NULL package %p.\n", package ); + + check_interface( package, &IID_IUnknown ); + check_interface( package, &IID_IInspectable ); + check_interface( package, &IID_IAgileObject ); + check_interface( package, &IID_IPackage ); + + ref = IPackage_Release( package ); + ok( !ref, "got ref %ld.\n", ref ); +done: ref = IPackageStatics_Release( package_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by IStorageFile. --- include/windows.storage.streams.idl | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/include/windows.storage.streams.idl b/include/windows.storage.streams.idl index 9255fb43ff3..bcbdf588ec6 100644 --- a/include/windows.storage.streams.idl +++ b/include/windows.storage.streams.idl @@ -30,14 +30,19 @@ namespace Windows.Storage.Streams { interface IBufferStatics; interface IContentTypeProvider; interface IInputStream; + interface IInputStreamReference; interface IOutputStream; interface IRandomAccessStream; + interface IRandomAccessStreamReference; + interface IRandomAccessStreamStatics; interface IRandomAccessStreamWithContentType; runtimeclass Buffer;
declare { interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.Streams.IBuffer *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.Streams.IRandomAccessStream *>; interface Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IBuffer *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IRandomAccessStream *>; }
[ @@ -75,6 +80,26 @@ namespace Windows.Storage.Streams { [out, retval] Windows.Foundation.MemoryBuffer **value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(905a0fe1-bc53-11df-8c49-001e4fc686da), + ] + interface IRandomAccessStream : IInspectable + requires Windows.Foundation.IClosable, + Windows.Storage.Streams.IInputStream, + Windows.Storage.Streams.IOutputStream + { + [propget] HRESULT Size([out, retval] UINT64 *value); + [propput] HRESULT Size([in] UINT64 value); + HRESULT GetInputStreamAt([in] UINT64 position, [out, retval] Windows.Storage.Streams.IInputStream **stream); + HRESULT GetOutputStreamAt([in] UINT64 position, [out, retval] Windows.Storage.Streams.IOutputStream **stream); + [propget] HRESULT Position([out, retval] UINT64 *value); + HRESULT Seek([in] UINT64 position); + HRESULT CloneStream([out, retval] Windows.Storage.Streams.IRandomAccessStream **stream); + [propget] HRESULT CanRead([out, retval] boolean *value); + [propget] HRESULT CanWrite([out, retval] boolean *value); + } + [ uuid(cc254827-4b3d-438f-9232-10c76bc7e038), ] @@ -88,6 +113,15 @@ namespace Windows.Storage.Streams { { }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Storage.Streams.IRandomAccessStreamStatics, Windows.Foundation.UniversalApiContract, 1.0) + ] + runtimeclass RandomAccessStream + { + } + [ activatable(Windows.Storage.Streams.IBufferFactory, Windows.Foundation.UniversalApiContract, 1.0), contract(Windows.Foundation.UniversalApiContract, 1.0),
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by IStorageFolder. --- include/windows.storage.idl | 135 ++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+)
diff --git a/include/windows.storage.idl b/include/windows.storage.idl index de918ddc104..aa050040640 100644 --- a/include/windows.storage.idl +++ b/include/windows.storage.idl @@ -20,13 +20,139 @@ #pragma winrt ns_prefix #endif
+import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; import "windows.foundation.idl"; +/* import "windows.storage.fileproperties.idl"; */ +/* import "windows.storage.provider.idl"; */ +/* import "windows.storage.search.idl"; */ +import "windows.storage.streams.idl"; +import "windows.system.idl";
namespace Windows.Storage { + typedef enum FileAccessMode FileAccessMode; + typedef enum NameCollisionOption NameCollisionOption; + interface IStorageFolder; interface IStorageFolderStatics; + interface IStorageFolderStatics2; + interface IStorageFileStatics; + interface IStorageFileStatics2; + interface IStorageItem;
runtimeclass StorageFolder; + runtimeclass StorageFile; + runtimeclass StorageStreamTransaction; + + declare { + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.StorageFile *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.StorageStreamTransaction *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.StorageStreamTransaction *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum FileAccessMode + { + Read = 0, + ReadWrite = 1, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum NameCollisionOption + { + GenerateUniqueName = 0, + ReplaceExisting = 1, + FailIfExists = 2, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(fa3f6186-4214-428c-a64c-14c9ac7315ea) + ] + interface IStorageFile : IInspectable + requires Windows.Storage.IStorageItem, + Windows.Storage.Streams.IRandomAccessStreamReference, + Windows.Storage.Streams.IInputStreamReference + { + [propget] HRESULT FileType([out, retval] HSTRING *value); + [propget] HRESULT ContentType([out, retval] HSTRING *value); + HRESULT OpenAsync( + [in] Windows.Storage.FileAccessMode mode, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IRandomAccessStream *> **operation + ); + HRESULT OpenTransactedWriteAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageStreamTransaction *> **operation); + [overload("CopyAsync")] + HRESULT CopyOverloadDefaultNameAndOptions( + [in] Windows.Storage.IStorageFolder *folder, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation + ); + [overload("CopyAsync")] + HRESULT CopyOverloadDefaultOptions( + [in] Windows.Storage.IStorageFolder *folder, + [in] HSTRING name, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + [overload("CopyAsync")] + HRESULT CopyOverload( + [in] Windows.Storage.IStorageFolder *folder, + [in] HSTRING name, + [in] Windows.Storage.NameCollisionOption option, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation + ); + HRESULT CopyAndReplaceAsync([in] Windows.Storage.IStorageFile *file, [out, retval] Windows.Foundation.IAsyncAction **operation); + [overload("MoveAsync")] + HRESULT MoveOverloadDefaultNameAndOptions([in] Windows.Storage.IStorageFolder *folder, [out, retval] Windows.Foundation.IAsyncAction **operation); + [overload("MoveAsync")] + HRESULT MoveOverloadDefaultOptions( + [in] Windows.Storage.IStorageFolder *folder, + [in] HSTRING name, + [out, retval] Windows.Foundation.IAsyncAction **operation + ); + [overload("MoveAsync")] + HRESULT MoveOverload( + [in] Windows.Storage.IStorageFolder *folder, + [in] HSTRING name, + [in] Windows.Storage.NameCollisionOption option, + [out, retval] Windows.Foundation.IAsyncAction **operation); + HRESULT MoveAndReplaceAsync([in] Windows.Storage.IStorageFile *file, [out, retval] Windows.Foundation.IAsyncAction **operation); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Storage.StorageStreamTransaction), + uuid(f67cf363-a53d-4d94-ae2c-67232d93acdd) + ] + interface IStorageStreamTransaction : IInspectable + requires Windows.Foundation.IClosable + { + [propget] HRESULT Stream([out, retval] Windows.Storage.Streams.IRandomAccessStream **value); + HRESULT CommitAsync([out, retval] Windows.Foundation.IAsyncAction **operation); + } + + [ + 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 + { + [default] interface Windows.Storage.IStorageFile; + interface Windows.Storage.Streams.IInputStreamReference; + interface Windows.Storage.Streams.IRandomAccessStreamReference; + interface Windows.Storage.IStorageItem; + interface Windows.Storage.IStorageItemProperties; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItemProperties2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItem2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItemPropertiesWithProvider; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageFilePropertiesWithAvailability; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageFile2; + }
[ contract(Windows.Foundation.UniversalApiContract, 1.0), @@ -36,4 +162,13 @@ namespace Windows.Storage { { [default] interface Windows.Storage.IStorageFolder; } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + runtimeclass StorageStreamTransaction + { + [default] interface Windows.Storage.IStorageStreamTransaction; + interface Windows.Foundation.IClosable; + } }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by IStorageItem. --- include/Makefile.in | 1 + include/windows.storage.fileproperties.idl | 62 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 include/windows.storage.fileproperties.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 96f79518c2e..a1908b42137 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -845,6 +845,7 @@ SOURCES = \ windows.security.credentials.idl \ windows.security.cryptography.idl \ windows.security.isolation.idl \ + windows.storage.fileproperties.idl \ windows.storage.idl \ windows.storage.streams.idl \ windows.system.idl \ diff --git a/include/windows.storage.fileproperties.idl b/include/windows.storage.fileproperties.idl new file mode 100644 index 00000000000..9426d02fefb --- /dev/null +++ b/include/windows.storage.fileproperties.idl @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; +import "windows.devices.geolocation.idl"; +/* import "windows.storage.idl"; */ +import "windows.storage.streams.idl"; + +namespace Windows.Storage.FileProperties { + interface IBasicProperties; + + runtimeclass BasicProperties; + + declare { + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.FileProperties.BasicProperties *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.FileProperties.BasicProperties *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Storage.FileProperties.BasicProperties), + uuid(d05d55db-785e-4a66-be02-9beec58aea81) + ] + interface IBasicProperties : IInspectable + { + [propget] HRESULT Size([out, retval] UINT64 *value); + [propget] HRESULT DateModified([out, retval] Windows.Foundation.DateTime *value); + [propget] HRESULT ItemDate([out, retval] Windows.Foundation.DateTime *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + runtimeclass BasicProperties + { + [default] interface Windows.Storage.FileProperties.IBasicProperties; + interface Windows.Storage.FileProperties.IStorageItemExtraProperties; + } +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by IStorageFolder. --- include/windows.storage.idl | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/include/windows.storage.idl b/include/windows.storage.idl index aa050040640..b3913a980af 100644 --- a/include/windows.storage.idl +++ b/include/windows.storage.idl @@ -33,7 +33,10 @@ import "windows.system.idl";
namespace Windows.Storage { typedef enum FileAccessMode FileAccessMode; + typedef enum FileAttributes FileAttributes; typedef enum NameCollisionOption NameCollisionOption; + typedef enum StorageDeleteOption StorageDeleteOption; + typedef enum StorageItemTypes StorageItemTypes;
interface IStorageFolder; interface IStorageFolderStatics; @@ -62,6 +65,21 @@ namespace Windows.Storage { ReadWrite = 1, };
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + flags + ] + enum FileAttributes + { + Normal = 0x0, + ReadOnly = 0x1, + Directory = 0x10, + Archive = 0x20, + Temporary = 0x100, + [contract(Windows.Foundation.UniversalApiContract, 1.0)] + LocallyIncomplete = 0x200, + }; + [ contract(Windows.Foundation.UniversalApiContract, 1.0) ] @@ -72,6 +90,26 @@ namespace Windows.Storage { FailIfExists = 2, };
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum StorageDeleteOption + { + Default = 0, + PermanentDelete = 1, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + flags + ] + enum StorageItemTypes + { + None = 0x0, + File = 0x1, + Folder = 0x2, + }; + [ contract(Windows.Foundation.UniversalApiContract, 1.0), uuid(fa3f6186-4214-428c-a64c-14c9ac7315ea) @@ -123,6 +161,28 @@ namespace Windows.Storage { HRESULT MoveAndReplaceAsync([in] Windows.Storage.IStorageFile *file, [out, retval] Windows.Foundation.IAsyncAction **operation); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(4207a996-ca2f-42f7-bde8-8b10457a7f30) + ] + interface IStorageItem : IInspectable + { + [overload("RenameAsync")] + HRESULT RenameAsyncOverloadDefaultOptions([in] HSTRING name, [out, retval] Windows.Foundation.IAsyncAction **operation); + [overload("RenameAsync")] + HRESULT RenameAsync([in] HSTRING name, [in] Windows.Storage.NameCollisionOption option, [out, retval] Windows.Foundation.IAsyncAction **operation); + [overload("DeleteAsync")] + HRESULT DeleteAsyncOverloadDefaultOptions([out, retval] Windows.Foundation.IAsyncAction **operation); + [overload("DeleteAsync")] + HRESULT DeleteAsync([in] Windows.Storage.StorageDeleteOption option, [out, retval] Windows.Foundation.IAsyncAction **operation); + HRESULT GetBasicPropertiesAsync([out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.FileProperties.BasicProperties *> **operation); + [propget] HRESULT Name([out, retval] HSTRING *value); + [propget] HRESULT Path([out, retval] HSTRING *value); + [propget] HRESULT Attributes([out, retval] Windows.Storage.FileAttributes *value); + [propget] HRESULT DateCreated([out, retval] Windows.Foundation.DateTime *value); + HRESULT IsOfType([in] Windows.Storage.StorageItemTypes type, [out, retval] boolean *value); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), exclusiveto(Windows.Storage.StorageStreamTransaction),
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by StorageFolder. --- include/Makefile.in | 1 + include/windows.storage.search.idl | 35 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 include/windows.storage.search.idl
diff --git a/include/Makefile.in b/include/Makefile.in index a1908b42137..baf8793fe75 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -847,6 +847,7 @@ SOURCES = \ windows.security.isolation.idl \ windows.storage.fileproperties.idl \ windows.storage.idl \ + windows.storage.search.idl \ windows.storage.streams.idl \ windows.system.idl \ windows.system.power.idl \ diff --git a/include/windows.storage.search.idl b/include/windows.storage.search.idl new file mode 100644 index 00000000000..093b0837afb --- /dev/null +++ b/include/windows.storage.search.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * 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 + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; +/* import "windows.data.text.idl"; */ +/* import "windows.storage.idl"; */ +import "windows.storage.fileproperties.idl"; +import "windows.storage.streams.idl"; + +namespace Windows.Storage.Search { + interface IStorageFolderQueryOperations; +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/windows.storage.idl | 86 +++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-)
diff --git a/include/windows.storage.idl b/include/windows.storage.idl index b3913a980af..717460a0817 100644 --- a/include/windows.storage.idl +++ b/include/windows.storage.idl @@ -25,13 +25,14 @@ import "asyncinfo.idl"; import "eventtoken.idl"; import "windowscontracts.idl"; import "windows.foundation.idl"; -/* import "windows.storage.fileproperties.idl"; */ +import "windows.storage.fileproperties.idl"; /* import "windows.storage.provider.idl"; */ -/* import "windows.storage.search.idl"; */ +import "windows.storage.search.idl"; import "windows.storage.streams.idl"; import "windows.system.idl";
namespace Windows.Storage { + typedef enum CreationCollisionOption CreationCollisionOption; typedef enum FileAccessMode FileAccessMode; typedef enum FileAttributes FileAttributes; typedef enum NameCollisionOption NameCollisionOption; @@ -50,12 +51,36 @@ namespace Windows.Storage { runtimeclass StorageStreamTransaction;
declare { + interface Windows.Foundation.Collections.IVectorView<Windows.Storage.IStorageItem *>; + interface Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFile *>; + interface Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFolder *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Foundation.Collections.IVectorView<Windows.Storage.IStorageItem *> *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFile *> *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFolder *> *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.IStorageItem *>; interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.StorageFile *>; + interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.StorageFolder *>; interface Windows.Foundation.AsyncOperationCompletedHandler<Windows.Storage.StorageStreamTransaction *>; + interface Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.IStorageItem *> *>; + interface Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFile *> *>; + interface Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFolder *> *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.IStorageItem *>; interface Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *>; + interface Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFolder *>; interface Windows.Foundation.IAsyncOperation<Windows.Storage.StorageStreamTransaction *>; }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum CreationCollisionOption + { + GenerateUniqueName = 0, + ReplaceExisting = 1, + FailIfExists = 2, + OpenIfExists = 3, + }; + [ contract(Windows.Foundation.UniversalApiContract, 1.0) ] @@ -161,6 +186,52 @@ namespace Windows.Storage { HRESULT MoveAndReplaceAsync([in] Windows.Storage.IStorageFile *file, [out, retval] Windows.Foundation.IAsyncAction **operation); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(72d1cb78-b3ef-4f75-a80b-6fd9dae2944b) + ] + interface IStorageFolder : IInspectable + requires Windows.Storage.IStorageItem + { + [overload("CreateFileAsync")] + HRESULT CreateFileAsyncOverloadDefaultOptions( + [in] HSTRING name, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation + ); + [overload("CreateFileAsync")] + HRESULT CreateFileAsync( + [in] HSTRING name, + [in] Windows.Storage.CreationCollisionOption options, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation + ); + [overload("CreateFolderAsync")] + HRESULT CreateFolderAsyncOverloadDefaultOptions( + [in] HSTRING name, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFolder *> **operation + ); + [overload("CreateFolderAsync")] + HRESULT CreateFolderAsync( + [in] HSTRING name, + [in] Windows.Storage.CreationCollisionOption options, + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFolder *> **operation + ); + HRESULT GetFileAsync([in] HSTRING name, [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile *> **operation); + HRESULT GetFolderAsync([in] HSTRING name, [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFolder *> **operation); + HRESULT GetItemAsync([in] HSTRING name, [out, retval] Windows.Foundation.IAsyncOperation<Windows.Storage.IStorageItem *> **operation); + [overload("GetFilesAsync")] + HRESULT GetFilesAsyncOverloadDefaultOptionsStartAndCount( + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFile *> *> **operation + ); + [overload("GetFoldersAsync")] + HRESULT GetFoldersAsyncOverloadDefaultOptionsStartAndCount( + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.StorageFolder *> *> **operation + ); + [overload("GetItemsAsync")] + HRESULT GetItemsAsyncOverloadDefaultStartAndCount( + [out, retval] Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<Windows.Storage.IStorageItem *> *> **operation + ); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), uuid(4207a996-ca2f-42f7-bde8-8b10457a7f30) @@ -216,11 +287,20 @@ namespace Windows.Storage {
[ contract(Windows.Foundation.UniversalApiContract, 1.0), - static(Windows.Storage.IStorageFolderStatics, Windows.Foundation.UniversalApiContract, 1.0) + static(Windows.Storage.IStorageFolderStatics, Windows.Foundation.UniversalApiContract, 1.0), + static(Windows.Storage.IStorageFolderStatics2, Windows.Foundation.UniversalApiContract, 10.0) ] runtimeclass StorageFolder { [default] interface Windows.Storage.IStorageFolder; + interface Windows.Storage.IStorageItem; + interface Windows.Storage.Search.IStorageFolderQueryOperations; + interface Windows.Storage.IStorageItemProperties; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItemProperties2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItem2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageFolder2; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Storage.IStorageItemPropertiesWithProvider; + [contract(Windows.Foundation.UniversalApiContract, 6.0)] interface Windows.Storage.IStorageFolder3; }
[
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665 --- dlls/windows.applicationmodel/package.c | 173 +++++++++++++++++++- dlls/windows.applicationmodel/private.h | 1 + dlls/windows.applicationmodel/tests/model.c | 14 ++ 3 files changed, 186 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index f7f6573526e..8e2c162548c 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -115,6 +115,164 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct storage_folder +{ + IStorageFolder IStorageFolder_iface; + LONG ref; +}; + +static inline struct storage_folder *impl_from_IStorageFolder( IStorageFolder *iface ) +{ + return CONTAINING_RECORD( iface, struct storage_folder, IStorageFolder_iface ); +} + +static HRESULT WINAPI storage_folder_QueryInterface( IStorageFolder *iface, REFIID iid, void **out ) +{ + struct storage_folder *impl = impl_from_IStorageFolder( 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_IStorageFolder )) + { + *out = &impl->IStorageFolder_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 storage_folder_AddRef( IStorageFolder *iface ) +{ + struct storage_folder *impl = impl_from_IStorageFolder( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI storage_folder_Release( IStorageFolder *iface ) +{ + struct storage_folder *impl = impl_from_IStorageFolder( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI storage_folder_GetIids( IStorageFolder *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 storage_folder_GetRuntimeClassName( IStorageFolder *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetTrustLevel( IStorageFolder *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_CreateFileAsyncOverloadDefaultOptions( IStorageFolder *iface, HSTRING name, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_CreateFileAsync( IStorageFolder *iface, HSTRING name, CreationCollisionOption options, + IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, name %s, options %d, operation %p stub!\n", iface, debugstr_hstring(name), options, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_CreateFolderAsyncOverloadDefaultOptions( IStorageFolder *iface, HSTRING name, + IAsyncOperation_StorageFolder **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_CreateFolderAsync( IStorageFolder *iface, HSTRING name, CreationCollisionOption options, + IAsyncOperation_StorageFolder **operation ) +{ + FIXME( "iface %p, name %s, options %d, operation %p stub!\n", iface, debugstr_hstring(name), options, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetFileAsync( IStorageFolder *iface, HSTRING name, IAsyncOperation_StorageFile **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetFolderAsync( IStorageFolder *iface, HSTRING name, IAsyncOperation_StorageFolder **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetItemAsync( IStorageFolder *iface, HSTRING name, IAsyncOperation_IStorageItem **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetFilesAsyncOverloadDefaultOptionsStartAndCount( IStorageFolder *iface, + IAsyncOperation_IVectorView_StorageFile **operation ) +{ + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetFoldersAsyncOverloadDefaultOptionsStartAndCount( IStorageFolder *iface, + IAsyncOperation_IVectorView_StorageFolder **operation ) +{ + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_folder_GetItemsAsyncOverloadDefaultStartAndCount( IStorageFolder *iface, + IAsyncOperation_IVectorView_IStorageItem **operation ) +{ + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + return E_NOTIMPL; +} + +static const struct IStorageFolderVtbl storage_folder_vtbl = +{ + storage_folder_QueryInterface, + storage_folder_AddRef, + storage_folder_Release, + /* IInspectable methods */ + storage_folder_GetIids, + storage_folder_GetRuntimeClassName, + storage_folder_GetTrustLevel, + /* IStorageFolder methods */ + storage_folder_CreateFileAsyncOverloadDefaultOptions, + storage_folder_CreateFileAsync, + storage_folder_CreateFolderAsyncOverloadDefaultOptions, + storage_folder_CreateFolderAsync, + storage_folder_GetFileAsync, + storage_folder_GetFolderAsync, + storage_folder_GetItemAsync, + storage_folder_GetFilesAsyncOverloadDefaultOptionsStartAndCount, + storage_folder_GetFoldersAsyncOverloadDefaultOptionsStartAndCount, + storage_folder_GetItemsAsyncOverloadDefaultStartAndCount, +}; + struct package { IPackage IPackage_iface; @@ -192,8 +350,19 @@ static HRESULT WINAPI package_get_Id( IPackage *iface, IPackageId **value )
static HRESULT WINAPI package_get_InstalledLocation( IPackage *iface, IStorageFolder **value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct storage_folder *impl; + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!value) return E_INVALIDARG; + if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + + impl->IStorageFolder_iface.lpVtbl = &storage_folder_vtbl; + impl->ref = 1; + + *value = &impl->IStorageFolder_iface; + TRACE( "created IStorageFolder %p.\n", *value ); + return S_OK; }
static HRESULT WINAPI package_get_IsFramework( IPackage *iface, boolean *value ) diff --git a/dlls/windows.applicationmodel/private.h b/dlls/windows.applicationmodel/private.h index 0ca3c8931bb..ef7750159d2 100644 --- a/dlls/windows.applicationmodel/private.h +++ b/dlls/windows.applicationmodel/private.h @@ -33,6 +33,7 @@ #define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.h" #define WIDL_using_Windows_ApplicationModel +#define WIDL_using_Windows_Storage #include "windows.applicationmodel.h"
extern IActivationFactory *package_factory; diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 14040f92f0e..849c205ded0 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -30,6 +30,7 @@ #define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.h" #define WIDL_using_Windows_ApplicationModel +#define WIDL_using_Windows_Storage #include "windows.applicationmodel.h"
#include "wine/test.h" @@ -51,6 +52,7 @@ static void test_PackageStatics(void) { static const WCHAR *package_statics_name = L"Windows.ApplicationModel.Package"; IPackageStatics *package_statics; + IStorageFolder *storage_folder; IActivationFactory *factory; IPackage *package; HSTRING str; @@ -94,6 +96,18 @@ static void test_PackageStatics(void) check_interface( package, &IID_IAgileObject ); check_interface( package, &IID_IPackage );
+ hr = IPackage_get_InstalledLocation( package, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = IPackage_get_InstalledLocation( package, &storage_folder ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + check_interface( storage_folder, &IID_IUnknown ); + check_interface( storage_folder, &IID_IInspectable ); + check_interface( storage_folder, &IID_IAgileObject ); + check_interface( storage_folder, &IID_IStorageFolder ); + + ref = IStorageFolder_Release( storage_folder ); + ok( !ref, "got ref %ld.\n", ref ); ref = IPackage_Release( package ); ok( !ref, "got ref %ld.\n", ref ); done:
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed for Minecraft Windows 10. --- dlls/windows.applicationmodel/package.c | 93 +++++++++++++++++++++ dlls/windows.applicationmodel/tests/model.c | 7 ++ 2 files changed, 100 insertions(+)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index 8e2c162548c..7a8ff890ae3 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -118,6 +118,7 @@ static const struct IActivationFactoryVtbl factory_vtbl = struct storage_folder { IStorageFolder IStorageFolder_iface; + IStorageItem IStorageItem_iface; LONG ref; };
@@ -142,6 +143,13 @@ static HRESULT WINAPI storage_folder_QueryInterface( IStorageFolder *iface, REFI return S_OK; }
+ if (IsEqualGUID( iid, &IID_IStorageItem )) + { + *out = &impl->IStorageItem_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -273,6 +281,90 @@ static const struct IStorageFolderVtbl storage_folder_vtbl = storage_folder_GetItemsAsyncOverloadDefaultStartAndCount, };
+DEFINE_IINSPECTABLE( storage_item, IStorageItem, struct storage_folder, IStorageFolder_iface ) + +static HRESULT WINAPI storage_item_RenameAsyncOverloadDefaultOptions( IStorageItem *iface, HSTRING name, IAsyncAction **operation ) +{ + FIXME( "iface %p, name %s, operation %p stub!\n", iface, debugstr_hstring(name), operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_RenameAsync( IStorageItem *iface, HSTRING name, NameCollisionOption option, IAsyncAction **operation ) +{ + FIXME( "iface %p, name %s, option %d, operation %p stub!\n", iface, debugstr_hstring(name), option, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_DeleteAsyncOverloadDefaultOptions( IStorageItem *iface, IAsyncAction **operation ) +{ + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_DeleteAsync( IStorageItem *iface, StorageDeleteOption option, IAsyncAction **operation ) +{ + FIXME( "iface %p, option %d, operation %p stub!\n", iface, option, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_GetBasicPropertiesAsync( IStorageItem *iface, IAsyncOperation_BasicProperties **operation ) +{ + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_get_Name( IStorageItem *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_get_Path( IStorageItem *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_get_Attributes( IStorageItem *iface, FileAttributes *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_get_DateCreated( IStorageItem *iface, DateTime *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI storage_item_IsOfType( IStorageItem *iface, StorageItemTypes type, boolean *value ) +{ + FIXME( "iface %p, type %d, value %p stub!\n", iface, type, value ); + return E_NOTIMPL; +} + +static const struct IStorageItemVtbl storage_item_vtbl = +{ + storage_item_QueryInterface, + storage_item_AddRef, + storage_item_Release, + /* IInspectable methods */ + storage_item_GetIids, + storage_item_GetRuntimeClassName, + storage_item_GetTrustLevel, + /* IStorageItem methods */ + storage_item_RenameAsyncOverloadDefaultOptions, + storage_item_RenameAsync, + storage_item_DeleteAsyncOverloadDefaultOptions, + storage_item_DeleteAsync, + storage_item_GetBasicPropertiesAsync, + storage_item_get_Name, + storage_item_get_Path, + storage_item_get_Attributes, + storage_item_get_DateCreated, + storage_item_IsOfType, +}; + struct package { IPackage IPackage_iface; @@ -358,6 +450,7 @@ static HRESULT WINAPI package_get_InstalledLocation( IPackage *iface, IStorageFo if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;
impl->IStorageFolder_iface.lpVtbl = &storage_folder_vtbl; + impl->IStorageItem_iface.lpVtbl = &storage_item_vtbl; impl->ref = 1;
*value = &impl->IStorageFolder_iface; diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 849c205ded0..d543cf37c8e 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -54,6 +54,7 @@ static void test_PackageStatics(void) IPackageStatics *package_statics; IStorageFolder *storage_folder; IActivationFactory *factory; + IStorageItem *storage_item; IPackage *package; HSTRING str; HRESULT hr; @@ -106,6 +107,12 @@ static void test_PackageStatics(void) check_interface( storage_folder, &IID_IAgileObject ); check_interface( storage_folder, &IID_IStorageFolder );
+ hr = IStorageFolder_QueryInterface( storage_folder, &IID_IStorageItem, (void **)&storage_item ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = IStorageItem_Release( storage_item ); + ok( ref == 1, "got ref %ld.\n", ref ); + ref = IStorageFolder_Release( storage_folder ); ok( !ref, "got ref %ld.\n", ref ); ref = IPackage_Release( package );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.applicationmodel/tests/model.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index d543cf37c8e..d626ccbbeb4 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -55,9 +55,11 @@ static void test_PackageStatics(void) IStorageFolder *storage_folder; IActivationFactory *factory; IStorageItem *storage_item; + WCHAR buffer[MAX_PATH]; + HSTRING str, wine_str; IPackage *package; - HSTRING str; HRESULT hr; + INT32 res; LONG ref;
hr = WindowsCreateString( package_statics_name, wcslen( package_statics_name ), &str ); @@ -110,6 +112,17 @@ static void test_PackageStatics(void) hr = IStorageFolder_QueryInterface( storage_folder, &IID_IStorageItem, (void **)&storage_item ); ok( hr == S_OK, "got hr %#lx.\n", hr );
+ hr = IStorageItem_get_Path( storage_item, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = IStorageItem_get_Path( storage_item, &str ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + GetModuleFileNameW( NULL, buffer, MAX_PATH ); + hr = WindowsCreateString( buffer, wcslen(buffer), &wine_str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = WindowsCompareStringOrdinal( str, wine_str, &res ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + todo_wine ok( !res, "got string %s.\n", debugstr_hstring(str) ); + ref = IStorageItem_Release( storage_item ); ok( ref == 1, "got ref %ld.\n", ref );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665 --- dlls/windows.applicationmodel/package.c | 10 ++++++++-- dlls/windows.applicationmodel/tests/model.c | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index 7a8ff890ae3..e7cc26ec6c1 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -321,8 +321,14 @@ static HRESULT WINAPI storage_item_get_Name( IStorageItem *iface, HSTRING *value
static HRESULT WINAPI storage_item_get_Path( IStorageItem *iface, HSTRING *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + WCHAR buffer[MAX_PATH]; + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!value) return E_INVALIDARG; + if (!GetModuleFileNameW( NULL, buffer, MAX_PATH )) return HRESULT_FROM_WIN32( GetLastError() ); + + return WindowsCreateString( buffer, wcslen(buffer), value ); }
static HRESULT WINAPI storage_item_get_Attributes( IStorageItem *iface, FileAttributes *value ) diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index d626ccbbeb4..7cc76197455 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -113,15 +113,15 @@ static void test_PackageStatics(void) ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IStorageItem_get_Path( storage_item, NULL ); - todo_wine ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); hr = IStorageItem_get_Path( storage_item, &str ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); GetModuleFileNameW( NULL, buffer, MAX_PATH ); hr = WindowsCreateString( buffer, wcslen(buffer), &wine_str ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = WindowsCompareStringOrdinal( str, wine_str, &res ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); - todo_wine ok( !res, "got string %s.\n", debugstr_hstring(str) ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( !res, "got string %s.\n", debugstr_hstring(str) );
ref = IStorageItem_Release( storage_item ); ok( ref == 1, "got ref %ld.\n", ref );
I'm unsure how to add tests for this given it requires an app to be installed via MSIX to get a package ID in Windows otherwise `IPackageStatics::get_Current()` returns `0x80073d54`.
I managed to get some tests running in a WinRT application context without too much trouble, I think it would be better to run the tests with it if we intend to check how it is supposed to work.
I'd suggest to split the IDL changes to a separate MR in the meantime, and I'll work on getting some framework available upstream to run the tests.
I managed to get some tests running in a WinRT application context without too much trouble, I think it would be better to run the tests with it if we intend to check how it is supposed to work.
Impressive, very nice. I had no doubt you could get the tests running.
I'm not sure how you did it but in my VM I tried adding an AppxManifest.xml file with <Application> tag including the executable attribute along with the test in the same folder and ran the PowerShell command `Add-AppxPackage`. After tinkering with it, I managed to get it to install the app but not the exe with it. Even using the MSIX Packaging Tool did not help.
I'd suggest to split the IDL changes to a separate MR in the meantime, and I'll work on getting some framework available upstream to run the tests.
Sounds good, MR https://gitlab.winehq.org/wine/wine/-/merge_requests/3552 created.