https://git.reactos.org/?p=reactos.git;a=commitdiff;h=31139640eaf53b8147a4a…
commit 31139640eaf53b8147a4a4f46d7b98c8543de5bf
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Mar 5 00:31:58 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)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