dir = dir.getParentFile();
}
if (dir == null) {
throw new FileNotFoundException("No ancestor found for " + file);
}
Kernel32 klib = Kernel32.INSTANCE;
int mask = Kernel32.FILE_SHARE_READ
| Kernel32.FILE_SHARE_WRITE | Kernel32.FILE_SHARE_DELETE;
int flags = Kernel32.FILE_FLAG_BACKUP_SEMANTICS
| Kernel32.FILE_FLAG_OVERLAPPED;
HANDLE handle = klib.CreateFile(file.getAbsolutePath(),
Kernel32.FILE_LIST_DIRECTORY,
mask, null, Kernel32.OPEN_EXISTING,
flags, null);
if (Kernel32.INVALID_HANDLE_VALUE.equals(handle)) {
throw new IOException("Unable to open " + file + " ("
+ klib.GetLastError() + ")");
}
int notifyMask = convertMask(eventMask);
FileInfo finfo = new FileInfo(file, handle, notifyMask, recursive);
fileMap.put(file, finfo);
handleMap.put(handle, finfo);
// Existing port is returned
port = klib.CreateIoCompletionPort(handle, port, handle.getPointer(), 0);
if (Kernel32.INVALID_HANDLE_VALUE.equals(port)) {
throw new IOException("Unable to create/use I/O Completion port "
+ "for " + file + " ("
+ klib.GetLastError() + ")");
}
// TODO: use FileIOCompletionRoutine callback method instead of a
// dedicated thread
if (!klib.ReadDirectoryChangesW(handle, finfo.info, finfo.info.size(),
recursive, notifyMask, finfo.infoLength,
finfo.overlapped, null)) {
int err = klib.GetLastError();
throw new IOException("ReadDirectoryChangesW failed on "
+ finfo.file + ", handle " + handle
+ ": '" + getSystemError(err)
+ "' (" + err + ")");
}