Пример #1
0
        static void Main(string[] args)
        {
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            logger.WriteLine("Made by FailedShack");
            SetConsoleVisibility(false);
            Application.EnableVisualStyles();

            try
            {
                database.LoadFromDir(Path.Combine(GetLauncherPath(), "data"));
            }
            catch (FileNotFoundException e)
            {
                MessageBox.Show(e.Message + "\nMake sure this file is under the data directory.", "Initialization error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            if (!File.Exists("ver") || !File.Exists("WiiU_USB_Helper.exe"))
            {
                MessageBox.Show("Could not find Wii U USB Helper, please make sure this executable is in the correct folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }
            helperVersion = File.ReadAllLines("ver")[0];
            int revision = Int32.Parse(helperVersion.Substring(helperVersion.LastIndexOf('.') + 1));

            if (helperVersion.StartsWith("0.6.1"))
            {
                // Workaround to allow it to launch
                if (revision >= 653)
                {
                    string installPath = GetInstallPath();
                    string lastTitles  = Path.Combine(installPath, "lasttitles");
                    if (revision > 653)
                    {
                        string installConfPath = GetInstallConfPath();
                        Directory.CreateDirectory(installConfPath);
                        File.Create(Path.Combine(installConfPath, "user.config")).Close();
                    }
                    if (!File.Exists(lastTitles))
                    {
                        Directory.CreateDirectory(installPath);
                        StringBuilder sb = new StringBuilder();
                        // Rev. 653 minimums: 3 lines, single character each
                        // Revs. 654 & 655 minimums: 25 lines, 16 chars each
                        for (int lines = 0; lines != 25; lines++)
                        {
                            sb.Append('0', 16).AppendLine();
                        }
                        File.WriteAllText(lastTitles, sb.ToString());
                    }
                }
            }
            if (!CertMaker.rootCertExists() || !CertMaker.rootCertIsTrusted())
            {
                MessageBox.Show(
                    "You will now be prompted to install an SSL certificate, this is required to allow other programs to make HTTPS requests while Wii U USB Helper is open.\n" +
                    "This is part of the initial setup process.\n", "First run - Read carefully!", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                while (true)
                {
                    if (!CertMaker.createRootCert() || !CertMaker.trustRootCert())
                    {
                        DialogResult result = MessageBox.Show("The setup process cannot continue without an SSL certificate.\nAre you sure you want to cancel?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                        if (result == DialogResult.Yes)
                        {
                            Environment.Exit(0);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                string firefox = GetFirefoxExecutable();
                if (firefox != null)
                {
                    logger.WriteLine("Firefox: " + firefox);
                    MessageBox.Show("You will now also be prompted to install the certificate on Firefox.\nMake sure to check 'Trust this CA to identify websites'.", "First run", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    proxy.Start();
                    while (!FiddlerApplication.IsStarted())
                    {
                        Thread.Sleep(30);
                    }
                    StartProcess(firefox, "http://www.wiiuusbhelper.com/certificate");
                }
            }
            logger.WriteLine("Found trusted SSL Certificate.");

            if (!FiddlerApplication.IsStarted())
            {
                proxy.Start();
            }

            string executable = Path.Combine(GetLauncherPath(), "WiiU_USB_Helper.exe");

            // Patching
            if (args.Length == 1)
            {
                var group = Regex.Match(args[0], "[-]{1,2}(.*)").Groups[1];
                if (group.Success && group.Value == "nopatch")
                {
                    patch = false;
                    logger.WriteLine("Patching has been disabled.");
                }
            }
            if (patch)
            {
                ProgressDialog dialog = new ProgressDialog();
                dialog.SetHeader("Patching...");
                dialog.SetStyle(ProgressBarStyle.Marquee);
                dialog.GetProgressBar().MarqueeAnimationSpeed = 30;
                new Thread(() => {
                    dialog.ShowDialog();
                }).Start();
                RSAPatcher patcher           = new RSAPatcher(executable);
                RSACryptoServiceProvider rsa = GetRSA();
                string xml = rsa.ToXmlString(false);
                rsa.Dispose();
                var builder  = new StringBuilder();
                var element  = XElement.Parse(xml);
                var settings = new XmlWriterSettings
                {
                    OmitXmlDeclaration = true,
                    Indent             = true
                };
                using (var xmlWriter = XmlWriter.Create(builder, settings))
                {
                    element.Save(xmlWriter);
                }
                executable = Path.Combine(GetLauncherPath(), "Patched.exe");
                patcher.SetPublicKey(builder.ToString(), executable);
                dialog.Invoke(new Action(() => dialog.Close()));
                logger.WriteLine("Patched public key.");
            }

            // Time to launch Wii U USB Helper
            sessionStart = DateTime.UtcNow;
            process      = StartProcess(executable, helperVersion);
            ContextMenu trayMenu   = new ContextMenu();
            MenuItem    dlEmulator = new MenuItem("Download Emulator");

            foreach (EmulatorConfiguration.Emulator emulator in Enum.GetValues(typeof(EmulatorConfiguration.Emulator)))
            {
                EmulatorConfiguration config = EmulatorConfiguration.GetConfiguration(emulator);
                dlEmulator.MenuItems.Add(config.GetName(), (sender, e) => OnDownloadEmulator(config));
            }
            MenuItem advanced = new MenuItem("Advanced");

            advanced.MenuItems.Add("Toggle Console", OnVisibilityChange);
            advanced.MenuItems.Add("Clear Install", OnClearInstall);
            advanced.MenuItems.Add("Remove Certificate", OnRemoveCertificate);
            trayMenu.MenuItems.Add("Exit", OnExit);
            trayMenu.MenuItems.Add("Check for Updates", OnUpdateCheck);
            trayMenu.MenuItems.Add("Report Issue", OnDebugMessage);
            trayMenu.MenuItems.Add("Generate Donation Key", OnGenerateKey).Enabled = patch;
            trayMenu.MenuItems.Add(dlEmulator);
            trayMenu.MenuItems.Add(advanced);
            trayIcon.Text        = "Wii U USB Helper Launcher";
            trayIcon.Icon        = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
            trayIcon.ContextMenu = trayMenu;
            trayIcon.Visible     = true;
            backgroundThread     = new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                while (!process.HasExited)
                {
                    try
                    {
                        Thread.Sleep(30);
                    }
                    catch (ThreadInterruptedException) { }
                }
                Cleanup();
                Application.Exit();
            });
            backgroundThread.Start();
            Application.Run();
        }
Пример #2
0
        static void Main(string[] args)
        {
            Settings.Load();
            Settings.Save();
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            logger.WriteLine("Made by FailedShack");
            SetConsoleVisibility(false);
            Application.EnableVisualStyles();

            if (Settings.ShowUpdateNag)
            {
                Task.Run(async() =>
                {
                    JObject release;
                    try
                    {
                        release = await GithubUtil.GetRelease("FailedShack", "USBHelperLauncher", "latest");
                    }
                    catch
                    {
                        return;
                    }
                    string newVersion = (string)release["tag_name"];
                    string version    = GetVersion();
                    if (newVersion.CompareTo(version) > 0)
                    {
                        var updateNag       = new CheckboxDialog("New version found: " + newVersion + "\nCurrent version: " + version + "\nDo you want to open the download site?", "Do not show this again.", "Update Checker", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                        DialogResult result = updateNag.ShowDialog();
                        if (result == DialogResult.Yes)
                        {
                            Process.Start((string)release["html_url"]);
                        }
                        Settings.ShowUpdateNag = !updateNag.Checked;
                        Settings.Save();
                    }
                });
            }

            string hostsFile = GetHostsFile();

            if (File.Exists(hostsFile))
            {
                try
                {
                    Hosts = Hosts.Load(hostsFile);
                }
                catch (Exception e)
                {
                    MessageBox.Show("Could not load hosts file: " + e.Message, "Malformed hosts file", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                Hosts = new Hosts();
                if (Settings.ShowHostsWarning)
                {
                    var hostsWarning = new CheckboxDialog(
                        "It appears you don't currently have a hosts redirector file. This file may be required to route obsolete hostnames to their correct destination.\n" +
                        "If you intended to use this feature, make sure a file named 'hosts.json' is located in the same directory as this executable.\n" +
                        "You may also use the built-in editor located in the Advanced section in the tray icon's context menu.", "Do not show this again.", "Hosts file missing", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    hostsWarning.ShowDialog();
                    Settings.ShowHostsWarning = !hostsWarning.Checked;
                    Settings.Save();
                }
            }

            try
            {
                database.LoadFromDir(Path.Combine(GetLauncherPath(), "data"));
            }
            catch (FileNotFoundException e)
            {
                MessageBox.Show(e.Message + "\nMake sure this file is under the data directory.", "Initialization error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            if (!File.Exists("ver") || !File.Exists("WiiU_USB_Helper.exe"))
            {
                MessageBox.Show("Could not find Wii U USB Helper, please make sure this executable is in the correct folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }
            helperVersion = File.ReadAllLines("ver")[0];
            int revision = Int32.Parse(helperVersion.Substring(helperVersion.LastIndexOf('.') + 1));

            if (helperVersion.StartsWith("0.6.1"))
            {
                // Workaround to allow it to launch
                if (revision >= 653)
                {
                    string installPath = GetInstallPath();
                    string lastTitles  = Path.Combine(installPath, "lasttitles");
                    if (revision > 653)
                    {
                        string installConfPath = GetInstallConfPath();
                        Directory.CreateDirectory(installConfPath);
                        File.Create(Path.Combine(installConfPath, "user.config")).Close();
                    }
                    if (!File.Exists(lastTitles))
                    {
                        Directory.CreateDirectory(installPath);
                        StringBuilder sb = new StringBuilder();
                        // Rev. 653 minimums: 3 lines, single character each
                        // Revs. 654 & 655 minimums: 25 lines, 16 chars each
                        for (int lines = 0; lines != 25; lines++)
                        {
                            sb.Append('0', 16).AppendLine();
                        }
                        File.WriteAllText(lastTitles, sb.ToString());
                    }
                }
            }
            if (!CertMaker.rootCertExists() && !CertMaker.createRootCert())
            {
                MessageBox.Show("Creation of the interception certificate failed.", "Unable to generate certificate.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            string executable = Path.Combine(GetLauncherPath(), "WiiU_USB_Helper.exe");

            var running = Process.GetProcessesByName("Patched").FirstOrDefault(p => p.GetMainModuleFileName().StartsWith(GetLauncherPath(), StringComparison.OrdinalIgnoreCase));

            if (running != default(Process))
            {
                DialogResult result = MessageBox.Show("An instance of Wii U USB Helper is already running.\nWould you like to close it?", "Already running", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                if (result == DialogResult.No)
                {
                    Environment.Exit(0);
                }
                running.Kill();
            }

            proxy.Start();

            // Patching
            for (int i = 0; i < args.Length; i++)
            {
                var group = Regex.Match(args[i], "[-]{1,2}(.*)").Groups[1];
                if (group.Success)
                {
                    switch (group.Value)
                    {
                    case "nopatch":
                        patch = false;
                        logger.WriteLine("Patching has been disabled.");
                        break;

                    case "verbose":
                        Verbose = true;
                        logger.WriteLine("Verbose logging enabled.");
                        break;
                    }
                }
            }

            ProgressDialog dialog = new ProgressDialog();

            dialog.SetStyle(ProgressBarStyle.Marquee);
            dialog.GetProgressBar().MarqueeAnimationSpeed = 30;
            dialog.SetHeader("Injecting...");
            new Thread(() => {
                dialog.ShowDialog();
            }).Start();
            var injector = new ModuleInitInjector(executable);

            executable = Path.Combine(GetLauncherPath(), "Patched.exe");
            injector.Inject(executable);
            logger.WriteLine("Injected module initializer.");
            if (patch)
            {
                dialog.Invoke(new Action(() => dialog.SetHeader("Patching...")));
                RSAPatcher patcher           = new RSAPatcher(executable);
                RSACryptoServiceProvider rsa = GetRSA();
                string xml = rsa.ToXmlString(false);
                rsa.Dispose();
                var builder  = new StringBuilder();
                var element  = XElement.Parse(xml);
                var settings = new XmlWriterSettings
                {
                    OmitXmlDeclaration = true,
                    Indent             = true
                };
                using (var xmlWriter = XmlWriter.Create(builder, settings))
                {
                    element.Save(xmlWriter);
                }
                patcher.SetPublicKey(builder.ToString());
                logger.WriteLine("Patched public key.");
            }
            dialog.Invoke(new Action(() => dialog.Close()));

            // Time to launch Wii U USB Helper
            sessionStart = DateTime.UtcNow;
            process      = StartProcess(executable, helperVersion);

            if (Settings.DisableOptionalPatches)
            {
                logger.WriteLine("Optional patches have been disabled.");
            }

            new Thread(() =>
            {
                logger.WriteLine("Sending information to injector...");
                var client  = new PipeClient();
                var packets = new List <ActionPacket>();
                if (patch)
                {
                    packets.Add(new DonationKeyPacket()
                    {
                        DonationKey = GenerateDonationKey()
                    });
                }
                packets.AddRange(new List <ActionPacket>()
                {
                    new CertificateAuthorityPacket()
                    {
                        CaCert = CertMaker.GetRootCertificate()
                    },
                    new ProxyPacket()
                    {
                        Proxy = proxy.GetWebProxy()
                    },
                    new DownloaderSettingsPacket()
                    {
                        MaxRetries          = Settings.MaxRetries,
                        DelayBetweenRetries = Settings.DelayBetweenRetries
                    },
                    new OptionalPatchesPacket()
                    {
                        DisableOptionalPatches = Settings.DisableOptionalPatches
                    },
                    new TerminationPacket()
                });
                foreach (ActionPacket packet in packets)
                {
                    if (!client.SendPacket(packet))
                    {
                        logger.WriteLine(string.Format("Could not send IPC packet of type {0}", packet.GetType().Name));
                    }
                }
            }).Start();

            ContextMenu trayMenu   = new ContextMenu();
            MenuItem    dlEmulator = new MenuItem("Download Emulator");

            foreach (EmulatorConfiguration.Emulator emulator in Enum.GetValues(typeof(EmulatorConfiguration.Emulator)))
            {
                EmulatorConfiguration config = EmulatorConfiguration.GetConfiguration(emulator);
                dlEmulator.MenuItems.Add(config.GetName(), (sender, e) => OnDownloadEmulator(config));
            }
            MenuItem advanced = new MenuItem("Advanced");

            advanced.MenuItems.Add("Toggle Console", OnVisibilityChange);
            advanced.MenuItems.Add("Clear Install", OnClearInstall);
            advanced.MenuItems.Add("Generate Donation Key", OnGenerateKey).Enabled = patch;
            advanced.MenuItems.Add("Hosts Editor", OnOpenHostsEditor);
            trayMenu.MenuItems.Add("Exit", OnExit);
            trayMenu.MenuItems.Add("Check for Updates", OnUpdateCheck);
            trayMenu.MenuItems.Add("Report Issue", OnDebugMessage);
            trayMenu.MenuItems.Add(dlEmulator);
            trayMenu.MenuItems.Add(advanced);
            trayIcon.Text        = "Wii U USB Helper Launcher";
            trayIcon.Icon        = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
            trayIcon.ContextMenu = trayMenu;
            trayIcon.Visible     = true;
            backgroundThread     = new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                while (!process.HasExited)
                {
                    try
                    {
                        Thread.Sleep(30);
                    }
                    catch (ThreadInterruptedException) { }
                }
                Cleanup();
                Application.Exit();
            });
            backgroundThread.Start();
            Application.Run();
        }
Пример #3
0
        static void Main(string[] args)
        {
            Settings.Load();
            Settings.Save();
            proxy     = new Net.Proxy(8877);
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            for (int i = 0; i < args.Length; i++)
            {
                var group = Regex.Match(args[i], "[-]{1,2}(.*)").Groups[1];
                if (group.Success)
                {
                    switch (group.Value)
                    {
                    case "nopatch":
                        PatchPublicKey = false;
                        break;

                    case "showconsole":
                        showConsole = true;
                        break;
                    }
                }
            }

            logger.WriteLine("Made by FailedShack");
            SetConsoleVisibility(showConsole);
            Application.EnableVisualStyles();

            if (Settings.ShowUpdateNag)
            {
                Task.Run(async() =>
                {
                    JObject release;
                    try
                    {
                        release = await GithubUtil.GetRelease("FailedShack", "USBHelperLauncher", "latest");
                    }
                    catch
                    {
                        return;
                    }
                    string newVersion = (string)release["tag_name"];
                    string version    = GetVersion();
                    if (newVersion.CompareTo(version) > 0)
                    {
                        var updateNag       = new CheckboxDialog("New version found: " + newVersion + "\nCurrent version: " + version + "\nDo you want to open the download site?", "Do not show this again.", "Update Checker", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                        DialogResult result = updateNag.ShowDialog();
                        if (result == DialogResult.Yes)
                        {
                            Process.Start((string)release["html_url"]);
                        }
                        Settings.ShowUpdateNag = !updateNag.Checked;
                        Settings.Save();
                    }
                });
            }

            string hostsFile = GetHostsFile();

            if (File.Exists(hostsFile))
            {
                try
                {
                    Hosts = Hosts.Load(hostsFile);
                }
                catch (Exception e)
                {
                    MessageBox.Show("Could not load hosts file: " + e.Message, "Malformed hosts file", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                Hosts = new Hosts();
                if (Settings.ShowHostsWarning)
                {
                    var hostsWarning = new CheckboxDialog(
                        "It appears you don't currently have a hosts redirector file. This file may be required to route obsolete hostnames to their correct destination.\n" +
                        "If you intended to use this feature, make sure a file named 'hosts.json' is located in the same directory as this executable.\n" +
                        "You may also use the built-in editor located in the Advanced section in the tray icon's context menu.", "Do not show this again.", "Hosts file missing", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    hostsWarning.ShowDialog();
                    Settings.ShowHostsWarning = !hostsWarning.Checked;
                    Settings.Save();
                }
            }

            try
            {
                database.LoadFromDir(Path.Combine(GetLauncherPath(), "data"));
            }
            catch (FileNotFoundException e)
            {
                MessageBox.Show(e.Message + "\nMake sure this file is under the data directory.", "Initialization error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            if (!File.Exists("ver") || !File.Exists("WiiU_USB_Helper.exe"))
            {
                MessageBox.Show("Could not find Wii U USB Helper, please make sure this executable is in the correct folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }
            helperVersion = File.ReadAllLines("ver")[0];
            int revision = int.Parse(helperVersion.Substring(helperVersion.LastIndexOf('.') + 1));

            if (helperVersion.StartsWith("0.6.1"))
            {
                // Workaround to allow it to launch
                if (revision >= 653)
                {
                    string installPath = GetInstallPath();
                    string lastTitles  = Path.Combine(installPath, "lasttitles");
                    if (revision > 653)
                    {
                        string installConfPath = GetInstallConfPath();
                        Directory.CreateDirectory(installConfPath);
                        File.Create(Path.Combine(installConfPath, "user.config")).Close();
                    }
                    if (!File.Exists(lastTitles))
                    {
                        Directory.CreateDirectory(installPath);
                        StringBuilder sb = new StringBuilder();
                        // Rev. 653 minimums: 3 lines, single character each
                        // Revs. 654 & 655 minimums: 25 lines, 16 chars each
                        for (int lines = 0; lines != 25; lines++)
                        {
                            sb.Append('0', 16).AppendLine();
                        }
                        File.WriteAllText(lastTitles, sb.ToString());
                    }
                }
            }

            // Ensure that the cached title key JSON files are valid
            string[] toCheck = { "3FFFD23A80F800ABFCC436A5EC8F7F0B94C728A4", "9C6DD14B8E3530B701BC4F1B77345DADB0C32020" };
            foreach (string file in toCheck)
            {
                string path = Path.Combine(GetInstallPath(), file);
                if (File.Exists(path))
                {
                    try
                    {
                        JToken.Parse(File.ReadAllText(path));
                    }
                    catch (JsonReaderException)
                    {
                        File.Delete(path);
                        logger.WriteLine(string.Format("Removed bad cache file: {0}", file));
                    }
                }
            }

            // Make sure that FiddlerCore's key container can be accessed
            string keyContainerName = FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.KeyContainerName", "FiddlerBCKey");

            try
            {
                CspParameters cspParams = new CspParameters {
                    KeyContainerName = keyContainerName
                };
                var _ = new CspKeyContainerInfo(cspParams).UniqueKeyContainerName; // this will throw an exception if the container cannot be accessed
            }
            catch (CryptographicException)
            {
                byte[] hash;
                using (MD5 md5 = MD5.Create())
                {
                    hash = md5.ComputeHash(Encoding.ASCII.GetBytes(keyContainerName.ToLower() + "\0"));
                }
                var reader = new BinaryReader(new MemoryStream(hash));
                var sb     = new StringBuilder();
                for (int i = 0; i < 4; i++)
                {
                    sb.AppendFormat("{0:x8}", reader.ReadInt32());
                }

                string hashString   = sb.ToString();
                string userSID      = WindowsIdentity.GetCurrent().User.ToString();
                string rsaPath      = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft", "Crypto", "RSA", userSID);
                string keyContainer = Directory.GetFiles(rsaPath).Where(n => Path.GetFileName(n).ToLower().StartsWith(hashString)).FirstOrDefault();

                if (keyContainer != null)
                {
                    File.Delete(keyContainer);
                    logger.WriteLine(string.Format("Removed broken key container (Name: \"{0}\", Hash: {1}).", keyContainerName, hashString));
                }
            }

            if (!CertMaker.rootCertExists() && !CertMaker.createRootCert())
            {
                MessageBox.Show("Creation of the interception certificate failed.", "Unable to generate certificate.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            string executable = Path.Combine(GetLauncherPath(), "WiiU_USB_Helper.exe");

            var running = Process.GetProcessesByName("Patched").FirstOrDefault(p => p.GetMainModuleFileName().StartsWith(GetLauncherPath(), StringComparison.OrdinalIgnoreCase));

            if (running != default(Process))
            {
                DialogResult result = MessageBox.Show("An instance of Wii U USB Helper is already running.\nWould you like to close it?", "Already running", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                if (result == DialogResult.No)
                {
                    Environment.Exit(0);
                }
                running.Kill();
            }

            proxy.Start();
            ServiceHost host = new ServiceHost(typeof(LauncherService), new Uri("net.pipe://localhost/LauncherService"));

            host.AddServiceEndpoint(typeof(ILauncherService), new NetNamedPipeBinding(), "");
            host.Open();

            // Patching
            ProgressDialog dialog = new ProgressDialog();

            dialog.SetStyle(ProgressBarStyle.Marquee);
            dialog.GetProgressBar().MarqueeAnimationSpeed = 30;
            dialog.SetHeader("Injecting...");
            new Thread(() => {
                dialog.ShowDialog();
            }).Start();
            var injector = new ModuleInitInjector(executable);

            executable = Path.Combine(GetLauncherPath(), "Patched.exe");
            injector.Inject(executable);
            logger.WriteLine("Injected module initializer.");
            if (PatchPublicKey)
            {
                dialog.Invoke(new Action(() => dialog.SetHeader("Patching...")));
                RSAPatcher patcher = new RSAPatcher(executable);
                string     xml;
                using (var rsa = new RSACryptoServiceProvider(2048))
                {
                    rsaParams = rsa.ExportParameters(true);
                    xml       = rsa.ToXmlString(false);
                }
                var builder  = new StringBuilder();
                var element  = XElement.Parse(xml);
                var settings = new XmlWriterSettings
                {
                    OmitXmlDeclaration = true,
                    Indent             = true
                };
                using (var xmlWriter = XmlWriter.Create(builder, settings))
                {
                    element.Save(xmlWriter);
                }
                patcher.SetPublicKey(builder.ToString());
                logger.WriteLine("Patched public key.");
            }
            else
            {
                logger.WriteLine("Patching has been disabled.");
            }
            dialog.Invoke(new Action(() => dialog.Close()));

            // Time to launch Wii U USB Helper
            sessionStart = DateTime.UtcNow;
            process      = StartProcess(executable, helperVersion);

            if (Settings.DisableOptionalPatches)
            {
                logger.WriteLine("Optional patches have been disabled.");
            }

            ContextMenu trayMenu   = new ContextMenu();
            MenuItem    dlEmulator = new MenuItem("Download Emulator");

            foreach (EmulatorConfiguration.Emulator emulator in Enum.GetValues(typeof(EmulatorConfiguration.Emulator)))
            {
                EmulatorConfiguration config = EmulatorConfiguration.GetConfiguration(emulator);
                dlEmulator.MenuItems.Add(config.GetName(), (sender, e) => OnDownloadEmulator(config));
            }
            MenuItem advanced = new MenuItem("Advanced");

            advanced.MenuItems.Add("Toggle Console", OnVisibilityChange);
            advanced.MenuItems.Add("Clear Install", OnClearInstall);
            advanced.MenuItems.Add("Generate Donation Key", OnGenerateKey).Enabled = PatchPublicKey;
            advanced.MenuItems.Add("Hosts Editor", OnOpenHostsEditor);
            advanced.MenuItems.Add("Export Sessions", OnExportSessions);
            trayMenu.MenuItems.Add("Exit", OnExit);
            trayMenu.MenuItems.Add("Check for Updates", OnUpdateCheck);
            trayMenu.MenuItems.Add("Report Issue", OnDebugMessage);
            trayMenu.MenuItems.Add(dlEmulator);
            trayMenu.MenuItems.Add(advanced);
            trayIcon = new NotifyIcon
            {
                Text        = "Wii U USB Helper Launcher",
                Icon        = Icon.ExtractAssociatedIcon(Application.ExecutablePath),
                ContextMenu = trayMenu,
                Visible     = true
            };
            backgroundThread = new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                while (!process.HasExited)
                {
                    try
                    {
                        Thread.Sleep(30);
                    }
                    catch (ThreadInterruptedException) { }
                }
                Cleanup();
                Application.Exit();
            });
            backgroundThread.Start();
            Application.Run();
        }