Commit 33914a1b authored by Alexandre Julliard's avatar Alexandre Julliard

services: Send the service name in the control requests.

Only start a single dispatcher thread for all services.
parent cd550bf6
......@@ -32,15 +32,20 @@ cpp_quote("#define SVCCTL_ENDPOINT {'\\\\','p','i','p','e','\\\\','s','v','c','c
cpp_quote("#define SVCCTL_STARTED_EVENT {'_','_','w','i','n','e','_','S','v','c','c','t','l','S','t','a','r','t','e','d',0}")
/* Service startup protocol over control pipe - not compatible with Windows */
cpp_quote("typedef struct service_start_info_t")
cpp_quote("{")
cpp_quote(" DWORD cmd;")
cpp_quote(" DWORD size;")
cpp_quote(" WCHAR str[1];")
cpp_quote("} service_start_info;")
cpp_quote("#define WINESERV_STARTINFO 1")
cpp_quote("#define WINESERV_SENDCONTROL 2")
enum service_pipe_command
{
WINESERV_STARTINFO = 1,
WINESERV_SENDCONTROL = 2
};
typedef struct service_start_info_t
{
enum service_pipe_command cmd; /* request code */
DWORD total_size; /* total request size */
DWORD name_size; /* size of name in data buffer */
DWORD control; /* control code */
WCHAR data[1];
} service_start_info;
[
uuid(367abb81-9844-35f1-ad32-98f038001003),
......
......@@ -708,15 +708,24 @@ static BOOL service_accepts_control(const struct service_entry *service, DWORD d
/******************************************************************************
* service_send_control
*/
static BOOL service_send_control(HANDLE pipe, DWORD dwControl, DWORD *result)
static BOOL service_send_control(struct service_entry *service, HANDLE pipe, DWORD dwControl, DWORD *result)
{
DWORD cmd[2], count = 0;
service_start_info *ssi;
DWORD len, count = 0;
BOOL r;
cmd[0] = WINESERV_SENDCONTROL;
cmd[1] = dwControl;
r = WriteFile(pipe, cmd, sizeof cmd, &count, NULL);
if (!r || count != sizeof cmd)
/* calculate how much space we need to send the startup info */
len = strlenW(service->name) + 1;
ssi = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, data[len]));
ssi->cmd = WINESERV_SENDCONTROL;
ssi->control = dwControl;
ssi->total_size = FIELD_OFFSET(service_start_info, data[len]);
ssi->name_size = strlenW(service->name) + 1;
strcpyW( ssi->data, service->name );
r = WriteFile(pipe, ssi, ssi->total_size, &count, NULL);
if (!r || count != ssi->total_size)
{
WINE_ERR("service protocol error - failed to write pipe!\n");
return r;
......@@ -837,7 +846,7 @@ DWORD svcctl_ControlService(
{
DWORD result = ERROR_SUCCESS;
ret = service_send_control(control_pipe, dwControl, &result);
ret = service_send_control(service->service_entry, control_pipe, dwControl, &result);
if (dwControl == SERVICE_CONTROL_STOP)
{
......
......@@ -621,17 +621,17 @@ static DWORD service_wait_for_startup(struct service_entry *service_entry, HANDL
/******************************************************************************
* service_send_start_message
*/
static BOOL service_send_start_message(HANDLE pipe, LPCWSTR *argv, DWORD argc)
static BOOL service_send_start_message(struct service_entry *service, LPCWSTR *argv, DWORD argc)
{
DWORD i, len, count, result;
service_start_info *ssi;
LPWSTR p;
BOOL r;
WINE_TRACE("%p %p %d\n", pipe, argv, argc);
WINE_TRACE("%s %p %d\n", wine_dbgstr_w(service->name), argv, argc);
/* FIXME: this can block so should be done in another thread */
r = ConnectNamedPipe(pipe, NULL);
r = ConnectNamedPipe(service->control_pipe, NULL);
if (!r && GetLastError() != ERROR_PIPE_CONNECTED)
{
WINE_ERR("pipe connect failed\n");
......@@ -639,16 +639,20 @@ static BOOL service_send_start_message(HANDLE pipe, LPCWSTR *argv, DWORD argc)
}
/* calculate how much space do we need to send the startup info */
len = 1;
len = strlenW(service->name) + 1;
for (i=0; i<argc; i++)
len += strlenW(argv[i])+1;
len++;
ssi = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, str[len]));
ssi = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, data[len]));
ssi->cmd = WINESERV_STARTINFO;
ssi->size = len;
ssi->control = 0;
ssi->total_size = FIELD_OFFSET(service_start_info, data[len]);
ssi->name_size = strlenW(service->name) + 1;
strcpyW( ssi->data, service->name );
/* copy service args into a single buffer*/
p = &ssi->str[0];
p = &ssi->data[ssi->name_size];
for (i=0; i<argc; i++)
{
strcpyW(p, argv[i]);
......@@ -656,10 +660,10 @@ static BOOL service_send_start_message(HANDLE pipe, LPCWSTR *argv, DWORD argc)
}
*p=0;
r = WriteFile(pipe, ssi, FIELD_OFFSET(service_start_info, str[len]), &count, NULL);
r = WriteFile(service->control_pipe, ssi, ssi->total_size, &count, NULL);
if (r)
{
r = ReadFile(pipe, &result, sizeof result, &count, NULL);
r = ReadFile(service->control_pipe, &result, sizeof result, &count, NULL);
if (r && result)
{
SetLastError(result);
......@@ -709,8 +713,7 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
if (err == ERROR_SUCCESS)
{
if (!service_send_start_message(service->control_pipe,
service_argv, service_argc))
if (!service_send_start_message(service, service_argv, service_argc))
err = ERROR_SERVICE_REQUEST_TIMEOUT;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment