From: Sebastian Lackner sebastian@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- Changes from staging version:
* use .cross.res extension for cross-compiled resource * use replace_extension() instead of defining a new function * use phony targets in the tests makefile so that the custom DLL is always built * enforce directory name the same way we do for other targets
aclocal.m4 | 25 +++++++++ tools/make_makefiles | 11 +++- tools/makedep.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 175 insertions(+), 3 deletions(-)
diff --git a/aclocal.m4 b/aclocal.m4 index 9364188..a711b20 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -540,6 +540,22 @@ $ac_dir/crosstest: __builddeps__ dummy fi }
+wine_fn_config_resource () +{ + ac_dir=$[1] + ac_name=$[2] + ac_flags=$[3] + + ac_clean= + test -n "$CROSSTARGET" && ac_clean=`expr $ac_dir/$ac_name : "\(.*\)\."`_crossres.`expr $ac_name : ".*\.\(.*\)"` + test -n "$DLLEXT" || ac_clean="$ac_dir/$ac_name" + + AS_VAR_IF([enable_tests],[no],[wine_fn_disabled_rules $ac_clean; return]) + + wine_fn_append_file SUBDIRS $ac_dir + wine_fn_clean_rules $ac_clean +} + wine_fn_config_tool () { ac_dir=$[1] @@ -643,6 +659,15 @@ wine_fn_config_test $1 ac_name[]ac_suffix [$2]dnl m4_popdef([ac_suffix])dnl m4_popdef([ac_name])])
+dnl **** Create a test resource makefile from config.status **** +dnl +dnl Usage: WINE_CONFIG_RESOURCE(dir,flags) +dnl +AC_DEFUN([WINE_CONFIG_RESOURCE],[AC_REQUIRE([WINE_CONFIG_HELPERS])dnl +m4_pushdef([ac_name],[m4_bpatsubst([$1],[.*/([^/]*)$],[\1])])dnl +wine_fn_config_resource $1 ac_name [$2]dnl +m4_popdef([ac_name])]) + dnl **** Create a static lib makefile from config.status **** dnl dnl Usage: WINE_CONFIG_LIB(name,flags) diff --git a/tools/make_makefiles b/tools/make_makefiles index f57a7e2..44f0fc2 100755 --- a/tools/make_makefiles +++ b/tools/make_makefiles @@ -224,7 +224,7 @@ sub parse_makefile($) { die "Configure substitution is not allowed in $file" unless $file eq "Makefile"; } - if (/^\s*(MODULE|IMPORTLIB|TESTDLL|PARENTSRC|APPMODE)\s*=\s*(.*)/) + if (/^\s*(MODULE|IMPORTLIB|TESTDLL|RESOURCE|PARENTSRC|APPMODE)\s*=\s*(.*)/) { my $var = $1; $make{$var} = $2; @@ -466,6 +466,15 @@ sub update_makefiles(@) (my $dir = $file) =~ s/^(.*)/Makefile/$1/; push @lines, "WINE_CONFIG_TEST($dir$flag_args)\n"; } + elsif (defined($make{"RESOURCE"})) # test resource + { + die "MODULE should not be defined in $file" if defined $make{"MODULE"}; + die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"}; + (my $dir = $file) =~ s/^(.*)/Makefile/$1/; + (my $name = $dir) =~ s/^.*/(.*)$/$1/; + die "Invalid RESOURCE in $file" unless $make{"RESOURCE"} eq $name; + push @lines, "WINE_CONFIG_RESOURCE($dir$flag_args)\n"; + } elsif (defined($make{"MODULE"}) && $make{"MODULE"} =~ /.a$/) # import lib { die "MODULE should not be defined as static lib in $file" unless $file =~ /^dlls//; diff --git a/tools/makedep.c b/tools/makedep.c index ec339e0..afa061a 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -174,6 +174,7 @@ struct makefile const char *parent_dir; const char *module; const char *testdll; + const char *resource; const char *sharedlib; const char *staticlib; const char *staticimplib; @@ -2345,6 +2346,7 @@ static struct strarray output_sources( const struct makefile *make ) struct strarray includes = empty_strarray; struct strarray phony_targets = empty_strarray; struct strarray all_targets = empty_strarray; + struct strarray resource_dlls = get_expanded_make_var_array( make, "RC_DLLS" ); struct strarray install_rules[NB_INSTALL_RULES]; char *ldrpath_local = get_expanded_make_variable( make, "LDRPATH_LOCAL" ); char *ldrpath_install = get_expanded_make_variable( make, "LDRPATH_INSTALL" ); @@ -2642,7 +2644,7 @@ static struct strarray output_sources( const struct makefile *make ) } else { - int need_cross = make->testdll || + int need_cross = make->testdll || make->resource || (source->file->flags & FLAG_C_IMPLIB) || (make->module && make->staticlib);
@@ -2656,7 +2658,7 @@ static struct strarray output_sources( const struct makefile *make ) output_filenames( includes ); output_filenames( make->define_args ); output_filenames( extradefs ); - if (make->module || make->staticlib || make->sharedlib || make->testdll) + if (make->module || make->staticlib || make->sharedlib || make->testdll || make->resource) { output_filenames( dll_flags ); if (make->use_msvcrt) output_filenames( msvcrt_flags ); @@ -2710,6 +2712,66 @@ static struct strarray output_sources( const struct makefile *make ) output( "\n" ); }
+ /* rules for resource dlls, call Makefile in subdirectory */ + + if (resource_dlls.count) + { + for (i = 0; i < resource_dlls.count; i++) + { + output( ".PHONY: %s\n", resource_dlls.str[i] ); + output( "%s:\n", resource_dlls.str[i] ); + output( "\t@cd %s && $(MAKE) %s%s\n", resource_dlls.str[i], + resource_dlls.str[i], dll_ext ); + } + + output( "%s:", obj_dir_path( make, "resource_dlls.res" )); + for (i = 0; i < resource_dlls.count; i++) + output( " %s", resource_dlls.str[i] ); + output( "\n" ); + output( "\t(" ); + for (i = 0; i < resource_dlls.count; i++) + { + if (i != 0) output( "; \\n " ); + output( "echo "%s RCDATA %s/%s%s"", resource_dlls.str[i], + resource_dlls.str[i], resource_dlls.str[i], dll_ext ); + } + output( ") | %s -o $@\n", tools_path( make, "wrc" ) ); + strarray_add( &clean_files, "resource_dlls.res" ); + strarray_add( &object_files, "resource_dlls.res" ); + + if (crosstarget && (make->testdll || (make->module && make->staticlib))) + { + for (i = 0; i < resource_dlls.count; i++) + { + char *name = replace_extension( resource_dlls.str[i], ".dll", "_crossres.dll" ); + output( ".PHONY: %s/crossres\n", resource_dlls.str[i] ); + output( "%s/crossres:\n", resource_dlls.str[i] ); + output( "\t@cd %s && $(MAKE) %s\n", resource_dlls.str[i], name ); + free( name ); + } + + output( "%s:", obj_dir_path( make, "resource_dlls.cross.res" )); + for (i = 0; i < resource_dlls.count; i++) + { + char *name = replace_extension( resource_dlls.str[i], ".dll", "_crossres.dll" ); + output( " %s/crossres", resource_dlls.str[i] ); + free( name ); + } + output( "\n" ); + output( "\t(" ); + for (i = 0; i < resource_dlls.count; i++) + { + char *name = replace_extension( resource_dlls.str[i], ".dll", "_crossres.dll" ); + if (i != 0) output( "; \\n " ); + output( "echo "%s RCDATA %s/%s"", resource_dlls.str[i], resource_dlls.str[i], name ); + free( name ); + } + output( ") | %s -o $@\n", tools_path( make, "wrc" ) ); + strarray_add( &clean_files, "resource_dlls.cross.res" ); + strarray_add( &crossobj_files, "resource_dlls.cross.res" ); + } + } + if (make->module && !make->staticlib) { struct strarray all_libs = empty_strarray; @@ -3101,6 +3163,81 @@ static struct strarray output_sources( const struct makefile *make ) add_install_rule( make, install_rules, make->scripts.str[i], make->scripts.str[i], strmake( "S$(bindir)/%s", make->scripts.str[i] ));
+ if (make->resource) + { + char *extra_wine_flags = get_expanded_make_variable( make, "WINEFLAGS" ); + char *extra_cross_flags = get_expanded_make_variable( make, "CROSSFLAGS" ); + struct strarray all_libs = empty_strarray; + char *module_path = obj_dir_path( make, make->resource ); + char *spec_file = NULL; + + if (!make->appmode.count) + spec_file = src_dir_path( make, replace_extension( make->resource, ".dll", ".spec" )); + for (i = 0; i < make->imports.count; i++) + strarray_add( &all_libs, strmake( "-l%s", make->imports.str[i] )); + strarray_addall( &all_libs, get_expanded_make_var_array( make, "LIBS" )); + + if (*dll_ext) + { + strarray_add( &all_targets, strmake( "%s%s", make->resource, dll_ext )); + strarray_add( &all_targets, strmake( "%s.fake", make->resource )); + output( "%s%s %s.fake:", module_path, dll_ext, module_path ); + } + else + { + strarray_add( &all_targets, make->resource ); + output( "%s:", module_path ); + } + if (spec_file) output_filename( spec_file ); + output_filenames_obj_dir( make, object_files ); + output_filenames_obj_dir( make, res_files ); + output( "\n" ); + output( "\t%s -o $@", tools_path( make, "winegcc" )); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filenames( target_flags ); + output_filenames( unwind_flags ); + if (spec_file) + { + output( " -shared %s", spec_file ); + output_filenames( make->extradllflags ); + } + else output_filenames( make->appmode ); + if (extra_wine_flags) output( " %s", extra_wine_flags ); + output_filenames_obj_dir( make, object_files ); + output_filenames_obj_dir( make, res_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + + if (crosstarget) + { + char *crossres = replace_extension( make->resource, ".dll", "_crossres.dll" ); + + strarray_add( &clean_files, crossres ); + output( "%s:", obj_dir_path( make, crossres )); + output_filenames_obj_dir( make, crossobj_files ); + output_filenames_obj_dir( make, res_files ); + output( "\n" ); + output( "\t%s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget ); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filename( "--lib-suffix=.cross.a" ); + if (spec_file) + { + output( " -shared %s", spec_file ); + output_filenames( make->extradllflags ); + } + else output_filenames( make->appmode ); + if (extra_cross_flags) output( " %s", extra_cross_flags ); + output_filenames_obj_dir( make, crossobj_files ); + output_filenames_obj_dir( make, res_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + } + } + if (!make->disabled) { if (all_targets.count) @@ -3476,6 +3613,7 @@ static void load_sources( struct makefile *make ) make->parent_dir = get_expanded_make_variable( make, "PARENTSRC" ); make->module = get_expanded_make_variable( make, "MODULE" ); make->testdll = get_expanded_make_variable( make, "TESTDLL" ); + make->resource = get_expanded_make_variable( make, "RESOURCE" ); make->sharedlib = get_expanded_make_variable( make, "SHAREDLIB" ); make->staticlib = get_expanded_make_variable( make, "STATICLIB" ); make->importlib = get_expanded_make_variable( make, "IMPORTLIB" );
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/Makefile.in | 3 +++ dlls/msi/tests/custom.dll/Makefile.in | 4 ++++ dlls/msi/tests/custom.dll/custom.spec | 0 dlls/msi/tests/custom.dll/main.c | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 dlls/msi/tests/custom.dll/Makefile.in create mode 100644 dlls/msi/tests/custom.dll/custom.spec create mode 100644 dlls/msi/tests/custom.dll/main.c
diff --git a/dlls/msi/tests/Makefile.in b/dlls/msi/tests/Makefile.in index 66f8abb..fd3d9bd 100644 --- a/dlls/msi/tests/Makefile.in +++ b/dlls/msi/tests/Makefile.in @@ -13,3 +13,6 @@ C_SRCS = \ record.c \ source.c \ suminfo.c + +RC_DLLS = \ + custom.dll diff --git a/dlls/msi/tests/custom.dll/Makefile.in b/dlls/msi/tests/custom.dll/Makefile.in new file mode 100644 index 0000000..a711e4b --- /dev/null +++ b/dlls/msi/tests/custom.dll/Makefile.in @@ -0,0 +1,4 @@ +RESOURCE = custom.dll + +C_SRCS = \ + main.c diff --git a/dlls/msi/tests/custom.dll/custom.spec b/dlls/msi/tests/custom.dll/custom.spec new file mode 100644 index 0000000..e69de29 diff --git a/dlls/msi/tests/custom.dll/main.c b/dlls/msi/tests/custom.dll/main.c new file mode 100644 index 0000000..838b8ae --- /dev/null +++ b/dlls/msi/tests/custom.dll/main.c @@ -0,0 +1,26 @@ +/* + * DLL for testing type 1 custom actions + * + * Copyright 2017 Zebediah Figura + * + * 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> + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) +{ + return TRUE; +}
On Thu, 2017-11-23 at 15:35 -0600, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/msi/tests/Makefile.in | 3 +++ dlls/msi/tests/custom.dll/Makefile.in | 4 ++++ dlls/msi/tests/custom.dll/custom.spec | 0 dlls/msi/tests/custom.dll/main.c | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 dlls/msi/tests/custom.dll/Makefile.in create mode 100644 dlls/msi/tests/custom.dll/custom.spec create mode 100644 dlls/msi/tests/custom.dll/main.c
It doesn't build here:
$ make make[1]: Entering directory '/home/hans/wine/dlls/msi/tests/custom.dll' make[1]: *** No rule to make target 'custom.dll.so'. Stop. make[1]: Leaving directory '/home/hans/wine/dlls/msi/tests/custom.dll' Makefile:606: recipe for target 'custom.dll' failed make: *** [custom.dll] Error 2
On 11/24/2017 03:03 AM, Hans Leidekker wrote:
On Thu, 2017-11-23 at 15:35 -0600, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/msi/tests/Makefile.in | 3 +++ dlls/msi/tests/custom.dll/Makefile.in | 4 ++++ dlls/msi/tests/custom.dll/custom.spec | 0 dlls/msi/tests/custom.dll/main.c | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 dlls/msi/tests/custom.dll/Makefile.in create mode 100644 dlls/msi/tests/custom.dll/custom.spec create mode 100644 dlls/msi/tests/custom.dll/main.c
It doesn't build here:
$ make make[1]: Entering directory '/home/hans/wine/dlls/msi/tests/custom.dll' make[1]: *** No rule to make target 'custom.dll.so'. Stop. make[1]: Leaving directory '/home/hans/wine/dlls/msi/tests/custom.dll' Makefile:606: recipe for target 'custom.dll' failed make: *** [custom.dll] Error 2
I'll try to look into this. Could you send me your custom.dll/Makefile? Thanks.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/custom.dll/Makefile.in | 1 + dlls/msi/tests/custom.dll/custom.spec | 1 + dlls/msi/tests/custom.dll/main.c | 17 ++++++ dlls/msi/tests/install.c | 100 ++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+)
diff --git a/dlls/msi/tests/custom.dll/Makefile.in b/dlls/msi/tests/custom.dll/Makefile.in index a711e4b..c606b22 100644 --- a/dlls/msi/tests/custom.dll/Makefile.in +++ b/dlls/msi/tests/custom.dll/Makefile.in @@ -1,4 +1,5 @@ RESOURCE = custom.dll +IMPORTS = msi
C_SRCS = \ main.c diff --git a/dlls/msi/tests/custom.dll/custom.spec b/dlls/msi/tests/custom.dll/custom.spec index e69de29..2a01b3d 100644 --- a/dlls/msi/tests/custom.dll/custom.spec +++ b/dlls/msi/tests/custom.dll/custom.spec @@ -0,0 +1 @@ +@ stdcall test_retval(long) diff --git a/dlls/msi/tests/custom.dll/main.c b/dlls/msi/tests/custom.dll/main.c index 838b8ae..7a970bf 100644 --- a/dlls/msi/tests/custom.dll/main.c +++ b/dlls/msi/tests/custom.dll/main.c @@ -18,9 +18,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <stdarg.h> +#include <stdio.h> + #include <windef.h> +#include <winbase.h> +#include <msi.h> +#include <msiquery.h>
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) { return TRUE; } + +UINT WINAPI test_retval(MSIHANDLE hinst) +{ + char prop[10]; + DWORD len = sizeof(prop); + UINT retval; + + MsiGetPropertyA(hinst, "TEST_RETVAL", prop, &len); + sscanf(prop, "%u", &retval); + return retval; +} diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 9d2a75b..cc1b536 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -70,6 +70,8 @@ static CHAR COMMON_FILES_DIR[MAX_PATH]; static CHAR APP_DATA_DIR[MAX_PATH]; static CHAR WINDOWS_DIR[MAX_PATH];
+static const char *customdll; + /* msi database data */
static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" @@ -690,6 +692,16 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt "Component\tComponent\n" "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
+static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "testretval\t\t710\n"; + +static const CHAR ca1_custom_action_dat[] = "Action\tType\tSource\tTarget\n" + "s72\ti2\tS64\tS0\n" + "CustomAction\tAction\n" + "testretval\t1\tcustom.dll\ttest_retval\n"; + static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -1689,6 +1701,13 @@ static const msi_table sf_tables[] = ADD_TABLE(property), };
+static const msi_table ca1_tables[] = +{ + ADD_TABLE(property), + ADD_TABLE(ca1_install_exec_seq), + ADD_TABLE(ca1_custom_action), +}; + static const msi_table ca51_tables[] = { ADD_TABLE(ca51_component), @@ -2595,6 +2614,29 @@ static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) return RegDeleteKeyA( key, subkey ); }
+static char *load_resource(const char *name) +{ + static char path[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempFileNameA(".", name, 0, path); + + file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", path, GetLastError()); + + res = FindResourceA(NULL, name, (LPCSTR)RT_RCDATA); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); + + return path; +} + static void test_MsiInstallProduct(void) { UINT r; @@ -4020,6 +4062,59 @@ error: DeleteFileA("augustus"); }
+static void add_custom_dll(void) +{ + MSIHANDLE hdb = 0, record; + UINT res; + + res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb); + ok(res == ERROR_SUCCESS, "failed to open db: %u\n", res); + + res = run_query(hdb, 0, "CREATE TABLE `Binary` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL PRIMARY KEY `Name`)"); + ok(res == ERROR_SUCCESS, "failed to create Binary table: %u\n", res); + + record = MsiCreateRecord(1); + res = MsiRecordSetStreamA(record, 1, customdll); + ok(res == ERROR_SUCCESS, "failed to add %s to stream: %u\n", customdll, res); + + res = run_query(hdb, record, "INSERT INTO `Binary` (`Name`, `Data`) VALUES ('custom.dll', ?)"); + ok(res == ERROR_SUCCESS, "failed to insert into Binary table: %u\n", res); + + res = MsiDatabaseCommit(hdb); + ok(res == ERROR_SUCCESS, "failed to commit database: %u\n", res); + + MsiCloseHandle(record); + MsiCloseHandle(hdb); +} + +static void test_customaction1(void) +{ + UINT r; + + create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table)); + add_custom_dll(); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=0"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=1626"); /* ERROR_FUNCTION_NOT_CALLED*/ + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=1602"); + ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=259"); /* ERROR_NO_MORE_ITEMS */ + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* any other error maps to ERROR_INSTALL_FAILURE */ + r = MsiInstallProductA(msifile, "TEST_RETVAL=1"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + DeleteFileA(msifile); +} + static void test_customaction51(void) { UINT r; @@ -5996,6 +6091,8 @@ START_TEST(install) lstrcatA(log_file, "\msitest.log"); MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
+ customdll = load_resource("custom.dll"); + if (pSRSetRestorePointA) /* test has side-effects on win2k3 that cause failures in following tests */ test_MsiInstallProduct(); test_MsiSetComponentState(); @@ -6015,6 +6112,7 @@ START_TEST(install) test_adminprops(); test_missingcab(); test_sourcefolder(); + test_customaction1(); test_customaction51(); test_installstate(); test_sourcepath(); @@ -6040,6 +6138,8 @@ START_TEST(install) test_feature_tree(); test_deferred_action();
+ DeleteFileA(customdll); + DeleteFileA(log_file);
if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=34342
Your paranoid android.
=== wxppro (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w2003std (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== wvistau64 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w2008s64 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w7u (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w7pro64 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w8 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w864 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w1064 (32 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== wvistau64 (64 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w2008s64 (64 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w7pro64 (64 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w864 (64 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
=== w1064 (64 bit install) === install.c:2625: Test failed: couldn't find resource install.c:4094: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4097: Test failed: Expected ERROR_SUCCESS, got 1603 install.c:4100: Test failed: Expected ERROR_INSTALL_USEREXIT, got 1603 install.c:4103: Test failed: Expected ERROR_SUCCESS, got 1603
On 11/23/2017 07:21 PM, Marvin wrote:
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=34342
Your paranoid android.
I had mistakenly thought that the testbot ran make_makefiles before building. I've sent a patch in an attempt to fix this. I've successfully run the install tests with a cross-compiled executable (e.g. [1]), but I can resend the patch series with configure changes added if that would be preferred.
For bug #18070.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/tests/custom.dll/Makefile.in | 2 +- dlls/msi/tests/custom.dll/custom.spec | 1 + dlls/msi/tests/custom.dll/main.c | 41 +++++++++++++++++++++++++++++++++++ dlls/msi/tests/install.c | 30 ++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/msi/tests/custom.dll/Makefile.in b/dlls/msi/tests/custom.dll/Makefile.in index c606b22..1e7babe 100644 --- a/dlls/msi/tests/custom.dll/Makefile.in +++ b/dlls/msi/tests/custom.dll/Makefile.in @@ -1,5 +1,5 @@ RESOURCE = custom.dll -IMPORTS = msi +IMPORTS = msi uuid ole32
C_SRCS = \ main.c diff --git a/dlls/msi/tests/custom.dll/custom.spec b/dlls/msi/tests/custom.dll/custom.spec index 2a01b3d..9d1e821 100644 --- a/dlls/msi/tests/custom.dll/custom.spec +++ b/dlls/msi/tests/custom.dll/custom.spec @@ -1 +1,2 @@ +@ stdcall main_test(long) @ stdcall test_retval(long) diff --git a/dlls/msi/tests/custom.dll/main.c b/dlls/msi/tests/custom.dll/main.c index 7a970bf..d174c6e 100644 --- a/dlls/msi/tests/custom.dll/main.c +++ b/dlls/msi/tests/custom.dll/main.c @@ -23,14 +23,55 @@
#include <windef.h> #include <winbase.h> +#define COBJMACROS +#include <objbase.h> +#include <unknwn.h> #include <msi.h> #include <msiquery.h>
+static void ok_(MSIHANDLE hinst, int todo, const char *file, int line, int condition, const char *msg, ...) +{ + static char buffer[2000]; + MSIHANDLE record; + va_list valist; + + va_start(valist, msg); + vsprintf(buffer, msg, valist); + va_end(valist); + + record = MsiCreateRecord(5); + MsiRecordSetInteger(record, 1, todo); + MsiRecordSetStringA(record, 2, file); + MsiRecordSetInteger(record, 3, line); + MsiRecordSetInteger(record, 4, condition); + MsiRecordSetStringA(record, 5, buffer); + MsiProcessMessage(hinst, INSTALLMESSAGE_USER, record); + MsiCloseHandle(record); +} +#define ok(hinst, condition, ...) ok_(hinst, 0, __FILE__, __LINE__, condition, __VA_ARGS__) +#define todo_wine_ok(hinst, condition, ...) ok_(hinst, 1, __FILE__, __LINE__, condition, __VA_ARGS__) + BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) { return TRUE; }
+/* Main test. Anything that doesn't depend on a specific install configuration + * or have undesired side effects should go here. */ +UINT WINAPI main_test(MSIHANDLE hinst) +{ + IUnknown *unk = NULL; + HRESULT hres; + + /* Test for an MTA apartment */ + hres = CoCreateInstance(&CLSID_Picture_Metafile, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + todo_wine_ok(hinst, hres == S_OK, "CoCreateInstance failed with %08x\n", hres); + + if (unk) IUnknown_Release(unk); + + return ERROR_SUCCESS; +} + UINT WINAPI test_retval(MSIHANDLE hinst) { char prop[10]; diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index cc1b536..118530f 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -695,11 +695,13 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "s72\tS255\tI2\n" "InstallExecuteSequence\tAction\n" - "testretval\t\t710\n"; + "maintest\tMAIN_TEST\t700\n" + "testretval\tTEST_RETVAL\t710\n";
static const CHAR ca1_custom_action_dat[] = "Action\tType\tSource\tTarget\n" "s72\ti2\tS64\tS0\n" "CustomAction\tAction\n" + "maintest\t1\tcustom.dll\tmain_test\n" "testretval\t1\tcustom.dll\ttest_retval\n";
static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" @@ -4087,6 +4089,27 @@ static void add_custom_dll(void) MsiCloseHandle(hdb); }
+static INT CALLBACK ok_callback(void *context, UINT message_type, MSIHANDLE record) +{ + if (message_type == INSTALLMESSAGE_USER) + { + char file[200]; + char msg[2000]; + DWORD len; + + len = sizeof(file); + MsiRecordGetStringA(record, 2, file, &len); + len = sizeof(msg); + MsiRecordGetStringA(record, 5, msg, &len); + + todo_wine_if(MsiRecordGetInteger(record, 1)) + ok_(file, MsiRecordGetInteger(record, 3)) (MsiRecordGetInteger(record, 4), "%s", msg); + + return 1; + } + return 0; +} + static void test_customaction1(void) { UINT r; @@ -4096,6 +4119,10 @@ static void test_customaction1(void)
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+ r = MsiInstallProductA(msifile, "MAIN_TEST=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* Test return values */ r = MsiInstallProductA(msifile, "TEST_RETVAL=0"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
@@ -6092,6 +6119,7 @@ START_TEST(install) MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
customdll = load_resource("custom.dll"); + MsiSetExternalUIRecord(ok_callback, INSTALLLOGMODE_USER, NULL, NULL);
if (pSRSetRestorePointA) /* test has side-effects on win2k3 that cause failures in following tests */ test_MsiInstallProduct();
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- I've left off including the fix for now, since I want to fix my existing regressions before causing any new ones...
dlls/msi/tests/custom.dll/main.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/msi/tests/custom.dll/main.c b/dlls/msi/tests/custom.dll/main.c index d174c6e..3730e3a 100644 --- a/dlls/msi/tests/custom.dll/main.c +++ b/dlls/msi/tests/custom.dll/main.c @@ -60,6 +60,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) * or have undesired side effects should go here. */ UINT WINAPI main_test(MSIHANDLE hinst) { + UINT res; IUnknown *unk = NULL; HRESULT hres;
@@ -69,6 +70,10 @@ UINT WINAPI main_test(MSIHANDLE hinst)
if (unk) IUnknown_Release(unk);
+ /* Test MsiGetDatabaseState() */ + res = MsiGetDatabaseState(hinst); + todo_wine_ok(hinst, res == MSIDBSTATE_ERROR, "expected MSIDBSTATE_ERROR, got %u\n", res); + return ERROR_SUCCESS; }
On Thu, 2017-11-23 at 15:35 -0600, Zebediah Figura wrote:
From: Sebastian Lackner sebastian@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Changes from staging version:
- use .cross.res extension for cross-compiled resource
It wouldn't be cross-compiled in a MinGW build.
- use replace_extension() instead of defining a new function
- use phony targets in the tests makefile so that the custom DLL is always
built
- enforce directory name the same way we do for other targets
Overall this looks like a useful thing to have in Wine. Testing custom action dlls using static data would quickly become unmanageable, and there are other places where we could make use of this framework.
On 11/24/2017 03:01 AM, Hans Leidekker wrote:
On Thu, 2017-11-23 at 15:35 -0600, Zebediah Figura wrote:
From: Sebastian Lackner sebastian@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Changes from staging version:
- use .cross.res extension for cross-compiled resource
It wouldn't be cross-compiled in a MinGW build.
Right, in which case it'll just be resource_dlls.res, unless I'm missing something. The staging version used .cross.o, probably just because of a copy-paste error.