mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2025-08-29 10:43:55 +02:00
637 lines
30 KiB
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();
|
|
}
|