schedsvc: Also watch for job file modifications.

Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Dmitry Timoshkov 2018-05-04 11:39:26 +08:00 committed by Alexandre Julliard
parent c130ec5678
commit f7d1e16183
3 changed files with 68 additions and 19 deletions

View File

@ -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];

View File

@ -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)
{

View File

@ -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;