Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- programs/services/services.c | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/programs/services/services.c b/programs/services/services.c index 2edc02d300c..08b7488473b 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -1190,12 +1190,49 @@ static DWORD process_send_start_message(struct process_entry *process, BOOL shar return result; }
+static DWORD start_service_deps(struct service_entry *service) +{ + struct service_entry *entry; + LPWSTR name; + DWORD err; + + if (!service->dependOnServices) + return ERROR_SUCCESS; + + for (name = service->dependOnServices; *name; name += lstrlenW(name) + 1) + { + entry = scmdatabase_find_service(service->db, name); + if (!entry) + { + WINE_ERR("Service %s depends on %s which doesn't exist\n", debugstr_w(service->name), debugstr_w(name)); + return ERROR_SERVICE_DEPENDENCY_DELETED; + } + + err = service_start(entry, 0, NULL); + if (err != ERROR_SUCCESS && err != ERROR_SERVICE_ALREADY_RUNNING) + { + WINE_FIXME("Dependent on service %s failed to start: %lu\n", + wine_dbgstr_w(entry->name), err); + return ERROR_SERVICE_DEPENDENCY_FAIL; + } + } + + return ERROR_SUCCESS; +} + DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *service_argv) { struct process_entry *process = NULL; BOOL shared_process; DWORD err;
+ err = start_service_deps(service); + if (err != ERROR_SUCCESS) + { + WINE_TRACE("returning %lu\n", err); + return err; + } + err = service_start_process(service, &process, &shared_process); if (err == ERROR_SUCCESS) { @@ -1221,7 +1258,7 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR * release_process(process); }
- WINE_TRACE("returning %ld\n", err); + WINE_TRACE("returning %lu\n", err); return err; }
Hello,
is there anything that could be improved in this patch to make it acceptable?
Dmitry Timoshkov dmitry@baikal.ru writes:
Hello,
is there anything that could be improved in this patch to make it acceptable?
It needs a mechanism to avoid dependency loops. Possibly trying to start the parent service process first would work.
Alexandre Julliard julliard@winehq.org wrote:
is there anything that could be improved in this patch to make it acceptable?
It needs a mechanism to avoid dependency loops. Possibly trying to start the parent service process first would work.
I'm not sure what you mean by the parent service. The situation that I observe here is that the service with the missing dependency gets started by services.exe and that service is crashing because it apparently doesn't check for missing functionality. An attempt to start such a service under Windows with 'sc start' fails with ERROR_SERVICE_DEPENDENCY_DELETED error.
Dmitry Timoshkov dmitry@baikal.ru writes:
Alexandre Julliard julliard@winehq.org wrote:
is there anything that could be improved in this patch to make it acceptable?
It needs a mechanism to avoid dependency loops. Possibly trying to start the parent service process first would work.
I'm not sure what you mean by the parent service. The situation that I observe here is that the service with the missing dependency gets started by services.exe and that service is crashing because it apparently doesn't check for missing functionality. An attempt to start such a service under Windows with 'sc start' fails with ERROR_SERVICE_DEPENDENCY_DELETED error.
I mean the head of the dependency chain. If service 'foo' depends on 'bar' and 'bar' depends on 'foo' (possible indirectly), your code is going to recurse forever.