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
7fc3f72d
Commit
7fc3f72d
authored
Mar 03, 2016
by
Sebastian Lackner
Committed by
Alexandre Julliard
Mar 03, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Move process related fields into a separate struct.
Signed-off-by:
Sebastian Lackner
<
sebastian@fds-team.de
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
00b1184f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
92 additions
and
56 deletions
+92
-56
rpc.c
programs/services/rpc.c
+14
-14
services.c
programs/services/services.c
+64
-36
services.h
programs/services/services.h
+14
-6
No files found.
programs/services/rpc.c
View file @
7fc3f72d
...
...
@@ -773,8 +773,8 @@ DWORD __cdecl svcctl_SetServiceStatus(
if
(
lpServiceStatus
->
dwCurrentState
==
SERVICE_STOPPED
)
run_after_timeout
(
service_terminate
,
service
->
service_entry
,
service_kill_timeout
);
else
if
(
service
->
service_entry
->
status_changed_event
)
SetEvent
(
service
->
service_entry
->
status_changed_event
);
else
if
(
service
->
service_entry
->
process
->
status_changed_event
)
SetEvent
(
service
->
service_entry
->
process
->
status_changed_event
);
return
ERROR_SUCCESS
;
}
...
...
@@ -984,26 +984,26 @@ static BOOL service_accepts_control(const struct service_entry *service, DWORD d
}
/******************************************************************************
*
service
_send_command
*
process
_send_command
*/
BOOL
service_send_command
(
struct
service_entry
*
service
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
)
BOOL
process_send_command
(
struct
process_entry
*
process
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
)
{
OVERLAPPED
overlapped
;
DWORD
count
,
ret
;
BOOL
r
;
overlapped
.
hEvent
=
service
->
overlapped_event
;
r
=
WriteFile
(
service
->
control_pipe
,
data
,
size
,
&
count
,
&
overlapped
);
overlapped
.
hEvent
=
process
->
overlapped_event
;
r
=
WriteFile
(
process
->
control_pipe
,
data
,
size
,
&
count
,
&
overlapped
);
if
(
!
r
&&
GetLastError
()
==
ERROR_IO_PENDING
)
{
ret
=
WaitForSingleObject
(
service
->
overlapped_event
,
service_pipe_timeout
);
ret
=
WaitForSingleObject
(
process
->
overlapped_event
,
service_pipe_timeout
);
if
(
ret
==
WAIT_TIMEOUT
)
{
WINE_ERR
(
"sending command timed out
\n
"
);
*
result
=
ERROR_SERVICE_REQUEST_TIMEOUT
;
return
FALSE
;
}
r
=
GetOverlappedResult
(
service
->
control_pipe
,
&
overlapped
,
&
count
,
FALSE
);
r
=
GetOverlappedResult
(
process
->
control_pipe
,
&
overlapped
,
&
count
,
FALSE
);
}
if
(
!
r
||
count
!=
size
)
{
...
...
@@ -1011,17 +1011,17 @@ BOOL service_send_command( struct service_entry *service, const void *data, DWOR
*
result
=
(
!
r
?
GetLastError
()
:
ERROR_WRITE_FAULT
);
return
FALSE
;
}
r
=
ReadFile
(
service
->
control_pipe
,
result
,
sizeof
*
result
,
&
count
,
&
overlapped
);
r
=
ReadFile
(
process
->
control_pipe
,
result
,
sizeof
*
result
,
&
count
,
&
overlapped
);
if
(
!
r
&&
GetLastError
()
==
ERROR_IO_PENDING
)
{
ret
=
WaitForSingleObject
(
service
->
overlapped_event
,
service_pipe_timeout
);
ret
=
WaitForSingleObject
(
process
->
overlapped_event
,
service_pipe_timeout
);
if
(
ret
==
WAIT_TIMEOUT
)
{
WINE_ERR
(
"receiving command result timed out
\n
"
);
*
result
=
ERROR_SERVICE_REQUEST_TIMEOUT
;
return
FALSE
;
}
r
=
GetOverlappedResult
(
service
->
control_pipe
,
&
overlapped
,
&
count
,
FALSE
);
r
=
GetOverlappedResult
(
process
->
control_pipe
,
&
overlapped
,
&
count
,
FALSE
);
}
if
(
!
r
||
count
!=
sizeof
*
result
)
{
...
...
@@ -1054,7 +1054,7 @@ static BOOL service_send_control(struct service_entry *service, DWORD dwControl,
ssi
->
name_size
=
strlenW
(
service
->
name
)
+
1
;
strcpyW
(
ssi
->
data
,
service
->
name
);
r
=
service_send_command
(
service
,
ssi
,
ssi
->
total_size
,
result
);
r
=
process_send_command
(
service
->
process
,
ssi
,
ssi
->
total_size
,
result
);
HeapFree
(
GetProcessHeap
(),
0
,
ssi
);
return
r
;
}
...
...
@@ -1170,7 +1170,7 @@ DWORD __cdecl svcctl_ControlService(
if
(
dwControl
==
SERVICE_CONTROL_STOP
)
service
->
service_entry
->
force_shutdown
=
TRUE
;
control_mutex
=
service
->
service_entry
->
control_mutex
;
control_mutex
=
service
->
service_entry
->
process
->
control_mutex
;
service_unlock
(
service
->
service_entry
);
ret
=
WaitForSingleObject
(
control_mutex
,
30000
);
...
...
@@ -1926,7 +1926,7 @@ DWORD events_loop(void)
WINE_TRACE
(
"Exceeded maximum wait object count
\n
"
);
break
;
}
wait_handles
[
num_handles
]
=
iter
->
service_entry
->
process
;
wait_handles
[
num_handles
]
=
iter
->
service_entry
->
process
->
process
;
num_handles
++
;
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
...
...
programs/services/services.c
View file @
7fc3f72d
...
...
@@ -68,8 +68,30 @@ static const WCHAR SZ_DESCRIPTION[] = {'D','e','s','c','r','i','p','t','i'
static
const
WCHAR
SZ_PRESHUTDOWN
[]
=
{
'P'
,
'r'
,
'e'
,
's'
,
'h'
,
'u'
,
't'
,
'd'
,
'o'
,
'w'
,
'n'
,
'T'
,
'i'
,
'm'
,
'e'
,
'o'
,
'u'
,
't'
,
0
};
static
const
WCHAR
SZ_WOW64
[]
=
{
'W'
,
'O'
,
'W'
,
'6'
,
'4'
,
0
};
static
DWORD
process_create
(
struct
process_entry
**
entry
)
{
*
entry
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
**
entry
));
if
(
!*
entry
)
return
ERROR_NOT_ENOUGH_SERVER_MEMORY
;
(
*
entry
)
->
control_pipe
=
INVALID_HANDLE_VALUE
;
/* all other fields are zero */
return
ERROR_SUCCESS
;
}
static
void
free_process_entry
(
struct
process_entry
*
entry
)
{
CloseHandle
(
entry
->
process
);
CloseHandle
(
entry
->
control_mutex
);
CloseHandle
(
entry
->
control_pipe
);
CloseHandle
(
entry
->
overlapped_event
);
CloseHandle
(
entry
->
status_changed_event
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
);
}
DWORD
service_create
(
LPCWSTR
name
,
struct
service_entry
**
entry
)
{
DWORD
err
;
*
entry
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
**
entry
));
if
(
!*
entry
)
return
ERROR_NOT_ENOUGH_SERVER_MEMORY
;
...
...
@@ -79,7 +101,12 @@ DWORD service_create(LPCWSTR name, struct service_entry **entry)
HeapFree
(
GetProcessHeap
(),
0
,
*
entry
);
return
ERROR_NOT_ENOUGH_SERVER_MEMORY
;
}
(
*
entry
)
->
control_pipe
=
INVALID_HANDLE_VALUE
;
if
((
err
=
process_create
(
&
(
*
entry
)
->
process
))
!=
ERROR_SUCCESS
)
{
HeapFree
(
GetProcessHeap
(),
0
,
(
*
entry
)
->
process
);
HeapFree
(
GetProcessHeap
(),
0
,
*
entry
);
return
err
;
}
(
*
entry
)
->
status
.
dwCurrentState
=
SERVICE_STOPPED
;
(
*
entry
)
->
status
.
dwWin32ExitCode
=
ERROR_SERVICE_NEVER_STARTED
;
(
*
entry
)
->
preshutdown_timeout
=
default_preshutdown_timeout
;
...
...
@@ -98,11 +125,7 @@ void free_service_entry(struct service_entry *entry)
HeapFree
(
GetProcessHeap
(),
0
,
entry
->
description
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
->
dependOnServices
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
->
dependOnGroups
);
CloseHandle
(
entry
->
process
);
CloseHandle
(
entry
->
control_mutex
);
CloseHandle
(
entry
->
control_pipe
);
CloseHandle
(
entry
->
overlapped_event
);
CloseHandle
(
entry
->
status_changed_event
);
free_process_entry
(
entry
->
process
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
);
}
...
...
@@ -332,13 +355,14 @@ static void scmdatabase_wait_terminate(struct scmdatabase *db)
run
=
FALSE
;
LIST_FOR_EACH_ENTRY
(
service
,
&
db
->
services
,
struct
service_entry
,
entry
)
{
if
(
service
->
process
)
struct
process_entry
*
process
=
service
->
process
;
if
(
process
->
process
)
{
scmdatabase_unlock
(
db
);
WaitForSingleObject
(
service
->
process
,
INFINITE
);
WaitForSingleObject
(
process
->
process
,
INFINITE
);
scmdatabase_lock
(
db
);
CloseHandle
(
service
->
process
);
service
->
process
=
NULL
;
CloseHandle
(
process
->
process
);
process
->
process
=
NULL
;
run
=
TRUE
;
break
;
}
...
...
@@ -729,7 +753,7 @@ static DWORD service_start_process(struct service_entry *service_entry, HANDLE *
}
service_entry
->
status
.
dwProcessId
=
pi
.
dwProcessId
;
service_entry
->
process
=
pi
.
hProcess
;
service_entry
->
process
->
process
=
pi
.
hProcess
;
*
process
=
pi
.
hProcess
;
CloseHandle
(
pi
.
hThread
);
...
...
@@ -738,7 +762,7 @@ static DWORD service_start_process(struct service_entry *service_entry, HANDLE *
static
DWORD
service_wait_for_startup
(
struct
service_entry
*
service_entry
,
HANDLE
process_handle
)
{
HANDLE
handles
[
2
]
=
{
service_entry
->
status_changed_event
,
process_handle
};
HANDLE
handles
[
2
]
=
{
service_entry
->
process
->
status_changed_event
,
process_handle
};
DWORD
state
,
ret
;
WINE_TRACE
(
"%p
\n
"
,
service_entry
);
...
...
@@ -769,6 +793,7 @@ static DWORD service_wait_for_startup(struct service_entry *service_entry, HANDL
static
BOOL
service_send_start_message
(
struct
service_entry
*
service
,
HANDLE
process_handle
,
LPCWSTR
*
argv
,
DWORD
argc
)
{
struct
process_entry
*
process
=
service
->
process
;
OVERLAPPED
overlapped
;
DWORD
i
,
len
,
result
;
service_start_info
*
ssi
;
...
...
@@ -777,16 +802,16 @@ static BOOL service_send_start_message(struct service_entry *service, HANDLE pro
WINE_TRACE
(
"%s %p %d
\n
"
,
wine_dbgstr_w
(
service
->
name
),
argv
,
argc
);
overlapped
.
hEvent
=
service
->
overlapped_event
;
if
(
!
ConnectNamedPipe
(
service
->
control_pipe
,
&
overlapped
))
overlapped
.
hEvent
=
process
->
overlapped_event
;
if
(
!
ConnectNamedPipe
(
process
->
control_pipe
,
&
overlapped
))
{
if
(
GetLastError
()
==
ERROR_IO_PENDING
)
{
HANDLE
handles
[
2
];
handles
[
0
]
=
service
->
overlapped_event
;
handles
[
0
]
=
process
->
overlapped_event
;
handles
[
1
]
=
process_handle
;
if
(
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
service_pipe_timeout
)
!=
WAIT_OBJECT_0
)
CancelIo
(
service
->
control_pipe
);
CancelIo
(
process
->
control_pipe
);
if
(
!
HasOverlappedIoCompleted
(
&
overlapped
))
{
WINE_ERR
(
"service %s failed to start
\n
"
,
wine_dbgstr_w
(
service
->
name
));
...
...
@@ -822,7 +847,7 @@ static BOOL service_send_start_message(struct service_entry *service, HANDLE pro
}
*
p
=
0
;
r
=
service_send_command
(
service
,
ssi
,
ssi
->
total_size
,
&
result
);
r
=
process_send_command
(
process
,
ssi
,
ssi
->
total_size
,
&
result
);
if
(
r
&&
result
)
{
SetLastError
(
result
);
...
...
@@ -836,6 +861,7 @@ static BOOL service_send_start_message(struct service_entry *service, HANDLE pro
DWORD
service_start
(
struct
service_entry
*
service
,
DWORD
service_argc
,
LPCWSTR
*
service_argv
)
{
struct
process_entry
*
process
=
service
->
process
;
DWORD
err
;
LPWSTR
name
;
HANDLE
process_handle
=
NULL
;
...
...
@@ -844,26 +870,26 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
if
(
err
!=
ERROR_SUCCESS
)
return
err
;
if
(
WaitForSingleObject
(
service
->
process
,
0
)
==
WAIT_TIMEOUT
)
if
(
WaitForSingleObject
(
process
->
process
,
0
)
==
WAIT_TIMEOUT
)
{
scmdatabase_unlock_startup
(
service
->
db
);
return
ERROR_SERVICE_ALREADY_RUNNING
;
}
CloseHandle
(
service
->
control_pipe
);
service
->
control_mutex
=
CreateMutexW
(
NULL
,
TRUE
,
NULL
);
CloseHandle
(
process
->
control_pipe
);
process
->
control_mutex
=
CreateMutexW
(
NULL
,
TRUE
,
NULL
);
service
->
force_shutdown
=
FALSE
;
if
(
!
service
->
status_changed_event
)
service
->
status_changed_event
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
!
service
->
overlapped_event
)
service
->
overlapped_event
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
if
(
!
process
->
status_changed_event
)
process
->
status_changed_event
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
!
process
->
overlapped_event
)
process
->
overlapped_event
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
name
=
service_get_pipe_name
();
service
->
control_pipe
=
CreateNamedPipeW
(
name
,
PIPE_ACCESS_DUPLEX
|
FILE_FLAG_OVERLAPPED
,
process
->
control_pipe
=
CreateNamedPipeW
(
name
,
PIPE_ACCESS_DUPLEX
|
FILE_FLAG_OVERLAPPED
,
PIPE_TYPE_BYTE
|
PIPE_WAIT
,
1
,
256
,
256
,
10000
,
NULL
);
HeapFree
(
GetProcessHeap
(),
0
,
name
);
if
(
service
->
control_pipe
==
INVALID_HANDLE_VALUE
)
if
(
process
->
control_pipe
==
INVALID_HANDLE_VALUE
)
{
WINE_ERR
(
"failed to create pipe for %s, error = %d
\n
"
,
wine_dbgstr_w
(
service
->
name
),
GetLastError
());
...
...
@@ -883,7 +909,7 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
}
if
(
err
==
ERROR_SUCCESS
)
ReleaseMutex
(
service
->
control_mutex
);
ReleaseMutex
(
process
->
control_mutex
);
else
service_terminate
(
service
);
scmdatabase_unlock_startup
(
service
->
db
);
...
...
@@ -895,16 +921,18 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
void
service_terminate
(
struct
service_entry
*
service
)
{
struct
process_entry
*
process
=
service
->
process
;
service_lock
(
service
);
TerminateProcess
(
service
->
process
,
0
);
CloseHandle
(
service
->
process
);
service
->
process
=
NULL
;
CloseHandle
(
service
->
status_changed_event
);
service
->
status_changed_event
=
NULL
;
CloseHandle
(
service
->
control_mutex
);
service
->
control_mutex
=
NULL
;
CloseHandle
(
service
->
control_pipe
);
service
->
control_pipe
=
INVALID_HANDLE_VALUE
;
TerminateProcess
(
process
->
process
,
0
);
CloseHandle
(
process
->
process
);
process
->
process
=
NULL
;
CloseHandle
(
process
->
status_changed_event
);
process
->
status_changed_event
=
NULL
;
CloseHandle
(
process
->
control_mutex
);
process
->
control_mutex
=
NULL
;
CloseHandle
(
process
->
control_pipe
);
process
->
control_pipe
=
INVALID_HANDLE_VALUE
;
service
->
status
.
dwProcessId
=
0
;
service
->
status
.
dwCurrentState
=
SERVICE_STOPPED
;
...
...
programs/services/services.h
View file @
7fc3f72d
...
...
@@ -31,6 +31,15 @@ struct scmdatabase
CRITICAL_SECTION
cs
;
};
struct
process_entry
{
HANDLE
process
;
HANDLE
control_mutex
;
HANDLE
control_pipe
;
HANDLE
overlapped_event
;
HANDLE
status_changed_event
;
};
struct
service_entry
{
struct
list
entry
;
...
...
@@ -43,11 +52,7 @@ struct service_entry
LPWSTR
description
;
LPWSTR
dependOnServices
;
LPWSTR
dependOnGroups
;
HANDLE
process
;
HANDLE
control_mutex
;
HANDLE
control_pipe
;
HANDLE
overlapped_event
;
HANDLE
status_changed_event
;
struct
process_entry
*
process
;
BOOL
force_shutdown
;
BOOL
marked_for_delete
;
BOOL
is_wow64
;
...
...
@@ -79,7 +84,10 @@ void service_lock(struct service_entry *service);
void
service_unlock
(
struct
service_entry
*
service
);
DWORD
service_start
(
struct
service_entry
*
service
,
DWORD
service_argc
,
LPCWSTR
*
service_argv
);
void
service_terminate
(
struct
service_entry
*
service
);
BOOL
service_send_command
(
struct
service_entry
*
service
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
);
/* Process functions */
BOOL
process_send_command
(
struct
process_entry
*
process
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
);
extern
HANDLE
g_hStartedEvent
;
...
...
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