예제 #1
0
        public void ScanFolderForFilesShouldAddFiles()
        {
            // Arrange
            var directoryProvider = new Mock <IDirectoryProvider>();
            var fileProvider      = new Mock <IIsoFileProvider>();

            fileProvider.Setup(m => m.GetIsoFile(@"D:\file01.txt")).Returns(new IsoFile {
                Name = "file01.txt"
            });
            fileProvider.Setup(m => m.GetIsoFile(@"D:\file02.txt")).Returns(new IsoFile {
                Name = "file02.txt"
            });
            fileProvider.Setup(m => m.GetIsoFile(@"D:\file03.txt")).Returns(new IsoFile {
                Name = "file03.txt"
            });
            directoryProvider.Setup(m => m.GetDirectories(It.IsAny <string>())).Returns(new string[0]);
            directoryProvider.Setup(m => m.GetFiles(@"D:\", It.IsAny <string>())).Returns(new string[] { @"D:\file01.txt", @"D:\file02.txt", @"D:\file03.txt" });
            var            fileScanner = new FileScanner(directoryProvider.Object, fileProvider.Object);
            IsoFolder      rootFolder;
            string         driveLetter    = "D";
            FileScanResult fileScanResult = new FileScanResult();

            // Act
            rootFolder = fileScanner.ScanFolderForFiles(driveLetter, fileScanResult, null);

            // Assert
            Assert.AreEqual(3, rootFolder.ChildFiles.Count);
            Assert.AreEqual(0, rootFolder.ChildFolders.Count);
            Assert.AreEqual("file01.txt", rootFolder.ChildFiles.ToList()[0].Name);
            Assert.AreEqual(0, fileScanResult.FilesWithErrorCount);
            Assert.AreEqual(0, fileScanResult.FoldersWithErrorCount);
            Assert.AreEqual(3, fileScanResult.ProcessedFileCount);
            Assert.AreEqual(1, fileScanResult.ProcessedFolderCount);
        }
예제 #2
0
        private Image GetIconFileScanStatus(FileScanResult result)
        {
            Image image;

            switch (result.Status)
            {
            case FileScanStatus.ChangedFile:
                image = Resources.changed;
                break;

            case FileScanStatus.UnchangedFile:
                image = Resources.unchanged;
                break;

            case FileScanStatus.NewFile:
                image = Resources._new;
                break;

            case FileScanStatus.FileRemoved:
                image = Resources.changed;
                break;

            default:     //Error
                image = Resources.error;
                break;
            }

            return(image);
        }
예제 #3
0
        private List <FileScanResult> GetScanResults(int page = 0, int number = 10)
        {
            if (ScanOne == null || ScanOther == null)
            {
                MessageBox.Show("One or more scans were not found!", "Scan(s) not found",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            Scan latestScan;
            Scan previousScan;

            if (ScanOne.Time >= ScanOther.Time)
            {
                latestScan   = ScanOne;
                previousScan = ScanOther;
            }
            else
            {
                latestScan   = ScanOther;
                previousScan = ScanOne;
            }

            if (latestScan.HashAlgorithm.Id != previousScan.HashAlgorithm.Id)
            {
                MessageBox.Show("Hashing algorithms used for boths scans differ!", "Different hashing algorithms",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            List <FileScanResult> results = FileScanResult.GetScanResultCompare2Scans(latestScan, previousScan,
                                                                                      page, number);

            return(results);
        }
예제 #4
0
        public void ScanFolderForFilesShouldReturnRootFolder()
        {
            // Arrange
            var directoryProvider = new Mock <IDirectoryProvider>();
            var fileProvider      = new Mock <IIsoFileProvider>();

            directoryProvider.Setup(m => m.GetDirectories(It.IsAny <string>())).Returns(new string[0]);
            var            fileScanner = new FileScanner(directoryProvider.Object, fileProvider.Object);
            IsoFolder      rootFolder;
            string         driveLetter    = "D";
            FileScanResult fileScanResult = new FileScanResult();

            // Act
            rootFolder = fileScanner.ScanFolderForFiles(driveLetter, fileScanResult, null);

            // Assert
            Assert.IsNotNull(rootFolder);
            Assert.AreEqual("/", rootFolder.Name);
            Assert.AreEqual(driveLetter + ":\\", rootFolder.Path);
            Assert.IsNull(rootFolder.Parent);
            Assert.AreEqual(0, rootFolder.ChildFiles.Count);
            Assert.AreEqual(0, rootFolder.ChildFolders.Count);
            Assert.AreEqual(0, fileScanResult.FilesWithErrorCount);
            Assert.AreEqual(0, fileScanResult.FoldersWithErrorCount);
            Assert.AreEqual(0, fileScanResult.ProcessedFileCount);
            Assert.AreEqual(1, fileScanResult.ProcessedFolderCount);
        }
        public void Success_sync()
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(GetMockApiUrl());

            string existingDataId = "61dffeaa728844adbf49eb090e4ece0e";

            CreateStub("/file", "POST", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.scanFile.scanFile_success.json"));
            CreateStub("/file/" + existingDataId, "GET", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.fetchScanResult.fetchScanResult_success.json"));

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MetadefenderCoreClient.test.resources.testScanFile.txt"))
            {
                FileScanResult result = metadefenderCoreClient.ScanFileSync(
                    stream, new FileScanOptions().SetFileName("fileName.txt"), 50, 1000 * 30, 4000);
                Assert.AreEqual("Allowed", result.process_info.result);
                Assert.AreEqual("Clean", result.scan_results.scan_all_result_a);
                Assert.Null(result.extracted_files);
            }

            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("POST", "/file"));
            }
                                       );
            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("GET", "/file/" + existingDataId));
            }
                                       );
        }
예제 #6
0
        private void DisplayScanResults(List <FileScanResult> results)
        {
            Records = new List <Panel>();

            for (int i = 0; i < results.Count; i++)
            {
                FileScanResult currentResult = results[i];

                DisplayScanResultRecord(currentResult, i);
            }
        }
예제 #7
0
        public void FileScanResultConstructorShouldInitializeValues()
        {
            //Arrange
            FileScanResult fileScanResult;

            //Act
            fileScanResult = new FileScanResult();

            //Assert
            Assert.AreEqual(0, fileScanResult.ProcessedFileCount);
            Assert.AreEqual(0, fileScanResult.FilesWithErrorCount);
            Assert.AreEqual(0, fileScanResult.ProcessedFolderCount);
            Assert.AreEqual(0, fileScanResult.FoldersWithErrorCount);
            Assert.IsNotNull(fileScanResult.Log);
            Assert.AreEqual(0, fileScanResult.Log.Length);
        }
예제 #8
0
        private async void btnScan_Click(object sender, EventArgs e)
        {
            _scanResult        = new FileScanResult();
            chkShowLog.Enabled = false;
            txtLog.Text        = "scanning in progress...";
            await FileScanner.ScanFolderForFilesAsync(txtPath.Text, _scanResult);

            chkShowLog.Enabled = true;
            if (chkShowLog.Checked)
            {
                txtLog.Text = _scanResult.Log.ToString();
            }
            else
            {
                txtLog.Text = "scan finished!";
                MessageBox.Show("Scan Finished!");
            }
        }
        private static void FetchScanResultByHash(string apiUrl, string hash)
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(apiUrl);

            try
            {
                FileScanResult result = metadefenderCoreClient.FetchScanResultByHash(hash);
                Console.WriteLine("Fetch result by file hash: " + result.process_info.result);
                if (result.process_info.post_processing != null)
                {
                    Console.WriteLine("post processing: " + result.process_info.post_processing);
                }
            }
            catch (MetadefenderClientException e)
            {
                Console.WriteLine("Error during fetch scan by hash: " + e.GetDetailedMessage());
            }
        }
예제 #10
0
        public void Success()
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(GetMockApiUrl());

            string existingHash = "e981b537cff14c3fbbba923d7a71ff2e";

            CreateStub("/hash/" + existingHash, "GET", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.fetchScanResultByHash.fetchScanResultByHash_success.json"));

            FileScanResult result = metadefenderCoreClient.FetchScanResultByHash(existingHash);

            Assert.AreEqual(existingHash, result.data_id);
            Assert.AreEqual("Allowed", result.process_info.result);
            Assert.AreEqual("Clean", result.scan_results.scan_all_result_a);

            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("GET", "/hash/" + existingHash));
            });
        }
예제 #11
0
        private FileScanComparison ExpandIndividualDetailsRecord(Panel record, int id)
        {
            FileScanResult     fileScanResult = Results[id];
            FileScanComparison expandedRecord = new FileScanComparison();

            expandedRecord.Name = "ExpandedRecord_" + id;
            expandedRecord.SetFileScanResult(fileScanResult);
            expandedRecord.BackColor = Color.White;
            expandedRecord.ForeColor = Color.Black;
            int y = record.Location.Y + record.Height + 1;

            expandedRecord.Location = new Point(record.Location.X, y);
            //expandedRecord.AutoScaleMode = AutoScaleMode.Inherit;
            RecordDetails.Add(expandedRecord);

            FileScanComparisons.Controls.Add(expandedRecord);

            return(expandedRecord);
        }
예제 #12
0
        public void Success()
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(GetMockApiUrl());

            string existingDataId = "59f92cb3e3194c6381d3f8819a0d47ed";

            CreateStub("/file/" + existingDataId, "GET", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.fetchScanResult.fetchScanResult_success.json"));

            FileScanResult result = metadefenderCoreClient.FetchScanResult(existingDataId);

            Assert.AreEqual(existingDataId, result.data_id);
            Assert.AreEqual("Allowed", result.process_info.result);
            Assert.AreEqual("Clean", result.scan_results.scan_all_result_a);
            Assert.Null(result.extracted_files);

            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("GET", "/file/" + existingDataId));
            }
                                       );
        }
        public void SetFileScanResult(FileScanResult result)
        {
            this.StatusLabel.Text = result.StatusString;

            if (!string.IsNullOrEmpty(result.LatestFileScan.Error.ErrorMessage))
            {
                this.LatestChecksum.Text = result.LatestFileScan.Error.ErrorMessage;
            }
            else if (result.LatestFileScan.Checksum != null)
            {
                this.LatestChecksum.Text = result.LatestFileScan.Checksum;
            }

            if (!string.IsNullOrEmpty(result.PreviousFileScan.Error.ErrorMessage))
            {
                this.PreviousChecksum.Text = result.PreviousFileScan.Error.ErrorMessage;
            }
            else if (result.PreviousFileScan.Checksum != null)
            {
                this.PreviousChecksum.Text = result.PreviousFileScan.Checksum;
            }
        }
예제 #14
0
        private void backgroundDataBlockScanner_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                ResetAllScanAttributes();
                return;
            }

            bool resultInvalidated = false;

            if (e.Error == null)
            {
                // Get used sourcedata
                IFragment sourceFragment = (_currentCodecStreamIndex == -1) ? ((IFragment)_currentDataBlocks[_currentDataBlockIndex]) : ((IFragment)_currentValidCodecStreams[_currentCodecStreamIndex]);

                // Report result to users of this scanner
                FileScanResult result = new FileScanResult(sourceFragment, e.Result as IResultNode,
                                                           _currentDataBlocks[_currentDataBlockIndex],
                                                           (_currentCodecStreamIndex >= 0) ? _currentValidCodecStreams[_currentCodecStreamIndex] : null,
                                                           _currentValidCodecStreams.Count);
                ResultDetected(this, result);

                // Check if the result is invalidated by one of the event listeners.
                resultInvalidated = ScanNextCodecStreamOnInvalidation && !result.IsValid;
            }

            // Continue scan operation
            if (_currentCodecStreamIndex == -1)
            {
                // We where scanning a Datablock
                ScanNextDataBlock();
            }
            else
            {
                // We where scanning a CodecStream
                ScanNextCodecStream(resultInvalidated);
            }
        }
예제 #15
0
        private void DisplayScanResultRecord(FileScanResult result, int number)
        {
            Panel      record          = new Panel();
            PictureBox icon            = new PictureBox();
            ToolTip    statusToolTip   = new ToolTip();
            Label      filePath        = new Label();
            ToolTip    filePathToolTip = new ToolTip();

            icon.Image = GetIconFileScanStatus(result);
            statusToolTip.SetToolTip(icon, GetToolTipTextFileScanStatus(result));
            icon.Size     = new Size(28, 28);
            icon.Location = new Point(2, 2);

            filePath.Text      = result.FilePath;
            filePath.ForeColor = Color.FromArgb(67, 70, 78);
            filePath.Size      = new Size(this.Width - icon.Width - 10, 28);

            record.Name      = "Record_" + number;
            record.Location  = new Point(0, (number * RECORD_HEIGHT) + 1);
            record.Size      = new Size(800, RECORD_HEIGHT);
            record.BackColor = Color.White;

            record.Controls.Add(icon);
            record.Controls.Add(filePath);
            FileScanComparisons.Controls.Add(record);

            filePath.TextAlign = ContentAlignment.MiddleLeft;
            filePath.Location  = new Point(icon.Width + 2, (record.Size.Height - filePath.Height) / 2);

            icon.MouseEnter     += RecordControl_MouseHover;
            filePath.MouseEnter += RecordControl_MouseHover;
            record.MouseEnter   += Record_MouseHover;
            icon.Click          += RecordControl_Click;
            record.Click        += Record_Click;
            filePath.Click      += RecordControl_Click;

            Records.Add(record);
        }
예제 #16
0
        public void Success_withArchive()
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(GetMockApiUrl());

            string existingDataId = "fafb3a12b0d141909b3a3ba6b26e42c9";

            CreateStub("/file/" + existingDataId, "GET", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.fetchScanResult.fetchScanResult_success_withArchive.json"));


            FileScanResult result = metadefenderCoreClient.FetchScanResult(existingDataId);

            Assert.AreEqual(existingDataId, result.data_id);
            Assert.AreEqual("Allowed", result.process_info.result);
            Assert.AreEqual("Clean", result.scan_results.scan_all_result_a);
            Assert.NotNull(result.extracted_files);
            Assert.AreEqual(2L, result.extracted_files.files_in_archive.Count);

            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("GET", "/file/" + existingDataId));
            }
                                       );
        }
        public void Success_syncTimeout()
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(GetMockApiUrl());

            string existingDataId = "61dffeaa728844adbf49eb090e4ece0e";

            CreateStub("/file", "POST", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.scanFile.scanFile_success.json"));
            CreateStub("/file/" + existingDataId, "GET", 200, GetJsonFromFile("MetadefenderCoreClient.test.resources.apiResponses.fetchScanResult.fetchScanResult_inProgress.json"));

            bool isException = false;

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MetadefenderCoreClient.test.resources.testScanFile.txt"))
            {
                try
                {
                    // it should be a timeout, because we return in progress response every time
                    FileScanResult result = metadefenderCoreClient.ScanFileSync(stream, new FileScanOptions().SetFileName("fileName.txt"), 50, 1000 * 30, 2000);
                }
                catch (TimeoutException)
                {
                    isException = true;
                }
                Assert.True(isException);
            }

            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("POST", "/file"));
            }
                                       );
            HttpServer.AssertWasCalled(x =>
            {
                return(x.CustomVerb("GET", "/file/" + existingDataId));
            }
                                       );
        }
        private static void ScanFileSync(string apiUrl, string file)
        {
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(apiUrl);

            try
            {
                Stream         inputStream = File.Open(file, FileMode.Open);
                FileScanResult result      = metadefenderCoreClient.ScanFileSync(inputStream,
                                                                                 new FileScanOptions().SetFileName(GetFileNameFromPath(file)), 200, 1000 * 30, 5000);
                Console.WriteLine("File scan finished with result: " + result.process_info.result);
                if (result.process_info.post_processing != null)
                {
                    Console.WriteLine("post processing: " + result.process_info.post_processing);
                }
            }
            catch (MetadefenderClientException e)
            {
                Console.WriteLine("Error during file scan: " + e.GetDetailedMessage());
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine("File not found: " + file + " Exception: " + e.Message);
            }
        }
        private static void ScanFileSync(string apiUrl, string file, string rule = "")
        {
            int TaskTimeout = 600 * 1000; // 10 minutes
            MetadefenderCoreClient metadefenderCoreClient = new MetadefenderCoreClient(apiUrl);

            // The Core ID is usefull when using external LB
            // It actually points the cookie value that identify the core server the LB sent the file to
            string CoreId = apiUrl;

            try
            {
                Stream inputStream = File.Open(file, FileMode.Open);

                FileScanOptions fso = new FileScanOptions();
                fso.SetFileName(GetFileNameFromPath(file));
                if (!string.IsNullOrEmpty(rule))
                {
                    fso.SetRule(rule);
                }

                FileScanResult result = metadefenderCoreClient.ScanFileSync(inputStream, fso, 200, 1000 * 30, TaskTimeout, out CoreId);
                Console.WriteLine("File scan finished with result: " + result.process_info.result);

                if (CoreId.ToLower() != apiUrl.ToLower())
                {
                    Console.WriteLine("Core Id: {0}", CoreId);
                }

                if (result.process_info.post_processing != null)
                {
                    if (!string.IsNullOrEmpty(result.process_info.post_processing.actions_ran))
                    {
                        Console.WriteLine("post processing: " + result.process_info.post_processing.actions_ran);
                    }

                    if (result.process_info.post_processing.actions_ran.ToLower().Contains("sanitized"))
                    {
                        Console.WriteLine("\nFile was sanitized. Where would you like to save the sanitized file?");
                        Console.Write("Enter folder path: ");
                        string destinationPath = Console.ReadLine();
                        if (!Directory.Exists(destinationPath))
                        {
                            throw new Exception(string.Format("Destination folder {0} does not exist!", destinationPath));
                        }

                        string cdrErrorMessage = null;
                        Stream sanitizedStream = metadefenderCoreClient.DownloadSanitizedFile(result.data_id, out cdrErrorMessage);

                        if (string.IsNullOrEmpty(cdrErrorMessage))
                        {
                            string sanitizedFilename = result.process_info.post_processing.converted_destination;

                            // save the file on disk
                            using (var fileStream = File.Create(Path.Combine(destinationPath, sanitizedFilename)))
                            {
                                sanitizedStream.Seek(0, SeekOrigin.Begin);
                                sanitizedStream.CopyTo(fileStream, 81920);
                            }
                        }
                        else
                        {
                            Console.WriteLine("Failed to download sanitized file! Reason: {0}", cdrErrorMessage);
                        }
                    }
                }
            }
            catch (MetadefenderClientException e)
            {
                Console.WriteLine("Error during file scan: " + e.GetDetailedMessage());
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine("File not found: " + file + " Exception: " + e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("General error: " + file + " Exception: " + e.Message);
            }
        }
예제 #20
0
        private async Task ScanIsoCompilations()
        {
            IsoFilesPath = GetIsoFilesReadyToScan();
            ShowLogMessage("Scanning ISO compilations...");
            var isoFilesFoundMessage = string.Format("{0} ISO files found", IsoFilesPath.Count);

            ShowInformationMessage(isoFilesFoundMessage);
            ShowLogMessage(isoFilesFoundMessage);
            var currentIsoFilePathIndex = 0;
            var unmountResult           = await UnMount();

            if (!unmountResult)
            {
                ShowLogMessage(string.Format("Error trying to unmount file from unit. Process aborted."));
                return;
            }

            foreach (var isoFilePath in IsoFilesPath)
            {
                var mountResult = await VirtualCloneDrive.MountAsync(isoFilePath);

                if (mountResult.HasError)
                {
                    ShowLogMessage(string.Format("Error trying to mount: {0}", Path.GetFileName(isoFilePath)));
                }
                else
                {
                    var volumeName = VirtualCloneDrive.VolumeLabel;
                    ShowLogMessage(string.Format("Scanning: {0}...", volumeName));
                    ShowInformationMessage(string.Format("Scanning: {0} [{1} of {2}]", volumeName,
                                                         currentIsoFilePathIndex + 1,
                                                         IsoFilesPath.Count));

                    if (!Entities.IsoVolumes.Any(i => i.VolumeLabel == volumeName))
                    {
                        var iso = new IsoVolume
                        {
                            DateCreated = DateTime.Now,
                            FileName    = Path.GetFileName(IsoFilesPath[currentIsoFilePathIndex]),
                            Size        = Convert.ToDecimal(VirtualCloneDrive.TotalSize),
                            VolumeLabel = volumeName
                        };

                        Entities.IsoVolumes.Add(iso);
                        Entities.SaveChanges();

                        var fileScanResult = new FileScanResult();
                        await IsoFileScanner.ScanFolderForFilesAsync(Entities, iso,
                                                                     VirtualCloneDrive.UnitLetter,
                                                                     fileScanResult);

                        iso.FileCount             = fileScanResult.ProcessedFileCount;
                        Entities.Entry(iso).State = EntityState.Modified;
                        Entities.SaveChanges();
                        ShowLogMessage(string.Format(
                                           "Scan finished for {0} ({1}), scan time: {2}, files processed: {3}",
                                           volumeName, iso.FileName,
                                           fileScanResult.TotalTime.ToString("hh\\:mm\\:ss"),
                                           fileScanResult.ProcessedFileCount));
                        SaveScanLog(iso.FileName, fileScanResult.Log.ToString());
                    }
                    else
                    {
                        ShowLogMessage(string.Format("ISO '{0}' already exists on the database.", volumeName));
                    }

                    unmountResult = await UnMount();

                    if (!unmountResult)
                    {
                        ShowLogMessage(string.Format("Error trying to unmount '{0}'. Process aborted.", isoFilePath));
                        break;
                    }
                }

                currentIsoFilePathIndex += 1;
            }
        }
예제 #21
0
 private string GetToolTipTextFileScanStatus(FileScanResult result)
 {
     return(result.StatusString);
 }
예제 #22
0
파일: Scan.cs 프로젝트: mamcer/isofinder
        public async void Execute()
        {
            txtConsole.Text        = string.Empty;
            lblInformation.Visible = false;

            ShowLogMessage("Scan started...");
            TotalScanStartTime = DateTime.Now;

            var currentIsoFilePathIndex = 0;
            var isoFilesCount           = _isoScannerInfo.SelectedIsoFileNames.Count();
            var isoFilesFoundMessage    = string.Format("{0} iso files found", isoFilesCount);

            ShowInformationMessage(isoFilesFoundMessage);
            ShowLogMessage(isoFilesFoundMessage);
            var unmountResult = await UnMount();

            if (!unmountResult)
            {
                ShowLogMessage(string.Format("Error trying to unmount file from unit. Process aborted."));
                return;
            }

            foreach (var isoFileName in _isoScannerInfo.SelectedIsoFileNames)
            {
                var isoFilePath = Path.Combine(_isoScannerInfo.IsoFolderPath, isoFileName);
                var mountResult = await VirtualCloneDrive.MountAsync(isoFilePath);

                if (mountResult.HasError)
                {
                    ShowLogMessage(string.Format("Error trying to mount: {0}", Path.GetFileName(isoFilePath)));
                }
                else
                {
                    var volumeName = VirtualCloneDrive.VolumeLabel;
                    ShowLogMessage(string.Format("Scanning: {0}...", volumeName));
                    ShowInformationMessage(string.Format("Scanning: {0} [{1} of {2}]", volumeName,
                                                         currentIsoFilePathIndex + 1,
                                                         isoFilesCount));

                    if (!_unitOfWork.IsoVolumeRepository.Search(i => i.VolumeLabel == volumeName).Any())
                    {
                        var initialFolder = new IsoFolder {
                            Name = "$", Path = "/", IsoVolumeId = 0
                        };
                        var iso = new IsoVolume
                        {
                            Created     = DateTime.Now,
                            FileName    = Path.GetFileName(isoFileName),
                            Size        = Convert.ToDecimal(VirtualCloneDrive.TotalSize),
                            VolumeLabel = volumeName,
                            FileCount   = 0,
                            RootFolder  = initialFolder
                        };

                        _unitOfWork.IsoVolumeRepository.Insert(iso);
                        _unitOfWork.Save();

                        var fileScanResult = new FileScanResult();
                        try
                        {
                            var rootFolder = _fileScanner.ScanFolderForFiles(VirtualCloneDrive.UnitLetter, fileScanResult, iso);
                            iso.FileCount  = fileScanResult.ProcessedFileCount;
                            iso.RootFolder = rootFolder;
                        }
                        catch (Exception ex)
                        {
                            ShowLogMessage(string.Format("Error scanning iso file: {0}", Path.GetFileName(isoFilePath)));
                            ShowLogMessage(ex.Message);
                        }

                        ShowLogMessage(string.Format(
                                           "Scan finished for {0} ({1}), scan duration: {2}, files processed: {3}",
                                           volumeName, iso.FileName,
                                           fileScanResult.TotalTime.ToString("hh\\:mm\\:ss"),
                                           fileScanResult.ProcessedFileCount));
                        try
                        {
                            ShowLogMessage("Saving changes to the database...");
                            _unitOfWork.IsoVolumeRepository.Update(iso);
                            _unitOfWork.IsoFolderRepository.Delete(initialFolder);
                            _unitOfWork.Save();
                            ShowLogMessage("Changes successfully saved");
                        }
                        catch (Exception ex)
                        {
                            _unitOfWork.IsoVolumeRepository.Delete(iso);
                            _unitOfWork.IsoFolderRepository.Delete(initialFolder);
                            _unitOfWork.Save();
                            ShowLogMessage("An error has ocurred saving changes to database");
                            fileScanResult.Log.Append(ex.Message);
                            fileScanResult.Log.Append(ex.StackTrace);
                        }

                        try
                        {
                            ShowLogMessage("Saving log file...");
                            SaveScanLog(iso.FileName, fileScanResult.Log.ToString());
                            ShowLogMessage(string.Format("Log file successfully saved for {0} ", iso.FileName));
                        }
                        catch
                        {
                            ShowLogMessage("Failed to save log file");
                            ShowLogMessage(fileScanResult.Log.ToString());
                        }
                    }
                    else
                    {
                        ShowLogMessage(string.Format("Iso Volume '{0}' already exists in the database.", volumeName));
                    }

                    unmountResult = await UnMount();

                    if (!unmountResult)
                    {
                        ShowLogMessage(string.Format("Error trying to unmount '{0}'. Process aborted.", isoFilePath));
                        break;
                    }
                }

                currentIsoFilePathIndex += 1;
            }

            ShowLogMessage("Scan finished");
            var totalTime = string.Format("Total time: {0}",
                                          DateTime.Now.Subtract(TotalScanStartTime).ToString("hh\\:mm\\:ss"));

            ShowLogMessage(totalTime);
            ShowInformationMessage(string.Format("Scan finished. {0}", totalTime));

            if (WorkFinished != null)
            {
                WorkFinished();
            }
        }