schedsvc: Mark service as auto-start once a task is registered.
Dmitry Timoshkov
dmitry at baikal.ru
Thu Mar 13 22:58:16 CDT 2014
---
dlls/schedsvc/schedsvc.c | 6 ++++-
dlls/schedsvc/schedsvc_private.h | 2 ++
dlls/schedsvc/svc_main.c | 53 ++++++++++++++++++++++++++++++++++++++--
3 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/dlls/schedsvc/schedsvc.c b/dlls/schedsvc/schedsvc.c
index 538a423..6ce8064 100644
--- a/dlls/schedsvc/schedsvc.c
+++ b/dlls/schedsvc/schedsvc.c
@@ -208,7 +208,11 @@ HRESULT __cdecl SchRpcRegisterTask(const WCHAR *path, const WCHAR *xml, DWORD fl
}
hr = write_xml_utf8(full_name, disposition, xml);
- if (hr == S_OK) *actual_path = heap_strdupW(relative_path);
+ if (hr == S_OK)
+ {
+ *actual_path = heap_strdupW(relative_path);
+ schedsvc_auto_start();
+ }
heap_free(full_name);
return hr;
diff --git a/dlls/schedsvc/schedsvc_private.h b/dlls/schedsvc/schedsvc_private.h
index 082bda5..fd0225f 100644
--- a/dlls/schedsvc/schedsvc_private.h
+++ b/dlls/schedsvc/schedsvc_private.h
@@ -21,6 +21,8 @@
#include "wine/unicode.h"
+void schedsvc_auto_start(void) DECLSPEC_HIDDEN;
+
static void *heap_alloc_zero(SIZE_T size) __WINE_ALLOC_SIZE(1);
static inline void *heap_alloc_zero(SIZE_T size)
{
diff --git a/dlls/schedsvc/svc_main.c b/dlls/schedsvc/svc_main.c
index fe5d4fc..95872cd 100644
--- a/dlls/schedsvc/svc_main.c
+++ b/dlls/schedsvc/svc_main.c
@@ -29,9 +29,60 @@
WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
+static const WCHAR scheduleW[] = {'S','c','h','e','d','u','l','e',0};
static SERVICE_STATUS_HANDLE schedsvc_handle;
static HANDLE done_event;
+void schedsvc_auto_start(void)
+{
+ static DWORD start_type;
+ SC_HANDLE scm, service;
+ QUERY_SERVICE_CONFIGW *cfg;
+ DWORD cfg_size;
+
+ if (start_type == SERVICE_AUTO_START) return;
+
+ TRACE("changing service start type to SERVICE_AUTO_START\n");
+
+ scm = OpenSCManagerW(NULL, NULL, 0);
+ if (!scm)
+ {
+ WARN("failed to open SCM (%u)\n", GetLastError());
+ return;
+ }
+
+ service = OpenServiceW(scm, scheduleW, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
+ if (service)
+ {
+ if (!QueryServiceConfigW(service, NULL, 0, &cfg_size) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ cfg = HeapAlloc(GetProcessHeap(), 0, cfg_size);
+ if (cfg)
+ {
+ if (QueryServiceConfigW(service, cfg, cfg_size, &cfg_size))
+ {
+ start_type = cfg->dwStartType;
+ if (start_type != SERVICE_AUTO_START)
+ {
+ if (ChangeServiceConfigW(service, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ start_type = SERVICE_AUTO_START;
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, cfg);
+ }
+ }
+ else
+ WARN("failed to query service config (%u)\n", GetLastError());
+
+ CloseServiceHandle(service);
+ }
+ else
+ WARN("failed to open service (%u)\n", GetLastError());
+
+ CloseServiceHandle(scm);
+}
+
static void schedsvc_update_status(DWORD state)
{
SERVICE_STATUS status;
@@ -122,8 +173,6 @@ static void RPC_finish(void)
void WINAPI ServiceMain(DWORD argc, LPWSTR *argv)
{
- static const WCHAR scheduleW[] = {'S','c','h','e','d','u','l','e',0};
-
WINE_TRACE("starting Task Scheduler Service\n");
if (RPC_init() != RPC_S_OK) return;
--
1.8.5.5
More information about the wine-patches
mailing list