2022-03-17 18:43:01 +01:00
|
|
|
#include <windows.h>
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
struct dirmonitor_internal {
|
2022-03-17 18:43:01 +01:00
|
|
|
HANDLE handle;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int buffer_size) {
|
|
|
|
HANDLE handle = monitor->handle;
|
|
|
|
if (handle && handle != INVALID_HANDLE_VALUE) {
|
|
|
|
DWORD bytes_transferred;
|
|
|
|
if (ReadDirectoryChangesW(handle, buffer, buffer_size, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, &bytes_transferred, NULL, NULL) == 0)
|
|
|
|
return 0;
|
|
|
|
return bytes_transferred;
|
|
|
|
}
|
|
|
|
return 0;
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
struct dirmonitor* init_dirmonitor() {
|
2022-10-11 02:40:41 +02:00
|
|
|
return calloc(1, sizeof(struct dirmonitor_internal));
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
static void close_monitor_handle(struct dirmonitor_internal* monitor) {
|
|
|
|
if (monitor->handle && monitor->handle != INVALID_HANDLE_VALUE) {
|
|
|
|
HANDLE handle = monitor->handle;
|
|
|
|
monitor->handle = NULL;
|
|
|
|
CancelIoEx(handle, NULL);
|
|
|
|
CloseHandle(handle);
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
2022-04-24 19:40:58 +02:00
|
|
|
}
|
2022-03-17 18:43:01 +01:00
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
void deinit_dirmonitor(struct dirmonitor_internal* monitor) {
|
|
|
|
close_monitor_handle(monitor);
|
|
|
|
}
|
2022-03-17 18:43:01 +01:00
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int buffer_size, int (*change_callback)(int, const char*, void*), void* data) {
|
|
|
|
for (FILE_NOTIFY_INFORMATION* info = (FILE_NOTIFY_INFORMATION*)buffer; (char*)info < buffer + buffer_size; info = (FILE_NOTIFY_INFORMATION*)(((char*)info) + info->NextEntryOffset)) {
|
2022-11-16 04:23:45 +01:00
|
|
|
char transform_buffer[MAX_PATH*4];
|
|
|
|
int count = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)info->FileName, info->FileNameLength, transform_buffer, MAX_PATH*4 - 1, NULL, NULL);
|
2022-06-23 23:43:49 +02:00
|
|
|
change_callback(count, transform_buffer, data);
|
2022-03-17 18:43:01 +01:00
|
|
|
if (!info->NextEntryOffset)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) {
|
2022-03-17 18:43:01 +01:00
|
|
|
close_monitor_handle(monitor);
|
2022-04-24 19:40:58 +02:00
|
|
|
monitor->handle = CreateFileA(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
|
|
return !monitor->handle || monitor->handle == INVALID_HANDLE_VALUE ? -1 : 1;
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
void remove_dirmonitor(struct dirmonitor_internal* monitor, int fd) {
|
2022-03-17 18:43:01 +01:00
|
|
|
close_monitor_handle(monitor);
|
2022-04-02 23:03:29 +02:00
|
|
|
}
|
2022-10-11 02:40:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
int get_mode_dirmonitor() { return 1; }
|