2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
\r
9 #ifdef HAVE_NOTIFY_WIN32
\r
11 # define WIN32_LEAN_AND_MEAN
\r
12 # include <windows.h>
\r
13 # undef WIN32_LEAN_AND_MEAN
\r
14 # include <process.h>
\r
16 # include "ecore_file_private.h"
\r
19 typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32;
\r
20 typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data;
\r
22 /* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */
\r
23 # define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096
\r
24 # define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x))
\r
26 struct _Ecore_File_Monitor_Win32_Data
\r
28 char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE];
\r
29 OVERLAPPED overlapped;
\r
32 Ecore_File_Monitor *monitor;
\r
33 Ecore_Win32_Handler *h;
\r
38 struct _Ecore_File_Monitor_Win32
\r
40 Ecore_File_Monitor monitor;
\r
41 Ecore_File_Monitor_Win32_Data *file;
\r
42 Ecore_File_Monitor_Win32_Data *dir;
\r
45 static Ecore_File_Monitor *_monitors = NULL;
\r
47 static int _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh);
\r
50 static Ecore_File_Monitor_Win32_Data *
\r
51 _ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type)
\r
53 Ecore_File_Monitor_Win32_Data *md;
\r
56 md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data));
\r
57 if (!md) return NULL;
\r
59 md->handle = CreateFile(monitor->path,
\r
60 FILE_LIST_DIRECTORY,
\r
65 FILE_FLAG_BACKUP_SEMANTICS |
\r
66 FILE_FLAG_OVERLAPPED,
\r
68 if (md->handle == INVALID_HANDLE_VALUE)
\r
71 md->event = CreateEvent(NULL, FALSE, FALSE, NULL);
\r
75 ZeroMemory (&md->overlapped, sizeof(md->overlapped));
\r
76 md->overlapped.hEvent = md->event;
\r
78 filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;
\r
80 FILE_NOTIFY_CHANGE_ATTRIBUTES |
\r
81 FILE_NOTIFY_CHANGE_SIZE |
\r
82 FILE_NOTIFY_CHANGE_LAST_WRITE |
\r
83 FILE_NOTIFY_CHANGE_LAST_ACCESS |
\r
84 FILE_NOTIFY_CHANGE_CREATION |
\r
85 FILE_NOTIFY_CHANGE_SECURITY;
\r
87 if (!ReadDirectoryChangesW(md->handle,
\r
89 ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,
\r
97 md->h = ecore_main_win32_handler_add(md->event,
\r
98 _ecore_file_monitor_win32_cb,
\r
103 md->monitor = monitor;
\r
109 CloseHandle(md->event);
\r
111 CloseHandle(md->handle);
\r
119 _ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md)
\r
123 CloseHandle(md->event);
\r
124 CloseHandle (md->handle);
\r
129 _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh)
\r
131 char filename[PATH_MAX];
\r
132 PFILE_NOTIFY_INFORMATION fni;
\r
133 Ecore_File_Monitor_Win32_Data *md;
\r
139 Ecore_File_Event event = ECORE_FILE_EVENT_NONE;
\r
141 md = (Ecore_File_Monitor_Win32_Data *)data;
\r
143 if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE))
\r
146 fni = (PFILE_NOTIFY_INFORMATION)md->buffer;
\r
150 offset = fni->NextEntryOffset;
\r
152 wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1));
\r
156 memcpy(wname, fni->FileName, fni->FileNameLength);
\r
157 wname[fni->FileNameLength]='\0';
\r
158 name = evil_wchar_to_char(wname);
\r
163 _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name);
\r
166 switch (fni->Action)
\r
168 case FILE_ACTION_ADDED:
\r
170 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
\r
172 event = ECORE_FILE_EVENT_CREATED_FILE;
\r
174 case FILE_ACTION_REMOVED:
\r
176 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
\r
178 event = ECORE_FILE_EVENT_DELETED_FILE;
\r
180 case FILE_ACTION_MODIFIED:
\r
182 event = ECORE_FILE_EVENT_MODIFIED;
\r
184 case FILE_ACTION_RENAMED_OLD_NAME:
\r
186 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
\r
188 event = ECORE_FILE_EVENT_DELETED_FILE;
\r
190 case FILE_ACTION_RENAMED_NEW_NAME:
\r
192 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
\r
194 event = ECORE_FILE_EVENT_CREATED_FILE;
\r
197 fprintf(stderr, "unknown event\n");
\r
198 event = ECORE_FILE_EVENT_NONE;
\r
201 if (event != ECORE_FILE_EVENT_NONE)
\r
202 md->monitor->func(md->monitor->data, md->monitor, event, filename);
\r
204 fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset);
\r
207 filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;
\r
209 FILE_NOTIFY_CHANGE_ATTRIBUTES |
\r
210 FILE_NOTIFY_CHANGE_SIZE |
\r
211 FILE_NOTIFY_CHANGE_LAST_WRITE |
\r
212 FILE_NOTIFY_CHANGE_LAST_ACCESS |
\r
213 FILE_NOTIFY_CHANGE_CREATION |
\r
214 FILE_NOTIFY_CHANGE_SECURITY;
\r
216 ReadDirectoryChangesW(md->handle,
\r
218 ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,
\r
228 ecore_file_monitor_win32_init(void)
\r
234 ecore_file_monitor_win32_shutdown(void)
\r
239 Ecore_File_Monitor *
\r
240 ecore_file_monitor_win32_add(const char *path,
\r
241 void (*func) (void *data, Ecore_File_Monitor *em,
\r
242 Ecore_File_Event event,
\r
246 Ecore_File_Monitor_Win32 *m;
\r
247 Ecore_File_Monitor *em;
\r
250 if (!path || (*path == '\0')) return NULL;
\r
251 if (!ecore_file_exists(path) || !ecore_file_is_dir(path))
\r
253 if (!func) return NULL;
\r
255 em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32));
\r
256 if (!em) return NULL;
\r
261 em->path = strdup(path);
\r
267 len = strlen(em->path);
\r
268 if (em->path[len - 1] == '/' || em->path[len - 1] == '\\')
\r
269 em->path[len - 1] = '\0';
\r
271 m = ECORE_FILE_MONITOR_WIN32(em);
\r
273 m->file = _ecore_file_monitor_win32_data_new(em, 0);
\r
281 m->dir = _ecore_file_monitor_win32_data_new(em, 1);
\r
284 _ecore_file_monitor_win32_data_free(m->file);
\r
290 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
\r
296 ecore_file_monitor_win32_del(Ecore_File_Monitor *em)
\r
298 Ecore_File_Monitor_Win32 *m;
\r
303 m = ECORE_FILE_MONITOR_WIN32(em);
\r
304 _ecore_file_monitor_win32_data_free(m->dir);
\r
305 _ecore_file_monitor_win32_data_free(m->file);
\r