https://git.reactos.org/?p=reactos.git;a=commitdiff;h=31139640eaf53b8147a4a4...
commit 31139640eaf53b8147a4a4f46d7b98c8543de5bf Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Mon Mar 5 00:31:58 2018 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Mon Mar 5 00:31:58 2018 +0100
[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 +- modules/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(-)
diff --git a/modules/rostests/winetests/msi/CMakeLists.txt b/modules/rostests/winetests/msi/CMakeLists.txt index 3a3a03d77f..23e2f53412 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 7d8eaa2ebf..31cc9819b0 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 <stdio.h> +#include <stdlib.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <srrestoreptapi.h> +#include <wtypes.h> +#include <shellapi.h> +#include <winsvc.h> + +#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 1cb4959bc3..39d1980122 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 <stdio.h>
-#include <ole2.h> +#include <initguid.h> +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <oaidl.h> + +#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 0000000000..feb8061519 --- /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 <stdarg.h> +#include <stdio.h> + +#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__) + + +/* 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 0000000000..bb400fffe9 --- /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 15fb93c82e..3cbb9b3e28 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 <stdio.h> + +#include <windows.h> +#include <objidl.h> +#include <msi.h> +#include <msidefs.h> +#include <msiquery.h> + +#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 cc00af063f..6cb52cf04d 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 <stdio.h> +#include <windows.h> +#include <shlwapi.h> +#include <msi.h> +#include <msiquery.h> + +#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 2e08918b9e..69095cd8f0 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 <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <objidl.h> +#include <srrestoreptapi.h> +#include <shlobj.h> +#include <winsvc.h> +#include <shellapi.h> + +#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 25d9dad459..4b545f2d5a 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 <stdio.h> +#include <windows.h> +#include <msi.h> +#include <msiquery.h> +#include <msidefs.h> +#include <sddl.h> +#include <fci.h> +#include <shellapi.h> +#include <objidl.h> + +#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 0000000000..6aa15fe499 --- /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 f29baa9d25..2022953f9b 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 <assert.h> +#include <stdio.h> +#include <windows.h> +#include <msidefs.h> +#include <msi.h> +#include <msiquery.h> +#include <srrestoreptapi.h> #include <shlobj.h>
+#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 bb2276ee58..b6e990b461 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 <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <wtypes.h> + +#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 67839b12f0..f5ae370220 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 a37e408c98..777f1f78ed 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 <windows.h> +#include <msi.h> +#include <msiquery.h> + +#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 daf2979bbb..a03cf557aa 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 <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <sddl.h> #include <secext.h> +#include <objbase.h> + +#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 40fcef4488..8c2e292ab8 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 <stdio.h> +#include <windows.h> +#include <msi.h> +#include <msiquery.h> +#include <objidl.h> + +#include "wine/test.h"
/* * The following are defined in Windows SDK's msidefs.h