From ed122dd7855e8226e5757c98dee9ccd8fb47257b Mon Sep 17 00:00:00 2001
From: Roman Dadkov <romand@etersoft.ru>
Date: Mon, 7 Nov 2011 23:08:26 +0400
Subject: [PATCH] msi: Office installed (eterbug #7630).

---
 dlls/msi/action.c |   47 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index d895b11..6bc4fff 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -864,11 +864,6 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
     return ERROR_SUCCESS;
 }
 
-/*
- * Also we cannot enable/disable components either, so for now I am just going 
- * to do all the directories for all the components.
- */
-
 static UINT ACTION_CreateFolders(MSIPACKAGE *package)
 {
     static const WCHAR query[] = {
@@ -2685,12 +2680,6 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
-    if (package->script->CurrentlyScripting)
-    {
-        msi_schedule_action(package, INSTALL_SCRIPT, szWriteRegistryValues);
-        return 0;
-    }
-
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -5660,8 +5649,10 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
     SC_HANDLE scm = NULL, service = NULL;
     LPCWSTR component, *vector = NULL;
     LPWSTR name, args, display_name = NULL;
-    DWORD event, numargs, len;
+    DWORD event, numargs, len, wait, dummy;
     UINT r = ERROR_FUNCTION_FAILED;
+    SERVICE_STATUS_PROCESS status;
+    ULONGLONG start_time;
 
     component = MSI_RecordGetString(rec, 6);
     comp = msi_get_loaded_component(package, component);
@@ -5678,6 +5669,7 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
     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))
     {
@@ -5700,7 +5692,7 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
             GetServiceDisplayNameW( scm, name, display_name, &len );
     }
 
-    service = OpenServiceW(scm, name, SERVICE_START);
+    service = OpenServiceW(scm, name, SERVICE_START|SERVICE_QUERY_STATUS);
     if (!service)
     {
         ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
@@ -5717,6 +5709,33 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
     }
 
     r = ERROR_SUCCESS;
+    if (wait)
+    {
+        /* wait for at most 30 seconds for the service to be up and running */
+        if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO,
+            (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy))
+        {
+            TRACE("failed to query service status (%u)\n", GetLastError());
+            goto done;
+        }
+        start_time = GetTickCount64();
+        while (status.dwCurrentState == SERVICE_START_PENDING)
+        {
+            if (GetTickCount64() - start_time > 30000) break;
+            Sleep(1000);
+            if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO,
+                (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy))
+            {
+                TRACE("failed to query service status (%u)\n", GetLastError());
+                goto done;
+            }
+        }
+        if (status.dwCurrentState != SERVICE_RUNNING)
+        {
+            WARN("service failed to start %u\n", status.dwCurrentState);
+            r = ERROR_FUNCTION_FAILED;
+        }
+    }
 
 done:
     uirow = MSI_CreateRecord( 2 );
@@ -6597,7 +6616,6 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
     HKEY env = NULL;
     MSICOMPONENT *comp;
     MSIRECORD *uirow;
-    static const WCHAR empty[] = {0};
     int action = 0;
 
     component = MSI_RecordGetString(rec, 4);
@@ -6613,7 +6631,6 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
     }
     name = MSI_RecordGetString(rec, 2);
     value = MSI_RecordGetString(rec, 3);
-    if (!value) value = empty;
 
     TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
 
-- 
1.7.6.4
