Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
1c5affa2
Commit
1c5affa2
authored
Aug 31, 2016
by
Sebastian Lackner
Committed by
Alexandre Julliard
Aug 31, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32: Unify service startup and control handling.
Signed-off-by:
Sebastian Lackner
<
sebastian@fds-team.de
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
328fbb68
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
52 additions
and
60 deletions
+52
-60
service.c
dlls/advapi32/service.c
+32
-33
svcctl.idl
include/wine/svcctl.idl
+3
-6
rpc.c
programs/services/rpc.c
+4
-4
services.c
programs/services/services.c
+11
-16
services.h
programs/services/services.h
+2
-1
No files found.
dlls/advapi32/service.c
View file @
1c5affa2
...
...
@@ -379,9 +379,9 @@ static DWORD WINAPI service_thread(LPVOID arg)
/******************************************************************************
* service_handle_start
*/
static
DWORD
service_handle_start
(
service_data
*
service
,
const
WCHAR
*
data
,
DWORD
count
)
static
DWORD
service_handle_start
(
service_data
*
service
,
const
void
*
data
,
DWORD
data_size
)
{
TRACE
(
"%s argsize %u
\n
"
,
debugstr_w
(
service
->
name
),
count
);
DWORD
count
=
data_size
/
sizeof
(
WCHAR
);
if
(
service
->
thread
)
{
...
...
@@ -390,8 +390,11 @@ static DWORD service_handle_start(service_data *service, const WCHAR *data, DWOR
}
heap_free
(
service
->
args
);
service
->
args
=
heap_alloc
(
count
*
sizeof
(
WCHAR
));
memcpy
(
service
->
args
,
data
,
count
*
sizeof
(
WCHAR
)
);
service
->
args
=
heap_alloc
((
count
+
2
)
*
sizeof
(
WCHAR
));
if
(
count
)
memcpy
(
service
->
args
,
data
,
count
*
sizeof
(
WCHAR
)
);
service
->
args
[
count
++
]
=
0
;
service
->
args
[
count
++
]
=
0
;
service
->
thread
=
CreateThread
(
NULL
,
0
,
service_thread
,
service
,
0
,
NULL
);
SetEvent
(
service_event
);
/* notify the main loop */
...
...
@@ -401,14 +404,16 @@ 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
control
,
void
*
data
)
static
DWORD
service_handle_control
(
service_data
*
service
,
DWORD
control
,
const
void
*
data
,
DWORD
data_size
)
{
DWORD
ret
=
ERROR_INVALID_SERVICE_CONTROL
;
TRACE
(
"%s control %u data %p
\n
"
,
debugstr_w
(
service
->
name
),
control
,
data
);
TRACE
(
"%s control %u data %p
data_size %u
\n
"
,
debugstr_w
(
service
->
name
),
control
,
data
,
data_size
);
if
(
service
->
handler
)
ret
=
service
->
handler
(
control
,
0
,
data
,
service
->
context
);
if
(
control
==
SERVICE_CONTROL_START
)
ret
=
service_handle_start
(
service
,
data
,
data_size
);
else
if
(
service
->
handler
)
ret
=
service
->
handler
(
control
,
0
,
(
void
*
)
data
,
service
->
context
);
return
ret
;
}
...
...
@@ -472,39 +477,33 @@ static DWORD WINAPI service_control_dispatcher(LPVOID arg)
goto
done
;
}
if
(
info
.
magic
!=
SERVICE_PROTOCOL_MAGIC
)
{
ERR
(
"received invalid request for service %s
\n
"
,
debugstr_w
(
name
)
);
result
=
ERROR_INVALID_PARAMETER
;
goto
done
;
}
/* find the service */
if
(
!
(
service
=
find_service_by_name
(
name
)))
{
FIXME
(
"got request
%u for unknown service %s
\n
"
,
info
.
cmd
,
debugstr_w
(
name
)
);
FIXME
(
"got request
for unknown service %s
\n
"
,
debugstr_w
(
name
)
);
result
=
ERROR_INVALID_PARAMETER
;
goto
done
;
}
TRACE
(
"got request %u for service %s
\n
"
,
info
.
cmd
,
debugstr_w
(
name
)
);
/* handle the request */
switch
(
info
.
cmd
)
if
(
!
service
->
handle
)
{
case
WINESERV_STARTINFO
:
if
(
!
service
->
handle
)
{
if
(
!
(
service
->
handle
=
OpenServiceW
(
disp
->
manager
,
name
,
SERVICE_SET_STATUS
))
||
!
(
service
->
full_access_handle
=
OpenServiceW
(
disp
->
manager
,
name
,
GENERIC_READ
|
GENERIC_WRITE
)))
FIXME
(
"failed to open service %s
\n
"
,
debugstr_w
(
name
)
);
}
result
=
service_handle_start
(
service
,
(
WCHAR
*
)
data
,
data_size
/
sizeof
(
WCHAR
));
break
;
case
WINESERV_SENDCONTROL
:
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
);
result
=
ERROR_INVALID_PARAMETER
;
break
;
if
(
!
(
service
->
handle
=
OpenServiceW
(
disp
->
manager
,
name
,
SERVICE_SET_STATUS
))
||
!
(
service
->
full_access_handle
=
OpenServiceW
(
disp
->
manager
,
name
,
GENERIC_READ
|
GENERIC_WRITE
)))
FIXME
(
"failed to open service %s
\n
"
,
debugstr_w
(
name
)
);
}
data_size
-=
info
.
name_size
*
sizeof
(
WCHAR
);
result
=
service_handle_control
(
service
,
info
.
control
,
data_size
?
&
data
[
info
.
name_size
*
sizeof
(
WCHAR
)]
:
NULL
,
data_size
);
done:
LeaveCriticalSection
(
&
service_cs
);
WriteFile
(
disp
->
pipe
,
&
result
,
sizeof
(
result
),
&
count
,
NULL
);
...
...
@@ -592,13 +591,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
,
NULL
);
ret
=
service_handle_control
(
services
[
i
],
SERVICE_CONTROL_PRESHUTDOWN
,
NULL
,
0
);
wait_handles
[
n
++
]
=
services
[
i
]
->
thread
;
}
}
else
if
(
res
&&
(
st
.
dwControlsAccepted
&
SERVICE_ACCEPT_SHUTDOWN
))
{
ret
=
service_handle_control
(
services
[
i
],
SERVICE_CONTROL_SHUTDOWN
,
NULL
);
ret
=
service_handle_control
(
services
[
i
],
SERVICE_CONTROL_SHUTDOWN
,
NULL
,
0
);
wait_handles
[
n
++
]
=
services
[
i
]
->
thread
;
}
}
...
...
include/wine/svcctl.idl
View file @
1c5affa2
...
...
@@ -34,15 +34,12 @@ cpp_quote("#define SVCCTL_ENDPOINTA \"\\\\pipe\\\\svcctl\"")
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
*/
enum
service_pipe_command
{
WINESERV_STARTINFO
=
1
,
WINESERV_SENDCONTROL
=
2
}
;
cpp_quote
(
"#define SERVICE_PROTOCOL_MAGIC 0x57494e45"
)
cpp_quote
(
"#define SERVICE_CONTROL_START 0"
)
typedef
struct
service_start_info_t
{
enum
service_pipe_command
cmd
; /* request code
*/
DWORD
magic
; /* protocol magic
*/
DWORD
total_size
; /* total request size */
DWORD
name_size
; /* size of name in data buffer */
DWORD
control
; /* control code */
...
...
programs/services/rpc.c
View file @
1c5affa2
...
...
@@ -979,7 +979,7 @@ static BOOL service_accepts_control(const struct service_entry *service, DWORD d
/******************************************************************************
* process_send_command
*/
BOOL
process_send_command
(
struct
process_entry
*
process
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
)
static
BOOL
process_send_command
(
struct
process_entry
*
process
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
)
{
OVERLAPPED
overlapped
;
DWORD
count
,
ret
;
...
...
@@ -1030,8 +1030,8 @@ 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
control
,
const
BYTE
*
data
,
DWORD
data_size
,
DWORD
*
result
)
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
;
...
...
@@ -1041,7 +1041,7 @@ static BOOL process_send_control(struct process_entry *process, const WCHAR *nam
len
=
(
strlenW
(
name
)
+
1
)
*
sizeof
(
WCHAR
)
+
data_size
;
ssi
=
HeapAlloc
(
GetProcessHeap
(),
0
,
FIELD_OFFSET
(
service_start_info
,
data
[
len
]));
ssi
->
cmd
=
WINESERV_SENDCONTROL
;
ssi
->
magic
=
SERVICE_PROTOCOL_MAGIC
;
ssi
->
control
=
control
;
ssi
->
total_size
=
FIELD_OFFSET
(
service_start_info
,
data
[
len
]);
ssi
->
name_size
=
strlenW
(
name
)
+
1
;
...
...
programs/services/services.c
View file @
1c5affa2
...
...
@@ -844,8 +844,7 @@ static DWORD process_send_start_message(struct process_entry *process, const WCH
{
OVERLAPPED
overlapped
;
DWORD
i
,
len
,
result
;
service_start_info
*
ssi
;
LPWSTR
p
;
WCHAR
*
str
,
*
p
;
WINE_TRACE
(
"%p %s %p %d
\n
"
,
process
,
wine_dbgstr_w
(
name
),
argv
,
argc
);
...
...
@@ -872,32 +871,28 @@ static DWORD process_send_start_message(struct process_entry *process, const WCH
}
}
/* calculate how much space do we need to send the startup info */
len
=
strlenW
(
name
)
+
1
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
for
(
i
=
0
;
i
<
argc
;
i
++
)
len
+=
strlenW
(
argv
[
i
])
+
1
;
len
=
(
len
+
1
)
*
sizeof
(
WCHAR
);
ssi
=
HeapAlloc
(
GetProcessHeap
(),
0
,
FIELD_OFFSET
(
service_start_info
,
data
[
len
]));
ssi
->
cmd
=
WINESERV_STARTINFO
;
ssi
->
control
=
0
;
ssi
->
total_size
=
FIELD_OFFSET
(
service_start_info
,
data
[
len
]);
ssi
->
name_size
=
strlenW
(
name
)
+
1
;
strcpyW
((
WCHAR
*
)
ssi
->
data
,
name
);
if
(
!
(
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
)))
return
ERROR_NOT_ENOUGH_SERVER_MEMORY
;
/* copy service args into a single buffer*/
p
=
(
WCHAR
*
)
&
ssi
->
data
[
ssi
->
name_size
*
sizeof
(
WCHAR
)];
for
(
i
=
0
;
i
<
argc
;
i
++
)
p
=
str
;
strcpyW
(
p
,
name
);
p
+=
strlenW
(
name
)
+
1
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
strcpyW
(
p
,
argv
[
i
]);
p
+=
strlenW
(
p
)
+
1
;
}
*
p
=
0
;
*
p
=
0
;
if
(
!
process_send_co
mmand
(
process
,
ssi
,
ssi
->
total_size
,
&
result
))
if
(
!
process_send_co
ntrol
(
process
,
name
,
SERVICE_CONTROL_START
,
(
const
BYTE
*
)
str
,
len
,
&
result
))
result
=
ERROR_SERVICE_REQUEST_TIMEOUT
;
HeapFree
(
GetProcessHeap
(),
0
,
s
si
);
HeapFree
(
GetProcessHeap
(),
0
,
s
tr
);
return
result
;
}
...
...
programs/services/services.h
View file @
1c5affa2
...
...
@@ -95,7 +95,8 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
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
);
BOOL
process_send_control
(
struct
process_entry
*
process
,
const
WCHAR
*
name
,
DWORD
control
,
const
BYTE
*
data
,
DWORD
data_size
,
DWORD
*
result
);
void
process_terminate
(
struct
process_entry
*
process
);
extern
DWORD
service_pipe_timeout
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment