public static void Init()
        {
            var args        = Environment.GetCommandLineArgs();
            var ipcType     = (IPCType)Enum.Parse(typeof(IPCType), args[2]);
            var launcherUri = args[3];

            IPCUtil.CreateService(
                ipcType,
                typeof(InjectorService),
                typeof(IInjectorService),
                out var serviceUri
                );

            LauncherService = IPCUtil.CreateChannel <ILauncherService>(ipcType, launcherUri);
            LauncherService.SendInjectorSettings(serviceUri);

            Harmony = new Harmony("me.failedshack.usbhelperinjector");
            var assembly = Assembly.GetExecutingAssembly();

            assembly.GetTypes()
            .Where(type =>
                   VersionSpecific.Applies(type, HelperVersion) &&
                   !(Overrides.DisableOptionalPatches && Optional.IsOptional(type)) &&
                   (!WineOnly.IsWineOnly(type) || WineCompat)
                   )
            .Do(type => Harmony.CreateClassProcessor(type).Patch());

            if (WineCompat)
            {
                RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
            }
        }
Ejemplo n.º 2
0
        public static void Init()
        {
            var args        = Environment.GetCommandLineArgs();
            var ipcType     = (IPCType)Enum.Parse(typeof(IPCType), args[2]);
            var launcherUri = args[3];

            IPCUtil.CreateService(
                ipcType,
                typeof(InjectorService),
                typeof(IInjectorService),
                out var serviceUri
                );

            LauncherService = IPCUtil.CreateChannel <ILauncherService>(ipcType, launcherUri);
            LauncherService.SendInjectorSettings(serviceUri);

            Harmony = new Harmony("me.failedshack.usbhelperinjector");
            var assembly = Assembly.GetExecutingAssembly();

            assembly.GetTypes()
            .Where(type =>
                   VersionSpecific.Applies(type, HelperVersion) &&
                   !(Overrides.DisableOptionalPatches && Optional.IsOptional(type)) &&
                   (!WineOnly.IsWineOnly(type) || WineCompat)
                   )
            .Do(type => Harmony.CreateClassProcessor(type).Patch());

            if (WineCompat)
            {
                RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
            }

            NusGrabberFormPatch.Shown += (form, e) =>
            {
                FF  player = null;
                var button = new OnOffButton()
                {
                    OnImage  = Resources.AudioOn,
                    OffImage = Resources.AudioOff,
                    State    = PlayMusic
                };
                button.StateChanged += (sender, e1) =>
                {
                    // avoid preloading ffplay
                    // TODO: make this not so hackish
                    if (player == null)
                    {
                        if (!button.State)
                        {
                            return;
                        }
                        player = FF.Play("-loop 0 -nodisp loop.ogg");
                    }
                    player.Pause = !button.State;
                    LauncherService.SetPlayMusic(button.State);
                };
                var toolWindow = ((Form)form).Controls.Find("toolWindow5", true)[0];
                toolWindow.Controls.Add(button);
                button.BringToFront();
            };
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            Settings.Load();
            Settings.Save();
            _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 "nokey":
                        OverridePublicKey = false;
                        break;

                    case "showconsole":
                        showConsole = true;
                        break;

                    case "portable":
                        Settings.Portable = true;
                        Settings.Save();
                        break;

                    case "wine":
                        WineCompat = true;
                        break;
                    }
                }
            }

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

            if (!WineCompat && WineUtil.IsRunningInWine())
            {
                var result = MessageBox.Show(
                    "Detected Wine environment.\nWould you like to enable settings/patches to improve Wine compatibility?\n(To enable this by default, run USBHelperLauncher with the \"--wine\" flag)",
                    "Question",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question
                    );
                WineCompat = result == DialogResult.Yes;
            }
            if (WineCompat)
            {
                Logger.WriteLine("Wine compatibility settings enabled");
                Settings.ForceHttp = true;
                Settings.IPCType   = IPCType.TCP;
                Settings.Save();
            }

            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();
                    }
                }).Wait();
            }

            if (Settings.ShowTranslateNag && Locale.ChosenLocale != LocaleProvider.DefaultLocale)
            {
                var localeInfo   = Locale.KnownLocales[Locale.ChosenLocale];
                var translateNag = MessageBox.Show(
                    string.Format("We are currently looking for volunteers to translate Wii U USB Helper to other languages. " +
                                  "You may be able to contribute by submitting translations for {0} on Crowdin.\nWould you like to open the site?", localeInfo.Name),
                    "Appeal to Translate", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                if (translateNag == DialogResult.Yes)
                {
                    Process.Start("https://crowdin.com/project/wii-u-usb-helper");
                }
                Settings.ShowTranslateNag = false;
                Settings.Save();
            }

            try
            {
                MOTD.DisplayIfNeeded(Locale.ChosenLocale);
            }
            catch (WebException e)
            {
                Logger.WriteLine("Could not load message of the day: {0}", e.Message);
            }

            var certs = new DirectoryInfo("certs");

            if (certs.Exists)
            {
                foreach (var file in certs.EnumerateFiles().Where(x => x.Length > 0))
                {
                    try
                    {
                        Proxy.CertificateStore.Import(file.FullName);
                    }
                    catch (CryptographicException)
                    {
                        MessageBox.Show(string.Format("{0} is not a valid certificate file.", file.Name, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error));
                        Environment.Exit(-1);
                    }
                }
            }

            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);
                    Hosts = new Hosts();
                }

                var conflicting = Proxy.GetConflictingHosts();
                if (!Settings.HostsExpert && conflicting.Count > 0)
                {
                    var hostsConflictWarning = new CheckboxDialog(
                        "The following hostnames specified in the hosts file are normally handled by USBHelperLauncher:\n\n" + string.Join("\n", conflicting) +
                        "\n\nIf you override them the program may not function properly." +
                        "\nDo you want to exclude them?", "Do not show this again.", "Conflicting hosts", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    DialogResult result = hostsConflictWarning.ShowDialog();
                    if (result == DialogResult.Yes)
                    {
                        Hosts.hosts = Hosts.hosts.Where(x => !conflicting.Contains(x.Key)).ToDictionary(x => x.Key, x => x.Value);
                    }
                    Settings.HostsExpert = hostsConflictWarning.Checked;
                    Settings.Save();
                }
            }
            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(-1);
            }

            if (!File.Exists("WiiU_USB_Helper.exe"))
            {
                MessageBox.Show(
                    File.Exists("ver")
                        ? $"Could not find Wii U USB Helper, your Antivirus software probably deleted it. Try adding the install directory ({GetLauncherPath()}) to your Antivirus' exclusions or disable your Antivirus, then reinstall USB Helper."
                        : "Could not find Wii U USB Helper, please make sure you unpacked the launcher's files (e.g. USBHelperLauncher.exe) and Wii U USB Helper's files (e.g. WiiU_USB_Helper.exe) into the same directory.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error
                    );
                Environment.Exit(-1);
            }
            HelperVersion = File.ReadAllLines("ver")[0];

            // 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 keyContainer = FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.KeyContainerName", "FiddlerBCKey");

            if (WinUtil.CSP.TryAcquire(keyContainer) == WinUtil.CSP.NTE_BAD_KEY_STATE)
            {
                WinUtil.CSP.Delete(keyContainer);
                Logger.WriteLine("Removed broken key container: {0}", keyContainer);
            }

            CertMaker.oCertProvider = new BCCertMaker.BCCertMaker(); // Don't try to load CertMaker.dll
            if (!Settings.ForceHttp && !CertMaker.rootCertExists() && !CertMaker.createRootCert())
            {
                MessageBox.Show("Creation of the interception certificate failed.", "Unable to generate certificate.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(-1);
            }

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

            var running = Process.GetProcessesByName("WiiU_USB_Helper_")
                          .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();
            }

            // The target .NET version (4.5) only uses TLS 1.0 and 1.1 by default
            ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

            Proxy.Start();

            // Update translations
            var dialog = new ProgressDialog();
            var worker = dialog.GetWorker();

            dialog.SetHeader("Updating translations...");
            new Thread(() => dialog.ShowDialog()).Start();
            Task.Run(async() =>
            {
                try
                {
                    if (await Locale.UpdateIfNeeded(dialog))
                    {
                        Logger.WriteLine("Updated translations: {0}", Settings.TranslationsBuild);
                    }
                    else
                    {
                        Logger.WriteLine("Translations were up to date.");
                    }
                }
                catch (Exception e)
                {
                    Logger.WriteLine("Could not update translations: {0}", e.Message);
                }
            }).Wait();

            IPCUtil.CreateService(
                Settings.IPCType,
                typeof(LauncherService),
                typeof(ILauncherService),
                out var serviceUri
                );
            Logger.WriteLine($"WCF host uri: {serviceUri}");

            // Patching
            dialog.Invoke(new Action(() =>
            {
                dialog.SetStyle(ProgressBarStyle.Marquee);
                dialog.GetProgressBar().MarqueeAnimationSpeed = 30;
                dialog.SetHeader("Injecting...");
            }));
            var injector = new ModuleInitInjector(executable);

            executable = Path.Combine(GetLauncherPath(), "WiiU_USB_Helper_.exe");
            if (injector.RequiresInject(executable))
            {
                injector.Inject(executable);
                Logger.WriteLine("Injected module initializer.");
            }
            else
            {
                Logger.WriteLine("Module initializer already injected.");
            }
            dialog.Invoke(new Action(() => dialog.Close()));

            if (OverridePublicKey)
            {
                // Generate an RSA key pair for our donation keys
                using (var rsa = new RSACryptoServiceProvider(2048))
                {
                    rsaParams = rsa.ExportParameters(true);
                    PublicKey = rsa.ToXmlString(false);
                }
            }

            // Time to launch Wii U USB Helper
            SessionStart = DateTime.UtcNow;
            var startInfo = new ProcessStartInfo()
            {
                FileName              = executable,
                Arguments             = string.Join(" ", HelperVersion, Settings.IPCType, serviceUri),
                UseShellExecute       = false,
                RedirectStandardError = true,
                StandardErrorEncoding = Encoding.Default
            };
            var process = new Process()
            {
                StartInfo = startInfo
            };

            process.EnableRaisingEvents = true;
            process.Exited += async(sender, e) =>
                              // Not raised in the main thread, must invoke there to interact with UI
                              await Dispatcher.InvokeAsync(async() =>
            {
                if (killed)
                {
                    return;
                }
                if (process.ExitCode != 0)
                {
                    Logger.WriteLine("Wii U USB Helper returned non-zero exit code 0x{0:x}:\n{1}", process.ExitCode, process.StandardError.ReadToEnd().Trim());;
                    var result = MessageBox.Show(string.Format("Uh-oh. Wii U USB Helper has crashed unexpectedly.\nDo you want to generate a debug log?\n\nError code: 0x{0:x}", process.ExitCode), "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
                    if (result == DialogResult.Yes)
                    {
                        await GenerateDebugLog();
                    }
                }
                Cleanup();
                Application.Exit();
            });

            process.Start();
            HelperProcess = process;

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

            if (Settings.ForceHttp)
            {
                Logger.WriteLine("Requests will be proxied over plain HTTP.");
            }

            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 language = new MenuItem("Language")
            {
                RadioCheck = true
            };

            foreach (var lang in Locale.AvailableLocales)
            {
                language.MenuItems.Add(lang.Value.Native, (sender, e) =>
                {
                    Settings.Locale = lang.Key;
                    Settings.Save();
                    MessageBox.Show("Your language choice has been saved.\nPlease restart USBHelperLauncher for changes to take effect.", "Restart required", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }).Checked = lang.Key == Locale.ChosenLocale;
            }
            if (language.MenuItems.Count == 0)
            {
                language.MenuItems.Add("No translations found").Enabled = false;
            }
            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 = OverridePublicKey;
            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", async(sender, e) => await GenerateDebugLog());
            trayMenu.MenuItems.Add(dlEmulator);
            trayMenu.MenuItems.Add(language);
            trayMenu.MenuItems.Add(advanced);
            trayIcon = new NotifyIcon
            {
                Text        = "Wii U USB Helper Launcher",
                Icon        = Icon.ExtractAssociatedIcon(Application.ExecutablePath),
                ContextMenu = trayMenu,
                Visible     = true
            };
            Application.Run();
        }