public ScanInventory_Form(StartAudit_Form appForm)
        {
            InitializeComponent();
            this.m_appForm = appForm;
            status = "Connect";
            this.m_UpdateReadHandler = new UpdateRead(myUpdateRead);
            this.m_UpdateStatusHandler = new UpdateStatus(myUpdateStatus);
            this.m_ReadTag = new Symbol.RFID3.TagData();

            m_ReaderAPI = m_appForm.m_ReaderAPI;
            m_ReaderAPI = new RFIDReader("127.0.0.1", 5084, 0);

            this.m_AntennaInfoForm = m_appForm.m_AntennaInfoForm;
            this.m_AntennaConfigForm = m_appForm.m_AntennaConfigForm;
            this.m_PostFilterForm = m_appForm.m_PostFilterForm;
            this.m_AccessFilterForm = m_appForm.m_AccessFilterForm;
            this.m_TriggerForm = m_appForm.m_TriggerForm;

            this.m_ReaderMgmt = new ReaderManagement();
            this.m_TagTable = new Hashtable(1023);
            this.m_AccessOpResult = new AccessOperationResult();
            this.m_IsConnected = false;
            this.m_TagTotalCount = 0;
            this.m_ReaderInitiatedDisconnectionReceived = false;
            this.m_isBeepingEnabled = true;
        }
예제 #2
0
 public Renderer(String regionDir, String outPath, UpdateStatus updateStatus = null, DoneCallback callback = null)
 {
     this.regionDir = regionDir;
     this.outPath = outPath;
     this.updateStatus = updateStatus;
     this.callback = callback;
 }
예제 #3
0
 public InterpreterProperties(InterpreterProperties rhs)
 {
     executingGraphNode = rhs.executingGraphNode;
     nodeIterations = rhs.nodeIterations;
     functionCallArguments = rhs.functionCallArguments;
     functionCallDotCallDimensions = rhs.functionCallDotCallDimensions;
     updateStatus = rhs.updateStatus;
 }
예제 #4
0
		RowUpdatedEventArgs (DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) 
		{
			this.dataRow = dataRow;
			this.command = command;
			this.statementType = statementType;
			this.tableMapping = tableMapping;
			this.status = UpdateStatus.Continue;
		}
예제 #5
0
 public void Reset()
 {
     executingGraphNode = null;
     nodeIterations = new List<GraphNode>();
     functionCallArguments = new List<StackValue>();
     functionCallDotCallDimensions = new List<StackValue>();
     updateStatus = UpdateStatus.kNormalUpdate;
 }
예제 #6
0
 public Engine(UpdateStatus us,LabelClickHandler l,PanelClickHandler p,EdgeMouseDown md, EdgeMouseUp mu)
 {
     UpdateState = us;
     l_MouseClick = l;
     p_MouseClick = p;
     l_MouseDown = md;
     l_MouseUp = mu;
 }
예제 #7
0
 public MainForm()
 {
     InitializeComponent();
     m_addMessageDelegate = new AddListItem(this.addMessage);
     m_removeMessageDelegate = new RemoveListItem(this.removeMessage);
     m_initMessageListDelegate = new InitList(this.initializeMessageList);
     m_updateStatusDelegate = new UpdateStatus(this.updateStatus);
     m_dispErrorMessageDelegate = new DispErrorMessage(this.displayErrorMessage);
 }
		protected RowUpdatedEventArgs (DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) 
		{
			this.dataRow = dataRow;
			this.command = command;
			this.statementType = statementType;
			this.tableMapping = tableMapping;
			this.errors = null;
			this.status = UpdateStatus.Continue;
			this.recordsAffected = 0; // FIXME
		}
예제 #9
0
 public UpdateWindow()
 {
     InitializeComponent();
     maxticks = new UpdateMaxTicks(this.SetMaxTicks);
     newtick = new UpdateTick(this.ProgressTick);
     setstatus = new UpdateStatus(this.NewStatus);
     weredone = new CloseWindow(this.Done);
     newprogress = new UpdateProgressText(this.setspeed);
     addticks = new UpdateAddMaxTicks(this.AddMaxTicks);
     runthread = false;
     this.KeyPreview = true;
 }
예제 #10
0
        public TVShowRenamer(UpdateStatus updateStatus,
							OnFoundMultipleSeries onFoundMultipleSeries,
							EpisodeRenamer episodeRenamer = null,
							EpisodeIdentifier episodeIdentifier = null,
							SeriesRepository seriesRepository = null)
        {
            SetRenamingStatus = updateStatus;
            OnFoundMultipleSeries = onFoundMultipleSeries;

            EpisodeRenamer = episodeRenamer ?? new EpisodeRenamer();
            EpisodeIdentifier = episodeIdentifier ?? new EpisodeIdentifier(onFoundMultipleSeries, SeriesRepository);
            SeriesRepository = seriesRepository ?? new SeriesRepository();
        }
        public FrmBarcodeScanSearch(StartAudit_Form appForm)
        {
            InitializeComponent();
            this.m_appForm = appForm;
            status = "Connect";
            this.m_UpdateReadHandler = new UpdateRead(myUpdateRead);
            this.m_UpdateStatusHandler = new UpdateStatus(myUpdateStatus);
            this.m_ReadTag = new Symbol.RFID3.TagData();

            m_ReaderAPI = m_appForm.m_ReaderAPI;
            m_ReaderAPI = new RFIDReader("127.0.0.1", 5084, 0);

            this.m_AntennaInfoForm = m_appForm.m_AntennaInfoForm;
            this.m_AntennaConfigForm = m_appForm.m_AntennaConfigForm;
            this.m_PostFilterForm = m_appForm.m_PostFilterForm;
            this.m_AccessFilterForm = m_appForm.m_AccessFilterForm;
            this.m_TriggerForm = m_appForm.m_TriggerForm;

            this.m_ReaderMgmt = new ReaderManagement();
            this.m_TagTable = new Hashtable(1023);
            this.m_AccessOpResult = new AccessOperationResult();
            this.m_IsConnected = false;
            this.m_TagTotalCount = 0;
            this.m_ReaderInitiatedDisconnectionReceived = false;
            this.m_isBeepingEnabled = true;

            //Barcode scan start
            try
            {
                // Let's use the first available scanner.
                scanner = new Barcode2();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Barcode2 instantiation failed with " + ex.Message);
                this.Close();
                return;
            }

            // Let's use triggers to fire up the scanner.
            scanner.Config.TriggerMode = TRIGGERMODES.HARD;

            // Register a scan event handler
            //scanner.OnScan += new Barcode2.OnScanHandler(barcode21_OnScan);
            scanner.OnScan += new Barcode2.OnScanHandler(barcode21_OnScan);
               // scanner.OnStatus += new Barcode2.OnStatusHandler(barcode21_OnStatus);

            //Barcode scan end
        }
예제 #12
0
        public void SetUpdateStatus(UpdateStatus Status, string StatusText)
        {
            Label_UpdateStatus.Content = StatusText;

            if (Status == UpdateStatus.NewVersionAvailable)
            {
                Label_UpdateStatus.Foreground = new SolidColorBrush(Colors.Blue);
                Label_UpdateStatus.MouseLeftButtonUp += delegate(object s, MouseButtonEventArgs e)
                {
                    System.Diagnostics.Process.Start(Control.WebAddressOfCrusadesFile);
                    Control.ExitApplication();
                };
                Label_UpdateStatus.Cursor = Cursors.Hand;
            }
        }
        /// <summary>
        /// Does asynchronous user authentication
        /// </summary>
        /// <param name="manager">BoxManager object which will be used for communication with Box.NET service</param>
        /// <param name="userLogin">User login</param>
        /// <param name="userPassword">User password</param>
        /// <param name="authenticationCompleted">Callback method which will be invoked after authorization process completes</param>
        /// <param name="updateAuthenticationStatus">Callback method which will be invoked on each step of authorization process. Can be null</param>
        /// <exception cref="ArgumentException">Thrown if <paramref name="authenticationCompleted"/> is null</exception>
        public static void Login(this BoxManager manager, string userLogin, string userPassword, AuthenticationProcessFinished authenticationCompleted, UpdateStatus updateAuthenticationStatus)
        {
            BoxManager.ThrowIfParameterIsNull(authenticationCompleted, "authenticationCompleted");

            AuthenticationInformation authenticationInformation = new AuthenticationInformation
            {
                CurrentOperationCompleted = ProcessUserAuthentication,
                LoginCompleted = authenticationCompleted,
                Password = userPassword,
                UserName = userLogin,
                Status = AuthenticationStatus.ReadyToStartAuthentication,
                Ticket = null,
                UpdateAuthenticationStatus = updateAuthenticationStatus,
                Manager = manager
            };

            ProcessUserAuthentication(authenticationInformation);
        }
예제 #14
0
        private void hbUpdates_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            tbVersion.Text = String.Format("{0} ({1})", VersionUtil.GetVersionName(), UI.CheckingForUpdates);
            e.Handled = true;

            versionChecker = new BackgroundWorker();
            versionChecker.DoWork += delegate(object s, DoWorkEventArgs args)
            {
                var result = new UpdateStatus();
                result.Succeeded = UpdateChecker.IsWorking();
                if (result.Succeeded)
                {
                    result.UpdateAvailable = UpdateChecker.IsUpdateAvailable();
                    result.LastVersion = UpdateChecker.GetLastReleasedVersion();
                }
                args.Result = result;
            };
            versionChecker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
            {
                var result = (UpdateStatus)args.Result;

                string text;
                if (!result.Succeeded)
                {
                    text = UI.FailedToRetrieveUpdateInformation;
                }
                else if (result.UpdateAvailable)
                {
                    text = String.Format(UI.UpdateAvailable, result.LastVersion.Version, result.LastVersion.ReleaseDate.ToShortDateString());
                }
                else
                {
                    text = UI.NoUpdateAvailable;
                }

                tbVersion.Text = String.Format("{0} ({1})", VersionUtil.GetVersionName(), text);
            };
            versionChecker.RunWorkerAsync();
        }
예제 #15
0
 internal static ArgumentException InvalidUpdateStatus(UpdateStatus status)
 {
     object [] args = new object [] { status };
     return(new ArgumentException(GetExceptionMessage("Invalid UpdateStatus: {0}", args)));
 }
예제 #16
0
        public void Undo(Bitmap selection, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, Bitmap populateOverlay, UpdateStatus updateStatus)
        {
            while (undoStack.Count > 0 && undoStack.Last.Value.PreviousAction == null)
            {
                redoStack.AddLast(undoStack.Last.Value);
                undoStack.RemoveLast();
            }

            if (undoStack.Count == 0)
                return;

            IAction previous = undoStack.Last.Value.PreviousAction;
            if (previous == null)
            {
                throw new Exception("Undo sanity check failed.");
            }

            if (previous is SelectionAction)
            {
                ApplySelectionState((SelectionAction)previous, selection);
            }
            else if (previous is BiomeAction)
            {
                ApplyBiomeState((BiomeAction)previous, region, terrainOverlay, biomeOverlay, ref tooltips, updateStatus);
            }
            else if (previous is PopulateAction)
            {
                ApplyPopulateState((PopulateAction)previous, region, populateOverlay);
            }

            MovePrevious();
            OnChange();
        }
예제 #17
0
		internal static ArgumentException InvalidUpdateStatus (UpdateStatus status)
		{
			object [] args = new object [] { status };
			return new ArgumentException (GetExceptionMessage ("Invalid UpdateStatus: {0}",args));
		}
예제 #18
0
        public object Run(int timeSleep = 10)
        {
            try
            {
                /*
                 *
                 * log.AddCaller(this);
                 * HeTrace.AddLogger("LaunchBox", log);
                 */

                //UpdateStatus += (x, y) => HeTrace.WriteLine(y, this);

                // Redirige les signaux
                //RedirectSignals();


                // Récupération des infos de la plateforme
                UpdateStatus?.Invoke(this, "Get infos from platform");

                /*
                 * Normalement on peut virer
                 * XML_Functions xf = new XML_Functions();
                 * xf.ReadFile(Common.PlatformsFile);
                 *
                 * Machine = xf.ScrapPlatform(PlatformName);*/

                Machine = XML_Platforms.GetPlatformPaths(Common.PlatformsFile, PlatformName);

                if (Machine.PlatformFolders.Count < 1)
                {
                    UpdateStatus?.Invoke(this, "Error: this machine has no path");
                    return(false);
                }

                // Backup datas
                MachineXMLFile = Path.Combine(PS.Default.LastLBpath, PS.Default.dPlatforms, $"{PlatformName}.xml");
                BackupPlatformFile(MachineXMLFile);
                UpdateStatus?.Invoke(this, $"Backup of '{MachineXMLFile}'");

                // Initialisation des dossiers cible
                // Memo solution la plus simple, fixant des limites et normalement évolutive
                string root = Path.GetDirectoryName(Path.GetDirectoryName(Machine.FolderPath));
                TGamesP = Path.Combine(Machine.FolderPath);
                UpdateStatus?.Invoke(this, $"Target Game path: {TGamesP}");

                TCheatsCodesP = Path.Combine(root, "Cheat Codes", PlatformName);
                UpdateStatus?.Invoke(this, $"Target Cheats path: {TCheatsCodesP}");

                TImagesP = Path.GetDirectoryName(Machine.PlatformFolders.First((x) => x.MediaType.Contains("Box", StringComparison.OrdinalIgnoreCase)).FolderPath);
                UpdateStatus?.Invoke(this, $"Target Images path: {TImagesP}");

                TManualsP = Machine.PlatformFolders.First((x) => x.MediaType == "Manual").FolderPath;
                UpdateStatus?.Invoke(this, $"Target Manuals  path: {TManualsP}");

                TMusicsP = Machine.PlatformFolders.First((x) => x.MediaType == "Music").FolderPath;
                UpdateStatus?.Invoke(this, $"Target Musics path: {TMusicsP}");

                TVideosP = Machine.PlatformFolders.First((x) => x.MediaType == "Video").FolderPath;
                UpdateStatus?.Invoke(this, $"Target Videos path: {TVideosP}");

                //
                int i = 0;
                //MaximumProgressT?.Invoke(this, Games.Count());
                //MaximumProgress?.Invoke(this, 100);
                foreach (FileObj game in Games)
                {
                    UpdateProgressT?.Invoke(this, i);

                    UpdateStatus?.Invoke(this, $"Work on: {game.Nom}");

                    string gameName = Path.GetFileNameWithoutExtension(game.Nom);
                    string tmpPath  = Path.Combine(Config.WorkingFolder, Path.GetFileNameWithoutExtension(game.Nom));

                    // Décompresser
                    if (Path.GetExtension(game.Path).Equals(".zip", StringComparison.OrdinalIgnoreCase))
                    {
                        ZipDecompression.UnCompressArchive(game.Path, tmpPath, CancelToken);
                    }


                    if (CancelToken.IsCancellationRequested)
                    {
                        UpdateStatus?.Invoke(this, "Stopped by user");
                        return(false);
                    }

                    // todo 7zip

                    // Chargement des données du jeu
                    string xmlFile = Path.Combine(tmpPath, "EBGame.xml");
                    LBGame lbGame  = XML_Games.Scrap_LBGame(xmlFile);
                    List <AdditionalApplication> clones = XML_Games.ListAddApps(xmlFile);



                    //05/04/2021                LBGame lbGame = XML_Games.Scrap_GameLB(Path.Combine(tmpPath, "EBGame.xml"), "LaunchBox_Backup", PS.Default.wCustomFields);

                    UpdateStatus?.Invoke(this, $"Game info xml loaded: {lbGame.Title}");

                    // Modification des chemins dans le jeu
                    Modify_Paths(lbGame, clones);

                    // Modification de la platforme du jeu
                    UpdateStatus?.Invoke(this, $"Altération of platform {lbGame.Platform} => {PlatformName}");
                    lbGame.Platform = PlatformName;

                    // Copier
                    Copy_LBManager(lbGame, tmpPath);

                    /*// Platform modification
                     * if (PS.Default.ChangePlatform)
                     *  XMLBackup.Change_Platform(Path.Combine(destPath, "EBGame.xml"), machine);*/


                    // Retrait du jeu si présence
                    bool?replace = false;
                    if (XML_Custom.TestPresence(MachineXMLFile, "Game", nameof(lbGame.Id).ToUpper(), lbGame.Id))
                    {
                        replace = AskDxMBox("Game is Already present", "Question", E_DxButtons.Yes | E_DxButtons.No, lbGame.Title);
                    }

                    if (replace == true)
                    {
                        XML_Games.Remove_Game(lbGame.Id, MachineXMLFile);
                    }


                    // Injection
                    XML_Games.InjectGame(lbGame, MachineXMLFile);
                    XML_Games.InjectAddApps(clones, MachineXMLFile);
                    if (PS.Default.wCustomFields)
                    {
                        //var r = XML_Games.ListCustomFields(xmlFile, "CustomField");
                        XML_Games.Trans_CustomF(xmlFile, MachineXMLFile);
                    }

                    UpdateStatus?.Invoke(this, $"Injection in xml Launchbox's files");
                    //XMLBackup.Copy_EBGame(gameName, Path.Combine(tmpPath, "EBGame.xml"), MachineXMLFile);


                    // Effacer le dossier temporaire
                    Delete(tmpPath);

                    UpdateStatus?.Invoke(this, "Game Finished");
                    UpdateProgress?.Invoke(this, 100);
                    i++;
                }

                UpdateStatus?.Invoke(this, "Task Finished");
                HeTrace.RemoveLogger("LaunchBoxAdapt");
                UpdateProgressT?.Invoke(this, 100);

                return(true);
            }
            catch (Exception exc)
            {
                HeTrace.WriteLine(exc.Message);
                return(false);
            }
        }
예제 #19
0
		private void InitializeJobStatusThread()
		{
            // set up event handler for engine to publish status events
            StatusEvent += new UpdateStatus(UpdateJobStatus);

			guiStatusPkg[0] = guiJobStatus;
			guiStatusPkg[1] = guiJobHistories;

			threadBroadcastJobStatus = new BackgroundWorker();
			threadBroadcastJobStatus.DoWork += new DoWorkEventHandler(threadJobStatusBroadcastRun);

			threadBroadcastJobStatus.RunWorkerAsync();
			log.Info("Background job to broadcast job Status started.");
		}
예제 #20
0
 public void UpdateStatus([FromBody] UpdateStatus statusModel)
 {
     taskService.UpdateStatus(statusModel);
 }
예제 #21
0
파일: Pregap.cs 프로젝트: morefun0302/Aaru
        // TODO: Fix offset
        void ReadCdFirstTrackPregap(uint blockSize, ref double currentSpeed, Dictionary <MediaTagType, byte[]> mediaTags,
                                    MmcSubchannel supportedSubchannel, ref double totalDuration)
        {
            bool sense;                               // Sense indicator

            byte[]   cmdBuf;                          // Data buffer
            double   cmdDuration;                     // Command execution time
            DateTime timeSpeedStart;                  // Time of start for speed calculation
            ulong    sectorSpeedStart            = 0; // Used to calculate correct speed
            bool     gotFirstTrackPregap         = false;
            int      firstTrackPregapSectorsGood = 0;
            var      firstTrackPregapMs          = new MemoryStream();

            _dumpLog.WriteLine("Reading first track pregap");
            UpdateStatus?.Invoke("Reading first track pregap");
            InitProgress?.Invoke();
            timeSpeedStart = DateTime.UtcNow;

            for (int firstTrackPregapBlock = -150; firstTrackPregapBlock < 0 && _resume.NextBlock == 0;
                 firstTrackPregapBlock++)
            {
                if (_aborted)
                {
                    _dumpLog.WriteLine("Aborted!");
                    UpdateStatus?.Invoke("Aborted!");

                    break;
                }

                PulseProgress?.
                Invoke($"Trying to read first track pregap sector {firstTrackPregapBlock} ({currentSpeed:F3} MiB/sec.)");

                // ReSharper disable IntVariableOverflowInUncheckedContext
                sense = _dev.ReadCd(out cmdBuf, out _, (uint)firstTrackPregapBlock, blockSize, 1,
                                    MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
                                    MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);

                // ReSharper restore IntVariableOverflowInUncheckedContext

                if (!sense &&
                    !_dev.Error)
                {
                    firstTrackPregapMs.Write(cmdBuf, 0, (int)blockSize);
                    gotFirstTrackPregap = true;
                    firstTrackPregapSectorsGood++;
                    totalDuration += cmdDuration;
                }
                else
                {
                    // Write empty data
                    if (gotFirstTrackPregap)
                    {
                        firstTrackPregapMs.Write(new byte[blockSize], 0, (int)blockSize);
                    }
                }

                sectorSpeedStart++;

                double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                if (elapsed < 1)
                {
                    continue;
                }

                currentSpeed     = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                sectorSpeedStart = 0;
                timeSpeedStart   = DateTime.UtcNow;
            }

            if (firstTrackPregapSectorsGood > 0)
            {
                mediaTags.Add(MediaTagType.CD_FirstTrackPregap, firstTrackPregapMs.ToArray());
            }

            EndProgress?.Invoke();
            UpdateStatus?.Invoke($"Got {firstTrackPregapSectorsGood} first track pregap sectors.");
            _dumpLog.WriteLine("Got {0} first track pregap sectors.", firstTrackPregapSectorsGood);

            firstTrackPregapMs.Close();
        }
예제 #22
0
        /// <summary>
        /// Update a single Cinemachine Virtual Camera if and only if it
        /// hasn't already been updated this frame.  Always update vcams via this method.
        /// Calling this more than once per frame for the same camera will have no effect.
        /// </summary>
        internal bool UpdateVirtualCamera(ICinemachineCamera vcam, Vector3 worldUp, float deltaTime)
        {
            //UnityEngine.Profiling.Profiler.BeginSample("CinemachineCore.UpdateVirtualCamera");
            if (mUpdateStatus == null)
            {
                mUpdateStatus = new Dictionary <ICinemachineCamera, UpdateStatus>();
            }
            if (vcam.VirtualCameraGameObject == null)
            {
                if (mUpdateStatus.ContainsKey(vcam))
                {
                    mUpdateStatus.Remove(vcam);
                }
                //UnityEngine.Profiling.Profiler.EndSample();
                return(false); // camera was deleted
            }
            UpdateStatus status = new UpdateStatus();

            if (!mUpdateStatus.TryGetValue(vcam, out status))
            {
                status.frame           = -1;
                status.subframe        = 0;
                status.lastFixedUpdate = -1;
                status.targetPos       = Matrix4x4.zero;
                mUpdateStatus.Add(vcam, status);
            }
            int subframes = (CurrentUpdateFilter == UpdateFilter.Late)
                ? 1 : CinemachineBrain.GetSubframeCount();
            int now = Time.frameCount;

            if (status.frame != now)
            {
                status.subframe = 0;
            }

            // If we're in smart update mode and the target moved, then we must update now
            bool updateNow = (CurrentUpdateFilter == UpdateFilter.Any);

            if (!updateNow)
            {
                Matrix4x4 targetPos;
                if (!GetTargetPosition(vcam, out targetPos))
                {
                    updateNow = CurrentUpdateFilter == UpdateFilter.Late;
                }
                else
                {
                    if (status.targetPos != targetPos)
                    {
                        updateNow = true;
                    }
                    status.targetPos = targetPos;
                }
            }

            // If we haven't been updated in a couple of frames, better update now
            if (CurrentUpdateFilter == UpdateFilter.Late && status.lastFixedUpdate < (now - 2))
            {
                updateNow = true;
            }
            if (updateNow)
            {
                if (Application.isPlaying)
                {
                    vcam.InconsistentTargetAnimation
                        = CurrentUpdateFilter == UpdateFilter.Late &&
                          status.lastFixedUpdate > (now - 100);
                }
                while (status.subframe < subframes)
                {
//Debug.Log(vcam.Name + ": frame " + Time.frameCount + "." + status.subframe + ", " + CurrentUpdateFilter);
                    vcam.UpdateCameraState(worldUp, deltaTime);
                    if (CurrentUpdateFilter == UpdateFilter.Fixed)
                    {
                        status.lastFixedUpdate = now;
                    }
                    ++status.subframe;
                }
                status.frame = now;
            }

            mUpdateStatus[vcam] = status;
            //UnityEngine.Profiling.Profiler.EndSample();
            return(true);
        }
예제 #23
0
 public UpdateChecker(TimeSpan period, WasabiClient client) : base(period)
 {
     WasabiClient = Guard.NotNull(nameof(client), client);
     UpdateStatus = new UpdateStatus(true, true, new Version());
 }
예제 #24
0
        /// <summary>Dumps inter-session lead-outs</summary>
        /// <param name="blocks">Total number of positive sectors</param>
        /// <param name="blockSize">Size of the read sector in bytes</param>
        /// <param name="currentSpeed">Current read speed</param>
        /// <param name="currentTry">Current dump hardware try</param>
        /// <param name="extents">Extents</param>
        /// <param name="ibgLog">IMGBurn log</param>
        /// <param name="imageWriteDuration">Duration of image write</param>
        /// <param name="leadOutExtents">Lead-out extents</param>
        /// <param name="maxSpeed">Maximum speed</param>
        /// <param name="mhddLog">MHDD log</param>
        /// <param name="minSpeed">Minimum speed</param>
        /// <param name="read6">Device supports READ(6)</param>
        /// <param name="read10">Device supports READ(10)</param>
        /// <param name="read12">Device supports READ(12)</param>
        /// <param name="read16">Device supports READ(16)</param>
        /// <param name="readcd">Device supports READ CD</param>
        /// <param name="supportedSubchannel">Drive's maximum supported subchannel</param>
        /// <param name="subSize">Subchannel size in bytes</param>
        /// <param name="totalDuration">Total commands duration</param>
        void DumpCdLeadOuts(ulong blocks, uint blockSize, ref double currentSpeed, DumpHardwareType currentTry,
                            ExtentsULong extents, IbgLog ibgLog, ref double imageWriteDuration,
                            ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog, ref double minSpeed,
                            bool read6, bool read10, bool read12, bool read16, bool readcd,
                            MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration)
        {
            byte[]     cmdBuf     = null; // Data buffer
            const uint sectorSize = 2352; // Full sector size
            bool       sense      = true; // Sense indicator

            UpdateStatus?.Invoke("Reading lead-outs");
            _dumpLog.WriteLine("Reading lead-outs");

            InitProgress?.Invoke();

            foreach ((ulong item1, ulong item2) in leadOutExtents.ToArray())
            {
                for (ulong i = item1; i <= item2; i++)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    double cmdDuration = 0;

                    #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator

                    // ReSharper disable CompareOfFloatsByEqualityOperator
                    if (currentSpeed > maxSpeed &&
                        currentSpeed != 0)
                    {
                        maxSpeed = currentSpeed;
                    }

                    if (currentSpeed < minSpeed &&
                        currentSpeed != 0)
                    {
                        minSpeed = currentSpeed;
                    }

                    // ReSharper restore CompareOfFloatsByEqualityOperator
                    #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                    PulseProgress?.Invoke($"Reading sector {i} at lead-out ({currentSpeed:F3} MiB/sec.)");

                    if (readcd)
                    {
                        sense = _dev.ReadCd(out cmdBuf, out _, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes, false,
                                            false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
                                            supportedSubchannel, _dev.Timeout, out cmdDuration);

                        totalDuration += cmdDuration;
                    }
                    else if (read16)
                    {
                        sense = _dev.Read16(out cmdBuf, out _, 0, false, true, false, i, blockSize, 0, 1, false,
                                            _dev.Timeout, out cmdDuration);
                    }
                    else if (read12)
                    {
                        sense = _dev.Read12(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
                                            false, _dev.Timeout, out cmdDuration);
                    }
                    else if (read10)
                    {
                        sense = _dev.Read10(out cmdBuf, out _, 0, false, true, false, false, (uint)i, blockSize, 0, 1,
                                            _dev.Timeout, out cmdDuration);
                    }
                    else if (read6)
                    {
                        sense = _dev.Read6(out cmdBuf, out _, (uint)i, blockSize, 1, _dev.Timeout, out cmdDuration);
                    }

                    if (!sense &&
                        !_dev.Error)
                    {
                        mhddLog.Write(i, cmdDuration);
                        ibgLog.Write(i, currentSpeed * 1024);
                        extents.Add(i, _maximumReadable, true);
                        leadOutExtents.Remove(i);
                        DateTime writeStart = DateTime.Now;

                        if (supportedSubchannel != MmcSubchannel.None)
                        {
                            byte[] data = new byte[sectorSize * _maximumReadable];
                            byte[] sub  = new byte[subSize * _maximumReadable];

                            for (int b = 0; b < _maximumReadable; b++)
                            {
                                Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), data, sectorSize * b, sectorSize);

                                Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
                            }

                            _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
                            _outputPlugin.WriteSectorsTag(sub, i, _maximumReadable, SectorTagType.CdSectorSubchannel);
                        }
                        else
                        {
                            _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);
                        }

                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                    }
                    else
                    {
                        // TODO: Reset device after X errors
                        if (_stopOnError)
                        {
                            return; // TODO: Return more cleanly
                        }
                        // Write empty data
                        DateTime writeStart = DateTime.Now;

                        if (supportedSubchannel != MmcSubchannel.None)
                        {
                            _outputPlugin.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);

                            _outputPlugin.WriteSectorsTag(new byte[subSize * _skip], i, 1,
                                                          SectorTagType.CdSectorSubchannel);
                        }
                        else
                        {
                            _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, 1);
                        }

                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

                        mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                        ibgLog.Write(i, 0);
                    }

                    double newSpeed = ((double)blockSize * _maximumReadable) / 1048576 / (cmdDuration / 1000);

                    if (!double.IsInfinity(newSpeed))
                    {
                        currentSpeed = newSpeed;
                    }

                    _resume.NextBlock = i + 1;
                }
            }

            EndProgress?.Invoke();
        }
예제 #25
0
        /// <summary>Dumps an ATA device</summary>
        public void Ata()
        {
            if (dumpRaw)
            {
                if (force)
                {
                    ErrorMessage?.Invoke("Raw dumping not yet supported in ATA devices, continuing...");
                }
                else
                {
                    StoppingErrorMessage?.Invoke("Raw dumping not yet supported in ATA devices, aborting...");

                    return;
                }
            }

            const ushort ATA_PROFILE        = 0x0001;
            const uint   TIMEOUT            = 5;
            double       imageWriteDuration = 0;

            UpdateStatus?.Invoke("Requesting ATA IDENTIFY DEVICE.");
            dumpLog.WriteLine("Requesting ATA IDENTIFY DEVICE.");
            bool sense = dev.AtaIdentify(out byte[] cmdBuf, out _);

            if (!sense &&
                Identify.Decode(cmdBuf).HasValue)
            {
                Identify.IdentifyDevice?ataIdNullable = Identify.Decode(cmdBuf);

                if (ataIdNullable != null)
                {
                    Identify.IdentifyDevice ataId = ataIdNullable.Value;
                    byte[] ataIdentify            = cmdBuf;
                    cmdBuf = new byte[0];

                    DateTime start;
                    DateTime end;
                    double   totalDuration = 0;
                    double   currentSpeed  = 0;
                    double   maxSpeed      = double.MinValue;
                    double   minSpeed      = double.MaxValue;

                    // Initializate reader
                    UpdateStatus?.Invoke("Initializing reader.");
                    dumpLog.WriteLine("Initializing reader.");
                    var ataReader = new Reader(dev, TIMEOUT, ataIdentify);

                    // Fill reader blocks
                    ulong blocks = ataReader.GetDeviceBlocks();

                    // Check block sizes
                    if (ataReader.GetBlockSize())
                    {
                        dumpLog.WriteLine("ERROR: Cannot get block size: {0}.", ataReader.ErrorMessage);
                        ErrorMessage(ataReader.ErrorMessage);

                        return;
                    }

                    uint blockSize          = ataReader.LogicalBlockSize;
                    uint physicalsectorsize = ataReader.PhysicalBlockSize;

                    if (ataReader.FindReadCommand())
                    {
                        dumpLog.WriteLine("ERROR: Cannot find correct read command: {0}.", ataReader.ErrorMessage);
                        ErrorMessage(ataReader.ErrorMessage);

                        return;
                    }

                    // Check how many blocks to read, if error show and return
                    if (ataReader.GetBlocksToRead())
                    {
                        dumpLog.WriteLine("ERROR: Cannot get blocks to read: {0}.", ataReader.ErrorMessage);
                        ErrorMessage(ataReader.ErrorMessage);

                        return;
                    }

                    uint   blocksToRead = ataReader.BlocksToRead;
                    ushort cylinders    = ataReader.Cylinders;
                    byte   heads        = ataReader.Heads;
                    byte   sectors      = ataReader.Sectors;

                    UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * blockSize} bytes).");

                    UpdateStatus?.
                    Invoke($"Device reports {cylinders} cylinders {heads} heads {sectors} sectors per track.");

                    UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
                    UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block.");
                    UpdateStatus?.Invoke($"Device reports {physicalsectorsize} bytes per physical block.");
                    dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);

                    dumpLog.WriteLine("Device reports {0} cylinders {1} heads {2} sectors per track.", cylinders, heads,
                                      sectors);

                    dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
                    dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
                    dumpLog.WriteLine("Device reports {0} bytes per physical block.", physicalsectorsize);

                    bool removable = !dev.IsCompactFlash &&
                                     ataId.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.Removable);

                    DumpHardwareType currentTry = null;
                    ExtentsULong     extents    = null;

                    ResumeSupport.Process(ataReader.IsLba, removable, blocks, dev.Manufacturer, dev.Model, dev.Serial,
                                          dev.PlatformId, ref resume, ref currentTry, ref extents);

                    if (currentTry == null ||
                        extents == null)
                    {
                        StoppingErrorMessage?.Invoke("Could not process resume file, not continuing...");

                        return;
                    }

                    MhddLog mhddLog;
                    IbgLog  ibgLog;
                    double  duration;

                    bool ret = true;

                    if (dev.IsUsb &&
                        dev.UsbDescriptors != null &&
                        !outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors))
                    {
                        ret = false;
                        dumpLog.WriteLine("Output format does not support USB descriptors.");
                        ErrorMessage("Output format does not support USB descriptors.");
                    }

                    if (dev.IsPcmcia &&
                        dev.Cis != null &&
                        !outputPlugin.SupportedMediaTags.Contains(MediaTagType.PCMCIA_CIS))
                    {
                        ret = false;
                        dumpLog.WriteLine("Output format does not support PCMCIA CIS descriptors.");
                        ErrorMessage("Output format does not support PCMCIA CIS descriptors.");
                    }

                    if (!outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
                    {
                        ret = false;
                        dumpLog.WriteLine("Output format does not support ATA IDENTIFY.");
                        ErrorMessage("Output format does not support ATA IDENTIFY.");
                    }

                    if (!ret)
                    {
                        dumpLog.WriteLine("Several media tags not supported, {0}continuing...", force ? "" : "not ");

                        if (force)
                        {
                            ErrorMessage("Several media tags not supported, continuing...");
                        }
                        else
                        {
                            StoppingErrorMessage?.Invoke("Several media tags not supported, not continuing...");

                            return;
                        }
                    }

                    ret = outputPlugin.Create(outputPath,
                                              dev.IsCompactFlash ? MediaType.CompactFlash : MediaType.GENERIC_HDD,
                                              formatOptions, blocks, blockSize);

                    // Cannot create image
                    if (!ret)
                    {
                        dumpLog.WriteLine("Error creating output image, not continuing.");
                        dumpLog.WriteLine(outputPlugin.ErrorMessage);

                        StoppingErrorMessage?.Invoke("Error creating output image, not continuing." +
                                                     Environment.NewLine +
                                                     outputPlugin.ErrorMessage);

                        return;
                    }

                    // Setting geometry
                    outputPlugin.SetGeometry(cylinders, heads, sectors);

                    if (ataReader.IsLba)
                    {
                        UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");

                        if (skip < blocksToRead)
                        {
                            skip = blocksToRead;
                        }

                        mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
                        ibgLog  = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE);

                        if (resume.NextBlock > 0)
                        {
                            UpdateStatus?.Invoke($"Resuming from block {resume.NextBlock}.");
                            dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);
                        }

                        bool newTrim = false;

                        start = DateTime.UtcNow;
                        DateTime timeSpeedStart   = DateTime.UtcNow;
                        ulong    sectorSpeedStart = 0;
                        InitProgress?.Invoke();

                        for (ulong i = resume.NextBlock; i < blocks; i += blocksToRead)
                        {
                            if (aborted)
                            {
                                currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                                UpdateStatus?.Invoke("Aborted!");
                                dumpLog.WriteLine("Aborted!");

                                break;
                            }

                            if (blocks - i < blocksToRead)
                            {
                                blocksToRead = (byte)(blocks - i);
                            }

                            #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                            if (currentSpeed > maxSpeed &&
                                currentSpeed != 0)
                            {
                                maxSpeed = currentSpeed;
                            }

                            if (currentSpeed < minSpeed &&
                                currentSpeed != 0)
                            {
                                minSpeed = currentSpeed;
                            }
                            #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                            UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)",
                                                   (long)i, (long)blocks);

                            bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);

                            if (!error)
                            {
                                mhddLog.Write(i, duration);
                                ibgLog.Write(i, currentSpeed * 1024);
                                DateTime writeStart = DateTime.Now;
                                outputPlugin.WriteSectors(cmdBuf, i, blocksToRead);
                                imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                                extents.Add(i, blocksToRead, true);
                            }
                            else
                            {
                                if (i + skip > blocks)
                                {
                                    skip = (uint)(blocks - i);
                                }

                                for (ulong b = i; b < i + skip; b++)
                                {
                                    resume.BadBlocks.Add(b);
                                }

                                mhddLog.Write(i, duration < 500 ? 65535 : duration);

                                ibgLog.Write(i, 0);
                                DateTime writeStart = DateTime.Now;
                                outputPlugin.WriteSectors(new byte[blockSize * skip], i, skip);
                                imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                                dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", skip, i);
                                i      += skip - blocksToRead;
                                newTrim = true;
                            }

                            sectorSpeedStart += blocksToRead;
                            resume.NextBlock  = i + blocksToRead;

                            double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                            if (elapsed < 1)
                            {
                                continue;
                            }

                            currentSpeed     = sectorSpeedStart * blockSize / (1048576 * elapsed);
                            sectorSpeedStart = 0;
                            timeSpeedStart   = DateTime.UtcNow;
                        }

                        end = DateTime.Now;
                        EndProgress?.Invoke();
                        mhddLog.Close();

                        ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                                     blockSize * (double)(blocks + 1) / 1024 /
                                     (totalDuration / 1000), devicePath);

                        UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");

                        UpdateStatus?.
                        Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec.");

                        UpdateStatus?.
                        Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration:F3} KiB/sec.");

                        dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);

                        dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
                                          (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));

                        dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
                                          (double)blockSize * (double)(blocks + 1) / 1024 / imageWriteDuration);

                        #region Trimming
                        if (resume.BadBlocks.Count > 0 &&
                            !aborted &&
                            !notrim &&
                            newTrim)
                        {
                            start = DateTime.UtcNow;
                            UpdateStatus?.Invoke("Trimming bad sectors");
                            dumpLog.WriteLine("Trimming bad sectors");

                            ulong[] tmpArray = resume.BadBlocks.ToArray();
                            InitProgress?.Invoke();

                            foreach (ulong badSector in tmpArray)
                            {
                                if (aborted)
                                {
                                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                                    UpdateStatus?.Invoke("Aborted!");
                                    dumpLog.WriteLine("Aborted!");

                                    break;
                                }

                                PulseProgress?.Invoke($"Trimming sector {badSector}");

                                bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);

                                totalDuration += duration;

                                if (error)
                                {
                                    continue;
                                }

                                resume.BadBlocks.Remove(badSector);
                                extents.Add(badSector);
                                outputPlugin.WriteSector(cmdBuf, badSector);
                            }

                            EndProgress?.Invoke();
                            end = DateTime.UtcNow;
                            UpdateStatus?.Invoke($"Trimmming finished in {(end - start).TotalSeconds} seconds.");
                            dumpLog.WriteLine("Trimmming finished in {0} seconds.", (end - start).TotalSeconds);
                        }
                        #endregion Trimming

                        #region Error handling
                        if (resume.BadBlocks.Count > 0 &&
                            !aborted &&
                            retryPasses > 0)
                        {
                            int  pass    = 1;
                            bool forward = true;

                            InitProgress?.Invoke();
repeatRetryLba:
                            ulong[] tmpArray = resume.BadBlocks.ToArray();

                            foreach (ulong badSector in tmpArray)
                            {
                                if (aborted)
                                {
                                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                                    UpdateStatus?.Invoke("Aborted!");
                                    dumpLog.WriteLine("Aborted!");

                                    break;
                                }

                                PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector,
                                                                    pass, forward ? "forward" : "reverse",
                                                                    persistent ? "recovering partial data, " : ""));

                                bool error = ataReader.ReadBlock(out cmdBuf, badSector, out duration);

                                totalDuration += duration;

                                if (!error)
                                {
                                    resume.BadBlocks.Remove(badSector);
                                    extents.Add(badSector);
                                    outputPlugin.WriteSector(cmdBuf, badSector);
                                    UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
                                    dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
                                }
                                else if (persistent)
                                {
                                    outputPlugin.WriteSector(cmdBuf, badSector);
                                }
                            }

                            if (pass < retryPasses &&
                                !aborted &&
                                resume.BadBlocks.Count > 0)
                            {
                                pass++;
                                forward = !forward;
                                resume.BadBlocks.Sort();
                                resume.BadBlocks.Reverse();

                                goto repeatRetryLba;
                            }

                            EndProgress?.Invoke();
                        }
                        #endregion Error handling LBA

                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                    }
                    else
                    {
                        mhddLog = new MhddLog(outputPrefix + ".mhddlog.bin", dev, blocks, blockSize, blocksToRead);
                        ibgLog  = new IbgLog(outputPrefix + ".ibg", ATA_PROFILE);

                        ulong currentBlock = 0;
                        blocks = (ulong)(cylinders * heads * sectors);
                        start  = DateTime.UtcNow;
                        DateTime timeSpeedStart   = DateTime.UtcNow;
                        ulong    sectorSpeedStart = 0;
                        InitProgress?.Invoke();

                        for (ushort cy = 0; cy < cylinders; cy++)
                        {
                            for (byte hd = 0; hd < heads; hd++)
                            {
                                for (byte sc = 1; sc < sectors; sc++)
                                {
                                    if (aborted)
                                    {
                                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                                        UpdateStatus?.Invoke("Aborted!");
                                        dumpLog.WriteLine("Aborted!");

                                        break;
                                    }

                                    #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                                    if (currentSpeed > maxSpeed &&
                                        currentSpeed != 0)
                                    {
                                        maxSpeed = currentSpeed;
                                    }

                                    if (currentSpeed < minSpeed &&
                                        currentSpeed != 0)
                                    {
                                        minSpeed = currentSpeed;
                                    }
                                    #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                                    PulseProgress?.
                                    Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");

                                    bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);

                                    totalDuration += duration;

                                    if (!error)
                                    {
                                        mhddLog.Write(currentBlock, duration);
                                        ibgLog.Write(currentBlock, currentSpeed * 1024);
                                        DateTime writeStart = DateTime.Now;

                                        outputPlugin.WriteSector(cmdBuf,
                                                                 (ulong)((cy * heads + hd) * sectors + (sc - 1)));

                                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                                        extents.Add(currentBlock);

                                        dumpLog.WriteLine("Error reading cylinder {0} head {1} sector {2}.", cy, hd,
                                                          sc);
                                    }
                                    else
                                    {
                                        resume.BadBlocks.Add(currentBlock);
                                        mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);

                                        ibgLog.Write(currentBlock, 0);
                                        DateTime writeStart = DateTime.Now;

                                        outputPlugin.WriteSector(new byte[blockSize],
                                                                 (ulong)((cy * heads + hd) * sectors + (sc - 1)));

                                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                                    }

                                    sectorSpeedStart++;
                                    currentBlock++;

                                    double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                                    if (elapsed < 1)
                                    {
                                        continue;
                                    }

                                    currentSpeed     = sectorSpeedStart * blockSize / (1048576 * elapsed);
                                    sectorSpeedStart = 0;
                                    timeSpeedStart   = DateTime.UtcNow;
                                }
                            }
                        }

                        end = DateTime.Now;
                        EndProgress?.Invoke();
                        mhddLog.Close();

                        ibgLog.Close(dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                                     blockSize * (double)(blocks + 1) / 1024 /
                                     (totalDuration / 1000), devicePath);

                        UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");

                        UpdateStatus?.
                        Invoke($"Average dump speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000):F3} KiB/sec.");

                        UpdateStatus?.
                        Invoke($"Average write speed {(double)blockSize * (double)(blocks + 1) / 1024 / (imageWriteDuration / 1000):F3} KiB/sec.");

                        dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);

                        dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
                                          (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000));

                        dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
                                          (double)blockSize * (double)(blocks + 1) / 1024 /
                                          (imageWriteDuration / 1000));
                    }

                    foreach (ulong bad in resume.BadBlocks)
                    {
                        dumpLog.WriteLine("Sector {0} could not be read.", bad);
                    }

                    outputPlugin.SetDumpHardware(resume.Tries);

                    if (preSidecar != null)
                    {
                        outputPlugin.SetCicmMetadata(preSidecar);
                    }

                    dumpLog.WriteLine("Closing output file.");
                    UpdateStatus?.Invoke("Closing output file.");
                    DateTime closeStart = DateTime.Now;
                    outputPlugin.Close();
                    DateTime closeEnd = DateTime.Now;
                    UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
                    dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

                    if (aborted)
                    {
                        dumpLog.WriteLine("Aborted!");
                        UpdateStatus?.Invoke("Aborted!");

                        return;
                    }

                    double totalChkDuration = 0;

                    if (!nometadata)
                    {
                        dumpLog.WriteLine("Creating sidecar.");
                        UpdateStatus?.Invoke("Creating sidecar.");
                        var         filters     = new FiltersList();
                        IFilter     filter      = filters.GetFilter(outputPath);
                        IMediaImage inputPlugin = ImageFormat.Detect(filter);

                        if (!inputPlugin.Open(filter))
                        {
                            StoppingErrorMessage?.Invoke("Could not open created image.");

                            return;
                        }

                        DateTime chkStart = DateTime.UtcNow;
                        sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding);
                        sidecarClass.InitProgressEvent    += InitProgress;
                        sidecarClass.UpdateProgressEvent  += UpdateProgress;
                        sidecarClass.EndProgressEvent     += EndProgress;
                        sidecarClass.InitProgressEvent2   += InitProgress2;
                        sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
                        sidecarClass.EndProgressEvent2    += EndProgress2;
                        sidecarClass.UpdateStatusEvent    += UpdateStatus;
                        CICMMetadataType sidecar = sidecarClass.Create();

                        if (preSidecar != null)
                        {
                            preSidecar.BlockMedia = sidecar.BlockMedia;
                            sidecar = preSidecar;
                        }

                        if (dev.IsUsb &&
                            dev.UsbDescriptors != null)
                        {
                            dumpLog.WriteLine("Reading USB descriptors.");
                            UpdateStatus?.Invoke("Reading USB descriptors.");
                            ret = outputPlugin.WriteMediaTag(dev.UsbDescriptors, MediaTagType.USB_Descriptors);

                            if (ret)
                            {
                                sidecar.BlockMedia[0].USB = new USBType
                                {
                                    ProductID = dev.UsbProductId, VendorID = dev.UsbVendorId, Descriptors = new DumpType
                                    {
                                        Image     = outputPath, Size = (ulong)dev.UsbDescriptors.Length,
                                        Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray()
                                    }
                                }
                            }
                            ;
                        }

                        if (dev.IsPcmcia &&
                            dev.Cis != null)
                        {
                            dumpLog.WriteLine("Reading PCMCIA CIS.");
                            UpdateStatus?.Invoke("Reading PCMCIA CIS.");
                            ret = outputPlugin.WriteMediaTag(dev.Cis, MediaTagType.PCMCIA_CIS);

                            if (ret)
                            {
                                sidecar.BlockMedia[0].PCMCIA = new PCMCIAType
                                {
                                    CIS = new DumpType
                                    {
                                        Image     = outputPath, Size = (ulong)dev.Cis.Length,
                                        Checksums = Checksum.GetChecksums(dev.Cis).ToArray()
                                    }
                                }
                            }
                            ;

                            dumpLog.WriteLine("Decoding PCMCIA CIS.");
                            UpdateStatus?.Invoke("Decoding PCMCIA CIS.");
                            Tuple[] tuples = CIS.GetTuples(dev.Cis);

                            if (tuples != null)
                            {
                                foreach (Tuple tuple in tuples)
                                {
                                    switch (tuple.Code)
                                    {
                                    case TupleCodes.CISTPL_MANFID:
                                        ManufacturerIdentificationTuple manfid =
                                            CIS.DecodeManufacturerIdentificationTuple(tuple);

                                        if (manfid != null)
                                        {
                                            sidecar.BlockMedia[0].PCMCIA.ManufacturerCode =
                                                manfid.ManufacturerID;

                                            sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID;
                                            sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true;
                                            sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified         = true;
                                        }

                                        break;

                                    case TupleCodes.CISTPL_VERS_1:
                                        Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple);

                                        if (vers != null)
                                        {
                                            sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer;
                                            sidecar.BlockMedia[0].PCMCIA.ProductName  = vers.Product;

                                            sidecar.BlockMedia[0].PCMCIA.Compliance =
                                                $"{vers.MajorVersion}.{vers.MinorVersion}";

                                            sidecar.BlockMedia[0].PCMCIA.AdditionalInformation =
                                                vers.AdditionalInformation;
                                        }

                                        break;
                                    }
                                }
                            }
                        }

                        ret = outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY);

                        if (ret)
                        {
                            sidecar.BlockMedia[0].ATA = new ATAType
                            {
                                Identify = new DumpType
                                {
                                    Image     = outputPath, Size = (ulong)cmdBuf.Length,
                                    Checksums = Checksum.GetChecksums(cmdBuf).ToArray()
                                }
                            }
                        }
                        ;

                        DateTime chkEnd = DateTime.UtcNow;

                        totalChkDuration = (chkEnd - chkStart).TotalMilliseconds;
                        UpdateStatus?.Invoke($"Sidecar created in {(chkEnd - chkStart).TotalSeconds} seconds.");

                        UpdateStatus?.
                        Invoke($"Average checksum speed {(double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000):F3} KiB/sec.");

                        dumpLog.WriteLine("Sidecar created in {0} seconds.", (chkEnd - chkStart).TotalSeconds);

                        dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
                                          (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000));

                        List <(ulong start, string type)> filesystems = new List <(ulong start, string type)>();

                        if (sidecar.BlockMedia[0].FileSystemInformation != null)
                        {
                            filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation
                                                 where partition.FileSystems != null
                                                 from fileSystem in partition.FileSystems
                                                 select(partition.StartSector, fileSystem.Type));
                        }

                        if (filesystems.Count > 0)
                        {
                            foreach (var filesystem in filesystems.Select(o => new
                            {
                                o.start, o.type
                            }).Distinct())
                            {
                                UpdateStatus?.
                                Invoke($"Found filesystem {filesystem.type} at sector {filesystem.start}");

                                dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type,
                                                  filesystem.start);
                            }
                        }

                        (string type, string subType)xmlType;

                        if (dev.IsCompactFlash)
                        {
                            xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash);
                        }
                        else if (dev.IsPcmcia)
                        {
                            xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI);
                        }
                        else
                        {
                            xmlType = CommonTypes.Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD);
                        }

                        sidecar.BlockMedia[0].DiskType          = xmlType.type;
                        sidecar.BlockMedia[0].DiskSubType       = xmlType.subType;
                        sidecar.BlockMedia[0].Interface         = "ATA";
                        sidecar.BlockMedia[0].LogicalBlocks     = blocks;
                        sidecar.BlockMedia[0].PhysicalBlockSize = physicalsectorsize;
                        sidecar.BlockMedia[0].LogicalBlockSize  = blockSize;
                        sidecar.BlockMedia[0].Manufacturer      = dev.Manufacturer;
                        sidecar.BlockMedia[0].Model             = dev.Model;
                        sidecar.BlockMedia[0].Serial            = dev.Serial;
                        sidecar.BlockMedia[0].Size = blocks * blockSize;

                        if (cylinders > 0 &&
                            heads > 0 &&
                            sectors > 0)
                        {
                            sidecar.BlockMedia[0].Cylinders          = cylinders;
                            sidecar.BlockMedia[0].CylindersSpecified = true;
                            sidecar.BlockMedia[0].Heads                    = heads;
                            sidecar.BlockMedia[0].HeadsSpecified           = true;
                            sidecar.BlockMedia[0].SectorsPerTrack          = sectors;
                            sidecar.BlockMedia[0].SectorsPerTrackSpecified = true;
                        }

                        UpdateStatus?.Invoke("Writing metadata sidecar");

                        var xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create);

                        var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
                        xmlSer.Serialize(xmlFs, sidecar);
                        xmlFs.Close();
                    }

                    UpdateStatus?.Invoke("");

                    UpdateStatus?.
                    Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");

                    UpdateStatus?.
                    Invoke($"Average speed: {(double)blockSize * (double)(blocks + 1) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");

                    UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
                    UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
                    UpdateStatus?.Invoke($"{resume.BadBlocks.Count} sectors could not be read.");

                    if (resume.BadBlocks.Count > 0)
                    {
                        resume.BadBlocks.Sort();
                    }

                    UpdateStatus?.Invoke("");
                }

                if (dev.IsCompactFlash)
                {
                    Statistics.AddMedia(MediaType.CompactFlash, true);
                }
                else if (dev.IsPcmcia)
                {
                    Statistics.AddMedia(MediaType.PCCardTypeI, true);
                }
                else
                {
                    Statistics.AddMedia(MediaType.GENERIC_HDD, true);
                }
            }
            else
            {
                StoppingErrorMessage?.Invoke("Unable to communicate with ATA device.");
            }
        }
    }
}
예제 #26
0
파일: UMD.cs 프로젝트: paulyc/Aaru
        void DumpUmd()
        {
            const uint      blockSize     = 2048;
            const MediaType dskType       = MediaType.UMD;
            uint            blocksToRead  = 16;
            double          totalDuration = 0;
            double          currentSpeed  = 0;
            double          maxSpeed      = double.MinValue;
            double          minSpeed      = double.MaxValue;
            DateTime        start;
            DateTime        end;

            byte[] senseBuf;

            bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
                                     _dev.Timeout, out _);

            if (sense)
            {
                _dumpLog.WriteLine("Could not read...");
                StoppingErrorMessage?.Invoke("Could not read...");

                return;
            }

            ushort fatStart      = (ushort)((readBuffer[0x0F] << 8) + readBuffer[0x0E]);
            ushort sectorsPerFat = (ushort)((readBuffer[0x17] << 8) + readBuffer[0x16]);
            ushort rootStart     = (ushort)((sectorsPerFat * 2) + fatStart);
            ushort rootSize      = (ushort)((((readBuffer[0x12] << 8) + readBuffer[0x11]) * 32) / 512);
            ushort umdStart      = (ushort)(rootStart + rootSize);

            UpdateStatus?.Invoke($"Reading root directory in sector {rootStart}...");
            _dumpLog.WriteLine("Reading root directory in sector {0}...", rootStart);

            sense = _dev.Read12(out readBuffer, out _, 0, false, true, false, false, rootStart, 512, 0, 1, false,
                                _dev.Timeout, out _);

            if (sense)
            {
                _dumpLog.WriteLine("Could not read...");
                StoppingErrorMessage?.Invoke("Could not read...");

                return;
            }

            uint   umdSizeInBytes  = BitConverter.ToUInt32(readBuffer, 0x3C);
            ulong  blocks          = umdSizeInBytes / blockSize;
            string mediaPartNumber = Encoding.ASCII.GetString(readBuffer, 0, 11).Trim();

            ulong totalSize = blocks * blockSize;

            if (totalSize > 1099511627776)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1099511627776d:F3} TiB)");
            }
            else if (totalSize > 1073741824)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1073741824d:F3} GiB)");
            }
            else if (totalSize > 1048576)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1048576d:F3} MiB)");
            }
            else if (totalSize > 1024)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1024d:F3} KiB)");
            }
            else
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize} bytes)");
            }

            UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * blockSize} bytes).");
            UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
            UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block.");
            UpdateStatus?.Invoke($"Device reports {2048} bytes per physical block.");
            UpdateStatus?.Invoke($"SCSI device type: {_dev.ScsiType}.");
            UpdateStatus?.Invoke($"Media identified as {dskType}.");
            UpdateStatus?.Invoke($"Media part number is {mediaPartNumber}.");
            _dumpLog.WriteLine("Device reports {0} blocks ({1} bytes).", blocks, blocks * blockSize);
            _dumpLog.WriteLine("Device can read {0} blocks at a time.", blocksToRead);
            _dumpLog.WriteLine("Device reports {0} bytes per logical block.", blockSize);
            _dumpLog.WriteLine("Device reports {0} bytes per physical block.", 2048);
            _dumpLog.WriteLine("SCSI device type: {0}.", _dev.ScsiType);
            _dumpLog.WriteLine("Media identified as {0}.", dskType);
            _dumpLog.WriteLine("Media part number is {0}.", mediaPartNumber);

            bool ret;

            var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
            var ibgLog  = new IbgLog(_outputPrefix + ".ibg", 0x0010);

            ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);

            // Cannot create image
            if (!ret)
            {
                _dumpLog.WriteLine("Error creating output image, not continuing.");
                _dumpLog.WriteLine(_outputPlugin.ErrorMessage);

                StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
                                             _outputPlugin.ErrorMessage);

                return;
            }

            start = DateTime.UtcNow;
            double imageWriteDuration = 0;

            (_outputPlugin as IWritableOpticalImage)?.SetTracks(new List <Track>
            {
                new Track
                {
                    TrackBytesPerSector    = (int)blockSize,
                    TrackEndSector         = blocks - 1,
                    TrackSequence          = 1,
                    TrackRawBytesPerSector = (int)blockSize,
                    TrackSubchannelType    = TrackSubchannelType.None,
                    TrackSession           = 1,
                    TrackType = TrackType.Data
                }
            });

            DumpHardwareType currentTry = null;
            ExtentsULong     extents    = null;

            ResumeSupport.Process(true, _dev.IsRemovable, blocks, _dev.Manufacturer, _dev.Model, _dev.Serial,
                                  _dev.PlatformId, ref _resume, ref currentTry, ref extents, _dev.FirmwareRevision,
                                  _private);

            if (currentTry == null ||
                extents == null)
            {
                StoppingErrorMessage?.Invoke("Could not process resume file, not continuing...");

                return;
            }

            if (_resume.NextBlock > 0)
            {
                _dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
            }

            bool newTrim = false;

            DateTime timeSpeedStart   = DateTime.UtcNow;
            ulong    sectorSpeedStart = 0;

            InitProgress?.Invoke();

            for (ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
            {
                if (_aborted)
                {
                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                    UpdateStatus?.Invoke("Aborted!");
                    _dumpLog.WriteLine("Aborted!");

                    break;
                }

                if (blocks - i < blocksToRead)
                {
                    blocksToRead = (uint)(blocks - i);
                }

                if (currentSpeed > maxSpeed &&
                    currentSpeed > 0)
                {
                    maxSpeed = currentSpeed;
                }

                if (currentSpeed < minSpeed &&
                    currentSpeed > 0)
                {
                    minSpeed = currentSpeed;
                }

                UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
                                       (long)blocks);

                sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
                                    (uint)(umdStart + (i * 4)), 512, 0, blocksToRead * 4, false, _dev.Timeout,
                                    out double cmdDuration);

                totalDuration += cmdDuration;

                if (!sense &&
                    !_dev.Error)
                {
                    mhddLog.Write(i, cmdDuration);
                    ibgLog.Write(i, currentSpeed * 1024);
                    DateTime writeStart = DateTime.Now;
                    _outputPlugin.WriteSectors(readBuffer, i, blocksToRead);
                    imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                    extents.Add(i, blocksToRead, true);
                }
                else
                {
                    _errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);

                    // TODO: Reset device after X errors
                    if (_stopOnError)
                    {
                        return; // TODO: Return more cleanly
                    }
                    if (i + _skip > blocks)
                    {
                        _skip = (uint)(blocks - i);
                    }

                    // Write empty data
                    DateTime writeStart = DateTime.Now;
                    _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip);
                    imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

                    for (ulong b = i; b < i + _skip; b++)
                    {
                        _resume.BadBlocks.Add(b);
                    }

                    mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                    ibgLog.Write(i, 0);
                    _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
                    i      += _skip - blocksToRead;
                    newTrim = true;
                }

                sectorSpeedStart += blocksToRead;
                _resume.NextBlock = i + blocksToRead;

                double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                if (elapsed < 1)
                {
                    continue;
                }

                currentSpeed     = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                sectorSpeedStart = 0;
                timeSpeedStart   = DateTime.UtcNow;
            }

            _resume.BadBlocks = _resume.BadBlocks.Distinct().ToList();

            end = DateTime.UtcNow;
            EndProgress?.Invoke();
            mhddLog.Close();

            ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                         (blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000), _devicePath);

            UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");

            UpdateStatus?.
            Invoke($"Average dump speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000):F3} KiB/sec.");

            UpdateStatus?.
            Invoke($"Average write speed {((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration:F3} KiB/sec.");

            _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);

            _dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
                               ((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000));

            _dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
                               ((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);

            #region Trimming
            if (_resume.BadBlocks.Count > 0 &&
                !_aborted &&
                _trim &&
                newTrim)
            {
                start = DateTime.UtcNow;
                _dumpLog.WriteLine("Trimming skipped sectors");

                ulong[] tmpArray = _resume.BadBlocks.ToArray();
                InitProgress?.Invoke();

                foreach (ulong badSector in tmpArray)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    PulseProgress?.Invoke($"Trimming sector {badSector}");

                    sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
                                        (uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
                                        out double _);

                    if (sense || _dev.Error)
                    {
                        _errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);

                        continue;
                    }

                    _resume.BadBlocks.Remove(badSector);
                    extents.Add(badSector);
                    _outputPlugin.WriteSector(readBuffer, badSector);
                }

                EndProgress?.Invoke();
                end = DateTime.UtcNow;
                _dumpLog.WriteLine("Trimming finished in {0} seconds.", (end - start).TotalSeconds);
            }
            #endregion Trimming

            #region Error handling
            if (_resume.BadBlocks.Count > 0 &&
                !_aborted &&
                _retryPasses > 0)
            {
                int  pass              = 1;
                bool forward           = true;
                bool runningPersistent = false;

                Modes.ModePage?currentModePage = null;
                byte[]         md6;

                if (_persistent)
                {
                    Modes.ModePage_01 pg;

                    sense = _dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
                                            _dev.Timeout, out _);

                    if (!sense)
                    {
                        Modes.DecodedMode?dcMode6 = Modes.DecodeMode6(readBuffer, _dev.ScsiType);

                        if (dcMode6.HasValue)
                        {
                            foreach (Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
                                                                                          modePage.Page == 0x01 && modePage.Subpage == 0x00))
                            {
                                currentModePage = modePage;
                            }
                        }
                    }

                    if (currentModePage == null)
                    {
                        pg = new Modes.ModePage_01
                        {
                            PS             = false,
                            AWRE           = true,
                            ARRE           = true,
                            TB             = false,
                            RC             = false,
                            EER            = true,
                            PER            = false,
                            DTE            = true,
                            DCR            = false,
                            ReadRetryCount = 32
                        };

                        currentModePage = new Modes.ModePage
                        {
                            Page         = 0x01,
                            Subpage      = 0x00,
                            PageResponse = Modes.EncodeModePage_01(pg)
                        };
                    }

                    pg = new Modes.ModePage_01
                    {
                        PS             = false,
                        AWRE           = false,
                        ARRE           = false,
                        TB             = true,
                        RC             = false,
                        EER            = true,
                        PER            = false,
                        DTE            = false,
                        DCR            = false,
                        ReadRetryCount = 255
                    };

                    var md = new Modes.DecodedMode
                    {
                        Header = new Modes.ModeHeader(),
                        Pages  = new[]
                        {
                            new Modes.ModePage
                            {
                                Page         = 0x01,
                                Subpage      = 0x00,
                                PageResponse = Modes.EncodeModePage_01(pg)
                            }
                        }
                    };

                    md6 = Modes.EncodeMode6(md, _dev.ScsiType);

                    _dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks).");
                    sense = _dev.ModeSelect(md6, out senseBuf, true, false, _dev.Timeout, out _);

                    if (sense)
                    {
                        UpdateStatus?.
                        Invoke("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");

                        AaruConsole.DebugWriteLine("Error: {0}", Sense.PrettifySense(senseBuf));

                        _dumpLog.
                        WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
                    }
                    else
                    {
                        runningPersistent = true;
                    }
                }

                InitProgress?.Invoke();
repeatRetry:
                ulong[] tmpArray = _resume.BadBlocks.ToArray();

                foreach (ulong badSector in tmpArray)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    PulseProgress?.
                    Invoke($"Retrying sector {badSector}, pass {pass}, {(runningPersistent ? "recovering partial data, " : "")}{(forward ? "forward" : "reverse")}");

                    sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false,
                                        (uint)(umdStart + (badSector * 4)), 512, 0, 4, false, _dev.Timeout,
                                        out double cmdDuration);

                    totalDuration += cmdDuration;

                    if (sense || _dev.Error)
                    {
                        _errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
                    }

                    if (!sense &&
                        !_dev.Error)
                    {
                        _resume.BadBlocks.Remove(badSector);
                        extents.Add(badSector);
                        _outputPlugin.WriteSector(readBuffer, badSector);

                        UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");

                        _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
                    }
                    else if (runningPersistent)
                    {
                        _outputPlugin.WriteSector(readBuffer, badSector);
                    }
                }

                if (pass < _retryPasses &&
                    !_aborted &&
                    _resume.BadBlocks.Count > 0)
                {
                    pass++;
                    forward = !forward;
                    _resume.BadBlocks.Sort();

                    if (!forward)
                    {
                        _resume.BadBlocks.Reverse();
                    }

                    goto repeatRetry;
                }

                if (runningPersistent && currentModePage.HasValue)
                {
                    var md = new Modes.DecodedMode
                    {
                        Header = new Modes.ModeHeader(),
                        Pages  = new[]
                        {
                            currentModePage.Value
                        }
                    };

                    md6 = Modes.EncodeMode6(md, _dev.ScsiType);

                    _dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status).");
                    _dev.ModeSelect(md6, out _, true, false, _dev.Timeout, out _);
                }

                EndProgress?.Invoke();
                AaruConsole.WriteLine();
            }
            #endregion Error handling

            _resume.BadBlocks.Sort();

            foreach (ulong bad in _resume.BadBlocks)
            {
                _dumpLog.WriteLine("Sector {0} could not be read.", bad);
            }

            currentTry.Extents = ExtentsConverter.ToMetadata(extents);

            var metadata = new CommonTypes.Structs.ImageInfo
            {
                Application        = "Aaru",
                ApplicationVersion = Version.GetVersion(),
                MediaPartNumber    = mediaPartNumber
            };

            if (!_outputPlugin.SetMetadata(metadata))
            {
                ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
                                     _outputPlugin.ErrorMessage);
            }

            _outputPlugin.SetDumpHardware(_resume.Tries);

            if (_preSidecar != null)
            {
                _outputPlugin.SetCicmMetadata(_preSidecar);
            }

            _dumpLog.WriteLine("Closing output file.");
            UpdateStatus?.Invoke("Closing output file.");
            DateTime closeStart = DateTime.Now;
            _outputPlugin.Close();
            DateTime closeEnd = DateTime.Now;
            _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

            if (_aborted)
            {
                UpdateStatus?.Invoke("Aborted!");
                _dumpLog.WriteLine("Aborted!");

                return;
            }

            double totalChkDuration = 0;

            if (_metadata)
            {
                WriteOpticalSidecar(blockSize, blocks, dskType, null, null, 1, out totalChkDuration, null);
            }

            UpdateStatus?.Invoke("");

            UpdateStatus?.
            Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");

            UpdateStatus?.
            Invoke($"Average speed: {((double)blockSize * (double)(blocks + 1)) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");

            if (maxSpeed > 0)
            {
                UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
            }

            if (minSpeed > 0 &&
                minSpeed < double.MaxValue)
            {
                UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
            }

            UpdateStatus?.Invoke($"{_resume.BadBlocks.Count} sectors could not be read.");
            UpdateStatus?.Invoke("");

            Statistics.AddMedia(dskType, true);
        }
예제 #27
0
        ScanResults Scsi()
        {
            var     results = new ScanResults();
            MhddLog mhddLog;
            IbgLog  ibgLog;

            byte[] senseBuf;
            bool   sense = false;

            results.Blocks = 0;
            uint   blockSize      = 0;
            ushort currentProfile = 0x0001;

            if (dev.IsRemovable)
            {
                sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);

                if (sense)
                {
                    InitProgress?.Invoke();
                    FixedSense?decSense = Sense.DecodeFixed(senseBuf);

                    if (decSense.HasValue)
                    {
                        if (decSense.Value.ASC == 0x3A)
                        {
                            int leftRetries = 5;

                            while (leftRetries > 0)
                            {
                                PulseProgress?.Invoke("Waiting for drive to become ready");
                                Thread.Sleep(2000);
                                sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);

                                if (!sense)
                                {
                                    break;
                                }

                                leftRetries--;
                            }

                            if (sense)
                            {
                                StoppingErrorMessage?.Invoke("Please insert media in drive");

                                return(results);
                            }
                        }
                        else if (decSense.Value.ASC == 0x04 &&
                                 decSense.Value.ASCQ == 0x01)
                        {
                            int leftRetries = 10;

                            while (leftRetries > 0)
                            {
                                PulseProgress?.Invoke("Waiting for drive to become ready");
                                Thread.Sleep(2000);
                                sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);

                                if (!sense)
                                {
                                    break;
                                }

                                leftRetries--;
                            }

                            if (sense)
                            {
                                StoppingErrorMessage?.
                                Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");

                                return(results);
                            }
                        }

                        // These should be trapped by the OS but seems in some cases they're not
                        else if (decSense.Value.ASC == 0x28)
                        {
                            int leftRetries = 10;

                            while (leftRetries > 0)
                            {
                                PulseProgress?.Invoke("Waiting for drive to become ready");
                                Thread.Sleep(2000);
                                sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);

                                if (!sense)
                                {
                                    break;
                                }

                                leftRetries--;
                            }

                            if (sense)
                            {
                                StoppingErrorMessage?.
                                Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");

                                return(results);
                            }
                        }
                        else
                        {
                            StoppingErrorMessage?.
                            Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");

                            return(results);
                        }
                    }
                    else
                    {
                        StoppingErrorMessage?.Invoke("Unknown testing unit was ready.");

                        return(results);
                    }

                    EndProgress?.Invoke();
                }
            }

            Reader scsiReader = null;

            switch (dev.ScsiType)
            {
            case PeripheralDeviceTypes.DirectAccess:
            case PeripheralDeviceTypes.MultiMediaDevice:
            case PeripheralDeviceTypes.OCRWDevice:
            case PeripheralDeviceTypes.OpticalDevice:
            case PeripheralDeviceTypes.SimplifiedDevice:
            case PeripheralDeviceTypes.WriteOnceDevice:
                scsiReader     = new Reader(dev, dev.Timeout, null);
                results.Blocks = scsiReader.GetDeviceBlocks();

                if (scsiReader.FindReadCommand())
                {
                    StoppingErrorMessage?.Invoke("Unable to read medium.");

                    return(results);
                }

                blockSize = scsiReader.LogicalBlockSize;

                if (results.Blocks != 0 &&
                    blockSize != 0)
                {
                    results.Blocks++;

                    UpdateStatus?.
                    Invoke($"Media has {results.Blocks} blocks of {blockSize} bytes/each. (for a total of {results.Blocks * (ulong)blockSize} bytes)");
                }

                break;

            case PeripheralDeviceTypes.SequentialAccess:
                StoppingErrorMessage?.Invoke("Scanning will never be supported on SCSI Streaming Devices." +
                                             Environment.NewLine +
                                             "It has no sense to do it, and it will put too much strain on the tape.");

                return(results);
            }

            if (results.Blocks == 0)
            {
                StoppingErrorMessage?.Invoke("Unable to read medium or empty medium present...");

                return(results);
            }

            bool compactDisc = true;

            FullTOC.CDFullTOC?toc = null;

            if (dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice)
            {
                sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current,
                                             dev.Timeout, out _);

                if (!sense)
                {
                    Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);

                    currentProfile = ftr.CurrentProfile;

                    switch (ftr.CurrentProfile)
                    {
                    case 0x0005:
                    case 0x0008:
                    case 0x0009:
                    case 0x000A:
                    case 0x0020:
                    case 0x0021:
                    case 0x0022: break;

                    default:
                        compactDisc = false;

                        break;
                    }
                }

                if (compactDisc)
                {
                    currentProfile = 0x0008;

                    // We discarded all discs that falsify a TOC before requesting a real TOC
                    // No TOC, no CD (or an empty one)
                    bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);

                    if (!tocSense)
                    {
                        toc = FullTOC.Decode(cmdBuf);
                    }
                }
            }
            else
            {
                compactDisc = false;
            }

            uint blocksToRead = 64;

            results.A       = 0; // <3ms
            results.B       = 0; // >=3ms, <10ms
            results.C       = 0; // >=10ms, <50ms
            results.D       = 0; // >=50ms, <150ms
            results.E       = 0; // >=150ms, <500ms
            results.F       = 0; // >=500ms
            results.Errored = 0;
            DateTime start;
            DateTime end;

            results.ProcessingTime = 0;
            results.TotalTime      = 0;
            double currentSpeed = 0;

            results.MaxSpeed          = double.MinValue;
            results.MinSpeed          = double.MaxValue;
            results.UnreadableSectors = new List <ulong>();

            if (compactDisc)
            {
                if (toc == null)
                {
                    StoppingErrorMessage?.Invoke("Error trying to decode TOC...");

                    return(results);
                }

                bool readcd = !dev.ReadCd(out _, out senseBuf, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true,
                                          MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
                                          dev.Timeout, out _);

                if (readcd)
                {
                    UpdateStatus?.Invoke("Using MMC READ CD command.");
                }

                start = DateTime.UtcNow;

                while (true)
                {
                    if (readcd)
                    {
                        sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, false,
                                           false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
                                           MmcSubchannel.None, dev.Timeout, out _);

                        if (dev.Error)
                        {
                            blocksToRead /= 2;
                        }
                    }

                    if (!dev.Error ||
                        blocksToRead == 1)
                    {
                        break;
                    }
                }

                if (dev.Error)
                {
                    StoppingErrorMessage?.
                    Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");

                    return(results);
                }

                UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");

                InitBlockMap?.Invoke(results.Blocks, blockSize, blocksToRead, currentProfile);
                mhddLog = new MhddLog(mhddLogPath, dev, results.Blocks, blockSize, blocksToRead, false);
                ibgLog  = new IbgLog(ibgLogPath, currentProfile);
                DateTime timeSpeedStart   = DateTime.UtcNow;
                ulong    sectorSpeedStart = 0;

                InitProgress?.Invoke();

                for (ulong i = 0; i < results.Blocks; i += blocksToRead)
                {
                    if (aborted)
                    {
                        break;
                    }

                    double cmdDuration = 0;

                    if (results.Blocks - i < blocksToRead)
                    {
                        blocksToRead = (uint)(results.Blocks - i);
                    }

                    #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                    if (currentSpeed > results.MaxSpeed &&
                        currentSpeed != 0)
                    {
                        results.MaxSpeed = currentSpeed;
                    }

                    if (currentSpeed < results.MinSpeed &&
                        currentSpeed != 0)
                    {
                        results.MinSpeed = currentSpeed;
                    }
                    #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                    UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
                                           (long)i, (long)results.Blocks);

                    if (readcd)
                    {
                        sense = dev.ReadCd(out _, out senseBuf, (uint)i, 2352, blocksToRead, MmcSectorTypes.AllTypes,
                                           false, false, true, MmcHeaderCodes.AllHeaders, true, true,
                                           MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration);

                        results.ProcessingTime += cmdDuration;
                    }

                    if (!sense)
                    {
                        if (cmdDuration >= 500)
                        {
                            results.F += blocksToRead;
                        }
                        else if (cmdDuration >= 150)
                        {
                            results.E += blocksToRead;
                        }
                        else if (cmdDuration >= 50)
                        {
                            results.D += blocksToRead;
                        }
                        else if (cmdDuration >= 10)
                        {
                            results.C += blocksToRead;
                        }
                        else if (cmdDuration >= 3)
                        {
                            results.B += blocksToRead;
                        }
                        else
                        {
                            results.A += blocksToRead;
                        }

                        ScanTime?.Invoke(i, cmdDuration);
                        mhddLog.Write(i, cmdDuration);
                        ibgLog.Write(i, currentSpeed * 1024);
                    }
                    else
                    {
                        AaruConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf));

                        FixedSense?senseDecoded = Sense.DecodeFixed(senseBuf);

                        if (senseDecoded.HasValue)
                        {
                            // TODO: This error happens when changing from track type afaik. Need to solve that more cleanly
                            // LOGICAL BLOCK ADDRESS OUT OF RANGE
                            if ((senseDecoded.Value.ASC != 0x21 || senseDecoded.Value.ASCQ != 0x00) &&

                                // ILLEGAL MODE FOR THIS TRACK (requesting sectors as-is, this is a firmware misconception when audio sectors
                                // are in a track where subchannel indicates data)
                                (senseDecoded.Value.ASC != 0x64 || senseDecoded.Value.ASCQ != 0x00))
                            {
                                results.Errored += blocksToRead;

                                for (ulong b = i; b < i + blocksToRead; b++)
                                {
                                    results.UnreadableSectors.Add(b);
                                }

                                ScanUnreadable?.Invoke(i);
                                mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                                ibgLog.Write(i, 0);
                            }
                        }
                        else
                        {
                            ScanUnreadable?.Invoke(i);
                            results.Errored += blocksToRead;

                            for (ulong b = i; b < i + blocksToRead; b++)
                            {
                                results.UnreadableSectors.Add(b);
                            }

                            mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                            ibgLog.Write(i, 0);
                        }
                    }

                    sectorSpeedStart += blocksToRead;

                    double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                    if (elapsed < 1)
                    {
                        continue;
                    }

                    currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                    ScanSpeed?.Invoke(i, currentSpeed * 1024);
                    sectorSpeedStart = 0;
                    timeSpeedStart   = DateTime.UtcNow;
                }

                end = DateTime.UtcNow;
                EndProgress?.Invoke();
                mhddLog.Close();

                ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                             (blockSize * (double)(results.Blocks + 1)) / 1024 /
                             (results.ProcessingTime / 1000),
                             devicePath);
            }
            else
            {
                start = DateTime.UtcNow;

                UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");

                InitBlockMap?.Invoke(results.Blocks, blockSize, blocksToRead, currentProfile);
                mhddLog = new MhddLog(mhddLogPath, dev, results.Blocks, blockSize, blocksToRead, false);
                ibgLog  = new IbgLog(ibgLogPath, currentProfile);
                DateTime timeSpeedStart   = DateTime.UtcNow;
                ulong    sectorSpeedStart = 0;

                InitProgress?.Invoke();

                for (ulong i = 0; i < results.Blocks; i += blocksToRead)
                {
                    if (aborted)
                    {
                        break;
                    }

                    if (results.Blocks - i < blocksToRead)
                    {
                        blocksToRead = (uint)(results.Blocks - i);
                    }

                    #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                    if (currentSpeed > results.MaxSpeed &&
                        currentSpeed != 0)
                    {
                        results.MaxSpeed = currentSpeed;
                    }

                    if (currentSpeed < results.MinSpeed &&
                        currentSpeed != 0)
                    {
                        results.MinSpeed = currentSpeed;
                    }
                    #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                    UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
                                           (long)i, (long)results.Blocks);

                    sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration);
                    results.ProcessingTime += cmdDuration;

                    if (!sense &&
                        !dev.Error)
                    {
                        if (cmdDuration >= 500)
                        {
                            results.F += blocksToRead;
                        }
                        else if (cmdDuration >= 150)
                        {
                            results.E += blocksToRead;
                        }
                        else if (cmdDuration >= 50)
                        {
                            results.D += blocksToRead;
                        }
                        else if (cmdDuration >= 10)
                        {
                            results.C += blocksToRead;
                        }
                        else if (cmdDuration >= 3)
                        {
                            results.B += blocksToRead;
                        }
                        else
                        {
                            results.A += blocksToRead;
                        }

                        ScanTime?.Invoke(i, cmdDuration);
                        mhddLog.Write(i, cmdDuration);
                        ibgLog.Write(i, currentSpeed * 1024);
                    }

                    // TODO: Separate errors on kind of errors.
                    else
                    {
                        ScanUnreadable?.Invoke(i);
                        results.Errored += blocksToRead;

                        for (ulong b = i; b < i + blocksToRead; b++)
                        {
                            results.UnreadableSectors.Add(b);
                        }

                        mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
                        ibgLog.Write(i, 0);
                    }

                    sectorSpeedStart += blocksToRead;

                    double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                    if (elapsed < 1)
                    {
                        continue;
                    }

                    currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                    ScanSpeed?.Invoke(i, currentSpeed * 1024);
                    sectorSpeedStart = 0;
                    timeSpeedStart   = DateTime.UtcNow;
                }

                end = DateTime.UtcNow;
                EndProgress?.Invoke();
                mhddLog.Close();

                ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                             (blockSize * (double)(results.Blocks + 1)) / 1024 /
                             (results.ProcessingTime / 1000),
                             devicePath);
            }

            results.SeekMax   = double.MinValue;
            results.SeekMin   = double.MaxValue;
            results.SeekTotal = 0;
            const int SEEK_TIMES = 1000;

            var rnd = new Random();

            InitProgress?.Invoke();

            for (int i = 0; i < SEEK_TIMES; i++)
            {
                if (aborted)
                {
                    break;
                }

                uint seekPos = (uint)rnd.Next((int)results.Blocks);

                PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t");

                double seekCur;

                if (scsiReader.CanSeek)
                {
                    scsiReader.Seek(seekPos, out seekCur);
                }
                else
                {
                    scsiReader.ReadBlock(out _, seekPos, out seekCur);
                }

                #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                if (seekCur > results.SeekMax &&
                    seekCur != 0)
                {
                    results.SeekMax = seekCur;
                }

                if (seekCur < results.SeekMin &&
                    seekCur != 0)
                {
                    results.SeekMin = seekCur;
                }
                #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                results.SeekTotal += seekCur;
                GC.Collect();
            }

            EndProgress?.Invoke();

            results.ProcessingTime /= 1000;
            results.TotalTime       = (end - start).TotalSeconds;
            results.AvgSpeed        = (blockSize * (double)(results.Blocks + 1)) / 1048576 / results.ProcessingTime;
            results.SeekTimes       = SEEK_TIMES;

            return(results);
        }
예제 #28
0
 /// <summary>
 /// Constructor for SparkleUpdate when there are some updates available.
 /// </summary>
 public UpdateInfo(UpdateStatus status, AppCastItem[] updates)
 {
     Status  = status;
     Updates = updates;
 }
예제 #29
0
 public ReadResult(RssFeed feed, UpdateStatus status)
 {
     this.feed = feed;
     this.status = status;
 }
        /// <summary>
        /// Update a single Cinemachine Virtual Camera if and only if it
        /// hasn't already been updated this frame.  Always update vcams via this method.
        /// Calling this more than once per frame for the same camera will have no effect.
        /// </summary>
        internal void UpdateVirtualCamera(
            CinemachineVirtualCameraBase vcam, Vector3 worldUp, float deltaTime)
        {
            if (vcam == null)
            {
                return;
            }

            bool isSmartUpdate = (CurrentUpdateFilter & UpdateFilter.Smart) == UpdateFilter.Smart;

            UpdateTracker.UpdateClock updateClock
                = (UpdateTracker.UpdateClock)(CurrentUpdateFilter & ~UpdateFilter.Smart);

            // If we're in smart update mode and the target moved, then we must examine
            // how the target has been moving recently in order to figure out whether to
            // update now
            if (isSmartUpdate)
            {
                Transform updateTarget = GetUpdateTarget(vcam);
                if (updateTarget == null)
                {
                    return;   // vcam deleted
                }
                if (UpdateTracker.GetPreferredUpdate(updateTarget) != updateClock)
                {
                    return;   // wrong clock
                }
            }

            // Have we already been updated this frame?
            if (mUpdateStatus == null)
            {
                mUpdateStatus = new Dictionary <CinemachineVirtualCameraBase, UpdateStatus>();
            }
            UpdateStatus status;

            if (!mUpdateStatus.TryGetValue(vcam, out status))
            {
                status = new UpdateStatus();
                mUpdateStatus.Add(vcam, status);
            }
            int frameDelta = (updateClock == UpdateTracker.UpdateClock.Late)
                ? Time.frameCount - status.lastUpdateFrame
                : FixedFrameCount - status.lastUpdateFixedFrame;

            if (deltaTime >= 0)
            {
                if (frameDelta == 0 && status.lastUpdateMode == updateClock &&
                    status.lastUpdateDeltaTime == deltaTime)
                {
                    return; // already updated
                }
                if (frameDelta > 0)
                {
                    deltaTime *= frameDelta; // try to catch up if multiple frames
                }
            }

//Debug.Log((vcam.ParentCamera == null ? "" : vcam.ParentCamera.Name + ".") + vcam.Name + ": frame " + Time.frameCount + "/" + status.lastUpdateFixedFrame + ", " + CurrentUpdateFilter + ", deltaTime = " + deltaTime);
            vcam.InternalUpdateCameraState(worldUp, deltaTime);
            status.lastUpdateFrame      = Time.frameCount;
            status.lastUpdateFixedFrame = FixedFrameCount;
            status.lastUpdateMode       = updateClock;
            status.lastUpdateDeltaTime  = deltaTime;
        }
예제 #31
0
 public void RefreshStatus()
 {
     if (Status != UpdateStatus.UpdateCheckFailed && CurrentVersion != null && LatestVersion != null &&
         !string.IsNullOrEmpty(DownloadURL) && (forceUpdate || Helpers.CheckVersion(CurrentVersion, LatestVersion)))
     {
         Status = UpdateStatus.UpdateAvailable;
     }
     else
     {
         Status = UpdateStatus.UpToDate;
     }
 }
예제 #32
0
        ScanResults SecureDigital()
        {
            ScanResults results = new ScanResults();

            byte[] cmdBuf;
            bool   sense;

            results.Blocks = 0;
            const uint   TIMEOUT = 5;
            double       duration;
            const ushort SD_PROFILE    = 0x0001;
            uint         blocksToRead  = 128;
            uint         blockSize     = 512;
            bool         byteAddressed = true;

            switch (dev.Type)
            {
            case DeviceType.MMC:
            {
                sense = dev.ReadExtendedCsd(out cmdBuf, out _, TIMEOUT, out _);
                if (!sense)
                {
                    ExtendedCSD ecsd = Decoders.MMC.Decoders.DecodeExtendedCSD(cmdBuf);
                    blocksToRead   = ecsd.OptimalReadSize;
                    results.Blocks = ecsd.SectorCount;
                    blockSize      = (uint)(ecsd.SectorSize == 1 ? 4096 : 512);
                    // Supposing it's high-capacity MMC if it has Extended CSD...
                    byteAddressed = false;
                }

                if (sense || results.Blocks == 0)
                {
                    sense = dev.ReadCsd(out cmdBuf, out _, TIMEOUT, out _);
                    if (!sense)
                    {
                        CSD csd = Decoders.MMC.Decoders.DecodeCSD(cmdBuf);
                        results.Blocks = (ulong)((csd.Size + 1) * Math.Pow(2, csd.SizeMultiplier + 2));
                        blockSize      = (uint)Math.Pow(2, csd.ReadBlockLength);
                    }
                }

                break;
            }

            case DeviceType.SecureDigital:
            {
                sense = dev.ReadCsd(out cmdBuf, out _, TIMEOUT, out _);
                if (!sense)
                {
                    Decoders.SecureDigital.CSD csd = Decoders.SecureDigital.Decoders.DecodeCSD(cmdBuf);
                    results.Blocks = (ulong)(csd.Structure == 0
                                                     ? (csd.Size + 1) * Math.Pow(2, csd.SizeMultiplier + 2)
                                                     : (csd.Size + 1) * 1024);
                    blockSize = (uint)Math.Pow(2, csd.ReadBlockLength);
                    // Structure >=1 for SDHC/SDXC, so that's block addressed
                    byteAddressed = csd.Structure == 0;
                }

                break;
            }
            }

            if (results.Blocks == 0)
            {
                StoppingErrorMessage?.Invoke("Unable to get device size.");
                return(results);
            }

            while (true)
            {
                sense = dev.Read(out cmdBuf, out _, 0, blockSize, blocksToRead, byteAddressed, TIMEOUT, out duration);

                if (sense)
                {
                    blocksToRead /= 2;
                }

                if (!sense || blocksToRead == 1)
                {
                    break;
                }
            }

            if (sense)
            {
                StoppingErrorMessage?.Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");
                return(results);
            }

            results.A       = 0; // <3ms
            results.B       = 0; // >=3ms, <10ms
            results.C       = 0; // >=10ms, <50ms
            results.D       = 0; // >=50ms, <150ms
            results.E       = 0; // >=150ms, <500ms
            results.F       = 0; // >=500ms
            results.Errored = 0;
            DateTime start;
            DateTime end;

            results.ProcessingTime = 0;
            double currentSpeed = 0;

            results.MaxSpeed          = double.MinValue;
            results.MinSpeed          = double.MaxValue;
            results.UnreadableSectors = new List <ulong>();
            results.SeekMax           = double.MinValue;
            results.SeekMin           = double.MaxValue;
            results.SeekTotal         = 0;
            const int SEEK_TIMES = 1000;

            Random rnd = new Random();

            UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");

            InitBlockMap?.Invoke(results.Blocks, blockSize, blocksToRead, SD_PROFILE);
            MhddLog mhddLog = new MhddLog(mhddLogPath, dev, results.Blocks, blockSize, blocksToRead);
            IbgLog  ibgLog  = new IbgLog(ibgLogPath, SD_PROFILE);

            start = DateTime.UtcNow;
            DateTime timeSpeedStart   = DateTime.UtcNow;
            ulong    sectorSpeedStart = 0;

            InitProgress?.Invoke();
            for (ulong i = 0; i < results.Blocks; i += blocksToRead)
            {
                if (aborted)
                {
                    break;
                }

                if (results.Blocks - i < blocksToRead)
                {
                    blocksToRead = (byte)(results.Blocks - i);
                }

                #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                if (currentSpeed > results.MaxSpeed && currentSpeed != 0)
                {
                    results.MaxSpeed = currentSpeed;
                }
                if (currentSpeed < results.MinSpeed && currentSpeed != 0)
                {
                    results.MinSpeed = currentSpeed;
                }
                #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
                                       (long)results.Blocks);

                bool error = dev.Read(out cmdBuf, out _, (uint)i, blockSize, blocksToRead, byteAddressed, TIMEOUT,
                                      out duration);

                if (!error)
                {
                    if (duration >= 500)
                    {
                        results.F += blocksToRead;
                    }
                    else if (duration >= 150)
                    {
                        results.E += blocksToRead;
                    }
                    else if (duration >= 50)
                    {
                        results.D += blocksToRead;
                    }
                    else if (duration >= 10)
                    {
                        results.C += blocksToRead;
                    }
                    else if (duration >= 3)
                    {
                        results.B += blocksToRead;
                    }
                    else
                    {
                        results.A += blocksToRead;
                    }

                    ScanTime?.Invoke(i, duration);
                    mhddLog.Write(i, duration);
                    ibgLog.Write(i, currentSpeed * 1024);
                }
                else
                {
                    ScanUnreadable?.Invoke(i);
                    results.Errored += blocksToRead;
                    for (ulong b = i; b < i + blocksToRead; b++)
                    {
                        results.UnreadableSectors.Add(b);
                    }

                    mhddLog.Write(i, duration < 500 ? 65535 : duration);

                    ibgLog.Write(i, 0);
                }

                sectorSpeedStart += blocksToRead;

                double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
                if (elapsed < 1)
                {
                    continue;
                }

                currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
                ScanSpeed?.Invoke(i, currentSpeed * 1024);
                sectorSpeedStart = 0;
                timeSpeedStart   = DateTime.UtcNow;
            }

            end = DateTime.UtcNow;
            EndProgress?.Invoke();
            mhddLog.Close();
            ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                         blockSize * (double)(results.Blocks + 1) / 1024 /
                         (results.ProcessingTime / 1000), devicePath);

            InitProgress?.Invoke();
            for (int i = 0; i < SEEK_TIMES; i++)
            {
                if (aborted)
                {
                    break;
                }

                uint seekPos = (uint)rnd.Next((int)results.Blocks);

                PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t");

                dev.Read(out cmdBuf, out _, seekPos, blockSize, blocksToRead, byteAddressed, TIMEOUT,
                         out double seekCur);

                #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                if (seekCur > results.SeekMax && seekCur != 0)
                {
                    results.SeekMax = seekCur;
                }
                if (seekCur < results.SeekMin && seekCur != 0)
                {
                    results.SeekMin = seekCur;
                }
                #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                results.SeekTotal += seekCur;
                GC.Collect();
            }

            EndProgress?.Invoke();

            results.ProcessingTime /= 1000;
            results.TotalTime       = (end - start).TotalSeconds;
            results.AvgSpeed        = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime;
            results.SeekTimes       = SEEK_TIMES;

            return(results);
        }
예제 #33
0
파일: CdiReady.cs 프로젝트: paulyc/Aaru
        // TODO: Set pregap for Track 1
        // TODO: Detect errors in sectors
        /// <summary>Reads all the hidden track in CD-i Ready discs</summary>
        /// <param name="blocks">Total number of positive sectors</param>
        /// <param name="blockSize">Size of the read sector in bytes</param>
        /// <param name="currentSpeed">Current read speed</param>
        /// <param name="currentTry">Current dump hardware try</param>
        /// <param name="extents">Extents</param>
        /// <param name="ibgLog">IMGBurn log</param>
        /// <param name="imageWriteDuration">Duration of image write</param>
        /// <param name="leadOutExtents">Lead-out extents</param>
        /// <param name="maxSpeed">Maximum speed</param>
        /// <param name="mhddLog">MHDD log</param>
        /// <param name="minSpeed">Minimum speed</param>
        /// <param name="offsetBytes">Read offset</param>
        /// <param name="sectorsForOffset">Sectors needed to fix offset</param>
        /// <param name="subSize">Subchannel size in bytes</param>
        /// <param name="supportedSubchannel">Drive's maximum supported subchannel</param>
        /// <param name="totalDuration">Total commands duration</param>
        /// <param name="cdiReadyReadAsAudio">Is the drive returning CD-i Ready hidden track as audio?</param>
        /// <param name="tracks">Disc tracks</param>
        /// <param name="subLog">Subchannel log</param>
        /// <param name="desiredSubchannel">Subchannel desired to save</param>
        /// <param name="isrcs">List of disc ISRCs</param>
        /// <param name="mcn">Disc media catalogue number</param>
        /// <param name="subchannelExtents">List of subchannels not yet dumped correctly</param>
        /// <param name="smallestPregapLbaPerTrack">List of smallest pregap relative address per track</param>
        void ReadCdiReady(uint blockSize, ref double currentSpeed, DumpHardwareType currentTry, ExtentsULong extents,
                          IbgLog ibgLog, ref double imageWriteDuration, ExtentsULong leadOutExtents,
                          ref double maxSpeed, MhddLog mhddLog, ref double minSpeed, uint subSize,
                          MmcSubchannel supportedSubchannel, ref double totalDuration, Track[] tracks,
                          SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary <byte, string> isrcs,
                          ref string mcn, HashSet <int> subchannelExtents, ulong blocks, bool cdiReadyReadAsAudio,
                          int offsetBytes, int sectorsForOffset, Dictionary <byte, int> smallestPregapLbaPerTrack)
        {
            ulong    sectorSpeedStart = 0;               // Used to calculate correct speed
            DateTime timeSpeedStart   = DateTime.UtcNow; // Time of start for speed calculation
            bool     sense;                              // Sense indicator

            byte[]     cmdBuf;                           // Data buffer
            byte[]     senseBuf;                         // Sense buffer
            double     cmdDuration;                      // Command execution time
            const uint sectorSize = 2352;                // Full sector size
            Track      firstTrack = tracks.FirstOrDefault(t => t.TrackSequence == 1);
            uint       blocksToRead;                     // How many sectors to read at once

            if (firstTrack is null)
            {
                return;
            }

            if (cdiReadyReadAsAudio)
            {
                _dumpLog.WriteLine("Setting speed to 8x for CD-i Ready reading as audio.");
                UpdateStatus?.Invoke("Setting speed to 8x for CD-i Ready reading as audio.");

                _dev.SetCdSpeed(out _, RotationalControl.ClvAndImpureCav, 1416, 0, _dev.Timeout, out _);
            }

            InitProgress?.Invoke();

            for (ulong i = _resume.NextBlock; i < firstTrack.TrackStartSector; i += blocksToRead)
            {
                if (_aborted)
                {
                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                    UpdateStatus?.Invoke("Aborted!");
                    _dumpLog.WriteLine("Aborted!");

                    break;
                }

                uint firstSectorToRead = (uint)i;

                blocksToRead = _maximumReadable;

                if (blocksToRead == 1 && cdiReadyReadAsAudio)
                {
                    blocksToRead += (uint)sectorsForOffset;
                }

                if (cdiReadyReadAsAudio)
                {
                    // TODO: FreeBSD bug
                    if (offsetBytes < 0)
                    {
                        if (i == 0)
                        {
                            firstSectorToRead = uint.MaxValue - (uint)(sectorsForOffset - 1); // -1
                        }
                        else
                        {
                            firstSectorToRead -= (uint)sectorsForOffset;
                        }
                    }
                }

                if (currentSpeed > maxSpeed &&
                    currentSpeed > 0)
                {
                    maxSpeed = currentSpeed;
                }

                if (currentSpeed < minSpeed &&
                    currentSpeed > 0)
                {
                    minSpeed = currentSpeed;
                }

                UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i,
                                       (long)blocks);

                sense = _dev.ReadCd(out cmdBuf, out senseBuf, firstSectorToRead, blockSize, blocksToRead,
                                    MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
                                    MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);

                totalDuration += cmdDuration;

                double elapsed;

                // Overcome the track mode change drive error
                if (sense)
                {
                    for (uint r = 0; r < _maximumReadable; r++)
                    {
                        UpdateProgress?.Invoke($"Reading sector {i + r} of {blocks} ({currentSpeed:F3} MiB/sec.)",
                                               (long)i + r, (long)blocks);

                        sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)(i + r), blockSize,
                                            (uint)sectorsForOffset + 1, MmcSectorTypes.AllTypes, false, false, true,
                                            MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
                                            supportedSubchannel, _dev.Timeout, out cmdDuration);

                        totalDuration += cmdDuration;

                        if (!sense &&
                            !_dev.Error)
                        {
                            mhddLog.Write(i + r, cmdDuration);
                            ibgLog.Write(i + r, currentSpeed * 1024);
                            extents.Add(i + r, 1, true);
                            DateTime writeStart = DateTime.Now;

                            if (cdiReadyReadAsAudio)
                            {
                                FixOffsetData(offsetBytes, sectorSize, sectorsForOffset, supportedSubchannel,
                                              ref blocksToRead, subSize, ref cmdBuf, blockSize, false);
                            }

                            if (supportedSubchannel != MmcSubchannel.None)
                            {
                                byte[] data = new byte[sectorSize];
                                byte[] sub  = new byte[subSize];

                                Array.Copy(cmdBuf, 0, data, 0, sectorSize);

                                Array.Copy(cmdBuf, sectorSize, sub, 0, subSize);

                                if (cdiReadyReadAsAudio)
                                {
                                    data = Sector.Scramble(data);
                                }

                                _outputPlugin.WriteSectorsLong(data, i + r, 1);

                                bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
                                                                                               desiredSubchannel, sub, i + r, 1, subLog, isrcs, 1, ref mcn, tracks,
                                                                                               subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel,
                                                                                               _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);

                                // Set tracks and go back
                                if (indexesChanged)
                                {
                                    (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList());
                                    i -= _maximumReadable;

                                    continue;
                                }
                            }
                            else
                            {
                                _outputPlugin.WriteSectorsLong(cmdBuf, i + r, 1);
                            }

                            imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                        }
                        else
                        {
                            _errorLog?.WriteLine(i + r, _dev.Error, _dev.LastError, senseBuf);

                            leadOutExtents.Add(i + r, firstTrack.TrackStartSector - 1);

                            UpdateStatus?.
                            Invoke($"Adding CD-i Ready hole from LBA {i + r} to {firstTrack.TrackStartSector - 1} inclusive.");

                            _dumpLog.WriteLine("Adding CD-i Ready hole from LBA {0} to {1} inclusive.", i + r,
                                               firstTrack.TrackStartSector - 1);

                            break;
                        }

                        sectorSpeedStart += r;

                        _resume.NextBlock = i + r;

                        elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                        if (elapsed < 1)
                        {
                            continue;
                        }

                        currentSpeed     = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                        sectorSpeedStart = 0;
                        timeSpeedStart   = DateTime.UtcNow;
                    }
                }

                if (!sense &&
                    !_dev.Error)
                {
                    if (cdiReadyReadAsAudio)
                    {
                        FixOffsetData(offsetBytes, sectorSize, sectorsForOffset, supportedSubchannel, ref blocksToRead,
                                      subSize, ref cmdBuf, blockSize, false);
                    }

                    mhddLog.Write(i, cmdDuration);
                    ibgLog.Write(i, currentSpeed * 1024);
                    extents.Add(i, blocksToRead, true);
                    DateTime writeStart = DateTime.Now;

                    if (supportedSubchannel != MmcSubchannel.None)
                    {
                        byte[] data    = new byte[sectorSize * blocksToRead];
                        byte[] sub     = new byte[subSize * blocksToRead];
                        byte[] tmpData = new byte[sectorSize];

                        for (int b = 0; b < blocksToRead; b++)
                        {
                            if (cdiReadyReadAsAudio)
                            {
                                Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), tmpData, 0, sectorSize);
                                tmpData = Sector.Scramble(tmpData);
                                Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
                            }
                            else
                            {
                                Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), data, sectorSize * b, sectorSize);
                            }

                            Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
                        }

                        _outputPlugin.WriteSectorsLong(data, i, blocksToRead);

                        bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
                                                                                       desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, 1, ref mcn, tracks,
                                                                                       subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel,
                                                                                       _fixSubchannelCrc, _dumpLog, UpdateStatus, smallestPregapLbaPerTrack, true);

                        // Set tracks and go back
                        if (indexesChanged)
                        {
                            (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList());
                            i -= blocksToRead;

                            continue;
                        }
                    }
                    else
                    {
                        if (cdiReadyReadAsAudio)
                        {
                            byte[] tmpData = new byte[sectorSize];
                            byte[] data    = new byte[sectorSize * blocksToRead];

                            for (int b = 0; b < blocksToRead; b++)
                            {
                                Array.Copy(cmdBuf, (int)(b * sectorSize), tmpData, 0, sectorSize);
                                tmpData = Sector.Scramble(tmpData);
                                Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
                            }

                            _outputPlugin.WriteSectorsLong(data, i, blocksToRead);
                        }
                        else
                        {
                            _outputPlugin.WriteSectorsLong(cmdBuf, i, blocksToRead);
                        }
                    }

                    imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                }
                else
                {
                    _errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);

                    _resume.NextBlock = firstTrack.TrackStartSector;

                    break;
                }

                sectorSpeedStart += blocksToRead;

                _resume.NextBlock = i + blocksToRead;

                elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                if (elapsed < 1)
                {
                    continue;
                }

                currentSpeed     = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                sectorSpeedStart = 0;
                timeSpeedStart   = DateTime.UtcNow;
            }

            EndProgress?.Invoke();
        }
예제 #34
0
        /// <summary>
        /// Checks and compares the current AWB version with the version listed on the checkpage
        /// </summary>
        private void AWBVersion()
        {
            string json;

            UpdateUI("   Retrieving current version...", true);
            try
            {
                HttpWebRequest rq =
                    (HttpWebRequest)
                    WebRequest.Create(
                        "https://en.wikipedia.org/w/index.php?title=Wikipedia:AutoWikiBrowser/CheckPage/VersionJSON&action=raw");

                rq.Proxy = _proxy;

                rq.UserAgent = string.Format("AWBUpdater/{0} ({1}; .NET CLR {2})",
                                             Assembly.GetExecutingAssembly().GetName().Version,
                                             Environment.OSVersion.VersionString, Environment.Version);

                HttpWebResponse response = (HttpWebResponse)rq.GetResponse();

                using (Stream stream = response.GetResponseStream())
                    using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
                    {
                        json = sr.ReadToEnd();

                        sr.Close();
                        stream.Close();
                        response.Close();
                    }
            }
            catch
            {
                AppendLine("FAILED");
                throw new AbortException();
            }

            try
            {
                FileVersionInfo awbVersionInfo =
                    FileVersionInfo.GetVersionInfo(Path.Combine(_awbDirectory, "AutoWikiBrowser.exe"));

                JavaScriptSerializer jss = new JavaScriptSerializer();
                var updaterData          = jss.Deserialize <RootObject>(json);

                string versionToUpdateAWBTo = "";

                if (updaterData.enabledversions.All(v => v.version != awbVersionInfo.FileVersion))
                {
                    // The version of AWB in the directory definitely isn't enabled
                    _updateStatus = UpdateStatus.RequiredUpdate;

                    versionToUpdateAWBTo = updaterData.enabledversions.Where(x => !x.dev)
                                           .OrderByDescending(x => x.version).First().version;
                }
                else
                {
                    var newerVersions = updaterData.enabledversions
                                        .Where(x => !x.dev && new Version(x.version) > new Version(awbVersionInfo.FileVersion))
                                        .OrderByDescending(x => x.version).ToList();

                    if (newerVersions.Any())
                    {
                        _updateStatus = UpdateStatus.OptionalUpdateDeclined;

                        if (newerVersions.Count > 1)
                        {
                            using (VersionChooser chooser = new VersionChooser(newerVersions))
                            {
                                if (chooser.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(chooser.SelectedVersion))
                                {
                                    _updateStatus        = UpdateStatus.OptionalUpdate;
                                    versionToUpdateAWBTo = chooser.SelectedVersion;
                                }
                            }
                        }
                        else if (newerVersions.Count == 1 &&
                                 MessageBox.Show(
                                     string.Format("There is an optional update to AutoWikiBrowser. Would you like to upgrade to {0}?", newerVersions.First().version),
                                     "Optional update", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            _updateStatus        = UpdateStatus.OptionalUpdate;
                            versionToUpdateAWBTo = newerVersions.First().version;
                        }
                    }
                }

                if ((_updateStatus & (UpdateStatus.RequiredUpdate | UpdateStatus.OptionalUpdate)) != 0)
                {
                    _zipName = "AutoWikiBrowser" + VersionToFileVersion(versionToUpdateAWBTo) + ".zip";
                }
                else if (new Version(updaterData.updaterversion) > new Version(Assembly.GetExecutingAssembly().GetName().Version.ToString()))
                {
                    _zipName      = "AWBUpdater" + VersionToFileVersion(updaterData.updaterversion) + ".zip";
                    _updateStatus = UpdateStatus.UpdaterUpdate;
                }
            }
            catch
            {
                _updateStatus = UpdateStatus.Error;
                UpdateUI("   Unable to find AutoWikiBrowser.exe to query its version", true);
            }

            progressUpdate.Value = 35;
        }
예제 #35
0
        /// <summary>Dumps inter-session lead-outs</summary>
        /// <param name="blockSize">Size of the read sector in bytes</param>
        /// <param name="currentSpeed">Current read speed</param>
        /// <param name="currentTry">Current dump hardware try</param>
        /// <param name="extents">Extents</param>
        /// <param name="ibgLog">IMGBurn log</param>
        /// <param name="imageWriteDuration">Duration of image write</param>
        /// <param name="leadOutExtents">Lead-out extents</param>
        /// <param name="maxSpeed">Maximum speed</param>
        /// <param name="mhddLog">MHDD log</param>
        /// <param name="minSpeed">Minimum speed</param>
        /// <param name="read6">Device supports READ(6)</param>
        /// <param name="read10">Device supports READ(10)</param>
        /// <param name="read12">Device supports READ(12)</param>
        /// <param name="read16">Device supports READ(16)</param>
        /// <param name="readcd">Device supports READ CD</param>
        /// <param name="supportedSubchannel">Drive's maximum supported subchannel</param>
        /// <param name="subSize">Subchannel size in bytes</param>
        /// <param name="totalDuration">Total commands duration</param>
        /// <param name="tracks">Disc tracks</param>
        /// <param name="subLog">Subchannel log</param>
        /// <param name="desiredSubchannel">Subchannel desired to save</param>
        /// <param name="isrcs">List of disc ISRCs</param>
        /// <param name="mcn">Disc media catalogue number</param>
        /// <param name="subchannelExtents">List of subchannels not yet dumped correctly</param>
        /// <param name="smallestPregapLbaPerTrack">List of smallest pregap relative address per track</param>
        void DumpCdLeadOuts(uint blockSize, ref double currentSpeed, DumpHardwareType currentTry, ExtentsULong extents,
                            IbgLog ibgLog, ref double imageWriteDuration, ExtentsULong leadOutExtents,
                            ref double maxSpeed, MhddLog mhddLog, ref double minSpeed, bool read6, bool read10,
                            bool read12, bool read16, bool readcd, MmcSubchannel supportedSubchannel, uint subSize,
                            ref double totalDuration, SubchannelLog subLog, MmcSubchannel desiredSubchannel,
                            Dictionary <byte, string> isrcs, ref string mcn, Track[] tracks,
                            HashSet <int> subchannelExtents, Dictionary <byte, int> smallestPregapLbaPerTrack)
        {
            byte[]     cmdBuf     = null; // Data buffer
            const uint sectorSize = 2352; // Full sector size
            bool       sense      = true; // Sense indicator

            byte[] senseBuf = null;

            UpdateStatus?.Invoke("Reading lead-outs");
            _dumpLog.WriteLine("Reading lead-outs");

            InitProgress?.Invoke();

            foreach ((ulong item1, ulong item2) in leadOutExtents.ToArray())
            {
                for (ulong i = item1; i <= item2; i++)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    double cmdDuration = 0;

                    if (currentSpeed > maxSpeed &&
                        currentSpeed > 0)
                    {
                        maxSpeed = currentSpeed;
                    }

                    if (currentSpeed < minSpeed &&
                        currentSpeed > 0)
                    {
                        minSpeed = currentSpeed;
                    }

                    PulseProgress?.Invoke($"Reading sector {i} at lead-out ({currentSpeed:F3} MiB/sec.)");

                    if (readcd)
                    {
                        sense = _dev.ReadCd(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, MmcSectorTypes.AllTypes,
                                            false, false, true, MmcHeaderCodes.AllHeaders, true, true,
                                            MmcErrorField.None, supportedSubchannel, _dev.Timeout, out cmdDuration);

                        totalDuration += cmdDuration;
                    }
                    else if (read16)
                    {
                        sense = _dev.Read16(out cmdBuf, out senseBuf, 0, false, true, false, i, blockSize, 0, 1, false,
                                            _dev.Timeout, out cmdDuration);
                    }
                    else if (read12)
                    {
                        sense = _dev.Read12(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
                                            0, 1, false, _dev.Timeout, out cmdDuration);
                    }
                    else if (read10)
                    {
                        sense = _dev.Read10(out cmdBuf, out senseBuf, 0, false, true, false, false, (uint)i, blockSize,
                                            0, 1, _dev.Timeout, out cmdDuration);
                    }
                    else if (read6)
                    {
                        sense = _dev.Read6(out cmdBuf, out senseBuf, (uint)i, blockSize, 1, _dev.Timeout,
                                           out cmdDuration);
                    }

                    if (!sense &&
                        !_dev.Error)
                    {
                        mhddLog.Write(i, cmdDuration);
                        ibgLog.Write(i, currentSpeed * 1024);
                        extents.Add(i, _maximumReadable, true);
                        leadOutExtents.Remove(i);
                        DateTime writeStart = DateTime.Now;

                        if (supportedSubchannel != MmcSubchannel.None)
                        {
                            byte[] data = new byte[sectorSize * _maximumReadable];
                            byte[] sub  = new byte[subSize * _maximumReadable];

                            for (int b = 0; b < _maximumReadable; b++)
                            {
                                Array.Copy(cmdBuf, (int)(0 + (b * blockSize)), data, sectorSize * b, sectorSize);

                                Array.Copy(cmdBuf, (int)(sectorSize + (b * blockSize)), sub, subSize * b, subSize);
                            }

                            _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);

                            bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
                                                                                           desiredSubchannel, sub, i,
                                                                                           _maximumReadable, subLog,
                                                                                           isrcs, 0xAA, ref mcn, tracks,
                                                                                           subchannelExtents,
                                                                                           _fixSubchannelPosition,
                                                                                           _outputPlugin,
                                                                                           _fixSubchannel,
                                                                                           _fixSubchannelCrc, _dumpLog,
                                                                                           UpdateStatus,
                                                                                           smallestPregapLbaPerTrack);

                            // Set tracks and go back
                            if (indexesChanged)
                            {
                                (_outputPlugin as IWritableOpticalImage).SetTracks(tracks.ToList());
                                i--;

                                continue;
                            }
                        }
                        else
                        {
                            _outputPlugin.WriteSectors(cmdBuf, i, _maximumReadable);
                        }

                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                    }
                    else
                    {
                        _errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);

                        // TODO: Reset device after X errors
                        if (_stopOnError)
                        {
                            return; // TODO: Return more cleanly
                        }
                        // Write empty data
                        DateTime writeStart = DateTime.Now;

                        if (supportedSubchannel != MmcSubchannel.None)
                        {
                            _outputPlugin.WriteSectorsLong(new byte[sectorSize * _skip], i, 1);

                            _outputPlugin.WriteSectorsTag(new byte[subSize * _skip], i, 1,
                                                          SectorTagType.CdSectorSubchannel);
                        }
                        else
                        {
                            _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, 1);
                        }

                        imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

                        mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                        ibgLog.Write(i, 0);
                    }

                    double newSpeed = ((double)blockSize * _maximumReadable) / 1048576 / (cmdDuration / 1000);

                    if (!double.IsInfinity(newSpeed))
                    {
                        currentSpeed = newSpeed;
                    }

                    _resume.NextBlock = i + 1;
                }
            }

            EndProgress?.Invoke();
        }
예제 #36
0
        /// <summary>
        /// Update a single Cinemachine Virtual Camera if and only if it
        /// hasn't already been updated this frame.  Always update vcams via this method.
        /// Calling this more than once per frame for the same camera will have no effect.
        /// </summary>
        internal bool UpdateVirtualCamera(ICinemachineCamera vcam, Vector3 worldUp, float deltaTime)
        {
            //UnityEngine.Profiling.Profiler.BeginSample("CinemachineCore.UpdateVirtualCamera");
            int  now               = Time.frameCount;
            bool isSmartUpdate     = CurrentUpdateFilter != UpdateFilter.Any;
            bool isSmartLateUpdate = CurrentUpdateFilter == UpdateFilter.Late;

            if (mUpdateStatus == null)
            {
                mUpdateStatus = new Dictionary <ICinemachineCamera, UpdateStatus>();
            }
            if (vcam.VirtualCameraGameObject == null)
            {
                if (mUpdateStatus.ContainsKey(vcam))
                {
                    mUpdateStatus.Remove(vcam);
                }
                //UnityEngine.Profiling.Profiler.EndSample();
                return(false); // camera was deleted
            }
            UpdateStatus status;

            if (!mUpdateStatus.TryGetValue(vcam, out status))
            {
                status = new UpdateStatus(now);
                mUpdateStatus.Add(vcam, status);
            }

            int subframes = isSmartLateUpdate ? 1 : CinemachineBrain.GetSubframeCount();

            if (status.lastUpdateFrame != now)
            {
                status.lastUpdateSubframe = 0;
            }

            // If we're in smart update mode and the target moved, then we must examine
            // how the target has been moving recently in order to figure out whether to
            // update now
            bool updateNow = !isSmartUpdate;

            if (!updateNow)
            {
                Matrix4x4 targetPos;
                if (!GetTargetPosition(vcam, out targetPos))
                {
                    updateNow = isSmartLateUpdate; // no target
                }
                else
                {
                    updateNow = status.ChoosePreferredUpdate(now, targetPos, CurrentUpdateFilter)
                                == CurrentUpdateFilter;
                }
            }

            if (updateNow)
            {
                if (isSmartUpdate)
                {
                    status.preferredUpdate = CurrentUpdateFilter;
                }
                if (deltaTime < 0)
                {
                    status.hasInconsistentAnimation = status.hadInconsistentAnimation = false;
                }
                while (status.lastUpdateSubframe < subframes)
                {
//Debug.Log(vcam.Name + ": frame " + Time.frameCount + "." + status.lastUpdateSubframe + ", " + CurrentUpdateFilter);
                    vcam.UpdateCameraState(worldUp, deltaTime);
                    ++status.lastUpdateSubframe;
                }
                status.lastUpdateFrame = now;
            }

            mUpdateStatus[vcam] = status;
            //UnityEngine.Profiling.Profiler.EndSample();
            return(true);
        }
예제 #37
0
 private void Wait()
 {
     Status = "Standby mode";
     UpdateStatus?.Invoke(Status);
 }
예제 #38
0
		/// <summary>
		/// Initializes a new instance of the <see cref="TroposphirLauncher.Updater"/> class using the configurations provided by the specified <see cref="Config"/>.
		/// </summary>
		/// <param name="config">The Updater Config to use.</param>
		public Updater(Config config) {
			server = config.Server;
			progressCallback = config.Progress;
			stepCallback = config.StepChange;
			patchFolder = config.PatchFolder;
			Status = UpdateStatus.NOT_STARTED;
		}
예제 #39
0
        public void Redo(Bitmap selection, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, Bitmap populateOverlay, UpdateStatus updateStatus)
        {
            if (!MoveNext())
                return;

            if (undoStack.Last.Value.PreviousAction == null)
            {
                throw new Exception("Redo sanity check failed.");
            }

            if (undoStack.Last.Value is SelectionAction)
            {
                ApplySelectionState((SelectionAction)undoStack.Last.Value, selection);
            }
            else if (undoStack.Last.Value is BiomeAction)
            {
                ApplyBiomeState((BiomeAction)undoStack.Last.Value, region, terrainOverlay, biomeOverlay, ref tooltips, updateStatus);
            }
            else if (undoStack.Last.Value is PopulateAction)
            {
                ApplyPopulateState((PopulateAction)undoStack.Last.Value, region, populateOverlay);
            }

            OnChange();
        }
예제 #40
0
		/// <summary>
		/// Tries to execute a update step, setting the Updater's Status to the given value, then running the step. If the step fails, Status becomes <see cref="UpdateStatus.FAILED"/>.
		/// </summary>
		/// <returns><c>true</c>, if update step was successful, <c>false</c> otherwise.</returns>
		/// <param name="task">Action to be run, takes a Action&lt;float&gt; parameter which is a progress callback, must be called with ranges 0.0 to 1.0.</param>
		/// <param name="targetState">Target state.</param>
		bool TryUpdateStep(Action<Action<float>> task, UpdateStatus targetState) {
			try {
				Status = targetState;
				stepCallback(Status);
				task(progressCallback);
				return true;
			} catch (Exception e) {
				Console.WriteLine(string.Format("Failed completing update step {0} with error \"{1}\": \n{2}", task.Method.Name, e.Message, e.StackTrace));
				Status = UpdateStatus.FAILED;
				return false;
			}
		}
예제 #41
0
 private void ApplyBiomeState(BiomeAction action, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, UpdateStatus updateStatus)
 {
     foreach (ChunkState state in action.Chunks)
     {
         Chunk c = region.Chunks[state.Coords.X, state.Coords.Z];
         if (c == null || c.Root == null)
             continue;
         ((TAG_Byte_Array)c.Root["Level"]["Biomes"]).Payload = (byte[])state.Biomes.Clone();
     }
     tooltips = new String[biomeOverlay.Width, biomeOverlay.Height];
     if (terrainOverlay != null)
     {
         updateStatus("Generating terrain map");
         RegionUtil.RenderRegionTerrain(region, terrainOverlay);
     }
     updateStatus("Generating biome map");
     RegionUtil.RenderRegionBiomes(region, biomeOverlay, tooltips);
     updateStatus("");
 }
예제 #42
0
 /// <summary>
 /// Очищает поле вывода статуса на форме
 /// </summary>
 public void Clear()
 {
     if (textBoxStatus.InvokeRequired)
     {
         myDelegate = new UpdateStatus(Update);
         textBoxStatus.Invoke(myDelegate);
     }
     else
         textBoxStatus.Text = "";
 }
예제 #43
0
        public void RefreshStatus()
        {
            if (CurrentVersion == null)
            {
                CurrentVersion = Version.Parse(Application.ProductVersion);
            }

            if (Status != UpdateStatus.UpdateCheckFailed && CurrentVersion != null && LatestVersion != null && !string.IsNullOrEmpty(DownloadURL) &&
                (forceUpdate || Helpers.CompareVersion(CurrentVersion, LatestVersion) < 0 || (IsBeta && Helpers.CompareVersion(CurrentVersion, LatestVersion) == 0)))
            {
                Status = UpdateStatus.UpdateAvailable;
            }
            else
            {
                Status = UpdateStatus.UpToDate;
            }
        }
예제 #44
0
        public override UpdateStatus Update(FilestoreFile tempFileUpload, SampleEventMap map)
        {
            if (tempFileUpload != null)
            {
                FilestoreFile oldFile = this.Get(map);
                if (oldFile != null)
                {
                    if (this.CanModify(map))
                    {
                        WaterQualityDET      curdet   = new WaterQualityDET();
                        ExcelWaterQualityDET curexcel = new ExcelWaterQualityDET(curdet);
                        curexcel.Load(tempFileUpload);
                        curdet.Validate();
                        ValidationIssues curIssues = curdet.ValidationIssues;
                        if (curIssues.Count < 1)
                        {
                            WaterQualityDET      olddet = new WaterQualityDET();
                            ExcelWaterQualityDET excel  = new ExcelWaterQualityDET(olddet);
                            excel.Load(oldFile);
                            olddet.Validate();
                            ValidationIssues issues = olddet.ValidationIssues;
                            if (issues.Count < 1) //should be this is the old file
                            {
                                UpdateStatus status = null;
                                if (olddet.Deployments.Count < 1)     //old file has no data - bare det
                                {
                                    if (curdet.Deployments.Count < 1) //nothing to do really, new file has no data either
                                    {
                                        olddet = null;
                                        excel  = null;
                                        oldFile.Dispose();
                                        curdet   = null;
                                        curexcel = null;
                                        FileStoreManager.Instance.GetProvider().Delete(tempFileUpload);

                                        status = new UpdateStatus(UpdateIssue.AllOk);
                                        status.Add(new IssueNotice("NoDataInEither", "nothing to do"));
                                        return(status);
                                    }

                                    SampleEventMapItem item = map.Get(KnownDetType.WaterQuality);
                                    if (item != null)
                                    {
                                        olddet = null; //release old reference
                                        excel  = null; //release old reference

                                        //ok, no data in old file, but data in new file -- we have work to do -- handle first-time data insertion
                                        IWQDeploymentProvider  depl = WaterQualityManager.Instance.GetDeploymentProvider(this.Context);
                                        IWQMeasurementProvider meas = WaterQualityManager.Instance.GetMeasurementProvider(this.Context);
                                        if (depl != null && meas != null)
                                        {
                                            if (depl.CanCreate() && meas.CanCreate())
                                            {
                                                List <EntityBundle> bundles = this.GetBundles(map, KnownDetType.WaterQuality);
                                                if (bundles != null && bundles.Count == 2)
                                                {
                                                    status = this.InitialLoad(map.SampleEventId, bundles[0], bundles[1], curdet, depl, meas, item.IsPrivate);
                                                    if (status != null && status.Issue == UpdateIssue.AllOk) //success, so we overwrite the file
                                                    {
                                                        curdet   = null;
                                                        curexcel = null;
                                                        olddet   = null;
                                                        excel    = null;
                                                        IFileStoreProvider ip = FileStoreManager.Instance.GetProvider();
                                                        if (ip.Replace(tempFileUpload, oldFile)) //overwrite the existing file with the new one
                                                        {
                                                            tempFileUpload.Dispose();
                                                            oldFile.Dispose();
                                                            return(status); //we're done here
                                                        }
                                                        else
                                                        {
                                                            status = new UpdateStatus(UpdateIssue.DataIssue);
                                                            status.Add(new IssueNotice("File", "Failed to replace file"));
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    status = new UpdateStatus(UpdateIssue.DataIssue);
                                                    status.Add(new IssueNotice("Bundles", "Failed to get bundles"));
                                                }
                                            }
                                            else
                                            {
                                                status = new UpdateStatus(UpdateIssue.Security);
                                                status.Add(new IssueNotice("Permissions", "create denied"));
                                            }
                                        }
                                        else
                                        {
                                            status = new UpdateStatus(UpdateIssue.SystemIssue);
                                            status.Add(new IssueNotice("Failure", "Failed to get provider"));
                                        }
                                    }
                                    else
                                    {
                                        status = new UpdateStatus(UpdateIssue.NoExistingFile);
                                        status.Add(new IssueNotice("NoMapEntry", "Failed to find map reference"));
                                    }
                                    return(status);
                                }
                                else //crap -- this is an update where existing file already had data
                                {
                                    IWQDeploymentProvider  depl = WaterQualityManager.Instance.GetDeploymentProvider(this.Context);
                                    IWQMeasurementProvider meas = WaterQualityManager.Instance.GetMeasurementProvider(this.Context);
                                    if (depl != null && meas != null)
                                    {
                                        if (depl.CanCreate() && meas.CanCreate())
                                        {
                                            SampleEventMapItem  item    = map.Get(KnownDetType.WaterQuality);
                                            List <EntityBundle> bundles = this.GetBundles(map, KnownDetType.WaterQuality);
                                            if (item != null && bundles != null && bundles.Count == 2)
                                            {
                                                status = this.DeltaLoad(map.SampleEventId, bundles[0], bundles[1], curdet, olddet, depl, meas, map);
                                                if (status != null && status.Issue == UpdateIssue.AllOk) //success, so we overwrite the file
                                                {
                                                    curdet   = null;
                                                    curexcel = null;
                                                    olddet   = null;
                                                    excel    = null;
                                                    //NOTE -- making new file the permanent file and removing old file, then updating map for new file
                                                    IFileStoreProvider ip = FileStoreManager.Instance.GetProvider();
                                                    if (ip.Replace(tempFileUpload, oldFile)) //overwrite the existing file with the new one
                                                    {
                                                        tempFileUpload.Dispose();
                                                        oldFile.Dispose();
                                                        //ip.Delete(tempFileUpload); //may still be references so delete can fail
                                                        return(status); //we're done here
                                                    }
                                                    else
                                                    {
                                                        status = new UpdateStatus(UpdateIssue.DataIssue);
                                                        status.Add(new IssueNotice("File", "Failed to replace file"));
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                status = new UpdateStatus(UpdateIssue.DataIssue);
                                                status.Add(new IssueNotice("Bundles", "Failed to get bundles"));
                                            }
                                        }
                                        else
                                        {
                                            status = new UpdateStatus(UpdateIssue.Security);
                                            status.Add(new IssueNotice("Permissions", "create denied"));
                                        }
                                    }
                                    else
                                    {
                                        status = new UpdateStatus(UpdateIssue.SystemIssue);
                                        status.Add(new IssueNotice("Failure", "Failed to get provider"));
                                    }
                                    return(status);
                                }
                            }
                            else
                            {
                                UpdateStatus stat = new UpdateStatus(UpdateIssue.NoExistingFile);
                                foreach (ValidationIssue cur in issues)
                                {
                                    stat.Add(new IssueNotice(cur.IssueCode.ToString(), cur.IssueMessage));
                                }
                                return(stat);
                            }
                        }
                        else
                        {
                            UpdateStatus stat = new UpdateStatus(UpdateIssue.FileValidationIssues);
                            foreach (ValidationIssue cur in curIssues)
                            {
                                stat.Add(new IssueNotice(cur.IssueCode.ToString(), cur.IssueMessage));
                            }
                            return(stat);
                        }
                    }
                    else
                    {
                        UpdateStatus status = new UpdateStatus(UpdateIssue.Security);
                        status.Add(new IssueNotice("Permissions", "create denied"));
                        return(status);
                    }
                }
                return(new UpdateStatus(UpdateIssue.NoExistingFile));
            }
            return(new UpdateStatus(UpdateIssue.NoFilePosted));
        }
예제 #45
0
 public ReadResult(UpdateStatus status)
 {
     this.status = status;
 }
예제 #46
0
        private UpdateStatus InitialLoad(CompoundIdentity seId, EntityBundle sites, EntityBundle instruments, WaterQualityDET curdet, IWQDeploymentProvider depl, IWQMeasurementProvider meas, bool isPrivate)
        {
            UpdateStatus stat = null;

            if (sites == null || instruments == null || seId == null || seId.IsEmpty)
            {
                stat = new UpdateStatus(UpdateIssue.DataIssue);
                stat.Add(new IssueNotice("BundlesOrEvent", "Null value"));
            }
            else
            {
                //TODO -- may need to do case insensitive ops or not -- verify how excel part is implemented

                Dictionary <string, CompoundIdentity> deployIds = new Dictionary <string, CompoundIdentity>();
                BundleElement elem;
                foreach (DeploymentDTO cur in curdet.Deployments.Values)
                {
                    if (cur != null && !deployIds.ContainsKey(cur.DeployCode))
                    {
                        elem = sites.Get(cur.SiteId);
                        if (elem != null)
                        {
                            CompoundIdentity siteId = elem.EntityId;
                            elem = instruments.Get(cur.InstrumentId);
                            if (elem != null)
                            {
                                CompoundIdentity       sensorId = elem.EntityId;
                                WaterQualityDeployment dep      = depl.Create(cur.DeployCode, seId, siteId, sensorId, this.GetRange(cur.StartDate, cur.EndDate), cur.Comments, isPrivate);
                                if (dep != null)
                                {
                                    deployIds[dep.Name] = dep.Identity;
                                }
                                else
                                {
                                    stat = Add("Create", "Unable to create deployment " + cur.DeployCode, UpdateIssue.DataIssue, stat);
                                }
                            }
                            else
                            {
                                stat = Add("InstCode", "Empty or invalid Instrument Code on deployment " + cur.DeployCode, UpdateIssue.DataIssue, stat);
                            }
                        }
                        else
                        {
                            stat = Add("SiteCode", "Empty or invalid Site Code on Deployment " + cur.DeployCode, UpdateIssue.DataIssue, stat);
                        }
                    }
                    else
                    {
                        stat = Add("DeployCode", "A deployment is missing a deployment code", UpdateIssue.DataIssue, stat);
                    }
                }

                Dictionary <CompoundIdentity, WaterQualityMeasurementsDTO> items = new Dictionary <CompoundIdentity, WaterQualityMeasurementsDTO>();
                foreach (MeasurementDTO cur in curdet.Measurements.Values)
                {
                    if (cur != null && deployIds.ContainsKey(cur.DeployCode) && cur.MeasureDateTime != null)
                    {
                        CompoundIdentity depId = deployIds[cur.DeployCode];
                        if (depId != null)
                        {
                            if (!items.ContainsKey(depId))
                            {
                                items[depId] = WaterQualityMeasurementsDTO.Create(depId);
                            }

                            WaterQualityMeasurementsDTO elems = items[depId];
                            elems.Add(new WaterQualityMeasurementDTO(cur.MeasureDateTime.Value, cur.SurfaceElevation, cur.Temperature, cur.pH, cur.DO, cur.Conductivity, cur.Salinity, cur.Velocity));
                        }
                    }
                    else
                    {
                        stat = Add("Create", "Unable to create Measurement with key " + cur.DeployCode + ":" + cur.MeasureDateTime, UpdateIssue.DataIssue, stat);
                    }
                }

                foreach (WaterQualityMeasurementsDTO cur in items.Values)
                {
                    if (cur != null)
                    {
                        meas.Create(cur);
                    }
                }

                if (stat == null)
                {
                    stat = new UpdateStatus(UpdateIssue.AllOk);
                    stat.Add(new IssueNotice("NoIssues", "No issues"));
                }
            }
            return(stat);
        }
예제 #47
0
		private void UpdateCallback(UpdateStatus updateStatus, int progress)
		{
			UpdateStatus = updateStatus;
		}
예제 #48
0
        private void Copy_LBManager(LBGame lbGame, string tempFolder)
        {
            // todo ajouter une fonctino pour grouper les jeux dans le sous dossier
            //string gameF = Path.Combine(Path.GetDirectoryName(lbGame.ApplicationPath), lbGame.Title);

            UpdateStatus?.Invoke(this, "Copy files");
            MaximumProgress?.Invoke(this, 6);
            UpdateProgress?.Invoke(this, 0);

            int i = 0;

            foreach (string d in Directory.GetDirectories(tempFolder))
            {
                UpdateProgress?.Invoke(this, i);

                string dirName = Path.GetFileName(d);

                // Games
                if (dirName == PS.Default.Games)
                {
                    string tmp = Path.GetDirectoryName(lbGame.ApplicationPath);
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.Games} => '{tmp}'");
                    CopyContent(d, tmp);
                }

                // Cheat Codes
                else if (dirName == PS.Default.CheatCodes)
                {
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.CheatCodes} => '{TCheatsCodesP}'");
                    CopyContent(d, TCheatsCodesP);
                }

                // Images
                else if (dirName == PS.Default.Images)
                {
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.Images} => '{TImagesP}'");
                    CopyContent(d, TImagesP);
                }

                // Manuals
                else if (dirName == PS.Default.Manuals)
                {
                    string tmp = Path.GetDirectoryName(lbGame.ManualPath);
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.Manuals} => ({ tmp }'");
                    CopyContent(d, tmp);
                }

                // Musics
                else if (dirName == PS.Default.Musics)
                {
                    string tmp = Path.GetDirectoryName(lbGame.MusicPath);
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.Musics} => '{tmp}'");
                    CopyContent(d, tmp);
                }

                // Videos
                else if (dirName == PS.Default.Videos)
                {
                    string tmp = Path.GetDirectoryName(lbGame.VideoPath);
                    UpdateStatus?.Invoke(this, $"\t{Lang.I_Copy}: {Lang.Videos} => '{tmp}'");
                    CopyContent(d, tmp);
                }

                i++;
            }

            UpdateProgress?.Invoke(this, 6);
        }
예제 #49
0
        /// <summary>
        ///     Scans the media from an ATA device
        /// </summary>
        /// <returns>Scanning results</returns>
        ScanResults Ata()
        {
            ScanResults results = new ScanResults();
            bool        sense;

            results.Blocks = 0;
            const ushort ATA_PROFILE = 0x0001;
            const uint   TIMEOUT     = 5;

            sense = dev.AtaIdentify(out byte[] cmdBuf, out _);
            if (!sense && Identify.Decode(cmdBuf).HasValue)
            {
                // Initializate reader
                Reader ataReader = new Reader(dev, TIMEOUT, cmdBuf);
                // Fill reader blocks
                results.Blocks = ataReader.GetDeviceBlocks();
                if (ataReader.FindReadCommand())
                {
                    StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
                    return(results);
                }

                // Check block sizes
                if (ataReader.GetBlockSize())
                {
                    StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
                    return(results);
                }

                uint blockSize = ataReader.LogicalBlockSize;
                // Check how many blocks to read, if error show and return
                if (ataReader.GetBlocksToRead())
                {
                    StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
                    return(results);
                }

                uint   blocksToRead = ataReader.BlocksToRead;
                ushort cylinders    = ataReader.Cylinders;
                byte   heads        = ataReader.Heads;
                byte   sectors      = ataReader.Sectors;

                results.A       = 0; // <3ms
                results.B       = 0; // >=3ms, <10ms
                results.C       = 0; // >=10ms, <50ms
                results.D       = 0; // >=50ms, <150ms
                results.E       = 0; // >=150ms, <500ms
                results.F       = 0; // >=500ms
                results.Errored = 0;
                DateTime start;
                DateTime end;
                results.ProcessingTime = 0;
                double currentSpeed = 0;
                results.MaxSpeed          = double.MinValue;
                results.MinSpeed          = double.MaxValue;
                results.UnreadableSectors = new List <ulong>();
                results.SeekMax           = double.MinValue;
                results.SeekMin           = double.MaxValue;
                results.SeekTotal         = 0;
                const int SEEK_TIMES = 1000;

                double seekCur;

                Random rnd = new Random();

                MhddLog mhddLog;
                IbgLog  ibgLog;
                double  duration;
                if (ataReader.IsLba)
                {
                    UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");

                    InitBlockMap?.Invoke(results.Blocks, blockSize, blocksToRead, ATA_PROFILE);
                    mhddLog = new MhddLog(mhddLogPath, dev, results.Blocks, blockSize, blocksToRead);
                    ibgLog  = new IbgLog(ibgLogPath, ATA_PROFILE);

                    start = DateTime.UtcNow;
                    DateTime timeSpeedStart   = DateTime.UtcNow;
                    ulong    sectorSpeedStart = 0;
                    InitProgress?.Invoke();
                    for (ulong i = 0; i < results.Blocks; i += blocksToRead)
                    {
                        if (aborted)
                        {
                            break;
                        }

                        if (results.Blocks - i < blocksToRead)
                        {
                            blocksToRead = (byte)(results.Blocks - i);
                        }

                        #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                        if (currentSpeed > results.MaxSpeed && currentSpeed != 0)
                        {
                            results.MaxSpeed = currentSpeed;
                        }
                        if (currentSpeed < results.MinSpeed && currentSpeed != 0)
                        {
                            results.MinSpeed = currentSpeed;
                        }
                        #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                        UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
                                               (long)i, (long)results.Blocks);

                        bool error = ataReader.ReadBlocks(out cmdBuf, i, blocksToRead, out duration);

                        if (!error)
                        {
                            if (duration >= 500)
                            {
                                results.F += blocksToRead;
                            }
                            else if (duration >= 150)
                            {
                                results.E += blocksToRead;
                            }
                            else if (duration >= 50)
                            {
                                results.D += blocksToRead;
                            }
                            else if (duration >= 10)
                            {
                                results.C += blocksToRead;
                            }
                            else if (duration >= 3)
                            {
                                results.B += blocksToRead;
                            }
                            else
                            {
                                results.A += blocksToRead;
                            }

                            ScanTime?.Invoke(i, duration);
                            mhddLog.Write(i, duration);
                            ibgLog.Write(i, currentSpeed * 1024);
                        }
                        else
                        {
                            ScanUnreadable?.Invoke(i);
                            results.Errored += blocksToRead;
                            for (ulong b = i; b < i + blocksToRead; b++)
                            {
                                results.UnreadableSectors.Add(b);
                            }

                            mhddLog.Write(i, duration < 500 ? 65535 : duration);

                            ibgLog.Write(i, 0);
                        }

                        sectorSpeedStart += blocksToRead;

                        double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
                        if (elapsed < 1)
                        {
                            continue;
                        }

                        currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
                        ScanSpeed?.Invoke(i, currentSpeed * 1024);
                        sectorSpeedStart = 0;
                        timeSpeedStart   = DateTime.UtcNow;
                    }

                    end = DateTime.UtcNow;
                    EndProgress?.Invoke();
                    mhddLog.Close();
                    ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                                 blockSize * (double)(results.Blocks + 1) / 1024 /
                                 (results.ProcessingTime / 1000),
                                 devicePath);

                    InitProgress?.Invoke();
                    if (ataReader.CanSeekLba)
                    {
                        for (int i = 0; i < SEEK_TIMES; i++)
                        {
                            if (aborted)
                            {
                                break;
                            }

                            uint seekPos = (uint)rnd.Next((int)results.Blocks);

                            PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t");

                            ataReader.Seek(seekPos, out seekCur);

                            #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                            if (seekCur > results.SeekMax && seekCur != 0)
                            {
                                results.SeekMax = seekCur;
                            }
                            if (seekCur < results.SeekMin && seekCur != 0)
                            {
                                results.SeekMin = seekCur;
                            }
                            #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                            results.SeekTotal += seekCur;
                            GC.Collect();
                        }
                    }

                    EndProgress?.Invoke();
                }
                else
                {
                    InitBlockMap?.Invoke(results.Blocks, blockSize, blocksToRead, ATA_PROFILE);
                    mhddLog = new MhddLog(mhddLogPath, dev, results.Blocks, blockSize, blocksToRead);
                    ibgLog  = new IbgLog(ibgLogPath, ATA_PROFILE);

                    ulong currentBlock = 0;
                    results.Blocks = (ulong)(cylinders * heads * sectors);
                    start          = DateTime.UtcNow;
                    DateTime timeSpeedStart   = DateTime.UtcNow;
                    ulong    sectorSpeedStart = 0;
                    InitProgress?.Invoke();
                    for (ushort cy = 0; cy < cylinders; cy++)
                    {
                        for (byte hd = 0; hd < heads; hd++)
                        {
                            for (byte sc = 1; sc < sectors; sc++)
                            {
                                if (aborted)
                                {
                                    break;
                                }

                                #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                                if (currentSpeed > results.MaxSpeed && currentSpeed != 0)
                                {
                                    results.MaxSpeed = currentSpeed;
                                }
                                if (currentSpeed < results.MinSpeed && currentSpeed != 0)
                                {
                                    results.MinSpeed = currentSpeed;
                                }
                                #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                                PulseProgress
                                ?.Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");

                                bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);

                                if (!error)
                                {
                                    if (duration >= 500)
                                    {
                                        results.F += blocksToRead;
                                    }
                                    else if (duration >= 150)
                                    {
                                        results.E += blocksToRead;
                                    }
                                    else if (duration >= 50)
                                    {
                                        results.D += blocksToRead;
                                    }
                                    else if (duration >= 10)
                                    {
                                        results.C += blocksToRead;
                                    }
                                    else if (duration >= 3)
                                    {
                                        results.B += blocksToRead;
                                    }
                                    else
                                    {
                                        results.A += blocksToRead;
                                    }

                                    ScanTime?.Invoke(currentBlock, duration);
                                    mhddLog.Write(currentBlock, duration);
                                    ibgLog.Write(currentBlock, currentSpeed * 1024);
                                }
                                else
                                {
                                    ScanUnreadable?.Invoke(currentBlock);
                                    results.Errored += blocksToRead;
                                    results.UnreadableSectors.Add(currentBlock);
                                    mhddLog.Write(currentBlock, duration < 500 ? 65535 : duration);

                                    ibgLog.Write(currentBlock, 0);
                                }

                                sectorSpeedStart++;
                                currentBlock++;

                                double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
                                if (elapsed < 1)
                                {
                                    continue;
                                }

                                currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
                                ScanSpeed?.Invoke(currentBlock, currentSpeed * 1024);
                                sectorSpeedStart = 0;
                                timeSpeedStart   = DateTime.UtcNow;
                            }
                        }
                    }

                    end = DateTime.UtcNow;
                    EndProgress?.Invoke();
                    mhddLog.Close();
                    ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                                 blockSize * (double)(results.Blocks + 1) / 1024 /
                                 (results.ProcessingTime / 1000),
                                 devicePath);

                    InitProgress?.Invoke();
                    if (ataReader.CanSeek)
                    {
                        for (int i = 0; i < SEEK_TIMES; i++)
                        {
                            if (aborted)
                            {
                                break;
                            }

                            ushort seekCy = (ushort)rnd.Next(cylinders);
                            byte   seekHd = (byte)rnd.Next(heads);
                            byte   seekSc = (byte)rnd.Next(sectors);

                            PulseProgress
                            ?.Invoke($"\rSeeking to cylinder {seekCy}, head {seekHd}, sector {seekSc}...\t\t");

                            ataReader.SeekChs(seekCy, seekHd, seekSc, out seekCur);

                            #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
                            if (seekCur > results.SeekMax && seekCur != 0)
                            {
                                results.SeekMax = seekCur;
                            }
                            if (seekCur < results.SeekMin && seekCur != 0)
                            {
                                results.SeekMin = seekCur;
                            }
                            #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

                            results.SeekTotal += seekCur;
                            GC.Collect();
                        }
                    }

                    EndProgress?.Invoke();
                }

                results.ProcessingTime /= 1000;
                results.TotalTime       = (end - start).TotalSeconds;
                results.AvgSpeed        = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime;
                results.SeekTimes       = SEEK_TIMES;

                return(results);
            }

            StoppingErrorMessage?.Invoke("Unable to communicate with ATA device.");
            return(results);
        }
예제 #50
0
파일: MemoryStick.cs 프로젝트: paulyc/Aaru
        void DumpMs()
        {
            const ushort sbcProfile    = 0x0001;
            const uint   blockSize     = 512;
            double       totalDuration = 0;
            double       currentSpeed  = 0;
            double       maxSpeed      = double.MinValue;
            double       minSpeed      = double.MaxValue;
            uint         blocksToRead  = 64;
            DateTime     start;
            DateTime     end;
            MediaType    dskType;
            bool         sense;

            byte[] senseBuf;

            sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _);

            if (sense)
            {
                _dumpLog.WriteLine("Could not detect capacity...");
                StoppingErrorMessage?.Invoke("Could not detect capacity...");

                return;
            }

            uint blocks = (uint)((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]);

            blocks++;

            ulong totalSize = blocks * (ulong)blockSize;

            if (totalSize > 1099511627776)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1099511627776d:F3} TiB)");
            }
            else if (totalSize > 1073741824)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1073741824d:F3} GiB)");
            }
            else if (totalSize > 1048576)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1048576d:F3} MiB)");
            }
            else if (totalSize > 1024)
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize / 1024d:F3} KiB)");
            }
            else
            {
                UpdateStatus?.
                Invoke($"Media has {blocks} blocks of {blockSize} bytes/each. (for a total of {totalSize} bytes)");
            }

            if (blocks == 0)
            {
                _dumpLog.WriteLine("ERROR: Unable to read medium or empty medium present...");
                StoppingErrorMessage?.Invoke("Unable to read medium or empty medium present...");

                return;
            }

            UpdateStatus?.Invoke($"Device reports {blocks} blocks ({blocks * blockSize} bytes).");
            UpdateStatus?.Invoke($"Device can read {blocksToRead} blocks at a time.");
            UpdateStatus?.Invoke($"Device reports {blockSize} bytes per logical block.");
            UpdateStatus?.Invoke($"SCSI device type: {_dev.ScsiType}.");

            if (blocks > 262144)
            {
                dskType = MediaType.MemoryStickProDuo;
                _dumpLog.WriteLine("Media detected as MemoryStick Pro Duo...");
                UpdateStatus?.Invoke("Media detected as MemoryStick Pro Duo...");
            }
            else
            {
                dskType = MediaType.MemoryStickDuo;
                _dumpLog.WriteLine("Media detected as MemoryStick Duo...");
                UpdateStatus?.Invoke("Media detected as MemoryStick Duo...");
            }

            bool ret;

            var mhddLog = new MhddLog(_outputPrefix + ".mhddlog.bin", _dev, blocks, blockSize, blocksToRead, _private);
            var ibgLog  = new IbgLog(_outputPrefix + ".ibg", sbcProfile);

            ret = _outputPlugin.Create(_outputPath, dskType, _formatOptions, blocks, blockSize);

            // Cannot create image
            if (!ret)
            {
                _dumpLog.WriteLine("Error creating output image, not continuing.");
                _dumpLog.WriteLine(_outputPlugin.ErrorMessage);

                StoppingErrorMessage?.Invoke("Error creating output image, not continuing." + Environment.NewLine +
                                             _outputPlugin.ErrorMessage);

                return;
            }

            start = DateTime.UtcNow;
            double imageWriteDuration = 0;

            DumpHardwareType currentTry = null;
            ExtentsULong     extents    = null;

            ResumeSupport.Process(true, _dev.IsRemovable, blocks, _dev.Manufacturer, _dev.Model, _dev.Serial,
                                  _dev.PlatformId, ref _resume, ref currentTry, ref extents, _dev.FirmwareRevision,
                                  _private);

            if (currentTry == null ||
                extents == null)
            {
                StoppingErrorMessage?.Invoke("Could not process resume file, not continuing...");

                return;
            }

            if (_resume.NextBlock > 0)
            {
                _dumpLog.WriteLine("Resuming from block {0}.", _resume.NextBlock);
            }

            bool newTrim = false;

            DateTime timeSpeedStart   = DateTime.UtcNow;
            ulong    sectorSpeedStart = 0;

            InitProgress?.Invoke();

            for (ulong i = _resume.NextBlock; i < blocks; i += blocksToRead)
            {
                if (_aborted)
                {
                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                    UpdateStatus?.Invoke("Aborted!");
                    _dumpLog.WriteLine("Aborted!");

                    break;
                }

                if (blocks - i < blocksToRead)
                {
                    blocksToRead = (uint)(blocks - i);
                }

                if (currentSpeed > maxSpeed &&
                    currentSpeed > 0)
                {
                    maxSpeed = currentSpeed;
                }

                if (currentSpeed < minSpeed &&
                    currentSpeed > 0)
                {
                    minSpeed = currentSpeed;
                }

                UpdateProgress?.Invoke($"Reading sector {i} of {blocks} ({currentSpeed:F3} MiB/sec.)", (long)i, blocks);

                sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)i, blockSize, 0,
                                    blocksToRead, false, _dev.Timeout, out double cmdDuration);

                totalDuration += cmdDuration;

                if (!sense &&
                    !_dev.Error)
                {
                    mhddLog.Write(i, cmdDuration);
                    ibgLog.Write(i, currentSpeed * 1024);
                    DateTime writeStart = DateTime.Now;
                    _outputPlugin.WriteSectors(readBuffer, i, blocksToRead);
                    imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;
                    extents.Add(i, blocksToRead, true);
                }
                else
                {
                    _errorLog?.WriteLine(i, _dev.Error, _dev.LastError, senseBuf);

                    // TODO: Reset device after X errors
                    if (_stopOnError)
                    {
                        return; // TODO: Return more cleanly
                    }
                    if (i + _skip > blocks)
                    {
                        _skip = (uint)(blocks - i);
                    }

                    // Write empty data
                    DateTime writeStart = DateTime.Now;
                    _outputPlugin.WriteSectors(new byte[blockSize * _skip], i, _skip);
                    imageWriteDuration += (DateTime.Now - writeStart).TotalSeconds;

                    for (ulong b = i; b < i + _skip; b++)
                    {
                        _resume.BadBlocks.Add(b);
                    }

                    mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);

                    ibgLog.Write(i, 0);
                    _dumpLog.WriteLine("Skipping {0} blocks from errored block {1}.", _skip, i);
                    i      += _skip - blocksToRead;
                    newTrim = true;
                }

                sectorSpeedStart += blocksToRead;
                _resume.NextBlock = i + blocksToRead;

                double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;

                if (elapsed < 1)
                {
                    continue;
                }

                currentSpeed     = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
                sectorSpeedStart = 0;
                timeSpeedStart   = DateTime.UtcNow;
            }

            _resume.BadBlocks = _resume.BadBlocks.Distinct().ToList();

            end = DateTime.UtcNow;
            EndProgress?.Invoke();
            mhddLog.Close();

            ibgLog.Close(_dev, blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
                         (blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000), _devicePath);

            UpdateStatus?.Invoke($"Dump finished in {(end - start).TotalSeconds} seconds.");

            UpdateStatus?.
            Invoke($"Average dump speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000):F3} KiB/sec.");

            UpdateStatus?.
            Invoke($"Average write speed {((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration:F3} KiB/sec.");

            _dumpLog.WriteLine("Dump finished in {0} seconds.", (end - start).TotalSeconds);

            _dumpLog.WriteLine("Average dump speed {0:F3} KiB/sec.",
                               ((double)blockSize * (double)(blocks + 1)) / 1024 / (totalDuration / 1000));

            _dumpLog.WriteLine("Average write speed {0:F3} KiB/sec.",
                               ((double)blockSize * (double)(blocks + 1)) / 1024 / imageWriteDuration);

            #region Trimming
            if (_resume.BadBlocks.Count > 0 &&
                !_aborted &&
                _trim &&
                newTrim)
            {
                start = DateTime.UtcNow;
                UpdateStatus?.Invoke("Trimming skipped sectors");
                _dumpLog.WriteLine("Trimming skipped sectors");

                ulong[] tmpArray = _resume.BadBlocks.ToArray();
                InitProgress?.Invoke();

                foreach (ulong badSector in tmpArray)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        UpdateStatus?.Invoke("Aborted!");
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    PulseProgress?.Invoke($"Trimming sector {badSector}");

                    sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector,
                                        blockSize, 0, 1, false, _dev.Timeout, out double _);

                    if (sense || _dev.Error)
                    {
                        _errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);

                        continue;
                    }

                    _resume.BadBlocks.Remove(badSector);
                    extents.Add(badSector);
                    _outputPlugin.WriteSector(readBuffer, badSector);
                }

                EndProgress?.Invoke();
                end = DateTime.UtcNow;
                _dumpLog.WriteLine("Trimming finished in {0} seconds.", (end - start).TotalSeconds);
            }
            #endregion Trimming

            #region Error handling
            if (_resume.BadBlocks.Count > 0 &&
                !_aborted &&
                _retryPasses > 0)
            {
                int  pass              = 1;
                bool forward           = true;
                bool runningPersistent = false;

                Modes.ModePage?currentModePage = null;
                byte[]         md6;

                if (_persistent)
                {
                    Modes.ModePage_01 pg;

                    sense = _dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
                                            _dev.Timeout, out _);

                    if (sense)
                    {
                        sense = _dev.ModeSense10(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01,
                                                 _dev.Timeout, out _);

                        if (!sense)
                        {
                            Modes.DecodedMode?dcMode10 = Modes.DecodeMode10(readBuffer, _dev.ScsiType);

                            if (dcMode10.HasValue)
                            {
                                foreach (Modes.ModePage modePage in dcMode10.Value.Pages.Where(modePage =>
                                                                                               modePage.Page == 0x01 && modePage.Subpage == 0x00))
                                {
                                    currentModePage = modePage;
                                }
                            }
                        }
                    }
                    else
                    {
                        Modes.DecodedMode?dcMode6 = Modes.DecodeMode6(readBuffer, _dev.ScsiType);

                        if (dcMode6.HasValue)
                        {
                            foreach (Modes.ModePage modePage in dcMode6.Value.Pages.Where(modePage =>
                                                                                          modePage.Page == 0x01 && modePage.Subpage == 0x00))
                            {
                                currentModePage = modePage;
                            }
                        }
                    }

                    if (currentModePage == null)
                    {
                        pg = new Modes.ModePage_01
                        {
                            PS             = false,
                            AWRE           = true,
                            ARRE           = true,
                            TB             = false,
                            RC             = false,
                            EER            = true,
                            PER            = false,
                            DTE            = true,
                            DCR            = false,
                            ReadRetryCount = 32
                        };

                        currentModePage = new Modes.ModePage
                        {
                            Page         = 0x01,
                            Subpage      = 0x00,
                            PageResponse = Modes.EncodeModePage_01(pg)
                        };
                    }

                    pg = new Modes.ModePage_01
                    {
                        PS             = false,
                        AWRE           = false,
                        ARRE           = false,
                        TB             = true,
                        RC             = false,
                        EER            = true,
                        PER            = false,
                        DTE            = false,
                        DCR            = false,
                        ReadRetryCount = 255
                    };

                    var md = new Modes.DecodedMode
                    {
                        Header = new Modes.ModeHeader(),
                        Pages  = new[]
                        {
                            new Modes.ModePage
                            {
                                Page         = 0x01,
                                Subpage      = 0x00,
                                PageResponse = Modes.EncodeModePage_01(pg)
                            }
                        }
                    };

                    md6 = Modes.EncodeMode6(md, _dev.ScsiType);

                    UpdateStatus?.Invoke("Sending MODE SELECT to drive (return damaged blocks).");
                    _dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks).");
                    sense = _dev.ModeSelect(md6, out senseBuf, true, false, _dev.Timeout, out _);

                    if (sense)
                    {
                        UpdateStatus?.
                        Invoke("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");

                        AaruConsole.DebugWriteLine("Error: {0}", Sense.PrettifySense(senseBuf));

                        _dumpLog.
                        WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive.");
                    }
                    else
                    {
                        runningPersistent = true;
                    }
                }

                InitProgress?.Invoke();
repeatRetry:
                ulong[] tmpArray = _resume.BadBlocks.ToArray();

                foreach (ulong badSector in tmpArray)
                {
                    if (_aborted)
                    {
                        currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                        _dumpLog.WriteLine("Aborted!");

                        break;
                    }

                    PulseProgress?.Invoke(string.Format("Retrying sector {0}, pass {1}, {3}{2}", badSector, pass,
                                                        forward ? "forward" : "reverse",
                                                        runningPersistent ? "recovering partial data, " : ""));

                    sense = _dev.Read12(out readBuffer, out senseBuf, 0, false, true, false, false, (uint)badSector,
                                        blockSize, 0, 1, false, _dev.Timeout, out double cmdDuration);

                    totalDuration += cmdDuration;

                    if (sense || _dev.Error)
                    {
                        _errorLog?.WriteLine(badSector, _dev.Error, _dev.LastError, senseBuf);
                    }

                    if (!sense &&
                        !_dev.Error)
                    {
                        _resume.BadBlocks.Remove(badSector);
                        extents.Add(badSector);
                        _outputPlugin.WriteSector(readBuffer, badSector);
                        UpdateStatus?.Invoke($"Correctly retried block {badSector} in pass {pass}.");
                        _dumpLog.WriteLine("Correctly retried block {0} in pass {1}.", badSector, pass);
                    }
                    else if (runningPersistent)
                    {
                        _outputPlugin.WriteSector(readBuffer, badSector);
                    }
                }

                if (pass < _retryPasses &&
                    !_aborted &&
                    _resume.BadBlocks.Count > 0)
                {
                    pass++;
                    forward = !forward;
                    _resume.BadBlocks.Sort();

                    if (!forward)
                    {
                        _resume.BadBlocks.Reverse();
                    }

                    goto repeatRetry;
                }

                if (runningPersistent && currentModePage.HasValue)
                {
                    var md = new Modes.DecodedMode
                    {
                        Header = new Modes.ModeHeader(),
                        Pages  = new[]
                        {
                            currentModePage.Value
                        }
                    };

                    md6 = Modes.EncodeMode6(md, _dev.ScsiType);

                    UpdateStatus?.Invoke("Sending MODE SELECT to drive (return device to previous status).");
                    _dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status).");
                    _dev.ModeSelect(md6, out _, true, false, _dev.Timeout, out _);
                }

                EndProgress?.Invoke();
            }
            #endregion Error handling

            _resume.BadBlocks.Sort();

            foreach (ulong bad in _resume.BadBlocks)
            {
                _dumpLog.WriteLine("Sector {0} could not be read.", bad);
            }

            currentTry.Extents = ExtentsConverter.ToMetadata(extents);

            var metadata = new CommonTypes.Structs.ImageInfo
            {
                Application        = "Aaru",
                ApplicationVersion = Version.GetVersion()
            };

            if (!_outputPlugin.SetMetadata(metadata))
            {
                ErrorMessage?.Invoke("Error {0} setting metadata, continuing..." + Environment.NewLine +
                                     _outputPlugin.ErrorMessage);
            }

            _outputPlugin.SetDumpHardware(_resume.Tries);

            if (_preSidecar != null)
            {
                _outputPlugin.SetCicmMetadata(_preSidecar);
            }

            _dumpLog.WriteLine("Closing output file.");
            UpdateStatus?.Invoke("Closing output file.");
            DateTime closeStart = DateTime.Now;
            _outputPlugin.Close();
            DateTime closeEnd = DateTime.Now;
            UpdateStatus?.Invoke($"Closed in {(closeEnd - closeStart).TotalSeconds} seconds.");
            _dumpLog.WriteLine("Closed in {0} seconds.", (closeEnd - closeStart).TotalSeconds);

            if (_aborted)
            {
                UpdateStatus?.Invoke("Aborted!");
                _dumpLog.WriteLine("Aborted!");

                return;
            }

            double totalChkDuration = 0;

            if (_metadata)
            {
                UpdateStatus?.Invoke("Creating sidecar.");
                _dumpLog.WriteLine("Creating sidecar.");
                var         filters     = new FiltersList();
                IFilter     filter      = filters.GetFilter(_outputPath);
                IMediaImage inputPlugin = ImageFormat.Detect(filter);

                if (!inputPlugin.Open(filter))
                {
                    StoppingErrorMessage?.Invoke("Could not open created image.");

                    return;
                }

                DateTime chkStart = DateTime.UtcNow;
                _sidecarClass = new Sidecar(inputPlugin, _outputPath, filter.Id, _encoding);
                _sidecarClass.InitProgressEvent    += InitProgress;
                _sidecarClass.UpdateProgressEvent  += UpdateProgress;
                _sidecarClass.EndProgressEvent     += EndProgress;
                _sidecarClass.InitProgressEvent2   += InitProgress2;
                _sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
                _sidecarClass.EndProgressEvent2    += EndProgress2;
                _sidecarClass.UpdateStatusEvent    += UpdateStatus;
                CICMMetadataType sidecar = _sidecarClass.Create();
                end = DateTime.UtcNow;

                totalChkDuration = (end - chkStart).TotalMilliseconds;
                UpdateStatus?.Invoke($"Sidecar created in {(end - chkStart).TotalSeconds} seconds.");

                UpdateStatus?.
                Invoke($"Average checksum speed {((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000):F3} KiB/sec.");

                _dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds);

                _dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
                                   ((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000));

                if (_preSidecar != null)
                {
                    _preSidecar.BlockMedia = sidecar.BlockMedia;
                    sidecar = _preSidecar;
                }

                List <(ulong start, string type)> filesystems = new List <(ulong start, string type)>();

                if (sidecar.BlockMedia[0].FileSystemInformation != null)
                {
                    filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation
                                         where partition.FileSystems != null from fileSystem in partition.FileSystems
                                         select(partition.StartSector, fileSystem.Type));
                }

                if (filesystems.Count > 0)
                {
                    foreach (var filesystem in filesystems.Select(o => new
                    {
                        o.start,
                        o.type
                    }).Distinct())
                    {
                        UpdateStatus?.Invoke($"Found filesystem {filesystem.type} at sector {filesystem.start}");
                        _dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start);
                    }
                }

                sidecar.BlockMedia[0].Dimensions        = Dimensions.DimensionsFromMediaType(dskType);
                (string type, string subType)xmlType    = CommonTypes.Metadata.MediaType.MediaTypeToString(dskType);
                sidecar.BlockMedia[0].DiskType          = xmlType.type;
                sidecar.BlockMedia[0].DiskSubType       = xmlType.subType;
                sidecar.BlockMedia[0].Interface         = "USB";
                sidecar.BlockMedia[0].LogicalBlocks     = blocks;
                sidecar.BlockMedia[0].PhysicalBlockSize = (int)blockSize;
                sidecar.BlockMedia[0].LogicalBlockSize  = (int)blockSize;
                sidecar.BlockMedia[0].Manufacturer      = _dev.Manufacturer;
                sidecar.BlockMedia[0].Model             = _dev.Model;

                if (!_private)
                {
                    sidecar.BlockMedia[0].Serial = _dev.Serial;
                }

                sidecar.BlockMedia[0].Size = blocks * blockSize;

                if (_dev.IsRemovable)
                {
                    sidecar.BlockMedia[0].DumpHardwareArray = _resume.Tries.ToArray();
                }

                UpdateStatus?.Invoke("Writing metadata sidecar");

                var xmlFs = new FileStream(_outputPrefix + ".cicm.xml", FileMode.Create);

                var xmlSer = new XmlSerializer(typeof(CICMMetadataType));
                xmlSer.Serialize(xmlFs, sidecar);
                xmlFs.Close();
            }

            UpdateStatus?.Invoke("");

            UpdateStatus?.
            Invoke($"Took a total of {(end - start).TotalSeconds:F3} seconds ({totalDuration / 1000:F3} processing commands, {totalChkDuration / 1000:F3} checksumming, {imageWriteDuration:F3} writing, {(closeEnd - closeStart).TotalSeconds:F3} closing).");

            UpdateStatus?.
            Invoke($"Average speed: {((double)blockSize * (double)(blocks + 1)) / 1048576 / (totalDuration / 1000):F3} MiB/sec.");

            if (maxSpeed > 0)
            {
                UpdateStatus?.Invoke($"Fastest speed burst: {maxSpeed:F3} MiB/sec.");
            }

            if (minSpeed > 0 &&
                minSpeed < double.MaxValue)
            {
                UpdateStatus?.Invoke($"Slowest speed burst: {minSpeed:F3} MiB/sec.");
            }

            UpdateStatus?.Invoke($"{_resume.BadBlocks.Count} sectors could not be read.");
            UpdateStatus?.Invoke("");

            Statistics.AddMedia(dskType, true);
        }
예제 #51
0
 /// <summary>
 /// Constructor for SparkleUpdate when there are some updates available.
 /// </summary>
 public UpdateInfo(UpdateStatus status, List <AppCastItem> updates)
 {
     Status  = status;
     Updates = updates;
 }
예제 #52
0
 /// <summary>
 /// Constructor for SparkleUpdate for when there aren't any updates available. Updates are automatically set to null.
 /// </summary>
 public UpdateInfo(UpdateStatus status)
 {
     Status  = status;
     Updates = null;
 }
예제 #53
0
        /// <summary>Reads all CD user data</summary>
        /// <param name="audioExtents">Extents with audio sectors</param>
        /// <param name="blocks">Total number of positive sectors</param>
        /// <param name="blockSize">Size of the read sector in bytes</param>
        /// <param name="currentSpeed">Current read speed</param>
        /// <param name="currentTry">Current dump hardware try</param>
        /// <param name="extents">Extents</param>
        /// <param name="ibgLog">IMGBurn log</param>
        /// <param name="imageWriteDuration">Duration of image write</param>
        /// <param name="lastSector">Last sector number</param>
        /// <param name="leadOutExtents">Lead-out extents</param>
        /// <param name="maxSpeed">Maximum speed</param>
        /// <param name="mhddLog">MHDD log</param>
        /// <param name="minSpeed">Minimum speed</param>
        /// <param name="newTrim">Is trim a new one?</param>
        /// <param name="nextData">Next cluster of sectors is all data</param>
        /// <param name="offsetBytes">Read offset</param>
        /// <param name="read6">Device supports READ(6)</param>
        /// <param name="read10">Device supports READ(10)</param>
        /// <param name="read12">Device supports READ(12)</param>
        /// <param name="read16">Device supports READ(16)</param>
        /// <param name="readcd">Device supports READ CD</param>
        /// <param name="sectorsForOffset">Sectors needed to fix offset</param>
        /// <param name="subSize">Subchannel size in bytes</param>
        /// <param name="supportedSubchannel">Drive's maximum supported subchannel</param>
        /// <param name="supportsLongSectors">Supports reading EDC and ECC</param>
        /// <param name="totalDuration">Total commands duration</param>
        void ReadCdData(ExtentsULong audioExtents, ulong blocks, uint blockSize, ref double currentSpeed,
                        DumpHardwareType currentTry, ExtentsULong extents, IbgLog ibgLog, ref double imageWriteDuration,
                        long lastSector, ExtentsULong leadOutExtents, ref double maxSpeed, MhddLog mhddLog,
                        ref double minSpeed, out bool newTrim, bool nextData, int offsetBytes, bool read6, bool read10,
                        bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize,
                        MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
                        Track[] tracks)
        {
            ulong    sectorSpeedStart = 0;                 // Used to calculate correct speed
            DateTime timeSpeedStart   = DateTime.UtcNow;   // Time of start for speed calculation
            uint     blocksToRead     = 0;                 // How many sectors to read at once
            bool     sense            = true;              // Sense indicator

            byte[]     cmdBuf      = null;                 // Data buffer
            byte[]     senseBuf    = null;                 // Sense buffer
            double     cmdDuration = 0;                    // Command execution time
            const uint sectorSize  = 2352;                 // Full sector size

            newTrim = false;
            PlextorSubchannel supportedPlextorSubchannel;

            switch (supportedSubchannel)
            {
            case MmcSubchannel.None:
                supportedPlextorSubchannel = PlextorSubchannel.None;

                break;

            case MmcSubchannel.Raw:
                supportedPlextorSubchannel = PlextorSubchannel.All;

                break;

            case MmcSubchannel.Q16:
                supportedPlextorSubchannel = PlextorSubchannel.Q16;

                break;

            case MmcSubchannel.Rw:
                supportedPlextorSubchannel = PlextorSubchannel.Pack;

                break;

            default:
                supportedPlextorSubchannel = PlextorSubchannel.None;

                break;
            }

            InitProgress?.Invoke();

            int  currentReadSpeed      = _speed;
            bool crossingLeadOut       = false;
            bool failedCrossingLeadOut = false;

            for (ulong i = _resume.NextBlock; (long)i <= lastSector; i += blocksToRead)
            {
                if (_aborted)
                {
                    currentTry.Extents = ExtentsConverter.ToMetadata(extents);
                    UpdateStatus?.Invoke("Aborted!");
                    _dumpLog.WriteLine("Aborted!");

                    break;
                }

                while (leadOutExtents.Contains(i))
                {
                    i++;
                }

                if ((long)i > lastSector)
                {
                    break;
                }

                uint firstSectorToRead = (uint)i;

                Track track = tracks.OrderBy(t => t.TrackStartSector).LastOrDefault(t => i >= t.TrackStartSector);

                blocksToRead = 0;
                bool inData = nextData;

                for (ulong j = i; j < i + _maximumReadable; j++)
                {
                    if (j > (ulong)lastSector)
                    {
                        if (!failedCrossingLeadOut)
                        {
                            blocksToRead += (uint)sectorsForOffset;
                        }

                        if (sectorsForOffset > 0)
                        {
                            crossingLeadOut = true;
                        }

                        break;
                    }

                    if (nextData)
                    {
                        if (audioExtents.Contains(j))
                        {
                            nextData = false;

                            break;
                        }

                        blocksToRead++;
                    }
                    else
                    {
                        if (!audioExtents.Contains(j))
                        {
                            nextData = true;

                            break;
                        }

                        blocksToRead++;
                    }
                }

                if (track.TrackSequence != 0 &&
                    (i + blocksToRead) - (ulong)sectorsForOffset > track.TrackEndSector + 1)
                {
                    blocksToRead = (uint)(((track.TrackEndSector + 1) - i) + (ulong)sectorsForOffset);
                }

                if (blocksToRead == 1 &&
                    !inData)
                {
                    blocksToRead += (uint)sectorsForOffset;
                }

                if (_fixOffset && !inData)
                {
                    // TODO: FreeBSD bug
                    if (offsetBytes < 0)
                    {
                        if (i == 0)
                        {
                            firstSectorToRead = uint.MaxValue - (uint)(sectorsForOffset - 1); // -1
                        }
                        else
                        {
                            firstSectorToRead -= (uint)sectorsForOffset;
                        }
                    }
                }

                if (!inData &&
                    currentReadSpeed == 0xFFFF)
                {
                    _dumpLog.WriteLine("Setting speed to 8x for audio reading.");
                    UpdateStatus?.Invoke("Setting speed to 8x for audio reading.");

                    _dev.SetCdSpeed(out _, RotationalControl.ClvAndImpureCav, 1416, 0, _dev.Timeout, out _);

                    currentReadSpeed = 1200;
                }

                if (inData && currentReadSpeed != _speed)
                {
                    _dumpLog.WriteLine($"Setting speed to {(_speed == 0xFFFF ? "MAX for data reading" : $"{_speed}x")}.");
예제 #54
0
        internal static void GoCheckForUpdates(bool silentMode, bool force)
        {
            updateURL = string.Empty;
            updateVER = string.Empty;
            needToShowNotification = false;

            if (!force)
            {
                // only check for updates every 7 days
                if (Math.Abs((Settings.LatestUpdateCheck - DateTime.Today).TotalDays) < 7)
                {
                    return; // not time yet
                }
            }

            Random r = new Random(); // defeat any cache by appending a random number to the URL

            WebClient web = new WebClient();

            web.DownloadStringAsync(new Uri(WebUpdateFile + "?r=" + r.Next(int.MaxValue).ToString()));

            web.DownloadStringCompleted += (sender, e) =>
            {
                UpdateStatus updateStatus = UpdateStatus.Unknown;

                if (!e.Cancelled && e.Error == null)
                {
                    Settings.LatestUpdateCheck = DateTime.Now;

                    foreach (string line in e.Result.Split('\n'))
                    {
                        string[] data = line.Split(';');
                        if (data.Length >= 2 && data[0].Trim() == ThisApplication.Trim())
                        {
                            if (data[1].Trim() != ThisVersion.Trim())
                            {
                                updateStatus = UpdateStatus.UpdateAvailable;
                                updateVER    = data[1].Trim();
                                updateURL    = data[2].Trim();
                            }
                            else
                            {
                                updateStatus = UpdateStatus.UpToDate;
                            }

                            break;
                        }
                    }
                }

                if (silentMode)
                {
                    needToShowNotification = updateStatus == UpdateStatus.UpdateAvailable;
                }
                else
                {
                    switch (updateStatus)
                    {
                    case UpdateStatus.Unknown:
                        FlexibleMessageBox.Show("I'm not sure if you are up-to-date.\n\nI was not able to reach the update website.\n\nTry again later.", "CodeLab Updater", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        break;

                    case UpdateStatus.UpToDate:
                        FlexibleMessageBox.Show("You are up-to-date!", "CodeLab Updater", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        break;

                    case UpdateStatus.UpdateAvailable:
                        if (FlexibleMessageBox.Show("An update to CodeLab is available.\n\nWould you like to download CodeLab v" + updateVER + "?\n\n(This will not close your current CodeLab session.)", "CodeLab Updater", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                        {
                            LaunchUrl(updateURL);
                        }
                        break;
                    }
                }
            };
        }
예제 #55
0
		/// <summary>
		/// Start the update process, which consists of getting a server endpoint, computing th local files' hashes, dumping them to a debug file, getting the remote hash list and comparing it to the locally generated one, then downloading the necessary files to finally replace the current files with them.
		/// </summary>
		public void Update() {
			fileHashes = new Dictionary<string, string>();
			bool stepSuccessful = true;
			if (stepSuccessful && !cancelled) stepSuccessful = TryUpdateStep(GetServerUpdateEndpoint, UpdateStatus.STARTING);
			if (stepSuccessful && !cancelled) stepSuccessful = TryUpdateStep(CheckFiles, UpdateStatus.CHECKING);
			if (stepSuccessful && MainClass.DebugMode && !cancelled) stepSuccessful = TryUpdateStep(DumpHashes, UpdateStatus.CHECKING);
			if (stepSuccessful && !cancelled) stepSuccessful = TryUpdateStep(LoadUpdates, UpdateStatus.COMPARING);
			if (stepSuccessful && !cancelled) stepSuccessful = TryUpdateStep(DownloadFiles, UpdateStatus.DOWNLOADING);
			if (stepSuccessful && !cancelled) stepSuccessful = TryUpdateStep(ApplyPatches, UpdateStatus.APPLYING);
			Status = UpdateStatus.DONE; stepCallback(Status);
		}
예제 #56
0
        /// <summary>Creates optical metadata sidecar</summary>
        /// <param name="blockSize">Size of the read sector in bytes</param>
        /// <param name="blocks">Total number of positive sectors</param>
        /// <param name="mediaType">Disc type</param>
        /// <param name="layers">Disc layers</param>
        /// <param name="mediaTags">Media tags</param>
        /// <param name="sessions">Disc sessions</param>
        /// <param name="totalChkDuration">Total time spent doing checksums</param>
        /// <param name="discOffset">Disc write offset</param>
        void WriteOpticalSidecar(uint blockSize, ulong blocks, MediaType mediaType, LayersType layers,
                                 Dictionary <MediaTagType, byte[]> mediaTags, int sessions, out double totalChkDuration,
                                 int?discOffset)
        {
            _dumpLog.WriteLine("Creating sidecar.");
            var         filters     = new FiltersList();
            IFilter     filter      = filters.GetFilter(_outputPath);
            IMediaImage inputPlugin = ImageFormat.Detect(filter);

            totalChkDuration = 0;

            if (!inputPlugin.Open(filter))
            {
                StoppingErrorMessage?.Invoke("Could not open created image.");

                return;
            }

            DateTime chkStart = DateTime.UtcNow;

            // ReSharper disable once UseObjectOrCollectionInitializer
            _sidecarClass = new Sidecar(inputPlugin, _outputPath, filter.Id, _encoding);
            _sidecarClass.InitProgressEvent    += InitProgress;
            _sidecarClass.UpdateProgressEvent  += UpdateProgress;
            _sidecarClass.EndProgressEvent     += EndProgress;
            _sidecarClass.InitProgressEvent2   += InitProgress2;
            _sidecarClass.UpdateProgressEvent2 += UpdateProgress2;
            _sidecarClass.EndProgressEvent2    += EndProgress2;
            _sidecarClass.UpdateStatusEvent    += UpdateStatus;
            CICMMetadataType sidecar = _sidecarClass.Create();
            DateTime         end     = DateTime.UtcNow;

            if (_aborted)
            {
                return;
            }

            totalChkDuration = (end - chkStart).TotalMilliseconds;
            _dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds);

            _dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.",
                               ((double)blockSize * (double)(blocks + 1)) / 1024 / (totalChkDuration / 1000));

            if (_preSidecar != null)
            {
                _preSidecar.OpticalDisc = sidecar.OpticalDisc;
                sidecar = _preSidecar;
            }

            List <(ulong start, string type)> filesystems = new List <(ulong start, string type)>();

            if (sidecar.OpticalDisc[0].Track != null)
            {
                filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track
                                     where xmlTrack.FileSystemInformation != null
                                     from partition in xmlTrack.FileSystemInformation
                                     where partition.FileSystems != null from fileSystem in partition.FileSystems
                                     select(partition.StartSector, fileSystem.Type));
            }

            if (filesystems.Count > 0)
            {
                foreach (var filesystem in filesystems.Select(o => new
                {
                    o.start,
                    o.type
                }).Distinct())
                {
                    _dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start);
                }
            }

            sidecar.OpticalDisc[0].Dimensions        = Dimensions.DimensionsFromMediaType(mediaType);
            (string type, string subType)discType    = CommonTypes.Metadata.MediaType.MediaTypeToString(mediaType);
            sidecar.OpticalDisc[0].DiscType          = discType.type;
            sidecar.OpticalDisc[0].DiscSubType       = discType.subType;
            sidecar.OpticalDisc[0].DumpHardwareArray = _resume.Tries.ToArray();
            sidecar.OpticalDisc[0].Sessions          = (uint)sessions;
            sidecar.OpticalDisc[0].Layers            = layers;

            if (discOffset.HasValue)
            {
                sidecar.OpticalDisc[0].Offset          = (int)(discOffset / 4);
                sidecar.OpticalDisc[0].OffsetSpecified = true;
            }

            if (mediaTags != null)
            {
                foreach (KeyValuePair <MediaTagType, byte[]> tag in mediaTags.Where(tag => _outputPlugin.
                                                                                    SupportedMediaTags.
                                                                                    Contains(tag.Key)))
                {
                    AddMediaTagToSidecar(_outputPath, tag, ref sidecar);
                }
            }

            UpdateStatus?.Invoke("Writing metadata sidecar");

            var xmlFs = new FileStream(_outputPrefix + ".cicm.xml", FileMode.Create);

            var xmlSer = new XmlSerializer(typeof(CICMMetadataType));

            xmlSer.Serialize(xmlFs, sidecar);
            xmlFs.Close();
        }
예제 #57
0
 /// <summary>
 /// Обновляет текст на форме
 /// </summary>
 public void Update()
 {
     if (textBoxStatus.InvokeRequired)
     {
         myDelegate = new UpdateStatus(Update);
         textBoxStatus.Invoke(myDelegate);
     }
     else
         textBoxStatus.Text = textBoxStatus.Text + ((textBoxStatus.Text == "") ? "" : Environment.NewLine) + newLineText;
 }
예제 #58
0
 public UpdateStatusChangedEventArgs(UpdateStatus updateStatus)
 {
     UpdateStatus = updateStatus;
 }
예제 #59
0
 void UpdateDownloadList(string KBNumber, string guid, UpdateStatus status)
 {
 }
예제 #60
0
        /// <summary>Dumps an optical disc</summary>
        void Mmc(ref MediaType dskType)
        {
            bool sense;

            byte[] tmpBuf;
            bool   compactDisc = true;
            bool   isXbox      = false;

            _speedMultiplier = 1;

            // TODO: Log not only what is it reading, but if it was read correctly or not.
            sense = _dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, _dev.Timeout,
                                          out _);

            if (!sense)
            {
                Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);
                _dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile);

                switch (ftr.CurrentProfile)
                {
                case 0x0001:
                    dskType          = MediaType.GENERIC_HDD;
                    _speedMultiplier = -1;
                    goto default;

                case 0x0002:
                    dskType          = MediaType.PD650;
                    _speedMultiplier = -1;
                    goto default;

                case 0x0005:
                    dskType = MediaType.CDMO;

                    break;

                case 0x0008:
                    dskType = MediaType.CD;

                    break;

                case 0x0009:
                    dskType = MediaType.CDR;

                    break;

                case 0x000A:
                    dskType = MediaType.CDRW;

                    break;

                case 0x0010:
                    dskType          = MediaType.DVDROM;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0011:
                    dskType          = MediaType.DVDR;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0012:
                    dskType          = MediaType.DVDRAM;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0013:
                case 0x0014:
                    dskType          = MediaType.DVDRW;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0015:
                case 0x0016:
                    dskType          = MediaType.DVDRDL;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0017:
                    dskType          = MediaType.DVDRWDL;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0018:
                    dskType          = MediaType.DVDDownload;
                    _speedMultiplier = 9;
                    goto default;

                case 0x001A:
                    dskType          = MediaType.DVDPRW;
                    _speedMultiplier = 9;
                    goto default;

                case 0x001B:
                    dskType          = MediaType.DVDPR;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0020:
                    dskType = MediaType.DDCD;
                    goto default;

                case 0x0021:
                    dskType = MediaType.DDCDR;
                    goto default;

                case 0x0022:
                    dskType = MediaType.DDCDRW;
                    goto default;

                case 0x002A:
                    dskType          = MediaType.DVDPRWDL;
                    _speedMultiplier = 9;
                    goto default;

                case 0x002B:
                    dskType          = MediaType.DVDPRDL;
                    _speedMultiplier = 9;
                    goto default;

                case 0x0040:
                    dskType          = MediaType.BDROM;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0041:
                case 0x0042:
                    dskType          = MediaType.BDR;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0043:
                    dskType          = MediaType.BDRE;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0050:
                    dskType          = MediaType.HDDVDROM;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0051:
                    dskType          = MediaType.HDDVDR;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0052:
                    dskType          = MediaType.HDDVDRAM;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0053:
                    dskType          = MediaType.HDDVDRW;
                    _speedMultiplier = 30;
                    goto default;

                case 0x0058:
                    dskType          = MediaType.HDDVDRDL;
                    _speedMultiplier = 30;
                    goto default;

                case 0x005A:
                    dskType          = MediaType.HDDVDRWDL;
                    _speedMultiplier = 30;
                    goto default;

                default:
                    compactDisc = false;

                    break;
                }
            }

            if (compactDisc)
            {
                CompactDisc(out dskType);

                return;
            }

            var   scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw);
            ulong blocks     = scsiReader.GetDeviceBlocks();

            _dumpLog.WriteLine("Device reports disc has {0} blocks", blocks);
            Dictionary <MediaTagType, byte[]> mediaTags = new Dictionary <MediaTagType, byte[]>();

            if (dskType == MediaType.PD650)
            {
                switch (blocks + 1)
                {
                case 1281856:
                    dskType = MediaType.PD650_WORM;

                    break;

                case 58620544:
                    dskType = MediaType.REV120;

                    break;

                case 17090880:
                    dskType = MediaType.REV35;

                    break;

                // TODO: Unknown value
                default:
                    dskType = MediaType.REV70;

                    break;
                }
            }

            #region Nintendo
            switch (dskType)
            {
            case MediaType.Unknown when blocks > 0:
                _dumpLog.WriteLine("Reading Physical Format Information");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    PFI.PhysicalFormatInformation?nintendoPfi = PFI.Decode(cmdBuf);

                    if (nintendoPfi != null)
                    {
                        if (nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo &&
                            nintendoPfi.Value.PartVersion == 15)
                        {
                            _dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented.");

                            StoppingErrorMessage?.
                            Invoke("Dumping Nintendo GameCube or Wii discs is not yet implemented.");

                            return;
                        }
                    }
                }

                break;

            case MediaType.DVDDownload:
            case MediaType.DVDPR:
            case MediaType.DVDPRDL:
            case MediaType.DVDPRW:
            case MediaType.DVDPRWDL:
            case MediaType.DVDR:
            case MediaType.DVDRAM:
            case MediaType.DVDRDL:
            case MediaType.DVDROM:
            case MediaType.DVDRW:
            case MediaType.DVDRWDL:
            case MediaType.HDDVDR:
            case MediaType.HDDVDRAM:
            case MediaType.HDDVDRDL:
            case MediaType.HDDVDROM:
            case MediaType.HDDVDRW:
            case MediaType.HDDVDRWDL:
                _dumpLog.WriteLine("Reading Physical Format Information");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    if (PFI.Decode(cmdBuf).HasValue)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.DVD_PFI, tmpBuf);

                        PFI.PhysicalFormatInformation decPfi = PFI.Decode(cmdBuf).Value;
                        UpdateStatus?.Invoke($"PFI:\n{PFI.Prettify(decPfi)}");

                        // False book types
                        if (dskType == MediaType.DVDROM)
                        {
                            switch (decPfi.DiskCategory)
                            {
                            case DiskCategory.DVDPR:
                                dskType = MediaType.DVDPR;

                                break;

                            case DiskCategory.DVDPRDL:
                                dskType = MediaType.DVDPRDL;

                                break;

                            case DiskCategory.DVDPRW:
                                dskType = MediaType.DVDPRW;

                                break;

                            case DiskCategory.DVDPRWDL:
                                dskType = MediaType.DVDPRWDL;

                                break;

                            case DiskCategory.DVDR:
                                dskType = decPfi.PartVersion == 6 ? MediaType.DVDRDL : MediaType.DVDR;

                                break;

                            case DiskCategory.DVDRAM:
                                dskType = MediaType.DVDRAM;

                                break;

                            default:
                                dskType = MediaType.DVDROM;

                                break;

                            case DiskCategory.DVDRW:
                                dskType = decPfi.PartVersion == 3 ? MediaType.DVDRWDL : MediaType.DVDRW;

                                break;

                            case DiskCategory.HDDVDR:
                                dskType = MediaType.HDDVDR;

                                break;

                            case DiskCategory.HDDVDRAM:
                                dskType = MediaType.HDDVDRAM;

                                break;

                            case DiskCategory.HDDVDROM:
                                dskType = MediaType.HDDVDROM;

                                break;

                            case DiskCategory.HDDVDRW:
                                dskType = MediaType.HDDVDRW;

                                break;

                            case DiskCategory.Nintendo:
                                dskType = decPfi.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD;

                                break;

                            case DiskCategory.UMD:
                                dskType = MediaType.UMD;

                                break;
                            }
                        }
                    }
                }

                _dumpLog.WriteLine("Reading Disc Manufacturing Information");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.DiscManufacturingInformation, 0, _dev.Timeout,
                                               out _);

                if (!sense)
                {
                    if (DMI.IsXbox(cmdBuf) ||
                        DMI.IsXbox360(cmdBuf))
                    {
                        if (DMI.IsXbox(cmdBuf))
                        {
                            dskType = MediaType.XGD;
                        }
                        else if (DMI.IsXbox360(cmdBuf))
                        {
                            dskType = MediaType.XGD2;

                            // All XGD3 all have the same number of blocks
                            if (blocks == 25063 ||      // Locked (or non compatible drive)
                                blocks == 4229664 ||    // Xtreme unlock
                                blocks == 4246304)      // Wxripper unlock
                            {
                                dskType = MediaType.XGD3;
                            }
                        }

                        sense = _dev.ScsiInquiry(out byte[] inqBuf, out _);

                        if (sense ||
                            !Inquiry.Decode(inqBuf).HasValue ||
                            (Inquiry.Decode(inqBuf).HasValue&& !Inquiry.Decode(inqBuf).Value.KreonPresent))
                        {
                            _dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware.");

                            StoppingErrorMessage?.
                            Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware.");

                            return;
                        }

                        if (_dumpRaw && !_force)
                        {
                            StoppingErrorMessage?.
                            Invoke("Not continuing. If you want to continue reading cooked data when raw is not available use the force option.");

                            // TODO: Exit more gracefully
                            return;
                        }

                        isXbox = true;
                    }

                    if (cmdBuf.Length == 2052)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.DVD_DMI, tmpBuf);
                    }
                }

                break;
            }
            #endregion Nintendo

            #region All DVD and HD DVD types
            #endregion All DVD and HD DVD types

            #region DVD-ROM
            if (dskType == MediaType.DVDDownload ||
                dskType == MediaType.DVDROM)
            {
                _dumpLog.WriteLine("Reading Lead-in Copyright Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.CopyrightInformation, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    if (CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.DVD_CMI, tmpBuf);
                    }
                }
            }
            #endregion DVD-ROM

            switch (dskType)
            {
                #region DVD-ROM and HD DVD-ROM
            case MediaType.DVDDownload:
            case MediaType.DVDROM:
            case MediaType.HDDVDROM:
                _dumpLog.WriteLine("Reading Burst Cutting Area.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.BurstCuttingArea, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DVD_BCA, tmpBuf);
                }

                break;
                #endregion DVD-ROM and HD DVD-ROM

                #region DVD-RAM and HD DVD-RAM
            case MediaType.DVDRAM:
            case MediaType.HDDVDRAM:
                _dumpLog.WriteLine("Reading Disc Description Structure.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.DvdramDds, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    if (DDS.Decode(cmdBuf).HasValue)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.DVDRAM_DDS, tmpBuf);
                    }
                }

                _dumpLog.WriteLine("Reading Spare Area Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, _dev.Timeout,
                                               out _);

                if (!sense)
                {
                    if (Spare.Decode(cmdBuf).HasValue)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.DVDRAM_SpareArea, tmpBuf);
                    }
                }

                break;
                #endregion DVD-RAM and HD DVD-RAM

                #region DVD-R and DVD-RW
            case MediaType.DVDR:
            case MediaType.DVDRW:
                _dumpLog.WriteLine("Reading Pre-Recorded Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.PreRecordedInfo, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DVDR_PreRecordedInfo, tmpBuf);
                }

                break;
                #endregion DVD-R and DVD-RW
            }

            switch (dskType)
            {
                #region DVD-R, DVD-RW and HD DVD-R
            case MediaType.DVDR:
            case MediaType.DVDRW:
            case MediaType.HDDVDR:
                _dumpLog.WriteLine("Reading Media Identifier.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.DvdrMediaIdentifier, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DVDR_MediaIdentifier, tmpBuf);
                }

                _dumpLog.WriteLine("Reading Recordable Physical Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.DvdrPhysicalInformation, 0, _dev.Timeout,
                                               out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DVDR_PFI, tmpBuf);
                }

                break;
                #endregion DVD-R, DVD-RW and HD DVD-R

                #region All DVD+
            case MediaType.DVDPR:
            case MediaType.DVDPRDL:
            case MediaType.DVDPRW:
            case MediaType.DVDPRWDL:
                _dumpLog.WriteLine("Reading ADdress In Pregroove.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.Adip, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DVD_ADIP, tmpBuf);
                }

                _dumpLog.WriteLine("Reading Disc Control Blocks.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.Dcb, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.DCB, tmpBuf);
                }

                break;
                #endregion All DVD+

                #region HD DVD-ROM
            case MediaType.HDDVDROM:
                _dumpLog.WriteLine("Reading Lead-in Copyright Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0,
                                               MmcDiscStructureFormat.HddvdCopyrightInformation, 0, _dev.Timeout,
                                               out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.HDDVD_CPI, tmpBuf);
                }

                break;
                #endregion HD DVD-ROM

                #region All Blu-ray
            case MediaType.BDR:
            case MediaType.BDRE:
            case MediaType.BDROM:
            case MediaType.BDRXL:
            case MediaType.BDREXL:
                _dumpLog.WriteLine("Reading Disc Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
                                               MmcDiscStructureFormat.DiscInformation, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    if (DI.Decode(cmdBuf).HasValue)
                    {
                        tmpBuf = new byte[cmdBuf.Length - 4];
                        Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                        mediaTags.Add(MediaTagType.BD_DI, tmpBuf);
                    }
                }

                // TODO: PAC

                /*
                 * dumpLog.WriteLine("Reading PAC.");
                 * sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
                 *                            MmcDiscStructureFormat.Pac, 0, dev.Timeout, out _);
                 * if(!sense)
                 * {
                 *  tmpBuf = new byte[cmdBuf.Length - 4];
                 *  Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                 *  mediaTags.Add(MediaTagType.PAC, tmpBuf);
                 * }*/
                break;
                #endregion All Blu-ray
            }

            switch (dskType)
            {
                #region BD-ROM only
            case MediaType.BDROM:
                _dumpLog.WriteLine("Reading Burst Cutting Area.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
                                               MmcDiscStructureFormat.BdBurstCuttingArea, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.BD_BCA, tmpBuf);
                }

                break;
                #endregion BD-ROM only

                #region Writable Blu-ray only
            case MediaType.BDR:
            case MediaType.BDRE:
            case MediaType.BDRXL:
            case MediaType.BDREXL:
                _dumpLog.WriteLine("Reading Disc Definition Structure.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
                                               MmcDiscStructureFormat.BdDds, 0, _dev.Timeout, out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.BD_DDS, tmpBuf);
                }

                _dumpLog.WriteLine("Reading Spare Area Information.");

                sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0,
                                               MmcDiscStructureFormat.BdSpareAreaInformation, 0, _dev.Timeout,
                                               out _);

                if (!sense)
                {
                    tmpBuf = new byte[cmdBuf.Length - 4];
                    Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4);
                    mediaTags.Add(MediaTagType.BD_SpareArea, tmpBuf);
                }

                break;
                #endregion Writable Blu-ray only
            }

            if (isXbox)
            {
                Xgd(mediaTags, ref dskType);

                return;
            }

            Sbc(mediaTags, ref dskType, true);
        }