From 23e974deb514b594fd68790759d75313c5c41565 Mon Sep 17 00:00:00 2001 From: wj32 Date: Wed, 24 Dec 2008 07:26:47 +0000 Subject: [PATCH] added module provider git-svn-id: svn://svn.code.sf.net/p/processhacker/code@406 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/ProcessHacker/Components/HandleList.cs | 10 +- .../Components/ModuleList.Designer.cs | 107 +++++++ trunk/ProcessHacker/Components/ModuleList.cs | 197 +++++++++++++ .../ProcessHacker/Components/ModuleList.resx | 123 ++++++++ .../Components/ProcessTree/ProcessTree.cs | 14 +- trunk/ProcessHacker/Components/ServiceList.cs | 14 +- trunk/ProcessHacker/Components/ThreadList.cs | 15 +- .../Components/TokenProperties.cs | 29 +- .../Forms/HackerWindow.Designer.cs | 142 ++++----- trunk/ProcessHacker/Forms/HackerWindow.cs | 24 +- .../Forms/ListWindow.Designer.cs | 102 +++++++ trunk/ProcessHacker/Forms/ListWindow.cs | 35 +++ trunk/ProcessHacker/Forms/ListWindow.resx | 120 ++++++++ .../Forms/ProcessWindow.Designer.cs | 137 +++++++-- trunk/ProcessHacker/Forms/ProcessWindow.cs | 106 ++++++- trunk/ProcessHacker/Forms/ProcessWindow.resx | 274 +++++++++--------- trunk/ProcessHacker/Forms/ServiceWindow.cs | 4 +- trunk/ProcessHacker/ProcessHacker.csproj | 23 ++ .../Properties/Resources.Designer.cs | 14 + trunk/ProcessHacker/Properties/Resources.resx | 14 +- .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 2 +- .../ProcessHacker/Providers/ModuleProvider.cs | 184 ++++++++++++ .../Providers/ProcessProvider.cs | 8 +- .../ProcessHacker/Providers/ThreadProvider.cs | 14 +- trunk/ProcessHacker/Resources/folder_go.png | Bin 0 -> 694 bytes .../Win32/Handles/ProcessHandle.cs | 46 ++- trunk/ProcessHacker/app.config | 2 +- 28 files changed, 1446 insertions(+), 316 deletions(-) create mode 100644 trunk/ProcessHacker/Components/ModuleList.Designer.cs create mode 100644 trunk/ProcessHacker/Components/ModuleList.cs create mode 100644 trunk/ProcessHacker/Components/ModuleList.resx create mode 100644 trunk/ProcessHacker/Forms/ListWindow.Designer.cs create mode 100644 trunk/ProcessHacker/Forms/ListWindow.cs create mode 100644 trunk/ProcessHacker/Forms/ListWindow.resx create mode 100644 trunk/ProcessHacker/Providers/ModuleProvider.cs create mode 100644 trunk/ProcessHacker/Resources/folder_go.png diff --git a/trunk/ProcessHacker/Components/HandleList.cs b/trunk/ProcessHacker/Components/HandleList.cs index 2c65a12b6..772325fbc 100644 --- a/trunk/ProcessHacker/Components/HandleList.cs +++ b/trunk/ProcessHacker/Components/HandleList.cs @@ -122,8 +122,8 @@ namespace ProcessHacker { if (_provider != null) { - _provider.DictionaryAdded -= new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryRemoved -= new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.DictionaryAdded -= new HandleProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryRemoved -= new HandleProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } _provider = value; @@ -138,9 +138,9 @@ namespace ProcessHacker } _provider.UseInvoke = true; - _provider.Invoke = new Provider.ProviderInvokeMethod(this.BeginInvoke); - _provider.DictionaryAdded += new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.Invoke = new HandleProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new HandleProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryRemoved += new HandleProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } } } diff --git a/trunk/ProcessHacker/Components/ModuleList.Designer.cs b/trunk/ProcessHacker/Components/ModuleList.Designer.cs new file mode 100644 index 000000000..09914482b --- /dev/null +++ b/trunk/ProcessHacker/Components/ModuleList.Designer.cs @@ -0,0 +1,107 @@ +namespace ProcessHacker +{ + partial class ModuleList + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.listModules = new System.Windows.Forms.ListView(); + this.columnName = new System.Windows.Forms.ColumnHeader(); + this.columnBaseAddress = new System.Windows.Forms.ColumnHeader(); + this.columnSize = new System.Windows.Forms.ColumnHeader(); + this.columnDesc = new System.Windows.Forms.ColumnHeader(); + this.vistaMenu = new wyDay.Controls.VistaMenu(this.components); + ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).BeginInit(); + this.SuspendLayout(); + // + // listModules + // + this.listModules.AllowColumnReorder = true; + this.listModules.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnName, + this.columnBaseAddress, + this.columnSize, + this.columnDesc}); + this.listModules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listModules.FullRowSelect = true; + this.listModules.HideSelection = false; + this.listModules.Location = new System.Drawing.Point(0, 0); + this.listModules.Name = "listModules"; + this.listModules.ShowItemToolTips = true; + this.listModules.Size = new System.Drawing.Size(450, 472); + this.listModules.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.listModules.TabIndex = 3; + this.listModules.UseCompatibleStateImageBehavior = false; + this.listModules.View = System.Windows.Forms.View.Details; + // + // columnName + // + this.columnName.Text = "Name"; + this.columnName.Width = 100; + // + // columnBaseAddress + // + this.columnBaseAddress.Text = "Base Address"; + this.columnBaseAddress.Width = 80; + // + // columnSize + // + this.columnSize.Text = "Size"; + this.columnSize.Width = 70; + // + // columnDesc + // + this.columnDesc.Text = "Description"; + this.columnDesc.Width = 200; + // + // vistaMenu + // + this.vistaMenu.ContainerControl = this; + // + // ModuleList + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.listModules); + this.DoubleBuffered = true; + this.Name = "ModuleList"; + this.Size = new System.Drawing.Size(450, 472); + ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListView listModules; + private System.Windows.Forms.ColumnHeader columnBaseAddress; + private System.Windows.Forms.ColumnHeader columnName; + private System.Windows.Forms.ColumnHeader columnSize; + private System.Windows.Forms.ColumnHeader columnDesc; + private wyDay.Controls.VistaMenu vistaMenu; + } +} diff --git a/trunk/ProcessHacker/Components/ModuleList.cs b/trunk/ProcessHacker/Components/ModuleList.cs new file mode 100644 index 000000000..a72e664eb --- /dev/null +++ b/trunk/ProcessHacker/Components/ModuleList.cs @@ -0,0 +1,197 @@ +/* + * Process Hacker + * + * Copyright (C) 2008 wj32 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; +using System.Reflection; +using System.Windows.Forms; +using System.Diagnostics; + +namespace ProcessHacker +{ + public partial class ModuleList : UserControl + { + ModuleProvider _provider; + public new event KeyEventHandler KeyDown; + public new event MouseEventHandler MouseDown; + public new event MouseEventHandler MouseUp; + public new event EventHandler DoubleClick; + public event EventHandler SelectedIndexChanged; + + public ModuleList() + { + InitializeComponent(); + + listModules.KeyDown += new KeyEventHandler(ModuleList_KeyDown); + listModules.MouseDown += new MouseEventHandler(listModules_MouseDown); + listModules.MouseUp += new MouseEventHandler(listModules_MouseUp); + listModules.DoubleClick += new EventHandler(listModules_DoubleClick); + listModules.SelectedIndexChanged += new System.EventHandler(listModules_SelectedIndexChanged); + } + + private void listModules_DoubleClick(object sender, EventArgs e) + { + if (this.DoubleClick != null) + this.DoubleClick(sender, e); + } + + private void listModules_MouseUp(object sender, MouseEventArgs e) + { + if (this.MouseUp != null) + this.MouseUp(sender, e); + } + + private void listModules_MouseDown(object sender, MouseEventArgs e) + { + if (this.MouseDown != null) + this.MouseDown(sender, e); + } + + private void listModules_SelectedIndexChanged(object sender, System.EventArgs e) + { + if (this.SelectedIndexChanged != null) + this.SelectedIndexChanged(sender, e); + } + + private void ModuleList_KeyDown(object sender, KeyEventArgs e) + { + if (this.KeyDown != null) + this.KeyDown(sender, e); + } + + #region Properties + + public new bool DoubleBuffered + { + get + { + return (bool)typeof(ListView).GetProperty("DoubleBuffered", + BindingFlags.NonPublic | BindingFlags.Instance).GetValue(listModules, null); + } + set + { + typeof(ListView).GetProperty("DoubleBuffered", + BindingFlags.NonPublic | BindingFlags.Instance).SetValue(listModules, value, null); + } + } + + public override bool Focused + { + get + { + return listModules.Focused; + } + } + + public override ContextMenu ContextMenu + { + get { return listModules.ContextMenu; } + set { listModules.ContextMenu = value; } + } + + public override ContextMenuStrip ContextMenuStrip + { + get { return listModules.ContextMenuStrip; } + set { listModules.ContextMenuStrip = value; } + } + + public ListView List + { + get { return listModules; } + } + + public ModuleProvider Provider + { + get { return _provider; } + set + { + if (_provider != null) + { + _provider.DictionaryAdded -= new ModuleProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryRemoved -= new ModuleProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + } + + _provider = value; + + listModules.Items.Clear(); + + if (_provider != null) + { + foreach (ModuleItem item in _provider.Dictionary.Values) + { + provider_DictionaryAdded(item); + } + + _provider.UseInvoke = true; + _provider.Invoke = new ModuleProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new ModuleProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryRemoved += new ModuleProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + } + } + } + + #endregion + + #region Core Module List + + private void provider_DictionaryAdded(ModuleItem item) + { + HighlightedListViewItem litem = new HighlightedListViewItem(); + + litem.Name = item.BaseAddress.ToString(); + litem.Text = item.Name; + litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, "0x" + item.BaseAddress.ToString("x8"))); + litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, Misc.GetNiceSizeName(item.Size))); + litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, item.FileDescription)); + litem.ToolTipText = item.FileName; + + listModules.Items.Add(litem); + } + + private void provider_DictionaryRemoved(ModuleItem item) + { + listModules.Items[item.BaseAddress.ToString()].Remove(); + } + + #endregion + + #region Interfacing + + public void BeginUpdate() + { + listModules.BeginUpdate(); + } + + public void EndUpdate() + { + listModules.EndUpdate(); + } + + public ListView.ListViewItemCollection Items + { + get { return listModules.Items; } + } + + public ListView.SelectedListViewItemCollection SelectedItems + { + get { return listModules.SelectedItems; } + } + + #endregion + } +} diff --git a/trunk/ProcessHacker/Components/ModuleList.resx b/trunk/ProcessHacker/Components/ModuleList.resx new file mode 100644 index 000000000..cef2ba5e5 --- /dev/null +++ b/trunk/ProcessHacker/Components/ModuleList.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs index 9a488e11b..e49a20ee8 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs @@ -129,9 +129,9 @@ namespace ProcessHacker { if (_provider != null) { - _provider.DictionaryAdded -= new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified -= new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved -= new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.DictionaryAdded -= new ProcessProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified -= new ProcessProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved -= new ProcessProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } _provider = value; @@ -146,10 +146,10 @@ namespace ProcessHacker } _provider.UseInvoke = true; - _provider.Invoke = new Provider.ProviderInvokeMethod(this.BeginInvoke); - _provider.DictionaryAdded += new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified += new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.Invoke = new ProcessProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new ProcessProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified += new ProcessProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved += new ProcessProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } } } diff --git a/trunk/ProcessHacker/Components/ServiceList.cs b/trunk/ProcessHacker/Components/ServiceList.cs index a8129ab5e..c95c3f692 100644 --- a/trunk/ProcessHacker/Components/ServiceList.cs +++ b/trunk/ProcessHacker/Components/ServiceList.cs @@ -123,9 +123,9 @@ namespace ProcessHacker { if (_provider != null) { - _provider.DictionaryAdded -= new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified -= new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved -= new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.DictionaryAdded -= new ServiceProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified -= new ServiceProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved -= new ServiceProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } _provider = value; @@ -140,10 +140,10 @@ namespace ProcessHacker } _provider.UseInvoke = true; - _provider.Invoke = new Provider.ProviderInvokeMethod(this.BeginInvoke); - _provider.DictionaryAdded += new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified += new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.Invoke = new ServiceProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new ServiceProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified += new ServiceProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved += new ServiceProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } } } diff --git a/trunk/ProcessHacker/Components/ThreadList.cs b/trunk/ProcessHacker/Components/ThreadList.cs index b60a52767..44390f119 100644 --- a/trunk/ProcessHacker/Components/ThreadList.cs +++ b/trunk/ProcessHacker/Components/ThreadList.cs @@ -42,6 +42,7 @@ namespace ProcessHacker listThreads.SelectedIndexChanged += new System.EventHandler(listThreads_SelectedIndexChanged); listThreads.ContextMenu = menuThread; + GenericViewMenu.AddMenuItems(copyThreadMenuItem.MenuItems, listThreads, null); } private void listThreads_MouseUp(object sender, MouseEventArgs e) @@ -119,9 +120,9 @@ namespace ProcessHacker if (_provider != null) { - _provider.DictionaryAdded -= new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified -= new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved -= new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.DictionaryAdded -= new ThreadProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified -= new ThreadProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved -= new ThreadProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } _provider = value; @@ -136,10 +137,10 @@ namespace ProcessHacker } _provider.UseInvoke = true; - _provider.Invoke = new Provider.ProviderInvokeMethod(this.BeginInvoke); - _provider.DictionaryAdded += new Provider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified += new Provider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.Invoke = new ThreadProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new ThreadProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified += new ThreadProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved += new ThreadProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); _pid = _provider.PID; _process = Process.GetProcessById(_pid); diff --git a/trunk/ProcessHacker/Components/TokenProperties.cs b/trunk/ProcessHacker/Components/TokenProperties.cs index b59a646c1..1a8cd4f55 100644 --- a/trunk/ProcessHacker/Components/TokenProperties.cs +++ b/trunk/ProcessHacker/Components/TokenProperties.cs @@ -63,7 +63,7 @@ namespace ProcessHacker } catch (Exception ex) { - textUser.Text = ex.Message; + textUser.Text = "(" + ex.Message + ")"; } try @@ -72,17 +72,24 @@ namespace ProcessHacker } catch (Exception ex) { - textSessionID.Text = ex.Message; + textSessionID.Text = "(" + ex.Message + ")"; } - Win32.TOKEN_ELEVATION_TYPE type = token.GetElevationType(); + try + { + Win32.TOKEN_ELEVATION_TYPE type = token.GetElevationType(); - if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault) - textElevated.Text = "N/A"; - else if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeFull) - textElevated.Text = "True"; - else if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) - textElevated.Text = "False"; + if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault) + textElevated.Text = "N/A"; + else if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeFull) + textElevated.Text = "True"; + else if (type == Win32.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) + textElevated.Text = "False"; + } + catch (Exception ex) + { + textElevated.Text = "(" + ex.Message + ")"; + } try { @@ -109,7 +116,7 @@ namespace ProcessHacker } catch (Exception ex) { - textVirtualized.Text = ex.Message; + textVirtualized.Text = "(" + ex.Message + ")"; } try @@ -127,7 +134,7 @@ namespace ProcessHacker } catch (Exception ex) { - textSourceName.Text = ex.Message; + textSourceName.Text = "(" + ex.Message + ")"; } try diff --git a/trunk/ProcessHacker/Forms/HackerWindow.Designer.cs b/trunk/ProcessHacker/Forms/HackerWindow.Designer.cs index 3818ba8a6..0062764e2 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.Designer.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.Designer.cs @@ -49,7 +49,6 @@ this.suspendMenuItem = new System.Windows.Forms.MenuItem(); this.resumeMenuItem = new System.Windows.Forms.MenuItem(); this.menuItem5 = new System.Windows.Forms.MenuItem(); - this.propertiesProcessMenuItem = new System.Windows.Forms.MenuItem(); this.affinityProcessMenuItem = new System.Windows.Forms.MenuItem(); this.servicesProcessMenuItem = new System.Windows.Forms.MenuItem(); this.terminatorProcessMenuItem = new System.Windows.Forms.MenuItem(); @@ -63,6 +62,7 @@ this.runAsProcessMenuItem = new System.Windows.Forms.MenuItem(); this.launchAsUserProcessMenuItem = new System.Windows.Forms.MenuItem(); this.launchAsThisUserProcessMenuItem = new System.Windows.Forms.MenuItem(); + this.propertiesProcessMenuItem = new System.Windows.Forms.MenuItem(); this.menuItem7 = new System.Windows.Forms.MenuItem(); this.searchProcessMenuItem = new System.Windows.Forms.MenuItem(); this.copyProcessMenuItem = new System.Windows.Forms.MenuItem(); @@ -125,9 +125,11 @@ this.tabControlBig = new System.Windows.Forms.TabControl(); this.tabProcesses = new System.Windows.Forms.TabPage(); this.splitMain = new System.Windows.Forms.SplitContainer(); + this.treeProcesses = new ProcessHacker.ProcessTree(); this.tabControl = new System.Windows.Forms.TabControl(); this.tabProcess = new System.Windows.Forms.TabPage(); this.groupSearch = new System.Windows.Forms.GroupBox(); + this.buttonSearch = new wyDay.Controls.SplitButton(); this.treeMisc = new System.Windows.Forms.TreeView(); this.tabThreads = new System.Windows.Forms.TabPage(); this.tabModules = new System.Windows.Forms.TabPage(); @@ -144,7 +146,9 @@ this.columnHeader4 = new System.Windows.Forms.ColumnHeader(); this.columnHeader5 = new System.Windows.Forms.ColumnHeader(); this.tabHandles = new System.Windows.Forms.TabPage(); + this.listHandles = new ProcessHacker.HandleList(); this.tabServices = new System.Windows.Forms.TabPage(); + this.listServices = new ProcessHacker.ServiceList(); this.menuService = new System.Windows.Forms.ContextMenu(); this.goToProcessServiceMenuItem = new System.Windows.Forms.MenuItem(); this.startServiceMenuItem = new System.Windows.Forms.MenuItem(); @@ -174,10 +178,6 @@ this.propertiesHandleMenuItem = new System.Windows.Forms.MenuItem(); this.menuMisc = new System.Windows.Forms.ContextMenu(); this.copyMiscMenuItem = new System.Windows.Forms.MenuItem(); - this.treeProcesses = new ProcessHacker.ProcessTree(); - this.buttonSearch = new wyDay.Controls.SplitButton(); - this.listHandles = new ProcessHacker.HandleList(); - this.listServices = new ProcessHacker.ServiceList(); this.vistaMenu = new wyDay.Controls.VistaMenu(this.components); this.panelProc.SuspendLayout(); this.panelVirtualProtect.SuspendLayout(); @@ -384,13 +384,6 @@ this.menuItem5.Index = 3; this.menuItem5.Text = "-"; // - // propertiesProcessMenuItem - // - this.vistaMenu.SetImage(this.propertiesProcessMenuItem, global::ProcessHacker.Properties.Resources.application_form_magnify); - this.propertiesProcessMenuItem.Index = 9; - this.propertiesProcessMenuItem.Text = "&Properties..."; - this.propertiesProcessMenuItem.Click += new System.EventHandler(this.inspectProcessMenuItem_Click); - // // affinityProcessMenuItem // this.affinityProcessMenuItem.Index = 4; @@ -485,6 +478,13 @@ this.launchAsThisUserProcessMenuItem.Text = "Launch As This User..."; this.launchAsThisUserProcessMenuItem.Click += new System.EventHandler(this.launchAsThisUserProcessMenuItem_Click); // + // propertiesProcessMenuItem + // + this.vistaMenu.SetImage(this.propertiesProcessMenuItem, global::ProcessHacker.Properties.Resources.application_form_magnify); + this.propertiesProcessMenuItem.Index = 9; + this.propertiesProcessMenuItem.Text = "&Properties..."; + this.propertiesProcessMenuItem.Click += new System.EventHandler(this.inspectProcessMenuItem_Click); + // // menuItem7 // this.menuItem7.Index = 10; @@ -854,7 +854,7 @@ // // statusBar // - this.statusBar.Location = new System.Drawing.Point(0, 353); + this.statusBar.Location = new System.Drawing.Point(0, 426); this.statusBar.Name = "statusBar"; this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] { this.statusGeneral, @@ -898,7 +898,7 @@ this.tabControlBig.Location = new System.Drawing.Point(0, 0); this.tabControlBig.Name = "tabControlBig"; this.tabControlBig.SelectedIndex = 0; - this.tabControlBig.Size = new System.Drawing.Size(804, 353); + this.tabControlBig.Size = new System.Drawing.Size(804, 426); this.tabControlBig.TabIndex = 6; // // tabProcesses @@ -907,7 +907,7 @@ this.tabProcesses.Location = new System.Drawing.Point(4, 22); this.tabProcesses.Name = "tabProcesses"; this.tabProcesses.Padding = new System.Windows.Forms.Padding(3); - this.tabProcesses.Size = new System.Drawing.Size(796, 327); + this.tabProcesses.Size = new System.Drawing.Size(796, 400); this.tabProcesses.TabIndex = 0; this.tabProcesses.Text = "Processes"; this.tabProcesses.UseVisualStyleBackColor = true; @@ -926,10 +926,21 @@ // splitMain.Panel2 // this.splitMain.Panel2.Controls.Add(this.tabControl); - this.splitMain.Size = new System.Drawing.Size(790, 321); + this.splitMain.Size = new System.Drawing.Size(790, 394); this.splitMain.SplitterDistance = 348; this.splitMain.TabIndex = 3; // + // treeProcesses + // + this.treeProcesses.Dock = System.Windows.Forms.DockStyle.Fill; + this.treeProcesses.Location = new System.Drawing.Point(0, 0); + this.treeProcesses.Name = "treeProcesses"; + this.treeProcesses.Provider = null; + this.treeProcesses.Size = new System.Drawing.Size(348, 393); + this.treeProcesses.TabIndex = 4; + this.treeProcesses.SelectionChanged += new System.EventHandler(this.listProcesses_SelectionChanged); + this.treeProcesses.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listProcesses_KeyDown); + // // tabControl // this.tabControl.Controls.Add(this.tabProcess); @@ -941,7 +952,7 @@ this.tabControl.Location = new System.Drawing.Point(0, 0); this.tabControl.Name = "tabControl"; this.tabControl.SelectedIndex = 0; - this.tabControl.Size = new System.Drawing.Size(438, 321); + this.tabControl.Size = new System.Drawing.Size(438, 394); this.tabControl.TabIndex = 5; this.tabControl.SelectedIndexChanged += new System.EventHandler(this.tabControl_SelectedIndexChanged); // @@ -952,7 +963,7 @@ this.tabProcess.Location = new System.Drawing.Point(4, 22); this.tabProcess.Name = "tabProcess"; this.tabProcess.Padding = new System.Windows.Forms.Padding(3); - this.tabProcess.Size = new System.Drawing.Size(430, 295); + this.tabProcess.Size = new System.Drawing.Size(430, 368); this.tabProcess.TabIndex = 4; this.tabProcess.Text = "Process"; this.tabProcess.UseVisualStyleBackColor = true; @@ -969,6 +980,18 @@ this.groupSearch.TabStop = false; this.groupSearch.Text = "Search"; // + // buttonSearch + // + this.buttonSearch.AutoSize = true; + this.buttonSearch.Location = new System.Drawing.Point(6, 18); + this.buttonSearch.Name = "buttonSearch"; + this.buttonSearch.Size = new System.Drawing.Size(111, 23); + this.buttonSearch.SplitMenu = this.menuSearch; + this.buttonSearch.TabIndex = 3; + this.buttonSearch.Text = "Search button"; + this.buttonSearch.UseVisualStyleBackColor = true; + this.buttonSearch.Click += new System.EventHandler(this.buttonSearch_Click); + // // treeMisc // this.treeMisc.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -979,7 +1002,7 @@ this.treeMisc.Location = new System.Drawing.Point(6, 59); this.treeMisc.Name = "treeMisc"; this.treeMisc.ShowNodeToolTips = true; - this.treeMisc.Size = new System.Drawing.Size(418, 229); + this.treeMisc.Size = new System.Drawing.Size(418, 303); this.treeMisc.TabIndex = 1; // // tabThreads @@ -987,7 +1010,7 @@ this.tabThreads.Location = new System.Drawing.Point(4, 22); this.tabThreads.Name = "tabThreads"; this.tabThreads.Padding = new System.Windows.Forms.Padding(3); - this.tabThreads.Size = new System.Drawing.Size(430, 316); + this.tabThreads.Size = new System.Drawing.Size(430, 0); this.tabThreads.TabIndex = 6; this.tabThreads.Text = "Threads"; this.tabThreads.UseVisualStyleBackColor = true; @@ -998,7 +1021,7 @@ this.tabModules.Location = new System.Drawing.Point(4, 22); this.tabModules.Name = "tabModules"; this.tabModules.Padding = new System.Windows.Forms.Padding(3); - this.tabModules.Size = new System.Drawing.Size(430, 316); + this.tabModules.Size = new System.Drawing.Size(430, 368); this.tabModules.TabIndex = 0; this.tabModules.Text = "Modules"; this.tabModules.UseVisualStyleBackColor = true; @@ -1017,7 +1040,7 @@ this.listModules.Location = new System.Drawing.Point(3, 3); this.listModules.Name = "listModules"; this.listModules.ShowItemToolTips = true; - this.listModules.Size = new System.Drawing.Size(424, 310); + this.listModules.Size = new System.Drawing.Size(424, 362); this.listModules.TabIndex = 1; this.listModules.UseCompatibleStateImageBehavior = false; this.listModules.View = System.Windows.Forms.View.Details; @@ -1049,7 +1072,7 @@ this.tabMemory.Location = new System.Drawing.Point(4, 22); this.tabMemory.Name = "tabMemory"; this.tabMemory.Padding = new System.Windows.Forms.Padding(3); - this.tabMemory.Size = new System.Drawing.Size(430, 316); + this.tabMemory.Size = new System.Drawing.Size(430, 368); this.tabMemory.TabIndex = 1; this.tabMemory.Text = "Memory"; this.tabMemory.UseVisualStyleBackColor = true; @@ -1069,7 +1092,7 @@ this.listMemory.Location = new System.Drawing.Point(3, 3); this.listMemory.Name = "listMemory"; this.listMemory.ShowItemToolTips = true; - this.listMemory.Size = new System.Drawing.Size(424, 310); + this.listMemory.Size = new System.Drawing.Size(424, 362); this.listMemory.TabIndex = 2; this.listMemory.UseCompatibleStateImageBehavior = false; this.listMemory.View = System.Windows.Forms.View.Details; @@ -1106,22 +1129,43 @@ this.tabHandles.Location = new System.Drawing.Point(4, 22); this.tabHandles.Name = "tabHandles"; this.tabHandles.Padding = new System.Windows.Forms.Padding(3); - this.tabHandles.Size = new System.Drawing.Size(430, 316); + this.tabHandles.Size = new System.Drawing.Size(430, 368); this.tabHandles.TabIndex = 7; this.tabHandles.Text = "Handles"; this.tabHandles.UseVisualStyleBackColor = true; // + // listHandles + // + this.listHandles.Dock = System.Windows.Forms.DockStyle.Fill; + this.listHandles.DoubleBuffered = true; + this.listHandles.Location = new System.Drawing.Point(3, 3); + this.listHandles.Name = "listHandles"; + this.listHandles.Provider = null; + this.listHandles.Size = new System.Drawing.Size(424, 362); + this.listHandles.TabIndex = 0; + // // tabServices // this.tabServices.Controls.Add(this.listServices); this.tabServices.Location = new System.Drawing.Point(4, 22); this.tabServices.Name = "tabServices"; this.tabServices.Padding = new System.Windows.Forms.Padding(3); - this.tabServices.Size = new System.Drawing.Size(796, 348); + this.tabServices.Size = new System.Drawing.Size(796, 0); this.tabServices.TabIndex = 1; this.tabServices.Text = "Services"; this.tabServices.UseVisualStyleBackColor = true; // + // listServices + // + this.listServices.Dock = System.Windows.Forms.DockStyle.Fill; + this.listServices.DoubleBuffered = true; + this.listServices.Location = new System.Drawing.Point(3, 3); + this.listServices.Name = "listServices"; + this.listServices.Provider = null; + this.listServices.Size = new System.Drawing.Size(790, 0); + this.listServices.TabIndex = 0; + this.listServices.DoubleClick += new System.EventHandler(this.listServices_DoubleClick); + // // menuService // this.menuService.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { @@ -1318,50 +1362,6 @@ this.copyMiscMenuItem.Text = "&Copy"; this.copyMiscMenuItem.Click += new System.EventHandler(this.copyMiscMenuItem_Click); // - // treeProcesses - // - this.treeProcesses.Dock = System.Windows.Forms.DockStyle.Fill; - this.treeProcesses.Location = new System.Drawing.Point(0, 0); - this.treeProcesses.Name = "treeProcesses"; - this.treeProcesses.Provider = null; - this.treeProcesses.Size = new System.Drawing.Size(348, 320); - this.treeProcesses.TabIndex = 4; - this.treeProcesses.SelectionChanged += new System.EventHandler(this.listProcesses_SelectionChanged); - this.treeProcesses.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listProcesses_KeyDown); - // - // buttonSearch - // - this.buttonSearch.AutoSize = true; - this.buttonSearch.Location = new System.Drawing.Point(6, 18); - this.buttonSearch.Name = "buttonSearch"; - this.buttonSearch.Size = new System.Drawing.Size(111, 23); - this.buttonSearch.SplitMenu = this.menuSearch; - this.buttonSearch.TabIndex = 3; - this.buttonSearch.Text = "Search button"; - this.buttonSearch.UseVisualStyleBackColor = true; - this.buttonSearch.Click += new System.EventHandler(this.buttonSearch_Click); - // - // listHandles - // - this.listHandles.Dock = System.Windows.Forms.DockStyle.Fill; - this.listHandles.DoubleBuffered = true; - this.listHandles.Location = new System.Drawing.Point(3, 3); - this.listHandles.Name = "listHandles"; - this.listHandles.Provider = null; - this.listHandles.Size = new System.Drawing.Size(424, 310); - this.listHandles.TabIndex = 0; - // - // listServices - // - this.listServices.Dock = System.Windows.Forms.DockStyle.Fill; - this.listServices.DoubleBuffered = true; - this.listServices.Location = new System.Drawing.Point(3, 3); - this.listServices.Name = "listServices"; - this.listServices.Provider = null; - this.listServices.Size = new System.Drawing.Size(790, 342); - this.listServices.TabIndex = 0; - this.listServices.DoubleClick += new System.EventHandler(this.listServices_DoubleClick); - // // vistaMenu // this.vistaMenu.ContainerControl = this; @@ -1370,7 +1370,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(804, 375); + this.ClientSize = new System.Drawing.Size(804, 448); this.Controls.Add(this.tabControlBig); this.Controls.Add(this.statusBar); this.Controls.Add(this.panelVirtualProtect); diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 45a39736b..ad8d28039 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -2808,10 +2808,10 @@ namespace ProcessHacker listServices.List.EndUpdate(); HighlightedListViewItem.StateHighlighting = true; - serviceP.DictionaryAdded += new Provider.ProviderDictionaryAdded(serviceP_DictionaryAdded); - serviceP.DictionaryModified += new Provider.ProviderDictionaryModified(serviceP_DictionaryModified); - serviceP.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(serviceP_DictionaryRemoved); - serviceP.Updated -= new Provider.ProviderUpdateOnce(serviceP_Updated); + serviceP.DictionaryAdded += new ServiceProvider.ProviderDictionaryAdded(serviceP_DictionaryAdded); + serviceP.DictionaryModified += new ServiceProvider.ProviderDictionaryModified(serviceP_DictionaryModified); + serviceP.DictionaryRemoved += new ServiceProvider.ProviderDictionaryRemoved(serviceP_DictionaryRemoved); + serviceP.Updated -= new ServiceProvider.ProviderUpdateOnce(serviceP_Updated); if (processP.RunCount >= 1) this.Invoke(new MethodInvoker(UpdateCommon)); @@ -2819,9 +2819,9 @@ namespace ProcessHacker private void processP_Updated() { - processP.DictionaryAdded += new Provider.ProviderDictionaryAdded(processP_DictionaryAdded); - processP.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(processP_DictionaryRemoved); - processP.Updated -= new Provider.ProviderUpdateOnce(processP_Updated); + processP.DictionaryAdded += new ProcessProvider.ProviderDictionaryAdded(processP_DictionaryAdded); + processP.DictionaryRemoved += new ProcessProvider.ProviderDictionaryRemoved(processP_DictionaryRemoved); + processP.Updated -= new ProcessProvider.ProviderUpdateOnce(processP_Updated); if (processP.RunCount >= 1) this.Invoke(new MethodInvoker(UpdateCommon)); @@ -2870,7 +2870,7 @@ namespace ProcessHacker processP.Interval = RefreshInterval; treeProcesses.Provider = processP; - processP.Updated += new Provider.ProviderUpdateOnce(processP_Updated); + processP.Updated += new ProcessProvider.ProviderUpdateOnce(processP_Updated); processP.Enabled = true; HighlightedListViewItem.HighlightingDuration = Properties.Settings.Default.HighlightingDuration; @@ -2878,10 +2878,10 @@ namespace ProcessHacker listServices.List.BeginUpdate(); serviceP.Interval = RefreshInterval; listServices.Provider = serviceP; - serviceP.DictionaryAdded += new Provider.ProviderDictionaryAdded(serviceP_DictionaryAdded_Process); - serviceP.DictionaryModified += new Provider.ProviderDictionaryModified(serviceP_DictionaryModified_Process); - serviceP.DictionaryRemoved += new Provider.ProviderDictionaryRemoved(serviceP_DictionaryRemoved_Process); - serviceP.Updated += new Provider.ProviderUpdateOnce(serviceP_Updated); + serviceP.DictionaryAdded += new ServiceProvider.ProviderDictionaryAdded(serviceP_DictionaryAdded_Process); + serviceP.DictionaryModified += new ServiceProvider.ProviderDictionaryModified(serviceP_DictionaryModified_Process); + serviceP.DictionaryRemoved += new ServiceProvider.ProviderDictionaryRemoved(serviceP_DictionaryRemoved_Process); + serviceP.Updated += new ServiceProvider.ProviderUpdateOnce(serviceP_Updated); serviceP.Enabled = true; statusText.Text = "Waiting..."; diff --git a/trunk/ProcessHacker/Forms/ListWindow.Designer.cs b/trunk/ProcessHacker/Forms/ListWindow.Designer.cs new file mode 100644 index 000000000..cf0798e01 --- /dev/null +++ b/trunk/ProcessHacker/Forms/ListWindow.Designer.cs @@ -0,0 +1,102 @@ +namespace ProcessHacker +{ + partial class ListWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.buttonClose = new System.Windows.Forms.Button(); + this.listView = new System.Windows.Forms.ListView(); + this.columnName = new System.Windows.Forms.ColumnHeader(); + this.columnValue = new System.Windows.Forms.ColumnHeader(); + this.SuspendLayout(); + // + // buttonClose + // + this.buttonClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonClose.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.buttonClose.Location = new System.Drawing.Point(424, 275); + this.buttonClose.Name = "buttonClose"; + this.buttonClose.Size = new System.Drawing.Size(75, 23); + this.buttonClose.TabIndex = 0; + this.buttonClose.Text = "&Close"; + this.buttonClose.UseVisualStyleBackColor = true; + this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click); + // + // listView + // + this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnName, + this.columnValue}); + this.listView.FullRowSelect = true; + this.listView.Location = new System.Drawing.Point(12, 12); + this.listView.Name = "listView"; + this.listView.ShowItemToolTips = true; + this.listView.Size = new System.Drawing.Size(487, 257); + this.listView.TabIndex = 1; + this.listView.UseCompatibleStateImageBehavior = false; + this.listView.View = System.Windows.Forms.View.Details; + // + // columnName + // + this.columnName.Text = "Name"; + this.columnName.Width = 150; + // + // columnValue + // + this.columnValue.Text = "Value"; + this.columnValue.Width = 300; + // + // ListWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(511, 310); + this.Controls.Add(this.listView); + this.Controls.Add(this.buttonClose); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ListWindow"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "List"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button buttonClose; + private System.Windows.Forms.ListView listView; + private System.Windows.Forms.ColumnHeader columnName; + private System.Windows.Forms.ColumnHeader columnValue; + } +} \ No newline at end of file diff --git a/trunk/ProcessHacker/Forms/ListWindow.cs b/trunk/ProcessHacker/Forms/ListWindow.cs new file mode 100644 index 000000000..f53ce8b12 --- /dev/null +++ b/trunk/ProcessHacker/Forms/ListWindow.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ProcessHacker +{ + public partial class ListWindow : Form + { + public ListWindow(List> list) + { + InitializeComponent(); + + foreach (KeyValuePair kvp in list) + { + ListViewItem item = new ListViewItem(); + + item.Text = kvp.Key; + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, kvp.Value)); + + listView.Items.Add(item); + } + + listView.ContextMenu = GenericViewMenu.GetMenu(listView); + } + + private void buttonClose_Click(object sender, EventArgs e) + { + this.Close(); + } + } +} diff --git a/trunk/ProcessHacker/Forms/ListWindow.resx b/trunk/ProcessHacker/Forms/ListWindow.resx new file mode 100644 index 000000000..ff31a6db5 --- /dev/null +++ b/trunk/ProcessHacker/Forms/ListWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs b/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs index ed14db571..fedb8a908 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs @@ -41,19 +41,26 @@ this.tabControl = new System.Windows.Forms.TabControl(); this.tabGeneral = new System.Windows.Forms.TabPage(); this.groupProcess = new System.Windows.Forms.GroupBox(); + this.buttonOpenCurDir = new System.Windows.Forms.Button(); + this.buttonPEBStrings = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this.textCurrentDirectory = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.textCmdLine = new System.Windows.Forms.TextBox(); this.groupFile = new System.Windows.Forms.GroupBox(); + this.buttonOpenFileNameFolder = new System.Windows.Forms.Button(); this.pictureIcon = new System.Windows.Forms.PictureBox(); this.textFileDescription = new System.Windows.Forms.TextBox(); this.textFileName = new System.Windows.Forms.TextBox(); this.textFileCompany = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.textFileVersion = new System.Windows.Forms.TextBox(); this.tabThreads = new System.Windows.Forms.TabPage(); this.listThreads = new ProcessHacker.ThreadList(); this.tabToken = new System.Windows.Forms.TabPage(); this.tabModules = new System.Windows.Forms.TabPage(); + this.listModules = new ProcessHacker.ModuleList(); this.tabMemory = new System.Windows.Forms.TabPage(); this.tabHandles = new System.Windows.Forms.TabPage(); this.tabServices = new System.Windows.Forms.TabPage(); @@ -65,6 +72,7 @@ this.groupFile.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureIcon)).BeginInit(); this.tabThreads.SuspendLayout(); + this.tabModules.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).BeginInit(); this.SuspendLayout(); // @@ -108,7 +116,7 @@ this.tabControl.Multiline = true; this.tabControl.Name = "tabControl"; this.tabControl.SelectedIndex = 0; - this.tabControl.Size = new System.Drawing.Size(477, 291); + this.tabControl.Size = new System.Drawing.Size(477, 368); this.tabControl.TabIndex = 0; this.tabControl.TabIndexChanged += new System.EventHandler(this.tabControl_TabIndexChanged); // @@ -121,7 +129,7 @@ this.tabGeneral.Location = new System.Drawing.Point(4, 42); this.tabGeneral.Name = "tabGeneral"; this.tabGeneral.Padding = new System.Windows.Forms.Padding(3); - this.tabGeneral.Size = new System.Drawing.Size(469, 245); + this.tabGeneral.Size = new System.Drawing.Size(469, 322); this.tabGeneral.TabIndex = 2; this.tabGeneral.Text = "General"; this.tabGeneral.UseVisualStyleBackColor = true; @@ -131,15 +139,60 @@ this.groupProcess.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.groupProcess.Controls.Add(this.buttonOpenCurDir); + this.groupProcess.Controls.Add(this.buttonPEBStrings); + this.groupProcess.Controls.Add(this.label4); + this.groupProcess.Controls.Add(this.textCurrentDirectory); this.groupProcess.Controls.Add(this.label2); this.groupProcess.Controls.Add(this.textCmdLine); - this.groupProcess.Location = new System.Drawing.Point(8, 117); + this.groupProcess.Location = new System.Drawing.Point(8, 126); this.groupProcess.Name = "groupProcess"; - this.groupProcess.Size = new System.Drawing.Size(455, 122); + this.groupProcess.Size = new System.Drawing.Size(455, 190); this.groupProcess.TabIndex = 5; this.groupProcess.TabStop = false; this.groupProcess.Text = "Process"; // + // buttonOpenCurDir + // + this.buttonOpenCurDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOpenCurDir.Image = global::ProcessHacker.Properties.Resources.folder_go; + this.buttonOpenCurDir.Location = new System.Drawing.Point(425, 42); + this.buttonOpenCurDir.Name = "buttonOpenCurDir"; + this.buttonOpenCurDir.Size = new System.Drawing.Size(24, 24); + this.buttonOpenCurDir.TabIndex = 4; + this.buttonOpenCurDir.UseVisualStyleBackColor = true; + this.buttonOpenCurDir.Click += new System.EventHandler(this.buttonOpenCurDir_Click); + // + // buttonPEBStrings + // + this.buttonPEBStrings.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.buttonPEBStrings.Location = new System.Drawing.Point(6, 71); + this.buttonPEBStrings.Name = "buttonPEBStrings"; + this.buttonPEBStrings.Size = new System.Drawing.Size(102, 23); + this.buttonPEBStrings.TabIndex = 4; + this.buttonPEBStrings.Text = "PEB Strings..."; + this.buttonPEBStrings.UseVisualStyleBackColor = true; + this.buttonPEBStrings.Click += new System.EventHandler(this.buttonPEBStrings_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(6, 48); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(89, 13); + this.label4.TabIndex = 0; + this.label4.Text = "Current Directory:"; + // + // textCurrentDirectory + // + this.textCurrentDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textCurrentDirectory.Location = new System.Drawing.Point(101, 45); + this.textCurrentDirectory.Name = "textCurrentDirectory"; + this.textCurrentDirectory.ReadOnly = true; + this.textCurrentDirectory.Size = new System.Drawing.Size(318, 20); + this.textCurrentDirectory.TabIndex = 3; + // // label2 // this.label2.AutoSize = true; @@ -153,29 +206,42 @@ // this.textCmdLine.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textCmdLine.Location = new System.Drawing.Point(92, 19); + this.textCmdLine.Location = new System.Drawing.Point(101, 19); this.textCmdLine.Name = "textCmdLine"; this.textCmdLine.ReadOnly = true; - this.textCmdLine.Size = new System.Drawing.Size(357, 20); + this.textCmdLine.Size = new System.Drawing.Size(348, 20); this.textCmdLine.TabIndex = 3; // // groupFile // this.groupFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.groupFile.Controls.Add(this.buttonOpenFileNameFolder); this.groupFile.Controls.Add(this.pictureIcon); this.groupFile.Controls.Add(this.textFileDescription); this.groupFile.Controls.Add(this.textFileName); this.groupFile.Controls.Add(this.textFileCompany); + this.groupFile.Controls.Add(this.label1); this.groupFile.Controls.Add(this.label3); this.groupFile.Controls.Add(this.textFileVersion); this.groupFile.Location = new System.Drawing.Point(6, 6); this.groupFile.Name = "groupFile"; - this.groupFile.Size = new System.Drawing.Size(457, 105); + this.groupFile.Size = new System.Drawing.Size(457, 114); this.groupFile.TabIndex = 4; this.groupFile.TabStop = false; this.groupFile.Text = "File"; // + // buttonOpenFileNameFolder + // + this.buttonOpenFileNameFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOpenFileNameFolder.Image = global::ProcessHacker.Properties.Resources.folder_go; + this.buttonOpenFileNameFolder.Location = new System.Drawing.Point(427, 80); + this.buttonOpenFileNameFolder.Name = "buttonOpenFileNameFolder"; + this.buttonOpenFileNameFolder.Size = new System.Drawing.Size(24, 24); + this.buttonOpenFileNameFolder.TabIndex = 4; + this.buttonOpenFileNameFolder.UseVisualStyleBackColor = true; + this.buttonOpenFileNameFolder.Click += new System.EventHandler(this.buttonOpenFileNameFolder_Click); + // // pictureIcon // this.pictureIcon.Location = new System.Drawing.Point(6, 19); @@ -202,10 +268,10 @@ // this.textFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textFileName.Location = new System.Drawing.Point(101, 76); + this.textFileName.Location = new System.Drawing.Point(101, 83); this.textFileName.Name = "textFileName"; this.textFileName.ReadOnly = true; - this.textFileName.Size = new System.Drawing.Size(350, 20); + this.textFileName.Size = new System.Drawing.Size(320, 20); this.textFileName.TabIndex = 3; // // textFileCompany @@ -221,10 +287,19 @@ this.textFileCompany.TabIndex = 2; this.textFileCompany.Text = "File Company"; // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 60); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(77, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Image Version:"; + // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(6, 79); + this.label3.Location = new System.Drawing.Point(6, 86); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(89, 13); this.label3.TabIndex = 0; @@ -234,14 +309,11 @@ // this.textFileVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textFileVersion.BackColor = System.Drawing.SystemColors.Window; - this.textFileVersion.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textFileVersion.Location = new System.Drawing.Point(6, 57); + this.textFileVersion.Location = new System.Drawing.Point(101, 57); this.textFileVersion.Name = "textFileVersion"; this.textFileVersion.ReadOnly = true; - this.textFileVersion.Size = new System.Drawing.Size(445, 13); + this.textFileVersion.Size = new System.Drawing.Size(350, 20); this.textFileVersion.TabIndex = 2; - this.textFileVersion.Text = "File Version"; // // tabThreads // @@ -249,7 +321,7 @@ this.tabThreads.ImageKey = "hourglass"; this.tabThreads.Location = new System.Drawing.Point(4, 42); this.tabThreads.Name = "tabThreads"; - this.tabThreads.Size = new System.Drawing.Size(469, 245); + this.tabThreads.Size = new System.Drawing.Size(469, 322); this.tabThreads.TabIndex = 3; this.tabThreads.Text = "Threads"; this.tabThreads.UseVisualStyleBackColor = true; @@ -261,7 +333,7 @@ this.listThreads.Location = new System.Drawing.Point(0, 0); this.listThreads.Name = "listThreads"; this.listThreads.Provider = null; - this.listThreads.Size = new System.Drawing.Size(469, 245); + this.listThreads.Size = new System.Drawing.Size(469, 322); this.listThreads.TabIndex = 0; // // tabToken @@ -270,27 +342,38 @@ this.tabToken.Location = new System.Drawing.Point(4, 42); this.tabToken.Name = "tabToken"; this.tabToken.Padding = new System.Windows.Forms.Padding(3); - this.tabToken.Size = new System.Drawing.Size(469, 245); + this.tabToken.Size = new System.Drawing.Size(469, 322); this.tabToken.TabIndex = 1; this.tabToken.Text = "Token"; this.tabToken.UseVisualStyleBackColor = true; // // tabModules // + this.tabModules.Controls.Add(this.listModules); this.tabModules.ImageKey = "page_white_wrench"; this.tabModules.Location = new System.Drawing.Point(4, 42); this.tabModules.Name = "tabModules"; - this.tabModules.Size = new System.Drawing.Size(469, 245); + this.tabModules.Size = new System.Drawing.Size(469, 322); this.tabModules.TabIndex = 6; this.tabModules.Text = "Modules"; this.tabModules.UseVisualStyleBackColor = true; // + // listModules + // + this.listModules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listModules.DoubleBuffered = true; + this.listModules.Location = new System.Drawing.Point(0, 0); + this.listModules.Name = "listModules"; + this.listModules.Provider = null; + this.listModules.Size = new System.Drawing.Size(469, 322); + this.listModules.TabIndex = 0; + // // tabMemory // this.tabMemory.ImageKey = "database"; this.tabMemory.Location = new System.Drawing.Point(4, 42); this.tabMemory.Name = "tabMemory"; - this.tabMemory.Size = new System.Drawing.Size(469, 245); + this.tabMemory.Size = new System.Drawing.Size(469, 322); this.tabMemory.TabIndex = 4; this.tabMemory.Text = "Memory"; this.tabMemory.UseVisualStyleBackColor = true; @@ -300,7 +383,7 @@ this.tabHandles.ImageKey = "connect"; this.tabHandles.Location = new System.Drawing.Point(4, 42); this.tabHandles.Name = "tabHandles"; - this.tabHandles.Size = new System.Drawing.Size(469, 245); + this.tabHandles.Size = new System.Drawing.Size(469, 322); this.tabHandles.TabIndex = 5; this.tabHandles.Text = "Handles"; this.tabHandles.UseVisualStyleBackColor = true; @@ -310,7 +393,7 @@ this.tabServices.ImageKey = "cog"; this.tabServices.Location = new System.Drawing.Point(4, 42); this.tabServices.Name = "tabServices"; - this.tabServices.Size = new System.Drawing.Size(469, 245); + this.tabServices.Size = new System.Drawing.Size(469, 322); this.tabServices.TabIndex = 7; this.tabServices.Text = "Services"; this.tabServices.UseVisualStyleBackColor = true; @@ -335,7 +418,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(477, 291); + this.ClientSize = new System.Drawing.Size(477, 368); this.Controls.Add(this.tabControl); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.Menu = this.mainMenu; @@ -351,6 +434,7 @@ this.groupFile.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureIcon)).EndInit(); this.tabThreads.ResumeLayout(false); + this.tabModules.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.vistaMenu)).EndInit(); this.ResumeLayout(false); @@ -383,5 +467,12 @@ private System.Windows.Forms.GroupBox groupFile; private System.Windows.Forms.GroupBox groupProcess; private System.Windows.Forms.TabPage tabServices; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button buttonPEBStrings; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textCurrentDirectory; + private System.Windows.Forms.Button buttonOpenFileNameFolder; + private System.Windows.Forms.Button buttonOpenCurDir; + private ModuleList listModules; } } \ No newline at end of file diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.cs b/trunk/ProcessHacker/Forms/ProcessWindow.cs index ff65d458f..48619c92f 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.cs @@ -36,6 +36,7 @@ namespace ProcessHacker private Process _process; private ThreadProvider _threadP; + private ModuleProvider _moduleP; private TokenProperties _tokenProps; @@ -76,21 +77,51 @@ namespace ProcessHacker listThreads.Provider = _threadP; _threadP.Enabled = true; + _moduleP = new ModuleProvider(_pid); + _moduleP.Interval = Properties.Settings.Default.RefreshInterval; + _moduleP.RunOnceAsync(); + listModules.Provider = _moduleP; + _moduleP.Enabled = true; + try { pictureIcon.Image = Win32.GetProcessIcon(_process, true).ToBitmap(); } - catch { } + catch { pictureIcon.Image = global::ProcessHacker.Properties.Resources.Process.ToBitmap(); } try { - FileVersionInfo info = FileVersionInfo.GetVersionInfo(Misc.GetRealPath(_process.MainModule.FileName)); + string fileName; + + if (_pid == 4) + fileName = Misc.GetKernelFileName(); + else + fileName = Misc.GetRealPath(_process.MainModule.FileName); + + FileVersionInfo info = FileVersionInfo.GetVersionInfo(fileName); textFileDescription.Text = info.FileDescription; textFileCompany.Text = info.CompanyName; textFileVersion.Text = info.FileVersion; textFileName.Text = info.FileName; } - catch - { } + catch (Exception ex) + { + textFileDescription.Text = "(" + ex.Message + ")"; + textFileCompany.Text = ""; + } textCmdLine.Text = _processItem.CmdLine; + + try + { + using (Win32.ProcessHandle phandle + = new Win32.ProcessHandle(_pid, Program.MinProcessQueryRights | Win32.PROCESS_RIGHTS.PROCESS_VM_READ)) + { + textCurrentDirectory.Text = + phandle.GetPEBString(Win32.ProcessHandle.PEBOffset.CurrentDirectoryPath); + } + } + catch (Exception ex) + { + textCurrentDirectory.Text = "(" + ex.Message + ")"; + } } private void ProcessWindow_FormClosing(object sender, FormClosingEventArgs e) @@ -150,9 +181,76 @@ namespace ProcessHacker private void tabControl_TabIndexChanged(object sender, EventArgs e) { _threadP.Enabled = false; + _moduleP.Enabled = false; if (tabControl.SelectedTab == tabThreads) _threadP.Enabled = true; + else if (tabControl.SelectedTab == tabModules) + _moduleP.Enabled = true; + } + + private void buttonPEBStrings_Click(object sender, EventArgs e) + { + List> list = new List>(); + + try + { + using (Win32.ProcessHandle ph + = new Win32.ProcessHandle(_pid, Program.MinProcessQueryRights | Win32.PROCESS_RIGHTS.PROCESS_VM_READ)) + { + list.Add(new KeyValuePair("Command Line", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.CommandLine))); + list.Add(new KeyValuePair("Current Directory Path", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.CurrentDirectoryPath))); + list.Add(new KeyValuePair("Desktop Name", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.DesktopName))); + list.Add(new KeyValuePair("Path", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.DllPath))); + list.Add(new KeyValuePair("Image File Name", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.ImagePathName))); + list.Add(new KeyValuePair("Runtime Data", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.RuntimeData))); + list.Add(new KeyValuePair("Shell Info", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.ShellInfo))); + list.Add(new KeyValuePair("Window Title", + ph.GetPEBString(Win32.ProcessHandle.PEBOffset.WindowTitle))); + } + + ListWindow window = new ListWindow(list); + + window.TopMost = this.TopMost; + window.ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonOpenFileNameFolder_Click(object sender, EventArgs e) + { + try + { + Process.Start("explorer.exe", "/select," + textFileName.Text); + } + catch (Exception ex) + { + MessageBox.Show("Could not start process:\n\n" + ex.Message, "Process Hacker", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonOpenCurDir_Click(object sender, EventArgs e) + { + try + { + Process.Start("explorer.exe", "/select," + textCurrentDirectory.Text); + } + catch (Exception ex) + { + MessageBox.Show("Could not start process:\n\n" + ex.Message, "Process Hacker", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } } } } diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.resx b/trunk/ProcessHacker/Forms/ProcessWindow.resx index 42a23df6f..240fbebe0 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.resx +++ b/trunk/ProcessHacker/Forms/ProcessWindow.resx @@ -130,145 +130,141 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAY - IAAAAk1TRnQBSQFMAgEBBwEAAQwBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA - AwABIAMAAQEBAAEgBgABICoAAwoBDQMiATEDIAEvAwUBBxgAAxEBFwGrAWEBNQH/AYUBXwFIAfYDKQE/ - NAADBgEIAUEBQwFEAW4BXAFoAXYBswFkAYABoAHdAVsBigG3AfQBTQGGAbwB/QE9AXkBswH/AS0BbgGo - Af8BIwFjAZ4B/QEgAV0BjgH0ATABWAF7Ad0BQwFWAWMBswE9AUABQgFuAwYBCFAAAxgBIQNQAZ0DdwHw - A6EB/wOrAf8DpwH/A5UB/wNqAecDSgGKAxABFgwAAboBcwFCAf8BwAGJAVcB/wG/AYkBWgH/Aa8BZQE/ - Af8DKgFBMAABYwFzAYUBxAGHAbcB4AH/AZUBxgHmAf8BmwHNAekB/wGcAc0B6QH/AZkBxwHnAf8BlQHB - AeQB/wGOAbgB4AH/AYkBsAHdAf8BgQGnAdcB/wFxAZsBzwH/AVsBjAHCAf8BPAF2Aa4B/wE/AVkBbgHE - TAADLwFKA4IB9APOAf8D7QH/A/QB/wP1Af8D9AH/A+8B/wPiAf8DugH/A2kB5wMkATUIAAHDAYgBUQH/ - Ac8BogF1Af8BzQGiAYAB/wHAAYwBXgH/AbABagFBAf8CTgFNAZUDMQFOAyYBOQMWAR4DAwEEHAABYwFz - AYUBxAGYAbkB1AH/AcUBxwHEAf8B7AHYAccB/wH2AesB4wH/AfoB9QHxAf8B8wHnAd4B/wHfAb8BpgH/ - AdABpAGAAf8BywGaAXIB/wHIAZcBbwH/AaMBkwGMAf8BYAF9AZwB/wE/AVkBbgHETAADcgHqA94B/wPz - Af8D2wH/A9IB/wPbAf8D1gH/A8AB/wPJAf8D5gH/A8QB/wNpAeoIAANAAXEBzAGZAWkB/wHQAaMBgQH/ - Ac8BpAGDAf8BygGeAXMB/wG8AYUBVQH/Aa8BaQFBAf8BpwFcATgB/wGeAU8BMAH/AVsCWAHGAwcBCRgA - Ah4BHQEqAeYBwwGlAf8B7wHWAcAB/wH7AfIB6gH/Af4B/AH6Av8B/gH9Af8B/gH9AfwB/wH8AfYB8AH/ - AfgB6AHZAf8B9gHjAdEB/wH2AeIBzgH/AeYByAGtAf8BzgGgAXkB/wMdASpMAANyAeoD8AH/A94B/wPU - Af8D0gH/A9sB/wPWAf8DvwH/A7AB/wOzAf8D3gH/A2oB6gwAA0EBcgHOAZ0BbgH/AdUBrAGMAf8BywGb - AW4B/wHMAaABdAH/AcgBmwFuAf8BxQGVAWcB/wHAAY8BYQH/AawBZQFAAf8DQgF2HAABgAF1AWwBuQHt - AdMBuwH/AfoB8AHlAf8B/QH5AfUB/wH+AfwB+gH/Af4B/QH8Af8B/QH5AfQB/wH2AeMBzwH/AfcB5QHT - Af8B9gHjAdEB/wHdAbkBmgH/AXgBaQFgAbhQAANyAeoD8gH/A+IB/wPYAf8D1QH/A9wB/wPYAf8DwAH/ - A7MB/wO3Af8D4AH/A2wB6hAAA1YBsQHTAagBhgH/AdYBrAGOAf8ByQGYAWkB/wHEAZABYAH/Ab8BigFX - Af8BwgGPAV8B/wG/AYsBXAH/AWkBXwFHAfsDHQEpHAABdgFuAWcBsAHmAcUBqQH+AfcB6gHeAf8B/gH6 - AfcB/wH+AfwB+QH/Af0B9wHyAf8B+gHtAeIB/wHrAdABtwH/Ac4BnwF+Af4BcAFlAV0BrlQAA3IB6gPz - Af8D5wH/A90B/wPZAf8D4AH/A9sB/wPEAf8DuAH/A7sB/wPhAf8DbgHqEAADMQFOAdQBowF2Af8B3AG1 - AZgB/wHQAaEBdQH/AcwBmgFsAf8BzwGkAYMB/wHIAZoBbgH/AXUBjAFcAf8BYgG4AXIB/wGEAVABMgH7 - A1QBrwMHAQkYAAMnAToBswGiAZEB4QHzAeIB0gH/AfwB9AHtAf8B+wHxAecB/wHpAcwBtQH/AaMBiQF3 - AdwDJgE4WAADcgHqA/QB/wPqAf8D4QH/A90B/wPjAf8D3gH/A8kB/wO9Af8DvwH/A+IB/wNvAeoQAAMm - ATkB2wGrAYkB/wHhAb0BogH/AdYBqgGHAf8B2QGzAZQB/wHOAZ8BcgH/AY0BgQFfAfsBZQG8AXQB/wGT - AWcBPgH/AbABbQFHAf8BpAFaATkB/wFiAVwBWgHaAwMBBBwAAZABhAF4AccB9AHjAdAB/wHzAd8BzQH/ - AYgBeQFvAcNgAAN0AeoD9QH/A+4B/wPmAf8D4gH/A+YB/wPhAf8DzQH/A8IB/wPCAf8D4wH/A28B6hAA - AxYBHgHgAbEBjwH/AeYBxAGrAf8B4gG/AaQB/wHYAa0BjgH/AZgBfgFpAfoDQwF3AY0BcAE8AfwBuwGE - AVUB/wHAAY8BYQH/AbwBigFZAf8BnAFKAS0B/wMWAR4cAAGMAX8BdAHDAfQB4QHOAf8B8wHfAcwB/wGH - AXoBbQHCYAADdgHqA/YB/wPrAf8D3gH/A9YB/wPVAf8D0QH/A8MB/wO8Af8DwAH/A+UB/wNvAeoQAAMD - AQQBbQFmAWMB2gHkAbsBnwH/AeQBuwGfAf8BiQGPAXkB/AFuAcEBdwH/AZsBfAFPAfwBxwGWAWcB/wHL - AZ4BcwH/AbwBhQFRAf8BwwGSAWQB/wGmAVsBNwH/AyYBORQAAyYBOAGxAZ0BjQHdAfMB3QHJAf8B+gHu - AeIB/wH5AesB3gH/Ae0B0AG2Af8BpQGQAX4B2wMmAThYAAN3AeoD9wH/A+cB/wPvAf8D9gH/A/sB/wP6 - Af8D8AH/A94B/wPDAf8D5gH/A3AB6hQAAwcBCQNUAa8BnQGVAYgB+QFvAcUBggH/AbUBsAGBAf8B2AGw - AZIB/wHXAa4BjwH/AckBlwFnAf8BwwGPAV4B/wHIAZsBbgH/AbEBaQFCAf8DMQFOEAABeAFyAWwBrwHy - AdMBtgH+AfkB7AHgAf8B/QH4AfQB/wH7AfAB5gH/AfgB5wHXAf8B+QHrAd4B/wHyAdoBxQH/Ad8BtgGU - Af4BcwFqAWMBrlQAA3cB6gP4Af8D/hn/A/sB/wPqAf8DcQHqHAADGwEmAbkBqwGGAf0B4gG+AaMB/wHf - AbcBmgH/AdUBqAGGAf8B0AGhAXUB/wHLAZoBawH/Ac4BogGAAf8BvwGLAVoB/wJOAU0BlQwAAYMBfAF0 - AbgB+QHjAc0B/wH7AfMB7AH/Af4B+gH3Af8B/gH7AfgB/wH8AfUB7QH/AfcB5gHVAf8B9gHhAcwB/wH5 - AewB3wH/AfkB6wHdAf8B6wHOAbQB/wF8AXIBaQG4UAADWQG/A+EB/wP+Gf8D+wH/A88B/wNSAaEgAANC - AXYB5AG6AZ0B/wHmAcQBqwH/AeIBvgGkAf8B3gG5AZwB/wHZAbIBkwH/AdEBowF3Af8B0QGmAYUB/wG7 - AXcBSQH/AykBPwQAAx4BKgHAAcUBzQH/AZoBtwHcAf8BewGmAdUB/wFhAZUBygH/AU0BhwG+Af8BPQF5 - AbMB/wEtAW4BqAH/ASEBZQGfAf8BHAFhAZgB/wEqAWkBmgH/AVEBgwGnAf8BiAGUAZoB/wMdASpMAAMd - ASoDYAHRA9AB/wPoAf8D8wH/A/0B/wP8Af8D7QH/A+AB/wPCAf8DWwHDAxQBGyAAAwcBCQFcAlsBxgHj - AbQBkwH/Ad8BsQGOAf8B2gGrAYkB/wHaAa0BjAH/AdwBtQGYAf8B1wGvAZAB/wHMAZsBbAH/AaABcAFM - AfoEAAFrAX4BlAHRAYcBtwHgAf8BlQHGAeYB/wGbAc0B6QH/AZwBzQHpAf8BmQHHAecB/wGVAcEB5AH/ - AY4BuAHgAf8BiQGwAd0B/wGBAacB1wH/AXEBmwHPAf8BWwGMAcIB/wE8AXYBrgH/AT4BXAF1AdFQAAMF - AQcDNQFVA1QBrgNjAdYDmwH7A5kB+QNcAc0DUgGpAy0BRgMCAQMoAAMDAQQDFgEeAyYBOQMxBE4BlAHY - AacBggH/AdcBrAGLAf8B0wGnAYQB/wGTAXIBVgH2BAABYwFzAYUBxAGHAbcB4AH/AZUBxgHmAf8BnQHP - AeoB/wGhAdMB7AH/AaAB0QHrAf8BmwHKAegB/wGWAcIB5QH/AY8BugHiAf8BhwGxAd0B/wF3AaMB1AH/ - AV8BkAHEAf8BPAF2Aa4B/wE/AVkBbgHEtAADKQE+AbcBkwFlAfsBmwF9AWIB9gMuAUgEAAMGAQgBQQFD - AUQBbgFcAWgBdgGzAWkBhAGiAd0BbAGUAcMB9AFuAZ8B0gH9AWcBmQHRAf8BWgGQAcgB/wFNAYYBvAH9 - AUIBdwGmAfQBQwFoAYoB3QFIAVsBaAGzAT4BQAFCAW4DBgEIRAABCgGdAdkB/wEFAZkB2AH/AQABlAHX - Af8BAAGQAdYB/wEAAYwB1QH/AQABiAHUAf8BAAGEAdMB/wEAAYAB0gH/AQABUAHRAf8BAAFNAdEB/wEA - AUoB0AH/AQABRwHPAf8BAAFEAc8B/wEAAUIBzgH/YAADOwFjA1gBvwNXAb8DOwFjIAADFQEdAyMBNAMk - ATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDIwEzAxUBHQERAaMB2gH/AbwB6wH6 - Af8BvAHrAfwB/wG/Ae4B/gH/AcYB9AL/Ac4B+AL/AdMB+gL/AdAB+AL/AccB8gL/AboB6QH8Af8BswHk - AfkB/wGwAeIB+AH/AbAB4gH4Af8BAAFFAc8B/1QAAx0BKQMKAQ4DAQECA1wB6gO9Af8DsgH/A1wB6gMB - AQIDCgEOAx0BKRQAAyMBNAOwAfUD5QH9A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D5QH9 - A6gB8wMjATMBFwGoAdsB/wG/AewB+wH/AS0BzwH1Af8BFQGwAewB/wEAARUBLgH/AQABNQGJAf8BHQGJ - Ab4B/wEcAZoByAH/ARwBrgHnAf8BCwGlAeYB/wEAAZoB4QH/AQwBuAHuAf8BsQHjAfgB/wEAAUkB0AH/ - CAADUgGpAcMBjgFAAf8BwAGLAT4B/wG+AYgBPAH/AbsBhQE5Af8BuQGDATcB/wG0AVYBNAH/AbIBVAEy - Af8BsQFTATAB/wGuAVEBLwH/Aa0BTgEuAf8BqwFNASwB/wGpAUsBKwH/AakBSQEpAf8DUgGpDAADUAGb - A0MB/QNkAecDEgEZA2QB5wPLAf8DxwH/A2IB5wMSARkDXAHnA0AB/QNPAZsIAAM3AVsBigFqAVIB8AGb - AWoBSQH2AeUBtwGaAf8B+wL6Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D5QH9 - AyQBNgEdAa0B3AH/AcEB7gH7Af8BMwHTAfcB/wFAAdsB/AH/AQABOwGFAf8BlAHHAfkB/wGRAckB+QH/ - ARUBhQHJAf8BAAE+Aa4B/wEnAb0B7AH/ARoBvgHvAf8BEAG6Ae4B/wGzAeMB+QH/AQABTQHRAf8IAAHI - AZIBRDX/AakBSgEpAf8IAANEAXsDvAH/A94B/wOmAf8DZQH0A38B/gPEAf8DwgH/A20B/gNlAfQDpgH/ - A9IB/wOAAf8DRAF7BAABjAFwAWIB7wHmAbgBnAH/AekBvwGlAf8B3AGbAWwB/wHlAbgBnQH/A/wB/wP8 - Af8D/AH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wMkATYBIgGyAd0B/wHDAe8B+wH/ATkB1gH4 - Af8BIAG2AewB/wEXAYkBqgH/AeAB8gL/ASgBmgHYAf8BAAFOAb4B/wEdAZgBxQH/AQkBhgHFAf8BBwGb - Ad4B/wEWAb4B7wH/AbQB5QH5Af8BAAFSAdIB/wgAAcoBlAFGC/8B/gP/Af0B/wL+Af0B/wL+AfwB/wL+ - AfwB/wL+AfwB/wL+AfwB/wL+AfoB/wL+AfoB/wL8AfkF/wGqAUsBKwH/CAADRQF9A38B/gPVAf8DxQH/ - A8sB/wPRAf8DyQH/A8cB/wPMAf8DxQH/A70B/wPLAf8DbgH+A0UBfQQAAasBiAFtAfcB6wHEAa0B/wHs - AcgBsgH/AeoBwQGpAf8B3gGeAXAB/wHnAbsBoQH/A/wB/wP7Af8D+wH/A/oB/wP6Af8D+gH/A/oB/wP6 - Af8D/AH/AyQBNgEnAbcB3gH/AcYB8AH8Af8BPgHZAfgB/wFQAeIB/QH/ATcBtwHZAf8BTgG2AdUB/wGQ - AbcB0QH/ASkByQHkAf8BLwHfAfUB/wFMAdAB7QH/ARYBmAHcAf8BGAG6Ae0B/wG2AecB+QH/AQABgwHT - Af8IAAHMAZcBRwf/AfwD/wH9Af8C/gH8Af8C/gH8Af8C/gH7Af8C/QH6Af8C/QH6Af8C/QH6Af8C/QH6 - Af8C/AH3Af8C+wH2Bf8BrAFNASwB/wwAA0gBhQPFAf8DwQH/A8UB/wPHAf8DqgH/A6cB/wPBAf8DvgH/ - A7UB/wOqAf8DSAGFCAADQgF1AbQBjAFqAfkB7AHHAbAB/wHtAcoBtQH/AesBwwGrAf8B3gGhAXQB/wHn - AboBnwH/A/sB/wP7Af8D+wH/A/oB/wP6Af8D+AH/A/gB/wP8Af8DJAE2ASwBuwHfAf8BxwHxAfwB/wFD - AdwB+QH/ASoBuwHtAf8BNQG9Ae8B/wFFAcYB5wH/AUYBuAHWAf8BwgH2Af0B/wE3Ad8B9wH/ATEB4gH4 - Af8BTQHTAfAB/wEXAZcB3AH/AagB3AH1Af8BAAGIAdQB/wgAAdEBnAFLBf8C/gH8Af8C/gH8Af8C/gH8 - Af8C/QH7Af8C/QH7Af8C/QH6Af8C/QH4Af8C+wH5Af8B+wH6AfcB/wH7AfoB9gH/AfsB+AH0Bf8BsAFS - ATAB/wQAA1wBzQNfAeMDYQHuA88B/wPGAf8DzAH/A1sBxgMsAUQDLAFEA1sBxgPBAf8DvAH/A7kB/wNh - Ae4DWQHjA1oBzQQAA0MBeAHQAZYBfwH+Ae0ByAGzAf8B7QHNAbgB/wHpAb4BowH/AdYBjgFcAf8D/AH/ - A/wB/wP8Af8D+wH/A/kB/wP5Af8D+AH/A/wB/wMkATYBMAG/AeAB/wHIAfMB/AH/AUkB3wH5Af8BiQHm - Af0B/wGVAecC/wGaAeUC/wFNAcoB5wH/AUsBywHnAf8BxwH3Af0B/wEyAdwB9QH/AS4B4QH3Af8BTwHU - AfEB/wEcAZkB3gH/AQABjQHWAf8IAAHUAZ4BTQX/Av4B/AH/Av0B+wH/Av0B/AH/Av0B+wH/Av0B+QH/ - AvwB+AH/AfsB+QH3Af8B+wH5AfUB/wH7AfgB9AH/AfsB9wHyAf8B+wH1AfIF/wGyAVQBMgH/BAADqAH9 - A+IB/wPSAf8DxgH/A80B/wOxAf8DLAFECAADLAFEA6gB/wPCAf8DtwH/A8AB/wPSAf8DQAH9BwABAQNM - AZIB4AGpAYgB/wHrAccBsAH/Ad0BoQF0Af8BvAGlAZUB/wOsAf8D0AH/A9QB/wPvAf8D+QH/A/YB/wP2 - Af8D/AH/AyQBNgE0AcIB4QH/AckB8wH8Af8BywHzAf0B/wHUAfYB/gH/AdcB9gL/AdgB9AL/AeAB+AL/ - AakB4wH1Af8BTQHTAe4B/wHHAfcB/QH/ATMB3AH1Af8BLwHiAfcB/wFOAdYB8gH/ARIBmAHeAf8DIQEw - BAAB1QGgAU4F/wL9AfwB/wL9AfsB/wL9AfoB/wL8AfkB/wH8AfsB9wH/AfsB+QH1Af8B+wH4AfQB/wH7 - AfcB8wH/AfsB9QHyAf8B+gHzAe8B/wH4AfIB7AX/AbUBVgE0Af8EAAOoAf0D6QH/A9YB/wPJAf8DzgH/ - A6UB/wMsAUQIAAMsAUQDrAH/A8QB/wO6Af8DxgH/A90B/wNBAf0HAAEBAyQBNgHwAdYBxgH/Ad4BrQGQ - Af8BxAGvAaMB/wPVAf8DuwH/A6YB/wOgAf8DkAH/A8kB/wPzAf8D8gH/A/wB/wMkATYBNQHDAeEB/wGI - AaABqAH/A5EB/wOOAf8BLgG5AdwB/wEpAbgB3wH/ASUBtQHeAf8BIQGxAd0B/wETAbAB3gH/AVAB1AHu - Af8BxAH2Af0B/wFAAd0B9gH/AUEBygHtAf8BNwGjAdcB/wFeAmQB7AMbASYB2AGiAVEF/wL9AfoB/wL8 - AfoB/wH8AfsB+QH/AfsB+gH2Af8B+wH4AfUB/wH7AfcB9AH/AfsB9gHxAf8B+AH0Ae4B/wH3AfIB6wH/ - AfcB8AHqAf8B9gHsAegF/wG3AYEBNgH/BAADXAHNA18B4wNhAe4D2AH/A80B/wO8Af8DWwHGAywBRAMs - AUQDWwHGA8MB/wPCAf8DzQH/A2EB7gNfAeMDXAHNBwABAQMkATYD/AH/A/sB/wOsAf8DywH/A9IB/wPJ - Af8D0gH/A8YB/wOPAf8D7wH/A+0B/wP8Af8DJAE2BAADWwHDA8YB/wOUAf8DBgEIEAADNwFaAVIB0wHr - Af8BsgHjAfkB/wGLAcAB5wH/Aa4B0wH2Af8BxAHgAfwB/wFmAm0B9wHZAaMBUQX/AfwB+wH5Af8B/AH7 - AfgB/wH7AfkB9wH/AfsB9wH0Af8B+gH3AfIB/wH5AfUB8AH/AfcB8wHtAf8B9gHvAeoB/wH1AesB5wH/ - AfMB6gHkAf8B8gHnAd4F/wG6AYUBOAH/DAADSAGFA9QB/wPMAf8DyQH/A7oB/wOcAf8DoQH/A8IB/wPG - Af8DwQH/A7cB/wNIAYUPAAEBAyQBNgP8Af8D+wH/A9sB/wOyAf8D1gH/A6AB/wOSAf8DwAH/A4oB/wPq - Af8D5gH/A/wB/wMkATYEAANUAa4DxAH/A6EB/wMdASkQAAMdASkBOAGZAakB/wFLAb4B5wH/AbQB0gHw - Af8B5QHzAv8BrAHSAe8B/wFXAl8B6AHbAaQBUjX/Ab0BhwE7Af8IAANFAX0DhwH+A9wB/wPUAf8D2QH/ - A9sB/wPWAf8D1AH/A9kB/wPSAf8DywH/A8gB/wN5Af4DRQF9CwABAQMkATYD/AH/A/kB/wPaAf8DtQH/ - A+YB/wOaAf8DsAH/A68B/wO9Af8D/AH/A/wB/wP8Af8DJAE2BAADQgF1A7oB/wO/Af8DXgHdAxYBHwME - AQUDBAEFAxYBHwNlAeUDqAH/AU8BpAGzAf8BLAGlAdgB/wGFAbEB2wH/ARoBnQHQAf8DOAFeAdwBpwFT - Af8B3AGnAVMB/wHcAacBUwH/AdwBpwFTAf8B3AGnAVMB/wHcAacBUwH/AdwBpwFTAf8B3AGnAVMB/wHc - AacBUwH/AdwBpwFTAf8B3AGnAVMB/wHcAacBUwH/AdwBpwFTAf8B3AGnAVMB/wHAAYsBPgH/CAADRAF7 - A9wB/wPtAf8D2wH/A2UB9AOBAf4D1gH/A9QB/wN/Af4DZQH0A8sB/wPnAf8DtwH/A0QBewsAAQEDJAE2 - A/wB/wP3Af8D7wH/A6YB/wPhAf8D0gH/A7QB/wPqAf8D/AH/A/YB/wP0Af8DTQGRAxcBIAQAAwkBDANf - AdsDxAH/A74B/wOhAf8DlgH/A5MB/wOXAf8DrgH/A64B/wNfAdsDBwEJDAACqAGFAf0B6AG5AZIB/wHo - AbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGS - Af8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wGoAZABQAH9DAADUAGbA6gB/QNkAecDEgEZ - A2QB5wPeAf8D3QH/A2QB5wMSARkDZAHnA6cB/QNQAZsQAAMkATYD5AH9A/QB/wP1Af8D1AH/A6UB/wOd - Af8DvgH/A+kB/wP8Af8D5wH/A00BkQMXASADAQECCAADIQEwA2AB3gO8Af8DygH/A8wB/wPKAf8DwgH/ - A60B/wNgAd4DIQEwEAADPgFrA2UB9AHcAacBUwH/AdwBpgFSAf8B2gGkAVIB/wHYAaIBUQH/AdUBoAFO - Af8B1AGeAU0B/wHSAZ0BSwH/Ac8BmgFKAf8BzgGZAUgB/wHLAZYBRwH/AckBlAFEAf8DZQH0Az4BaxAA - Ax0BKQMKAQ4DAQECA1wB6gPlAf8D5AH/A1wB6gMBAQIDCgEOAx0BKRQAAyMBMwOWAfAD5AH9A/wB/wP8 - Af8D/AH/A/wB/wP8Af8D/AH/A/gB/wNNAZEDFwEgAwEBAhAAAwkBDANHAYEDVwG6A1wBzANcAcwDVwG6 - A0cBgQMJAQxsAAM7AWMDWQG/A1kBvwM7AWMgAAMUARwDIwEzAyQBNgMkATYDJAE2AyQBNgMkATYDJAE2 - AyQBNgMkATYDFwEgAwEBAggAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAH8 - AT8BDwH/AYABAQIAAeACBwH/AYABAQIAAcABAwEAAT8BgAEBAgABwAEDAQABHwGAAQECAAHAAQMBgAEf - AcABAwIAAcABAwHAAQ8B4AEHAgABwAEDAcABAwHwAQ8CAAHAAQMBwAEBAfwBPwIAAcABAwHAAQEB/AE/ - AgABwAEDAcABAQHwAQ8CAAHAAQMB4AEBAeABBwIAAcABAwH4AQEBwAEDAgABwAEDAfwBAAGAAQECAAHA - AQMB/AEAAYABAQIAAeABBwH+AQABgAEBAgAD/wHwAYABAQMAAQMC/wH8AT8BwAIAAQMC/wHgAQcBwAIA - AQMBAAEBAcABAwMAAQMBAAEBAYABAQMAAQMBAAEBAYABAQMAAQMBAAEBAcABAwMAAQMBAAEBAgABgAIA - AQMBAAIBAoACAAEBAQACAQKABAABAQIAAYABAAGHAYABAAEBAcABAwGAAQABhwGAAQABAQGAAQEBgAEA - AYACAAEBAYABAQGAAQABgAEHAQABAQHAAQMBwAEAAcABDwEAAQEB4AEHAcABAQHgAR8C/wH8AT8BwAED - Cw== + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABa + HwAAAk1TRnQBSQFMAgEBBwEAAQwBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEgBgABICoAAwoBDQMiATEDIAEvAwUBBxgAAxEBFwGrAUQBGAH/AWIBXwFIAfYDKQE/ + NAADBgEIA0ABbgNWAbMDXgHdAVICZQH0AUABhgGoAf0BIAFcAbMB/wEQAVEBqAH/AkABngH9AVIBXQFl + AfQCWAFeAd0DVgGzAT8CQAFuAwYBCFAAAxgBIQNQAZ0DXQHwA6EB/wOrAf8DpwH/A5UB/wNkAecDSgGK + AxABFgwAAboBVgElAf8BwAGJAToB/wG/AYkBPQH/Aa8BSAEiAf8DKgFBMAADWwHEAYcBtwHgAf8BlQHG + AeYB/wGbAc0B6QH/AZwBzQHpAf8BmQHHAecB/wGVAcEB5AH/AY4BuAHgAf8BiQGwAd0B/wGBAacB1wH/ + AVQBmwHPAf8BPgGMAcIB/wEfAVkBrgH/AlkBWwHETAADLwFKA2UB9APOAf8D7QH/A/QB/wP1Af8D9AH/ + A+8B/wPiAf8DugH/A2QB5wMkATUIAAHDAYgBNAH/Ac8BogFYAf8BzQGiAYAB/wHAAYwBQQH/AbABTQEk + Af8CTgFNAZUDMQFOAyYBOQMWAR4DAwEEHAADWwHEAZgBuQHUAf8BxQHHAcQB/wHsAdgBxwH/AfYB6wHj + Af8B+gH1AfEB/wHzAecB3gH/Ad8BvwGmAf8B0AGkAYAB/wHLAZoBVQH/AcgBlwFSAf8BowGTAYwB/wFD + AWABnAH/AlkBWwHETAADXAHqA94B/wPzAf8D2wH/A9IB/wPbAf8D1gH/A8AB/wPJAf8D5gH/A8QB/wNc + AeoIAANAAXEBzAGZAUwB/wHQAaMBgQH/Ac8BpAGDAf8BygGeAVYB/wG8AYUBOAH/Aa8BTAEkAf8BpwE/ + ARsB/wGeATIBEwH/AVsCWAHGAwcBCRgAAx0BKgHmAcMBpQH/Ae8B1gHAAf8B+wHyAeoB/wH+AfwB+gL/ + Af4B/QH/Af4B/QH8Af8B/AH2AfAB/wH4AegB2QH/AfYB4wHRAf8B9gHiAc4B/wHmAcgBrQH/Ac4BoAFc + Af8DHQEqTAADXAHqA/AB/wPeAf8D1AH/A9IB/wPbAf8D1gH/A78B/wOwAf8DswH/A94B/wNcAeoMAANB + AXIBzgGdAVEB/wHVAawBjAH/AcsBmwFRAf8BzAGgAVcB/wHIAZsBUQH/AcUBlQFKAf8BwAGPAUQB/wGs + AUgBIwH/A0IBdhwAA1gBuQHtAdMBuwH/AfoB8AHlAf8B/QH5AfUB/wH+AfwB+gH/Af4B/QH8Af8B/QH5 + AfQB/wH2AeMBzwH/AfcB5QHTAf8B9gHjAdEB/wHdAbkBmgH/A1cBuFAAA1wB6gPyAf8D4gH/A9gB/wPV + Af8D3AH/A9gB/wPAAf8DswH/A7cB/wPgAf8DXAHqEAADVgGxAdMBqAGGAf8B1gGsAY4B/wHJAZgBTAH/ + AcQBkAFDAf8BvwGKAToB/wHCAY8BQgH/Ab8BiwE/Af8CXwFHAfsDHQEpHAADVQGwAawBiwF/Af4B9wHq + Ad4B/wH+AfoB9wH/Af4B/AH5Af8B/QH3AfIB/wH6Ae0B4gH/AesB0AG3Af8BlAF/AX4B/gNUAa5UAANc + AeoD8wH/A+cB/wPdAf8D2QH/A+AB/wPbAf8DxAH/A7gB/wO7Af8D4QH/A1wB6hAAAzEBTgHUAaMBWQH/ + AdwBtQGYAf8B0AGhAVgB/wHMAZoBTwH/Ac8BpAGDAf8ByAGaAVEB/wFYAYwBPwH/AUUBuAFVAf8BXwFQ + ATIB+wNUAa8DBwEJGAADJwE6A2EB4QHzAeIB0gH/AfwB9AHtAf8B+wHxAecB/wHpAcwBtQH/A2EB3AMm + AThYAANcAeoD9AH/A+oB/wPhAf8D3QH/A+MB/wPeAf8DyQH/A70B/wO/Af8D4gH/A1wB6hAAAyYBOQHb + AasBiQH/AeEBvQGiAf8B1gGqAYcB/wHZAbMBlAH/Ac4BnwFVAf8DXwH7AUgBvAFXAf8BkwFKASEB/wGw + AVABKgH/AaQBPQEcAf8BYQJeAdoDAwEEHAADWQHHAfQB4wHQAf8B8wHfAc0B/wNbAcNgAANcAeoD9QH/ + A+4B/wPmAf8D4gH/A+YB/wPhAf8DzQH/A8IB/wPCAf8D4wH/A1wB6hAAAxYBHgHgAbEBjwH/AeYBxAGr + Af8B4gG/AaQB/wHYAa0BjgH/AWoBXAFNAfoDQwF3AWYBUQErAfwBuwGEATgB/wHAAY8BRAH/AbwBigE8 + Af8BnAEtARAB/wMWAR4cAANbAcMB9AHhAc4B/wHzAd8BzAH/A1kBwmAAA1wB6gP2Af8D6wH/A94B/wPW + Af8D1QH/A9EB/wPDAf8DvAH/A8AB/wPlAf8DXAHqEAADAwEEA2EB2gHkAbsBnwH/AeQBuwGfAf8BZQFn + AVwB/AFRAcEBWgH/AWsBXwErAfwBxwGWAUoB/wHLAZ4BVgH/AbwBhQE0Af8BwwGSAUcB/wGmAT4BGgH/ + AyYBORQAAyYBOANeAd0B8wHdAckB/wH6Ae4B4gH/AfkB6wHeAf8B7QHQAbYB/wNfAdsDJgE4WAADXAHq + A/cB/wPnAf8D7wH/A/YB/wP7Af8D+gH/A/AB/wPeAf8DwwH/A+YB/wNcAeoUAAMHAQkDVAGvA2oB+QFS + AcUBggH/AbUBsAGBAf8B2AGwAZIB/wHXAa4BjwH/AckBlwFKAf8BwwGPAUEB/wHIAZsBUQH/AbEBTAEl + Af8DMQFOEAADVAGvAbgBmQF/Af4B+QHsAeAB/wH9AfgB9AH/AfsB8AHmAf8B+AHnAdcB/wH5AesB3gH/ + AfIB2gHFAf8BpQJ/Af4DVAGuVAADXAHqA/gB/wP+Gf8D+wH/A+oB/wNcAeocAAMbASYCqAGGAf0B4gG+ + AaMB/wHfAbcBmgH/AdUBqAGGAf8B0AGhAVgB/wHLAZoBTgH/Ac4BogGAAf8BvwGLAT0B/wJOAU0BlQwA + A1cBuAH5AeMBzQH/AfsB8wHsAf8B/gH6AfcB/wH+AfsB+AH/AfwB9QHtAf8B9wHmAdUB/wH2AeEBzAH/ + AfkB7AHfAf8B+QHrAd0B/wHrAc4BtAH/A1cBuFAAA1kBvwPhAf8D/hn/A/sB/wPPAf8DUgGhIAADQgF2 + AeQBugGdAf8B5gHEAasB/wHiAb4BpAH/Ad4BuQGcAf8B2QGyAZMB/wHRAaMBWgH/AdEBpgGFAf8BuwFa + ASwB/wMpAT8EAAMdASoBwAHFAc0B/wGaAbcB3AH/AV4BpgHVAf8BRAGVAcoB/wEwAYcBvgH/ASABXAGz + Af8BEAFRAagB/wEEAUgBnwH/AQABRAGYAf8BDQFMAZoB/wE0AYMBpwH/AYgBlAGaAf8DHQEqTAADHQEq + A1wB0QPQAf8D6AH/A/MB/wP9Af8D/AH/A+0B/wPgAf8DwgH/A1sBwwMUARsgAAMHAQkDWwHGAeMBtAGT + Af8B3wGxAY4B/wHaAasBiQH/AdoBrQGMAf8B3AG1AZgB/wHXAa8BkAH/AcwBmwFPAf8BbgJNAfoEAANc + AdEBhwG3AeAB/wGVAcYB5gH/AZsBzQHpAf8BnAHNAekB/wGZAccB5wH/AZUBwQHkAf8BjgG4AeAB/wGJ + AbAB3QH/AYEBpwHXAf8BVAGbAc8B/wE+AYwBwgH/AR8BWQGuAf8BWAJcAdFQAAMFAQcDNQFVA1QBrgNg + AdYDdgH7A2oB+QNcAc0DUgGpAy0BRgMCAQMoAAMDAQQDFgEeAyYBOQMxBE4BlAHYAacBggH/AdcBrAGL + Af8B0wGnAYQB/wJiAVYB9gQAA1sBxAGHAbcB4AH/AZUBxgHmAf8BnQHPAeoB/wGhAdMB7AH/AaAB0QHr + Af8BmwHKAegB/wGWAcIB5QH/AY8BugHiAf8BhwGxAd0B/wFaAaMB1AH/AUIBkAHEAf8BHwFZAa4B/wJZ + AVsBxLQAAykBPgGEAWQBXwH7A2IB9gMuAUgEAAMGAQgDQAFuA1YBswNeAd0DZQH0AUQBnwGoAf0BSgGZ + AdEB/wE9AZAByAH/AUABhgGoAf0BUgJlAfQBWAJeAd0DVgGzAT8CQAFuAwYBCEUAAZ0B2QH/AQABmQHY + Af8BAAGUAdcB/wEAAZAB1gH/AQABjAHVAf8BAAGIAdQB/wEAAYQB0wH/AQABgAHSAf8BAAEzAdEB/wEA + ATAB0QH/AQABLQHQAf8BAAEqAc8B/wEAAScBzwH/AQABJQHOAf9gAAM7AWMDWAG/A1cBvwM7AWMgAAMV + AR0DIwE0AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMjATMDFQEdAQABowHa + Af8BvAHrAfoB/wG8AesB/AH/Ab8B7gH+Af8BxgH0Av8BzgH4Av8B0wH6Av8B0AH4Av8BxwHyAv8BugHp + AfwB/wGzAeQB+QH/AbAB4gH4Af8BsAHiAfgB/wEAASgBzwH/VAADHQEpAwoBDgMBAQIDXAHqA70B/wOy + Af8DXAHqAwEBAgMKAQ4DHQEpFAADIwE0A2AB9QOuAf0D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/ + A/wB/wOuAf0DXwHzAyMBMwEAAagB2wH/Ab8B7AH7Af8BEAHPAfUB/wEAAbAB7AH/AgABEQH/AQABGAGJ + Af8BAAGJAb4B/wEAAZoByAH/AQABrgHnAf8BAAGlAeYB/wEAAZoB4QH/AQABuAHuAf8BsQHjAfgB/wEA + ASwB0AH/CAADUgGpAcMBjgEjAf8BwAGLASEB/wG+AYgBHwH/AbsBhQEcAf8BuQGDARoB/wG0ATkBFwH/ + AbIBNwEVAf8BsQE2ARMB/wGuATQBEgH/Aa0BMQERAf8BqwEwAQ8B/wGpAS4BDgH/AakBLAEMAf8DUgGp + DAADUAGbA0AB/QNkAecDEgEZA2QB5wPLAf8DxwH/A2IB5wMSARkDXAHnA0AB/QNPAZsIAAM3AVsCXQFS + AfACYgFJAfYB5QG3AZoB/wH7AvoB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wOu + Af0DJAE2AQABrQHcAf8BwQHuAfsB/wEWAdMB9wH/ASMB2wH8Af8BAAEeAYUB/wGUAccB+QH/AZEByQH5 + Af8BAAGFAckB/wEAASEBrgH/AQoBvQHsAf8BAAG+Ae8B/wEAAboB7gH/AbMB4wH5Af8BAAEwAdEB/wgA + AcgBkgEnNf8BqQEtAQwB/wgAA0QBewO8Af8D3gH/A6YB/wNlAfQDfwH+A8QB/wPCAf8DbQH+A2UB9AOm + Af8D0gH/A4AB/wNEAXsEAANiAe8B5gG4AZwB/wHpAb8BpQH/AdwBmwFPAf8B5QG4AZ0B/wP8Af8D/AH/ + A/wB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP8Af8DJAE2AQUBsgHdAf8BwwHvAfsB/wEcAdYB+AH/ + AQMBtgHsAf8BAAGJAaoB/wHgAfIC/wELAZoB2AH/AQABMQG+Af8BAAGYAcUB/wEAAYYBxQH/AQABmwHe + Af8BAAG+Ae8B/wG0AeUB+QH/AQABNQHSAf8IAAHKAZQBKQv/Af4D/wH9Af8C/gH9Af8C/gH8Af8C/gH8 + Af8C/gH8Af8C/gH8Af8C/gH6Af8C/gH6Af8C/AH5Bf8BqgEuAQ4B/wgAA0UBfQN/Af4D1QH/A8UB/wPL + Af8D0QH/A8kB/wPHAf8DzAH/A8UB/wO9Af8DywH/A24B/gNFAX0EAANtAfcB6wHEAa0B/wHsAcgBsgH/ + AeoBwQGpAf8B3gGeAVMB/wHnAbsBoQH/A/wB/wP7Af8D+wH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D/AH/ + AyQBNgEKAbcB3gH/AcYB8AH8Af8BIQHZAfgB/wEzAeIB/QH/ARoBtwHZAf8BMQG2AdUB/wGQAbcB0QH/ + AQwByQHkAf8BEgHfAfUB/wEvAdAB7QH/AQABmAHcAf8BAAG6Ae0B/wG2AecB+QH/AQABgwHTAf8IAAHM + AZcBKgf/AfwD/wH9Af8C/gH8Af8C/gH8Af8C/gH7Af8C/QH6Af8C/QH6Af8C/QH6Af8C/QH6Af8C/AH3 + Af8C+wH2Bf8BrAEwAQ8B/wwAA0gBhQPFAf8DwQH/A8UB/wPHAf8DqgH/A6cB/wPBAf8DvgH/A7UB/wOq + Af8DSAGFCAADQgF1AXoCagH5AewBxwGwAf8B7QHKAbUB/wHrAcMBqwH/Ad4BoQFXAf8B5wG6AZ8B/wP7 + Af8D+wH/A/sB/wP6Af8D+gH/A/gB/wP4Af8D/AH/AyQBNgEPAbsB3wH/AccB8QH8Af8BJgHcAfkB/wEN + AbsB7QH/ARgBvQHvAf8BKAHGAecB/wEpAbgB1gH/AcIB9gH9Af8BGgHfAfcB/wEUAeIB+AH/ATAB0wHw + Af8BAAGXAdwB/wGoAdwB9QH/AQABiAHUAf8IAAHRAZwBLgX/Av4B/AH/Av4B/AH/Av4B/AH/Av0B+wH/ + Av0B+wH/Av0B+gH/Av0B+AH/AvsB+QH/AfsB+gH3Af8B+wH6AfYB/wH7AfgB9AX/AbABNQETAf8EAANc + Ac0DXwHjA2EB7gPPAf8DxgH/A8wB/wNbAcYDLAFEAywBRANbAcYDwQH/A7wB/wO5Af8DYQHuA1kB4wNa + Ac0EAANDAXgBlgJ/Af4B7QHIAbMB/wHtAc0BuAH/AekBvgGjAf8B1gGOAT8B/wP8Af8D/AH/A/wB/wP7 + Af8D+QH/A/kB/wP4Af8D/AH/AyQBNgETAb8B4AH/AcgB8wH8Af8BLAHfAfkB/wGJAeYB/QH/AZUB5wL/ + AZoB5QL/ATABygHnAf8BLgHLAecB/wHHAfcB/QH/ARUB3AH1Af8BEQHhAfcB/wEyAdQB8QH/AQABmQHe + Af8BAAGNAdYB/wgAAdQBngEwBf8C/gH8Af8C/QH7Af8C/QH8Af8C/QH7Af8C/QH5Af8C/AH4Af8B+wH5 + AfcB/wH7AfkB9QH/AfsB+AH0Af8B+wH3AfIB/wH7AfUB8gX/AbIBNwEVAf8EAAOoAf0D4gH/A9IB/wPG + Af8DzQH/A7EB/wMsAUQIAAMsAUQDqAH/A8IB/wO3Af8DwAH/A9IB/wNAAf0HAAEBA0wBkgHgAakBiAH/ + AesBxwGwAf8B3QGhAVcB/wG8AaUBlQH/A6wB/wPQAf8D1AH/A+8B/wP5Af8D9gH/A/YB/wP8Af8DJAE2 + ARcBwgHhAf8ByQHzAfwB/wHLAfMB/QH/AdQB9gH+Af8B1wH2Av8B2AH0Av8B4AH4Av8BqQHjAfUB/wEw + AdMB7gH/AccB9wH9Af8BFgHcAfUB/wESAeIB9wH/ATEB1gHyAf8BAAGYAd4B/wMhATAEAAHVAaABMQX/ + Av0B/AH/Av0B+wH/Av0B+gH/AvwB+QH/AfwB+wH3Af8B+wH5AfUB/wH7AfgB9AH/AfsB9wHzAf8B+wH1 + AfIB/wH6AfMB7wH/AfgB8gHsBf8BtQE5ARcB/wQAA6gB/QPpAf8D1gH/A8kB/wPOAf8DpQH/AywBRAgA + AywBRAOsAf8DxAH/A7oB/wPGAf8D3QH/A0AB/QcAAQEDJAE2AfAB1gHGAf8B3gGtAZAB/wHEAa8BowH/ + A9UB/wO7Af8DpgH/A6AB/wOQAf8DyQH/A/MB/wPyAf8D/AH/AyQBNgEYAcMB4QH/AYgBoAGoAf8DkQH/ + A44B/wERAbkB3AH/AQwBuAHfAf8BCAG1Ad4B/wEEAbEB3QH/AQABsAHeAf8BMwHUAe4B/wHEAfYB/QH/ + ASMB3QH2Af8BJAHKAe0B/wEaAaMB1wH/AV4CZAHsAxsBJgHYAaIBNAX/Av0B+gH/AvwB+gH/AfwB+wH5 + Af8B+wH6AfYB/wH7AfgB9QH/AfsB9wH0Af8B+wH2AfEB/wH4AfQB7gH/AfcB8gHrAf8B9wHwAeoB/wH2 + AewB6AX/AbcBgQEZAf8EAANcAc0DXwHjA2EB7gPYAf8DzQH/A7wB/wNbAcYDLAFEAywBRANbAcYDwwH/ + A8IB/wPNAf8DYQHuA18B4wNcAc0HAAEBAyQBNgP8Af8D+wH/A6wB/wPLAf8D0gH/A8kB/wPSAf8DxgH/ + A48B/wPvAf8D7QH/A/wB/wMkATYEAANbAcMDxgH/A5QB/wMGAQgQAAM3AVoBNQHTAesB/wGyAeMB+QH/ + AYsBwAHnAf8BrgHTAfYB/wHEAeAB/AH/AWYCbQH3AdkBowE0Bf8B/AH7AfkB/wH8AfsB+AH/AfsB+QH3 + Af8B+wH3AfQB/wH6AfcB8gH/AfkB9QHwAf8B9wHzAe0B/wH2Ae8B6gH/AfUB6wHnAf8B8wHqAeQB/wHy + AecB3gX/AboBhQEbAf8MAANIAYUD1AH/A8wB/wPJAf8DugH/A5wB/wOhAf8DwgH/A8YB/wPBAf8DtwH/ + A0gBhQ8AAQEDJAE2A/wB/wP7Af8D2wH/A7IB/wPWAf8DoAH/A5IB/wPAAf8DigH/A+oB/wPmAf8D/AH/ + AyQBNgQAA1QBrgPEAf8DoQH/Ax0BKRAAAx0BKQEbAZkBqQH/AS4BvgHnAf8BtAHSAfAB/wHlAfMC/wGs + AdIB7wH/AVcCXwHoAdsBpAE1Nf8BvQGHAR4B/wgAA0UBfQN/Af4D3AH/A9QB/wPZAf8D2wH/A9YB/wPU + Af8D2QH/A9IB/wPLAf8DyAH/A3kB/gNFAX0LAAEBAyQBNgP8Af8D+QH/A9oB/wO1Af8D5gH/A5oB/wOw + Af8DrwH/A70B/wP8Af8D/AH/A/wB/wMkATYEAANCAXUDugH/A78B/wNeAd0DFgEfAwQBBQMEAQUDFgEf + A2UB5QOoAf8BMgGkAbMB/wEPAaUB2AH/AYUBsQHbAf8BAAGdAdAB/wM4AV4B3AGnATYB/wHcAacBNgH/ + AdwBpwE2Af8B3AGnATYB/wHcAacBNgH/AdwBpwE2Af8B3AGnATYB/wHcAacBNgH/AdwBpwE2Af8B3AGn + ATYB/wHcAacBNgH/AdwBpwE2Af8B3AGnATYB/wHcAacBNgH/AcABiwEhAf8IAANEAXsD3AH/A+0B/wPb + Af8DZQH0A38B/gPWAf8D1AH/A38B/gNlAfQDywH/A+cB/wO3Af8DRAF7CwABAQMkATYD/AH/A/cB/wPv + Af8DpgH/A+EB/wPSAf8DtAH/A+oB/wP8Af8D9gH/A/QB/wNNAZEDFwEgBAADCQEMA18B2wPEAf8DvgH/ + A6EB/wOWAf8DkwH/A5cB/wOuAf8DrgH/A18B2wMHAQkMAAKoAYUB/QHoAbkBkgH/AegBuQGSAf8B6AG5 + AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/ + AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AagBkAFAAf0MAANQAZsDqAH9A2QB5wMSARkDZAHnA94B/wPd + Af8DZAHnAxIBGQNkAecDpwH9A1ABmxAAAyQBNgOuAf0D9AH/A/UB/wPUAf8DpQH/A50B/wO+Af8D6QH/ + A/wB/wPnAf8DTQGRAxcBIAMBAQIIAAMhATADYAHeA7wB/wPKAf8DzAH/A8oB/wPCAf8DrQH/A2AB3gMh + ATAQAAM+AWsDZQH0AdwBpwE2Af8B3AGmATUB/wHaAaQBNQH/AdgBogE0Af8B1QGgATEB/wHUAZ4BMAH/ + AdIBnQEuAf8BzwGaAS0B/wHOAZkBKwH/AcsBlgEqAf8ByQGUAScB/wNlAfQDPgFrEAADHQEpAwoBDgMB + AQIDXAHqA+UB/wPkAf8DXAHqAwEBAgMKAQ4DHQEpFAADIwEzA10B8AOuAf0D/AH/A/wB/wP8Af8D/AH/ + A/wB/wP8Af8D+AH/A00BkQMXASADAQECEAADCQEMA0cBgQNXAboDXAHMA1wBzANXAboDRwGBAwkBDGwA + AzsBYwNZAb8DWQG/AzsBYyAAAxQBHAMjATMDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMX + ASADAQECCAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/wEAAfwBPwEPAf8BgAEB + AgAB4AIHAf8BgAEBAgABwAEDAQABPwGAAQECAAHAAQMBAAEfAYABAQIAAcABAwGAAR8BwAEDAgABwAED + AcABDwHgAQcCAAHAAQMBwAEDAfABDwIAAcABAwHAAQEB/AE/AgABwAEDAcABAQH8AT8CAAHAAQMBwAEB + AfABDwIAAcABAwHgAQEB4AEHAgABwAEDAfgBAQHAAQMCAAHAAQMB/AEAAYABAQIAAcABAwH8AQABgAEB + AgAB4AEHAf4BAAGAAQECAAP/AfABgAEBAwABAwL/AfwBPwHAAgABAwL/AeABBwHAAgABAwEAAQEBwAED + AwABAwEAAQEBgAEBAwABAwEAAQEBgAEBAwABAwEAAQEBwAEDAwABAwEAAQECAAGAAgABAwEAAgECgAIA + AQEBAAIBAoAEAAEBAgABgAEAAYcBgAEAAQEBwAEDAYABAAGHAYABAAEBAYABAQGAAQABgAIAAQEBgAEB + AYABAAGAAQcBAAEBAcABAwHAAQABwAEPAQABAQHgAQcBwAEBAeABHwL/AfwBPwHAAQML \ No newline at end of file diff --git a/trunk/ProcessHacker/Forms/ServiceWindow.cs b/trunk/ProcessHacker/Forms/ServiceWindow.cs index a7dfc137e..e6c04988c 100644 --- a/trunk/ProcessHacker/Forms/ServiceWindow.cs +++ b/trunk/ProcessHacker/Forms/ServiceWindow.cs @@ -71,7 +71,7 @@ namespace ProcessHacker _provider.Dictionary[s].Status.ServiceStatusProcess.CurrentState.ToString() })).Name = s; } - _provider.DictionaryModified += new Provider.ProviderDictionaryModified(_provider_DictionaryModified); + _provider.DictionaryModified += new ServiceProvider.ProviderDictionaryModified(_provider_DictionaryModified); this.FillComboBox(comboErrorControl, typeof(Win32.SERVICE_ERROR_CONTROL)); this.FillComboBox(comboStartType, typeof(Win32.SERVICE_START_TYPE)); @@ -87,7 +87,7 @@ namespace ProcessHacker private void ServiceWindow_FormClosing(object sender, FormClosingEventArgs e) { - _provider.DictionaryModified -= new Provider.ProviderDictionaryModified(_provider_DictionaryModified); + _provider.DictionaryModified -= new ServiceProvider.ProviderDictionaryModified(_provider_DictionaryModified); } private void _provider_DictionaryModified(ServiceItem oldItem, ServiceItem newItem) diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj index 490363f53..823ae7cec 100644 --- a/trunk/ProcessHacker/ProcessHacker.csproj +++ b/trunk/ProcessHacker/ProcessHacker.csproj @@ -124,6 +124,10 @@ ColorModifier.cs Designer + + ModuleList.cs + Designer + HandleList.cs Designer @@ -159,6 +163,10 @@ AboutWindow.cs Designer + + ListWindow.cs + Designer + ProcessWindow.cs Designer @@ -253,6 +261,12 @@ ColorModifier.cs + + UserControl + + + ModuleList.cs + UserControl @@ -305,6 +319,12 @@ Code + + Form + + + ListWindow.cs + Form @@ -385,6 +405,7 @@ + @@ -513,7 +534,9 @@ + + diff --git a/trunk/ProcessHacker/Properties/Resources.Designer.cs b/trunk/ProcessHacker/Properties/Resources.Designer.cs index b31e6bc4c..b82e4b1a2 100644 --- a/trunk/ProcessHacker/Properties/Resources.Designer.cs +++ b/trunk/ProcessHacker/Properties/Resources.Designer.cs @@ -221,6 +221,13 @@ namespace ProcessHacker.Properties { } } + internal static System.Drawing.Bitmap folder_go { + get { + object obj = ResourceManager.GetObject("folder_go", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap group { get { object obj = ResourceManager.GetObject("group", resourceCulture); @@ -305,6 +312,13 @@ namespace ProcessHacker.Properties { } } + internal static System.Drawing.Icon Process { + get { + object obj = ResourceManager.GetObject("Process", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + internal static System.Drawing.Icon Process_small { get { object obj = ResourceManager.GetObject("Process_small", resourceCulture); diff --git a/trunk/ProcessHacker/Properties/Resources.resx b/trunk/ProcessHacker/Properties/Resources.resx index 9ffcaec9a..0f30cdc89 100644 --- a/trunk/ProcessHacker/Properties/Resources.resx +++ b/trunk/ProcessHacker/Properties/Resources.resx @@ -214,6 +214,9 @@ ..\Resources\help.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Icons\Process_small.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\table_relationship.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -226,6 +229,9 @@ ..\Resources\pencil.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\report_user.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\folder_explore.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -241,10 +247,10 @@ ..\Resources\disk.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\report_user.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\folder_go.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Icons\Process_small.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Icons\Process.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/trunk/ProcessHacker/Properties/Settings.Designer.cs b/trunk/ProcessHacker/Properties/Settings.Designer.cs index dc4557c5a..3a7fc2c45 100644 --- a/trunk/ProcessHacker/Properties/Settings.Designer.cs +++ b/trunk/ProcessHacker/Properties/Settings.Designer.cs @@ -709,7 +709,7 @@ namespace ProcessHacker.Properties { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("779, 569")] + [global::System.Configuration.DefaultSettingValueAttribute("493, 465")] public global::System.Drawing.Size ProcessWindowSize { get { return ((global::System.Drawing.Size)(this["ProcessWindowSize"])); diff --git a/trunk/ProcessHacker/Properties/Settings.settings b/trunk/ProcessHacker/Properties/Settings.settings index 109ccecff..4745a8f11 100644 --- a/trunk/ProcessHacker/Properties/Settings.settings +++ b/trunk/ProcessHacker/Properties/Settings.settings @@ -174,7 +174,7 @@ False - 779, 569 + 493, 465 \ No newline at end of file diff --git a/trunk/ProcessHacker/Providers/ModuleProvider.cs b/trunk/ProcessHacker/Providers/ModuleProvider.cs new file mode 100644 index 000000000..89172f1ea --- /dev/null +++ b/trunk/ProcessHacker/Providers/ModuleProvider.cs @@ -0,0 +1,184 @@ +/* + * Process Hacker + * + * Copyright (C) 2008 wj32 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Threading; +using System.Windows.Forms; +using System.Text; + +namespace ProcessHacker +{ + public struct ModuleItem + { + public int BaseAddress; + public int Size; + public string Name; + public string FileName; + public string FileDescription; + public string FileVersion; + } + + public class ModuleProvider : Provider + { + private int _pid; + + public ModuleProvider(int PID) + : base() + { + _pid = PID; + + this.ProviderUpdate += new ProviderUpdateOnce(UpdateOnce); + } + + private void UpdateOnce() + { + if (_pid == 4) + this.UpdateDrivers(); + else + this.UpdateModules(); + } + + private void UpdateDrivers() + { + int requiredSize = 0; + int[] imageBases; + List done = new List(); + Dictionary bases = new Dictionary(); + Dictionary newdictionary = new Dictionary(this.Dictionary); + + Win32.EnumDeviceDrivers(null, 0, out requiredSize); + imageBases = new int[requiredSize]; + Win32.EnumDeviceDrivers(imageBases, requiredSize * sizeof(int), out requiredSize); + + for (int i = 0; i < requiredSize; i++) + { + if (bases.ContainsKey(imageBases[i]) || imageBases[i] == 0) + continue; + + bases.Add(imageBases[i], null); + } + + // look for unloaded drivers + foreach (int b in Dictionary.Keys) + { + if (!bases.ContainsKey(b)) + { + this.CallDictionaryRemoved(this.Dictionary[b]); + newdictionary.Remove(b); + } + } + + // look for new drivers + foreach (int b in bases.Keys) + { + if (!Dictionary.ContainsKey(b)) + { + ModuleItem item = new ModuleItem(); + StringBuilder name = new StringBuilder(256); + StringBuilder filename = new StringBuilder(256); + + Win32.GetDeviceDriverBaseName(b, name, 255); + Win32.GetDeviceDriverFileName(b, filename, 255); + + item.BaseAddress = b; + item.Name = name.ToString(); + item.FileName = Misc.GetRealPath(filename.ToString()); + + try + { + FileVersionInfo info = FileVersionInfo.GetVersionInfo(item.FileName); + + item.FileDescription = info.FileDescription; + item.FileVersion = info.FileVersion; + } + catch + { } + + newdictionary.Add(b, item); + this.CallDictionaryAdded(item); + } + } + + this.Dictionary = newdictionary; + } + + private void UpdateModules() + { + Process process = Process.GetProcessById(_pid); + ProcessModuleCollection modulesCollection = process.Modules; + Dictionary modules = new Dictionary(); + Dictionary newdictionary = new Dictionary(this.Dictionary); + + foreach (ProcessModule m in modulesCollection) + modules.Add(m.BaseAddress.ToInt32(), m); + + // look for unloaded modules + foreach (int b in Dictionary.Keys) + { + if (!modules.ContainsKey(b)) + { + this.CallDictionaryRemoved(this.Dictionary[b]); + newdictionary.Remove(b); + } + } + + // look for new modules + foreach (int b in modules.Keys) + { + if (!Dictionary.ContainsKey(b)) + { + ProcessModule m = modules[b]; + ModuleItem item = new ModuleItem(); + + item.Name = m.ModuleName; + + try { item.FileName = Misc.GetRealPath(m.FileName); } + catch { } + try { item.BaseAddress = b; } + catch { } + try { item.Size = m.ModuleMemorySize; } + catch { } + + try + { + FileVersionInfo info = FileVersionInfo.GetVersionInfo(item.FileName); + + item.FileDescription = info.FileDescription; + item.FileVersion = info.FileVersion; + } + catch + { } + + newdictionary.Add(b, item); + this.CallDictionaryAdded(item); + } + } + + this.Dictionary = newdictionary; + } + + public int PID + { + get { return _pid; } + } + } +} diff --git a/trunk/ProcessHacker/Providers/ProcessProvider.cs b/trunk/ProcessHacker/Providers/ProcessProvider.cs index 80c184ccc..e17cc19c3 100644 --- a/trunk/ProcessHacker/Providers/ProcessProvider.cs +++ b/trunk/ProcessHacker/Providers/ProcessProvider.cs @@ -48,6 +48,7 @@ namespace ProcessHacker public Win32.TokenHandle TokenQueryHandle; public Win32.ProcessHandle ProcessQueryHandle; public Win32.ProcessHandle ProcessQueryLimitedHandle; + public Win32.ProcessHandle ProcessQueryLimitedVmReadHandle; } public class ProcessProvider : Provider @@ -239,10 +240,11 @@ namespace ProcessHacker try { - using (Win32.ProcessHandle phandle = + item.ProcessQueryLimitedVmReadHandle = new Win32.ProcessHandle(pid, - Program.MinProcessQueryRights | Win32.PROCESS_RIGHTS.PROCESS_VM_READ)) - item.CmdLine = phandle.GetCommandLine(); + Program.MinProcessQueryRights | Win32.PROCESS_RIGHTS.PROCESS_VM_READ); + + item.CmdLine = item.ProcessQueryLimitedVmReadHandle.GetCommandLine(); } catch { } diff --git a/trunk/ProcessHacker/Providers/ThreadProvider.cs b/trunk/ProcessHacker/Providers/ThreadProvider.cs index 621926630..25d70e7f3 100644 --- a/trunk/ProcessHacker/Providers/ThreadProvider.cs +++ b/trunk/ProcessHacker/Providers/ThreadProvider.cs @@ -90,16 +90,16 @@ namespace ProcessHacker { Process process = Process.GetProcessById(_pid); ProcessThreadCollection threads = process.Threads; - List tids = new List(); + Dictionary tids = new Dictionary(); Dictionary newdictionary = new Dictionary(this.Dictionary); foreach (ProcessThread t in threads) - tids.Add(t.Id); + tids.Add(t.Id, t); // look for dead threads foreach (int tid in Dictionary.Keys) { - if (!tids.Contains(tid)) + if (!tids.ContainsKey(tid)) { this.CallDictionaryRemoved(this.Dictionary[tid]); newdictionary.Remove(tid); @@ -107,9 +107,11 @@ namespace ProcessHacker } // look for new threads - foreach (ProcessThread t in threads) + foreach (int tid in tids.Keys) { - if (!Dictionary.ContainsKey(t.Id)) + ProcessThread t = tids[tid]; + + if (!Dictionary.ContainsKey(tid)) { ThreadItem item = new ThreadItem(); @@ -125,7 +127,7 @@ namespace ProcessHacker try { using (Win32.ThreadHandle handle = - new Win32.ThreadHandle(t.Id, Win32.THREAD_RIGHTS.THREAD_QUERY_INFORMATION)) + new Win32.ThreadHandle(tid, Win32.THREAD_RIGHTS.THREAD_QUERY_INFORMATION)) { int retLen; diff --git a/trunk/ProcessHacker/Resources/folder_go.png b/trunk/ProcessHacker/Resources/folder_go.png new file mode 100644 index 0000000000000000000000000000000000000000..34a736f70261338c9bca98c38b78193740fa83a0 GIT binary patch literal 694 zcmV;n0!jUeP)N@Zw27r|iugjyK_i?%mf=ZN1k*q&Uedp~2B7g_+fS`hk+Nr1A{hI)z0`VHB6Nndl zX$Di6C%-U4JXr@~z-vS-U`e(1B@n-FV+JTmdRsylL39C=TOrljOR~Cct>JYCvg#mK z1ulqf0!%<`#~!NMu5Ba=9u&fmP-Zhc6E?!yaAE01t20W#1|(JmqlC- zu^GHsMqCzbhR}vI*0gbTWQ<2wA~0LlNQ8*Dc(aJuEaI~Cy?zX0(B7i0rEb>&+G>xJ z3k&o-xX8WohAjXsqHu`)jo1ugGgz-V-_eT`kMj#kXL{&TC&D=t zDS)urCatsVt!&16hZE0Sc81**wR}pC@@4w{a?#MB{`E|khgw{yHQH-JtJz=E5u9kb zz}U public class ProcessHandle : Win32Handle, IWithToken { + /// + /// Specifies an offset in a process' process environment block (PEB). + /// + public enum PEBOffset + { + CurrentDirectoryPath = 0x24, + DllPath = 0x30, + ImagePathName = 0x38, + CommandLine = 0x40, + WindowTitle = 0x70, + DesktopName = 0x78, + ShellInfo = 0x80, + RuntimeData = 0x88 + } + /// /// Creates a process handle using an existing handle. /// The handle will not be closed automatically. @@ -90,7 +105,7 @@ namespace ProcessHacker /// A string. public string GetCommandLine() { - return this.GetPEBString(66); + return this.GetPEBString(PEBOffset.CommandLine); } /// @@ -100,7 +115,7 @@ namespace ProcessHacker /// A file name, in kernel file name format. public string GetImageFileName() { - return this.GetPEBString(58); + return this.GetPEBString(PEBOffset.ImagePathName); } /// @@ -113,39 +128,46 @@ namespace ProcessHacker return this.GetBasicInformation().InheritedFromUniqueProcessId; } - private string GetPEBString(int offset) + /// + /// Reads a UNICODE_STRING from the process' process environment block. + /// + /// The offset to the UNICODE_STRING structure. + /// A string. + public string GetPEBString(PEBOffset offset) { - PROCESS_BASIC_INFORMATION basicInfo = new PROCESS_BASIC_INFORMATION(); - int retLen; + int readLen; int pebBaseAddress = 0x7ffd7000; - if (ZwQueryInformationProcess(this, PROCESS_INFORMATION_CLASS.ProcessBasicInformation, - ref basicInfo, Marshal.SizeOf(basicInfo), out retLen) != 0) - pebBaseAddress = basicInfo.PebBaseAddress; + try + { + pebBaseAddress = this.GetBasicInformation().PebBaseAddress; + } + catch + { } byte[] data2 = new byte[4]; // read address of parameter information block - if (!ReadProcessMemory(this, basicInfo.PebBaseAddress + 16, data2, 4, out retLen)) + if (!ReadProcessMemory(this, pebBaseAddress + 16, data2, 4, out readLen)) throw new Exception(GetLastErrorMessage()); int paramInfoAddrI = Misc.BytesToInt(data2, Misc.Endianness.Little); // read length of string - if (!ReadProcessMemory(this, paramInfoAddrI + offset, data2, 2, out retLen)) + if (!ReadProcessMemory(this, paramInfoAddrI + (int)offset, data2, 2, out readLen)) throw new Exception(GetLastErrorMessage()); ushort strLength = Misc.BytesToUShort(data2, Misc.Endianness.Little); byte[] stringData = new byte[strLength]; // read address of string - if (!ReadProcessMemory(this, paramInfoAddrI + offset + 2, data2, 4, out retLen)) + if (!ReadProcessMemory(this, paramInfoAddrI + (int)offset + 4, data2, 4, out readLen)) throw new Exception(GetLastErrorMessage()); int strAddr = Misc.BytesToInt(data2, Misc.Endianness.Little); // read string - if (!ReadProcessMemory(this, strAddr, stringData, strLength, out retLen)) + if (!ReadProcessMemory(this, strAddr, stringData, strLength, out readLen)) throw new Exception(GetLastErrorMessage()); // return decoded unicode string diff --git a/trunk/ProcessHacker/app.config b/trunk/ProcessHacker/app.config index 91dee419e..6c4fe3a5d 100644 --- a/trunk/ProcessHacker/app.config +++ b/trunk/ProcessHacker/app.config @@ -179,7 +179,7 @@ False - 779, 569 + 493, 465