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>
This commit is contained in:
parent
7a200887bb
commit
8f8626feef
|
@ -401,14 +401,14 @@ static DWORD service_handle_start(service_data *service, const WCHAR *data, DWOR
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* service_handle_control
|
* 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;
|
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)
|
if (service->handler)
|
||||||
ret = service->handler(dwControl, 0, NULL, service->context);
|
ret = service->handler(control, 0, data, service->context);
|
||||||
return ret;
|
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));
|
result = service_handle_start(service, (WCHAR *)data, data_size / sizeof(WCHAR));
|
||||||
break;
|
break;
|
||||||
case WINESERV_SENDCONTROL:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR("received invalid command %u\n", info.cmd);
|
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");
|
FIXME("service should be able to delay shutdown\n");
|
||||||
timeout += spi.dwPreshutdownTimeout;
|
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;
|
wait_handles[n++] = services[i]->thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (res && (st.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN))
|
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;
|
wait_handles[n++] = services[i]->thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1039,21 +1039,23 @@ BOOL process_send_command(struct process_entry *process, const void *data, DWORD
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* process_send_control
|
* 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;
|
service_start_info *ssi;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
BOOL r;
|
BOOL r;
|
||||||
|
|
||||||
/* calculate how much space we need to send the startup info */
|
/* 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 = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, data[len]));
|
||||||
ssi->cmd = WINESERV_SENDCONTROL;
|
ssi->cmd = WINESERV_SENDCONTROL;
|
||||||
ssi->control = dwControl;
|
ssi->control = control;
|
||||||
ssi->total_size = FIELD_OFFSET(service_start_info, data[len]);
|
ssi->total_size = FIELD_OFFSET(service_start_info, data[len]);
|
||||||
ssi->name_size = strlenW(name) + 1;
|
ssi->name_size = strlenW(name) + 1;
|
||||||
strcpyW((WCHAR *)ssi->data, name);
|
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);
|
r = process_send_command(process, ssi, ssi->total_size, result);
|
||||||
HeapFree( GetProcessHeap(), 0, ssi );
|
HeapFree( GetProcessHeap(), 0, ssi );
|
||||||
|
@ -1185,7 +1187,7 @@ DWORD __cdecl svcctl_ControlService(
|
||||||
return ERROR_SERVICE_REQUEST_TIMEOUT;
|
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)
|
if (lpServiceStatus)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue