[2/3] services: Hold a reference to process in svcctl_ControlService.
Sebastian Lackner
sebastian at fds-team.de
Mon Apr 18 10:08:37 CDT 2016
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
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);
--
2.7.1
More information about the wine-patches
mailing list