diff options
author | zturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-21 22:33:51 +0000 |
---|---|---|
committer | zturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-21 22:33:51 +0000 |
commit | 7041dce98ee6a0d4838a059619c1dac233aab247 (patch) | |
tree | d382097693a8d92b586fd4f48ef58c014bb0e485 /tools/win | |
parent | eedf4d86fd753baec4595f1fa7a3b84f61e90870 (diff) | |
download | chromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.zip chromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.tar.gz chromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.tar.bz2 |
Various fixes and UI improvements.
* Added executable icon to list view rows.
* Use the actual module executable name instead of argv[0] (fixes issue
when running not through the shortcut)
* Fixes some button anchoring behavior.
* Moved the command to the Debug menu instead of Tools menu.
BUG=305760
Review URL: https://codereview.chromium.org/27183010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229941 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/win')
-rw-r--r-- | tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs | 282 | ||||
-rw-r--r-- | tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs | 21 | ||||
-rw-r--r-- | tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct | 6 | ||||
-rw-r--r-- | tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs | 76 | ||||
-rw-r--r-- | tools/win/ChromeDebug/LowLevel/NativeMethods.cs | 7 | ||||
-rw-r--r-- | tools/win/ChromeDebug/LowLevel/Types.cs | 42 |
6 files changed, 269 insertions, 165 deletions
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs index 392a7142..3465e3e 100644 --- a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs +++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs @@ -32,159 +32,154 @@ namespace ChromeDebug /// </summary> private void InitializeComponent() { - this.listViewProcesses = new System.Windows.Forms.ListView(); - this.columnHeaderDummy = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderProcess = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderPid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderSession = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderCmdLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.buttonAttach = new System.Windows.Forms.Button(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.buttonRefresh = new System.Windows.Forms.Button(); - this.checkBoxOnlyChrome = new System.Windows.Forms.CheckBox(); - this.groupBox1.SuspendLayout(); - this.SuspendLayout(); - // - // listViewProcesses - // - this.listViewProcesses.AllowColumnReorder = true; - this.listViewProcesses.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.listViewProcesses = new System.Windows.Forms.ListView(); + this.columnHeaderProcess = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderPid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderSession = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderCmdLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.buttonAttach = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.buttonRefresh = new System.Windows.Forms.Button(); + this.checkBoxOnlyChrome = new System.Windows.Forms.CheckBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // listViewProcesses + // + this.listViewProcesses.AllowColumnReorder = true; + this.listViewProcesses.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.listViewProcesses.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeaderDummy, + this.listViewProcesses.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.columnHeaderProcess, this.columnHeaderPid, this.columnHeaderTitle, this.columnHeaderType, this.columnHeaderSession, this.columnHeaderCmdLine}); - this.listViewProcesses.FullRowSelect = true; - this.listViewProcesses.Location = new System.Drawing.Point(14, 27); - this.listViewProcesses.Name = "listViewProcesses"; - this.listViewProcesses.Size = new System.Drawing.Size(884, 462); - this.listViewProcesses.TabIndex = 0; - this.listViewProcesses.UseCompatibleStateImageBehavior = false; - this.listViewProcesses.View = System.Windows.Forms.View.Details; - // - // columnHeaderDummy - // - this.columnHeaderDummy.Width = 0; - // - // columnHeaderProcess - // - this.columnHeaderProcess.Text = "Executable"; - this.columnHeaderProcess.Width = 65; - // - // columnHeaderPid - // - this.columnHeaderPid.Text = "PID"; - this.columnHeaderPid.Width = 30; - // - // columnHeaderTitle - // - this.columnHeaderTitle.Text = "Title"; - this.columnHeaderTitle.Width = 32; - // - // columnHeaderType - // - this.columnHeaderType.Text = "Type"; - this.columnHeaderType.Width = 36; - // - // columnHeaderSession - // - this.columnHeaderSession.Text = "Session"; - this.columnHeaderSession.Width = 49; - // - // columnHeaderCmdLine - // - this.columnHeaderCmdLine.Text = "Command Line"; - this.columnHeaderCmdLine.Width = 668; - // - // buttonAttach - // - this.buttonAttach.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonAttach.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonAttach.Location = new System.Drawing.Point(684, 603); - this.buttonAttach.Name = "buttonAttach"; - this.buttonAttach.Size = new System.Drawing.Size(118, 41); - this.buttonAttach.TabIndex = 2; - this.buttonAttach.Text = "Attach"; - this.buttonAttach.UseVisualStyleBackColor = true; - this.buttonAttach.Click += new System.EventHandler(this.buttonAttach_Click); - // - // buttonCancel - // - this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.buttonCancel.Location = new System.Drawing.Point(808, 603); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(118, 41); - this.buttonCancel.TabIndex = 3; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.UseVisualStyleBackColor = true; - // - // groupBox1 - // - this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.listViewProcesses.FullRowSelect = true; + this.listViewProcesses.Location = new System.Drawing.Point(14, 27); + this.listViewProcesses.Name = "listViewProcesses"; + this.listViewProcesses.Size = new System.Drawing.Size(884, 462); + this.listViewProcesses.TabIndex = 0; + this.listViewProcesses.UseCompatibleStateImageBehavior = false; + this.listViewProcesses.View = System.Windows.Forms.View.Details; + // + // columnHeaderProcess + // + this.columnHeaderProcess.Text = "Executable"; + this.columnHeaderProcess.Width = 65; + // + // columnHeaderPid + // + this.columnHeaderPid.Text = "PID"; + this.columnHeaderPid.Width = 30; + // + // columnHeaderTitle + // + this.columnHeaderTitle.Text = "Title"; + this.columnHeaderTitle.Width = 32; + // + // columnHeaderType + // + this.columnHeaderType.Text = "Type"; + this.columnHeaderType.Width = 36; + // + // columnHeaderSession + // + this.columnHeaderSession.Text = "Session"; + this.columnHeaderSession.Width = 49; + // + // columnHeaderCmdLine + // + this.columnHeaderCmdLine.Text = "Command Line"; + this.columnHeaderCmdLine.Width = 668; + // + // buttonAttach + // + this.buttonAttach.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonAttach.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonAttach.Location = new System.Drawing.Point(684, 603); + this.buttonAttach.Name = "buttonAttach"; + this.buttonAttach.Size = new System.Drawing.Size(118, 41); + this.buttonAttach.TabIndex = 2; + this.buttonAttach.Text = "Attach"; + this.buttonAttach.UseVisualStyleBackColor = true; + this.buttonAttach.Click += new System.EventHandler(this.buttonAttach_Click); + // + // buttonCancel + // + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(808, 603); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(118, 41); + this.buttonCancel.TabIndex = 3; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + // + // groupBox1 + // + this.groupBox1.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.groupBox1.Controls.Add(this.listViewProcesses); - this.groupBox1.Location = new System.Drawing.Point(12, 27); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(914, 511); - this.groupBox1.TabIndex = 5; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Available Processes"; - // - // buttonRefresh - // - this.buttonRefresh.Location = new System.Drawing.Point(808, 552); - this.buttonRefresh.Name = "buttonRefresh"; - this.buttonRefresh.Size = new System.Drawing.Size(117, 33); - this.buttonRefresh.TabIndex = 6; - this.buttonRefresh.Text = "Refresh"; - this.buttonRefresh.UseVisualStyleBackColor = true; - this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click); - // - // checkBoxOnlyChrome - // - this.checkBoxOnlyChrome.AutoSize = true; - this.checkBoxOnlyChrome.Checked = true; - this.checkBoxOnlyChrome.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxOnlyChrome.Location = new System.Drawing.Point(12, 561); - this.checkBoxOnlyChrome.Name = "checkBoxOnlyChrome"; - this.checkBoxOnlyChrome.Size = new System.Drawing.Size(165, 17); - this.checkBoxOnlyChrome.TabIndex = 7; - this.checkBoxOnlyChrome.Text = "Only show Chrome processes"; - this.checkBoxOnlyChrome.UseVisualStyleBackColor = true; - this.checkBoxOnlyChrome.CheckedChanged += new System.EventHandler(this.checkBoxOnlyChrome_CheckedChanged); - // - // AttachDialog - // - this.AcceptButton = this.buttonAttach; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.buttonCancel; - this.ClientSize = new System.Drawing.Size(940, 656); - this.ControlBox = false; - this.Controls.Add(this.checkBoxOnlyChrome); - this.Controls.Add(this.buttonRefresh); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.buttonAttach); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "AttachDialog"; - this.ShowInTaskbar = false; - this.Text = "Attach to Chrome"; - this.Load += new System.EventHandler(this.AttachDialog_Load); - this.groupBox1.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); + this.groupBox1.Controls.Add(this.listViewProcesses); + this.groupBox1.Location = new System.Drawing.Point(12, 27); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(914, 511); + this.groupBox1.TabIndex = 5; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Available Processes"; + // + // buttonRefresh + // + this.buttonRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonRefresh.Location = new System.Drawing.Point(808, 552); + this.buttonRefresh.Name = "buttonRefresh"; + this.buttonRefresh.Size = new System.Drawing.Size(117, 33); + this.buttonRefresh.TabIndex = 6; + this.buttonRefresh.Text = "Refresh"; + this.buttonRefresh.UseVisualStyleBackColor = true; + this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click); + // + // checkBoxOnlyChrome + // + this.checkBoxOnlyChrome.AutoSize = true; + this.checkBoxOnlyChrome.Checked = true; + this.checkBoxOnlyChrome.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxOnlyChrome.Location = new System.Drawing.Point(12, 561); + this.checkBoxOnlyChrome.Name = "checkBoxOnlyChrome"; + this.checkBoxOnlyChrome.Size = new System.Drawing.Size(165, 17); + this.checkBoxOnlyChrome.TabIndex = 7; + this.checkBoxOnlyChrome.Text = "Only show Chrome processes"; + this.checkBoxOnlyChrome.UseVisualStyleBackColor = true; + this.checkBoxOnlyChrome.CheckedChanged += new System.EventHandler(this.checkBoxOnlyChrome_CheckedChanged); + // + // AttachDialog + // + this.AcceptButton = this.buttonAttach; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(940, 656); + this.ControlBox = false; + this.Controls.Add(this.checkBoxOnlyChrome); + this.Controls.Add(this.buttonRefresh); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonAttach); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AttachDialog"; + this.ShowInTaskbar = false; + this.Text = "Attach to Chrome"; + this.Load += new System.EventHandler(this.AttachDialog_Load); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -197,7 +192,6 @@ namespace ChromeDebug private System.Windows.Forms.ColumnHeader columnHeaderPid; private System.Windows.Forms.ColumnHeader columnHeaderTitle; private System.Windows.Forms.ColumnHeader columnHeaderCmdLine; - private System.Windows.Forms.ColumnHeader columnHeaderDummy; private System.Windows.Forms.ColumnHeader columnHeaderType; private System.Windows.Forms.ColumnHeader columnHeaderSession; private System.Windows.Forms.GroupBox groupBox1; diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs index a6505d3..2c38983 100644 --- a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs +++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs @@ -127,8 +127,10 @@ namespace ChromeDebug { item.Title = p.MainWindowTitle; item.Exe = p.ProcessName; if (item.CmdLineArgs != null) - item.Category = DetermineProcessCategory(item.CmdLineArgs); + item.Category = DetermineProcessCategory(item.Detail.Win32ProcessImagePath, + item.CmdLineArgs); + Icon icon = item.Detail.SmallIcon; List<ProcessViewItem> items = loadedProcessTable[item.Category]; item.Group = processGroups[item.Category]; items.Add(item); @@ -147,11 +149,11 @@ namespace ChromeDebug { // Using a heuristic based on the command line, tries to determine what type of process this // is. - private ProcessCategory DetermineProcessCategory(string[] cmdline) { + private ProcessCategory DetermineProcessCategory(string imagePath, string[] cmdline) { if (cmdline == null || cmdline.Length == 0) return ProcessCategory.Other; - string file = Path.GetFileName(cmdline[0]); + string file = Path.GetFileName(imagePath); if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase)) return ProcessCategory.DelegateExecute; else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) { @@ -173,13 +175,19 @@ namespace ChromeDebug { private void InsertCategoryItems(ProcessCategory category) { foreach (ProcessViewItem item in loadedProcessTable[category]) { - item.SubItems.Add(item.Exe); + item.Text = item.Exe; item.SubItems.Add(item.ProcessId.ToString()); item.SubItems.Add(item.Title); item.SubItems.Add(item.MachineType.ToString()); item.SubItems.Add(item.SessionId.ToString()); item.SubItems.Add(item.DisplayCmdLine); listViewProcesses.Items.Add(item); + + Icon icon = item.Detail.SmallIcon; + if (icon != null) { + item.ImageList.Images.Add(icon); + item.ImageIndex = item.ImageList.Images.Count - 1; + } } } @@ -196,9 +204,8 @@ namespace ChromeDebug { listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); // Finally, iterate over each column, and resize those columns that just got smaller. - listViewProcesses.Columns[0].Width = 0; int total = 0; - for (int i = 1; i < listViewProcesses.Columns.Count; ++i) { + for (int i = 0; i < listViewProcesses.Columns.Count; ++i) { // Resize to the largest of the two, but don't let it go over a pre-defined maximum. int max = Math.Max(listViewProcesses.Columns[i].Width, widths[i]); int capped = Math.Min(max, 300); @@ -216,6 +223,8 @@ namespace ChromeDebug { private void RepopulateListView() { listViewProcesses.Items.Clear(); + listViewProcesses.SmallImageList = new ImageList(); + listViewProcesses.SmallImageList.ImageSize = new Size(16, 16); ReloadNativeProcessInfo(); diff --git a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct index ca02527..bfc9246 100644 --- a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct +++ b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct @@ -21,6 +21,10 @@ <!--This header contains the command ids for the menus provided by the shell. --> <Extern href="vsshlids.h"/> + <!--These headers contain the menu guids for attaching commands to the debug menu. --> + <Extern href="VSDbgCmd.h"/> + <Extern href="VSDebugGuids.h"/> + @@ -44,7 +48,7 @@ <Groups> <Group guid="guidChromeDebugCmdSet" id="MyMenuGroup" priority="0x0600"> - <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/> + <Parent guid="guidVSDebugGroup" id="IDM_DEBUG_MENU"/> </Group> diff --git a/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs index fbbb358..973ea0c 100644 --- a/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs +++ b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs @@ -12,6 +12,8 @@ using System.Text; using System.Threading.Tasks; using ChromeDebug.LowLevel; +using System.Runtime.InteropServices; +using System.Drawing; namespace ChromeDebug { internal class ProcessDetail : IDisposable { @@ -44,6 +46,43 @@ namespace ChromeDebug { } } + public string NativeProcessImagePath { + get { + if (nativeProcessImagePath == null) { + nativeProcessImagePath = QueryProcessImageName( + LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT); + } + return nativeProcessImagePath; + } + } + + public string Win32ProcessImagePath { + get { + if (win32ProcessImagePath == null) { + win32ProcessImagePath = QueryProcessImageName( + LowLevelTypes.ProcessQueryImageNameMode.WIN32_FORMAT); + } + return win32ProcessImagePath; + } + } + + public Icon SmallIcon { + get { + LowLevel.LowLevelTypes.SHFILEINFO info = new LowLevelTypes.SHFILEINFO(true); + LowLevel.LowLevelTypes.SHGFI flags = LowLevel.LowLevelTypes.SHGFI.Icon + | LowLevelTypes.SHGFI.SmallIcon + | LowLevelTypes.SHGFI.OpenIcon + | LowLevelTypes.SHGFI.UseFileAttributes; + int cbFileInfo = Marshal.SizeOf(info); + LowLevel.NativeMethods.SHGetFileInfo(Win32ProcessImagePath, + 256, + ref info, + (uint)cbFileInfo, + (uint)flags); + return Icon.FromHandle(info.hIcon); + } + } + // Returns the command line that this process was launched with. Uses lazy evaluation and // caches the result. Reads the command line from the PEB of the running process. public string CommandLine { @@ -92,6 +131,19 @@ namespace ChromeDebug { } } + private string QueryProcessImageName(LowLevelTypes.ProcessQueryImageNameMode mode) { + StringBuilder moduleBuffer = new StringBuilder(1024); + int size = moduleBuffer.Capacity; + NativeMethods.QueryFullProcessImageName( + processHandle, + mode, + moduleBuffer, + ref size); + if (mode == LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT) + moduleBuffer.Insert(0, "\\\\?\\GLOBALROOT"); + return moduleBuffer.ToString(); + } + // Loads the top-level structure of the process's information block and caches it. private void CacheProcessInformation() { System.Diagnostics.Debug.Assert(CanReadPeb); @@ -151,29 +203,19 @@ namespace ChromeDebug { private void CacheMachineType() { System.Diagnostics.Debug.Assert(CanQueryProcessInformation); - StringBuilder moduleBuffer = new StringBuilder(1024); - int size = moduleBuffer.Capacity; - // If our extension is running in a 32-bit process (which it is), then attempts to access // files in C:\windows\system (and a few other files) will redirect to C:\Windows\SysWOW64 // and we will mistakenly think that the image file is a 32-bit image. The way around this // is to use a native system format path, of the form: // \\?\GLOBALROOT\Device\HarddiskVolume0\Windows\System\foo.dat - // By using the NATIVE_SYSTEM_FORMAT flag to QueryFullProcessImageName, we can get the path - // in this format. - NativeMethods.QueryFullProcessImageName( - processHandle, - LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT, - moduleBuffer, - ref size); - moduleBuffer.Insert(0, "\\\\?\\GLOBALROOT"); - string module = moduleBuffer.ToString(); + // NativeProcessImagePath gives us the full process image path in the desired format. + string path = NativeProcessImagePath; // Open the PE File as a binary file, and parse just enough information to determine the // machine type. //http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx using (SafeFileHandle safeHandle = NativeMethods.CreateFile( - module, + path, LowLevelTypes.FileAccessFlags.GENERIC_READ, LowLevelTypes.FileShareFlags.SHARE_READ, IntPtr.Zero, @@ -214,7 +256,9 @@ namespace ChromeDebug { // open with. private int processId; private IntPtr processHandle; - LowLevelTypes.ProcessAccessFlags processHandleFlags; + private LowLevelTypes.ProcessAccessFlags processHandleFlags; + private string nativeProcessImagePath; + private string win32ProcessImagePath; // The machine type is read by parsing the PE image file of the running process, so we cache // its value since the operation expensive. @@ -229,6 +273,10 @@ namespace ChromeDebug { private Nullable<LowLevelTypes.RTL_USER_PROCESS_PARAMETERS> cachedProcessParams; private string cachedCommandLine; + ~ProcessDetail() { + Dispose(); + } + public void Dispose() { if (processHandle != IntPtr.Zero) NativeMethods.CloseHandle(processHandle); diff --git a/tools/win/ChromeDebug/LowLevel/NativeMethods.cs b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs index 4fb46fd..170cd91 100644 --- a/tools/win/ChromeDebug/LowLevel/NativeMethods.cs +++ b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs @@ -61,5 +61,12 @@ namespace ChromeDebug.LowLevel { LowLevelTypes.FileCreationDisposition dwDisp, LowLevelTypes.FileFlagsAndAttributes dwFlags, IntPtr hTemplateFile); + + [DllImport("shell32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr SHGetFileInfo(string pszPath, + uint dwFileAttributes, + ref LowLevelTypes.SHFILEINFO psfi, + uint cbFileInfo, + uint uFlags); } } diff --git a/tools/win/ChromeDebug/LowLevel/Types.cs b/tools/win/ChromeDebug/LowLevel/Types.cs index 17fc19b..483acf7 100644 --- a/tools/win/ChromeDebug/LowLevel/Types.cs +++ b/tools/win/ChromeDebug/LowLevel/Types.cs @@ -102,6 +102,28 @@ namespace ChromeDebug.LowLevel { public enum PROCESSINFOCLASS : int { PROCESS_BASIC_INFORMATION = 0 }; + + [Flags] + public enum SHGFI : uint { + Icon = 0x000000100, + DisplayName = 0x000000200, + TypeName = 0x000000400, + Attributes = 0x000000800, + IconLocation = 0x000001000, + ExeType = 0x000002000, + SysIconIndex = 0x000004000, + LinkOverlay = 0x000008000, + Selected = 0x000010000, + Attr_Specified = 0x000020000, + LargeIcon = 0x000000000, + SmallIcon = 0x000000001, + OpenIcon = 0x000000002, + ShellIconSize = 0x000000004, + PIDL = 0x000000008, + UseFileAttributes = 0x000000010, + AddOverlays = 0x000000020, + OverlayIndex = 0x000000040, + } #endregion #region Structures @@ -172,6 +194,26 @@ namespace ChromeDebug.LowLevel { public IntPtr PebBaseAddress { get { return pebBaseAddress; } } public UIntPtr UniqueProcessId { get { return uniqueProcessId; } } } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct SHFILEINFO { + // C# doesn't support overriding the default constructor of value types, so we need to use + // a dummy constructor. + public SHFILEINFO(bool dummy) { + hIcon = IntPtr.Zero; + iIcon = 0; + dwAttributes = 0; + szDisplayName = ""; + szTypeName = ""; + } + public IntPtr hIcon; + public int iIcon; + public uint dwAttributes; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string szDisplayName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string szTypeName; + }; #endregion } } |