Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
9183a171
Commit
9183a171
authored
Aug 29, 2011
by
Francois Gouget
Committed by
Alexandre Julliard
Aug 30, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Cleanup when a service fails to start so it is still fully considered to be stopped.
parent
79ef408c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
27 deletions
+42
-27
service.c
dlls/advapi32/tests/service.c
+11
-14
services.c
programs/services/services.c
+31
-13
No files found.
dlls/advapi32/tests/service.c
View file @
9183a171
...
...
@@ -2065,7 +2065,7 @@ cleanup:
CloseServiceHandle
(
scm_handle
);
}
static
DWORD
try_start_stop
(
SC_HANDLE
svc_handle
,
const
char
*
name
,
int
todo
,
DWORD
is_nt4
)
static
DWORD
try_start_stop
(
SC_HANDLE
svc_handle
,
const
char
*
name
,
DWORD
is_nt4
)
{
BOOL
ret
;
DWORD
le1
,
le2
;
...
...
@@ -2082,24 +2082,21 @@ static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, int todo, DW
ret
=
pQueryServiceStatusEx
(
svc_handle
,
SC_STATUS_PROCESS_INFO
,
(
BYTE
*
)
&
statusproc
,
sizeof
(
statusproc
),
&
needed
);
ok
(
ret
,
"%s: QueryServiceStatusEx() failed le=%u
\n
"
,
name
,
GetLastError
());
todo_wine
ok
(
statusproc
.
dwCurrentState
==
SERVICE_STOPPED
,
"%s: should be stopped state=%x
\n
"
,
name
,
statusproc
.
dwCurrentState
);
todo_wine
ok
(
statusproc
.
dwProcessId
==
0
,
"%s: ProcessId should be 0 instead of %x
\n
"
,
name
,
statusproc
.
dwProcessId
);
ok
(
statusproc
.
dwCurrentState
==
SERVICE_STOPPED
,
"%s: should be stopped state=%x
\n
"
,
name
,
statusproc
.
dwCurrentState
);
ok
(
statusproc
.
dwProcessId
==
0
,
"%s: ProcessId should be 0 instead of %x
\n
"
,
name
,
statusproc
.
dwProcessId
);
}
ret
=
StartServiceA
(
svc_handle
,
0
,
NULL
);
le2
=
GetLastError
();
ok
(
!
ret
,
"%s: StartServiceA() should have failed
\n
"
,
name
);
if
(
todo
)
todo_wine
ok
(
le2
==
le1
,
"%s: the second try should yield the same error: %u != %u
\n
"
,
name
,
le1
,
le2
);
else
ok
(
le2
==
le1
,
"%s: the second try should yield the same error: %u != %u
\n
"
,
name
,
le1
,
le2
);
ok
(
le2
==
le1
,
"%s: the second try should yield the same error: %u != %u
\n
"
,
name
,
le1
,
le2
);
status
.
dwCurrentState
=
0xdeadbeef
;
ret
=
ControlService
(
svc_handle
,
SERVICE_CONTROL_STOP
,
&
status
);
le2
=
GetLastError
();
ok
(
!
ret
,
"%s: ControlService() should have failed
\n
"
,
name
);
todo_wine
ok
(
le2
==
ERROR_SERVICE_NOT_ACTIVE
,
"%s: %d != ERROR_SERVICE_NOT_ACTIVE
\n
"
,
name
,
le2
);
todo_wine
ok
(
status
.
dwCurrentState
==
SERVICE_STOPPED
||
ok
(
status
.
dwCurrentState
==
SERVICE_STOPPED
||
broken
(
is_nt4
),
/* NT4 returns a random value */
"%s: should be stopped state=%x
\n
"
,
name
,
status
.
dwCurrentState
);
...
...
@@ -2153,14 +2150,14 @@ static void test_start_stop(void)
ok
(
FALSE
,
"Could not create the service: %d
\n
"
,
GetLastError
());
goto
cleanup
;
}
le
=
try_start_stop
(
svc_handle
,
displayname
,
1
,
is_nt4
);
le
=
try_start_stop
(
svc_handle
,
displayname
,
is_nt4
);
todo_wine
ok
(
le
==
ERROR_SERVICE_DISABLED
,
"%d != ERROR_SERVICE_DISABLED
\n
"
,
le
);
/* Then one with a bad path */
displayname
=
"Winetest Bad Path"
;
ret
=
ChangeServiceConfigA
(
svc_handle
,
SERVICE_NO_CHANGE
,
SERVICE_DEMAND_START
,
SERVICE_NO_CHANGE
,
"c:
\\
no_such_file.exe"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
displayname
);
ok
(
ret
,
"ChangeServiceConfig() failed le=%u
\n
"
,
GetLastError
());
try_start_stop
(
svc_handle
,
displayname
,
0
,
is_nt4
);
try_start_stop
(
svc_handle
,
displayname
,
is_nt4
);
if
(
is_nt4
)
{
...
...
@@ -2175,8 +2172,8 @@ static void test_start_stop(void)
displayname
=
"Winetest Exit Service"
;
ret
=
ChangeServiceConfigA
(
svc_handle
,
SERVICE_NO_CHANGE
,
SERVICE_NO_CHANGE
,
SERVICE_NO_CHANGE
,
cmd
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
displayname
);
ok
(
ret
,
"ChangeServiceConfig() failed le=%u
\n
"
,
GetLastError
());
le
=
try_start_stop
(
svc_handle
,
displayname
,
0
,
is_nt4
);
todo_wine
ok
(
le
==
ERROR_SERVICE_REQUEST_TIMEOUT
,
"%d != ERROR_SERVICE_REQUEST_TIMEOUT
\n
"
,
le
);
le
=
try_start_stop
(
svc_handle
,
displayname
,
is_nt4
);
ok
(
le
==
ERROR_SERVICE_REQUEST_TIMEOUT
,
"%d != ERROR_SERVICE_REQUEST_TIMEOUT
\n
"
,
le
);
/* And finally with a service that plays dead, forcing a timeout.
* This time we will put no quotes. That should work too, even if there are
...
...
@@ -2187,8 +2184,8 @@ static void test_start_stop(void)
ret
=
ChangeServiceConfigA
(
svc_handle
,
SERVICE_NO_CHANGE
,
SERVICE_NO_CHANGE
,
SERVICE_NO_CHANGE
,
cmd
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
displayname
);
ok
(
ret
,
"ChangeServiceConfig() failed le=%u
\n
"
,
GetLastError
());
le
=
try_start_stop
(
svc_handle
,
displayname
,
0
,
is_nt4
);
todo_wine
ok
(
le
==
ERROR_SERVICE_REQUEST_TIMEOUT
,
"%d != ERROR_SERVICE_REQUEST_TIMEOUT
\n
"
,
le
);
le
=
try_start_stop
(
svc_handle
,
displayname
,
is_nt4
);
ok
(
le
==
ERROR_SERVICE_REQUEST_TIMEOUT
,
"%d != ERROR_SERVICE_REQUEST_TIMEOUT
\n
"
,
le
);
cleanup:
if
(
svc_handle
)
...
...
programs/services/services.c
View file @
9183a171
...
...
@@ -772,25 +772,43 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
{
WINE_ERR
(
"failed to create pipe for %s, error = %d
\n
"
,
wine_dbgstr_w
(
service
->
name
),
GetLastError
());
scmdatabase_unlock_startup
(
service
->
db
);
return
GetLastError
();
err
=
GetLastError
();
}
else
{
err
=
service_start_process
(
service
,
&
process_handle
);
if
(
err
==
ERROR_SUCCESS
)
{
if
(
!
service_send_start_message
(
service
,
process_handle
,
service_argv
,
service_argc
))
err
=
ERROR_SERVICE_REQUEST_TIMEOUT
;
}
err
=
service_start_process
(
service
,
&
process_handle
);
if
(
err
==
ERROR_SUCCESS
)
err
=
service_wait_for_startup
(
service
,
process_handle
);
if
(
err
==
ERROR_SUCCESS
)
{
if
(
!
service_send_start_message
(
service
,
process_handle
,
service_argv
,
service_argc
))
err
=
ERROR_SERVICE_REQUEST_TIMEOUT
;
if
(
process_handle
)
CloseHandle
(
process_handle
);
}
if
(
err
==
ERROR_SUCCESS
)
err
=
service_wait_for_startup
(
service
,
process_handle
);
if
(
process_handle
)
CloseHandle
(
process_handle
);
ReleaseMutex
(
service
->
control_mutex
);
ReleaseMutex
(
service
->
control_mutex
);
else
{
CloseHandle
(
service
->
overlapped_event
);
service
->
overlapped_event
=
NULL
;
CloseHandle
(
service
->
status_changed_event
);
service
->
status_changed_event
=
NULL
;
CloseHandle
(
service
->
control_mutex
);
service
->
control_mutex
=
NULL
;
if
(
service
->
control_pipe
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
service
->
control_pipe
);
service
->
control_pipe
=
INVALID_HANDLE_VALUE
;
service
->
status
.
dwProcessId
=
0
;
service_lock_exclusive
(
service
);
service
->
status
.
dwCurrentState
=
SERVICE_STOPPED
;
service_unlock
(
service
);
}
scmdatabase_unlock_startup
(
service
->
db
);
WINE_TRACE
(
"returning %d
\n
"
,
err
);
...
...
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