diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs index 021d8960c..019965d67 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs @@ -138,11 +138,11 @@ namespace ProcessHacker { foreach (string service in Program.HackerWindow.ProcessServices[pNode.Pid]) { - if (Program.HackerWindow.ServiceProvider.Dictionary.ContainsKey(service)) + if (Program.ServiceProvider.Dictionary.ContainsKey(service)) { - if (Program.HackerWindow.ServiceProvider.Dictionary[service].Status.DisplayName != "") + if (Program.ServiceProvider.Dictionary[service].Status.DisplayName != "") servicesText += " " + service + " (" + - Program.HackerWindow.ServiceProvider.Dictionary[service].Status.DisplayName + ")\n"; + Program.ServiceProvider.Dictionary[service].Status.DisplayName + ")\n"; else servicesText += " " + service + "\n"; } diff --git a/trunk/ProcessHacker/Components/ServiceProperties.cs b/trunk/ProcessHacker/Components/ServiceProperties.cs index 4070b67ab..1f7189520 100644 --- a/trunk/ProcessHacker/Components/ServiceProperties.cs +++ b/trunk/ProcessHacker/Components/ServiceProperties.cs @@ -56,7 +56,7 @@ namespace ProcessHacker.Components PID = -1; - _provider = Program.HackerWindow.ServiceProvider; + _provider = Program.ServiceProvider; if (services.Length == 1) { diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 7c612a9f0..6ffca1b4e 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -47,45 +47,124 @@ namespace ProcessHacker private delegate void AddMenuItemDelegate(string text, EventHandler onClick); + // This entire file is a big monolithic mess. + #region Variables + // One-instance windows. public HelpWindow HelpWindow; public HandleFilterWindow HandleFilterWindow; public HiddenProcessesWindow HiddenProcessesWindow; public LogWindow LogWindow; - public MiniSysInfo MiniSysInfoWindow; + public MiniSysInfo MiniSysInfoWindow; // Not used (yet) + /// + /// The thread for the System Information window. This is to avoid + /// freezing the main window every second to update the graphs. + /// Thread sysInfoThread; + /// + /// The System Information window. No methods should be called on + /// it directly because it belongs to another thread. + /// public SysInfoWindow SysInfoWindow; + // The three main providers. They should be accessed using + // Program.ProcessProvider, ServiceProvider and NetworkProvider, + // rsepectively. However, these three variables are remnants of + // the old PH. + /// + /// The processes/system provider. + /// ProcessSystemProvider processP; + /// + /// The services provider. + /// ServiceProvider serviceP; + /// + /// The network connections provider. + /// NetworkProvider networkP; + /// + /// The UAC shield bitmap. Used for the various menu items which + /// require UAC elevation. + /// Bitmap uacShieldIcon; + /// + /// A black icon which all notification icons are set to initially + /// before their first paint. + /// Icon blackIcon; + /// + /// A dummy UsageIcon to avoid null instance checks in the icon-related + /// functions. + /// UsageIcon dummyIcon; + /// + /// The list of notification icons. + /// List notifyIcons = new List(); + /// + /// The CPU history icon, with a history of CPU usage. + /// CpuHistoryIcon cpuHistoryIcon; + /// + /// The CPU usage icon, which indicates the current CPU usage (no history). + /// Dedicated to those Process Explorer users who don't like the + /// CPU history icon. + /// CpuUsageIcon cpuUsageIcon; + /// + /// The I/O history icon. + /// IoHistoryIcon ioHistoryIcon; + /// + /// The commit history icon. + /// CommitHistoryIcon commitHistoryIcon; + /// + /// The physical memory history icon. + /// PhysMemHistoryIcon physMemHistoryIcon; + /// + /// A dictionary relating services to processes. Each key is a PID and + /// each value is a list of service names hosted in that particular process. + /// Dictionary> processServices = new Dictionary>(); + /// + /// The number of selected processes. Not used. + /// int processSelectedItems; - int processSelectedPID; - - List listControls = new List(); + /// + /// The selected PID. + /// + int processSelectedPid; + /// + /// A queue of status messages, processed by the message timer. + /// Queue> statusMessages = new Queue>(); + /// + /// The PH log, with events such as process creation/termination and various + /// service events. + /// List> _log = new List>(); + /// + /// A list of window handles owned by the currently selected process. + /// Only populated when the user right-clicks exactly one process. + /// IList windowHandles = new List(); + #endregion #region Properties + // The following two properties were used by the Window menu system. + // Not very useful, but still needed for now. + public MenuItem WindowMenuItem { get { return windowMenuItem; } @@ -96,41 +175,35 @@ namespace ProcessHacker get { return vistaMenu; } } - public ProcessSystemProvider ProcessProvider - { - get { return processP; } - } - + // Mostly used by Save.cs. public ProcessTree ProcessTree { get { return treeProcesses; } } - public ServiceProvider ServiceProvider - { - get { return serviceP; } - } + // The two properties below aren't used at all. public ListView ServiceList { get { return listServices.List; } } - public NetworkProvider NetworkProvider - { - get { return networkP; } - } - public ListView NetworkList { get { return listNetwork.List; } } + /// + /// Provides a list of service names hosted by a process. + /// public IDictionary> ProcessServices { get { return processServices; } } + /// + /// The PH log. + /// public IList> Log { get { return _log; } @@ -786,19 +859,26 @@ namespace ProcessHacker { virtualizationProcessMenuItem.Checked = false; + // Menu item fixup... if (treeProcesses.SelectedTreeNodes.Count == 0) { + // If nothing is selected, disable everything. + // The Select All menu item will be enabled later if + // we have at least one process in the tree. menuProcess.DisableAll(); } else if (treeProcesses.SelectedTreeNodes.Count == 1) { + // All actions should work with one process selected. menuProcess.EnableAll(); + // Singular nouns. priorityMenuItem.Text = "&Priority"; terminateMenuItem.Text = "&Terminate Process"; suspendMenuItem.Text = "&Suspend Process"; resumeMenuItem.Text = "&Resume Process"; + // Check the appropriate priority level menu item. realTimeMenuItem.Checked = false; highMenuItem.Checked = false; aboveNormalMenuItem.Checked = false; @@ -808,7 +888,7 @@ namespace ProcessHacker try { - using (var phandle = new ProcessHandle(processSelectedPID, Program.MinProcessQueryRights)) + using (var phandle = new ProcessHandle(processSelectedPid, Program.MinProcessQueryRights)) { switch (phandle.GetPriorityClass()) { @@ -844,9 +924,10 @@ namespace ProcessHacker priorityMenuItem.Enabled = false; } + // Check the virtualization menu item. try { - using (var phandle = new ProcessHandle(processSelectedPID, Program.MinProcessQueryRights)) + using (var phandle = new ProcessHandle(processSelectedPid, Program.MinProcessQueryRights)) { try { @@ -865,9 +946,10 @@ namespace ProcessHacker virtualizationProcessMenuItem.Enabled = false; } + // Enable/disable DLL injection based on the process' session ID. try { - if (processP.Dictionary[processSelectedPID].SessionId != Program.CurrentSessionId) + if (processP.Dictionary[processSelectedPid].SessionId != Program.CurrentSessionId) injectDllProcessMenuItem.Enabled = false; else injectDllProcessMenuItem.Enabled = true; @@ -877,6 +959,9 @@ namespace ProcessHacker Logging.Log(ex); } + // Disable Terminate Process Tree if the selected process doesn't + // have any children. Note that this may also happen if the user + // is sorting the list (!). try { if (treeProcesses.SelectedTreeNodes[0].IsLeaf && @@ -890,52 +975,54 @@ namespace ProcessHacker Logging.Log(ex); } - // should declare a int variable - //callback should return false if find window handle - //load - //to do + // Find the process' windows (if any). windowHandles.Clear(); Win32.EnumWindows( - (hwnd, param) => - { - //IsWindowEnabled? - //GetWindowLong - // hParent is IsWindowVisible?IsWindowEnabled? - //Shell_TrayWnd - //WS_Caption - if ( Win32.IsWindow(hwnd) && Win32.IsWindowVisible(hwnd)) + (hwnd, param) => { - int pid; - Win32.GetWindowThreadProcessId(hwnd, out pid); - - // todo find main window handle - if (pid == processSelectedPID) - { - windowHandles.Add(hwnd); - //return false; - } - } - return true; - },0); + // IsWindowEnabled? + // GetWindowLong + // hParent is IsWindowVisible?IsWindowEnabled? + // Shell_TrayWnd + // WS_Caption + if (Win32.IsWindow(hwnd) && Win32.IsWindowVisible(hwnd)) + { + int pid; + Win32.GetWindowThreadProcessId(hwnd, out pid); + // TODO: Find main window handle + if (pid == processSelectedPid) + { + windowHandles.Add(hwnd); + // return false; + } + } + return true; + }, 0); + + // Enable the Window submenu if we found windows owned + // by the process. Otherwise, disable the submenu. if (windowHandles.Count > 0) { - // to load - //GetWindowPlacement + // GetWindowPlacement windowProcessMenuItem.Enabled = true; - } else - windowProcessMenuItem.Enabled = false; + { + windowProcessMenuItem.Enabled = false; + } } else { + // Assume most process actions will not work with more than one process. menuProcess.DisableAll(); + // Use plural nouns. terminateMenuItem.Text = "&Terminate Processes"; suspendMenuItem.Text = "&Suspend Processes"; resumeMenuItem.Text = "&Resume Processes"; + // Enable a specific set of actions. terminateMenuItem.Enabled = true; suspendMenuItem.Enabled = true; resumeMenuItem.Enabled = true; @@ -943,14 +1030,15 @@ namespace ProcessHacker copyProcessMenuItem.Enabled = true; } - if (processSelectedPID < 0 && treeProcesses.SelectedNodes.Count == 1) + // Special case for DPCs and Interrupts. + if (processSelectedPid < 0 && treeProcesses.SelectedNodes.Count == 1) { - // probably DPCs or Interrupts priorityMenuItem.Text = "&Priority"; menuProcess.DisableAll(); propertiesProcessMenuItem.Enabled = true; } + // Enable/disable the Select All menu item. if (treeProcesses.Model.Nodes.Count == 0) { selectAllProcessMenuItem.Enabled = false; @@ -1062,7 +1150,7 @@ namespace ProcessHacker { try { - using (var phandle = new ProcessHandle(processSelectedPID, + using (var phandle = new ProcessHandle(processSelectedPid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights)) { string currentDirectory = phandle.GetPebString(PebOffset.CurrentDirectoryPath); @@ -1070,7 +1158,7 @@ namespace ProcessHacker try { - using (var phandle2 = new ProcessHandle(processSelectedPID, ProcessAccess.Terminate)) + using (var phandle2 = new ProcessHandle(processSelectedPid, ProcessAccess.Terminate)) phandle2.Terminate(); } catch (Exception ex) @@ -1135,7 +1223,7 @@ namespace ProcessHacker try { - using (var phandle = new ProcessHandle(processSelectedPID, Program.MinProcessQueryRights)) + using (var phandle = new ProcessHandle(processSelectedPid, Program.MinProcessQueryRights)) { using (var thandle = phandle.GetToken(TokenAccess.GenericWrite)) { @@ -1152,12 +1240,12 @@ namespace ProcessHacker private void propertiesProcessMenuItem_Click(object sender, EventArgs e) { // user hasn't got any processes selected - if (processSelectedPID == -1) + if (processSelectedPid == -1) return; try { - ProcessWindow pForm = Program.GetProcessWindow(processP.Dictionary[processSelectedPID], + ProcessWindow pForm = Program.GetProcessWindow(processP.Dictionary[processSelectedPid], new Program.PWindowInvokeAction(delegate(ProcessWindow f) { Program.FocusWindow(f); @@ -1172,7 +1260,7 @@ namespace ProcessHacker private void affinityProcessMenuItem_Click(object sender, EventArgs e) { - ProcessAffinity affForm = new ProcessAffinity(processSelectedPID); + ProcessAffinity affForm = new ProcessAffinity(processSelectedPid); try { @@ -1191,7 +1279,7 @@ namespace ProcessHacker sfd.Filter = "Dump Files (*.dmp)|*.dmp|All Files (*.*)|*.*"; sfd.FileName = - processP.Dictionary[processSelectedPID].Name + + processP.Dictionary[processSelectedPid].Name + "_" + DateTime.Now.ToString("yyMMdd") + ".dmp"; @@ -1208,7 +1296,7 @@ namespace ProcessHacker { try { - using (var phandle = new ProcessHandle(processSelectedPID, + using (var phandle = new ProcessHandle(processSelectedPid, ProcessAccess.DupHandle | ProcessAccess.QueryInformation | ProcessAccess.SuspendResume | ProcessAccess.VmRead)) phandle.WriteDump(sfd.FileName); @@ -1301,10 +1389,10 @@ namespace ProcessHacker private void terminatorProcessMenuItem_Click(object sender, EventArgs e) { - TerminatorWindow w = new TerminatorWindow(processSelectedPID); + TerminatorWindow w = new TerminatorWindow(processSelectedPid); - w.Text = "Terminator - " + processP.Dictionary[processSelectedPID].Name + - " (PID " + processSelectedPID.ToString() + ")"; + w.Text = "Terminator - " + processP.Dictionary[processSelectedPid].Name + + " (PID " + processSelectedPid.ToString() + ")"; w.TopMost = this.TopMost; w.ShowDialog(); @@ -1316,7 +1404,7 @@ namespace ProcessHacker { try { - Properties.Settings.Default.RunAsCommand = processP.Dictionary[processSelectedPID].FileName; + Properties.Settings.Default.RunAsCommand = processP.Dictionary[processSelectedPid].FileName; RunWindow run = new RunWindow(); @@ -1336,7 +1424,7 @@ namespace ProcessHacker RunWindow run = new RunWindow(); run.TopMost = this.TopMost; - run.UsePID(processSelectedPID); + run.UsePID(processSelectedPid); run.ShowDialog(); } catch (Exception ex) @@ -1353,7 +1441,7 @@ namespace ProcessHacker { try { - using (var phandle = new ProcessHandle(processSelectedPID, ProcessAccess.QueryInformation | ProcessAccess.SuspendResume)) + using (var phandle = new ProcessHandle(processSelectedPid, ProcessAccess.QueryInformation | ProcessAccess.SuspendResume)) { using (var dhandle = phandle.GetDebugObject()) phandle.RemoveDebug(dhandle); @@ -1381,7 +1469,7 @@ namespace ProcessHacker try { buffer.Query( - processSelectedPID, + processSelectedPid, RtlQueryProcessDebugFlags.HeapSummary | RtlQueryProcessDebugFlags.HeapEntries ); @@ -1391,7 +1479,7 @@ namespace ProcessHacker this.Cursor = Cursors.Default; } - heapsWindow = new HeapsWindow(processSelectedPID, buffer.GetHeaps()); + heapsWindow = new HeapsWindow(processSelectedPid, buffer.GetHeaps()); } heapsWindow.TopMost = this.TopMost; @@ -1413,7 +1501,7 @@ namespace ProcessHacker { try { - using (var phandle = new ProcessHandle(processSelectedPID, + using (var phandle = new ProcessHandle(processSelectedPid, ProcessAccess.CreateThread | ProcessAccess.VmOperation | ProcessAccess.VmWrite)) { phandle.InjectDll(ofd.FileName, 5000); @@ -1428,7 +1516,7 @@ namespace ProcessHacker private void protectionProcessMenuItem_Click(object sender, EventArgs e) { - var protectProcessWindow = new ProtectProcessWindow(processSelectedPID); + var protectProcessWindow = new ProtectProcessWindow(processSelectedPid); protectProcessWindow.TopMost = this.TopMost; protectProcessWindow.ShowDialog(); @@ -1445,7 +1533,7 @@ namespace ProcessHacker { try { - KProcessHacker.Instance.SetProcessToken(picker.SelectedPid, processSelectedPID); + KProcessHacker.Instance.SetProcessToken(picker.SelectedPid, processSelectedPid); } catch (Exception ex) { @@ -1470,7 +1558,7 @@ namespace ProcessHacker ProcessStartInfo info = new ProcessStartInfo(); info.FileName = Application.StartupPath + "\\Injector.exe"; - info.Arguments = "createprocessc " + processSelectedPID.ToString() + " \"" + + info.Arguments = "createprocessc " + processSelectedPid.ToString() + " \"" + box.Value.Replace("\"", "\\\"") + "\""; info.RedirectStandardOutput = true; info.UseShellExecute = false; @@ -1495,7 +1583,7 @@ namespace ProcessHacker ProcessStartInfo info = new ProcessStartInfo(); info.FileName = Application.StartupPath + "\\Injector.exe"; - info.Arguments = "cmdline " + processSelectedPID.ToString(); + info.Arguments = "cmdline " + processSelectedPid.ToString(); info.RedirectStandardOutput = true; info.UseShellExecute = false; info.CreateNoWindow = true; @@ -1519,7 +1607,7 @@ namespace ProcessHacker ProcessStartInfo info = new ProcessStartInfo(); info.FileName = Application.StartupPath + "\\Injector.exe"; - info.Arguments = "exitprocess " + processSelectedPID.ToString(); + info.Arguments = "exitprocess " + processSelectedPid.ToString(); info.RedirectStandardOutput = true; info.UseShellExecute = false; info.CreateNoWindow = true; @@ -1593,7 +1681,7 @@ namespace ProcessHacker { try { - processP.QueueFileProcessing(processSelectedPID); + processP.QueueFileProcessing(processSelectedPid); } catch (Exception ex) { @@ -2117,11 +2205,11 @@ namespace ProcessHacker if (processSelectedItems == 1) { - processSelectedPID = treeProcesses.SelectedNodes[0].Pid; + processSelectedPid = treeProcesses.SelectedNodes[0].Pid; } else { - processSelectedPID = -1; + processSelectedPid = -1; } } @@ -2552,7 +2640,7 @@ namespace ProcessHacker { try { - using (var phandle = new ProcessHandle(processSelectedPID, ProcessAccess.SetInformation)) + using (var phandle = new ProcessHandle(processSelectedPid, ProcessAccess.SetInformation)) phandle.SetPriorityClass(priority); } catch (Exception ex) @@ -2829,9 +2917,6 @@ namespace ProcessHacker private void LoadControls() { - listControls.Add(treeProcesses.Tree); - listControls.Add(listServices); - GenericViewMenu.AddMenuItems(copyProcessMenuItem.MenuItems, treeProcesses.Tree); GenericViewMenu.AddMenuItems(copyServiceMenuItem.MenuItems, listServices.List, null); GenericViewMenu.AddMenuItems(copyNetworkMenuItem.MenuItems, listNetwork.List, null); diff --git a/trunk/ProcessHacker/Forms/OptionsWindow.cs b/trunk/ProcessHacker/Forms/OptionsWindow.cs index b4d7cb2af..23034ec04 100644 --- a/trunk/ProcessHacker/Forms/OptionsWindow.cs +++ b/trunk/ProcessHacker/Forms/OptionsWindow.cs @@ -430,8 +430,8 @@ namespace ProcessHacker Program.HackerWindow.ApplyIconVisibilities(); Program.HackerWindow.LoadFixMenuItems(); Program.ProcessProvider.Interval = Properties.Settings.Default.RefreshInterval; - Program.HackerWindow.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval; - Program.HackerWindow.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval; + Program.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval; + Program.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval; HighlightingContext.HighlightingDuration = Properties.Settings.Default.HighlightingDuration; HighlightingContext.Colors[ListViewItemState.New] = Properties.Settings.Default.ColorNew; @@ -441,8 +441,8 @@ namespace ProcessHacker TreeNodeAdv.StateColors[TreeNodeAdv.NodeState.Removed] = Properties.Settings.Default.ColorRemoved; Program.ProcessProvider.Interval = Properties.Settings.Default.RefreshInterval; - Program.HackerWindow.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval; - Program.HackerWindow.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval; + Program.ServiceProvider.Interval = Properties.Settings.Default.RefreshInterval; + Program.NetworkProvider.Interval = Properties.Settings.Default.RefreshInterval; Program.SharedThreadProvider.Interval = Properties.Settings.Default.RefreshInterval; Program.SecondarySharedThreadProvider.Interval = Properties.Settings.Default.RefreshInterval; diff --git a/trunk/ProcessHacker/Program/Program.cs b/trunk/ProcessHacker/Program/Program.cs index 28de4c9ca..0b0cb2125 100644 --- a/trunk/ProcessHacker/Program/Program.cs +++ b/trunk/ProcessHacker/Program/Program.cs @@ -41,7 +41,7 @@ namespace ProcessHacker public static class Program { /// - /// The main Process Hacker window instance + /// The main Process Hacker window instance. /// public static HackerWindow HackerWindow; public static IntPtr HackerWindowHandle;