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; }
public Renderer(String regionDir, String outPath, UpdateStatus updateStatus = null, DoneCallback callback = null) { this.regionDir = regionDir; this.outPath = outPath; this.updateStatus = updateStatus; this.callback = callback; }
public InterpreterProperties(InterpreterProperties rhs) { executingGraphNode = rhs.executingGraphNode; nodeIterations = rhs.nodeIterations; functionCallArguments = rhs.functionCallArguments; functionCallDotCallDimensions = rhs.functionCallDotCallDimensions; updateStatus = rhs.updateStatus; }
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; }
public void Reset() { executingGraphNode = null; nodeIterations = new List<GraphNode>(); functionCallArguments = new List<StackValue>(); functionCallDotCallDimensions = new List<StackValue>(); updateStatus = UpdateStatus.kNormalUpdate; }
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; }
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 }
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; }
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 }
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); }
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(); }
internal static ArgumentException InvalidUpdateStatus(UpdateStatus status) { object [] args = new object [] { status }; return(new ArgumentException(GetExceptionMessage("Invalid UpdateStatus: {0}", args))); }
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(); }
internal static ArgumentException InvalidUpdateStatus (UpdateStatus status) { object [] args = new object [] { status }; return new ArgumentException (GetExceptionMessage ("Invalid UpdateStatus: {0}",args)); }
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); } }
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."); }
public void UpdateStatus([FromBody] UpdateStatus statusModel) { taskService.UpdateStatus(statusModel); }
// 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(); }
/// <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); }
public UpdateChecker(TimeSpan period, WasabiClient client) : base(period) { WasabiClient = Guard.NotNull(nameof(client), client); UpdateStatus = new UpdateStatus(true, true, new Version()); }
/// <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(); }
/// <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."); } } } }
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); }
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); }
/// <summary> /// Constructor for SparkleUpdate when there are some updates available. /// </summary> public UpdateInfo(UpdateStatus status, AppCastItem[] updates) { Status = status; Updates = updates; }
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; }
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; } }
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); }
// 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(); }
/// <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; }
/// <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(); }
/// <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); }
private void Wait() { Status = "Standby mode"; UpdateStatus?.Invoke(Status); }
/// <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; }
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(); }
/// <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<float> 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; } }
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(""); }
/// <summary> /// Очищает поле вывода статуса на форме /// </summary> public void Clear() { if (textBoxStatus.InvokeRequired) { myDelegate = new UpdateStatus(Update); textBoxStatus.Invoke(myDelegate); } else textBoxStatus.Text = ""; }
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; } }
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)); }
public ReadResult(UpdateStatus status) { this.status = status; }
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); }
private void UpdateCallback(UpdateStatus updateStatus, int progress) { UpdateStatus = updateStatus; }
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); }
/// <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); }
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); }
/// <summary> /// Constructor for SparkleUpdate when there are some updates available. /// </summary> public UpdateInfo(UpdateStatus status, List <AppCastItem> updates) { Status = status; Updates = updates; }
/// <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; }
/// <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")}.");
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; } } }; }
/// <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); }
/// <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(); }
/// <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; }
public UpdateStatusChangedEventArgs(UpdateStatus updateStatus) { UpdateStatus = updateStatus; }
void UpdateDownloadList(string KBNumber, string guid, UpdateStatus status) { }
/// <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); }