msi [1/3]: Implement the InstallServices action

James Hawkins truiken at gmail.com
Thu Oct 19 17:49:54 CDT 2006


Hi,

Changelog:
* Implement the InstallServices action.

 dlls/msi/action.c        |  102 +++++++++++++++++++++++++++++++++++++++++++---
 dlls/msi/tests/install.c |   10 +----
 2 files changed, 97 insertions(+), 15 deletions(-)

-- 
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index d893af2..e81fcb7 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -34,6 +34,7 @@ #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
 #include "winreg.h"
+#include "winsvc.h"
 #include "wine/debug.h"
 #include "msidefs.h"
 #include "msipriv.h"
@@ -4075,6 +4076,100 @@ static UINT ACTION_PublishComponents(MSI
     return rc;
 }
 
+static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
+{
+    MSIPACKAGE *package = (MSIPACKAGE*)param;
+    MSIRECORD *row;
+    MSIFILE *file;
+    SC_HANDLE hscm, service = NULL;
+    LPCWSTR name, disp, comp, depends, pass;
+    LPCWSTR load_order, serv_name, key;
+    DWORD serv_type, start_type;
+    DWORD err_control;
+
+    static const WCHAR query[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
+         '`','C','o','m','p','o','n','e','n','t','`',' ',
+         'W','H','E','R','E',' ',
+         '`','C','o','m','p','o','n','e','n','t','`',' ',
+         '=','\'','%','s','\'',0};
+
+    hscm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, GENERIC_WRITE);
+    if (!hscm)
+    {
+        ERR("Failed to open the SC Manager!\n");
+        goto done;
+    }
+
+    start_type = MSI_RecordGetInteger(rec, 5);
+    if (start_type == SERVICE_BOOT_START || start_type == SERVICE_SYSTEM_START)
+        goto done;
+
+    depends = MSI_RecordGetString(rec, 8);
+    if (depends && *depends)
+        FIXME("Dependency list unhandled!\n");
+
+    name = MSI_RecordGetString(rec, 2);
+    disp = MSI_RecordGetString(rec, 3);
+    serv_type = MSI_RecordGetInteger(rec, 4);
+    err_control = MSI_RecordGetInteger(rec, 6);
+    load_order = MSI_RecordGetString(rec, 7);
+    serv_name = MSI_RecordGetString(rec, 9);
+    pass = MSI_RecordGetString(rec, 10);
+    comp = MSI_RecordGetString(rec, 12);
+
+    /* fetch the service path */
+    row = MSI_QueryGetRecord(package->db, query, comp);
+    if (!row)
+    {
+        ERR("Control query failed!\n");
+        goto done;
+    }
+
+    key = MSI_RecordGetString(row, 6);
+    msiobj_release(&row->hdr);
+
+    file = get_loaded_file(package, key);
+    if (!file)
+    {
+        ERR("Failed to load the service file\n");
+        goto done;
+    }
+
+    service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type,
+                             start_type, err_control, file->TargetPath,
+                             load_order, NULL, NULL, serv_name, pass);
+    if (!service)
+    {
+        if (GetLastError() != ERROR_SERVICE_EXISTS)
+            ERR("Failed to create service %s: %d\n", debugstr_w(name), GetLastError());
+    }
+
+done:
+    CloseServiceHandle(service);
+    CloseServiceHandle(hscm);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_InstallServices( MSIPACKAGE *package )
+{
+    UINT rc;
+    MSIQUERY * view;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'S','e','r','v','i','c','e','I','n','s','t','a','l','l',0};
+    
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallService, package);
+    msiobj_release(&view->hdr);
+
+    return rc;
+}
+
 static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
                                            LPCSTR action, LPCWSTR table )
 {
@@ -4149,13 +4244,6 @@ static UINT ACTION_SelfUnregModules( MSI
     return msi_unimplemented_action_stub( package, "SelfUnregModules", table );
 }
 
-static UINT ACTION_InstallServices( MSIPACKAGE *package )
-{
-    static const WCHAR table[] = {
-        'S','e','r','v','i','c','e','I','n','s','t','a','l','l',0 };
-    return msi_unimplemented_action_stub( package, "InstallServices", table );
-}
-
 static UINT ACTION_StartServices( MSIPACKAGE *package )
 {
     static const WCHAR table[] = {
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 36d9240..0c43dee 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -622,16 +622,10 @@ static void check_service_is_installed(v
     ok(scm != NULL, "Failed to open the SC Manager\n");
 
     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
-    todo_wine
-    {
-        ok(service != NULL, "Failed to open TestService\n");
-    }
+    ok(service != NULL, "Failed to open TestService\n");
 
     res = DeleteService(service);
-    todo_wine
-    {
-        ok(res, "Failed to delete TestService\n");
-    }
+    ok(res, "Failed to delete TestService\n");
 }
 
 static void test_MsiInstallProduct(void)
-- 
1.4.2.1


More information about the wine-patches mailing list