[1/7] schedsvc: Add Task Scheduler service. Try 3.

Dmitry Timoshkov dmitry at baikal.ru
Thu Mar 6 21:10:28 CST 2014


---
 configure.ac                |   1 +
 dlls/schedsvc/Makefile.in   |   8 +++
 dlls/schedsvc/schedsvc.c    | 158 ++++++++++++++++++++++++++++++++++++++++
 dlls/schedsvc/schedsvc.spec |   1 +
 dlls/schedsvc/schrpc.idl    |   3 +
 dlls/schedsvc/svc_main.c    | 171 ++++++++++++++++++++++++++++++++++++++++++++
 include/wine/schrpc.idl     | 100 ++++++++++++++++++++++++++
 loader/wine.inf.in          |  16 +++++
 8 files changed, 458 insertions(+)
 create mode 100644 dlls/schedsvc/Makefile.in
 create mode 100644 dlls/schedsvc/schedsvc.c
 create mode 100644 dlls/schedsvc/schedsvc.spec
 create mode 100644 dlls/schedsvc/schrpc.idl
 create mode 100644 dlls/schedsvc/svc_main.c
 create mode 100644 include/wine/schrpc.idl

diff --git a/configure.ac b/configure.ac
index ee8cd1a..8de9249 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3108,6 +3108,7 @@ WINE_CONFIG_DLL(scarddlg)
 WINE_CONFIG_DLL(sccbase)
 WINE_CONFIG_DLL(schannel)
 WINE_CONFIG_TEST(dlls/schannel/tests)
+WINE_CONFIG_DLL(schedsvc)
 WINE_CONFIG_DLL(scrrun,,[clean])
 WINE_CONFIG_TEST(dlls/scrrun/tests,[clean])
 WINE_CONFIG_DLL(scsiport.sys)
diff --git a/dlls/schedsvc/Makefile.in b/dlls/schedsvc/Makefile.in
new file mode 100644
index 0000000..d1ee5c3
--- /dev/null
+++ b/dlls/schedsvc/Makefile.in
@@ -0,0 +1,8 @@
+MODULE    = schedsvc.dll
+IMPORTS   = rpcrt4 advapi32
+
+C_SRCS = \
+	schedsvc.c \
+	svc_main.c
+
+IDL_SRCS = schrpc.idl
diff --git a/dlls/schedsvc/schedsvc.c b/dlls/schedsvc/schedsvc.c
new file mode 100644
index 0000000..9b9d7c5
--- /dev/null
+++ b/dlls/schedsvc/schedsvc.c
@@ -0,0 +1,158 @@
+/*
+ * Task Scheduler Service
+ *
+ * Copyright 2014 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "schrpc.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
+
+HRESULT __cdecl SchRpcHighestVersion(DWORD *version)
+{
+    WINE_FIXME("%p: stub\n", version);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcRegisterTask(const WCHAR *path, const WCHAR *xml, DWORD flags, const WCHAR *sddl,
+                                   DWORD task_logon_type, DWORD n_creds, const TASK_USER_CRED *creds,
+                                   WCHAR **actual_path, TASK_XML_ERROR_INFO **xml_error_info)
+{
+    WINE_FIXME("%s,%s,%#x,%s,%u,%u,%p,%p,%p: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(xml), flags,
+            wine_dbgstr_w(sddl), task_logon_type, n_creds, creds, actual_path, xml_error_info);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcRetrieveTask(const WCHAR *path, const WCHAR *languages, ULONG *n_languages, WCHAR **xml)
+{
+    WINE_FIXME("%s,%s,%p,%p: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(languages), n_languages, xml);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcCreateFolder(const WCHAR *path, const WCHAR *sddl, DWORD flags)
+{
+    WINE_FIXME("%s,%s,%#x: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(sddl), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcSetSecurity(const WCHAR *path, const WCHAR *sddl, DWORD flags)
+{
+    WINE_FIXME("%s,%s,%#x: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(sddl), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcGetSecurity(const WCHAR *path, DWORD flags, WCHAR **sddl)
+{
+    WINE_FIXME("%s,%#x,%p: stub\n", wine_dbgstr_w(path), flags, sddl);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcEnumFolders(const WCHAR *path, DWORD flags, DWORD *start_index, DWORD n_requested,
+                                  DWORD *n_names, TASK_NAMES *names)
+{
+    WINE_FIXME("%s,%#x,%p,%u,%p,%p: stub\n", wine_dbgstr_w(path), flags, start_index, n_requested, n_names, names);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcEnumTasks(const WCHAR *path, DWORD flags, DWORD *start_index, DWORD n_requested,
+                                DWORD *n_names, TASK_NAMES *names)
+{
+    WINE_FIXME("%s,%#x,%p,%u,%p,%p: stub\n", wine_dbgstr_w(path), flags, start_index, n_requested, n_names, names);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcEnumInstances(const WCHAR *path, DWORD flags, DWORD *n_guids, GUID **guids)
+{
+    WINE_FIXME("%s,%#x,%p,%p: stub\n", wine_dbgstr_w(path), flags, n_guids, guids);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcGetInstanceInfo(GUID guid, WCHAR **path, DWORD *task_state, WCHAR **action,
+                                      WCHAR **info, DWORD *n_instances, GUID **instances, DWORD *pid)
+{
+    WINE_FIXME("%s,%p,%p,%p,%p,%p,%p,%p: stub\n", wine_dbgstr_guid(&guid), path, task_state, action,
+            info, n_instances, instances, pid);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcStopInstance(GUID guid, DWORD flags)
+{
+    WINE_FIXME("%s,%#x: stub\n", wine_dbgstr_guid(&guid), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcStop(const WCHAR *path, DWORD flags)
+{
+    WINE_FIXME("%s,%#x: stub\n", wine_dbgstr_w(path), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcRun(const WCHAR *path, DWORD n_args, const WCHAR **args, DWORD flags,
+                          DWORD session_id, const WCHAR *user, GUID *guid)
+{
+    WINE_FIXME("%s,%u,%p,%#x,%#x,%s,%p: stub\n", wine_dbgstr_w(path), n_args, args, flags,
+            session_id, wine_dbgstr_w(user), guid);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcDelete(const WCHAR *path, DWORD flags)
+{
+    WINE_FIXME("%s,%#x: stub\n", wine_dbgstr_w(path), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcRename(const WCHAR *path, const WCHAR *name, DWORD flags)
+{
+    WINE_FIXME("%s,%s,%#x: stub\n", wine_dbgstr_w(path), wine_dbgstr_w(name), flags);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcScheduledRuntimes(const WCHAR *path, SYSTEMTIME *start, SYSTEMTIME *end, DWORD flags,
+                                        DWORD n_requested, DWORD *n_runtimes, SYSTEMTIME **runtimes)
+{
+    WINE_FIXME("%s,%p,%p,%#x,%u,%p,%p: stub\n", wine_dbgstr_w(path), start, end, flags,
+            n_requested, n_runtimes, runtimes);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcGetLastRunInfo(const WCHAR *path, SYSTEMTIME *last_runtime, DWORD *last_return_code)
+{
+    WINE_FIXME("%s,%p,%p: stub\n", wine_dbgstr_w(path), last_runtime, last_return_code);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcGetTaskInfo(const WCHAR *path, DWORD flags, DWORD *enabled, DWORD *task_state)
+{
+    WINE_FIXME("%s,%#x,%p,%p: stub\n", wine_dbgstr_w(path), flags, enabled, task_state);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcGetNumberOfMissedRuns(const WCHAR *path, DWORD *runs)
+{
+    WINE_FIXME("%s,%p: stub\n", wine_dbgstr_w(path), runs);
+    return E_NOTIMPL;
+}
+
+HRESULT __cdecl SchRpcEnableTask(const WCHAR *path, DWORD enabled)
+{
+    WINE_FIXME("%s,%u: stub\n", wine_dbgstr_w(path), enabled);
+    return E_NOTIMPL;
+}
diff --git a/dlls/schedsvc/schedsvc.spec b/dlls/schedsvc/schedsvc.spec
new file mode 100644
index 0000000..daa8857
--- /dev/null
+++ b/dlls/schedsvc/schedsvc.spec
@@ -0,0 +1 @@
+@ stdcall -private ServiceMain(long ptr)
diff --git a/dlls/schedsvc/schrpc.idl b/dlls/schedsvc/schrpc.idl
new file mode 100644
index 0000000..935a0b2
--- /dev/null
+++ b/dlls/schedsvc/schrpc.idl
@@ -0,0 +1,3 @@
+#pragma makedep server
+
+#include "wine/schrpc.idl"
diff --git a/dlls/schedsvc/svc_main.c b/dlls/schedsvc/svc_main.c
new file mode 100644
index 0000000..b4e03d9
--- /dev/null
+++ b/dlls/schedsvc/svc_main.c
@@ -0,0 +1,171 @@
+/*
+ * Task Scheduler Service
+ *
+ * Copyright 2014 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winsvc.h"
+#include "rpc.h"
+#include "schrpc.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
+
+static SERVICE_STATUS_HANDLE schedsvc_handle;
+static HANDLE done_event;
+
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+    TRACE("(%p,%u,%p)\n", instance, reason, reserved);
+
+    switch (reason)
+    {
+    case DLL_PROCESS_ATTACH:
+        DisableThreadLibraryCalls(instance);
+        break;
+    }
+    return TRUE;
+}
+
+static void schedsvc_update_status(DWORD state)
+{
+    SERVICE_STATUS status;
+
+    status.dwServiceType = SERVICE_WIN32;
+    status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+    status.dwWin32ExitCode = 0;
+    status.dwServiceSpecificExitCode = 0;
+    status.dwCheckPoint = 0;
+    status.dwWaitHint = 0;
+    status.dwControlsAccepted = 0;
+    status.dwCurrentState = state;
+
+    SetServiceStatus(schedsvc_handle, &status);
+}
+
+static void WINAPI schedsvc_handler(DWORD control)
+{
+    WINE_TRACE("%#x\n", control);
+
+    switch (control)
+    {
+    case SERVICE_CONTROL_STOP:
+    case SERVICE_CONTROL_SHUTDOWN:
+        schedsvc_update_status(SERVICE_STOP_PENDING);
+        SetEvent(done_event);
+        break;
+
+    default:
+        schedsvc_update_status(SERVICE_RUNNING);
+        break;
+    }
+}
+
+static RPC_BINDING_VECTOR *sched_bindings;
+
+static RPC_STATUS RPC_init(void)
+{
+    WCHAR transport[] = SCHEDSVC_TRANSPORT;
+    RPC_STATUS status;
+
+    WINE_TRACE("using %s\n", wine_dbgstr_w(transport));
+
+    status = RpcServerUseProtseqEpW(transport, 0, NULL, NULL);
+    if (status != RPC_S_OK)
+    {
+        WINE_ERR("RpcServerUseProtseqEp error %#x\n", status);
+        return status;
+    }
+
+    status = RpcServerRegisterIf(ITaskSchedulerService_v1_0_s_ifspec, 0, 0);
+    if (status != RPC_S_OK)
+    {
+        WINE_ERR("RpcServerRegisterIf error %#x\n", status);
+        return status;
+    }
+
+    status = RpcServerInqBindings(&sched_bindings);
+    if (status != RPC_S_OK)
+    {
+        WINE_ERR("RpcServerInqBindings error %#x\n", status);
+        return status;
+    }
+
+    status = RpcEpRegisterW(ITaskSchedulerService_v1_0_s_ifspec, sched_bindings, NULL, NULL);
+    if (status != RPC_S_OK)
+    {
+        WINE_ERR("RpcEpRegister error %#x\n", status);
+        return status;
+    }
+
+    status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
+    if (status != RPC_S_OK)
+    {
+        WINE_ERR("RpcServerListen error %#x\n", status);
+        return status;
+    }
+    return RPC_S_OK;
+}
+
+static void RPC_finish(void)
+{
+    RpcMgmtStopServerListening(NULL);
+    RpcEpUnregister(ITaskSchedulerService_v1_0_s_ifspec, sched_bindings, NULL);
+    RpcBindingVectorFree(&sched_bindings);
+    RpcServerUnregisterIf(NULL, NULL, FALSE);
+}
+
+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;
+
+    schedsvc_handle = RegisterServiceCtrlHandlerW(scheduleW, schedsvc_handler);
+    if (!schedsvc_handle)
+    {
+        WINE_ERR("RegisterServiceCtrlHandler error %d\n", GetLastError());
+        return;
+    }
+
+    done_event = CreateEventW(NULL, TRUE, FALSE, NULL);
+
+    schedsvc_update_status(SERVICE_RUNNING);
+
+    WaitForSingleObject(done_event, INFINITE);
+
+    RPC_finish();
+    schedsvc_update_status(SERVICE_STOPPED);
+
+    WINE_TRACE("exiting Task Scheduler Service\n");
+}
+
+void  __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len)
+{
+    return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr)
+{
+    HeapFree(GetProcessHeap(), 0, ptr);
+}
diff --git a/include/wine/schrpc.idl b/include/wine/schrpc.idl
new file mode 100644
index 0000000..c451082
--- /dev/null
+++ b/include/wine/schrpc.idl
@@ -0,0 +1,100 @@
+/*
+ * Task Scheduler Service definitions
+ *
+ * Copyright 2014 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+cpp_quote("#define SCHEDSVC_TRANSPORT {'n','c','a','l','r','p','c',0}")
+
+import "oaidl.idl";
+import "ocidl.idl";
+
+[
+    uuid(86d35949-83c9-4044-b424-db363231fd0c),
+    implicit_handle(handle_t rpc_handle),
+    version(1.0),
+    pointer_default(unique)
+]
+interface ITaskSchedulerService
+{
+    typedef struct _TASK_USER_CRED
+    {
+        [string] const WCHAR *user;
+        [string] const WCHAR *password;
+        DWORD flags;
+    } TASK_USER_CRED;
+
+    typedef struct _TASK_XML_ERROR_INFO
+    {
+        DWORD line, column;
+        [string] WCHAR *node;
+        [string] WCHAR *value;
+    } TASK_XML_ERROR_INFO;
+
+    typedef [string] WCHAR **TASK_NAMES;
+
+    HRESULT SchRpcHighestVersion([out] DWORD *version);
+    HRESULT SchRpcRegisterTask([in, string, unique] const WCHAR *path,
+                [in, string] const WCHAR *xml, [in] DWORD flags,
+                [in, string, unique] const WCHAR *sddl,
+                [in] DWORD task_logon_type, [in] DWORD n_creds,
+                [in, size_is(n_creds), unique] const TASK_USER_CRED *creds,
+                [out, string] WCHAR **actual_path,
+                [out] TASK_XML_ERROR_INFO **xml_error_info);
+    HRESULT SchRpcRetrieveTask([in, string] const WCHAR *path,
+                [in, string] const WCHAR *languages,
+                [in] unsigned long *n_languages, [out, string] WCHAR **xml);
+    HRESULT SchRpcCreateFolder([in, string] const WCHAR *path,
+                [in, string, unique] const WCHAR *sddl, [in] DWORD flags);
+    HRESULT SchRpcSetSecurity([in, string] const WCHAR *path,
+                [in, string] const WCHAR *sddl, [in] DWORD flags);
+    HRESULT SchRpcGetSecurity([in, string] const WCHAR *path,
+                [in] DWORD flags, [out, string] WCHAR **sddl);
+    HRESULT SchRpcEnumFolders([in, string] const WCHAR *path,
+                [in] DWORD flags, [in, out] DWORD *start_index,
+                [in] DWORD n_requested, [out] DWORD *n_names,
+                [out, size_is(,*n_names)] TASK_NAMES *names);
+    HRESULT SchRpcEnumTasks([in, string] const WCHAR *path,
+                [in] DWORD flags, [in, out] DWORD *start_index,
+                [in] DWORD n_requested, [out] DWORD *n_names,
+                [out, size_is(,*n_names)] TASK_NAMES *names);
+    HRESULT SchRpcEnumInstances([in, string, unique] const WCHAR *path,
+                [in] DWORD flags, [out] DWORD *n_guids,
+                [out, size_is(,*n_guids)] GUID **guids);
+    HRESULT SchRpcGetInstanceInfo([in] GUID guid, [out, string] WCHAR **path,
+                [out] DWORD *task_state, [out, string] WCHAR **action,
+                [out, string] WCHAR **info, [out] DWORD *n_instances,
+                [out, size_is(,*n_instances)] GUID **instances, [out] DWORD *pid);
+    HRESULT SchRpcStopInstance([in] GUID guid, [in] DWORD flags);
+    HRESULT SchRpcStop([in, string, unique] const WCHAR *path, [in] DWORD flags);
+    HRESULT SchRpcRun([in, string] const WCHAR *path,
+                [in] DWORD n_args, [in, size_is(n_args),unique] const WCHAR **args,
+                [in] DWORD flags, [in] DWORD session_id,
+                [in, unique, string] const WCHAR *user, [out] GUID *guid);
+    HRESULT SchRpcDelete([in, string] const WCHAR *path, [in] DWORD flags);
+    HRESULT SchRpcRename([in, string] const WCHAR *path, [in, string] const WCHAR *name, [in] DWORD flags);
+    HRESULT SchRpcScheduledRuntimes([in, string] const WCHAR *path,
+                [in, unique] SYSTEMTIME *start, [in, unique] SYSTEMTIME *end,
+                [in] DWORD flags, [in] DWORD n_requested, [out] DWORD *n_runtimes,
+                [out, size_is(,*n_runtimes)] SYSTEMTIME **runtimes);
+    HRESULT SchRpcGetLastRunInfo([in, string] const WCHAR *path,
+                [out] SYSTEMTIME *last_runtime, [out] DWORD *last_return_code);
+    HRESULT SchRpcGetTaskInfo([in, string] const WCHAR *path, [in] DWORD flags,
+                [out] DWORD *enabled, [out] DWORD *task_state);
+    HRESULT SchRpcGetNumberOfMissedRuns([in, string] const WCHAR *path, [out] DWORD *runs);
+    HRESULT SchRpcEnableTask([in, string] const WCHAR *path, [in] DWORD enabled);
+}
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 595d4b9..7486cfd 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -124,6 +124,7 @@ AddService=PlugPlay,0,PlugPlayService
 AddService=FontCache3.0.0.0,0,WPFFontCacheService
 AddService=LanmanServer,0,LanmanServerService
 AddService=FontCache,0,FontCacheService
+AddService=Schedule,0,TaskSchedulerService
 
 [DefaultInstall.NT.Services]
 AddService=BITS,0,BITSService
@@ -136,6 +137,7 @@ AddService=PlugPlay,0,PlugPlayService
 AddService=FontCache3.0.0.0,0,WPFFontCacheService
 AddService=LanmanServer,0,LanmanServerService
 AddService=FontCache,0,FontCacheService
+AddService=Schedule,0,TaskSchedulerService
 
 [DefaultInstall.ntamd64.Services]
 AddService=BITS,0,BITSService
@@ -148,6 +150,7 @@ AddService=PlugPlay,0,PlugPlayService
 AddService=FontCache3.0.0.0,0,WPFFontCacheService
 AddService=LanmanServer,0,LanmanServerService
 AddService=FontCache,0,FontCacheService
+AddService=Schedule,0,TaskSchedulerService
 
 [Strings]
 MciExtStr="Software\Microsoft\Windows NT\CurrentVersion\MCI Extensions"
@@ -3026,6 +3029,19 @@ ErrorControl=1
 HKR,Parameters,"ServiceDll",,"%11%\fntcache.dll"
 ;; HKLM,%CurrentVersionNT%\SvcHost,"netsvcs",0x00010008,"fontcache"
 
+[TaskSchedulerService]
+AddReg=TaskSchedulerServiceKeys
+Description="Task Scheduler"
+DisplayName="Task Scheduler"
+ServiceBinary="%11%\svchost.exe -k netsvcs"
+ServiceType=32
+StartType=3
+ErrorControl=1
+
+[TaskSchedulerServiceKeys]
+HKR,Parameters,"ServiceDll",,"%11%\schedsvc.dll"
+HKLM,%CurrentVersionNT%\SvcHost,"netsvcs",0x00010008,"Schedule"
+
 [Services]
 HKLM,%CurrentVersion%\RunServices,"winemenubuilder",2,"%11%\winemenubuilder.exe -a -r"
 HKLM,"System\CurrentControlSet\Services\Eventlog\Application",,16
-- 
1.8.5.5




More information about the wine-patches mailing list