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
d8dec0b3
Commit
d8dec0b3
authored
Jun 20, 2019
by
Jacek Caban
Committed by
Alexandre Julliard
Jun 20, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Support delayed autostart services.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4c750a35
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
1 deletion
+116
-1
services.c
programs/services/services.c
+115
-1
services.h
programs/services/services.h
+1
-0
No files found.
programs/services/services.c
View file @
d8dec0b3
...
...
@@ -29,6 +29,7 @@
#include <userenv.h>
#include "wine/debug.h"
#include "wine/heap.h"
#include "svcctl.h"
#include "services.h"
...
...
@@ -42,6 +43,7 @@ struct scmdatabase *active_database;
DWORD
service_pipe_timeout
=
10000
;
DWORD
service_kill_timeout
=
60000
;
static
DWORD
default_preshutdown_timeout
=
180000
;
static
DWORD
autostart_delay
=
120000
;
static
void
*
environment
=
NULL
;
static
HKEY
service_current_key
=
NULL
;
...
...
@@ -68,6 +70,7 @@ static const WCHAR SZ_TAG[] = {'T','a','g',0};
static
const
WCHAR
SZ_DESCRIPTION
[]
=
{
'D'
,
'e'
,
's'
,
'c'
,
'r'
,
'i'
,
'p'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
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
const
WCHAR
SZ_DELAYED_AUTOSTART
[]
=
{
'D'
,
'e'
,
'l'
,
'a'
,
'y'
,
'e'
,
'd'
,
'A'
,
'u'
,
't'
,
'o'
,
'S'
,
't'
,
'a'
,
'r'
,
't'
,
0
};
static
DWORD
process_create
(
const
WCHAR
*
name
,
struct
process_entry
**
entry
)
{
...
...
@@ -186,6 +189,8 @@ static DWORD load_service_config(HKEY hKey, struct service_entry *entry)
if
(
load_reg_dword
(
hKey
,
SZ_WOW64
,
&
value
)
==
0
&&
value
==
1
)
entry
->
is_wow64
=
TRUE
;
if
(
load_reg_dword
(
hKey
,
SZ_DELAYED_AUTOSTART
,
&
value
)
==
0
&&
value
==
1
)
entry
->
delayed_autostart
=
TRUE
;
WINE_TRACE
(
"Image path = %s
\n
"
,
wine_dbgstr_w
(
entry
->
config
.
lpBinaryPathName
)
);
WINE_TRACE
(
"Group = %s
\n
"
,
wine_dbgstr_w
(
entry
->
config
.
lpLoadOrderGroup
)
);
...
...
@@ -329,11 +334,101 @@ static int __cdecl compare_tags(const void *a, const void *b)
return
service_a
->
config
.
dwTagId
-
service_b
->
config
.
dwTagId
;
}
static
PTP_CLEANUP_GROUP
delayed_autostart_cleanup
;
struct
delayed_autostart_params
{
unsigned
int
count
;
struct
service_entry
**
services
;
};
static
void
CALLBACK
delayed_autostart_cancel_callback
(
void
*
object
,
void
*
userdata
)
{
struct
delayed_autostart_params
*
params
=
object
;
while
(
params
->
count
--
)
release_service
(
params
->
services
[
params
->
count
]);
heap_free
(
params
->
services
);
heap_free
(
params
);
}
static
void
CALLBACK
delayed_autostart_callback
(
TP_CALLBACK_INSTANCE
*
instance
,
void
*
context
,
TP_WAIT
*
wait
,
TP_WAIT_RESULT
result
)
{
struct
delayed_autostart_params
*
params
=
context
;
struct
service_entry
*
service
;
unsigned
int
i
;
DWORD
err
;
if
(
result
==
WAIT_TIMEOUT
)
{
scmdatabase_lock_startup
(
active_database
,
INFINITE
);
for
(
i
=
0
;
i
<
params
->
count
;
i
++
)
{
service
=
params
->
services
[
i
];
if
(
service
->
status
.
dwCurrentState
==
SERVICE_STOPPED
)
{
TRACE
(
"Starting deleyed auto-start service %s
\n
"
,
debugstr_w
(
service
->
name
));
err
=
service_start
(
service
,
0
,
NULL
);
if
(
err
!=
ERROR_SUCCESS
)
FIXME
(
"Delayed auto-start service %s failed to start: %d
\n
"
,
wine_dbgstr_w
(
service
->
name
),
err
);
}
release_service
(
service
);
}
scmdatabase_unlock_startup
(
active_database
);
}
heap_free
(
params
->
services
);
heap_free
(
params
);
CloseThreadpoolWait
(
wait
);
}
static
BOOL
schedule_delayed_autostart
(
struct
service_entry
**
services
,
unsigned
int
count
)
{
struct
delayed_autostart_params
*
params
;
TP_CALLBACK_ENVIRON
environment
;
LARGE_INTEGER
timestamp
;
TP_WAIT
*
wait
;
FILETIME
ft
;
if
(
!
(
delayed_autostart_cleanup
=
CreateThreadpoolCleanupGroup
()))
{
ERR
(
"CreateThreadpoolCleanupGroup failed with error %u
\n
"
,
GetLastError
());
return
FALSE
;
}
if
(
!
(
params
=
heap_alloc
(
sizeof
(
*
params
))))
return
FALSE
;
params
->
count
=
count
;
params
->
services
=
services
;
memset
(
&
environment
,
0
,
sizeof
(
environment
));
environment
.
Version
=
1
;
environment
.
CleanupGroup
=
delayed_autostart_cleanup
;
environment
.
CleanupGroupCancelCallback
=
delayed_autostart_cancel_callback
;
timestamp
.
QuadPart
=
(
ULONGLONG
)
autostart_delay
*
-
10000
;
ft
.
dwLowDateTime
=
timestamp
.
u
.
LowPart
;
ft
.
dwHighDateTime
=
timestamp
.
u
.
HighPart
;
if
(
!
(
wait
=
CreateThreadpoolWait
(
delayed_autostart_callback
,
params
,
&
environment
)))
{
ERR
(
"CreateThreadpoolWait failed: %u
\n
"
,
GetLastError
());
heap_free
(
params
);
return
FALSE
;
}
SetThreadpoolWait
(
wait
,
params
,
&
ft
);
return
TRUE
;
}
static
void
scmdatabase_autostart_services
(
struct
scmdatabase
*
db
)
{
struct
service_entry
**
services_list
;
unsigned
int
i
=
0
;
unsigned
int
size
=
32
;
unsigned
int
delayed_cnt
=
0
;
struct
service_entry
*
service
;
services_list
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
*
sizeof
(
services_list
[
0
]));
...
...
@@ -370,6 +465,12 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
{
DWORD
err
;
service
=
services_list
[
i
];
if
(
service
->
delayed_autostart
)
{
TRACE
(
"delayed starting %s
\n
"
,
wine_dbgstr_w
(
service
->
name
));
services_list
[
delayed_cnt
++
]
=
service
;
continue
;
}
err
=
service_start
(
service
,
0
,
NULL
);
if
(
err
!=
ERROR_SUCCESS
)
WINE_FIXME
(
"Auto-start service %s failed to start: %d
\n
"
,
...
...
@@ -378,7 +479,9 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
}
scmdatabase_unlock_startup
(
db
);
HeapFree
(
GetProcessHeap
(),
0
,
services_list
);
if
(
!
delayed_cnt
||
!
schedule_delayed_autostart
(
services_list
,
delayed_cnt
))
heap_free
(
services_list
);
}
static
void
scmdatabase_wait_terminate
(
struct
scmdatabase
*
db
)
...
...
@@ -1115,6 +1218,8 @@ static void load_registry_parameters(void)
{
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
'P'
,
'i'
,
'p'
,
'e'
,
'T'
,
'i'
,
'm'
,
'e'
,
'o'
,
'u'
,
't'
,
0
};
static
const
WCHAR
killtimeoutW
[]
=
{
'W'
,
'a'
,
'i'
,
't'
,
'T'
,
'o'
,
'K'
,
'i'
,
'l'
,
'l'
,
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
'T'
,
'i'
,
'm'
,
'e'
,
'o'
,
'u'
,
't'
,
0
};
static
const
WCHAR
autostartdelayW
[]
=
{
'A'
,
'u'
,
't'
,
'o'
,
'S'
,
't'
,
'a'
,
'r'
,
't'
,
'D'
,
'e'
,
'l'
,
'a'
,
'y'
,
0
};
HKEY
key
;
WCHAR
buffer
[
64
];
DWORD
type
,
count
,
val
;
...
...
@@ -1131,6 +1236,10 @@ static void load_registry_parameters(void)
type
==
REG_SZ
&&
(
val
=
wcstol
(
buffer
,
NULL
,
10
)))
service_kill_timeout
=
val
;
count
=
sizeof
(
val
);
if
(
!
RegQueryValueExW
(
key
,
autostartdelayW
,
NULL
,
&
type
,
(
BYTE
*
)
&
val
,
&
count
)
&&
type
==
REG_DWORD
)
autostart_delay
=
val
;
RegCloseKey
(
key
);
}
...
...
@@ -1164,6 +1273,11 @@ int main(int argc, char *argv[])
SetEvent
(
started_event
);
WaitForSingleObject
(
exit_event
,
INFINITE
);
scmdatabase_wait_terminate
(
active_database
);
if
(
delayed_autostart_cleanup
)
{
CloseThreadpoolCleanupGroupMembers
(
delayed_autostart_cleanup
,
TRUE
,
NULL
);
CloseThreadpoolCleanupGroup
(
delayed_autostart_cleanup
);
}
RPC_Stop
();
}
scmdatabase_destroy
(
active_database
);
...
...
programs/services/services.h
View file @
d8dec0b3
...
...
@@ -63,6 +63,7 @@ struct service_entry
BOOL
force_shutdown
;
BOOL
marked_for_delete
;
BOOL
is_wow64
;
BOOL
delayed_autostart
;
struct
list
handles
;
};
...
...
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