using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Windows.Forms;

/*
    Changes for ModMii by blackb0x
	------------------------------
	- Downgraded to .NET 4.5 so that Windows 8, 8.1, 10 and 11 are supported w/o .NET updates
	- Allow any .app files to be processed (ModMii makes it safe)
	- Removed the option to download vWii base .app files (they're broken?)
	- Don't apply "WT" .app signatures
	- Use Wii U NUS because rc24.xyz doesn't work
	- Cleaned up the project a little and made the executable file smaller
	------------------------------
*/

namespace ThemeWii
{
    class Theme
    {
        const string version = "2.0";
        private string allUrls = string.Empty;
        string appOut = string.Empty;
        string mymOut = string.Empty;
        string openedMym = string.Empty;
        static string tmpDir = string.Empty;
        //static string OutputFilepath = string.Empty;
        private static bool vWii = false;
        private const string vWII_titleID = "0000000700000002";
        private const string titleID = "0000000100000002";
        private static string[,] contInfo;
        private static string[] allowedversions = { "00000070", "00000072", "00000075", "00000078", "0000007b", "0000007e",
                "00000081", "00000084", "00000087", "0000008a", "0000008d", "00000094", "00000097", "0000009a", "0000009d" };
                //"0000001f", "0000001c", "00000022" }; // Drop broken vWii base .app files for XFlak
        private static bool approved_app_file = false;
        private static string user_appFile = null;
        private static string user_mymFile = null;
        private static string user_saveFile = null;
        private static string titleVersion;
        private static string title_Version;
        private static string All_nus_Urls(int pos)
        {
            string outputstr;
            switch (pos)
            {
                case 0:
                    outputstr = "http://ccs.cdn.sho.rc24.xyz/ccs/download"; // Nus rc24
                    break;
                case 1:
                    outputstr = "http://ccs.cdn.wup.shop.nintendo.net/ccs/download/"; // Nus Wii U
                    break;
                case 2:
                    outputstr = "http://nus.cdn.shop.wii.com/ccs/download"; // Nus Wii
                    break;
                case 3:
                    outputstr = "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download";
                    break;
                default:
                    outputstr = "http://ccs.cdn.sho.rc24.xyz/ccs/download";
                    break;
            }
            return outputstr;
        }
        private static void PrintTitle()
        {
            Console.WriteLine("  --------------------------------------------------\n");
            Console.WriteLine("  ThemeWii Command-Line {0} by Scooby74029\n", version);
            Console.WriteLine("  --------------------------------------------------\n");
            Console.WriteLine("  This program will convert .mym files to .csm files . \n");
            return;
        }
        private static void Print_App_List()
        {
            Console.WriteLine("  version 4.0                                   version 4.1");
            Console.WriteLine("  70 => 00000070.app from Region J (v416)       78 => 00000078.app from Region J (v448)");
            Console.WriteLine("  72 => 00000072.app from Region U (v417)       7b => 0000007b.app from Region U (v449)");
            Console.WriteLine("  75 => 00000075.app from Region E (v418)       7e => 0000007e.app from Region E (v450)");
            Console.WriteLine("        Korean Region Unavailable               81 => 00000081.app from Region K (v454)");
            Console.WriteLine("");
            Console.WriteLine("  version 4.2                                   version 4.3");
            Console.WriteLine("  84 => 00000084.app from Region J (v480)       94 => 00000094.app from Region J (v512)");
            Console.WriteLine("  87 => 00000087.app from Region U (v481)       97 => 00000097.app from Region U (v513)");
            Console.WriteLine("  8a => 0000008a.app from Region E (v482)       9a => 0000009a.app from Region E (v514)");
            Console.WriteLine("  8d => 0000008d.app from Region K (v486)       9d => 0000009d.app from Region K (v518)");
            Console.WriteLine("");
/*
            Console.WriteLine("  version vWii");
            Console.WriteLine("  1c => 0000001c.app from Region J (v608)");
            Console.WriteLine("  1f => 0000001f.app from Region U (v609)");
            Console.WriteLine("  22 => 00000022.app from Region E (v610)");
            Console.WriteLine("        Korean Region Unavailable        ");
            Console.WriteLine("");
*/
            return;
        }
        private static void PrintInstructions()
        {
            Console.WriteLine("  Usage: themewii [2/4/5] --> Single Argument .");
            Console.WriteLine("");
            Console.WriteLine("  Usage: themewii [1] [2] [3] --> Three Arguments .");
            Console.WriteLine("");
            Console.WriteLine("  [1] --> [darkwii.mym] Name of .mym file . (ex: darkwii.mym)");
            Console.WriteLine("");
            Console.WriteLine("  [2] --> [xx or xxxxxxxx] This can be any file from appslist . (ex: 97 or 00000097");
            Console.WriteLine("");
            Console.WriteLine("  [3] --> [darkwii.csm] Name of the saved file . (ex: darkwii_4.1U_spin.csm/.app");
            Console.WriteLine("");
            Console.WriteLine("  [4] --> [list] List of .app files .");
            Console.WriteLine("");
            Console.WriteLine("  [5] --> [help] Prints instructions .");
            Console.WriteLine("");
        }
        static Image ResizeImage(Image img, int x, int y)
        {
            Image newimage = new Bitmap(x, y);
            using (Graphics gfx = Graphics.FromImage(newimage))
            {
                gfx.DrawImage(img, 0, 0, x, y);
            }
            return newimage;
        }
        static void DeASH(iniEntry mymC, string appOut)
        {
            ProcessStartInfo pInfo = new ProcessStartInfo(Application.StartupPath + "\\ASH.exe", string.Format("\"{0}\"", appOut + mymC.file));
            pInfo.UseShellExecute = false;
            // pInfo.RedirectStandardOutput = true;
            pInfo.CreateNoWindow = true;

            Process p = Process.Start(pInfo);
            p.WaitForExit();

            //ErrorBox(p.StandardOutput.ReadToEnd() + "\n\n" + mymC.file);
        }
        static void CreateCsm(string savePath, string appPath, string mymPath)
        {
            Console.Write("  Unpacking base app ... \n");

            tmpDir = Application.StartupPath + "\\tmp\\";//Path.GetTempPath() + Guid.NewGuid().ToString() + "\\";
            string appOut = tmpDir + "appOut\\";
            string mymOut = tmpDir + "mymOut\\";
            List<iniEntry> editedContainers = new List<iniEntry>();
            Directory.CreateDirectory(tmpDir);
            Directory.CreateDirectory(appOut);
            Directory.CreateDirectory(mymOut);
            // int counter = 1;

            //Unpack .app
            try
            {
                Wii.U8.UnpackU8(File.ReadAllBytes(appPath), appOut);
            }
            catch (Exception ex) { Console.Write(ex.Message); return; }

            //Unpack .mym
            try
            {
                System.IO.Compression.ZipFile.ExtractToDirectory(mymPath, mymOut);
            }
            catch (Exception ex) { Console.Write(ex.Message); return; }

            //Parse ini
            if (!File.Exists(mymOut + "mym.ini")) { Console.Write("  mym.ini wasn't found!"); return; }
            mymini ini = mymini.LoadIni(mymOut + "mym.ini");

            Console.Write("  Parsing mym.ini ... \n");

            foreach (iniEntry tempEntry in ini.Entries)
            {
                if (tempEntry.entryType == iniEntry.EntryType.Container)
                {
                    if (!File.Exists(appOut + tempEntry.file))
                        continue;

                    bool extracted = false;

                    while (!extracted)
                    {
                        byte[] fourBytes = Wii.Tools.LoadFileToByteArray(appOut + tempEntry.file, 0, 4);

                        if (fourBytes[0] == 'A' && fourBytes[1] == 'S' &&
                                fourBytes[2] == 'H' && fourBytes[3] == '0') //ASH0
                        {
                            try
                            {
                                DeASH(tempEntry, appOut);

                                File.Delete(appOut + tempEntry.file);
                                FileInfo fi = new FileInfo(appOut + tempEntry.file + ".arc");
                                fi.MoveTo(appOut + tempEntry.file);
                            }
                            catch
                            {
                                //        Console.Write("Entry: " + tempEntry.entry + "\n\nASH.exe returned an error!\nYou may try to decompress the ASH files manually...");
                                return;
                            }
                        }
                        else if (fourBytes[0] == 'L' && fourBytes[1] == 'Z' &&
                                fourBytes[2] == '7' && fourBytes[3] == '7') //Lz77
                        {
                            try
                            {
                                byte[] decompressedFile = Wii.Lz77.Decompress(File.ReadAllBytes(appOut + tempEntry.file), 0);

                                File.Delete(appOut + tempEntry.file);
                                File.WriteAllBytes(appOut + tempEntry.file, decompressedFile);
                            }
                            catch (Exception ex)
                            {
                                Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);
                                return;
                            }
                        }
                        else if (fourBytes[0] == 'Y' && fourBytes[1] == 'a' &&
                                fourBytes[2] == 'z' && fourBytes[3] == '0') //Yaz0
                        {
                            //Nothing to do about yet...
                            break;
                        }
                        else if (fourBytes[0] == 0x55 && fourBytes[1] == 0xaa &&
                                fourBytes[2] == 0x38 && fourBytes[3] == 0x2d) //U8
                        {
                            try
                            {
                                Wii.U8.UnpackU8(appOut + tempEntry.file, appOut + tempEntry.file.Replace('.', '_') + "_out");
                                File.Delete(appOut + tempEntry.file);
                                extracted = true;
                            }
                            catch (Exception ex)
                            {
                                Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);
                                return;
                            }
                        }
                        else break;
                    }

                    editedContainers.Add(tempEntry);
                }
                else if (tempEntry.entryType == iniEntry.EntryType.CustomImage)
                {
                    try
                    {
                        if (File.Exists(appOut + tempEntry.file))
                        {
                            OpenFileDialog ofd = new OpenFileDialog();
                            ofd.Title = tempEntry.name;
                            ofd.Filter = "PNG|*.png";

                            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                            {
                                Image img = Image.FromFile(ofd.FileName);
                                img = ResizeImage(img, tempEntry.width, tempEntry.height);

                                if (File.Exists(appOut + tempEntry.file)) File.Delete(appOut + tempEntry.file);
                                Wii.TPL.ConvertToTPL(img, appOut + tempEntry.file, (int)tempEntry.format);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);
                        return;
                    }
                }
                else if (tempEntry.entryType == iniEntry.EntryType.StaticImage)
                {
                    try
                    {
                        if (File.Exists(mymOut + tempEntry.source))
                        {
                            Image img = Image.FromFile(mymOut + tempEntry.source);
                            img = ResizeImage(img, tempEntry.width, tempEntry.height);

                            if (File.Exists(appOut + tempEntry.file)) File.Delete(appOut + tempEntry.file);
                            Wii.TPL.ConvertToTPL(img, appOut + tempEntry.file, (int)tempEntry.format);
                        }
                        else
                            continue;
                    }
                    catch (Exception ex)
                    {
                        Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);

                    }
                }
                else if (tempEntry.entryType == iniEntry.EntryType.CustomData)
                {
                    try
                    {
                        if (File.Exists(appOut + tempEntry.file))
                        {
                            OpenFileDialog ofd = new OpenFileDialog();
                            ofd.FileName = tempEntry.name;

                            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                            {
                                File.Copy(ofd.FileName, appOut + tempEntry.file, true);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);
                        return;
                    }
                }
                else if (tempEntry.entryType == iniEntry.EntryType.StaticData)
                {
                    try
                    {
                        if (File.Exists(mymOut + tempEntry.source))
                        {
                            File.Copy(mymOut + tempEntry.source, appOut + tempEntry.file, true);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Write("  Entry: " + tempEntry.entry + "\n\n" + ex.Message);
                    }
                }
            }

            //Repack Containers
            foreach (iniEntry tempEntry in editedContainers)
            {

                byte[] u8Container = Wii.U8.PackU8(appOut + tempEntry.file.Replace('.', '_') + "_out");
                Wii.Lz77.Compress(u8Container, appOut + tempEntry.file);
                Directory.Delete(appOut + tempEntry.file.Replace('.', '_') + "_out", true);
            }

            //Repack app
            //savePath = OutputFilepath;
            Wii.U8.PackU8(appOut, savePath);

        }
        static string Convertappfile(string input)
        {
            string retstr;
            retstr = "000000" + input;

            return retstr;
        }
        private static string Get_title_Version(string input_Version)
        {
            switch (input_Version.ToLower())
            {
                case "0000001c":
                    titleVersion = "608"; // vwii j
                    break;
                case "0000001f":
                    titleVersion = "609"; // vwii u
                    break;
                case "00000022":
                    titleVersion = "610"; // vwii e
                    break;
                case "00000070":
                    titleVersion = "416"; // 4.0 j
                    break;
                case "00000072":
                    titleVersion = "417"; // 4.0 u
                    break;
                case "00000075":
                    titleVersion = "418"; // 4.0 e
                    break;
                case "00000078":
                    titleVersion = "448"; // 4.1 j
                    break;
                case "0000007b":
                    titleVersion = "449"; // 4.1 u
                    break;
                case "0000007e":
                    titleVersion = "450"; // 4.1 e
                    break;
                case "00000081":
                    titleVersion = "454"; // 4.1 k
                    break;
                case "00000084":
                    titleVersion = "480"; // 4.2 j
                    break;
                case "00000087":
                    titleVersion = "481"; // 4.2 u
                    break;
                case "0000008a":
                    titleVersion = "482"; // 4.2 e
                    break;
                case "0000008d":
                    titleVersion = "486"; // 4.2 k
                    break;
                case "00000094":
                    titleVersion = "512"; // 4.3 j
                    break;
                case "00000097":
                    titleVersion = "513"; // 4.3 u
                    break;
                case "0000009a":
                    titleVersion = "514"; // 4.3 E
                    break;
                case "0000009d":
                    titleVersion = "518"; // 4.3 k
                    break;
            }
            return titleVersion;
        }
        private static bool Download_appfile(string input, bool vWii)
        {
            string tempDir = Application.StartupPath + "\\tmp\\";//Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + "\\";
            string fileName = input;
            //string titleVersion = string.Empty;
            string current_titleID = string.Empty;
            int url_Pos = 1;
            byte[] current_CommonKey;
            /*
            switch (input.ToLower())
            {
                case "0000001c":
                    titleVersion = "608"; // vwii j
                    break;
                case "0000001f":
                    titleVersion = "609"; // vwii u
                    break;
                case "00000022":
                    titleVersion = "610"; // vwii e
                    break;
                case "00000070":
                    titleVersion = "416"; // 4.0 j
                    break;
                case "00000072":
                    titleVersion = "417"; // 4.0 u
                    break;
                case "00000075":
                    titleVersion = "418"; // 4.0 e
                    break;
                case "00000078":
                    titleVersion = "448"; // 4.1 j
                    break;
                case "0000007b":
                    titleVersion = "449"; // 4.1 u
                    break;
                case "0000007e":
                    titleVersion = "450"; // 4.1 e
                    break;
                case "00000081":
                    titleVersion = "454"; // 4.1 k
                    break;
                case "00000084":
                    titleVersion = "480"; // 4.2 j
                    break;
                case "00000087":
                    titleVersion = "481"; // 4.2 u
                    break;
                case "0000008a":
                    titleVersion = "482"; // 4.2 e
                    break;
                case "0000008d":
                    titleVersion = "486"; // 4.2 k
                    break;
                case "00000094":
                    titleVersion = "512"; // 4.3 j
                    break;
                case "00000097":
                    titleVersion = "513"; // 4.3 u
                    break;
                case "0000009a":
                    titleVersion = "514"; // 4.3 E
                    break;
                case "0000009d":
                    titleVersion = "518"; // 4.3 k
                    break;
            }
            */
            titleVersion = Get_title_Version(input.ToLower());
            //Grab cetk + appfile
            Directory.CreateDirectory(tempDir);
            WebClient wcDownload = new WebClient();
            Console.WriteLine(" ");
            Console.Write("  Grabbing Ticket ");
            if (vWii) current_titleID = vWII_titleID;
            else current_titleID = titleID;
            try { wcDownload.DownloadFile(string.Format("{0}/{1}/{2}", All_nus_Urls(url_Pos), current_titleID, "cetk"), tempDir + "cetk"); }
            catch (Exception et)
            {
                Console.WriteLine(" ");
                Console.Write("  Grabbing Ticket Failed . all_nus_Urls(3)\n" + et.Message);
                Directory.Delete(tempDir, true);
                return false;
            }
            Console.Write("Complete . \n");
            Console.WriteLine(" ");
            Console.Write("  Grabbing Tmd v{0} ", titleVersion);
            try { wcDownload.DownloadFile(string.Format("{0}/{1}/{2}{3}", All_nus_Urls(url_Pos), current_titleID, "tmd.", titleVersion), tempDir + "tmd"); }
            catch (Exception es)
            {
                Console.WriteLine(" ");
                Console.Write("  Grabbing Tmd Failed... from RiiUrl\n" + es.Message);
                Directory.Delete(tempDir, true);
                return false;
            }
            Console.Write("Complete ! \n");
            contInfo = GetContentInfo(File.ReadAllBytes(tempDir + "tmd"));
            int contentIndex = -1;
            for (int i = 0; i < contInfo.GetLength(0); i++)
                if (contInfo[i, 0] == fileName) { contentIndex = i; break; }
            Console.WriteLine(" ");
            Console.WriteLine("  Content - ({0} bytes)", contInfo[contentIndex, 3]);
            Console.Write("  Downloading Content " + fileName + " ");
            try { wcDownload.DownloadFile(string.Format("{0}/{1}/{2}", All_nus_Urls(url_Pos), current_titleID, fileName), tempDir + fileName); }
            catch (Exception ef)
            {
                Console.Write("Failed...\n" + ef.Message);
                Directory.Delete(tempDir, true);
                return false;
            }
            Console.Write("Complete ! \n");
            byte[] vWii_common = new byte[] { 0x30, 0xBF, 0xC7, 0x6E, 0x7C, 0x19, 0xAF, 0xBB, 0x23, 0x16, 0x33, 0x30, 0xCE, 0xD7, 0xC2, 0x8D };
            byte[] commonkey = new byte[] { 0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7 };
            byte[] encTitleKey;
            byte[] decTitleKey;
            if (vWii) current_CommonKey = vWii_common;
            else current_CommonKey = commonkey;
            encTitleKey = GetPartOfByteArray(File.ReadAllBytes(tempDir + "cetk"), 447, 16);
            decTitleKey = GetTitleKey(encTitleKey, HexStringToByteArray(titleID), current_CommonKey);
            byte[] tmdHash = HexStringToByteArray(contInfo[contentIndex, 4]);
            //Decrypt appfile
            Console.Write("  Decrypting Content ");
            byte[] decContent = DecryptContent(
                File.ReadAllBytes(tempDir + fileName), File.ReadAllBytes(tempDir + "tmd"), contentIndex, decTitleKey);
            Console.Write("Complete ! \n");
            //Check SHA1
            Console.Write("  Hash Check: ");
            if (HashCheck(decContent, tmdHash)) { Console.Write(" OK !\n"); }
            else { Console.Write(" Failed !\n"); Directory.Delete(tempDir, true); return false; }
            File.WriteAllBytes(fileName, decContent);
            //Delete Temps
            Directory.Delete(tempDir, true);
            return true;
        }
        private static bool Check_user_appfile(string appfileName)
        {
/*
            int allowed_version_cntr;

            for (allowed_version_cntr = 0; allowed_version_cntr < allowedversions.Length; allowed_version_cntr++)
            {
                if ((appfileName == "0000001f") || (appfileName == "0000001c") || (appfileName == "00000022"))
                    vWii = true;
                else
                    vWii = false;
                if (appfileName == allowedversions[allowed_version_cntr])
                {
                    approved_app_file = true;
                    break;
                }
            }
*/
            // Allow everything for XFlak's ModMii
            approved_app_file = true;
            return approved_app_file;
        }
        private static bool Checklocalfile(string appfileName)
        {
            if (!File.Exists(appfileName)) return false;
            else return true;
        }
        private static void Main(string[] args)
        {
            int themeWii_running = 1;
            bool app_file_Downloaded;

            //Console.Title = "Theme Wii V2"; // Allows ModMii to set any title

            if (!File.Exists("ash.exe"))
            {
                Console.WriteLine("  ASH.exe couldn't be found in the this directory .");
                Console.WriteLine("  This file is needed .");
                Console.WriteLine("  Press any key to exit .");
                Console.ReadKey();
                return;
            }

            while (themeWii_running == 1)
            {
                if (args.Length > 0)
                {
                    if (args[0].ToLower() == "exit") { break; }
                    if (args[0].ToLower() == "help")
                    {
                        PrintTitle();
                        PrintInstructions();
                        args[0] = Console.ReadLine();
                        continue;
                    }
                    if (args[0].ToLower() == "list")
                    {
                        Print_App_List();
                        Console.WriteLine("  Choose App File for the Theme .\n");
                        args[0] = Console.ReadLine();
                        continue;
                    }
                    if (args.Length == 1)
                    {
                        if (args[0].Length == 2) args[0] = Convertappfile(args[0]);
                        approved_app_file = Check_user_appfile(args[0]);
                        if (!approved_app_file)
                        {
                            Console.WriteLine("\n  ERROR: " + args[0] + " is not an allowed .app file .");
                            //Console.WriteLine("  Press any key to Continue .");
                            //Console.ReadKey();
                            //Console.Clear();
                            //PrintTitle();
                            //Print_App_List();
                            //Console.WriteLine("  Choose App File for the Theme .\n");
                            //args[0] = Console.ReadLine();
                            break;
                        }
                        else
                        {
                            app_file_Downloaded = Checklocalfile(args[0]);
                            if (app_file_Downloaded)
                            {
                                int offset_signature = 0;
                                int file_size;
                                long filesize;
                                FileStream app_file = new FileStream(args[0], FileMode.Open);
                                filesize = app_file.Length;
                                file_size = (int)filesize;
                                byte[] singleByte = new byte[filesize];
                                app_file.Read(singleByte, 0, file_size);
                                int[] U_E_offsets_vWii = { 2448, 2456, 2506 };
                                int[] J_offsets_vWii = { 17808, 17816, 17866 };
                                int[] U_offsets_Wii = { 2272, 2288, 2334 };
                                int[] J_offsets_Wii = { 17664, 17680, 17726 };
                                int[] E_offsets_Wii = { 2304, 2320, 2366 };
                                int[] K_offsets_Wii = { 2528, 2536, 2582 };
#pragma warning disable CS0219 // Variable is assigned but its value is never used
                                bool signature_verified = false;
#pragma warning restore CS0219 // Variable is assigned but its value is never used
                                bool appFile_verified = false;
                                int offset_driveletter = 0;
                                int offset_regionstr = 0;
                                int verify_start = 0;
                                int verify_pos1 = 0;
                                int verify_pos2 = 0;
                                int verify_pos3 = 0;

                                switch (args[0])
                                {
                                    case "0000001f": // vwii U v609
                                    case "00000022": // vwii E v610
                                        offset_signature = U_E_offsets_vWii[0];
                                        offset_driveletter = U_E_offsets_vWii[1];
                                        offset_regionstr = U_E_offsets_vWii[2];
                                        verify_start = 68;
                                        if (args[0] == "0000001f")
                                        {
                                            verify_pos1 = 85;
                                            verify_pos2 = 83;
                                            verify_pos3 = 50;
                                        }
                                        else
                                        {
                                            verify_pos1 = 69;
                                            verify_pos2 = 85;
                                            verify_pos3 = 50;
                                        }
                                        break;
                                    case "0000001c": // vwii J v608
                                        offset_signature = J_offsets_vWii[0];
                                        offset_driveletter = J_offsets_vWii[1];
                                        offset_regionstr = J_offsets_vWii[2];
                                        verify_start = 68;
                                        verify_pos1 = 74;
                                        verify_pos2 = 80;
                                        verify_pos3 = 50;
                                        break;
                                    case "00000097": // 4.3 u
                                    case "00000087": // 4.2 u
                                    case "0000007b": // 4.1 u
                                    case "00000072": // 4.0 u
                                        offset_signature = U_offsets_Wii[0];
                                        offset_driveletter = U_offsets_Wii[1];
                                        if (args[0] == "0000007b")
                                            offset_regionstr = U_offsets_Wii[2] + 3;
                                        else
                                            offset_regionstr = U_offsets_Wii[2];
                                        verify_start = 67;
                                        verify_pos1 = 85;
                                        verify_pos2 = 83;
                                        verify_pos3 = 50;
                                        break;
                                    case "0000009a": // 4.3 e
                                    case "0000008a": // 4.2 e
                                    case "0000007e": // 4.1 e
                                    case "00000075": // 4.0 e
                                        offset_signature = E_offsets_Wii[0];
                                        offset_driveletter = E_offsets_Wii[1];
                                        if (args[0] == "0000007e")
                                            offset_regionstr = E_offsets_Wii[2] + 3;
                                        else
                                            offset_regionstr = E_offsets_Wii[2];
                                        verify_start = 67;
                                        verify_pos1 = 69;
                                        verify_pos2 = 85;
                                        verify_pos3 = 50;
                                        break;
                                    case "00000094": // 4.3 j
                                    case "00000084": // 4.2 j
                                    case "00000078": // 4.1 j
                                    case "00000070": // 4.0 j
                                        offset_signature = J_offsets_Wii[0];
                                        offset_driveletter = J_offsets_Wii[1];
                                        if (args[0] == "00000078")
                                            offset_regionstr = J_offsets_Wii[2] + 3;
                                        else
                                            offset_regionstr = J_offsets_Wii[2];
                                        verify_start = 67;
                                        verify_pos1 = 74;
                                        verify_pos2 = 80;
                                        verify_pos3 = 50;
                                        break;
                                    case "0000009d": // 4.3 k
                                    case "0000008d": // 4.2 k
                                    case "00000081": // 4.1 k
                                        offset_signature = K_offsets_Wii[0];
                                        offset_driveletter = K_offsets_Wii[1];
                                        if (args[0] == "00000081")
                                            offset_regionstr = K_offsets_Wii[2] + 3;
                                        else
                                            offset_regionstr = K_offsets_Wii[2];
                                        verify_start = 67;
                                        verify_pos1 = 75;
                                        verify_pos2 = 82;
                                        verify_pos3 = 50;
                                        break;
                                }
                                // verify correct app file for the region is used
                                titleVersion = Get_title_Version(args[0]);
                                Console.Write("  Verifing app file {0} for v{1} ", args[0], titleVersion);
                                if (vWii)
                                {
                                    if (singleByte[offset_driveletter] == verify_start)
                                        if (singleByte[offset_regionstr] == verify_pos1)
                                            if (singleByte[offset_regionstr + 1] == verify_pos2)
                                                if (singleByte[offset_regionstr + 2] == verify_pos3)
                                                    appFile_verified = true;
                                }
                                else
                                {
                                    if (args[0] == "00000070") appFile_verified = true;
                                    else
                                    {
                                        if (singleByte[offset_driveletter] == verify_start)
                                            if (singleByte[offset_regionstr] == verify_pos1)
                                                if (singleByte[offset_regionstr + 1] == verify_pos2)
                                                    if (singleByte[offset_regionstr + 2] == verify_pos3)
                                                        appFile_verified = true;
                                    }
                                }
                                Console.WriteLine("{0}", appFile_verified == true ? "Complete ." : "Failed .");
                                app_file.Close(); // Skip signatures for XFlak
                                Console.Write("  Found .app file " + args[0] + " . Using it .");
/*
                                if (singleByte[offset_signature] == 87)
                                {
                                    if (singleByte[offset_signature + 1] == 84)
                                    {
                                        app_file.Close();
                                        Console.Write("  Found .app file " + args[0] + " . Using it .");
                                        //Console.WriteLine("  Press any key to exit .");
                                        // Console.ReadKey();
                                        // break;
                                    }
                                }
                                else
                                {
                                    Console.Write("  Signing .app file " + args[0] + " ");
                                    FileStream signed_app_file = new FileStream("tmp", FileMode.OpenOrCreate);
                                    for (int i = 0; i < singleByte.Length; i++)
                                    {
                                        if (i == offset_signature)
                                            singleByte[i] = 87; // W
                                        if (i == offset_signature + 1)
                                            singleByte[i] = 84; // T

                                        signed_app_file.Write(singleByte, i, 1);
                                    }
                                    app_file.Close();
                                    signed_app_file.Close();
                                    Console.WriteLine("Complete .");
                                }
                                Console.Write("  Verifing Signature ");
                                // add verify func
                                FileStream verify_tmp = new FileStream("tmp", FileMode.Open);
                                filesize = verify_tmp.Length;
                                file_size = (int)filesize;
                                byte[] single_Byte = new byte[filesize];
                                verify_tmp.Read(single_Byte, 0, file_size);

                                if (single_Byte[offset_signature] == 87)// W
                                    if (single_Byte[offset_signature + 1] == 84)// T
                                    {
                                        signature_verified = true;
                                        verify_tmp.Close();
                                    }
                                verify_tmp.Close();

                                Console.WriteLine("{0}", signature_verified == true ? "Complete ." : "Failed .");
*/
                                File.Delete(args[0]);
                                File.Move("tmp", args[0]);

                                //Console.WriteLine(" Press any key to exit .");

                                //Console.ReadKey();
                                break;
                            }
                            else
                            {
                                app_file_Downloaded = Download_appfile(args[0], vWii);
                                continue;
                            }
                        }
                    }
                    if (args.Length == 3)
                    {
                        if (!File.Exists(args[0]))
                        {
                            Console.WriteLine("  {0} couldn't be found in the this directory .", args[0]);
                            Console.WriteLine("  This file is needed .");
                            //Console.WriteLine("  Press any key to Continue .");
                            // Console.ReadKey();
                            break;
                        }
                        if (args[1].Length == 2) { args[1] = Convertappfile(args[1]); }
                        approved_app_file = Check_user_appfile(args[1]);
                        if (!approved_app_file)
                        {
                            Console.WriteLine("\n  ERROR: " + args[1] + " is not an allowed .app file .");
                            //Console.WriteLine("  Press any key to Continue .");
                            //Console.ReadKey();
                            // Console.Clear();
                            break;
                        }
                        app_file_Downloaded = Checklocalfile(args[1]);
                        if (!app_file_Downloaded)
                        {
                            app_file_Downloaded = Download_appfile(args[1], vWii);
                            continue;
                        }
                        if (args[2] != null)
                        {
                            if (Directory.Exists(Application.StartupPath + "\\tmp"))
                            {
                                Directory.Delete(Application.StartupPath + "\\tmp", true);
                            }
                            CreateCsm(args[2], args[1], args[0]);
                            Directory.Delete(Application.StartupPath + "\\tmp", true);
                            break;
                        }
                    }
                }
                else
                {
                    if (user_appFile == null)
                    {
                        PrintTitle();
                        PrintInstructions();
                        Console.WriteLine("  Press any key to Continue .");
                        Console.ReadKey();
                        Console.Clear();
                        Print_App_List();
                        Console.WriteLine("  Choose App File for the Theme .\n");
                        Console.Write("  ");
                        user_appFile = Console.ReadLine();
                        continue;
                    }
                    if (user_appFile.Length == 2) { user_appFile = Convertappfile(user_appFile); }
                    if (user_appFile.ToLower() == "help")
                    {
                        Console.Clear();
                        PrintTitle();
                        PrintInstructions();
                        user_appFile = Console.ReadLine();
                        continue;
                    }
                    if (user_appFile.ToLower() == "exit") break;
                    if (user_appFile.ToLower() == "list")
                    {
                        Console.Clear();
                        PrintTitle();
                        Print_App_List();
                        Console.WriteLine("  Choose App File for the Theme .\n");
                        user_appFile = Console.ReadLine();
                        continue;
                    }
                    approved_app_file = Check_user_appfile(user_appFile);
                    if (!approved_app_file)
                    {
                        Console.WriteLine("\n  ERROR: " + user_appFile + " is not an allowed .app file .");
                        Console.WriteLine("  Press any key to Continue .");
                        Console.ReadKey();
                        Console.Clear();
                        user_appFile = null;
                        Print_App_List();
                        Console.WriteLine("  Choose App File for the Theme .\n");
                        user_appFile = Console.ReadLine();
                        continue;
                    }
                    app_file_Downloaded = Checklocalfile(user_appFile);
                    if (!app_file_Downloaded)
                    {
#pragma warning disable IDE0059
                        app_file_Downloaded = Download_appfile(user_appFile, vWii);
#pragma warning restore IDE0059
                        continue;
                    }
                    if (approved_app_file)
                    {
                        if (!File.Exists(user_appFile))
                        {
                            Console.WriteLine("  {0} couldn't be found in the this directory .", user_appFile);
                            Console.WriteLine("  This file is needed .");
                            Console.WriteLine("  Press any key to Continue .");
                            Console.ReadKey();
                            continue;
                        }
                        if (File.Exists(user_appFile))
                        {
                            int offset_signature = 0;
                            int file_size;
                            long filesize;
                            FileStream app_file = new FileStream(user_appFile, FileMode.Open);
                            filesize = app_file.Length;
                            file_size = (int)filesize;
                            byte[] singleByte = new byte[filesize];
                            app_file.Read(singleByte, 0, file_size);
                            int[] U_E_offsets_vWii = { 2448, 2456, 2506 };
                            int[] J_offsets_vWii = { 17808, 17816, 17866 };
                            int[] U_offsets_Wii = { 2272, 2288, 2334 };
                            int[] J_offsets_Wii = { 17664, 17680, 17726 };
                            int[] E_offsets_Wii = { 2304, 2320, 2366 };
                            int[] K_offsets_Wii = { 2528, 2536, 2582 };
#pragma warning disable CS0219 // Variable is assigned but its value is never used
                            bool signature_verified = false;
#pragma warning restore CS0219 // Variable is assigned but its value is never used
                            bool appFile_verified = false;
                            int offset_driveletter = 0;
                            int offset_regionstr = 0;
                            int verify_start = 0;
                            int verify_pos1 = 0;
                            int verify_pos2 = 0;
                            int verify_pos3 = 0;

                            switch (user_appFile)
                            {
                                case "0000001f": // vwii U v609
                                case "00000022": // vwii E v610
                                    offset_signature = U_E_offsets_vWii[0];
                                    offset_driveletter = U_E_offsets_vWii[1];
                                    offset_regionstr = U_E_offsets_vWii[2];
                                    verify_start = 68;
                                    if (user_appFile == "0000001f")
                                    {
                                        verify_pos1 = 85;
                                        verify_pos2 = 83;
                                        verify_pos3 = 50;
                                    }
                                    else
                                    {
                                        verify_pos1 = 69;
                                        verify_pos2 = 85;
                                        verify_pos3 = 50;
                                    }
                                    break;
                                case "0000001c": // vwii J v608
                                    offset_signature = J_offsets_vWii[0];
                                    offset_driveletter = J_offsets_vWii[1];
                                    offset_regionstr = J_offsets_vWii[2];
                                    verify_start = 68;
                                    verify_pos1 = 74;
                                    verify_pos2 = 80;
                                    verify_pos3 = 50;
                                    break;
                                case "00000097": // 4.3 u
                                case "00000087": // 4.2 u
                                case "0000007b": // 4.1 u
                                case "00000072": // 4.0 u
                                    offset_signature = U_offsets_Wii[0];
                                    offset_driveletter = U_offsets_Wii[1];
                                    if (user_appFile == "0000007b")
                                        offset_regionstr = U_offsets_Wii[2] + 3;
                                    else
                                        offset_regionstr = U_offsets_Wii[2];
                                    verify_start = 67;
                                    verify_pos1 = 85;
                                    verify_pos2 = 83;
                                    verify_pos3 = 50;
                                    break;
                                case "0000009a": // 4.3 e
                                case "0000008a": // 4.2 e
                                case "0000007e": // 4.1 e
                                case "00000075": // 4.0 e
                                    offset_signature = E_offsets_Wii[0];
                                    offset_driveletter = E_offsets_Wii[1];
                                    if (user_appFile == "0000007e")
                                        offset_regionstr = E_offsets_Wii[2] + 3;
                                    else 
                                        offset_regionstr = E_offsets_Wii[2];
                                    verify_start = 67;
                                    verify_pos1 = 69;
                                    verify_pos2 = 85;
                                    verify_pos3 = 50;
                                    break;
                                case "00000094": // 4.3 j
                                case "00000084": // 4.2 j
                                case "00000078": // 4.1 j
                                case "00000070": // 4.0 j
                                    offset_signature = J_offsets_Wii[0];
                                    offset_driveletter = J_offsets_Wii[1];
                                    if (user_appFile == "00000078")
                                        offset_regionstr = J_offsets_Wii[2] + 3;
                                    else
                                        offset_regionstr = J_offsets_Wii[2];
                                    verify_start = 67;
                                    verify_pos1 = 74;
                                    verify_pos2 = 80;
                                    verify_pos3 = 50;
                                    break;
                                case "0000009d": // 4.3 k
                                case "0000008d": // 4.2 k
                                case "00000081": // 4.1 k
                                    offset_signature = K_offsets_Wii[0];
                                    offset_driveletter = K_offsets_Wii[1];
                                    if (user_appFile == "00000081")
                                        offset_regionstr = K_offsets_Wii[2] + 3;
                                    else
                                        offset_regionstr = K_offsets_Wii[2];
                                    verify_start = 67;
                                    verify_pos1 = 75;
                                    verify_pos2 = 82;
                                    verify_pos3 = 50;
                                    break;
                            }
                            // verify correct app file for the region is used
                            titleVersion = Get_title_Version(user_appFile);
                            Console.Write("  Verifing app file {0} for v{1} ", user_appFile, titleVersion);
                            if (vWii)
                            {
                                if (singleByte[offset_driveletter] == verify_start)
                                    if (singleByte[offset_regionstr] == verify_pos1)
                                        if (singleByte[offset_regionstr + 1] == verify_pos2)
                                            if (singleByte[offset_regionstr + 2] == verify_pos3)
                                                appFile_verified = true;
                            }
                            else
                            {
                                if (user_appFile == "00000070") appFile_verified = true;
                                else
                                {
                                    if (singleByte[offset_driveletter] == verify_start)
                                        if (singleByte[offset_regionstr] == verify_pos1)
                                            if (singleByte[offset_regionstr + 1] == verify_pos2)
                                                if (singleByte[offset_regionstr + 2] == verify_pos3)
                                                    appFile_verified = true;
                                }
                            }
                            Console.WriteLine("{0}", appFile_verified == true ? "Complete ." : "Failed .");
                            app_file.Close(); // Skip signatures for XFlak
                            Console.Write("  Found .app file " + user_appFile + " . Using it .");
/*
                            if (singleByte[offset_signature] == 87)
                            {
                                if (singleByte[offset_signature + 1] == 84)
                                {
                                    app_file.Close();
                                    Console.Write("  Found .app file " + user_appFile + " . Using it .");
                                    
                                }
                            }
                            else
                            {
                                Console.Write("  Signing .app file " + user_appFile + " ");
                                FileStream signed_app_file = new FileStream("tmp", FileMode.OpenOrCreate);
                                for (int i = 0; i < singleByte.Length; i++)
                                {
                                    if (i == offset_signature)
                                        singleByte[i] = 87; // W
                                    if (i == offset_signature + 1)
                                        singleByte[i] = 84; // T

                                    signed_app_file.Write(singleByte, i, 1);
                                }
                                app_file.Close();
                                signed_app_file.Close();
                                Console.WriteLine("Complete .");

                                app_file.Close();
                                Console.Write("  Verifing Signature ");
                                // add verify func
                                FileStream verify_tmp = new FileStream("tmp", FileMode.Open);
                                filesize = verify_tmp.Length;
                                file_size = (int)filesize;
                                byte[] single_Byte = new byte[filesize];
                                verify_tmp.Read(single_Byte, 0, file_size);

                                if (single_Byte[offset_signature] == 87) // W
                                {
                                    if (single_Byte[offset_signature + 1] == 84) // T
                                    {
                                        signature_verified = true;
                                        verify_tmp.Close();
                                    }
                                }
                                verify_tmp.Close();

                                Console.WriteLine("{0}", signature_verified == true ? "Complete ." : "Failed .");

                                File.Delete(user_appFile);
                                File.Move("tmp", user_appFile);
                            }
*/
                            if (user_mymFile == null)
                            {
                                Console.WriteLine("  Type the .mym file name .\n  (ex: batman.mym)");
                                Console.Write("  ");
                                user_mymFile = Console.ReadLine();
                                if (user_mymFile.ToLower() == "exit") break;
                            }
                        }
                    }
                    if (!File.Exists(user_mymFile))
                    {
                        Console.WriteLine("  {0} couldn't be found in the this directory .", user_mymFile);
                        Console.WriteLine("  This file is needed .");
                        Console.WriteLine("  Press any key to Continue .");
                        Console.ReadKey();
                        user_mymFile = null;
                        continue;
                    }
                    if (app_file_Downloaded)
                    {
                        if (user_saveFile == null)
                        {
                            Console.WriteLine("  Type the save file name .\n  (ex: batman.csm/batman.app)");
                            user_saveFile = Console.ReadLine();
                        }
                        //Console.WriteLine("app [{0}] mym[{1}] save[{2}]", user_appFile, user_mymFile, user_saveFile);
                        if (Directory.Exists(Application.StartupPath + "\\tmp"))
                        {
                            Directory.Delete(Application.StartupPath + "\\tmp", true);
                        }
                        CreateCsm(user_saveFile, user_appFile, user_mymFile);
                        Console.WriteLine("  Press any key to exit .");
                        Console.ReadKey();
                        if (Directory.Exists(Application.StartupPath + "\\tmp"))
                        {
                            Directory.Delete(Application.StartupPath + "\\tmp", true);
                        }
                        break;
                    }
                }
            }
            return;
        }
        public static byte[] GetPartOfByteArray(byte[] array, int offset, int length)
        {
            byte[] ret = new byte[length];
            for (int i = 0; i < length; i++)
                ret[i] = array[offset + i];
            // Console.Write("ret = [");
            // for (int x = 0; x < ret.Length; x++)
            // {
            //     Console.Write(" " + ret[x]);
            // }
            // Console.WriteLine(" ]");
            return ret;
        }
        public static byte[] HexStringToByteArray(string hexstring)
        {
            byte[] ba = new byte[hexstring.Length / 2];
            //Console.Write("hexstr = [ ");
            for (int i = 0; i < hexstring.Length / 2; i++)
            {
                ba[i] = byte.Parse(hexstring.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
                //Console.Write(ba[i].ToString("X2") + " ");
            }
            //Console.WriteLine(" ]");
            return ba;
        }
        public static byte[] GetTitleKey(byte[] encryptedkey, byte[] title_id, byte[] common_key)
        {
            Array.Resize(ref title_id, 16);

            RijndaelManaged decrypt = new RijndaelManaged();
            decrypt.Mode = CipherMode.CBC;
            decrypt.Padding = PaddingMode.None;
            decrypt.KeySize = 128;
            decrypt.BlockSize = 128;
            decrypt.Key = common_key;
            decrypt.IV = title_id;

            ICryptoTransform cryptor = decrypt.CreateDecryptor();

            MemoryStream memory = new MemoryStream(encryptedkey);
            CryptoStream crypto = new CryptoStream(memory, cryptor, CryptoStreamMode.Read);

            byte[] decryptedkey = new byte[16];
            crypto.Read(decryptedkey, 0, decryptedkey.Length);

            crypto.Close();
            memory.Close();

            return decryptedkey;
        }
        public static int GetContentNum(byte[] tmd)
        {
            int contents = int.Parse(tmd[0x1de].ToString("x2") + tmd[0x1df].ToString("x2"), System.Globalization.NumberStyles.HexNumber);

            return contents;
        }
        /// <summary>
        /// [x, 0] = Content ID, [x, 1] = Index, [x, 2] = Type, [x, 3] = Size, [x, 4] = Sha1
        /// </summary>
        /// <param name="tmd"></param>
        /// <returns></returns>
        public static string[,] GetContentInfo(byte[] tmd)
        {
            int tmdpos = 0;

            int contentcount = GetContentNum(tmd);
            string[,] contentinfo = new string[contentcount, 5];
            //int[] test = new int[3];

            //test[0] = tmd[tmdpos + 0x180];
            // test[1] = tmd[tmdpos + 0x181];
            // test[2] = tmd[tmdpos + 0x182];
            title_Version = int.Parse(tmd[tmdpos + 0x180].ToString("x2") + tmd[tmdpos + 0x181].ToString("x2") + tmd[tmdpos + 0x182].ToString("x2"), System.Globalization.NumberStyles.HexNumber).ToString();
            for (int i = 0; i < contentcount; i++)
            {
                contentinfo[i, 0] = tmd[tmdpos + 0x1e4 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1e5 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1e6 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1e7 + (36 * i)].ToString("x2");
                contentinfo[i, 1] = "0000" +
                    tmd[tmdpos + 0x1e8 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1e9 + (36 * i)].ToString("x2");
                contentinfo[i, 2] = tmd[tmdpos + 0x1ea + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1eb + (36 * i)].ToString("x2");
                contentinfo[i, 3] = int.Parse(
                    tmd[tmdpos + 0x1ec + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1ed + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1ee + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1ef + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1f0 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1f1 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1f2 + (36 * i)].ToString("x2") +
                    tmd[tmdpos + 0x1f3 + (36 * i)].ToString("x2"), System.Globalization.NumberStyles.HexNumber).ToString();

                for (int j = 0; j < 20; j++)
                {
                    contentinfo[i, 4] += tmd[tmdpos + 0x1f4 + (36 * i) + j].ToString("x2");
                }
            }

            return contentinfo;
        }
        public static byte[] DecryptContent(byte[] content, byte[] tmd, int contentcount, byte[] titlekey)
        {
            byte[] iv = new byte[16];
            int contentsize = content.Length;
            iv[0] = tmd[0x1e8 + (0x24 * contentcount)];
            iv[1] = tmd[0x1e9 + (0x24 * contentcount)];


            RijndaelManaged decrypt = new RijndaelManaged();
            decrypt.Mode = CipherMode.CBC;
            decrypt.Padding = PaddingMode.None;
            decrypt.KeySize = 128;
            decrypt.BlockSize = 128;
            decrypt.Key = titlekey;
            decrypt.IV = iv;

            ICryptoTransform cryptor = decrypt.CreateDecryptor();

            MemoryStream memory = new MemoryStream(content);
            CryptoStream crypto = new CryptoStream(memory, cryptor, CryptoStreamMode.Read);

            bool fullread = false;
            byte[] buffer = new byte[memory.Length];
            byte[] cont = new byte[1];

            using (MemoryStream ms = new MemoryStream())
            {
                while (fullread == false)
                {
                    int len = 0;
                    if ((len = crypto.Read(buffer, 0, buffer.Length)) <= 0)
                    {
                        fullread = true;
                        cont = ms.ToArray();
                    }
                    ms.Write(buffer, 0, len);
                }
            }

            memory.Close();
            crypto.Close();

            Array.Resize(ref cont, int.Parse(contInfo[contentcount, 3]));

            return cont;
        }
        public static bool CompareByteArrays(byte[] first, byte[] second)
        {
            // Console.WriteLine("len1 = " + first.Length);
            // Console.WriteLine("len2 = " + second.Length);
            if (first.Length != second.Length)
            {

                return false;
            }
            else
            {
                for (int i = 0; i < first.Length; i++)
                    if (first[i] != second[i]) return false;

                return true;
            }
        }
        static bool HashCheck(byte[] newFile, byte[] tmdHash)
        {
            SHA1 sha = SHA1.Create();

            byte[] fileHash = sha.ComputeHash(newFile);
            /* Console.Write("app file hash [ ");
             for (int x = 0; x < fileHash.Length; x++)
             {
                 Console.Write(" " + fileHash[x].ToString("X2"));
             }
             Console.WriteLine(" ]");*/
            return CompareByteArrays(fileHash, tmdHash);
        }

    }
}
