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());
        }
コード例 #2
0
        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());
        }
コード例 #3
0
 private int HandlePermEvent(ref ProjFS.Event ev)
 {
     return(this.HandleNonProjEvent(ref ev, true));
 }
コード例 #4
0
 private int HandleNotifyEvent(ref ProjFS.Event ev)
 {
     return(this.HandleNonProjEvent(ref ev, false));
 }
コード例 #5
0
        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);
        }
コード例 #6
0
 private bool IsProviderEvent(ProjFS.Event ev)
 {
     return(ev.Pid == this.currentProcessId);
 }
コード例 #7
0
        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);
        }