예제 #1
0
        DokanError IDokanOperations.FindFiles(string fileName, out IList <FileInformation> files, DokanFileInfo info)
        {
            Log("FindFiles:{0}", fileName);

            var dircache = _cache.Get(fileName) as Tuple <DateTime, IList <FileInformation> >;

            if (dircache != null)
            {
                files = (dircache).Item2;
                Log("CacheHit:{0}", fileName);
                return(DokanError.ErrorSuccess);
            }


            byte[] handle;
            try
            {
                handle = _sftpSession.RequestOpenDir(GetUnixPath(fileName));
            }
            catch (SftpPermissionDeniedException)
            {
                files = null;
                return(DokanError.ErrorAccessDenied);
            }


            files = new List <FileInformation>();
            for (var sftpFiles = _sftpSession.RequestReadDir(handle);
                 sftpFiles != null;
                 sftpFiles = _sftpSession.RequestReadDir(handle))
            {
                (files as List <FileInformation>).AddRange(sftpFiles.Select(
                                                               file =>
                {
                    var sftpFileAttributes = file.Value;
                    if (sftpFileAttributes.IsSymbolicLink)
                    {
                        sftpFileAttributes = _sftpSession.RequestStat(
                            GetUnixPath(String.Format("{0}{1}", fileName, file.Key)), true) ??
                                             file.Value;
                    }


                    var fileInformation = new FileInformation
                    {
                        Attributes =
                            FileAttributes.NotContentIndexed,
                        CreationTime
                            =
                                sftpFileAttributes
                                .
                                LastWriteTime,
                        FileName
                            =
                                file.Key
                            ,
                        LastAccessTime
                            =
                                sftpFileAttributes
                                .
                                LastAccessTime,
                        LastWriteTime
                            =
                                sftpFileAttributes
                                .
                                LastWriteTime,
                        Length
                            =
                                sftpFileAttributes
                                .
                                Size
                    };
                    if (sftpFileAttributes.IsDirectory)
                    {
                        fileInformation.Attributes
                            |=
                                FileAttributes.
                                Directory;
                        fileInformation.Length = 0;
                    }
                    else
                    {
                        fileInformation.Attributes |= FileAttributes.Normal;
                    }
                    if (file.Key[0] == '.')
                    {
                        fileInformation.Attributes
                            |=
                                FileAttributes.
                                Hidden;
                    }

                    if (
                        !UserCanWrite(
                            sftpFileAttributes))
                    {
                        fileInformation.Attributes
                            |=
                                FileAttributes.
                                ReadOnly;
                    }
                    if (_useOfflineAttribute)
                    {
                        fileInformation.Attributes
                            |=
                                FileAttributes.
                                Offline;
                    }
                    return(fileInformation);
                }));



                int timeout = Math.Max(_attributeCacheTimeout + 2, _attributeCacheTimeout + sftpFiles.Length / 10);

                foreach (
                    var file in
                    sftpFiles.Where(
                        pair => !pair.Value.IsSymbolicLink))
                {
                    _cache.Set(GetUnixPath(String.Format("{0}{1}", fileName, file.Key)), file.Value,
                               DateTimeOffset.UtcNow.AddSeconds(timeout));
                }
            }


            _sftpSession.RequestClose(handle);


            _cache.Add(fileName, new Tuple <DateTime, IList <FileInformation> >(
                           (info.Context as SftpContext).Attributes.LastWriteTime,
                           files),
                       DateTimeOffset.UtcNow.AddSeconds(Math.Max(_attributeCacheTimeout,
                                                                 Math.Min(files.Count, _directoryCacheTimeout))));

            return(DokanError.ErrorSuccess);
        }