Hans Leidekker : msi: Properly handle service control events in Start/ StopService.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Dec 2 13:40:21 CST 2014
Module: wine
Branch: master
Commit: 2a8043aa6bb3a128f8f41c8a45c3238ce8873771
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2a8043aa6bb3a128f8f41c8a45c3238ce8873771
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Dec 2 12:41:26 2014 +0100
msi: Properly handle service control events in Start/StopService.
---
dlls/msi/action.c | 33 +++++++++++++++------------------
dlls/msi/tests/action.c | 36 ++++++++++++++++++++++++++++++------
2 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 939e426..1e527da 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -5952,24 +5952,21 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
if (!comp)
return ERROR_SUCCESS;
+ event = MSI_RecordGetInteger( rec, 3 );
+ deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
+
comp->Action = msi_get_component_action( package, comp );
- if (comp->Action != INSTALLSTATE_LOCAL)
+ if (!(comp->Action == INSTALLSTATE_LOCAL && (event & msidbServiceControlEventStart)) &&
+ !(comp->Action == INSTALLSTATE_ABSENT && (event & msidbServiceControlEventUninstallStart)))
{
- TRACE("component not scheduled for installation %s\n", debugstr_w(component));
+ TRACE("not starting %s\n", debugstr_w(name));
+ msi_free( name );
return ERROR_SUCCESS;
}
- deformat_string(package, MSI_RecordGetString(rec, 2), &name);
deformat_string(package, MSI_RecordGetString(rec, 4), &args);
- event = MSI_RecordGetInteger(rec, 3);
wait = MSI_RecordGetInteger(rec, 5);
- if (!(event & msidbServiceControlEventStart))
- {
- r = ERROR_SUCCESS;
- goto done;
- }
-
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
if (!scm)
{
@@ -6159,23 +6156,24 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param )
MSICOMPONENT *comp;
MSIRECORD *uirow;
LPCWSTR component;
- LPWSTR name = NULL, display_name = NULL;
+ WCHAR *name, *display_name = NULL;
DWORD event, len;
SC_HANDLE scm;
- event = MSI_RecordGetInteger( rec, 3 );
- if (!(event & msidbServiceControlEventStop))
- return ERROR_SUCCESS;
-
component = MSI_RecordGetString( rec, 6 );
comp = msi_get_loaded_component( package, component );
if (!comp)
return ERROR_SUCCESS;
+ event = MSI_RecordGetInteger( rec, 3 );
+ deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
+
comp->Action = msi_get_component_action( package, comp );
- if (comp->Action != INSTALLSTATE_ABSENT)
+ if (!(comp->Action == INSTALLSTATE_LOCAL && (event & msidbServiceControlEventStop)) &&
+ !(comp->Action == INSTALLSTATE_ABSENT && (event & msidbServiceControlEventUninstallStop)))
{
- TRACE("component not scheduled for removal %s\n", debugstr_w(component));
+ TRACE("not stopping %s\n", debugstr_w(name));
+ msi_free( name );
return ERROR_SUCCESS;
}
@@ -6195,7 +6193,6 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param )
}
CloseServiceHandle( scm );
- deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
stop_service( name );
done:
diff --git a/dlls/msi/tests/action.c b/dlls/msi/tests/action.c
index bd074a2..60562f1 100644
--- a/dlls/msi/tests/action.c
+++ b/dlls/msi/tests/action.c
@@ -247,7 +247,10 @@ static const char sss_service_control_dat[] =
"ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
"s72\tl255\ti2\tL255\tI2\ts72\n"
"ServiceControl\tServiceControl\n"
- "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
+ "ServiceControl\tSpooler\t1\t\t1\tservice_comp\n"
+ "ServiceControl2\tSpooler\t2\t\t1\tservice_comp\n"
+ "ServiceControl3\tSpooler\t16\t\t1\tservice_comp\n"
+ "ServiceControl4\tSpooler\t32\t\t1\tservice_comp\n";
static const char sss_install_exec_seq_dat[] =
"Action\tCondition\tSequence\n"
@@ -260,11 +263,15 @@ static const char sss_install_exec_seq_dat[] =
"CostFinalize\t\t1000\n"
"InstallValidate\t\t1400\n"
"InstallInitialize\t\t1500\n"
+ "StopServices\t\t4000\n"
"DeleteServices\t\t5000\n"
"MoveFiles\t\t5100\n"
"InstallFiles\t\t5200\n"
"DuplicateFiles\t\t5300\n"
"StartServices\t\t5400\n"
+ "RegisterProduct\t\t5500\n"
+ "PublishFeatures\t\t5600\n"
+ "PublishProduct\t\t5700\n"
"InstallFinalize\t\t6000\n";
static const char sds_install_exec_seq_dat[] =
@@ -5310,7 +5317,7 @@ error:
DeleteFileA(msifile);
}
-static void test_start_services(void)
+static void test_start_stop_services(void)
{
UINT r;
SC_HANDLE scm, service;
@@ -5359,6 +5366,23 @@ static void test_start_services(void)
r = MsiInstallProductA(msifile, NULL);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ if (error == ERROR_SUCCESS)
+ {
+ SERVICE_STATUS status;
+
+ scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ service = OpenServiceA(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
+
+ ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
+ ok(ret, "ControlService failed %u\n", GetLastError());
+
+ CloseServiceHandle(service);
+ CloseServiceHandle(scm);
+ }
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
@@ -5373,9 +5397,6 @@ static void test_start_services(void)
ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
- delete_test_files();
- DeleteFileA(msifile);
-
if (error == ERROR_SUCCESS)
{
SERVICE_STATUS status;
@@ -5389,6 +5410,9 @@ static void test_start_services(void)
CloseServiceHandle(service);
CloseServiceHandle(scm);
}
+
+ delete_test_files();
+ DeleteFileA(msifile);
}
static void test_delete_services(void)
@@ -6869,7 +6893,7 @@ START_TEST(action)
test_write_registry_values();
test_envvar();
test_create_remove_folder();
- test_start_services();
+ test_start_stop_services();
test_delete_services();
test_install_services();
test_self_registration();
More information about the wine-cvs
mailing list