Signed-off-by: Dmitry Timoshkov dmitry@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);