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`.
-- v9: 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(). windows.applicationmodel: Implement IPackageStatics::get_Current().
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.applicationmodel/package.c | 30 +++++++++++ dlls/windows.applicationmodel/private.h | 38 +++++++++++++ .../tests/application.c | 54 +++++++++++++++++++ dlls/windows.applicationmodel/tests/model.c | 6 +++ 4 files changed, 128 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/application.c b/dlls/windows.applicationmodel/tests/application.c index a3f0ceb07d9..9e4bd14b3e6 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -31,9 +31,61 @@
#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" + #define WINE_WINRT_TEST #include "winrt_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, "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"; + IPackageStatics *package_statics; + 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 ); + + 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 ); +} + int main( int argc, char const *argv[] ) { HRESULT hr; @@ -43,6 +95,8 @@ int main( int argc, char const *argv[] ) hr = RoInitialize( RO_INIT_MULTITHREADED ); ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr );
+ test_PackageStatics(); + RoUninitialize();
winrt_test_exit(); diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 2d0494dabda..44546194690 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -541,6 +541,7 @@ skip_tests: static void test_PackageStatics(void) { static const WCHAR *package_statics_name = L"Windows.ApplicationModel.Package"; + IPackageStatics *package_statics; IActivationFactory *factory; HSTRING str; HRESULT hr; @@ -561,6 +562,11 @@ static void test_PackageStatics(void) check_interface( factory, &IID_IUnknown ); check_interface( factory, &IID_IInspectable );
+ 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/private.h | 1 + .../tests/application.c | 14 ++ dlls/windows.applicationmodel/tests/model.c | 7 + 4 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/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/application.c b/dlls/windows.applicationmodel/tests/application.c index 9e4bd14b3e6..3dbed916530 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -58,6 +58,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; @@ -80,6 +81,19 @@ 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, "got hr %#lx.\n", hr ); + 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 ); ref = IPackageStatics_Release( package_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory ); diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 44546194690..b603e4c551e 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -543,6 +543,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; @@ -565,6 +566,12 @@ 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 ); + todo_wine ok( hr == 0x80073d54, "got hr %#lx.\n", hr ); + todo_wine ok( !package, "got package %p.\n", package ); + ref = IPackageStatics_Release( package_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665 --- dlls/windows.applicationmodel/package.c | 172 +++++++++++++++++- .../tests/application.c | 13 ++ 2 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index f7f6573526e..cb464aed2c1 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -115,6 +115,163 @@ 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_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 +349,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/tests/application.c b/dlls/windows.applicationmodel/tests/application.c index 3dbed916530..37e2e2338f1 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -35,6 +35,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"
#define WINE_WINRT_TEST @@ -57,6 +58,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; @@ -92,6 +94,17 @@ 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_IStorageFolder ); + + ref = IStorageFolder_Release( storage_folder ); + ok( !ref, "got ref %ld.\n", ref ); ref = IPackage_Release( package ); ok( !ref, "got ref %ld.\n", ref ); ref = IPackageStatics_Release( package_statics );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed for Minecraft Windows 10. --- dlls/windows.applicationmodel/package.c | 93 +++++++++++++++++++ .../tests/application.c | 6 ++ 2 files changed, 99 insertions(+)
diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index cb464aed2c1..66ea1b728c9 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; };
@@ -141,6 +142,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; @@ -272,6 +280,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; @@ -357,6 +449,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/application.c b/dlls/windows.applicationmodel/tests/application.c index 37e2e2338f1..a011b50d2de 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -60,6 +60,7 @@ static void test_PackageStatics(void) IPackageStatics *package_statics; IStorageFolder *storage_folder; IActivationFactory *factory; + IStorageItem *storage_item; IPackage *package; HSTRING str; HRESULT hr; @@ -103,6 +104,11 @@ static void test_PackageStatics(void) check_interface( storage_folder, &IID_IInspectable ); 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
--- .../windows.applicationmodel/tests/Makefile.in | 2 +- .../tests/application.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.applicationmodel/tests/Makefile.in b/dlls/windows.applicationmodel/tests/Makefile.in index ba41bd7be94..9289fe0bc8c 100644 --- a/dlls/windows.applicationmodel/tests/Makefile.in +++ b/dlls/windows.applicationmodel/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = windows.applicationmodel.dll -IMPORTS = combase advapi32 +IMPORTS = combase advapi32 kernelbase
application_EXTRADLLFLAGS = -mconsole
diff --git a/dlls/windows.applicationmodel/tests/application.c b/dlls/windows.applicationmodel/tests/application.c index a011b50d2de..44ae82533d7 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -28,6 +28,7 @@ #include "winbase.h" #include "initguid.h" #include "winstring.h" +#include "pathcch.h"
#include "roapi.h"
@@ -61,9 +62,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 ); @@ -107,6 +110,19 @@ 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, &str ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + GetModuleFileNameW( NULL, buffer, MAX_PATH ); + hr = PathCchRemoveFileSpec( buffer, ARRAY_SIZE(buffer) ); + todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + 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) ); + WindowsDeleteString( str ); + WindowsDeleteString( wine_str ); + ref = IStorageItem_Release( storage_item ); ok( ref == 1, "got ref %ld.\n", ref ); ref = IStorageFolder_Release( storage_folder );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52665 --- dlls/windows.applicationmodel/Makefile.in | 2 +- dlls/windows.applicationmodel/package.c | 13 +++++++++++-- dlls/windows.applicationmodel/tests/application.c | 8 ++++---- 3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.applicationmodel/Makefile.in b/dlls/windows.applicationmodel/Makefile.in index 7404721796e..ca0d03b0b23 100644 --- a/dlls/windows.applicationmodel/Makefile.in +++ b/dlls/windows.applicationmodel/Makefile.in @@ -1,5 +1,5 @@ MODULE = windows.applicationmodel.dll -IMPORTS = combase +IMPORTS = combase kernelbase
C_SRCS = \ main.c \ diff --git a/dlls/windows.applicationmodel/package.c b/dlls/windows.applicationmodel/package.c index 66ea1b728c9..5d5518848ed 100644 --- a/dlls/windows.applicationmodel/package.c +++ b/dlls/windows.applicationmodel/package.c @@ -20,6 +20,8 @@ #include "private.h" #include "wine/debug.h"
+#include "pathcch.h" + WINE_DEFAULT_DEBUG_CHANNEL(model);
struct package_statics @@ -320,8 +322,15 @@ 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]; + HRESULT hr; + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!GetModuleFileNameW( NULL, buffer, MAX_PATH )) return HRESULT_FROM_WIN32( GetLastError() ); + if (FAILED( hr = PathCchRemoveFileSpec( buffer, ARRAY_SIZE(buffer) ) )) return hr; + + return WindowsCreateString( buffer, wcslen(buffer), value ); }
static HRESULT WINAPI storage_item_get_Attributes( IStorageItem *iface, FileAttributes *value ) diff --git a/dlls/windows.applicationmodel/tests/application.c b/dlls/windows.applicationmodel/tests/application.c index 44ae82533d7..426d0d526a0 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -111,15 +111,15 @@ static void test_PackageStatics(void) ok( hr == S_OK, "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 = PathCchRemoveFileSpec( buffer, ARRAY_SIZE(buffer) ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); 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) ); WindowsDeleteString( str ); WindowsDeleteString( wine_str );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=137800
Your paranoid android.
=== w1064v1507 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064v1809 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064_tsign (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64_en_AE_u8 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w11pro64 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064v1507 (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064v1809 (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064_2qxl (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064_adm (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w1064_tsign (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64 (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64_ar (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64_ja (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w10pro64_zh_CN (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w11pro64_amd (64 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
Rémi Bernon (@rbernon) commented about dlls/windows.applicationmodel/tests/application.c:
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, &str );
- todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr );
- GetModuleFileNameW( NULL, buffer, MAX_PATH );
- hr = PathCchRemoveFileSpec( buffer, ARRAY_SIZE(buffer) );
- todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr );
- 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) );
- WindowsDeleteString( str );
- WindowsDeleteString( wine_str );
Fwiw this is not always the location of the executable, especially if it is located in a subfolder of the package, but the package root folder path instead. Anyway, this should be good enough for now.
This merge request was approved by Rémi Bernon.