예제 #1
0
 /// <summary>
 /// Try do delete files that have been decrypted temporarily, if the conditions are met for such a deletion,
 /// i.e. it is apparently not locked or in use etc.
 /// </summary>
 /// <param name="fileSystemState">The instance of FileSystemState where active files are recorded.</param>
 /// <param name="progress">The context where progress may be reported.</param>
 public static void PurgeActiveFiles(this FileSystemState fileSystemState, ProgressContext progress)
 {
     progress.NotifyLevelStart();
     fileSystemState.ForEach(ChangedEventMode.RaiseOnlyOnModified, (ActiveFile activeFile) =>
     {
         if (FileLock.IsLocked(activeFile.DecryptedFileInfo))
         {
             if (OS.Log.IsInfoEnabled)
             {
                 OS.Log.LogInfo("Not deleting '{0}' because it is marked as locked.".InvariantFormat(activeFile.DecryptedFileInfo.FullName));
             }
             return(activeFile);
         }
         if (activeFile.IsModified)
         {
             if (activeFile.Status.HasMask(ActiveFileStatus.NotShareable))
             {
                 activeFile = new ActiveFile(activeFile, activeFile.Status & ~ActiveFileStatus.NotShareable);
             }
             activeFile = CheckIfTimeToUpdate(activeFile, progress);
         }
         if (activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted))
         {
             activeFile = TryDelete(activeFile, progress);
         }
         return(activeFile);
     });
     progress.NotifyLevelFinished();
 }
예제 #2
0
 /// <summary>
 /// Enumerate all files listed as active, checking for status changes and take appropriate actions such as updating status
 /// in the FileSystemState, re-encrypting or deleting temporary plaintext copies.
 /// </summary>
 /// <param name="fileSystemState">The FileSystemState to enumerate and possibly update.</param>
 /// <param name="mode">Under what circumstances is the FileSystemState.Changed event raised.</param>
 /// <param name="progress">The ProgressContext to provide visual progress feedback via.</param>
 public static void CheckActiveFiles(this FileSystemState fileSystemState, ChangedEventMode mode, ProgressContext progress)
 {
     progress.NotifyLevelStart();
     progress.AddTotal(fileSystemState.ActiveFileCount);
     fileSystemState.ForEach(mode, (ActiveFile activeFile) =>
     {
         try
         {
             if (FileLock.IsLocked(activeFile.DecryptedFileInfo, activeFile.EncryptedFileInfo))
             {
                 return(activeFile);
             }
             if (OS.Current.UtcNow - activeFile.LastActivityTimeUtc <= new TimeSpan(0, 0, 5))
             {
                 return(activeFile);
             }
             activeFile = fileSystemState.CheckActiveFileActions(activeFile, progress);
             return(activeFile);
         }
         finally
         {
             progress.AddCount(1);
         }
     });
     progress.NotifyLevelFinished();
 }
예제 #3
0
        private async Task ProcessNew(File file, EofMessage eofMessage)
        {
            var tempPath = await BuildFile(file, eofMessage);

            if (tempPath is null)
            {
                return;
            }

            var filePath = file.GetFullPath();

            if (System.IO.File.Exists(filePath) && FileLock.IsLocked(filePath, checkWriteAccess: true))
            {
                WorkerLog.Instance.Warning($"File '{filePath}' is locked for writing. unable overwrite file");
            }
            else
            {
                WorkerLog.Instance.Information($"Decompressing file '{tempPath}'");
                await file.DecompressFrom(tempPath);

                WorkerLog.Instance.Information($"File decompressed to '{filePath}'");
                await MarkFileAsCompleted(file);
            }

            DeleteTempPath(tempPath);
        }
예제 #4
0
        public static void TestFileLockInvalidArguments()
        {
            IRuntimeFileInfo nullInfo = null;

            Assert.Throws <ArgumentNullException>(() => { FileLock.Lock(nullInfo); });
            Assert.Throws <ArgumentNullException>(() => { FileLock.IsLocked(nullInfo); });
            Assert.Throws <ArgumentNullException>(() => { FileLock.IsLocked(OS.Current.FileInfo(_fileExtPath), nullInfo); });
        }
예제 #5
0
 private void ClearRunDirectory()
 {
     foreach (var directory in Directory.GetDirectories(ScriptDirectory))
     {
         if (!FileLock.IsLocked(Path.Combine(directory, ".lock")))
         {
             Directory.Delete(directory, true);
         }
     }
 }
예제 #6
0
        public static void TestFileLockMethods()
        {
            IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_fileExtPath);

            Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file yet.");
            using (FileLock lock1 = FileLock.Lock(fileInfo))
            {
                Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should be now be a lock for this file.");
            }
            Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file again.");
        }
예제 #7
0
        public static void TestFileLockCaseSensitivity()
        {
            IRuntimeFileInfo fileInfo1 = OS.Current.FileInfo(_fileExtPath);
            IRuntimeFileInfo fileInfo2 = OS.Current.FileInfo(_fileExtPath.ToUpper(CultureInfo.InvariantCulture));

            Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file yet.");
            Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file yet.");
            using (FileLock lock1 = FileLock.Lock(fileInfo1))
            {
                Assert.That(FileLock.IsLocked(fileInfo1), Is.True, "There should be now be a lock for this file.");
                Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file still.");
            }
            Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file again.");
        }
예제 #8
0
        public static void TestFileLockWhenLocked()
        {
            IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_fileExtPath);

            Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file to start with.");
            using (FileLock lock1 = FileLock.Lock(fileInfo))
            {
                Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should be a lock for this file.");
                using (FileLock lock1a = FileLock.Lock(fileInfo))
                {
                    Assert.That(lock1a, Is.Null, "When trying to get a lock for a locked file, this should return null.");
                    Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should still be a lock for this file.");
                }
                Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should still be a lock for this file.");
            }
            Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file now.");
        }
예제 #9
0
        public static void TestSimple()
        {
            using (MemoryStream stream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("A short dummy stream")))
            {
                IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_davidCopperfieldTxtPath);
                using (LockingStream lockingStream = new LockingStream(fileInfo, stream))
                {
                    Assert.That(FileLock.IsLocked(fileInfo), "The file should be locked now.");
                    Assert.That(lockingStream.CanRead, "The stream should be readable.");
                    Assert.That(lockingStream.CanSeek, "The stream should be seekable.");
                    Assert.That(lockingStream.CanWrite, "The stream should be writeable.");
                    Assert.That(lockingStream.Length, Is.EqualTo("A short dummy stream".Length), "The length should be the same as the string.");

                    byte[] b    = new byte[1];
                    int    read = lockingStream.Read(b, 0, 1);
                    Assert.That(read, Is.EqualTo(1), "There should be one byte read.");
                    Assert.That(b[0], Is.EqualTo(Encoding.UTF8.GetBytes("A")[0]), "The byte read should be an 'A'.");
                    Assert.That(lockingStream.Position, Is.EqualTo(1), "After reading the first byte, the position should be at one.");

                    lockingStream.Write(b, 0, 1);
                    lockingStream.Position = 1;
                    read = lockingStream.Read(b, 0, 1);
                    Assert.That(read, Is.EqualTo(1), "There should be one byte read.");
                    Assert.That(b[0], Is.EqualTo(Encoding.UTF8.GetBytes("A")[0]), "The byte read should be an 'A'.");

                    lockingStream.Seek(-1, SeekOrigin.End);
                    Assert.That(lockingStream.Position, Is.EqualTo(lockingStream.Length - 1), "The position should be set by the Seek().");

                    lockingStream.SetLength(5);
                    lockingStream.Seek(0, SeekOrigin.End);
                    Assert.That(lockingStream.Position, Is.EqualTo(5), "After setting the length to 5, seeking to the end should set the position at 5.");

                    Assert.DoesNotThrow(() => { lockingStream.Flush(); }, "It's hard to test Flush() behavior here, not worth the trouble, but it should not throw!");
                }
                Assert.That(!FileLock.IsLocked(fileInfo), "The file should be unlocked now.");
                Assert.Throws <ObjectDisposedException>(() => { stream.Position = 0; }, "The underlying stream should be disposed.");
            }
        }
예제 #10
0
        private async Task ProcessChange(File file, EofMessage eofMessage)
        {
            var tempPath = await BuildFile(file, eofMessage);

            if (tempPath is null)
            {
                return;
            }

            var filePath = file.GetFullPath();

            if (System.IO.File.Exists(filePath) && !FileLock.IsLocked(filePath, checkWriteAccess: true))
            {
                WorkerLog.Instance.Information($"Applying delta to {filePath}");
                file.ApplyDelta(System.IO.File.ReadAllBytes(tempPath));
                await MarkFileAsCompleted(file);
            }
            else
            {
                WorkerLog.Instance.Warning($"File '{filePath}' does not exist or is locked for writing. unable to apply delta");
            }
            DeleteTempPath(tempPath);
        }
예제 #11
0
        public async Task <EofMessage> ProcessFile()
        {
            var path = _file.GetFullPath();

            EofMessage eofMessage = null;

            if (!string.IsNullOrWhiteSpace(path) && System.IO.File.Exists(path) && !FileLock.IsLocked(path))
            {
                try
                {
                    if (_file.IsNew())
                    {
                        eofMessage = await ProcessNewFile();
                    }
                    else
                    {
                        eofMessage = await ProcessChangedFile();
                    }
                }
                catch (Exception ex)
                {
                    WorkerLog.Instance.Error(ex, $"Unexpected error occured while disassembling file '{_file.Path}'");
                }
            }
            else
            {
                WorkerLog.Instance.Warning($"File '{path}' does not exist or is locked. File will not be processed");
            }

            if (eofMessage is null)
            {
                await _fileRepository.UpdateFileAsFailed(_file.Id);
            }

            return(eofMessage);
        }