This can then be used to run tests in an appx context, for instance for https://gitlab.winehq.org/wine/wine/-/merge_requests/3548
-- v3: windows.applicationmodel/tests: Test executing a WinRT package application. windows.applicationmodel/tests: Test IPackageManager_RegisterPackageAsync. makedep: Support generating .exe TESTDLL resources. makedep: Use #pragma makedep testdll for TESTDLL resources. windows.applicationmodel/tests: Add some IPackageManager tests. 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 | 33 +++++ 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 + include/windows.applicationmodel.core.idl | 2 + include/windows.applicationmodel.idl | 2 + 11 files changed, 346 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 078ee5bf201..8b1a92c6396 100644 --- a/configure.ac +++ b/configure.ac @@ -3137,6 +3137,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..c0c706787bc --- /dev/null +++ b/dlls/windows.applicationmodel/classes.idl @@ -0,0 +1,33 @@ +/* + * 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 + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "windows.foundation.idl"; +import "windows.storage.idl"; +import "windows.system.idl"; + +#define DO_NO_IMPORTS +#include "windows.applicationmodel.core.idl" +#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) diff --git a/include/windows.applicationmodel.core.idl b/include/windows.applicationmodel.core.idl index cc830609f7f..7a4ea85c642 100644 --- a/include/windows.applicationmodel.core.idl +++ b/include/windows.applicationmodel.core.idl @@ -20,10 +20,12 @@ #pragma winrt ns_prefix #endif
+#ifndef DO_NO_IMPORTS import "windows.foundation.idl"; import "windows.storage.idl"; import "windows.system.idl"; import "windows.applicationmodel.idl"; +#endif
namespace Windows.ApplicationModel { runtimeclass AppDisplayInfo; diff --git a/include/windows.applicationmodel.idl b/include/windows.applicationmodel.idl index 47557f7efb9..9c3718dc87d 100644 --- a/include/windows.applicationmodel.idl +++ b/include/windows.applicationmodel.idl @@ -20,10 +20,12 @@ #pragma winrt ns_prefix #endif
+#ifndef DO_NO_IMPORTS import "windows.foundation.idl"; import "windows.storage.idl"; import "windows.system.idl"; import "windows.applicationmodel.core.idl"; +#endif
namespace Windows.ApplicationModel.Core { runtimeclass AppListEntry;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/windows.applicationmodel/tests/model.c | 81 +++++++++++++++++++++ 1 file changed, 81 insertions(+)
diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index a86da0e84ad..50513e45fd4 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -30,7 +30,11 @@ #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"
@@ -47,6 +51,82 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) IUnknown_Release( unk ); }
+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; + IPackageManager *manager; + IIterator_Package *iter; + IPackage *package; + HSTRING str; + 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 ); + todo_wine + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + todo_wine + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + hr = IActivationFactory_ActivateInstance( factory, (IInspectable **)&manager ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + check_interface( manager, &IID_IUnknown ); + check_interface( manager, &IID_IInspectable ); + check_interface( manager, &IID_IAgileObject ); + check_interface( manager, &IID_IPackageManager ); + + hr = IPackageManager_FindPackages( manager, &packages ); + ok( hr == S_OK || broken(hr == E_ACCESSDENIED) /* w8adm */, "got hr %#lx.\n", hr ); + if (broken(hr == E_ACCESSDENIED)) + { + 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 ); + +skip_tests: + ref = IPackageManager_Release( manager ); + 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"; @@ -82,6 +162,7 @@ START_TEST(model) hr = RoInitialize( RO_INIT_MULTITHREADED ); ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr );
+ test_PackageManager(); test_PackageStatics();
RoUninitialize();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/combase/tests/wine.combase.test.c | 4 +++ dlls/dinput/tests/driver_bus.c | 4 +++ dlls/dinput/tests/driver_hid.c | 4 +++ dlls/dinput/tests/driver_hid_poll.c | 4 +++ dlls/imagehlp/tests/testdll.c | 4 +++ dlls/imm32/tests/ime_wrapper.c | 4 +++ dlls/imm32/tests/ime_wrapper.rc | 2 -- dlls/kernel32/tests/dummy.c | 22 +++++++++++++++ dlls/msi/tests/custom.c | 4 +++ dlls/msi/tests/selfreg.c | 4 +++ dlls/ntoskrnl.exe/tests/driver.c | 4 +++ dlls/ntoskrnl.exe/tests/driver2.c | 4 +++ dlls/ntoskrnl.exe/tests/driver3.c | 4 +++ dlls/ntoskrnl.exe/tests/driver_netio.c | 4 +++ dlls/ntoskrnl.exe/tests/driver_pnp.c | 4 +++ dlls/ole32/tests/testlib.c | 4 +++ dlls/setupapi/tests/coinst.c | 4 +++ dlls/setupapi/tests/selfreg.c | 4 +++ dlls/ucrtbase/tests/threaddll.c | 4 +++ tools/makedep.c | 37 +++++++++++++++----------- 20 files changed, 112 insertions(+), 17 deletions(-)
diff --git a/dlls/combase/tests/wine.combase.test.c b/dlls/combase/tests/wine.combase.test.c index e6171c6c6e7..3106a61b648 100644 --- a/dlls/combase/tests/wine.combase.test.c +++ b/dlls/combase/tests/wine.combase.test.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stddef.h>
diff --git a/dlls/dinput/tests/driver_bus.c b/dlls/dinput/tests/driver_bus.c index 44a14798337..c0d181c58a5 100644 --- a/dlls/dinput/tests/driver_bus.c +++ b/dlls/dinput/tests/driver_bus.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/dinput/tests/driver_hid.c b/dlls/dinput/tests/driver_hid.c index 8f015eb5ddf..5c1bda6871e 100644 --- a/dlls/dinput/tests/driver_hid.c +++ b/dlls/dinput/tests/driver_hid.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/dinput/tests/driver_hid_poll.c b/dlls/dinput/tests/driver_hid_poll.c index b5cf46f389e..aad1c6ee0e6 100644 --- a/dlls/dinput/tests/driver_hid_poll.c +++ b/dlls/dinput/tests/driver_hid_poll.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/imagehlp/tests/testdll.c b/dlls/imagehlp/tests/testdll.c index 3c079bfffd3..58e852b268d 100644 --- a/dlls/imagehlp/tests/testdll.c +++ b/dlls/imagehlp/tests/testdll.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <oaidl.h> #include <commdlg.h> #include <shlwapi.h> diff --git a/dlls/imm32/tests/ime_wrapper.c b/dlls/imm32/tests/ime_wrapper.c index d8a03499549..8d5eb498809 100644 --- a/dlls/imm32/tests/ime_wrapper.c +++ b/dlls/imm32/tests/ime_wrapper.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include "ime_test.h"
struct ime_functions ime_functions = {0}; diff --git a/dlls/imm32/tests/ime_wrapper.rc b/dlls/imm32/tests/ime_wrapper.rc index e71d81f4fc9..2ef04be21c5 100644 --- a/dlls/imm32/tests/ime_wrapper.rc +++ b/dlls/imm32/tests/ime_wrapper.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#pragma makedep testdll - #define WINE_LANGID 047f /* LANG_INVARIANT/SUBLANG_DEFAULT */ #define WINE_FILETYPE VFT_DRV #define WINE_FILESUBTYPE VFT2_DRV_INPUTMETHOD diff --git a/dlls/kernel32/tests/dummy.c b/dlls/kernel32/tests/dummy.c index b8eab8c219e..4837a3736ba 100644 --- a/dlls/kernel32/tests/dummy.c +++ b/dlls/kernel32/tests/dummy.c @@ -1,3 +1,25 @@ +/* + * Copyright 2019 Fabian Maurer + * + * 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 + */ + +#if 0 +#pragma makedep testdll +#endif + #include <windows.h>
static HINSTANCE instance; diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 30b9040acff..ef24de5cc22 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/custom.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/msi/tests/selfreg.c b/dlls/msi/tests/selfreg.c index 668e742e9ba..2f5e6f48ef1 100644 --- a/dlls/msi/tests/selfreg.c +++ b/dlls/msi/tests/selfreg.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <windef.h> #include <winbase.h> diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index bd388a6ec9e..5275aada3dc 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -20,6 +20,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/ntoskrnl.exe/tests/driver2.c b/dlls/ntoskrnl.exe/tests/driver2.c index c648ec60ffc..56260d711df 100644 --- a/dlls/ntoskrnl.exe/tests/driver2.c +++ b/dlls/ntoskrnl.exe/tests/driver2.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h>
#include "ntstatus.h" diff --git a/dlls/ntoskrnl.exe/tests/driver3.c b/dlls/ntoskrnl.exe/tests/driver3.c index a7737a960a0..917a1dbec6b 100644 --- a/dlls/ntoskrnl.exe/tests/driver3.c +++ b/dlls/ntoskrnl.exe/tests/driver3.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h>
#include "ntstatus.h" diff --git a/dlls/ntoskrnl.exe/tests/driver_netio.c b/dlls/ntoskrnl.exe/tests/driver_netio.c index 9f9478d75b0..365c90a05ab 100644 --- a/dlls/ntoskrnl.exe/tests/driver_netio.c +++ b/dlls/ntoskrnl.exe/tests/driver_netio.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 77332708fd3..f66d56de8c7 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include <stdio.h>
diff --git a/dlls/ole32/tests/testlib.c b/dlls/ole32/tests/testlib.c index 9631f81c9c3..0d5c915d12f 100644 --- a/dlls/ole32/tests/testlib.c +++ b/dlls/ole32/tests/testlib.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdio.h> #include <windows.h> #include <initguid.h> diff --git a/dlls/setupapi/tests/coinst.c b/dlls/setupapi/tests/coinst.c index ba526a5d3a1..82597b7bc54 100644 --- a/dlls/setupapi/tests/coinst.c +++ b/dlls/setupapi/tests/coinst.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <stdarg.h> #include "windef.h" #include "winbase.h" diff --git a/dlls/setupapi/tests/selfreg.c b/dlls/setupapi/tests/selfreg.c index f687990f3bc..3e45d661483 100644 --- a/dlls/setupapi/tests/selfreg.c +++ b/dlls/setupapi/tests/selfreg.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #define COBJMACROS #include "msxml.h"
diff --git a/dlls/ucrtbase/tests/threaddll.c b/dlls/ucrtbase/tests/threaddll.c index 72b8074054a..387a00bff03 100644 --- a/dlls/ucrtbase/tests/threaddll.c +++ b/dlls/ucrtbase/tests/threaddll.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep testdll +#endif + #include <windows.h>
#include "threaddll.h" diff --git a/tools/makedep.c b/tools/makedep.c index d3064ea4ff1..41f1756686f 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -100,6 +100,7 @@ struct incl_file #define FLAG_C_IMPLIB 0x040000 /* file is part of an import library */ #define FLAG_C_UNIX 0x080000 /* file is part of a Unix library */ #define FLAG_SFD_FONTS 0x100000 /* sfd file generated bitmap fonts */ +#define FLAG_C_TESTDLL 0x200000 /* file is part of a TESTDLL resource */
static const struct { @@ -965,6 +966,7 @@ static void parse_pragma_directive( struct file *source, char *str ) { if (!strcmp( flag, "implib" )) source->flags |= FLAG_C_IMPLIB; if (!strcmp( flag, "unix" )) source->flags |= FLAG_C_UNIX; + if (!strcmp( flag, "testdll" )) source->flags |= FLAG_C_TESTDLL; } } } @@ -3058,15 +3060,16 @@ static void output_source_in( struct makefile *make, struct incl_file *source, c
/******************************************************************* - * output_source_spec + * output_source_testdll */ -static void output_source_spec( struct makefile *make, struct incl_file *source, const char *obj ) +static void output_source_testdll( struct makefile *make, struct incl_file *source, const char *obj ) { struct strarray imports = get_expanded_file_local_var( make, obj, "IMPORTS" ); struct strarray dll_flags = empty_strarray; struct strarray default_imports = empty_strarray; struct strarray all_libs, dep_libs; const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *debug_file; + struct incl_file *spec_file = find_src_file( make, replace_extension( source->name, ".c", ".spec" ) ); unsigned int arch;
if (!imports.count) imports = make->imports; @@ -3074,6 +3077,8 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, strarray_addall( &dll_flags, get_expanded_file_local_var( make, obj, "EXTRADLLFLAGS" )); if (!strarray_exists( &dll_flags, "-nodefaultlibs" )) default_imports = get_default_imports( make, imports );
+ if (!spec_file) fatal_error( "testdll source %s needs a .spec file\n", source->name ); + for (arch = 0; arch < archs.count; arch++) { if (!is_multiarch( arch )) continue; @@ -3099,7 +3104,7 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, tools_path( make, "wrc" ));
output( "%s:", output_file ); - output_filename( source->filename ); + output_filename( spec_file->filename ); output_filename( obj_name ); if (res_name) output_filename( res_name ); output_filenames( dep_libs ); @@ -3111,7 +3116,7 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, output_filenames( dll_flags ); if (arch) output_filenames( get_expanded_arch_var_array( make, "EXTRADLLFLAGS", arch )); output_filename( "-shared" ); - output_filename( source->filename ); + output_filename( spec_file->filename ); output_filename( obj_name ); if (res_name) output_filename( res_name ); if ((debug_file = get_debug_file( make, dll_name, arch ))) @@ -3143,7 +3148,7 @@ static void output_source_xml( struct makefile *make, struct incl_file *source, */ static void output_source_one_arch( struct makefile *make, struct incl_file *source, const char *obj, struct strarray defines, struct strarray *targets, - unsigned int arch, int is_dll_src ) + unsigned int arch ) { const char *obj_name;
@@ -3171,7 +3176,7 @@ static void output_source_one_arch( struct makefile *make, struct incl_file *sou strarray_add( &make->unixobj_files, obj_name ); else if (source->file->flags & FLAG_C_IMPLIB) strarray_add( &make->implib_files[arch], obj_name ); - else if (!is_dll_src) + else if (!(source->file->flags & FLAG_C_TESTDLL)) strarray_add( &make->object_files[arch], obj_name ); else strarray_add( &make->clean_files, obj_name ); @@ -3204,8 +3209,8 @@ static void output_source_one_arch( struct makefile *make, struct incl_file *sou output_filename( arch_make_variable( "CFLAGS", arch )); output( "\n" );
- if (make->testdll && !is_dll_src && strendswith( source->name, ".c" ) && - !(source->file->flags & FLAG_GENERATED)) + if (make->testdll && strendswith( source->name, ".c" ) && + !(source->file->flags & (FLAG_GENERATED | FLAG_C_TESTDLL))) { const char *ok_file, *test_exe;
@@ -3228,22 +3233,25 @@ static void output_source_default( struct makefile *make, struct incl_file *sour { struct strarray defines = get_source_defines( make, source, obj ); struct strarray targets = empty_strarray; - int is_dll_src = (make->testdll && strendswith( source->name, ".c" ) && - find_src_file( make, replace_extension( source->name, ".c", ".spec" ))); unsigned int arch;
- for (arch = 0; arch < archs.count; arch++) - if (!source->arch || source->arch == arch) - output_source_one_arch( make, source, obj, defines, &targets, arch, is_dll_src ); + if (!strendswith( source->name, ".spec" )) + { + for (arch = 0; arch < archs.count; arch++) + if (!source->arch || source->arch == arch) + output_source_one_arch( make, source, obj, defines, &targets, arch ); + }
if (source->file->flags & FLAG_GENERATED) { if (!make->testdll || !strendswith( source->filename, "testlist.c" )) strarray_add( &make->clean_files, source->basename ); } + else if (source->file->flags & FLAG_C_TESTDLL) + output_source_testdll( make, source, obj ); else { - if (make->testdll && !is_dll_src && strendswith( source->name, ".c" )) + if (make->testdll && strendswith( source->name, ".c" )) strarray_add( &make->test_files, obj ); }
@@ -3280,7 +3288,6 @@ static const struct { "po", output_source_po }, { "in", output_source_in }, { "x", output_source_x }, - { "spec", output_source_spec }, { "xml", output_source_xml }, { NULL, output_source_default } };
From: Rémi Bernon rbernon@codeweavers.com
--- tools/makedep.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index 41f1756686f..79399108fb2 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -3068,7 +3068,7 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour struct strarray dll_flags = empty_strarray; struct strarray default_imports = empty_strarray; struct strarray all_libs, dep_libs; - const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *debug_file; + const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *debug_file, *ext; struct incl_file *spec_file = find_src_file( make, replace_extension( source->name, ".c", ".spec" ) ); unsigned int arch;
@@ -3077,7 +3077,9 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour strarray_addall( &dll_flags, get_expanded_file_local_var( make, obj, "EXTRADLLFLAGS" )); if (!strarray_exists( &dll_flags, "-nodefaultlibs" )) default_imports = get_default_imports( make, imports );
- if (!spec_file) fatal_error( "testdll source %s needs a .spec file\n", source->name ); + if (strarray_exists( &dll_flags, "-Wl,--subsystem,console" )) ext = ".exe"; + else if (!spec_file) fatal_error( "testdll source %s needs a .spec file\n", source->name ); + else ext = ".dll";
for (arch = 0; arch < archs.count; arch++) { @@ -3086,7 +3088,7 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour strarray_addall( &all_libs, add_import_libs( make, &dep_libs, imports, IMPORT_TYPE_DIRECT, arch ) ); strarray_addall( &all_libs, add_import_libs( make, &dep_libs, default_imports, IMPORT_TYPE_DEFAULT, arch ) ); if (!arch) strarray_addall( &all_libs, libs ); - dll_name = arch_module_name( strmake( "%s.dll", obj ), arch ); + dll_name = arch_module_name( strmake( "%s%s", obj, ext ), arch ); obj_name = obj_dir_path( make, strmake( "%s%s.o", arch_dirs[arch], obj )); output_file = obj_dir_path( make, dll_name ); output_rsrc = strmake( "%s.res", dll_name ); @@ -3100,11 +3102,11 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour output_filename( output_file ); output_filename( tools_path( make, "wrc" )); output( "\n" ); - output( "\t%secho "%s.dll TESTDLL \"%s\"" | %s -u -o $@\n", cmd_prefix( "WRC" ), obj, output_file, + output( "\t%secho "%s%s TESTDLL \"%s\"" | %s -u -o $@\n", cmd_prefix( "WRC" ), obj, ext, output_file, tools_path( make, "wrc" ));
output( "%s:", output_file ); - output_filename( spec_file->filename ); + if (spec_file) output_filename( spec_file->filename ); output_filename( obj_name ); if (res_name) output_filename( res_name ); output_filenames( dep_libs ); @@ -3115,8 +3117,8 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour output_filename( "-s" ); output_filenames( dll_flags ); if (arch) output_filenames( get_expanded_arch_var_array( make, "EXTRADLLFLAGS", arch )); - output_filename( "-shared" ); - output_filename( spec_file->filename ); + if (!strcmp( ext, ".dll" )) output_filename( "-shared" ); + if (spec_file) output_filename( spec_file->filename ); output_filename( obj_name ); if (res_name) output_filename( res_name ); if ((debug_file = get_debug_file( make, dll_name, arch )))
From: Rémi Bernon rbernon@codeweavers.com
--- .../tests/Makefile.in | 10 +- .../tests/application.c | 33 ++ .../tests/appxmanifest.xml | 26 ++ dlls/windows.applicationmodel/tests/model.c | 326 ++++++++++++++++++ .../tests/resource.rc | 22 ++ 5 files changed, 414 insertions(+), 3 deletions(-) create mode 100644 dlls/windows.applicationmodel/tests/application.c create mode 100644 dlls/windows.applicationmodel/tests/appxmanifest.xml create mode 100644 dlls/windows.applicationmodel/tests/resource.rc
diff --git a/dlls/windows.applicationmodel/tests/Makefile.in b/dlls/windows.applicationmodel/tests/Makefile.in index 265144f097c..2efd8ab7861 100644 --- a/dlls/windows.applicationmodel/tests/Makefile.in +++ b/dlls/windows.applicationmodel/tests/Makefile.in @@ -1,5 +1,9 @@ TESTDLL = windows.applicationmodel.dll -IMPORTS = combase +IMPORTS = combase advapi32
-C_SRCS = \ - model.c +application_EXTRADLLFLAGS = -Wl,--subsystem,console + +SOURCES = \ + model.c \ + application.c \ + resource.rc diff --git a/dlls/windows.applicationmodel/tests/application.c b/dlls/windows.applicationmodel/tests/application.c new file mode 100644 index 00000000000..9a812d6951a --- /dev/null +++ b/dlls/windows.applicationmodel/tests/application.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Rémi Bernon for CodeWeavers + * + * 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 + */ + +#if 0 +#pragma makedep testdll +#endif + +#define COBJMACROS +#include <stddef.h> +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + +int main( int argc, char const *argv[] ) +{ + return 0; +} diff --git a/dlls/windows.applicationmodel/tests/appxmanifest.xml b/dlls/windows.applicationmodel/tests/appxmanifest.xml new file mode 100644 index 00000000000..33cf6ae6c1c --- /dev/null +++ b/dlls/windows.applicationmodel/tests/appxmanifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" + xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" + xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedca... + <Identity Name="WineTest" Publisher="CN=Wine, O=The Wine Project, C=US" Version="1.0.0.0" ProcessorArchitecture="neutral" /> + <Properties> + <DisplayName>WineTest</DisplayName> + <PublisherDisplayName>The Wine Project</PublisherDisplayName> + <Description>Reserved</Description> + <Logo>logo.png</Logo> + </Properties> + <Resources> + <Resource Language="en-us" /> + </Resources> + <Dependencies> + <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.0.0" MaxVersionTested="10.0.65535.0" /> + </Dependencies> + <Capabilities> + <rescap:Capability Name="runFullTrust" /> + </Capabilities> + <Applications> + <Application Id="WineTest" Executable="application.exe" EntryPoint="Windows.FullTrustApplication"> + <uap:VisualElements BackgroundColor="transparent" DisplayName="WineTest" Square150x150Logo="logo.png" Square44x44Logo="logo.png" Description="WineTest" /> + </Application> + </Applications> +</Package> diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index 50513e45fd4..b15024f6ca9 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -38,6 +38,94 @@
#include "wine/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( obj, iid ) check_interface_( __LINE__, obj, iid ) static void check_interface_( unsigned int line, void *obj, const IID *iid ) { @@ -51,6 +139,238 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) IUnknown_Release( unk ); }
+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 ) + +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_PackageManager(void) { static const WCHAR *statics_name = RuntimeClass_Windows_Management_Deployment_PackageManager; @@ -120,6 +440,12 @@ static void test_PackageManager(void) ref = IIterable_Package_Release( packages ); ok( !ref, "got ref %ld.\n", ref );
+ if (SUCCEEDED(test_register_package( manager, &package ))) + { + test_remove_package( manager, package ); + IPackage_Release( package ); + } + skip_tests: ref = IPackageManager_Release( manager ); ok( !ref, "got ref %ld.\n", ref ); diff --git a/dlls/windows.applicationmodel/tests/resource.rc b/dlls/windows.applicationmodel/tests/resource.rc new file mode 100644 index 00000000000..a78e2afd7d9 --- /dev/null +++ b/dlls/windows.applicationmodel/tests/resource.rc @@ -0,0 +1,22 @@ +/* + * Copyright 2022 Rémi Bernon for CodeWeavers + * + * 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 "windef.h" + +/* @makedep: appxmanifest.xml */ +appxmanifest.xml RCDATA appxmanifest.xml
From: Rémi Bernon rbernon@codeweavers.com
--- .../tests/application.c | 17 ++ dlls/windows.applicationmodel/tests/model.c | 52 ++++ .../tests/winrt_test.h | 245 ++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 dlls/windows.applicationmodel/tests/winrt_test.h
diff --git a/dlls/windows.applicationmodel/tests/application.c b/dlls/windows.applicationmodel/tests/application.c index 9a812d6951a..a3f0ceb07d9 100644 --- a/dlls/windows.applicationmodel/tests/application.c +++ b/dlls/windows.applicationmodel/tests/application.c @@ -26,8 +26,25 @@
#include "windef.h" #include "winbase.h" +#include "initguid.h" +#include "winstring.h" + +#include "roapi.h" + +#define WINE_WINRT_TEST +#include "winrt_test.h"
int main( int argc, char const *argv[] ) { + HRESULT hr; + + if (!winrt_test_init()) return -1; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + RoUninitialize(); + + winrt_test_exit(); return 0; } diff --git a/dlls/windows.applicationmodel/tests/model.c b/dlls/windows.applicationmodel/tests/model.c index b15024f6ca9..ca1da5daded 100644 --- a/dlls/windows.applicationmodel/tests/model.c +++ b/dlls/windows.applicationmodel/tests/model.c @@ -37,6 +37,7 @@ #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 \ @@ -192,6 +193,9 @@ static void check_async_info_( int line, void *async, AsyncStatus expect_status,
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 ) { @@ -371,6 +375,53 @@ static void test_remove_package( IPackageManager *manager, IPackage *package ) 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; @@ -442,6 +493,7 @@ static void test_PackageManager(void)
if (SUCCEEDED(test_register_package( manager, &package ))) { + test_execute_package( package ); test_remove_package( manager, package ); IPackage_Release( package ); } diff --git a/dlls/windows.applicationmodel/tests/winrt_test.h b/dlls/windows.applicationmodel/tests/winrt_test.h new file mode 100644 index 00000000000..7419782f8df --- /dev/null +++ b/dlls/windows.applicationmodel/tests/winrt_test.h @@ -0,0 +1,245 @@ +/* + * Copyright 2023 Rémi Bernon for CodeWeavers + * + * 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_WINRT_TEST_H +#define __WINE_WINRT_TEST_H + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" + +#include "wine/test.h" + +/* desktop/winrt shared data */ +struct winetest_shared_data +{ + BOOL running_under_wine; + BOOL winetest_report_success; + BOOL winetest_debug; + LONG failures; + LONG todo_failures; +}; + +static HANDLE winrt_section; +static HANDLE winrt_okfile; +static HANDLE winrt_event; + +#define winrt_test_init() winrt_test_init_( __FILE__, __LINE__ ) +#define winrt_test_exit() winrt_test_exit_( __FILE__, __LINE__ ) + +#ifndef WINE_WINRT_TEST + +static BOOL winrt_test_init_( const char *file, int line ) +{ + struct winetest_shared_data *data; + + winrt_section = CreateFileMappingW( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(*data), + L"winetest_winrt_section" ); + if (!winrt_section && GetLastError() == ERROR_ACCESS_DENIED) + { + win_skip_(file, line)( "Skipping WinRT tests: failed to create mapping.\n" ); + return FALSE; + } + ok_(file, line)( !!winrt_section, "got error %lu\n", GetLastError() ); + + data = MapViewOfFile( winrt_section, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024 ); + ok_(file, line)( !!data, "MapViewOfFile failed, error %lu\n", GetLastError() ); + data->running_under_wine = !strcmp( winetest_platform, "wine" ); + data->winetest_report_success = winetest_report_success; + data->winetest_debug = winetest_debug; + UnmapViewOfFile( data ); + + winrt_okfile = CreateFileW( L"C:\Users\Public\Documents\winetest_winrt_okfile", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL ); + ok_(file, line)( winrt_okfile != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError() ); + + winrt_event = CreateEventW( 0, FALSE, FALSE, L"winetest_winrt_event" ); + ok_(file, line)( !!winrt_event, "got error %lu\n", GetLastError() ); + + subtest_(file, line)( "application" ); + return TRUE; +} + +static void winrt_test_exit_( const char *file, int line ) +{ + struct winetest_shared_data *data; + char buffer[512]; + DWORD size, res; + + res = WaitForSingleObject( winrt_event, 5000 ); + ok_(file, line)( !res, "WaitForSingleObject returned %#lx\n", res ); + CloseHandle( winrt_event ); + + SetFilePointer( winrt_okfile, 0, NULL, FILE_BEGIN ); + do + { + ReadFile( winrt_okfile, buffer, sizeof(buffer), &size, NULL ); + printf( "%.*s", (int)size, buffer ); + } while (size == sizeof(buffer)); + SetFilePointer( winrt_okfile, 0, NULL, FILE_BEGIN ); + SetEndOfFile( winrt_okfile ); + CloseHandle( winrt_okfile ); + DeleteFileW( L"C:\Users\Public\Documents\winetest_winrt_okfile" ); + + data = MapViewOfFile( winrt_section, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024 ); + ok_(file, line)( !!data, "MapViewOfFile failed, error %lu\n", GetLastError() ); + winetest_add_failures( InterlockedExchange( &data->failures, 0 ) ); + winetest_add_failures( InterlockedExchange( &data->todo_failures, 0 ) ); + UnmapViewOfFile( data ); + CloseHandle( winrt_section ); +} + +#else /* WINE_WINRT_TEST */ + +static DWORD tls_index; + +LONG winetest_successes; +LONG winetest_failures; +LONG winetest_flaky_failures; +LONG winetest_skipped; +LONG winetest_todo_successes; +LONG winetest_todo_failures; +LONG winetest_muted_traces; +LONG winetest_muted_skipped; +LONG winetest_muted_todo_successes; + +const char *winetest_platform; +int winetest_platform_is_wine; +int winetest_debug; +int winetest_report_success; +int winetest_color = 0; +int winetest_time = 0; +int winetest_start_time, winetest_last_time; + +/* silence todos and skips above this threshold */ +int winetest_mute_threshold = 42; + +struct winetest_thread_data *winetest_get_thread_data(void) +{ + struct winetest_thread_data *data; + + if (!(data = TlsGetValue( tls_index ))) + { + data = calloc( 1, sizeof(*data) ); + data->str_pos = data->strings; + TlsSetValue( tls_index, data ); + } + + return data; +} + +void winetest_print_lock(void) +{ +} + +void winetest_print_unlock(void) +{ +} + +int winetest_vprintf( const char *format, va_list args ) +{ + struct winetest_thread_data *data = winetest_get_thread_data(); + DWORD written; + int len; + + len = vsnprintf( data->str_pos, sizeof(data->strings) - (data->str_pos - data->strings), format, args ); + data->str_pos += len; + + if (len && data->str_pos[-1] == '\n') + { + WriteFile( winrt_okfile, data->strings, strlen( data->strings ), &written, NULL ); + data->str_pos = data->strings; + } + + return len; +} + +int winetest_get_time(void) +{ + return GetTickCount(); +} + +static inline BOOL winrt_test_init_( const char *file, int line ) +{ + const struct winetest_shared_data *data; + + tls_index = TlsAlloc(); + + winrt_okfile = CreateFileW( L"C:\Users\Public\Documents\winetest_winrt_okfile", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + if (!winrt_okfile) return FALSE; + + winrt_event = OpenEventW( EVENT_ALL_ACCESS, FALSE, L"winetest_winrt_event" ); + ok_(file, line)( !!winrt_event, "OpenEventW failed, error %lu\n", GetLastError() ); + + winrt_section = OpenFileMappingW( FILE_MAP_ALL_ACCESS, FALSE, L"winetest_winrt_section" ); + ok_(file, line)( !!winrt_section, "OpenFileMappingW failed, error %lu\n", GetLastError() ); + + data = MapViewOfFile( winrt_section, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024 ); + ok_(file, line)( !!data, "MapViewOfFile failed, error %lu\n", GetLastError() ); + winetest_platform_is_wine = data->running_under_wine; + winetest_platform = winetest_platform_is_wine ? "wine" : "windows"; + winetest_debug = data->winetest_debug; + winetest_report_success = data->winetest_report_success; + UnmapViewOfFile( data ); + + return TRUE; +} + +static inline void winrt_test_exit_( const char *file, int line ) +{ + char test_name[MAX_PATH], *tmp; + struct winetest_shared_data *data; + const char *source_file; + + source_file = strrchr( file, '/' ); + if (!source_file) source_file = strrchr( file, '\' ); + if (!source_file) source_file = file; + else source_file++; + + strcpy( test_name, source_file ); + if ((tmp = strrchr( test_name, '.' ))) *tmp = 0; + + data = MapViewOfFile( winrt_section, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024 ); + ok_(file, line)( !!data, "MapViewOfFile failed, error %lu\n", GetLastError() ); + InterlockedExchangeAdd( &data->failures, winetest_failures ); + InterlockedExchangeAdd( &data->todo_failures, winetest_todo_failures ); + UnmapViewOfFile( data ); + CloseHandle( winrt_section ); + + if (winetest_debug) + { + winetest_printf( "%04lx:%s: %ld tests executed (%ld marked as todo, 0 as flaky, %ld %s), %ld skipped.\n", + (DWORD)(DWORD_PTR)GetCurrentProcessId(), test_name, + winetest_successes + winetest_failures + winetest_todo_successes + winetest_todo_failures, + winetest_todo_successes, winetest_failures + winetest_todo_failures, + (winetest_failures + winetest_todo_failures != 1) ? "failures" : "failure", winetest_skipped ); + } + CloseHandle( winrt_okfile ); + + SetEvent( winrt_event ); + CloseHandle( winrt_event ); +} + +#endif /* WINE_WINRT_TEST */ + +#endif /* __WINE_WINRT_TEST_H */
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=136929
Your paranoid android.
=== w10pro64_ar (64 bit report) ===
msi: install.c:2171: Test failed: Failed to CreateFile C:\Users\winetest\AppData\Local\Temp\test2.cab install.c:3084: Test failed: Failed to flush the cabinet
=== w8adm (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 785#@#136929#@#102#@#5#@#exe32.report for Failure 785
=== w7u_2qxl (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 201#@#136929#@#116#@#1#@#exe32.report for Failure 201
=== w7u_adm (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 201#@#136929#@#116#@#2#@#exe32.report for Failure 201
=== w7u_el (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 201#@#136929#@#116#@#3#@#exe32.report for Failure 201
=== w7pro64 (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 201#@#136929#@#117#@#1#@#exe64.report for Failure 201
=== w10pro64_en_AE_u8 (testbot log) ===
WineRunTask.pl:error: Step no: Too long for TaskFailure 111#@#136929#@#129#@#9#@#exe64.report for Failure 111
=== w8 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w8adm (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w864 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== 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.
=== w11pro64 (32 bit report) ===
windows.applicationmodel: Fatal: test 'application' does not exist.
=== w864 (64 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_en_AE_u8 (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.
=== debian11 (build log) ===
WineRunWineTest.pl:error: Step no: Too long for TaskFailure 119#@#136929#@#176#@#1#@#win32_ar_MA.report for Failure 119 WineRunWineTest.pl:error: Step no: Too long for TaskFailure 119#@#136929#@#176#@#1#@#win32_de_DE.report for Failure 119 WineRunWineTest.pl:error: Step no: Too long for TaskFailure 119#@#136929#@#176#@#1#@#win32_fr_FR.report for Failure 119 WineRunWineTest.pl:error: Step no: Too long for TaskFailure 119#@#136929#@#176#@#1#@#win32_ja_JP.report for Failure 119
=== debian11b (build log) ===
WineRunWineTest.pl:error: Step no: Too long for TaskFailure 146#@#136929#@#176#@#2#@#wow64.report for Failure 146
v3: Rebase the MR on top of latest changes (should fix the build).
Anything else I should do here?