public static PersistantConfig Deserialize(string file) { XmlSerializer xs = new XmlSerializer(typeof(PersistantConfig)); StreamReader reader = File.OpenText(file); PersistantConfig c = (PersistantConfig)xs.Deserialize(reader); reader.Close(); StaticExports.SetConfigSetting("Disassembly_FriendlyNaming", c.ShaderViewer_FriendlyNaming ? "1" : "0"); foreach (var kv in c.ConfigSettingsValues) { if (kv.Key != null && kv.Key.Length > 0 && kv.Value != null) { c.SetConfigSetting(kv.Key, kv.Value); } } //external disassemblers foreach (var kv in c.ExternalDisassemblersValues) { if (kv.Key >= 0 && kv.Value != null) { c.SetExternalDisassemblers(kv.Key, kv.Value); } } // localhost should always be available bool foundLocalhost = false; for (int i = 0; i < c.RemoteHosts.Count; i++) { if (c.RemoteHosts[i].Hostname == "localhost") { foundLocalhost = true; break; } } if (!foundLocalhost) { RemoteHost host = new RemoteHost(); host.Hostname = "localhost"; c.RemoteHosts.Add(host); } return(c); }
public void ConnectToRemoteServer(RemoteHost host) { InitException = null; try { m_Remote = StaticExports.CreateRemoteServer(host.Hostname, 0); m_RemoteHost = host; m_RemoteHost.Connected = true; } catch (ReplayCreateException ex) { InitException = ex; } }
private void connect_Click(object sender, EventArgs e) { TreelistView.Node node = hosts.SelectedNode; if (node.Tag is RemoteConnect) { ConnectToHost(node); } else if (node.Tag is RemoteHost) { RemoteHost host = node.Tag as RemoteHost; if (host.ServerRunning) { DialogResult res = MessageBox.Show(String.Format("Are you sure you wish to shut down running remote server on {0}?", host.Hostname), "Remote server shutdown", MessageBoxButtons.YesNoCancel); if (res == DialogResult.Cancel || res == DialogResult.No) { return; } // shut down try { RemoteServer server = StaticExports.CreateRemoteServer(host.Hostname, 0); server.ShutdownServerAndConnection(); hosts.BeginUpdate(); SetRemoteServerLive(node, false, false); hosts.EndUpdate(); } catch (Exception) { MessageBox.Show("Error shutting down remote server", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } updateConnectButton(); } else { // try to run refresh.Enabled = false; Thread th = Helpers.NewThread(new ParameterizedThreadStart(RunRemoteServer)); th.Start(node); } } }
public void CheckStatus() { // special case - this is the local context if (Hostname == "localhost") { ServerRunning = false; VersionMismatch = Busy = false; return; } try { RemoteServer server = StaticExports.CreateRemoteServer(Hostname, 0); ServerRunning = true; VersionMismatch = Busy = false; server.ShutdownConnection(); // since we can only have one active client at once on a remote server, we need // to avoid DDOS'ing by doing multiple CheckStatus() one after the other so fast // that the active client can't be properly shut down. Sleeping here for a short // time gives that breathing room. // Not the most elegant solution, but it is simple Thread.Sleep(15); } catch (ReplayCreateException ex) { if (ex.Status == ReplayCreateStatus.NetworkRemoteBusy) { ServerRunning = true; Busy = true; } else if (ex.Status == ReplayCreateStatus.NetworkVersionMismatch) { ServerRunning = true; Busy = true; VersionMismatch = true; } else { ServerRunning = false; Busy = false; } } }
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, EnvironmentModification[] env, string logfile, CaptureOptions opts) { if (m_Remote == null) { return(StaticExports.ExecuteAndInject(app, workingDir, cmdLine, env, logfile, opts)); } else { UInt32 ret = 0; lock (m_Remote) { ret = m_Remote.ExecuteAndInject(app, workingDir, cmdLine, env, opts); } return(ret); } }
public UpdateDialog(Core core) { InitializeComponent(); doupdate.FlatStyle = FlatStyle.System; SendMessage(doupdate.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF); string[] response_split = core.Config.CheckUpdate_UpdateResponse.Split('\n'); progressText.Text = ""; progressBar.Visible = false; Text = updateVer.Text = String.Format("Update Available - v{0}", response_split[0]); m_NewVer = response_split[0]; m_URL = response_split[1]; int.TryParse(response_split[2], out m_Size); string notes = ""; for (int i = 3; i < response_split.Length; i++) { notes += response_split[i] + Environment.NewLine; } try { updateNotes.Rtf = notes.Trim(); } catch (Exception) { // most likely invalid formatting, so fall back to a sensible default updateNotes.Rtf = @"{\rtf1\ansi\fs36\sa200\sl276\slmult1RenderDoc v" + m_NewVer + @" \fs16" + @"\par A new version of RenderDoc is available and it's recommended that you update.}"; } updateNotes.Select(0, 0); updateMetadata.Text = "v" + StaticExports.GetVersionString() + Environment.NewLine + Environment.NewLine + String.Format("v{0}", response_split[0]) + Environment.NewLine + Environment.NewLine + String.Format("{0:0.00} MB", (float)m_Size / 1024.0f / 1024.0f); }
static void HandleException(Exception ex) { // we log out this string, which is matched against in renderdoccmd to pull out the callstack // from the log even in the case where the user chooses not to submit the error log StaticExports.LogText("--- Begin C# Exception Data ---"); if (ex != null) { LogException(ex); StaticExports.TriggerExceptionHandler(System.Runtime.InteropServices.Marshal.GetExceptionPointers(), true); } else { StaticExports.LogText("Exception is NULL"); StaticExports.TriggerExceptionHandler(IntPtr.Zero, true); } System.Diagnostics.Process.GetCurrentProcess().Kill(); }
public void AddAndroidHosts() { for (int i = RemoteHosts.Count - 1; i >= 0; i--) { if (RemoteHosts[i].Hostname.StartsWith("adb:")) { RemoteHosts.RemoveAt(i); } } string adbExePath = File.Exists(AdbExecutablePath) ? AdbExecutablePath : ""; // Set the config setting as it will be reused when we start the remoteserver etc. StaticExports.SetConfigSetting("adbExePath", adbExePath); string[] androidHosts = StaticExports.EnumerateAndroidDevices(); foreach (string hostName in androidHosts) { RemoteHost host = new RemoteHost(); host.Hostname = hostName; RemoteHosts.Add(host); } }
public void Serialize(string file) { if (ReadOnly) { return; } StaticExports.SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0"); try { ConfigSettingsValues.Clear(); foreach (var kv in ConfigSettings) { ConfigSettingsValues.Add(new SerializableKeyValuePair <string, string>(kv.Key, kv.Value)); } //external disassemblers ExternalDisassemblersValues.Clear(); foreach (var kv in ExternalDisassemblers) { ExternalDisassemblersValues.Add(new SerializableKeyValuePair <int, ExternalDisassembler>(kv.Key, kv.Value)); } XmlSerializer xs = new XmlSerializer(this.GetType()); StreamWriter writer = File.CreateText(file); xs.Serialize(writer, this); writer.Flush(); writer.Close(); } catch (System.IO.IOException ex) { // Can't recover, but let user know that we couldn't save their settings. MessageBox.Show(String.Format("Error saving config file: {1}\n{0}", file, ex.Message)); } }
public void SetConfigSetting(string name, string value) { ConfigSettings[name] = value; StaticExports.SetConfigSetting(name, value); }
private void ConnectionThreadEntry() { try { string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; m_Connection = StaticExports.CreateRemoteAccessConnection(m_Host, m_RemoteIdent, username, true); if (m_Connection.Connected) { string api = "..."; if (m_Connection.API.Length > 0) { api = m_Connection.API; } this.BeginInvoke((MethodInvoker) delegate { if (m_Connection.PID == 0) { connectionStatus.Text = String.Format("Connection established to {0} ({1})", m_Connection.Target, api); Text = String.Format("{0} ({1})", m_Connection.Target, api); } else { connectionStatus.Text = String.Format("Connection established to {0} [PID {1}] ({2})", m_Connection.Target, m_Connection.PID, api); Text = String.Format("{0} [PID {1}] ({2})", m_Connection.Target, m_Connection.PID, api); } connectionIcon.Image = global::renderdocui.Properties.Resources.connect; }); } else { throw new ApplicationException(); } while (m_Connection.Connected) { m_Connection.ReceiveMessage(); if (m_TriggerCapture) { m_Connection.TriggerCapture(); m_TriggerCapture = false; } if (m_QueueCapture) { m_Connection.QueueCapture((uint)m_CaptureFrameNum); m_QueueCapture = false; m_CaptureFrameNum = 0; } if (m_Disconnect) { m_Connection.Shutdown(); m_Connection = null; return; } if (m_Connection.InfoUpdated) { this.BeginInvoke((MethodInvoker) delegate { connectionStatus.Text = String.Format("Connection established to {0} ({1})", m_Connection.Target, m_Connection.API); Text = String.Format("{0} ({1})", m_Connection.Target, m_Connection.API); connectionIcon.Image = global::renderdocui.Properties.Resources.connect; }); m_Connection.InfoUpdated = false; } if (m_Connection.CaptureExists) { uint capID = m_Connection.CaptureFile.ID; DateTime timestamp = new DateTime(1970, 1, 1, 0, 0, 0); timestamp = timestamp.AddSeconds(m_Connection.CaptureFile.timestamp).ToLocalTime(); byte[] thumb = m_Connection.CaptureFile.thumbnail; string path = m_Connection.CaptureFile.localpath; if (path.Length == 0 || File.Exists(path)) { this.BeginInvoke((MethodInvoker) delegate { CaptureAdded(capID, m_Connection.Target, m_Connection.API, thumb, timestamp); if (path.Length > 0) { CaptureRetrieved(capID, path); } }); m_Connection.CaptureExists = false; if (path.Length == 0) { m_Connection.CopyCapture(capID, m_Core.TempLogFilename("remotecopy_" + m_Connection.Target)); } } } if (m_Connection.CaptureCopied) { uint capID = m_Connection.CaptureFile.ID; string path = m_Connection.CaptureFile.localpath; this.BeginInvoke((MethodInvoker) delegate { CaptureRetrieved(capID, path); }); m_Connection.CaptureCopied = false; } if (m_Connection.ChildAdded) { if (m_Connection.NewChild.PID != 0) { try { ChildProcess c = new ChildProcess(); c.PID = (int)m_Connection.NewChild.PID; c.ident = m_Connection.NewChild.ident; c.name = Process.GetProcessById((int)m_Connection.NewChild.PID).ProcessName; lock (m_Children) { m_Children.Add(c); } } catch (Exception) { // process expired/doesn't exist anymore } } m_Connection.ChildAdded = false; } } this.BeginInvoke((MethodInvoker) delegate { connectionStatus.Text = "Connection closed"; connectionIcon.Image = global::renderdocui.Properties.Resources.disconnect; ConnectionClosed(); }); } catch (ApplicationException) { this.BeginInvoke((MethodInvoker) delegate { Text = (m_Host.Length > 0 ? (m_Host + " - ") : "") + "Connection failed"; connectionStatus.Text = "Connection failed"; connectionIcon.Image = global::renderdocui.Properties.Resources.delete; ConnectionClosed(); }); } }
// this function looks up the remote connections and for each one open // queries it for the API, target (usually executable name) and if any user is already connected private static void LookupHostConnections(object o) { { lookupMutex.WaitOne(); lookupsInProgress++; lookupMutex.ReleaseMutex(); } TreelistView.Node node = o as TreelistView.Node; Control p = node.OwnerView; while (p.Parent != null) { p = p.Parent; } RemoteHostSelect rhs = p as RemoteHostSelect; string hostname = node["Hostname"] as string; string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; StaticExports.EnumerateRemoteConnections(hostname, (UInt32 i) => { try { var conn = StaticExports.CreateRemoteAccessConnection(hostname, i, username, false); if (node.OwnerView.Visible) { string target = conn.Target; string api = conn.API; string busy = conn.BusyClient; node.OwnerView.BeginInvoke((MethodInvoker) delegate { node.OwnerView.BeginUpdate(); node.Nodes.Add(new TreelistView.Node(new object[] { target, api, busy })).Tag = new RemoteConnect(hostname, i); node.OwnerView.EndUpdate(); node.Expand(); }); } conn.Shutdown(); } catch (ApplicationException) { } }); if (node.OwnerView.Visible) { node.OwnerView.BeginInvoke((MethodInvoker) delegate { node.OwnerView.BeginUpdate(); node.Italic = false; node.Image = null; node.OwnerView.EndUpdate(); }); } { lookupMutex.WaitOne(); lookupsInProgress--; lookupMutex.ReleaseMutex(); } if (!rhs.IsDisposed && rhs.Visible) { rhs.BeginInvoke((MethodInvoker) delegate { rhs.LookupComplete(); }); } }
public ReplayHostManager(Core core, MainWindow main) { InitializeComponent(); Icon = global::renderdocui.Properties.Resources.icon; m_Core = core; m_Main = main; string[] proxies = new string[0]; try { var dummy = StaticExports.CreateRemoteReplayConnection("-"); proxies = dummy.LocalProxies(); dummy.Shutdown(); } catch (ApplicationException ex) { string errmsg = "Unknown error message"; if (ex.Data.Contains("status")) { errmsg = ((ReplayCreateStatus)ex.Data["status"]).Str(); } MessageBox.Show(String.Format("Failed to fetch local proxy drivers: {0}.\n\nCheck diagnostic log in Help menu for more details.", errmsg), "Error getting driver list", MessageBoxButtons.OK, MessageBoxIcon.Error); } localProxy.Items.AddRange(proxies); m_Core.Config.LocalProxy = Helpers.Clamp(m_Core.Config.LocalProxy, 0, proxies.Length - 1); localProxy.SelectedIndex = m_Core.Config.LocalProxy; var driversTable = new TableLayoutPanel(); driversTable.SuspendLayout(); driversBox.Controls.Clear(); driversBox.Controls.Add(driversTable); driversTable.ColumnCount = 2; driversTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 30F)); driversTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 70F)); driversTable.Dock = System.Windows.Forms.DockStyle.Fill; driversTable.RowCount = m_Core.Config.ReplayHosts.Count + 1; int row = 0; List <string> hosts = new List <string>(); foreach (var kv in m_Core.Config.ReplayHosts) { var driver = kv.Key; var lab = new Label(); lab.Anchor = AnchorStyles.Right; lab.AutoSize = true; lab.Text = driver; var host = new ComboBox(); host.Dock = DockStyle.Fill; host.FormattingEnabled = true; host.TabIndex = row + 1; hosts.Clear(); if (kv.Value != "") { hosts.Add(kv.Value); } var plugins = renderdocplugin.PluginHelpers.GetPlugins(); // search plugins for to find other targets for this driver foreach (var plugin in plugins) { var replayman = renderdocplugin.PluginHelpers.GetPluginInterface <renderdocplugin.ReplayManagerPlugin>(plugin); if (replayman != null && replayman.GetTargetType() == driver) { var targets = replayman.GetOnlineTargets(); foreach (var t in targets) { if (!hosts.Contains(t)) { hosts.Add(t); } } } } // fill the combo box with previously used hosts foreach (var prev in m_Core.Config.PreviouslyUsedHosts) { if (prev.Key == driver && !hosts.Contains(prev.Value)) { hosts.Add(prev.Value); } } driversTable.Controls.Add(lab, 0, row); driversTable.Controls.Add(host, 1, row); driversTable.RowStyles.Add(new RowStyle()); hosts.Remove(""); host.Items.AddRange(hosts.ToArray()); if (kv.Value != "") { host.SelectedIndex = 0; } host.Tag = driver; host.SelectedValueChanged += new EventHandler(host_SelectedValueChanged); host.KeyUp += new KeyEventHandler(host_KeyUp); m_Hosts.Add(host); row++; } driversTable.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); driversTable.ResumeLayout(false); driversTable.PerformLayout(); }
// this function looks up the remote connections and for each one open // queries it for the API, target (usually executable name) and if any user is already connected private static void LookupHostConnections(object o) { { lookupMutex.WaitOne(); lookupsInProgress++; lookupMutex.ReleaseMutex(); } TreelistView.Node node = o as TreelistView.Node; Control p = node.OwnerView; while (p.Parent != null) { p = p.Parent; } RemoteManager rhs = p as RemoteManager; string hostname = node["hostname"] as string; string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; RemoteHost host = node.Tag as RemoteHost; host.CheckStatus(); SetRemoteServerLive(node, host.ServerRunning, host.Busy); StaticExports.EnumerateRemoteTargets(hostname, (UInt32 i) => { try { var conn = StaticExports.CreateTargetControl(hostname, i, username, false); if (node.OwnerView.Visible) { string target = conn.Target; string api = conn.API; string busy = conn.BusyClient; string running; if (busy != "") { running = String.Format("Running {0}, {1} is connected", api, busy); } else { running = String.Format("Running {0}", api); } node.OwnerView.BeginInvoke((MethodInvoker) delegate { node.OwnerView.BeginUpdate(); node.Nodes.Add(new TreelistView.Node(new object[] { target, running })).Tag = new RemoteConnect(hostname, i); node.OwnerView.EndUpdate(); node.Expand(); }); } conn.Shutdown(); } catch (ReplayCreateException) { } }); if (node.OwnerView.Visible) { node.OwnerView.BeginInvoke((MethodInvoker) delegate { node.OwnerView.BeginUpdate(); node.Italic = false; node.OwnerView.EndUpdate(); }); } { lookupMutex.WaitOne(); lookupsInProgress--; lookupMutex.ReleaseMutex(); } if (!rhs.IsDisposed && rhs.Visible) { rhs.BeginInvoke((MethodInvoker) delegate { rhs.LookupComplete(); }); } }
// this function looks up the remote connections and for each one open // queries it for the API, target (usually executable name) and if any user is already connected private static void LookupHostConnections(object o) { { lookupMutex.WaitOne(); lookupsInProgress++; lookupMutex.ReleaseMutex(); } TreelistView.Node node = o as TreelistView.Node; Control p = node.OwnerView; while (p.Parent != null) { p = p.Parent; } RemoteHostSelect rhs = p as RemoteHostSelect; string hostname = node["Hostname"] as string; var idents = StaticExports.EnumerateRemoteConnections(hostname); var remotes = new Dictionary <UInt32, AvailableRemote>(); string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; foreach (var i in idents) { if (i != 0) { try { var conn = StaticExports.CreateRemoteAccessConnection(hostname, i, username, false); var data = new AvailableRemote(conn.Target, conn.API, conn.BusyClient); conn.Shutdown(); remotes.Add(i, data); } catch (ApplicationException) { } } } if (node.OwnerView.Visible) { node.OwnerView.BeginInvoke((MethodInvoker) delegate { node.OwnerView.BeginUpdate(); node.Italic = false; node.Image = null; foreach (var kv in remotes) { node.Nodes.Add(new TreelistView.Node(new object[] { kv.Value.Target, kv.Value.API, kv.Value.Busy })).Tag = new RemoteConnect(hostname, kv.Key); node.Bold = true; } node.OwnerView.EndUpdate(); }); } { lookupMutex.WaitOne(); lookupsInProgress--; lookupMutex.ReleaseMutex(); } if (!rhs.IsDisposed && rhs.Visible) { rhs.BeginInvoke((MethodInvoker) delegate { rhs.LookupComplete(); }); } }
private void toggleGlobalHook_CheckedChanged(object sender, EventArgs e) { if (!toggleGlobalHook.Enabled) { return; } toggleGlobalHook.Enabled = false; if (toggleGlobalHook.Checked) { if (!Helpers.IsElevated) { DialogResult res = MessageBox.Show("RenderDoc needs to restart with admin privileges. Restart?", "Restart as admin", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (res == DialogResult.Yes) { string capfile = Path.GetTempFileName() + ".cap"; AutoStart.Checked = false; SaveSettings(capfile); var process = new Process(); process.StartInfo = new System.Diagnostics.ProcessStartInfo(Application.ExecutablePath, capfile); process.StartInfo.Verb = "runas"; try { process.Start(); } catch (Exception) { // don't restart if it failed for some reason (e.g. user clicked no to UAC) toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } m_Core.Config.Serialize(Core.ConfigFilename); m_Core.Config.ReadOnly = true; m_Core.AppWindow.Close(); return; } else { toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } } exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = false; foreach (Control c in capOptsFlow.Controls) { c.Enabled = false; } foreach (Control c in actionsFlow.Controls) { c.Enabled = false; } toggleGlobalHook.Text = "Disable Global Hook"; var path = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath)); var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg"); try { if (Environment.Is64BitProcess) { EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), path, "x86\\renderdocshim32.dll", out prevAppInitWoW64Enabled, out prevAppInitWoW64); EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), path, "renderdocshim64.dll", out prevAppInitEnabled, out prevAppInit); using (FileStream s = File.OpenWrite(regfile)) { using (StreamWriter sw = new StreamWriter(s)) { sw.WriteLine("Windows Registry Editor Version 5.00"); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitWoW64Enabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInitWoW64)); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit)); sw.Flush(); } } } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually EnableAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), path, "renderdocshim32.dll", out prevAppInitEnabled, out prevAppInit); using (FileStream s = File.OpenWrite(regfile)) { using (StreamWriter sw = new StreamWriter(s)) { sw.WriteLine("Windows Registry Editor Version 5.00"); sw.WriteLine(""); sw.WriteLine("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]"); sw.WriteLine(String.Format("\"LoadAppInit_DLLs\"=dword:{0:X8}", prevAppInitEnabled)); sw.WriteLine(String.Format("\"AppInit_DLLs\"=\"{0}\"", prevAppInit)); sw.Flush(); } } } } catch (System.Exception ex) { MessageBox.Show("Aborting. Couldn't save backup .reg file to " + regfile + Environment.NewLine + ex.ToString(), "Cannot save registry backup", MessageBoxButtons.OK, MessageBoxIcon.Error); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } // won't recurse because it's not enabled yet toggleGlobalHook.Checked = false; toggleGlobalHook.Text = "Enable Global Hook"; toggleGlobalHook.Enabled = true; return; } ExitPipeThread(); pipeExit = false; try { pipe32 = new NamedPipeServerStream("RenderDoc.GlobalHookControl32"); pipe64 = new NamedPipeServerStream("RenderDoc.GlobalHookControl64"); } catch (System.IO.IOException ex) { // tidy up and exit MessageBox.Show("Aborting. Couldn't create named pipe:" + Environment.NewLine + ex.Message, "Cannot create named pipe", MessageBoxButtons.OK, MessageBoxIcon.Error); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } // need to revert registry entries too if (Environment.Is64BitProcess) { RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), prevAppInitWoW64Enabled, prevAppInitWoW64); RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } if (File.Exists(regfile)) { File.Delete(regfile); } // won't recurse because it's not enabled yet toggleGlobalHook.Checked = false; toggleGlobalHook.Text = "Enable Global Hook"; toggleGlobalHook.Enabled = true; return; } pipeThread = Helpers.NewThread(new ThreadStart(PipeTick)); pipeThread.Start(); string exe = exePath.Text; string logfile = exe; if (logfile.Contains("/")) { logfile = logfile.Substring(logfile.LastIndexOf('/') + 1); } if (logfile.Contains("\\")) { logfile = logfile.Substring(logfile.LastIndexOf('\\') + 1); } if (logfile.Contains(".")) { logfile = logfile.Substring(0, logfile.IndexOf('.')); } logfile = m_Core.TempLogFilename(logfile); StaticExports.StartGlobalHook(exe, logfile, GetSettings().Options); } else { ExitPipeThread(); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = capture.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } toggleGlobalHook.Text = "Enable Global Hook"; if (Environment.Is64BitProcess) { RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("Wow6432Node"), prevAppInitWoW64Enabled, prevAppInitWoW64); RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } else { // if this is a 64-bit OS, it will re-direct our request to Wow6432Node anyway, so we // don't need to handle that manually RestoreAppInit(Registry.LocalMachine.CreateSubKey("SOFTWARE"), prevAppInitEnabled, prevAppInit); } var regfile = Path.Combine(Path.GetTempPath(), "RenderDoc_RestoreGlobalHook.reg"); if (File.Exists(regfile)) { File.Delete(regfile); } } toggleGlobalHook.Enabled = true; UpdateGlobalHook(); }
private void ConnectionThreadEntry() { try { string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; m_Connection = StaticExports.CreateTargetControl(m_Host, m_RemoteIdent, username, true); if (m_Connection.Connected) { string api = "No API detected"; if (m_Connection.API.Length > 0) { api = m_Connection.API; } this.BeginInvoke((MethodInvoker) delegate { if (m_Connection.PID == 0) { connectionStatus.Text = String.Format("Connection established to {0} ({1})", m_Connection.Target, api); SetText(String.Format("{0}", m_Connection.Target)); } else { connectionStatus.Text = String.Format("Connection established to {0} [PID {1}] ({2})", m_Connection.Target, m_Connection.PID, api); SetText(String.Format("{0} [PID {1}]", m_Connection.Target, m_Connection.PID)); } connectionIcon.Image = global::renderdocui.Properties.Resources.connect; }); } else { throw new ReplayCreateException(ReplayCreateStatus.NetworkIOFailed); } while (m_Connection.Connected) { m_Connection.ReceiveMessage(); if (m_TriggerCapture) { m_Connection.TriggerCapture((uint)m_CaptureNumFrames); m_TriggerCapture = false; } if (m_QueueCapture) { m_Connection.QueueCapture((uint)m_CaptureFrameNum); m_QueueCapture = false; m_CaptureFrameNum = 0; } if (m_CopyLogLocalPath != "") { m_Connection.CopyCapture(m_CopyLogID, m_CopyLogLocalPath); m_CopyLogLocalPath = ""; m_CopyLogID = uint.MaxValue; } List <uint> dels = new List <uint>(); lock (m_DeleteLogs) { dels.AddRange(m_DeleteLogs); m_DeleteLogs.Clear(); } foreach (var del in dels) { m_Connection.DeleteCapture(del); } if (m_Disconnect) { m_Connection.Shutdown(); m_Connection = null; return; } if (m_Connection.InfoUpdated) { this.BeginInvoke((MethodInvoker) delegate { if (m_Connection.PID == 0) { connectionStatus.Text = String.Format("Connection established to {0} ({1})", m_Connection.Target, m_Connection.API); SetText(String.Format("{0}", m_Connection.Target)); } else { connectionStatus.Text = String.Format("Connection established to {0} [PID {1}] ({2})", m_Connection.Target, m_Connection.PID, m_Connection.API); SetText(String.Format("{0} [PID {1}]", m_Connection.Target, m_Connection.PID)); } connectionIcon.Image = global::renderdocui.Properties.Resources.connect; }); m_Connection.InfoUpdated = false; } if (m_Connection.CaptureExists) { uint capID = m_Connection.CaptureFile.ID; DateTime timestamp = new DateTime(1970, 1, 1, 0, 0, 0); timestamp = timestamp.AddSeconds(m_Connection.CaptureFile.timestamp).ToLocalTime(); byte[] thumb = m_Connection.CaptureFile.thumbnail; int thumbWidth = m_Connection.CaptureFile.thumbWidth; int thumbHeight = m_Connection.CaptureFile.thumbHeight; string path = m_Connection.CaptureFile.path; bool local = m_Connection.CaptureFile.local; this.BeginInvoke((MethodInvoker) delegate { CaptureAdded(capID, m_Connection.Target, m_Connection.API, thumb, thumbWidth, thumbHeight, timestamp, path, local); }); m_Connection.CaptureExists = false; } if (m_Connection.CaptureCopied) { uint capID = m_Connection.CaptureFile.ID; string path = m_Connection.CaptureFile.path; this.BeginInvoke((MethodInvoker) delegate { CaptureCopied(capID, path); }); m_Connection.CaptureCopied = false; } if (m_Connection.ChildAdded) { if (m_Connection.NewChild.PID != 0) { try { ChildProcess c = new ChildProcess(); c.PID = (int)m_Connection.NewChild.PID; c.ident = m_Connection.NewChild.ident; c.name = Process.GetProcessById((int)m_Connection.NewChild.PID).ProcessName; lock (m_Children) { m_Children.Add(c); } } catch (Exception) { // process expired/doesn't exist anymore } } m_Connection.ChildAdded = false; } } this.BeginInvoke((MethodInvoker) delegate { connectionStatus.Text = "Connection closed"; connectionIcon.Image = global::renderdocui.Properties.Resources.disconnect; numFrames.Enabled = captureDelay.Enabled = captureFrame.Enabled = triggerCapture.Enabled = queueCap.Enabled = false; ConnectionClosed(); }); } catch (ReplayCreateException) { this.BeginInvoke((MethodInvoker) delegate { SetText("Connection failed"); connectionStatus.Text = "Connection failed"; connectionIcon.Image = global::renderdocui.Properties.Resources.delete; ConnectionClosed(); }); } }
private void toggleGlobalHook_CheckedChanged(object sender, EventArgs e) { if (!toggleGlobalHook.Enabled) { return; } toggleGlobalHook.Enabled = false; if (toggleGlobalHook.Checked) { if (!Helpers.IsElevated) { DialogResult res = MessageBox.Show("RenderDoc needs to restart with admin privileges. Restart?", "Restart as admin", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (res == DialogResult.Yes) { string capfile = Path.GetTempFileName() + ".cap"; AutoStart.Checked = false; SaveSettings(capfile); var process = new Process(); process.StartInfo = new System.Diagnostics.ProcessStartInfo(Application.ExecutablePath, capfile); process.StartInfo.Verb = "runas"; try { process.Start(); } catch (Exception) { // don't restart if it failed for some reason (e.g. user clicked no to UAC) toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } m_Core.Config.Serialize(Core.ConfigFilename); m_Core.Config.ReadOnly = true; m_Core.AppWindow.Close(); return; } else { toggleGlobalHook.Checked = false; toggleGlobalHook.Enabled = true; return; } } exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = launch.Enabled = save.Enabled = load.Enabled = false; foreach (Control c in capOptsFlow.Controls) { c.Enabled = false; } foreach (Control c in actionsFlow.Controls) { c.Enabled = false; } toggleGlobalHook.Text = "Disable Global Hook"; if (StaticExports.IsGlobalHookActive()) { StaticExports.StopGlobalHook(); } string exe = exePath.Text; string logfile = exe; if (logfile.Contains("/")) { logfile = logfile.Substring(logfile.LastIndexOf('/') + 1); } if (logfile.Contains("\\")) { logfile = logfile.Substring(logfile.LastIndexOf('\\') + 1); } if (logfile.Contains(".")) { logfile = logfile.Substring(0, logfile.IndexOf('.')); } logfile = m_Core.TempLogFilename(logfile); bool success = StaticExports.StartGlobalHook(exe, logfile, GetSettings().Options); if (!success) { // tidy up and exit MessageBox.Show("Aborting. Couldn't start global hook. Check diagnostic log in help menu for more information", "Couldn't start global hook", MessageBoxButtons.OK, MessageBoxIcon.Error); exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = launch.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } // won't recurse because it's not enabled yet toggleGlobalHook.Checked = false; toggleGlobalHook.Text = "Enable Global Hook"; toggleGlobalHook.Enabled = true; return; } } else { if (StaticExports.IsGlobalHookActive()) { StaticExports.StopGlobalHook(); } exePath.Enabled = exeBrowse.Enabled = workDirPath.Enabled = workDirBrowse.Enabled = cmdline.Enabled = launch.Enabled = save.Enabled = load.Enabled = true; foreach (Control c in capOptsFlow.Controls) { c.Enabled = true; } foreach (Control c in actionsFlow.Controls) { c.Enabled = true; } toggleGlobalHook.Text = "Enable Global Hook"; } toggleGlobalHook.Enabled = true; UpdateGlobalHook(); }