[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