using System; using System.Collections; using System.Runtime.InteropServices; using System.Threading; namespace System.IO { // Token: 0x02000123 RID: 291 internal class KeventWatcher : IFileWatcher { // Token: 0x06000A3C RID: 2620 RVA: 0x0001CA08 File Offset: 0x0001AC08 private KeventWatcher() { } // Token: 0x06000A3D RID: 2621 RVA: 0x0001CA10 File Offset: 0x0001AC10 public static bool GetInstance(out IFileWatcher watcher) { if (KeventWatcher.failed) { watcher = null; return false; } if (KeventWatcher.instance != null) { watcher = KeventWatcher.instance; return true; } KeventWatcher.watches = Hashtable.Synchronized(new Hashtable()); KeventWatcher.requests = Hashtable.Synchronized(new Hashtable()); KeventWatcher.conn = KeventWatcher.kqueue(); if (KeventWatcher.conn == -1) { KeventWatcher.failed = true; watcher = null; return false; } KeventWatcher.instance = new KeventWatcher(); watcher = KeventWatcher.instance; return true; } // Token: 0x06000A3E RID: 2622 RVA: 0x0001CA90 File Offset: 0x0001AC90 public void StartDispatching(FileSystemWatcher fsw) { KeventData keventData; lock (this) { if (KeventWatcher.thread == null) { KeventWatcher.thread = new Thread(new ThreadStart(this.Monitor)); KeventWatcher.thread.IsBackground = true; KeventWatcher.thread.Start(); } keventData = (KeventData)KeventWatcher.watches[fsw]; } if (keventData == null) { keventData = new KeventData(); keventData.FSW = fsw; keventData.Directory = fsw.FullPath; keventData.FileMask = fsw.MangledFilter; keventData.IncludeSubdirs = fsw.IncludeSubdirectories; keventData.Enabled = true; lock (this) { KeventWatcher.StartMonitoringDirectory(keventData); KeventWatcher.watches[fsw] = keventData; KeventWatcher.stop = false; } } } // Token: 0x06000A3F RID: 2623 RVA: 0x0001CB98 File Offset: 0x0001AD98 private static void StartMonitoringDirectory(KeventData data) { DirectoryInfo directoryInfo = new DirectoryInfo(data.Directory); if (data.DirEntries == null) { data.DirEntries = new Hashtable(); foreach (FileSystemInfo fileSystemInfo in directoryInfo.GetFileSystemInfos()) { data.DirEntries.Add(fileSystemInfo.FullName, new KeventFileData(fileSystemInfo, fileSystemInfo.LastAccessTime, fileSystemInfo.LastWriteTime)); } } int num = KeventWatcher.open(data.Directory, 0, 0); kevent kevent = default(kevent); kevent.udata = IntPtr.Zero; timespec timespec = default(timespec); timespec.tv_sec = 0; timespec.tv_usec = 0; if (num > 0) { kevent.ident = num; kevent.filter = -4; kevent.flags = 21; kevent.fflags = 31U; kevent.data = 0; kevent.udata = Marshal.StringToHGlobalAuto(data.Directory); kevent kevent2 = default(kevent); kevent2.udata = IntPtr.Zero; KeventWatcher.kevent(KeventWatcher.conn, ref kevent, 1, ref kevent2, 0, ref timespec); data.ev = kevent; KeventWatcher.requests[num] = data; } if (!data.IncludeSubdirs) { return; } } // Token: 0x06000A40 RID: 2624 RVA: 0x0001CCD8 File Offset: 0x0001AED8 public void StopDispatching(FileSystemWatcher fsw) { lock (this) { KeventData keventData = (KeventData)KeventWatcher.watches[fsw]; if (keventData != null) { KeventWatcher.StopMonitoringDirectory(keventData); KeventWatcher.watches.Remove(fsw); if (KeventWatcher.watches.Count == 0) { KeventWatcher.stop = true; } if (!keventData.IncludeSubdirs) { } } } } // Token: 0x06000A41 RID: 2625 RVA: 0x0001CD68 File Offset: 0x0001AF68 private static void StopMonitoringDirectory(KeventData data) { KeventWatcher.close(data.ev.ident); } // Token: 0x06000A42 RID: 2626 RVA: 0x0001CD7C File Offset: 0x0001AF7C private void Monitor() { while (!KeventWatcher.stop) { kevent kevent = default(kevent); kevent.udata = IntPtr.Zero; kevent kevent2 = default(kevent); kevent2.udata = IntPtr.Zero; timespec timespec = default(timespec); timespec.tv_sec = 0; timespec.tv_usec = 0; int num; lock (this) { num = KeventWatcher.kevent(KeventWatcher.conn, ref kevent2, 0, ref kevent, 1, ref timespec); } if (num > 0) { KeventData keventData = (KeventData)KeventWatcher.requests[kevent.ident]; KeventWatcher.StopMonitoringDirectory(keventData); KeventWatcher.StartMonitoringDirectory(keventData); this.ProcessEvent(kevent); } else { Thread.Sleep(500); } } lock (this) { KeventWatcher.thread = null; KeventWatcher.stop = false; } } // Token: 0x06000A43 RID: 2627 RVA: 0x0001CEA0 File Offset: 0x0001B0A0 private void ProcessEvent(kevent ev) { lock (this) { KeventData keventData = (KeventData)KeventWatcher.requests[ev.ident]; if (keventData.Enabled) { string text = string.Empty; FileSystemWatcher fsw = keventData.FSW; DirectoryInfo directoryInfo = new DirectoryInfo(keventData.Directory); FileSystemInfo fileSystemInfo = null; try { foreach (FileSystemInfo fileSystemInfo2 in directoryInfo.GetFileSystemInfos()) { if (keventData.DirEntries.ContainsKey(fileSystemInfo2.FullName) && fileSystemInfo2 is FileInfo) { KeventFileData keventFileData = (KeventFileData)keventData.DirEntries[fileSystemInfo2.FullName]; if (keventFileData.LastWriteTime != fileSystemInfo2.LastWriteTime) { text = fileSystemInfo2.Name; FileAction fileAction = FileAction.Modified; keventData.DirEntries[fileSystemInfo2.FullName] = new KeventFileData(fileSystemInfo2, fileSystemInfo2.LastAccessTime, fileSystemInfo2.LastWriteTime); if (fsw.IncludeSubdirectories && fileSystemInfo2 is DirectoryInfo) { keventData.Directory = text; KeventWatcher.requests[ev.ident] = keventData; this.ProcessEvent(ev); } this.PostEvent(text, fsw, fileAction, fileSystemInfo); } } } } catch (Exception) { } try { bool flag = true; while (flag) { foreach (object obj in keventData.DirEntries.Values) { KeventFileData keventFileData2 = (KeventFileData)obj; if (!File.Exists(keventFileData2.fsi.FullName) && !Directory.Exists(keventFileData2.fsi.FullName)) { text = keventFileData2.fsi.Name; FileAction fileAction = FileAction.Removed; keventData.DirEntries.Remove(keventFileData2.fsi.FullName); this.PostEvent(text, fsw, fileAction, fileSystemInfo); break; } } flag = false; } } catch (Exception) { } try { foreach (FileSystemInfo fileSystemInfo3 in directoryInfo.GetFileSystemInfos()) { if (!keventData.DirEntries.ContainsKey(fileSystemInfo3.FullName)) { fileSystemInfo = fileSystemInfo3; text = fileSystemInfo3.Name; FileAction fileAction = FileAction.Added; keventData.DirEntries[fileSystemInfo3.FullName] = new KeventFileData(fileSystemInfo3, fileSystemInfo3.LastAccessTime, fileSystemInfo3.LastWriteTime); this.PostEvent(text, fsw, fileAction, fileSystemInfo); } } } catch (Exception) { } } } } // Token: 0x06000A44 RID: 2628 RVA: 0x0001D1E8 File Offset: 0x0001B3E8 private void PostEvent(string filename, FileSystemWatcher fsw, FileAction fa, FileSystemInfo changedFsi) { RenamedEventArgs renamedEventArgs = null; if (fa == (FileAction)0) { return; } if (fsw.IncludeSubdirectories && fa == FileAction.Added && changedFsi is DirectoryInfo) { KeventData keventData = new KeventData(); keventData.FSW = fsw; keventData.Directory = changedFsi.FullName; keventData.FileMask = fsw.MangledFilter; keventData.IncludeSubdirs = fsw.IncludeSubdirectories; keventData.Enabled = true; lock (this) { KeventWatcher.StartMonitoringDirectory(keventData); } } if (!fsw.Pattern.IsMatch(filename, true)) { return; } lock (fsw) { fsw.DispatchEvents(fa, filename, ref renamedEventArgs); if (fsw.Waiting) { fsw.Waiting = false; global::System.Threading.Monitor.PulseAll(fsw); } } } // Token: 0x06000A45 RID: 2629 [DllImport("libc")] private static extern int open(string path, int flags, int mode_t); // Token: 0x06000A46 RID: 2630 [DllImport("libc")] private static extern int close(int fd); // Token: 0x06000A47 RID: 2631 [DllImport("libc")] private static extern int kqueue(); // Token: 0x06000A48 RID: 2632 [DllImport("libc")] private static extern int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist, int nevents, ref timespec ts); // Token: 0x040003B5 RID: 949 private static bool failed; // Token: 0x040003B6 RID: 950 private static KeventWatcher instance; // Token: 0x040003B7 RID: 951 private static Hashtable watches; // Token: 0x040003B8 RID: 952 private static Hashtable requests; // Token: 0x040003B9 RID: 953 private static Thread thread; // Token: 0x040003BA RID: 954 private static int conn; // Token: 0x040003BB RID: 955 private static bool stop; } }