From 31139640eaf53b8147a4a4f46d7b98c8543de5bf Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 5 Mar 2018 00:31:58 +0100 Subject: [PATCH] [MSI_WINETEST] Sync with Wine Staging 3.3. CORE-14434 --- modules/rostests/winetests/msi/CMakeLists.txt | 9 +- modules/rostests/winetests/msi/action.c | 52 ++++- modules/rostests/winetests/msi/automation.c | 17 +- modules/rostests/winetests/msi/custom.c | 153 ++++++++++++++ modules/rostests/winetests/msi/custom.spec | 4 + modules/rostests/winetests/msi/db.c | 12 +- modules/rostests/winetests/msi/format.c | 8 +- modules/rostests/winetests/msi/install.c | 190 ++++++++++++++++-- modules/rostests/winetests/msi/msi.c | 15 +- .../rostests/winetests/msi/msi_winetest.rc | 2 + modules/rostests/winetests/msi/package.c | 15 +- modules/rostests/winetests/msi/patch.c | 13 +- modules/rostests/winetests/msi/precomp.h | 1 + modules/rostests/winetests/msi/record.c | 6 +- modules/rostests/winetests/msi/source.c | 12 +- modules/rostests/winetests/msi/suminfo.c | 10 +- 16 files changed, 490 insertions(+), 29 deletions(-) create mode 100644 modules/rostests/winetests/msi/custom.c create mode 100644 modules/rostests/winetests/msi/custom.spec create mode 100644 modules/rostests/winetests/msi/msi_winetest.rc diff --git a/modules/rostests/winetests/msi/CMakeLists.txt b/modules/rostests/winetests/msi/CMakeLists.txt index 3a3a03d77fa..23e2f534129 100644 --- a/modules/rostests/winetests/msi/CMakeLists.txt +++ b/modules/rostests/winetests/msi/CMakeLists.txt @@ -3,6 +3,12 @@ add_definitions( -DUSE_WINE_TODOS -D__WINESRC__) +spec2def(custom.dll custom.spec) +add_library(custom SHARED custom.c ${CMAKE_CURRENT_BINARY_DIR}/custom.def) +target_link_libraries(custom uuid) +set_module_type(custom win32dll) +add_importlibs(custom msi ole32 msvcrt kernel32) + list(APPEND SOURCE action.c automation.c @@ -17,9 +23,10 @@ list(APPEND SOURCE suminfo.c precomp.h) -add_executable(msi_winetest ${SOURCE} testlist.c) +add_executable(msi_winetest ${SOURCE} testlist.c msi_winetest.rc) target_link_libraries(msi_winetest uuid) set_module_type(msi_winetest win32cui) add_importlibs(msi_winetest cabinet msi shell32 ole32 oleaut32 user32 advapi32 version msvcrt kernel32) add_pch(msi_winetest precomp.h SOURCE) add_rostests_file(TARGET msi_winetest) +add_dependencies(msi_winetest custom) diff --git a/modules/rostests/winetests/msi/action.c b/modules/rostests/winetests/msi/action.c index 7d8eaa2ebf6..31cc9819b0c 100644 --- a/modules/rostests/winetests/msi/action.c +++ b/modules/rostests/winetests/msi/action.c @@ -19,7 +19,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" static UINT (WINAPI *pMsiQueryComponentStateA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *); @@ -492,7 +506,22 @@ static const char wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" - "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; + "augustus\t\tMSITESTDIR\t0\t\taugustus\n" + "caesar\t\tMSITESTDIR\t1\t\t\n"; + +static const char wrv_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n" + "feature2\t\tFeature2\tFeature2\t2\t1\tTARGETDIR\t1"; + +static const char wrv_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\taugustus\n" + "feature2\tcaesar"; static const char wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" @@ -513,7 +542,8 @@ static const char wrv_registry_dat[] = "regdata12\t2\tSOFTWARE\\Wine\\msitest\tValue8\t#1\taugustus\n" "regdata13\t2\tSOFTWARE\\Wine\\msitest\tValue9\t#x1\taugustus\n" "regdata14\t2\tSOFTWARE\\Wine\\msitest\tValue10\t#x01\taugustus\n" - "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n"; + "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n" + "regdata16\t2\tSOFTWARE\\Wine\\msitest\tValue12\t#1\tcaesar\n"; static const char cf_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" @@ -1738,8 +1768,8 @@ static const msi_table wrv_tables[] = { ADD_TABLE(wrv_component), ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(ci2_feature_comp), + ADD_TABLE(wrv_feature), + ADD_TABLE(wrv_feature_comp), ADD_TABLE(ci2_file), ADD_TABLE(install_exec_seq), ADD_TABLE(rof_media), @@ -4974,7 +5004,7 @@ static void test_write_registry_values(void) goto error; } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); + ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); ok(delete_pf("msitest", FALSE), "Directory not created\n"); if (is_64bit) @@ -5097,6 +5127,15 @@ static void test_write_registry_values(void) ok(size == 1, "got %u\n", size); ok(type == REG_BINARY, "got %u\n", type); + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value12", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(*(DWORD *)buf == 1, "got %u\n", *(DWORD *)buf); + ok(size == 4, "got %u\n", size); + ok(type == REG_DWORD, "got %u\n", type); + RegDeleteValueA(hkey, "Value"); RegDeleteValueA(hkey, "Value1"); RegDeleteValueA(hkey, "Value2"); @@ -5109,6 +5148,7 @@ static void test_write_registry_values(void) RegDeleteValueA(hkey, "Value9"); RegDeleteValueA(hkey, "Value10"); RegDeleteValueA(hkey, "Value11"); + RegDeleteValueA(hkey, "Value12"); RegCloseKey(hkey); RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); diff --git a/modules/rostests/winetests/msi/automation.c b/modules/rostests/winetests/msi/automation.c index 1cb4959bc3f..39d19801225 100644 --- a/modules/rostests/winetests/msi/automation.c +++ b/modules/rostests/winetests/msi/automation.c @@ -19,10 +19,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS -#include "precomp.h" +#include -#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" + +#ifdef __REACTOS__ +#include "ole2.h" +#endif static BOOL is_wow64; diff --git a/modules/rostests/winetests/msi/custom.c b/modules/rostests/winetests/msi/custom.c new file mode 100644 index 00000000000..feb80615191 --- /dev/null +++ b/modules/rostests/winetests/msi/custom.c @@ -0,0 +1,153 @@ +/* + * 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 +#include + +#include +#include +#define COBJMACROS +#include +#include +#include +#include + +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__) + + +/* 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) +{ + UINT res; + 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); + + /* Test MsiGetDatabaseState() */ + res = MsiGetDatabaseState(hinst); + todo_wine_ok(hinst, res == MSIDBSTATE_ERROR, "expected MSIDBSTATE_ERROR, got %u\n", res); + + return ERROR_SUCCESS; +} + +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; +} + +static void append_file(MSIHANDLE hinst, const char *filename, const char *text) +{ + DWORD size; + HANDLE file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(hinst, file != INVALID_HANDLE_VALUE, "CreateFile failed, error %u\n", GetLastError()); + + SetFilePointer(file, 0, NULL, FILE_END); + WriteFile(file, text, strlen(text), &size, NULL); + CloseHandle(file); +} + +UINT WINAPI da_immediate(MSIHANDLE hinst) +{ + char prop[300]; + DWORD len = sizeof(prop); + + MsiGetPropertyA(hinst, "TESTPATH", prop, &len); + + append_file(hinst, prop, "one"); + + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "shouldn't be scheduled\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); + + return ERROR_SUCCESS; +} + +UINT WINAPI da_deferred(MSIHANDLE hinst) +{ + char prop[300]; + DWORD len = sizeof(prop); + LANGID lang; + UINT r; + + /* Test that we were in fact deferred */ + r = MsiGetPropertyA(hinst, "CustomActionData", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "CustomActionData was empty\n"); + + append_file(hinst, prop, "two"); + + /* Test available properties */ + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "ProductCode", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "got %s\n", prop); + + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "UserSID", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "got %s\n", prop); + + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "TESTPATH", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + todo_wine_ok(hinst, !prop[0], "got %s\n", prop); + + /* Test modes */ + ok(hinst, MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "should be scheduled\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); + + lang = MsiGetLanguage(hinst); + ok(hinst, lang != ERROR_INVALID_HANDLE, "MsiGetLanguage failed\n"); + + return ERROR_SUCCESS; +} diff --git a/modules/rostests/winetests/msi/custom.spec b/modules/rostests/winetests/msi/custom.spec new file mode 100644 index 00000000000..bb400fffe9d --- /dev/null +++ b/modules/rostests/winetests/msi/custom.spec @@ -0,0 +1,4 @@ +@ stdcall main_test(long) +@ stdcall test_retval(long) +@ stdcall da_immediate(long) +@ stdcall da_deferred(long) diff --git a/modules/rostests/winetests/msi/db.c b/modules/rostests/winetests/msi/db.c index 15fb93c82ed..3cbb9b3e284 100644 --- a/modules/rostests/winetests/msi/db.c +++ b/modules/rostests/winetests/msi/db.c @@ -18,7 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS + +#include + +#include +#include +#include +#include +#include + +#include "wine/test.h" static const char *msifile = "winetest-db.msi"; static const char *msifile2 = "winetst2-db.msi"; diff --git a/modules/rostests/winetests/msi/format.c b/modules/rostests/winetests/msi/format.c index cc00af063f4..6cb52cf04dc 100644 --- a/modules/rostests/winetests/msi/format.c +++ b/modules/rostests/winetests/msi/format.c @@ -19,7 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include +#include +#include + +#include "wine/test.h" static const char msifile[] = "winetest-format.msi"; diff --git a/modules/rostests/winetests/msi/install.c b/modules/rostests/winetests/msi/install.c index 2e08918b9e4..69095cd8f07 100644 --- a/modules/rostests/winetests/msi/install.c +++ b/modules/rostests/winetests/msi/install.c @@ -18,7 +18,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" static UINT (WINAPI *pMsiQueryComponentStateA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*); @@ -54,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" @@ -674,6 +692,18 @@ 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" + "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" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -1270,12 +1300,12 @@ static const char ft_install_exec_seq_dat[] = "InstallFinalize\t\t1500\n"; static const char da_custom_action_dat[] = - "Action\tType\tSource\tTarget\tISComments\n" - "s72\ti2\tS64\tS0\tS255\n" + "Action\tType\tSource\tTarget\n" + "s72\ti2\tS64\tS0\n" "CustomAction\tAction\n" - "deferred\t1074\tCMDEXE\t/c if exist msitest (exit 0) else (exit 1)\t\n" - "immediate\t50\tCMDEXE\t/c mkdir msitest\t\n" - "cleanup\t50\tCMDEXE\t/c rmdir msitest\t\n"; + "setprop\t51\tdeferred\t[TESTPATH]\n" + "immediate\t1\tcustom.dll\tda_immediate\n" + "deferred\t1025\tcustom.dll\tda_deferred\n"; static const char da_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" @@ -1285,10 +1315,10 @@ static const char da_install_exec_seq_dat[] = "FileCost\t\t300\n" "CostFinalize\t\t400\n" "InstallInitialize\t\t500\n" - "deferred\t\t600\n" - "immediate\t\t700\n" - "InstallFinalize\t\t1100\n" - "cleanup\t\t1200\n"; + "setprop\t\t600\n" + "deferred\t\t700\n" + "immediate\t\t800\n" + "InstallFinalize\t\t1100\n"; typedef struct _msi_table { @@ -1667,6 +1697,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), @@ -2573,6 +2610,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, "TESTDLL"); + 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; @@ -3998,6 +4058,84 @@ 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 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; + + create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table)); + add_custom_dll(); + + 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); + + 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; @@ -5904,23 +6042,45 @@ static void test_feature_tree(void) DeleteFileA( msifile ); } +static void check_file_matches(const char *filename, const char *text) +{ + char buffer[200]; + HANDLE file; + DWORD size; + + file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + ReadFile(file, buffer, sizeof(buffer), &size, NULL); + ok(size == strlen(text) && !memcmp(buffer, text, size), "got %.*s\n", size, buffer); + CloseHandle(file); +} + static void test_deferred_action(void) { + char path[200], file[200], buffer[200]; UINT r; + GetTempPathA(sizeof(path), path); + GetTempFileNameA(path, "da", 0, file); + sprintf(buffer, "TESTPATH=\"%s\"", file); + create_database(msifile, da_tables, sizeof(da_tables) / sizeof(da_tables[0])); + add_custom_dll(); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - r = MsiInstallProductA(msifile, "CMDEXE=\"cmd.exe\""); + r = MsiInstallProductA(msifile, buffer); if (r == ERROR_INSTALL_PACKAGE_REJECTED) { skip("Not enough rights to perform tests\n"); goto error; } -todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +todo_wine + check_file_matches(file, "onetwo"); + + ok(DeleteFileA(file), "Directory not created\n"); + error: DeleteFileA(msifile); } @@ -5971,6 +6131,9 @@ START_TEST(install) lstrcatA(log_file, "\\msitest.log"); 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(); test_MsiSetComponentState(); @@ -5990,6 +6153,7 @@ START_TEST(install) test_adminprops(); test_missingcab(); test_sourcefolder(); + test_customaction1(); test_customaction51(); test_installstate(); test_sourcepath(); @@ -6015,6 +6179,8 @@ START_TEST(install) test_feature_tree(); test_deferred_action(); + DeleteFileA(customdll); + DeleteFileA(log_file); if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) diff --git a/modules/rostests/winetests/msi/msi.c b/modules/rostests/winetests/msi/msi.c index 25d9dad4596..4b545f2d5a9 100644 --- a/modules/rostests/winetests/msi/msi.c +++ b/modules/rostests/winetests/msi/msi.c @@ -18,7 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" static BOOL is_wow64; static const char msifile[] = "winetest.msi"; diff --git a/modules/rostests/winetests/msi/msi_winetest.rc b/modules/rostests/winetests/msi/msi_winetest.rc new file mode 100644 index 00000000000..6aa15fe499b --- /dev/null +++ b/modules/rostests/winetests/msi/msi_winetest.rc @@ -0,0 +1,2 @@ + +CUSTOM.DLL TESTDLL "custom.dll" diff --git a/modules/rostests/winetests/msi/package.c b/modules/rostests/winetests/msi/package.c index f29baa9d259..2022953f9bd 100644 --- a/modules/rostests/winetests/msi/package.c +++ b/modules/rostests/winetests/msi/package.c @@ -19,11 +19,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS #include +#include +#include +#include +#include +#include +#include #include +#include "wine/test.h" + static BOOL is_wow64; static const char msifile[] = "winetest-package.msi"; static const WCHAR msifileW[] = @@ -5644,6 +5652,11 @@ static void test_installprops(void) ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf)); + buf[0] = 0; + size = MAX_PATH; + r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size); + if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf ); + if (pGetSystemInfo && pSHGetFolderPathA) { pGetSystemInfo(&si); diff --git a/modules/rostests/winetests/msi/patch.c b/modules/rostests/winetests/msi/patch.c index bb2276ee58b..b6e990b461e 100644 --- a/modules/rostests/winetests/msi/patch.c +++ b/modules/rostests/winetests/msi/patch.c @@ -18,7 +18,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include + +#include +#include +#include +#include +#include + +#include "wine/test.h" static UINT (WINAPI *pMsiApplyPatchA)( LPCSTR, LPCSTR, INSTALLTYPE, LPCSTR ); static UINT (WINAPI *pMsiGetPatchInfoExA)( LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, diff --git a/modules/rostests/winetests/msi/precomp.h b/modules/rostests/winetests/msi/precomp.h index 67839b12f0b..f5ae3702201 100644 --- a/modules/rostests/winetests/msi/precomp.h +++ b/modules/rostests/winetests/msi/precomp.h @@ -1,3 +1,4 @@ + #ifndef _MSI_WINETEST_PRECOMP_H_ #define _MSI_WINETEST_PRECOMP_H_ diff --git a/modules/rostests/winetests/msi/record.c b/modules/rostests/winetests/msi/record.c index a37e408c981..777f1f78ed0 100644 --- a/modules/rostests/winetests/msi/record.c +++ b/modules/rostests/winetests/msi/record.c @@ -18,7 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "wine/test.h" static const char *msifile = "winetest-record.msi"; static const WCHAR msifileW[] = diff --git a/modules/rostests/winetests/msi/source.c b/modules/rostests/winetests/msi/source.c index daf2979bbb3..a03cf557aaf 100644 --- a/modules/rostests/winetests/msi/source.c +++ b/modules/rostests/winetests/msi/source.c @@ -18,9 +18,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#include + +#include +#include +#include +#include +#include #include +#include + +#include "wine/test.h" static BOOL is_wow64; diff --git a/modules/rostests/winetests/msi/suminfo.c b/modules/rostests/winetests/msi/suminfo.c index 40fcef4488d..8c2e292ab8f 100644 --- a/modules/rostests/winetests/msi/suminfo.c +++ b/modules/rostests/winetests/msi/suminfo.c @@ -18,7 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS + +#include +#include +#include +#include +#include + +#include "wine/test.h" /* * The following are defined in Windows SDK's msidefs.h -- 2.17.1