Module: wine Branch: master Commit: 8f8626feef10ea1277d4201662e1212444b6a8f9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8f8626feef10ea1277d4201662...
Author: Sebastian Lackner sebastian@fds-team.de Date: Wed Aug 10 08:32:11 2016 +0200
services: Implement functionality to transfer extra data when sending service control.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 273e7c7..86bd713 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 54947c6..17900cc 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) {