wine/dlls/windows.applicationmodel/tests/model.c

637 lines
30 KiB
C

/*
* 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
#define WIDL_using_Windows_ApplicationModel_Core
#define WIDL_using_Windows_Management_Deployment
#define WIDL_using_Windows_Storage
#include "windows.applicationmodel.h"
#include "windows.management.deployment.h"
#include "wine/test.h"
#include "winrt_test.h"
#define DEFINE_ASYNC_COMPLETED_HANDLER( name, iface_type, async_type ) \
struct name \
{ \
iface_type iface_type##_iface; \
LONG refcount; \
BOOL invoked; \
HANDLE event; \
}; \
\
static HRESULT WINAPI name##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \
{ \
if (IsEqualGUID( iid, &IID_IUnknown ) || IsEqualGUID( iid, &IID_IAgileObject ) || \
IsEqualGUID( iid, &IID_##iface_type )) \
{ \
IUnknown_AddRef( iface ); \
*out = iface; \
return S_OK; \
} \
\
trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); \
*out = NULL; \
return E_NOINTERFACE; \
} \
\
static ULONG WINAPI name##_AddRef( iface_type *iface ) \
{ \
struct name *impl = CONTAINING_RECORD( iface, struct name, iface_type##_iface ); \
return InterlockedIncrement( &impl->refcount ); \
} \
\
static ULONG WINAPI name##_Release( iface_type *iface ) \
{ \
struct name *impl = CONTAINING_RECORD( iface, struct name, iface_type##_iface ); \
ULONG ref = InterlockedDecrement( &impl->refcount ); \
if (!ref) free( impl ); \
return ref; \
} \
\
static HRESULT WINAPI name##_Invoke( iface_type *iface, async_type *async, AsyncStatus status ) \
{ \
struct name *impl = CONTAINING_RECORD( iface, struct name, iface_type##_iface ); \
ok( !impl->invoked, "invoked twice\n" ); \
impl->invoked = TRUE; \
if (impl->event) SetEvent( impl->event ); \
return S_OK; \
} \
\
static iface_type##Vtbl name##_vtbl = \
{ \
name##_QueryInterface, \
name##_AddRef, \
name##_Release, \
name##_Invoke, \
}; \
\
static iface_type *name##_create( HANDLE event ) \
{ \
struct name *impl; \
\
if (!(impl = calloc( 1, sizeof(*impl) ))) return NULL; \
impl->iface_type##_iface.lpVtbl = &name##_vtbl; \
impl->event = event; \
impl->refcount = 1; \
\
return &impl->iface_type##_iface; \
} \
\
static DWORD await_##async_type( async_type *async, DWORD timeout ) \
{ \
iface_type *handler; \
HANDLE event; \
HRESULT hr; \
DWORD ret; \
\
event = CreateEventW( NULL, FALSE, FALSE, NULL ); \
ok( !!event, "CreateEventW failed, error %lu\n", GetLastError() ); \
handler = name##_create( event ); \
ok( !!handler, "Failed to create completion handler\n" ); \
hr = async_type##_put_Completed( async, handler ); \
ok( hr == S_OK, "put_Completed returned %#lx\n", hr ); \
ret = WaitForSingleObject( event, timeout ); \
ok( !ret, "WaitForSingleObject returned %#lx\n", ret ); \
CloseHandle( event ); \
iface_type##_Release( handler ); \
\
return ret; \
}
#define check_interface( a, b, c, d ) check_interface_( __LINE__, a, b, c, d )
static HRESULT check_interface_( unsigned int line, void *iface, REFIID iid, BOOL supported, BOOL is_broken )
{
HRESULT hr, expected_hr, broken_hr;
IUnknown *unknown = iface, *out;
if (supported)
{
expected_hr = S_OK;
broken_hr = E_NOINTERFACE;
}
else
{
expected_hr = E_NOINTERFACE;
broken_hr = S_OK;
}
hr = IUnknown_QueryInterface( unknown, iid, (void **)&out );
ok_(__FILE__, line)( hr == expected_hr || broken( is_broken && hr == broken_hr ),
"Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr );
if (SUCCEEDED( hr ))
IUnknown_Release( out );
return hr;
}
static void load_resource( const WCHAR *name, const WCHAR *type, const WCHAR *filename )
{
DWORD written;
HANDLE file;
HRSRC res;
void *ptr;
file = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
ok( file != INVALID_HANDLE_VALUE, "failed to create %s, error %lu\n", debugstr_w(filename), GetLastError() );
res = FindResourceW( NULL, name, type );
ok( res != 0, "couldn't find resource\n" );
ptr = LockResource( LoadResource( GetModuleHandleW( NULL ), res ) );
WriteFile( file, ptr, SizeofResource( GetModuleHandleW( NULL ), res ), &written, NULL );
ok( written == SizeofResource( GetModuleHandleW( NULL ), res ), "couldn't write resource\n" );
CloseHandle( file );
}
#define check_async_info( a, b, c ) check_async_info_( __LINE__, a, b, c )
static void check_async_info_( int line, void *async, AsyncStatus expect_status, HRESULT expect_hr )
{
AsyncStatus async_status;
IAsyncInfo *async_info;
HRESULT hr, async_hr;
UINT32 async_id;
hr = IInspectable_QueryInterface( async, &IID_IAsyncInfo, (void **)&async_info );
ok_(__FILE__, line)( hr == S_OK, "QueryInterface returned %#lx\n", hr );
async_id = 0xdeadbeef;
hr = IAsyncInfo_get_Id( async_info, &async_id );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Id returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Id returned %#lx\n", hr );
ok_(__FILE__, line)( !!async_id, "got id %u\n", async_id );
async_status = 0xdeadbeef;
hr = IAsyncInfo_get_Status( async_info, &async_status );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Status returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Status returned %#lx\n", hr );
ok_(__FILE__, line)( async_status == expect_status, "got status %u\n", async_status );
async_hr = 0xdeadbeef;
hr = IAsyncInfo_get_ErrorCode( async_info, &async_hr );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_ErrorCode returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_ErrorCode returned %#lx\n", hr );
if (expect_status < 4) todo_wine_if(FAILED(expect_hr)) ok_(__FILE__, line)( async_hr == expect_hr, "got error %#lx\n", async_hr );
else ok_(__FILE__, line)( async_hr == E_ILLEGAL_METHOD_CALL, "got error %#lx\n", async_hr );
IAsyncInfo_Release( async_info );
}
DEFINE_ASYNC_COMPLETED_HANDLER( async_deployment_result_handler, IAsyncOperationWithProgressCompletedHandler_DeploymentResult_DeploymentProgress,
IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress )
DEFINE_ASYNC_COMPLETED_HANDLER( async_applist_handler, IAsyncOperationCompletedHandler_IVectorView_AppListEntry,
IAsyncOperation_IVectorView_AppListEntry )
DEFINE_ASYNC_COMPLETED_HANDLER( async_boolean_handler, IAsyncOperationCompletedHandler_boolean, IAsyncOperation_boolean )
static HRESULT uri_create( const WCHAR *uri, IUriRuntimeClass **out )
{
static const WCHAR *statics_name = RuntimeClass_Windows_Foundation_Uri;
IUriRuntimeClassFactory *uri_factory;
IActivationFactory *activation;
HSTRING str;
HRESULT hr;
hr = WindowsCreateString( statics_name, wcslen( statics_name ), &str );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&activation );
WindowsDeleteString( str );
hr = IActivationFactory_QueryInterface( activation, &IID_IUriRuntimeClassFactory, (void **)&uri_factory );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IActivationFactory_Release( activation );
hr = WindowsCreateString( uri, wcslen( uri ), &str );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IUriRuntimeClassFactory_CreateUri( uri_factory, str, out );
WindowsDeleteString( str );
IUriRuntimeClassFactory_Release( uri_factory );
return hr;
}
static HRESULT test_register_package( IPackageManager *manager, IPackage **out )
{
static const WCHAR app_model_unlock[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock";
IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress *operation;
DWORD size, old_value = 0, new_value = 1;
WCHAR temp[MAX_PATH], path[MAX_PATH + 7];
IStorageFolder *storage_folder;
HSTRING str, name, publisher;
IIterable_Package *packages;
IStorageItem *storage_item;
IDeploymentResult *result;
IIterator_Package *iter;
IUriRuntimeClass *uri;
HRESULT hr, async_hr;
IPackage *package;
const WCHAR *buf;
UINT res, len;
HKEY hkey;
GetTempPathW( ARRAY_SIZE(temp), temp );
GetTempFileNameW( temp, L"winetest-winrt", 0, temp );
DeleteFileW( temp );
CreateDirectoryW( temp, NULL );
swprintf( path, MAX_PATH, L"%s\\%s", temp, L"application.exe" );
load_resource( L"application.exe", L"TESTDLL", path );
swprintf( path, MAX_PATH, L"%s\\%s", temp, L"appxmanifest.xml" );
load_resource( L"appxmanifest.xml", (const WCHAR *)RT_RCDATA, path );
swprintf( path, MAX_PATH, L"file://%s\\%s", temp, L"appxmanifest.xml" );
hr = uri_create( path, &uri );
ok( hr == S_OK, "got hr %#lx.\n", hr );
res = RegGetValueW( HKEY_LOCAL_MACHINE, app_model_unlock, L"AllowDevelopmentWithoutDevLicense", RRF_RT_DWORD, NULL,
(BYTE *)&old_value, &size );
if (res) old_value = 0xdeadbeef;
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, app_model_unlock, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL );
ok( !res, "RegCreateKeyExW failed, res %#x\n", res );
res = RegSetValueExW( hkey, L"AllowDevelopmentWithoutDevLicense", 0, REG_DWORD, (const BYTE *)&new_value, sizeof(new_value) );
ok( !res, "RegCreateKeyExW failed, res %#x\n", res );
/* DeploymentOptions_DevelopmentMode is invalid for AddPackageAsync */
hr = IPackageManager_AddPackageAsync( manager, uri, NULL, DeploymentOptions_DevelopmentMode, &operation );
ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr );
hr = IPackageManager_RegisterPackageAsync( manager, uri, NULL, DeploymentOptions_DevelopmentMode, &operation );
ok( hr == S_OK, "got hr %#lx.\n", hr );
ok( operation != NULL, "got operation %p\n", operation );
IUriRuntimeClass_Release( uri );
res = await_IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress( operation, 5000 );
ok( res == 0, "await_IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress returned %#x\n", res );
hr = IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress_GetResults( operation, &result );
ok( hr == S_OK, "GetResults returned %#lx\n", hr );
IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress_Release( operation );
if (old_value != 0xdeadbeef)
{
res = RegSetValueExW( hkey, L"AllowDevelopmentWithoutDevLicense", 0, REG_DWORD, (const BYTE *)&old_value, sizeof(old_value) );
ok( !res, "RegCreateKeyExW failed, res %#x\n", res );
}
RegCloseKey( hkey );
hr = IDeploymentResult_get_ExtendedErrorCode( result, &async_hr );
ok( hr == S_OK, "get_ExtendedErrorCode returned %#lx\n", hr );
ok( async_hr == S_OK || broken( async_hr == 0x80073cff ) /* 32-bit missing license */ ||
broken( async_hr == 0x80080204 ) /* W8 */ || broken( async_hr == 0x8004264b ) /* w1064v1507 */,
"got error %#lx\n", async_hr );
if (FAILED(async_hr))
{
win_skip("Failed to register package, skipping tests\n");
hr = IDeploymentResult_get_ErrorText( result, &str );
ok( hr == S_OK, "get_ExtendedErrorCode returned %#lx\n", hr );
trace( "got error %s\n", debugstr_hstring(str) );
IDeploymentResult_Release( result );
return async_hr;
}
IDeploymentResult_Release( result );
hr = WindowsCreateString( L"WineTest", wcslen( L"WineTest" ), &name );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = WindowsCreateString( L"CN=Wine, O=The Wine Project, C=US", wcslen( L"CN=Wine, O=The Wine Project, C=US" ), &publisher );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageManager_FindPackagesByNamePublisher( manager, name, publisher, &packages );
ok( hr == S_OK, "got hr %#lx.\n", hr );
WindowsDeleteString( name );
WindowsDeleteString( publisher );
hr = IIterable_Package_First( packages, &iter );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IIterable_Package_Release( packages );
hr = IIterator_Package_get_Current( iter, &package );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IIterator_Package_Release( iter );
hr = IPackage_get_InstalledLocation( package, &storage_folder );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IStorageFolder_QueryInterface( storage_folder, &IID_IStorageItem, (void **)&storage_item );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IStorageFolder_Release( storage_folder );
hr = IStorageItem_get_Path( storage_item, &str );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IStorageItem_Release( storage_item );
buf = WindowsGetStringRawBuffer( str, &len );
ok( !wcscmp( temp, buf ), "got path %s.\n", debugstr_hstring( str ) );
WindowsDeleteString( str );
*out = package;
return S_OK;
}
static void test_remove_package( IPackageManager *manager, IPackage *package )
{
IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress *operation;
IDeploymentResult *result;
HRESULT hr, async_hr;
IPackageId *id;
HSTRING name;
UINT res;
hr = IPackage_get_Id( package, &id );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageId_get_FullName( id, &name );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IPackageId_Release( id );
hr = IPackageManager_RemovePackageAsync( manager, name, &operation );
ok( hr == S_OK, "got hr %#lx.\n", hr );
ok( operation != NULL, "got operation %p\n", operation );
res = await_IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress( operation, 5000 );
ok( res == 0, "await_IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress returned %#x\n", res );
check_async_info( operation, Completed, S_OK );
hr = IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress_GetResults( operation, &result );
ok( hr == S_OK, "GetResults returned %#lx\n", hr );
hr = IDeploymentResult_get_ExtendedErrorCode( result, &async_hr );
ok( hr == S_OK, "get_ExtendedErrorCode returned %#lx\n", hr );
ok( async_hr == S_OK, "got error %#lx\n", async_hr );
IDeploymentResult_Release( result );
IAsyncOperationWithProgress_DeploymentResult_DeploymentProgress_Release( operation );
}
static void test_execute_package( IPackage *package )
{
IAsyncOperation_IVectorView_AppListEntry *async_list;
IAsyncOperation_boolean *async_launch;
IVectorView_AppListEntry *list;
IAppListEntry *app_entry;
IPackage3 *package3;
boolean launched;
HRESULT hr;
UINT res;
if (!winrt_test_init()) return;
hr = IPackage_QueryInterface( package, &IID_IPackage3, (void **)&package3 );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackage3_GetAppListEntriesAsync( package3, &async_list );
ok( hr == S_OK, "got hr %#lx.\n", hr );
res = await_IAsyncOperation_IVectorView_AppListEntry( async_list, 5000 );
ok( res == 0, "await_IAsyncOperation_IVectorView_AppListEntry returned %#x.\n", res );
check_async_info( async_list, Completed, S_OK );
hr = IAsyncOperation_IVectorView_AppListEntry_GetResults( async_list, &list );
ok( hr == S_OK, "GetResults returned %#lx\n", hr );
IAsyncOperation_IVectorView_AppListEntry_Release( async_list );
hr = IVectorView_AppListEntry_GetAt( list, 0, &app_entry );
ok( hr == S_OK, "got hr %#lx.\n", hr );
IVectorView_AppListEntry_Release( list );
IPackage3_Release( package3 );
hr = IAppListEntry_LaunchAsync( app_entry, &async_launch );
ok( hr == S_OK, "got hr %#lx.\n", hr );
res = await_IAsyncOperation_boolean( async_launch, 5000 );
ok( res == 0, "await_IAsyncOperation_boolean returned %#x.\n", res );
check_async_info( async_launch, Completed, S_OK );
hr = IAsyncOperation_boolean_GetResults( async_launch, &launched );
ok( hr == S_OK, "GetResults returned %#lx\n", hr );
ok( launched == TRUE, "got launched %u.\n", launched );
IAppListEntry_Release( app_entry );
winrt_test_exit();
}
static void test_PackageManager(void)
{
static const WCHAR *statics_name = RuntimeClass_Windows_Management_Deployment_PackageManager;
IStorageFolder *storage_folder;
IStorageItem *storage_item;
IActivationFactory *factory;
IIterable_Package *packages;
IInspectable *inspectable;
IPackageManager2 *manager2;
IPackageManager *manager;
IIterator_Package *iter;
IPackage *package;
HSTRING str, str2;
HRESULT hr;
LONG ref;
hr = WindowsCreateString( statics_name, wcslen( 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( statics_name ) );
return;
}
check_interface( factory, &IID_IUnknown, TRUE, FALSE );
check_interface( factory, &IID_IInspectable, TRUE, FALSE );
hr = IActivationFactory_ActivateInstance( factory, &inspectable );
ok( hr == S_OK, "got hr %#lx.\n", hr );
check_interface( inspectable, &IID_IUnknown, TRUE, FALSE );
check_interface( inspectable, &IID_IInspectable, TRUE, FALSE );
check_interface( inspectable, &IID_IAgileObject, TRUE, FALSE );
hr = IInspectable_QueryInterface( inspectable, &IID_IPackageManager, (void **)&manager );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageManager_FindPackagesByNamePublisher( manager, NULL, NULL, &packages );
ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr );
hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageManager_FindPackagesByNamePublisher( manager, str, NULL, &packages );
ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr );
hr = WindowsCreateString( L"The Wine Project", wcslen( L"The Wine Project" ), &str2 );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageManager_FindPackagesByNamePublisher( manager, NULL, str2, &packages );
ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr );
hr = IPackageManager_FindPackagesByNamePublisher( manager, str, str2, &packages );
todo_wine
ok( hr == S_OK || broken(hr == E_ACCESSDENIED) /* Requires admin privileges */, "got hr %#lx.\n", hr );
if (hr == S_OK) IIterable_Package_Release( packages );
WindowsDeleteString( str );
WindowsDeleteString( str2 );
hr = IPackageManager_QueryInterface( manager, &IID_IPackageManager2, (void **)&manager2 );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackageManager2_FindPackagesWithPackageTypes( manager2, 1, &packages );
todo_wine
ok( hr == S_OK || broken(hr == E_ACCESSDENIED) /* Requires admin privileges */, "got hr %#lx.\n", hr );
if (hr == S_OK) IIterable_Package_Release( packages );
ref = IPackageManager2_Release( manager2 );
ok( ref == 2, "got ref %ld.\n", ref );
hr = IPackageManager_FindPackages( manager, &packages );
todo_wine
ok( hr == S_OK || broken(hr == E_ACCESSDENIED) /* w8adm */, "got hr %#lx.\n", hr );
if (hr != S_OK)
{
todo_wine
win_skip("Unable to list packages, skipping package manager tests\n");
goto skip_tests;
}
hr = IIterable_Package_First( packages, &iter );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IIterator_Package_get_Current( iter, &package );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IPackage_get_InstalledLocation( package, &storage_folder );
ok( hr == S_OK, "got hr %#lx.\n", hr );
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 );
ok( hr == S_OK, "got hr %#lx.\n", hr );
WindowsDeleteString( str );
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 );
IPackage_Release( package );
ref = IIterator_Package_Release( iter );
ok( !ref, "got ref %ld.\n", ref );
ref = IIterable_Package_Release( packages );
ok( !ref, "got ref %ld.\n", ref );
if (SUCCEEDED(test_register_package( manager, &package )))
{
test_execute_package( package );
test_remove_package( manager, package );
IPackage_Release( package );
}
skip_tests:
ref = IPackageManager_Release( manager );
ok( ref == 1, "got ref %ld.\n", ref );
ref = IInspectable_Release( inspectable );
ok( !ref, "got ref %ld.\n", ref );
ref = IActivationFactory_Release( factory );
ok( ref == 1, "got ref %ld.\n", ref );
}
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;
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, TRUE, FALSE );
check_interface( factory, &IID_IInspectable, TRUE, FALSE );
hr = IActivationFactory_QueryInterface( factory, &IID_IPackageStatics, (void **)&package_statics );
ok( hr == S_OK, "got hr %#lx.\n", hr );
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 );
if (package) IPackage_Release( package );
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 );
}
static void test_DesignMode(void)
{
static const WCHAR *class_name = RuntimeClass_Windows_ApplicationModel_DesignMode;
IActivationFactory *factory;
HSTRING str;
HRESULT hr;
LONG ref;
hr = WindowsCreateString( class_name, wcslen( class_name ), &str );
ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory );
WindowsDeleteString( str );
ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr );
if (FAILED( hr ))
{
win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( class_name ) );
return;
}
check_interface( factory, &IID_IUnknown, TRUE, FALSE );
check_interface( factory, &IID_IInspectable, TRUE, FALSE );
check_interface( factory, &IID_IAgileObject, TRUE, FALSE );
check_interface( factory, &IID_IActivationFactory, TRUE, FALSE );
check_interface( factory, &IID_IDesignModeStatics, TRUE, FALSE );
check_interface( factory, &IID_IDesignModeStatics2, TRUE, TRUE );
ref = IActivationFactory_Release( factory );
ok( ref == 1, "got ref %ld.\n", ref );
}
START_TEST(model)
{
HRESULT hr;
hr = RoInitialize( RO_INIT_MULTITHREADED );
ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr );
test_PackageManager();
test_PackageStatics();
test_DesignMode();
RoUninitialize();
}