예제 #1
0
        public async Task UnlockFromQuarantine(FileScan scan)
        {
            await this.quarantine.UnlockFromQuarantine(scan);

            this.database.Update(scan);
            this.database.Persist();
        }
예제 #2
0
        private void HandleScans()
        {
            while (!this.token.Token.IsCancellationRequested)
            {
                try
                {
                    string path = this.queue.Take(this.token.Token);
                    string hash = this.hasher.HashSha256(path);

                    Report report = this.database.GetOrInsertReport(hash);

                    FileScan scan = new FileScan(path, report);
                    scan = this.ReconcileScan(scan);

                    if (scan.Report.State != ReportState.Scanned)
                    {
                        this.ScanAndReport(scan);
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                }
            }
        }
예제 #3
0
        public async Task LockInQuarantine(FileScan scan)
        {
            await this.quarantine.LockToQuarantine(scan);

            this.database.Update(scan);
            this.database.Persist();
        }
예제 #4
0
        public void Remove(FileScan scan)
        {
            this.database.Remove(scan);

            lock (this.mutex)
            {
                this.Scans.Remove(scan);
            }
        }
예제 #5
0
        private void CreateScan(FileScan scan)
        {
            lock (this.mutex)
            {
                this.Scans.Add(scan);
            }

            this.OnScanCreated?.Invoke(scan);
        }
예제 #6
0
 private void ReplaceScan(int id, FileScan scan)
 {
     lock (this.mutex)
     {
         int index = this.Scans.FindIndex(s => s.Id == id);
         if (index != -1)
         {
             this.Scans[index] = scan;
         }
     }
     this.OnScanUpdated?.Invoke(scan);
 }
예제 #7
0
        private void ScanAndReport(FileScan scan)
        {
            var uploadSource = Observable.If(
                () => scan.Report.State == ReportState.WaitingForScan,
                this.client.UploadFile(scan.Path)
                .SubscribeOn(Scheduler.Default)
                .Catch((Exception ex) => {
                return(Observable.Throw <FileScanResult>(ex).DelaySubscription(TimeSpan.FromSeconds(30)));
            })
                .Retry(),
                Observable.Return(new FileScanResult())
                );

            var reportSource = uploadSource.SelectMany(result =>
            {
                return(this.client.GetFileReport(scan.Report.Hash)
                       .SelectMany(report =>
                {
                    if (report?.ResponseCode == "-2" && scan.Report.State == ReportState.WaitingForScan)
                    {
                        scan.Report.State = ReportState.QueuedForAnalysis;
                        this.database.Update(scan.Report);
                        this.OnScanUpdated?.Invoke(scan);
                    }

                    if (report == null || report.Scans == null)
                    {
                        return Observable.Throw <FileReportResult>(new Exception("Not ready yet"));
                    }
                    return Observable.Return(report);
                })
                       .Catch((Exception ex) =>
                {
                    return Observable.Throw <FileReportResult>(ex).DelaySubscription(TimeSpan.FromSeconds(30));
                })
                       .Retry());
            });

            this.manager += reportSource
                            .Subscribe(result => {
                scan.Report.Result = result;
                scan.Report.State  = ReportState.Scanned;
                this.database.Update(scan.Report);
                this.OnScanUpdated?.Invoke(scan);
            });
        }
예제 #8
0
        private FileScan ReconcileScan(FileScan scan)
        {
            var existingScan = this.database.GetScan(scan.Path);

            scan.Size = new FileInfo(scan.Path).Length;

            if (existingScan != null)
            {
                existingScan.Size   = scan.Size;
                existingScan.Report = scan.Report;
                this.database.Update(existingScan);
                this.OnScanReplaced?.Invoke(existingScan.Id, existingScan);
                return(existingScan);
            }
            else
            {
                this.database.Insert(scan);
                this.OnScanCreated?.Invoke(scan);
                return(scan);
            }
        }
예제 #9
0
 private void UpdateScan(FileScan scan)
 {
     this.OnScanUpdated?.Invoke(scan);
 }