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