Module: wine Branch: master Commit: 168af6e7501202088cd6105ea798f97e145a06fd URL: http://source.winehq.org/git/wine.git/?a=commit;h=168af6e7501202088cd6105ea7...
Author: Sebastian Lackner sebastian@fds-team.de Date: Mon Apr 18 17:08:37 2016 +0200
services: Hold a reference to process in svcctl_ControlService.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/services/rpc.c | 15 ++++++++++----- programs/services/services.c | 7 +++++++ programs/services/services.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 59bbe7f..babb2b5 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -1086,9 +1086,9 @@ DWORD __cdecl svcctl_ControlService( { DWORD access_required; struct sc_service_handle *service; + struct process_entry *process; DWORD result; BOOL ret; - HANDLE control_mutex;
WINE_TRACE("(%p, %d, %p)\n", hService, dwControl, lpServiceStatus);
@@ -1169,14 +1169,18 @@ DWORD __cdecl svcctl_ControlService( if (dwControl == SERVICE_CONTROL_STOP) service->service_entry->force_shutdown = TRUE;
- control_mutex = service->service_entry->process->control_mutex; + /* Hold a reference to the process while sending the command. */ + process = grab_process(service->service_entry->process); service_unlock(service->service_entry);
- ret = WaitForSingleObject(control_mutex, 30000); + ret = WaitForSingleObject(process->control_mutex, 30000); if (ret != WAIT_OBJECT_0) + { + release_process(process); return ERROR_SERVICE_REQUEST_TIMEOUT; + }
- process_send_control(service->service_entry->process, service->service_entry->name, dwControl, &result); + process_send_control(process, service->service_entry->name, dwControl, &result);
if (lpServiceStatus) { @@ -1191,7 +1195,8 @@ DWORD __cdecl svcctl_ControlService( service_unlock(service->service_entry); }
- ReleaseMutex(control_mutex); + ReleaseMutex(process->control_mutex); + release_process(process); return result; }
diff --git a/programs/services/services.c b/programs/services/services.c index 5be6f5c..234c0ac 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -457,6 +457,13 @@ struct service_entry *scmdatabase_find_service_by_displayname(struct scmdatabase return NULL; }
+struct process_entry *grab_process(struct process_entry *process) +{ + if (process) + InterlockedIncrement(&process->ref_count); + return process; +} + void release_process(struct process_entry *process) { if (InterlockedDecrement(&process->ref_count) == 0) diff --git a/programs/services/services.h b/programs/services/services.h index b8f4774..3d6c486 100644 --- a/programs/services/services.h +++ b/programs/services/services.h @@ -88,6 +88,7 @@ void service_terminate(struct service_entry *service);
/* Process functions */
+struct process_entry *grab_process(struct process_entry *process); void release_process(struct process_entry *process); BOOL process_send_command(struct process_entry *process, const void *data, DWORD size, DWORD *result);