[PATCH 2/4] schedsvc: Add support for task termination.

Dmitry Timoshkov dmitry at baikal.ru
Wed May 16 04:47:36 CDT 2018


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/schedsvc/atsvc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c
index 61771d87b3..7b3e4979fd 100644
--- a/dlls/schedsvc/atsvc.c
+++ b/dlls/schedsvc/atsvc.c
@@ -55,6 +55,8 @@ typedef struct
     SYSTEMTIME last_runtime;
 } FIXDLEN_DATA;
 
+#define MAX_INSTANCE_COUNT 32
+
 struct job_t
 {
     struct list entry;
@@ -62,6 +64,7 @@ struct job_t
     AT_ENUM info;
     FIXDLEN_DATA data;
     USHORT instance_count;
+    HANDLE process[MAX_INSTANCE_COUNT];
 };
 
 static LONG current_jobid = 1;
@@ -76,16 +79,72 @@ static CRITICAL_SECTION_DEBUG cs_debug =
 };
 static CRITICAL_SECTION at_job_list_section = { &cs_debug, -1, 0, 0, 0, 0 };
 
+static void update_job_status(struct job_t *job)
+{
+    HANDLE hfile;
+    DWORD try, size;
+    struct
+    {
+        UINT exit_code;
+        UINT status;
+        UINT flags;
+        SYSTEMTIME last_runtime;
+        WORD instance_count;
+    } state;
+
+    try = 1;
+    for (;;)
+    {
+        hfile = CreateFileW(job->name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+        if (hfile == INVALID_HANDLE_VALUE)
+        {
+            if (try++ >= 3)
+            {
+                ERR("Failed to update %s, error %u\n", debugstr_w(job->name), GetLastError());
+                return;
+            }
+            Sleep(100);
+        }
+    }
+
+    if (SetFilePointer(hfile, FIELD_OFFSET(FIXDLEN_DATA, exit_code), NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER)
+    {
+        state.exit_code = job->data.exit_code;
+        state.status = job->data.status;
+        state.flags = job->data.flags;
+        state.last_runtime = job->data.last_runtime;
+        state.instance_count = job->instance_count;
+        WriteFile(hfile, &state, sizeof(state), &size, NULL);
+    }
+
+    CloseHandle(hfile);
+}
+
 void check_task_state(void)
 {
     struct job_t *job;
+    WORD i;
 
     EnterCriticalSection(&at_job_list_section);
 
     LIST_FOR_EACH_ENTRY(job, &at_job_list, struct job_t, entry)
     {
         if (job->data.flags & 0x08000000)
-            FIXME("Terminate(%s): not implemented\n", debugstr_w(job->info.Command));
+        {
+            TRACE("terminating process %s\n", debugstr_w(job->info.Command));
+
+            for (i = 0; i < job->instance_count; i++)
+            {
+                TerminateProcess(job->process[i], 0);
+                CloseHandle(job->process[i]);
+            }
+
+            job->data.exit_code = 0;
+            job->data.status = SCHED_S_TASK_TERMINATED;
+            job->data.flags &= ~0x08000000;
+            job->instance_count = 0;
+            update_job_status(job);
+        }
         else if (job->data.flags & 0x04000000)
             FIXME("Run(%s): not implemented\n", debugstr_w(job->info.Command));
     }
@@ -339,6 +398,14 @@ static void free_job_info(AT_ENUM *info)
 
 static void free_job(struct job_t *job)
 {
+    WORD i;
+
+    for (i = 0; i < job->instance_count; i++)
+    {
+        TerminateProcess(job->process[i], 0);
+        CloseHandle(job->process[i]);
+    }
+
     free_job_info(&job->info);
     heap_free(job->name);
     heap_free(job);
-- 
2.16.3




More information about the wine-devel mailing list