Ejemplo n.º 1
0
        public override void OnReceive(Context context, Intent intent)
        {
            var success = intent.GetBooleanExtra(WifiManager.ExtraResultsUpdated, false);

            if (success)
            {
                ScanFinished?.Invoke(this, EventArgs.Empty);
            }
        }
Ejemplo n.º 2
0
        // Todo: prevFile isn't necessary. Instead store the features of the current scan to be used on the next.
        // That could cause sync problems so it needs to be investigated.
        private void NewRun(Scan scan, int index)
        {
            var deltas            = new double[CompiledFeatures.FeatureCount];
            var benchmarks        = new double[CompiledFeatures.FeatureCount];
            var now               = scan.CurrentFrame.DateTime;
            var fileImageBase     = scan.CurrentFrame.Bitmap;
            var prevFileImageBase = CompiledFeatures.UsesDupeCheck(now) ? scan.PreviousFrame.Bitmap : null;

            try
            {
                foreach (var cWatchZone in CompiledFeatures.CWatchZones)
                {
                    CropScan(ref deltas, ref benchmarks, now, fileImageBase, prevFileImageBase, cWatchZone);
                }
            }
            catch (Exception e)
            {
                scan.Dispose();
                Log.Error(e, "Error scanning frame.");
                if (IsVideoSourceRunning() && !IsScannerLocked)
                {
                    ScanningCount--;
                }
            }

            var scanEnd = TimeStamp.CurrentDateTime.Time;

            try
            {
                DeltaManager?.AddResult(index, scan, scanEnd, deltas, benchmarks);
                NewResult(this, new DeltaOutput(DeltaManager, index, CurrentFPS));

                ScanningCount--;

                ScanFinished?.Invoke(this, scan);

                //scan.Dispose();

                // It's on its own thread so running it here should be okay.
                if (index % Math.Ceiling(AverageFPS) == 0)
                {
                    RefreshBenchmarks();
                }

                if (index >= 32 && AverageFPS > 64 && !Restarting)
                {
                    Log.Warning("Framerate is abnormally high, usually an indicator the video feed is not active.");
                    Restart();
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Unknown Scanner Error.");
            }
        }
Ejemplo n.º 3
0
        public void PortScannerManager(IEnumerable <string> ipranges, IEnumerable <int> ports)
        {
            var manualEvents = new ManualResetEvent[MaxThreads];
            int j            = 0;

            for (int k = 0; k < MaxThreads; k++)
            {
                manualEvents[k] = new ManualResetEvent(true);
            }

            Logger.LogMessageToFile("Scanning LAN", "NetworkDiscovery");


            if (!MainForm.ShuttingDown)
            {
                j = 0;
                foreach (string shost in ipranges)
                {
                    for (int i = 0; i < 255; i++)
                    {
                        string ip = shost.Replace("x", i.ToString(CultureInfo.InvariantCulture));
                        int    k  = j;
                        manualEvents[k].Reset();
                        IPAddress ipa;
                        if (IPAddress.TryParse(ip, out ipa))
                        {
                            var scanner = new Thread(p => PortScanner(ports, ipa, manualEvents[k]));
                            scanner.Start();

                            j = WaitHandle.WaitAny(manualEvents);
                        }
                        if (MainForm.ShuttingDown)
                        {
                            break;
                        }
                    }
                    if (MainForm.ShuttingDown)
                    {
                        break;
                    }
                }
            }

            if (j > 0)
            {
                WaitHandle.WaitAll(manualEvents);
            }

            if (!MainForm.ShuttingDown)
            {
                ScanFinished?.Invoke(this, EventArgs.Empty);
            }
        }
Ejemplo n.º 4
0
        public void ARPScannerManager(IEnumerable <IPAddress> ips, IEnumerable <int> ports)
        {
            var manualEvents = new ManualResetEvent[MaxThreads];
            int j            = 0;

            for (int k = 0; k < MaxThreads; k++)
            {
                manualEvents[k] = new ManualResetEvent(true);
            }

            Logger.LogMessage("ARP Scan", "NetworkDiscovery");


            if (!MainForm.ShuttingDown)
            {
                j = 0;
                foreach (IPAddress ip in ips)
                {
                    int k = j;
                    manualEvents[k].Reset();
                    IPAddress ipa = ip;

                    var scanner = new Thread(p => PortScanner(ports, ipa, manualEvents[k]));
                    scanner.Start();

                    j = WaitHandle.WaitAny(manualEvents);

                    if (MainForm.ShuttingDown)
                    {
                        break;
                    }
                }
            }

            if (j > 0)
            {
                WaitHandle.WaitAll(manualEvents);
            }

            if (!MainForm.ShuttingDown)
            {
                ScanFinished?.Invoke(this, EventArgs.Empty);
            }
        }
Ejemplo n.º 5
0
 private void RaiseScanFinished(List <FlacFrameInformation> frames)
 {
     ScanFinished?.Invoke(this, new FlacPreScanFinishedEventArgs(frames));
 }
Ejemplo n.º 6
0
        private bool onEvent(KodiEventMessage e)
        {
            switch (e.Sender)
            {
            case "onAbortRequested":
                AbortRequested?.Invoke(e.Sender, new EventArgs());
                break;

            case "onCleanStarted":
                CleanStarted?.Invoke(e.Sender, new LibraryEventArgs(e.EventArgs[0]));
                break;

            case "onCleanFinished":
                CleanFinished?.Invoke(e.Sender, new LibraryEventArgs(e.EventArgs[0]));
                break;

            case "onDPMSActivated":
                DPMSActivated?.Invoke(e.Sender, new EventArgs());
                break;

            case "onDPMSDeactivated":
                DPMSDeactivated?.Invoke(e.Sender, new EventArgs());
                break;

            case "onDatabaseScanStarted":
                DatabaseScanStarted?.Invoke(e.Sender, new DatabaseEventArgs(e.EventArgs[0]));
                break;

            case "onDatabaseUpdated":
                DatabaseUpdated?.Invoke(e.Sender, new DatabaseEventArgs(e.EventArgs[0]));
                break;

            case "onNotification":
                Notification?.Invoke(e.Sender, new NotificationEventArgs(
                                         e.EventArgs[0], e.EventArgs[1], e.EventArgs[2]
                                         ));
                break;

            case "onScanStarted":
                ScanStarted?.Invoke(e.Sender, new LibraryEventArgs(e.EventArgs[0]));
                break;

            case "onScanFinished":
                ScanFinished?.Invoke(e.Sender, new LibraryEventArgs(e.EventArgs[0]));
                break;

            case "onScreensaverActivated":
                ScreensaverActivated?.Invoke(e.Sender, new EventArgs());
                break;

            case "onScreensaverDeactivated":
                ScreensaverDeactivated?.Invoke(e.Sender, new EventArgs());
                break;

            case "onSettingsChanged":
                SettingsChanged?.Invoke(e.Sender, new EventArgs());
                break;

            default:
                PyConsole.WriteLine(string.Format("Unknown event '{0}' not handled", e.Sender));
                return(false);
            }
            return(true);
        }
Ejemplo n.º 7
0
 private void OnScanFinished(ScanFinishedEventArgs e)
 => ScanFinished?.Invoke(this, e);
Ejemplo n.º 8
0
        public static void ClamScanFileFromRepo(DbFile file)
        {
            try
            {
                if (Context.ClamdVersion == null)
                {
                    Failed?.Invoke("clamd is not usable");
                    return;
                }

                if (clam == null)
                {
                    Failed?.Invoke("clamd is not initalized");
                }

                string   repoPath;
                AlgoEnum algorithm;

                if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                             file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                             file.Sha256[3].ToString(), file.Sha256[4].ToString(), file.Sha256 + ".gz")))
                {
                    repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                            file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                            file.Sha256[3].ToString(), file.Sha256[4].ToString(), file.Sha256 + ".gz");
                    algorithm = AlgoEnum.GZip;
                }
                else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                  file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                  file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                  file.Sha256 + ".bz2")))
                {
                    repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                            file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                            file.Sha256[3].ToString(), file.Sha256[4].ToString(), file.Sha256 + ".bz2");
                    algorithm = AlgoEnum.BZip2;
                }
                else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                  file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                  file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                  file.Sha256 + ".lzma")))
                {
                    repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                            file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                            file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                            file.Sha256 + ".lzma");
                    algorithm = AlgoEnum.LZMA;
                }
                else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                  file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                  file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                  file.Sha256 + ".lz")))
                {
                    repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                            file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                            file.Sha256[3].ToString(), file.Sha256[4].ToString(), file.Sha256 + ".lz");
                    algorithm = AlgoEnum.LZip;
                }
                else
                {
                    Failed?.Invoke($"Cannot find file with hash {file.Sha256} in the repository");
                    return;
                }

                ClamScanResult result  = null;
                Stream         zStream = null;

                if (Settings.Current.ClamdIsLocal)
                {
                    if (algorithm == AlgoEnum.LZMA || algorithm == AlgoEnum.LZip)
                    {
                        string     tmpFile = Path.Combine(Settings.Current.TemporaryFolder, Path.GetTempFileName());
                        FileStream outFs   = new FileStream(tmpFile, FileMode.Create, FileAccess.Write);
                        FileStream inFs    = new FileStream(repoPath, FileMode.Open, FileAccess.Read);

                        if (algorithm == AlgoEnum.LZMA)
                        {
                            byte[] properties = new byte[5];
                            inFs.Read(properties, 0, 5);
                            inFs.Seek(8, SeekOrigin.Current);
                            zStream = new LzmaStream(properties, inFs, inFs.Length - 13, file.Length);
                        }
                        else
                        {
                            zStream = new LZipStream(inFs, CompressionMode.Decompress);
                        }

                        UpdateProgress?.Invoke("Uncompressing file...", null, 0, 0);

                        #if DEBUG
                        stopwatch.Restart();
                        #endif
                        zStream.CopyTo(outFs);
                        zStream.Close();
                        outFs.Close();
                        #if DEBUG
                        stopwatch.Stop();
                        Console.WriteLine("Core.ClamScanFileFromRepo({0}): Uncompressing took {1} seconds", file,
                                          stopwatch.Elapsed.TotalSeconds);
                        #endif

                        UpdateProgress?.Invoke("Requesting local scan to clamd server...", null, 0, 0);

                        #if DEBUG
                        stopwatch.Restart();
                        #endif
                        Task.Run(async() => { result = await clam.ScanFileOnServerMultithreadedAsync(tmpFile); })
                        .Wait();
                        #if DEBUG
                        stopwatch.Stop();
                        Console.WriteLine("Core.ClamScanFileFromRepo({0}): Clamd took {1} seconds to scan", file,
                                          stopwatch.Elapsed.TotalSeconds);
                        #endif

                        File.Delete(tmpFile);
                    }
                    else
                    {
                        UpdateProgress?.Invoke("Requesting local scan to clamd server...", null, 0, 0);

                        #if DEBUG
                        stopwatch.Restart();
                        #endif
                        Task.Run(async() => { result = await clam.ScanFileOnServerMultithreadedAsync(repoPath); })
                        .Wait();
                        #if DEBUG
                        stopwatch.Stop();
                        Console.WriteLine("Core.ClamScanFileFromRepo({0}): Clamd took {1} seconds to scan", file,
                                          stopwatch.Elapsed.TotalSeconds);
                        #endif
                    }
                }
                else
                {
                    FileStream inFs = new FileStream(repoPath, FileMode.Open, FileAccess.Read);

                    switch (algorithm)
                    {
                    case AlgoEnum.GZip:
                        zStream = new GZipStream(inFs, CompressionMode.Decompress);
                        break;

                    case AlgoEnum.BZip2:
                        zStream = new BZip2Stream(inFs, CompressionMode.Decompress);
                        break;

                    case AlgoEnum.LZMA:
                        byte[] properties = new byte[5];
                        inFs.Read(properties, 0, 5);
                        inFs.Seek(8, SeekOrigin.Current);
                        zStream = new LzmaStream(properties, inFs, inFs.Length - 13, file.Length);
                        break;

                    case AlgoEnum.LZip:
                        zStream = new LZipStream(inFs, CompressionMode.Decompress);
                        break;
                    }

                    UpdateProgress?.Invoke("Uploading file to clamd server...", null, 0, 0);

                    #if DEBUG
                    stopwatch.Restart();
                    #endif
                    Task.Run(async() => { result = await clam.SendAndScanFileAsync(zStream); }).Wait();
                    #if DEBUG
                    stopwatch.Stop();
                    Console.WriteLine("Core.ClamScanFileFromRepo({0}): Clamd took {1} seconds to scan", file,
                                      stopwatch.Elapsed.TotalSeconds);
                    #endif
                    zStream.Close();
                }

                if (result.InfectedFiles != null && result.InfectedFiles.Count > 0)
                {
                    file.HasVirus = true;
                    file.Virus    = result.InfectedFiles[0].VirusName;
                }
                else if (file.HasVirus == null)
                {
                    // If no scan has been done, mark as false.
                    // If a positive has already existed don't overwrite it.
                    file.HasVirus = false;
                    file.Virus    = null;
                }

                file.ClamTime = DateTime.UtcNow;

                dbCore.DbOps.UpdateFile(file);

                ScanFinished?.Invoke(file);
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                Failed?.Invoke($"Exception {ex.Message} when calling clamd");
                #if DEBUG
                Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
                #endif
            }
        }
Ejemplo n.º 9
0
        public static void VirusTotalFileFromRepo(DbFile file)
        {
            try
            {
                if (!Context.VirusTotalEnabled)
                {
                    Failed?.Invoke("VirusTotal is not usable");

                    return;
                }

                if (vTotal == null)
                {
                    Failed?.Invoke("VirusTotal is not initalized");
                }

                FileReport fResult = null;

                UpdateProgress?.Invoke("Requesting existing report to VirusTotal", null, 0, 0);

            #if DEBUG
                stopwatch.Restart();
            #endif
                Task.Run(async() =>
                {
                    fResult = await vTotal.GetFileReportAsync(file.Sha256);
                }).Wait();
            #if DEBUG
                stopwatch.Stop();

                Console.WriteLine("Core.VirusTotalFileFromRepo({0}): VirusTotal took {1} seconds to answer for SHA256 request",
                                  file, stopwatch.Elapsed.TotalSeconds);
            #endif

                if (fResult.ResponseCode == FileReportResponseCode.NotPresent)
                {
                    Failed?.Invoke(fResult.VerboseMsg);

                    return;
                }

                if (fResult.ResponseCode != FileReportResponseCode.Queued)
                {
                    if (fResult.ResponseCode == FileReportResponseCode.Present)
                    {
                        if (fResult.Positives > 0)
                        {
                            file.HasVirus = true;

                            if (fResult.Scans != null)
                            {
                                foreach (KeyValuePair <string, ScanEngine> engine in fResult.Scans)
                                {
                                    if (!engine.Value.Detected)
                                    {
                                        continue;
                                    }

                                    file.Virus          = engine.Value.Result;
                                    file.VirusTotalTime = engine.Value.Update;
                                    dbCore.DbOps.UpdateFile(file);

                                    ScanFinished?.Invoke(file);

                                    return;
                                }
                            }
                        }
                        else
                        {
                            // If no scan has been done, mark as false.
                            // If a positive has already existed don't overwrite it.
                            file.HasVirus       = false;
                            file.Virus          = null;
                            file.VirusTotalTime = DateTime.UtcNow;

                            dbCore.DbOps.UpdateFile(file);

                            ScanFinished?.Invoke(file);

                            return;
                        }
                    }

                    string   repoPath;
                    AlgoEnum algorithm;

                    if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                 file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                 file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                 file.Sha256 + ".gz")))
                    {
                        repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                file.Sha256 + ".gz");

                        algorithm = AlgoEnum.GZip;
                    }
                    else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                      file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                      file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                      file.Sha256 + ".bz2")))
                    {
                        repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                file.Sha256 + ".bz2");

                        algorithm = AlgoEnum.BZip2;
                    }
                    else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                      file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                      file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                      file.Sha256 + ".lzma")))
                    {
                        repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                file.Sha256 + ".lzma");

                        algorithm = AlgoEnum.LZMA;
                    }
                    else if (File.Exists(Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                      file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                      file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                      file.Sha256 + ".lz")))
                    {
                        repoPath = Path.Combine(Settings.Current.RepositoryPath, file.Sha256[0].ToString(),
                                                file.Sha256[1].ToString(), file.Sha256[2].ToString(),
                                                file.Sha256[3].ToString(), file.Sha256[4].ToString(),
                                                file.Sha256 + ".lz");

                        algorithm = AlgoEnum.LZip;
                    }
                    else
                    {
                        Failed?.Invoke($"Cannot find file with hash {file.Sha256} in the repository");

                        return;
                    }

                    UpdateProgress?.Invoke("Uncompressing file...", null, 0, 0);

                    var    inFs    = new FileStream(repoPath, FileMode.Open, FileAccess.Read);
                    Stream zStream = null;

                    switch (algorithm)
                    {
                    case AlgoEnum.GZip:
                        zStream = new GZipStream(inFs, CompressionMode.Decompress);

                        break;

                    case AlgoEnum.BZip2:
                        zStream = new BZip2Stream(inFs, CompressionMode.Decompress);

                        break;

                    case AlgoEnum.LZMA:
                        byte[] properties = new byte[5];
                        inFs.Read(properties, 0, 5);
                        inFs.Seek(8, SeekOrigin.Current);
                        zStream = new LzmaStream(properties, inFs, inFs.Length - 13, file.Length);

                        break;

                    case AlgoEnum.LZip:
                        zStream = new LZipStream(inFs, CompressionMode.Decompress);

                        break;
                    }

                    ScanResult sResult = null;

                #if DEBUG
                    stopwatch.Restart();
                #endif

                    // Cannot use zStream directly, VirusTotal.NET requests the size *sigh*
                    string tmpFile = Path.Combine(Settings.Current.TemporaryFolder, Path.GetTempFileName());
                    var    outFs   = new FileStream(tmpFile, FileMode.Create, FileAccess.ReadWrite);
                    zStream?.CopyTo(outFs);
                    zStream?.Close();
                    outFs.Seek(0, SeekOrigin.Begin);
                #if DEBUG
                    stopwatch.Stop();

                    Console.WriteLine("Core.VirusTotalFileFromRepo({0}): Uncompressing took {1} seconds", file,
                                      stopwatch.Elapsed.TotalSeconds);
                #endif

                    UpdateProgress?.Invoke("Uploading file to VirusTotal...", null, 0, 0);

                #if DEBUG
                    stopwatch.Restart();
                #endif
                    Task.Run(async() =>
                    {
                        sResult = await vTotal.ScanFileAsync(outFs, file.Sha256); // Keep filename private, sorry!
                    }).Wait();
                #if DEBUG
                    stopwatch.Stop();

                    Console.WriteLine("Core.VirusTotalFileFromRepo({0}): Upload to VirusTotal took {1} seconds", file,
                                      stopwatch.Elapsed.TotalSeconds);
                #endif
                    outFs.Close();

                    File.Delete(tmpFile);

                    if (sResult == null ||
                        sResult.ResponseCode == ScanFileResponseCode.Error)
                    {
                        if (sResult == null)
                        {
                            Failed?.Invoke("Cannot send file to VirusTotal");
                        }
                        else
                        {
                            Failed(sResult.VerboseMsg);
                        }

                        return;
                    }

                    // Seems that we are faster than them, getting a lot of "not queued" responses...
                    Thread.Sleep(2500);

                    Task.Run(async() =>
                    {
                        fResult = await vTotal.GetFileReportAsync(file.Sha256);
                    }).Wait();
                }

                UpdateProgress?.Invoke("Waiting for VirusTotal analysis...", null, 0, 0);

            #if DEBUG
                stopwatch.Restart();
            #endif
                int counter = 0;

                while (fResult.ResponseCode == FileReportResponseCode.Queued)
                {
                    // Timeout...
                    if (counter == 10)
                    {
                        break;
                    }

                    // Wait 15 seconds so we fall in the 4 requests/minute
                    Thread.Sleep(15000);

                    Task.Run(async() =>
                    {
                        fResult = await vTotal.GetFileReportAsync(file.Sha256);
                    }).Wait();

                    counter++;
                }
            #if DEBUG
                stopwatch.Stop();

                Console.WriteLine("Core.VirusTotalFileFromRepo({0}): VirusTotal took {1} seconds to do the analysis",
                                  file, stopwatch.Elapsed.TotalSeconds);
            #endif

                if (fResult.ResponseCode != FileReportResponseCode.Present)
                {
                    Failed?.Invoke(fResult.VerboseMsg);

                    return;
                }

                if (fResult.Positives > 0)
                {
                    file.HasVirus = true;

                    if (fResult.Scans == null)
                    {
                        return;
                    }

                    foreach (KeyValuePair <string, ScanEngine> engine in fResult.Scans)
                    {
                        if (!engine.Value.Detected)
                        {
                            continue;
                        }

                        file.Virus          = engine.Value.Result;
                        file.VirusTotalTime = engine.Value.Update;
                        dbCore.DbOps.UpdateFile(file);

                        ScanFinished?.Invoke(file);

                        return;
                    }
                }
                else
                {
                    // If no scan has been done, mark as false.
                    // If a positive has already existed don't overwrite it.
                    file.HasVirus       = false;
                    file.Virus          = null;
                    file.VirusTotalTime = DateTime.UtcNow;

                    dbCore.DbOps.UpdateFile(file);

                    ScanFinished?.Invoke(file);
                }
            }
            catch (Exception ex)
            {
                Failed?.Invoke($"Exception {ex.InnerException.Message} when calling VirusTotal");
            #if DEBUG
                Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
            #endif
            }
        }