private int HandleProjEvent(ref ProjFS.Event ev) { if (!this.ObtainProjFS(out ProjFS fs)) { return(-Errno.Constants.ENODEV); } // ignore events triggered by own process to prevent deadlocks if (this.IsProviderEvent(ev)) { return(0); } string triggeringProcessName = GetProcCmdline(ev.Pid); string relativePath = PtrToStringUTF8(ev.Path); Result result; if ((ev.Mask & ProjFS.Constants.PROJFS_ONDIR) != 0) { result = this.OnEnumerateDirectory( commandId: 0, relativePath: ConvertDotPath(relativePath), triggeringProcessId: ev.Pid, triggeringProcessName: triggeringProcessName); } else { byte[] providerId = new byte[PlaceholderIdLength]; byte[] contentId = new byte[PlaceholderIdLength]; result = fs.GetProjAttrs( relativePath, providerId, contentId); if (result == Result.Success) { result = this.OnGetFileStream( commandId: 0, relativePath: relativePath, providerId: providerId, contentId: contentId, triggeringProcessId: ev.Pid, triggeringProcessName: triggeringProcessName, fd: ev.Fd); } } return(-result.ToErrno()); }
private int HandleProjEvent(ref ProjFS.Event ev) { string triggeringProcessName = GetProcCmdline(ev.Pid); string relativePath = PtrToStringUTF8(ev.Path); Result result; if ((ev.Mask & ProjFS.Constants.PROJFS_ONDIR) != 0) { result = this.OnEnumerateDirectory( commandId: 0, relativePath: relativePath, triggeringProcessId: ev.Pid, triggeringProcessName: triggeringProcessName); } else { byte[] providerId = new byte[PlaceholderIdLength]; byte[] contentId = new byte[PlaceholderIdLength]; result = this.projfs.GetProjAttrs( relativePath, providerId, contentId); if (result == Result.Success) { result = this.OnGetFileStream( commandId: 0, relativePath: relativePath, providerId: providerId, contentId: contentId, triggeringProcessId: ev.Pid, triggeringProcessName: triggeringProcessName, fd: ev.Fd); } } return(-result.ToErrno()); }
private int HandlePermEvent(ref ProjFS.Event ev) { return(this.HandleNonProjEvent(ref ev, true)); }
private int HandleNotifyEvent(ref ProjFS.Event ev) { return(this.HandleNonProjEvent(ref ev, false)); }
private int HandleNonProjEvent(ref ProjFS.Event ev, bool perm) { // ignore events triggered by own process to prevent deadlocks if (this.IsProviderEvent(ev)) { return(perm ? (int)ProjFS.Constants.PROJFS_ALLOW : 0); } bool isLink = (ev.Mask & ProjFS.Constants.PROJFS_ONLINK) != 0; NotificationType nt; if ((ev.Mask & ProjFS.Constants.PROJFS_DELETE_PERM) != 0) { nt = NotificationType.PreDelete; } else if ((ev.Mask & ProjFS.Constants.PROJFS_CLOSE_WRITE) != 0) { nt = NotificationType.FileModified; } else if ((ev.Mask & ProjFS.Constants.PROJFS_CREATE) != 0 && !isLink) { nt = NotificationType.NewFileCreated; } else if ((ev.Mask & ProjFS.Constants.PROJFS_MOVE) != 0) { nt = NotificationType.FileRenamed; } else if ((ev.Mask & ProjFS.Constants.PROJFS_CREATE) != 0 && isLink) { nt = NotificationType.HardLinkCreated; } else if ((ev.Mask & ProjFS.Constants.PROJFS_OPEN_PERM) != 0) { nt = NotificationType.PreConvertToFull; } else { return(0); } bool isDirectory = (ev.Mask & ProjFS.Constants.PROJFS_ONDIR) != 0; string relativePath; if (nt == NotificationType.FileRenamed || nt == NotificationType.HardLinkCreated) { relativePath = PtrToStringUTF8(ev.TargetPath); } else { relativePath = PtrToStringUTF8(ev.Path); } Result result = this.OnNotifyOperation( relativePath: relativePath, isDirectory: isDirectory, notificationType: nt); int ret = -result.ToErrno(); if (perm) { if (ret == 0) { ret = (int)ProjFS.Constants.PROJFS_ALLOW; } else if (ret == -Errno.Constants.EPERM) { ret = (int)ProjFS.Constants.PROJFS_DENY; } } return(ret); }
private bool IsProviderEvent(ProjFS.Event ev) { return(ev.Pid == this.currentProcessId); }
private int HandleNonProjEvent(ref ProjFS.Event ev, bool perm) { NotificationType nt; if ((ev.Mask & ProjFS.Constants.PROJFS_DELETE_SELF) != 0) { nt = NotificationType.PreDelete; } else if ((ev.Mask & ProjFS.Constants.PROJFS_MOVE_SELF) != 0) { nt = NotificationType.FileRenamed; } else if ((ev.Mask & ProjFS.Constants.PROJFS_CREATE_SELF) != 0) { nt = NotificationType.NewFileCreated; } else { return(0); } bool isDirectory = (ev.Mask & ProjFS.Constants.PROJFS_ONDIR) != 0; string triggeringProcessName = GetProcCmdline(ev.Pid); byte[] providerId = new byte[PlaceholderIdLength]; byte[] contentId = new byte[PlaceholderIdLength]; string relativePath = PtrToStringUTF8(ev.Path); Result result = Result.Success; if (!isDirectory) { string currentRelativePath = relativePath; // TODO(Linux): can other intermediate file ops race us here? if (nt == NotificationType.FileRenamed) { currentRelativePath = PtrToStringUTF8(ev.TargetPath); } result = this.projfs.GetProjAttrs( currentRelativePath, providerId, contentId); } if (result == Result.Success) { result = this.OnNotifyOperation( commandId: 0, relativePath: relativePath, providerId: providerId, contentId: contentId, triggeringProcessId: ev.Pid, triggeringProcessName: triggeringProcessName, isDirectory: isDirectory, notificationType: nt); } int ret = -result.ToErrno(); if (perm) { if (ret == 0) { ret = (int)ProjFS.Constants.PROJFS_ALLOW; } else if (ret == -Errno.Constants.EPERM) { ret = (int)ProjFS.Constants.PROJFS_DENY; } } return(ret); }