private static bool RetrieveForkData(this Device device, ExecuteDeviceCommandAsyncTaskData data, IEnumerable <Fork> forksToRetrieve, string destinationDirectory, IEnumerable <string> fileNames) { var configuration = SingleInstanceApplication.Instance.GetConfiguration <Configuration>(); var succeeded = false; var numForks = forksToRetrieve.Count(); var forkFilenames = fileNames == null ? null : fileNames.ToList(); var forkBeingRetrieved = 0; foreach (var fork in forksToRetrieve) { if (data.AcceptCancelIfRequested()) { break; } ++forkBeingRetrieved; if (data != null) { data.UpdateTaskProgress((double)forkBeingRetrieved / numForks, string.Format(Resources.Strings.DeviceMultistageCommand_BackupFileSystem_RetrievingFiles_Format, forkBeingRetrieved, numForks)); } var bytesRemaining = (int)fork.Size; var offset = 0; succeeded = false; using (var memory = new System.IO.MemoryStream()) { do { const uint Address = 0u; var bytesToRead = System.Math.Min(bytesRemaining, Device.TotalRAMSize); succeeded = ReadForkToRam.Create(Address, fork.GlobalForkNumber, (uint)offset, bytesToRead).Execute <bool>(device.Port, data); byte[] dataRead = null; if (succeeded) { dataRead = (byte[])DownloadDataBlockFromRam.Create(Address, bytesToRead).Execute(device.Port, data, out succeeded); } if (succeeded) { memory.Write(dataRead, offset, bytesToRead); bytesRemaining -= bytesToRead; offset += bytesToRead; } }while (succeeded && (bytesRemaining > 0)); if (data != null) { data.UpdateTaskProgress((double)forkBeingRetrieved / numForks, string.Format(Resources.Strings.DeviceMultistageCommand_BackupFileSystem_SavingFiles_Format, forkBeingRetrieved, numForks)); } memory.Seek(0, System.IO.SeekOrigin.Begin); using (var tempFile = FileSystemFile.Inflate(memory)) { var fileName = (forkFilenames == null) ? configuration.GetForkDataFileName(fork.GlobalForkNumber) : forkFilenames[forkBeingRetrieved - 1]; var forkPath = System.IO.Path.Combine(destinationDirectory, fileName); forkPath = forkPath.EnsureUniqueFileName(); data.FailureMessage = forkPath; System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(forkPath)); try { // Test to see if this is a Fork containing a LUIGI file. memory.Seek(0, System.IO.SeekOrigin.Begin); LuigiFileHeader.Inflate(memory); forkPath = System.IO.Path.ChangeExtension(forkPath, ProgramFileKind.LuigiFile.FileExtension()); } catch (INTV.Core.UnexpectedFileTypeException) { // This is OK... we only want to execute certain functions if the file is a LUIGI file. } if (System.IO.File.Exists(forkPath)) { var crcOfTarget = Crc32.OfFile(forkPath); var crcOfSource = Crc32.OfFile(tempFile.FileInfo.FullName); if (crcOfTarget != crcOfSource) { forkPath = forkPath.EnsureUniqueFileName(); System.IO.File.Copy(tempFile.FileInfo.FullName, forkPath); } } else { System.IO.File.Copy(tempFile.FileInfo.FullName, forkPath); } fork.FilePath = forkPath; } } if (!succeeded) { break; } } return(succeeded); }