Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/schedsvc/atsvc.c | 74 ++++++++++++++++++++++++++++++---------- dlls/schedsvc/schedsvc_private.h | 1 + dlls/schedsvc/svc_main.c | 12 ++++++- 3 files changed, 68 insertions(+), 19 deletions(-)
diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c index e7e59a4c0a..53a18fd682 100644 --- a/dlls/schedsvc/atsvc.c +++ b/dlls/schedsvc/atsvc.c @@ -269,15 +269,12 @@ static BOOL load_job_data(const char *data, DWORD size, AT_ENUM *info) return TRUE; }
-void add_job(const WCHAR *name) +static BOOL load_job(const WCHAR *name, AT_ENUM *info) { HANDLE file, mapping; DWORD size, try; void *data; - struct job_t *job; - - job = heap_alloc_zero(sizeof(*job)); - if (!job) return; + BOOL ret = FALSE;
try = 1; for (;;) @@ -304,14 +301,7 @@ void add_job(const WCHAR *name) data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); if (data) { - if (load_job_data(data, size, &job->info)) - { - EnterCriticalSection(&at_job_list_section); - job->name = heap_strdupW(name); - job->info.JobId = current_jobid++; - list_add_tail(&at_job_list, &job->entry); - LeaveCriticalSection(&at_job_list_section); - } + ret = load_job_data(data, size, info); UnmapViewOfFile(data); }
@@ -320,11 +310,39 @@ void add_job(const WCHAR *name) break; }
- if (!job->info.JobId) + return ret; +} + +static void free_job_info(AT_ENUM *info) +{ + heap_free(info->Command); +} + +static void free_job(struct job_t *job) +{ + free_job_info(&job->info); + heap_free(job->name); + heap_free(job); +} + +void add_job(const WCHAR *name) +{ + struct job_t *job; + + job = heap_alloc_zero(sizeof(*job)); + if (!job) return; + + if (!load_job(name, &job->info)) { - heap_free(job->info.Command); - heap_free(job); + free_job(job); + return; } + + EnterCriticalSection(&at_job_list_section); + job->name = heap_strdupW(name); + job->info.JobId = current_jobid++; + list_add_tail(&at_job_list, &job->entry); + LeaveCriticalSection(&at_job_list_section); }
static BOOL write_signature(HANDLE hfile) @@ -523,12 +541,32 @@ void remove_job(const WCHAR *name) if (job) { list_remove(&job->entry); - heap_free(job->name); - heap_free(job); + free_job(job); } LeaveCriticalSection(&at_job_list_section); }
+void modify_job(const WCHAR *name) +{ + AT_ENUM info; + + if (load_job(name, &info)) + { + struct job_t *job; + + EnterCriticalSection(&at_job_list_section); + job = find_job(0, name); + if (job) + { + free_job_info(&job->info); + job->info = info; + } + else + free_job_info(&info); + LeaveCriticalSection(&at_job_list_section); + } +} + DWORD __cdecl NetrJobAdd(ATSVC_HANDLE server_name, AT_INFO *info, DWORD *jobid) { WCHAR windir[MAX_PATH]; diff --git a/dlls/schedsvc/schedsvc_private.h b/dlls/schedsvc/schedsvc_private.h index 215bba003e..c0aa188fda 100644 --- a/dlls/schedsvc/schedsvc_private.h +++ b/dlls/schedsvc/schedsvc_private.h @@ -25,6 +25,7 @@ void schedsvc_auto_start(void) DECLSPEC_HIDDEN; void add_job(const WCHAR *name) DECLSPEC_HIDDEN; void remove_job(const WCHAR *name) DECLSPEC_HIDDEN; +void modify_job(const WCHAR *name) DECLSPEC_HIDDEN;
static inline WCHAR *heap_strdupW(const WCHAR *src) { diff --git a/dlls/schedsvc/svc_main.c b/dlls/schedsvc/svc_main.c index fb7732c1d9..ba8de0430f 100644 --- a/dlls/schedsvc/svc_main.c +++ b/dlls/schedsvc/svc_main.c @@ -78,7 +78,8 @@ static DWORD WINAPI tasks_monitor_thread(void *arg) memset(&info, 0, sizeof(info));
ret = ReadDirectoryChangesW(htasks, &info, sizeof(info), FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, NULL); + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, + NULL, &ov, NULL); if (!ret) break;
events[0] = done_event; @@ -106,6 +107,15 @@ static DWORD WINAPI tasks_monitor_thread(void *arg) remove_job(path); break;
+ case FILE_ACTION_MODIFIED: + TRACE("FILE_ACTION_MODIFIED %s\n", debugstr_w(info.data.FileName)); + + GetWindowsDirectoryW(path, MAX_PATH); + lstrcatW(path, tasksW); + lstrcatW(path, info.data.FileName); + modify_job(path); + break; + default: FIXME("%s: action %#x not handled\n", debugstr_w(info.data.FileName), info.data.Action); break;