Example #1
0
        private static void OperationTex2Png()
        {
            string filename = ConsolePath("Full path to .tex file or partial path to txm/txv..?");

            if (filename.IsEmpty())
            {
                return;
            }
            if (Path.GetExtension(filename).ToLower() == ".txm" || Path.GetExtension(filename).ToLower() == ".txv")
            {
                filename = filename.Substring(0, filename.Length - 4);
            }
            DelayedStreamCache streams = new DelayedStreamCache();
            Txm    tex  = OpenTex(filename, streams);
            string path = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileName(filename) + ".ext");

            Directory.CreateDirectory(path);
            for (int i = 0; i < tex.Images.Count; i++)
            {
                string file = Path.Combine(path, tex.Images[i].Name);
                tex.Images[i].PrimaryBitmap.Save(file + ".png", ImageFormat.Png);
                if (tex.Images[i].SecondaryData != null)
                {
                    tex.Images[i].SecondaryData.Position = 0;
                    FileStream secondary = new FileStream(file + ".dat", FileMode.Create, FileAccess.Write);
                    Util.StreamCopy(secondary, tex.Images[i].SecondaryData);
                    secondary.Close();
                }
            }
            streams.Dispose();
        }
Example #2
0
 static void PlatformDetection_DetectDirectory(string path, PlatformList platforms)
 {
     if (DetectDirectoryNode != null)
     {
         DelayedStreamCache cache = new DelayedStreamCache();
         DirectoryNode      root  = DirectoryNode.FromPath(path, cache, FileAccess.Read, FileShare.Read);
         DetectDirectoryNode(path, root, platforms);
         cache.Dispose();
     }
 }
Example #3
0
        public void Dispose()
        {
            Mutex.WaitOne();

            if (Cache != null)
            {
                Cache.Dispose();
                Cache = null;
            }

            foreach (FormatData data in Data)
            {
                data.Dispose();
                ChangesetRemoved.Add(data);
            }

            Data.Clear();

            Mutex.ReleaseMutex();
        }
Example #4
0
        private static void OperationPackFPS4()
        {
            string dirname = ConsolePath("Full path to FPS4 file contents..?");
            string filename;

            if (dirname.EndsWith(".ext"))
            {
                filename = dirname.Substring(0, dirname.Length - 4);
            }
            else
            {
                filename = ConsolePath("Full path to FPS4 archive..?");
            }

            if (!File.Exists(filename))
            {
                Console.WriteLine("FPS4 file does not exist.");
                return;
            }

            Stream stream = new CachedReadStream(new FileStream(filename, FileMode.Open, FileAccess.Read));

            FPS4 fps = new FPS4(stream);

            DelayedStreamCache cache = new DelayedStreamCache();

            string[] files = Directory.GetFiles(dirname, "*", SearchOption.TopDirectoryOnly);
            foreach (string file in files)
            {
                string        fname = Path.GetFileName(file);
                FPS4Base.Node node  = fps.Base.Nodes.FirstOrDefault(n => n.Filename == fname);

                Stream data = new FileStream(file, FileMode.Open, FileAccess.Read);
                cache.AddStream(data);

                if (node == null)
                {
                    continue;

                    /* TODO: Only add when we want to
                     * node = new FPS4Base.Node(0, (uint)data.Length, (uint)data.Length, fname, 0, 0, data);
                     * fps.Base.Nodes.Insert((int)fps.Base.Files - 1, node);
                     * fps.Base.Files++;
                     */
                }
                else
                {
                    node.Data = data;
                }
            }

            fps.Base.Reorder();

            Stream ostream = new FileStream(filename + ".new", FileMode.Create, FileAccess.Write);

            fps.Base.Save(ostream);
            ostream.Close();

            stream.Close();

            cache.Dispose();
        }
Example #5
0
        private static void OperationPng2Tex()
        {
            string filename = ConsolePath("Full path to tex or txm/txv or png file..?");

            if (filename.IsEmpty())
            {
                return;
            }

            if (Path.GetExtension(filename).ToLower() == ".txm" || Path.GetExtension(filename).ToLower() == ".txv")
            {
                filename = filename.Substring(0, filename.Length - 4);
            }
            else if (Path.GetExtension(filename).ToLower() != ".tex")
            {
                filename = Path.GetDirectoryName(filename);
                if (filename.EndsWith(".ext"))
                {
                    filename = filename.Substring(0, filename.Length - 4);
                }
            }

            DelayedStreamCache streams = new DelayedStreamCache();
            Txm    tex = OpenTex(filename, streams);
            Stream txmstream;
            Stream txvstream;

            if (File.Exists(filename))
            {
                txmstream = new TemporaryStream();
                txvstream = new TemporaryStream();
            }
            else
            {
                txmstream = new FileStream(filename + ".txm.new", FileMode.Create);
                txvstream = new FileStream(filename + ".txv.new", FileMode.Create);
            }

            streams.AddStream(txmstream);
            streams.AddStream(txvstream);

            string[] files = Directory.GetFiles(filename + ".ext");
            files = files.OrderBy(f => f).ToArray();             // Want to make sure the .dat files come before the pngs (hacky, but meh).
            foreach (string file in files)
            {
                string name      = Path.GetFileName(file);
                string basename  = Path.GetFileNameWithoutExtension(name);
                string extension = Path.GetExtension(name);

                Txm.Image image = tex.Images.FirstOrDefault(i => i.Name == basename);
                if (image == null)
                {
                    if (extension != ".dat" && extension != ".png")
                    {
                        continue;
                    }
                    image                 = new Txm.Image();
                    image.Name            = basename;
                    image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>();
                    image.SecondaryData   = new MemoryStream();
                    image.Unknown1        = 1;
                    image.Unknown2        = 2 << 4;
                    image.Unknown3        = 1;
                    tex.Images.Add(image);
                }

                Stream stream = new FileStream(file, FileMode.Open);
                if (extension == ".dat")
                {
                    image.SecondaryData = new MemoryStream((int)stream.Length);
                    Util.StreamCopy(image.SecondaryData, stream);
                }
                else if (extension == ".png")
                {
                    Bitmap bitmap = new Bitmap(stream);
                    stream.Close();
                    stream = new MemoryStream();
                    if (image.SecondaryData is Substream || image.SecondaryData == null)
                    {
                        image.SecondaryData = new MemoryStream();
                    }
                    image.SecondaryData.Position = 0;
                    try {
                        image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4);
                    } catch (NotImplementedException ex) {
                        if (image.PrimaryEncoding.ID == 0xAAE4)
                        {
                            image.PrimaryEncoding = new ARGB();
                            image.Unknown1        = 5;
                            image.Unknown2        = 0xa5;
                            image.Unknown3        = 4;
                        }
                        else
                        {
                            image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>();
                            image.Unknown1        = 1;
                            image.Unknown2        = 2 << 4;
                            image.Unknown3        = 1;
                        }

                        try {
                            image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4);
                        } catch {
                            throw ex;
                        }
                    }
                    image.Width       = (uint)bitmap.Width;
                    image.Height      = (uint)bitmap.Height;
                    image.PrimaryData = stream;
                }

                streams.AddStream(stream);
            }

            tex.Save(txmstream, txvstream);

            if (File.Exists(filename))
            {
                Stream texstream = new FileStream(filename + ".new", FileMode.Create);
                streams.AddStream(texstream);
                FPS4Base fps = new FPS4Base();
                fps.DataOffset = 0x60;
                fps.BlockSize  = 0x0C;
                fps.Files      = 3;
                fps.Flags      = FPS4Base.NodeFlags.SectionSize | FPS4Base.NodeFlags.Filesize | FPS4Base.NodeFlags.Offset;
                fps.Type       = new byte[] { 0x74, 0x78, 0x6D, 0x76 };           // "txmv"
                fps.TypeOffset = 0x40;
                uint txmlen = (uint)Util.RoundUp(txmstream.Length, 0x20);
                uint txvlen = (uint)Util.RoundUp(txvstream.Length, 0x20);
                fps.Nodes.Add(new FPS4Base.Node(0x60, txmlen, (uint)txmstream.Length, "", 0, 0, txmstream));
                fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen, txvlen, (uint)txvstream.Length, "", 0, 0, txvstream));
                fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen + txvlen, 0, 0, "", 0, 0, null));
                fps.Save(texstream);
            }

            streams.Dispose();
        }
Example #6
0
        static void Main(string[] args)
        {
            string dir = string.Empty;

            if (args.Length == 2)
            {
                dir = args[1];
            }
            else if (args.Length == 1)
            {
                dir = args[0] + ".ext";
            }
            else
            {
                Console.WriteLine("Usage: wiidiscextractor /path/to/disc.iso /extract/path");
                return;
            }

            Directory.CreateDirectory(dir);

            try {
                if (!Directory.Exists(args[0]))
                {
                    throw new FormatException();
                }
                DelayedStreamCache cache = new DelayedStreamCache();
                DirectoryNode      dirn  = DirectoryNode.FromPath(args[0], cache, FileAccess.Read, FileShare.Read);
                DirectoryNode      gen   = dirn.Navigate("gen", false, true) as DirectoryNode;
                if (gen == null)                 // Just in case we're given the "wrong" directory that directly contains the ark
                {
                    gen = dirn;
                }

                List <Pair <int, Stream> > arkfiles = new List <Pair <int, Stream> >();
                Stream hdrfile = null;
                foreach (FileNode file in gen.Files)
                {
                    if (file.Name.ToLower().EndsWith(".hdr"))
                    {
                        hdrfile = file.Data;
                    }
                    else if (file.Name.ToLower().EndsWith(".ark"))
                    {
                        Match match = Regex.Match(file.Name.ToLower(), @"_(\d+).ark");
                        if (match.Success)
                        {
                            arkfiles.Add(new Pair <int, Stream>(int.Parse(match.Groups[1].Value), file.Data));
                        }
                        else
                        {
                            arkfiles.Add(new Pair <int, Stream>(0, file.Data));
                        }
                    }
                }

                // FreQuency/Amplitude where the header is the ark
                if (hdrfile == null)
                {
                    if (arkfiles.Count == 1)
                    {
                        hdrfile = arkfiles[0].Value;
                        arkfiles.Clear();
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }

                Ark ark = new Ark(new EndianReader(hdrfile, Endianness.LittleEndian), arkfiles.OrderBy(f => f.Key).Select(f => f.Value).ToArray());
                ark.Root.Extract(dir);
                cache.Dispose();
            } catch (FormatException) {
                Stream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
                try {
                    Iso9660 iso = new Iso9660(stream);
                    iso.Root.Extract(dir);
                } catch (Exception) {
                    try {
                        stream.Position = 0;
                        Disc disc = new Disc(stream);

                        File.WriteAllText(Path.Combine(dir, "title"), disc.Title);

                        foreach (var partition in disc.Partitions)
                        {
                            string path = Path.Combine(dir, "partition" + disc.Partitions.IndexOf(partition).ToString());
                            Directory.CreateDirectory(path);

                            partition.Root.Root.Extract(Path.Combine(path, "data"));

                            FileStream file = new FileStream(Path.Combine(path, "partition.tik"), FileMode.Create, FileAccess.Write);
                            partition.Ticket.Save(file);
                            file.Close();

                            file = new FileStream(Path.Combine(path, "partition.tmd"), FileMode.Create, FileAccess.Write);
                            partition.TMD.Save(file);
                            file.Close();

                            file = new FileStream(Path.Combine(path, "partition.certs"), FileMode.Create, FileAccess.Write);
                            file.Write(partition.CertificateChain);
                            file.Close();
                        }
                    } catch {
                        try {
                            stream.Position = 0;
                            DlcBin bin = new DlcBin(stream);
                            U8     u8  = new U8(bin.Data);
                            u8.Root.Extract(dir);
                        } catch {
                            try {
                                stream.Position = 0;
                                U8 u8 = new U8(stream);
                                u8.Root.Extract(dir);
                            } catch {
                                stream.Position = 0;
                                Rarc rarc = new Rarc(stream);
                                rarc.Root.Extract(dir);
                            }
                        }
                    }
                }
                stream.Close();
            }
        }
        public override void SaveSong(PlatformData data, FormatData formatdata, ProgressIndicator progress)
        {
            string path = data.Session["maindirpath"] as string;

            string otitle;
            ushort oindex;

            progress.NewTask(10);

            using (DelayedStreamCache cache = new DelayedStreamCache()) {
                progress.SetNextWeight(6);
                string          audioextension = ".mogg";
                Stream          audio          = null;
                Stream          preview        = null;
                AudioFormat     audioformat    = null;
                IList <IFormat> formats        = formatdata.Formats;
                if (formats.Contains(AudioFormatRB2Mogg.Instance))
                {
                    audio       = AudioFormatRB2Mogg.Instance.GetAudioStream(formatdata);
                    preview     = AudioFormatRB2Mogg.Instance.GetPreviewStream(formatdata);
                    audioformat = AudioFormatRB2Mogg.Instance.DecodeAudioFormat(formatdata);
                }
                else if (formats.Contains(AudioFormatRB2Bink.Instance))
                {
                    audio   = AudioFormatRB2Bink.Instance.GetAudioStream(formatdata);
                    preview = AudioFormatRB2Bink.Instance.GetPreviewStream(formatdata, progress);
                    if (!formatdata.HasStream(preview))
                    {
                        cache.AddStream(preview);
                    }
                    audioformat    = AudioFormatRB2Bink.Instance.DecodeAudioFormat(formatdata);
                    audioextension = ".bik";
                }
                else
                {
                    throw new NotSupportedException();
                }

                progress.Progress(6);

                ChartFormat chartformat = (formatdata.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(formatdata, progress);

                Stream album   = null;
                Stream chart   = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile);
                Stream pan     = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile);
                Stream weights = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile);
                Stream milo    = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile);

                progress.SetNextWeight(2);

                if (chart != null && ChartFormatRB.Instance.NeedsFixing(formatdata))
                {
                    formatdata.CloseStream(chart);
                    chart = null;
                }

                if (chart == null)
                {
                    chart = new TemporaryStream();
                    cache.AddStream(chart);
                    AdjustChart(formatdata.Song, audioformat, chartformat).ToMidi().ToMid().Save(chart);
                    chart.Position = 0;
                }

                if (weights == null)
                {
                    weights = new TemporaryStream();
                    cache.AddStream(weights);
                    CreateWeights(weights, chartformat);
                    weights.Position = 0;
                }

                if (pan == null)
                {
                    pan = new TemporaryStream();
                    cache.AddStream(pan);
                    CreatePan(pan, chartformat);
                    pan.Position = 0;
                }

                if (milo == null)
                {
                    milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.Milo3File);
                    if (milo == null)
                    {
                        milo = new MemoryStream(Properties.Resources.rawksd_milo);
                    }
                    else
                    {
                        Stream milostream = new TemporaryStream();
                        cache.AddStream(milostream);
                        Milo   milofile = new Milo(new EndianReader(milo, Endianness.LittleEndian));
                        FaceFX fx       = new FaceFX(new EndianReader(milofile.Data[0], Endianness.BigEndian));

                        TemporaryStream fxstream = new TemporaryStream();
                        fx.Save(new EndianReader(fxstream, Endianness.LittleEndian));
                        milofile.Data[0]    = fxstream;
                        milofile.Compressed = true;
                        milofile.Save(new EndianReader(milostream, Endianness.LittleEndian));
                        fxstream.Close();
                        formatdata.CloseStream(milo);
                        milo          = milostream;
                        milo.Position = 0;
                    }
                }

                //if (album == null)
                //	album = new MemoryStream(Properties.Resources.rawksd_albumart);

                progress.Progress(2);

                SongData song = new SongData(formatdata.Song);

                SongsDTA dta = GetSongsDTA(song, audioformat);

                if (album == null)
                {
                    dta.AlbumArt = false;
                }
                else
                {
                    dta.AlbumArt = true;
                }

                dta.Song.MidiFile = "dlc/content/songs/" + song.ID + "/" + song.ID + ".mid";

                DTB.NodeTree dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song));

                MemoryStream songsdta = new MemoryStream();
                cache.AddStream(songsdta);
                dtb.SaveDTA(songsdta);
                songsdta.Position = 0;

                U8            appdta = new U8();
                DirectoryNode dir    = new DirectoryNode("content");
                appdta.Root.AddChild(dir);
                DirectoryNode songsdir = new DirectoryNode("songs");
                dir.AddChild(songsdir);
                DirectoryNode songdir = new DirectoryNode(song.ID);
                songsdir.AddChild(songdir);
                songdir.AddChild(new FileNode(song.ID + "_prev.mogg", preview));
                songdir.AddChild(new FileNode("songs.dta", songsdta));
                DirectoryNode gendir;
                if (dta.AlbumArt.Value && album != null)
                {
                    gendir = new DirectoryNode("gen");
                    songdir.AddChild(gendir);
                    gendir.AddChild(new FileNode(song.ID + "_nomip_keep.bmp_wii", album));
                }

                U8 appsong = new U8();
                dir = new DirectoryNode("content");
                appsong.Root.AddChild(dir);
                songsdir = new DirectoryNode("songs");
                dir.AddChild(songsdir);
                songdir = new DirectoryNode(song.ID);
                songsdir.AddChild(songdir);
                songdir.AddChild(new FileNode(song.ID + audioextension, audio));
                songdir.AddChild(new FileNode(song.ID + ".mid", chart));
                songdir.AddChild(new FileNode(song.ID + ".pan", pan));
                gendir = new DirectoryNode("gen");
                songdir.AddChild(gendir);
                gendir.AddChild(new FileNode(song.ID + ".milo_wii", milo));
                gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights));

                Stream memoryDta = new TemporaryStream();
                cache.AddStream(memoryDta);
                appdta.Save(memoryDta);

                Stream memorySong = new TemporaryStream();
                cache.AddStream(memorySong);
                appsong.Save(memorySong);

                formatdata.CloseStream(audio);
                formatdata.CloseStream(preview);
                formatdata.CloseStream(chart);
                formatdata.CloseStream(album);
                formatdata.CloseStream(pan);
                formatdata.CloseStream(weights);
                formatdata.CloseStream(milo);

                FindUnusedContent(data, formatdata.Song, out otitle, out oindex);
                TMD tmd = GenerateDummyTMD(otitle);

                dta.Song.Name = "dlc/" + otitle + "/" + Util.Pad(oindex.ToString(), 3) + "/content/songs/" + song.ID + "/" + song.ID;
                dtb           = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song));
                HarmonixMetadata.SetSongsDTA(song, dtb);

                string dirpath = Path.Combine(Path.Combine(path, "rawk"), "rb2");
                if (!Directory.Exists(Path.Combine(dirpath, "customs")))
                {
                    Directory.CreateDirectory(Path.Combine(dirpath, "customs"));
                }
                Directory.CreateDirectory(Path.Combine(Path.Combine(dirpath, "customs"), song.ID));
                FileStream savestream = new FileStream(Path.Combine(Path.Combine(Path.Combine(dirpath, "customs"), song.ID), "data"), FileMode.Create);
                dtb.Save(new EndianReader(savestream, Endianness.LittleEndian));
                savestream.Close();

                TmdContent contentDta = new TmdContent();
                contentDta.ContentID = oindex;
                contentDta.Index     = oindex;
                contentDta.Type      = 0x4001;

                TmdContent contentSong = new TmdContent();
                contentSong.ContentID = oindex + 1U;
                contentSong.Index     = (ushort)(oindex + 1);
                contentSong.Type      = 0x4001;

                memoryDta.Position = 0;
                contentDta.Hash    = Util.SHA1Hash(memoryDta);
                contentDta.Size    = memoryDta.Length;

                memorySong.Position = 0;
                contentSong.Hash    = Util.SHA1Hash(memorySong);
                contentSong.Size    = memorySong.Length;

                for (int i = 1; i <= oindex + 1; i++)
                {
                    if (i == oindex)
                    {
                        tmd.Contents.Add(contentDta);
                    }
                    else if (i == oindex + 1)
                    {
                        tmd.Contents.Add(contentSong);
                    }
                    else
                    {
                        tmd.Contents.Add(new TmdContent()
                        {
                            Index = (ushort)i, ContentID = (uint)i, Size = 1, Type = 0x4001
                        });
                    }
                }

                tmd.Fakesign();

                uint consoleid = GetConsoleID(path);

                progress.Progress();

                dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), "sZAE");
                TemporaryStream binstream;
                DlcBin          bin;
                if (consoleid != 0 && !File.Exists(Path.Combine(dirpath, "000.bin")))
                {
                    Directory.CreateDirectory(dirpath);
                    binstream = new TemporaryStream();
                    binstream.Write(Properties.Resources.rawksd_000bin, 0, Properties.Resources.rawksd_000bin.Length);
                    binstream.Position = 8;
                    new EndianReader(binstream, Endianness.BigEndian).Write(consoleid);
                    binstream.ClosePersist();
                    File.Move(binstream.Name, Path.Combine(dirpath, "000.bin"));
                    binstream.Close();
                }

                dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), otitle);
                if (!Directory.Exists(dirpath))
                {
                    Directory.CreateDirectory(dirpath);
                }

                binstream        = new TemporaryStream();
                bin              = new DlcBin();
                bin.Bk.ConsoleID = consoleid;
                bin.TMD          = tmd;
                bin.Content      = tmd.Contents[oindex];
                bin.Data         = memoryDta;
                bin.Generate();
                bin.Bk.ContentSize = bin.Bk.TotalSize = 0;
                bin.Bk.TitleID     = 0x00010000535A4145UL;
                bin.Save(binstream);
                binstream.ClosePersist();
                string dtabinpath = Path.Combine(dirpath, Util.Pad(oindex.ToString(), 3) + ".bin");
                Util.Delete(dtabinpath);
                File.Move(binstream.Name, dtabinpath);
                binstream.Close();

                binstream        = new TemporaryStream();
                bin              = new DlcBin();
                bin.Bk.ConsoleID = consoleid;
                bin.TMD          = tmd;
                bin.Content      = tmd.Contents[oindex + 1];
                bin.Data         = memorySong;
                bin.Generate();
                bin.Bk.ContentSize = bin.Bk.TotalSize = 0;
                bin.Bk.TitleID     = 0x00010000535A4145UL;
                bin.Save(binstream);
                binstream.ClosePersist();
                string songbinpath = Path.Combine(dirpath, Util.Pad((oindex + 1).ToString(), 3) + ".bin");
                Util.Delete(songbinpath);
                File.Move(binstream.Name, songbinpath);
                binstream.Close();

                data.Mutex.WaitOne();
                string mainbinpath = Path.Combine(dirpath, "000.bin");
                if (!File.Exists(mainbinpath))
                {
                    binstream        = new TemporaryStream();
                    bin              = new DlcBin();
                    bin.Bk.ConsoleID = consoleid;
                    bin.TMD          = tmd;
                    bin.Content      = tmd.Contents[0];
                    bin.Data         = new MemoryStream(Properties.Resources.rawksd_savebanner, false);
                    bin.Generate();
                    bin.Bk.TitleID = 0x00010000535A4145UL;
                    bin.Save(binstream);
                    binstream.ClosePersist();
                    File.Move(binstream.Name, mainbinpath);
                    binstream.Close();
                }

                AddSongFromBins(data, song, dtabinpath, songbinpath, progress, true);

                SaveDTBCache(data);

                data.Mutex.ReleaseMutex();

                cache.Dispose();

                progress.Progress();
            }

            progress.EndTask();
        }