From 8f8626feef10ea1277d4201662e1212444b6a8f9 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 10 Aug 2016 08:32:11 +0200 Subject: [PATCH] services: Implement functionality to transfer extra data when sending service control. Signed-off-by: Sebastian Lackner Signed-off-by: Alexandre Julliard --- dlls/advapi32/service.c | 13 +++++++------ programs/services/rpc.c | 10 ++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 273e7c74b67..86bd713db1d 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -401,14 +401,14 @@ static DWORD service_handle_start(service_data *service, const WCHAR *data, DWOR /****************************************************************************** * service_handle_control */ -static DWORD service_handle_control(const service_data *service, DWORD dwControl) +static DWORD service_handle_control(const service_data *service, DWORD control, void *data) { DWORD ret = ERROR_INVALID_SERVICE_CONTROL; - TRACE("%s control %u\n", debugstr_w(service->name), dwControl); + TRACE("%s control %u data %p\n", debugstr_w(service->name), control, data); if (service->handler) - ret = service->handler(dwControl, 0, NULL, service->context); + ret = service->handler(control, 0, data, service->context); return ret; } @@ -494,7 +494,8 @@ static DWORD WINAPI service_control_dispatcher(LPVOID arg) result = service_handle_start(service, (WCHAR *)data, data_size / sizeof(WCHAR)); break; case WINESERV_SENDCONTROL: - result = service_handle_control(service, info.control); + result = service_handle_control(service, info.control, (data_size > info.name_size * sizeof(WCHAR)) ? + &data[info.name_size * sizeof(WCHAR)] : NULL); break; default: ERR("received invalid command %u\n", info.cmd); @@ -589,13 +590,13 @@ static BOOL service_run_main_thread(void) { FIXME("service should be able to delay shutdown\n"); timeout += spi.dwPreshutdownTimeout; - ret = service_handle_control( services[i], SERVICE_CONTROL_PRESHUTDOWN ); + ret = service_handle_control( services[i], SERVICE_CONTROL_PRESHUTDOWN, NULL ); wait_handles[n++] = services[i]->thread; } } else if (res && (st.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN)) { - ret = service_handle_control( services[i], SERVICE_CONTROL_SHUTDOWN ); + ret = service_handle_control( services[i], SERVICE_CONTROL_SHUTDOWN, NULL ); wait_handles[n++] = services[i]->thread; } } diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 54947c67218..17900cc5a62 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -1039,21 +1039,23 @@ BOOL process_send_command(struct process_entry *process, const void *data, DWORD /****************************************************************************** * process_send_control */ -static BOOL process_send_control(struct process_entry *process, const WCHAR *name, DWORD dwControl, DWORD *result) +static BOOL process_send_control(struct process_entry *process, const WCHAR *name, DWORD control, + const BYTE *data, DWORD data_size, DWORD *result) { service_start_info *ssi; DWORD len; BOOL r; /* calculate how much space we need to send the startup info */ - len = (strlenW(name) + 1) * sizeof(WCHAR); + len = (strlenW(name) + 1) * sizeof(WCHAR) + data_size; ssi = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, data[len])); ssi->cmd = WINESERV_SENDCONTROL; - ssi->control = dwControl; + ssi->control = control; ssi->total_size = FIELD_OFFSET(service_start_info, data[len]); ssi->name_size = strlenW(name) + 1; strcpyW((WCHAR *)ssi->data, name); + if (data_size) memcpy(&ssi->data[ssi->name_size * sizeof(WCHAR)], data, data_size); r = process_send_command(process, ssi, ssi->total_size, result); HeapFree( GetProcessHeap(), 0, ssi ); @@ -1185,7 +1187,7 @@ DWORD __cdecl svcctl_ControlService( return ERROR_SERVICE_REQUEST_TIMEOUT; } - process_send_control(process, service->service_entry->name, dwControl, &result); + process_send_control(process, service->service_entry->name, dwControl, NULL, 0, &result); if (lpServiceStatus) {