summaryrefslogtreecommitdiffstats
path: root/tools/win
diff options
context:
space:
mode:
authorzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-18 20:26:52 +0000
committerzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-18 20:26:52 +0000
commit81cc64b423512b123de7412179ed1d256e0443be (patch)
treecee5bcb2f238d863652f2984c75e7cd7b1003114 /tools/win
parent0e9cdd55c8fd221ab6fb38b295aea3c2273bb485 (diff)
downloadchromium_src-81cc64b423512b123de7412179ed1d256e0443be.zip
chromium_src-81cc64b423512b123de7412179ed1d256e0443be.tar.gz
chromium_src-81cc64b423512b123de7412179ed1d256e0443be.tar.bz2
Resubmit of ChromeDebug extension with fixed license headers.
BUG=0 notry=TRUE Review URL: https://chromiumcodereview.appspot.com/23526064 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223930 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/win')
-rw-r--r--tools/win/ChromeDebug/.gitignore5
-rw-r--r--tools/win/ChromeDebug/ChromeDebug.sln26
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs207
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs254
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx120
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ChromeDebug.csproj211
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct121
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ChromeDebugPackage.cs107
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/GlobalSuppressions.cs16
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/Guids.cs16
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/LICENSE27
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/PkgCmdID.cs13
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ProcessCategory.cs37
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs238
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/Properties/AssemblyInfo.cs40
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/Resources.Designer.cs63
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/Resources.resx140
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/Utility.cs85
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/VSPackage.resx151
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/source.extension.vsixmanifest24
-rw-r--r--tools/win/ChromeDebug/LowLevel/LowLevel.csproj64
-rw-r--r--tools/win/ChromeDebug/LowLevel/NativeMethods.cs65
-rw-r--r--tools/win/ChromeDebug/LowLevel/Properties/AssemblyInfo.cs40
-rw-r--r--tools/win/ChromeDebug/LowLevel/Types.cs177
-rw-r--r--tools/win/ChromeDebug/README.txt5
25 files changed, 2252 insertions, 0 deletions
diff --git a/tools/win/ChromeDebug/.gitignore b/tools/win/ChromeDebug/.gitignore
new file mode 100644
index 0000000..58eea67
--- /dev/null
+++ b/tools/win/ChromeDebug/.gitignore
@@ -0,0 +1,5 @@
+!*.sln
+ChromeDebug/obj/*
+ChromeDebug/bin/*
+LowLevel/obj/*
+LowLevel/bin/*
diff --git a/tools/win/ChromeDebug/ChromeDebug.sln b/tools/win/ChromeDebug/ChromeDebug.sln
new file mode 100644
index 0000000..ade84fd
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChromeDebug", "ChromeDebug\ChromeDebug.csproj", "{4CC60BED-569D-481A-B56B-6ECBC23CBC16}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LowLevel", "LowLevel\LowLevel.csproj", "{998C0725-F123-4ED3-9D44-12C1945F00D1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4CC60BED-569D-481A-B56B-6ECBC23CBC16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CC60BED-569D-481A-B56B-6ECBC23CBC16}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CC60BED-569D-481A-B56B-6ECBC23CBC16}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CC60BED-569D-481A-B56B-6ECBC23CBC16}.Release|Any CPU.Build.0 = Release|Any CPU
+ {998C0725-F123-4ED3-9D44-12C1945F00D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {998C0725-F123-4ED3-9D44-12C1945F00D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {998C0725-F123-4ED3-9D44-12C1945F00D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {998C0725-F123-4ED3-9D44-12C1945F00D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs
new file mode 100644
index 0000000..392a7142
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs
@@ -0,0 +1,207 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace ChromeDebug
+{
+ partial class AttachDialog
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </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)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.listViewProcesses.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeaderDummy,
+ 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)
+ | 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();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ListView listViewProcesses;
+ private System.Windows.Forms.Button buttonAttach;
+ private System.Windows.Forms.Button buttonCancel;
+ private System.Windows.Forms.ColumnHeader columnHeaderProcess;
+ 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;
+ private System.Windows.Forms.Button buttonRefresh;
+ private System.Windows.Forms.CheckBox checkBoxOnlyChrome;
+ }
+} \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
new file mode 100644
index 0000000..a6505d3
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
@@ -0,0 +1,254 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Management;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+using ChromeDebug.LowLevel;
+
+namespace ChromeDebug {
+ // The form that is displayed to allow the user to select processes to attach to. Note that we
+ // cannot interact with the DTE object from here (I assume this is because the dialog is running
+ // on a different thread, although I don't fully understand), so any access to the DTE object
+ // will have to be done through events that get posted back to the main package thread.
+ public partial class AttachDialog : Form {
+ private class ProcessViewItem : ListViewItem {
+ public ProcessViewItem() {
+ Category = ProcessCategory.Other;
+ MachineType = LowLevelTypes.MachineType.UNKNOWN;
+ }
+
+ public string Exe;
+ public int ProcessId;
+ public int SessionId;
+ public string Title;
+ public string DisplayCmdLine;
+ public string[] CmdLineArgs;
+ public ProcessCategory Category;
+ public LowLevelTypes.MachineType MachineType;
+
+ public ProcessDetail Detail;
+ }
+
+ private Dictionary<ProcessCategory, List<ProcessViewItem>> loadedProcessTable = null;
+ private Dictionary<ProcessCategory, ListViewGroup> processGroups = null;
+ private List<int> selectedProcesses = null;
+
+ public AttachDialog() {
+ InitializeComponent();
+
+ loadedProcessTable = new Dictionary<ProcessCategory, List<ProcessViewItem>>();
+ processGroups = new Dictionary<ProcessCategory, ListViewGroup>();
+ selectedProcesses = new List<int>();
+
+ // Create and initialize the groups and process lists only once. On a reset
+ // we don't clear the groups manually, clearing the list view should clear the
+ // groups. And we don't clear the entire processes_ dictionary, only the
+ // individual buckets inside the dictionary.
+ foreach (object value in Enum.GetValues(typeof(ProcessCategory))) {
+ ProcessCategory category = (ProcessCategory)value;
+
+ ListViewGroup group = new ListViewGroup(category.ToGroupTitle());
+ processGroups[category] = group;
+ listViewProcesses.Groups.Add(group);
+
+ loadedProcessTable[category] = new List<ProcessViewItem>();
+ }
+ }
+
+ // Provides an iterator that evaluates to the process ids of the entries that are selected
+ // in the list view.
+ public IEnumerable<int> SelectedItems {
+ get {
+ foreach (ProcessViewItem item in listViewProcesses.SelectedItems)
+ yield return item.ProcessId;
+ }
+ }
+
+ private void AttachDialog_Load(object sender, EventArgs e) {
+ RepopulateListView();
+ }
+
+ // Remove command line arguments that we aren't interested in displaying as part of the command
+ // line of the process.
+ private string[] FilterCommandLine(string[] args) {
+ Func<string, int, bool> AllowArgument = delegate(string arg, int index) {
+ if (index == 0)
+ return false;
+ return !arg.StartsWith("--force-fieldtrials", StringComparison.CurrentCultureIgnoreCase);
+ };
+
+ // The force-fieldtrials command line option makes the command line view useless, so remove
+ // it. Also remove args[0] since that is the process name.
+ args = args.Where(AllowArgument).ToArray();
+ return args;
+ }
+
+ private void ReloadNativeProcessInfo() {
+ foreach (List<ProcessViewItem> list in loadedProcessTable.Values) {
+ list.Clear();
+ }
+
+ Process[] processes = Process.GetProcesses();
+ foreach (Process p in processes) {
+ ProcessViewItem item = new ProcessViewItem();
+ try {
+ item.Detail = new ProcessDetail(p.Id);
+ if (item.Detail.CanReadPeb && item.Detail.CommandLine != null) {
+ item.CmdLineArgs = Utility.SplitArgs(item.Detail.CommandLine);
+ item.DisplayCmdLine = GetFilteredCommandLineString(item.CmdLineArgs);
+ }
+ item.MachineType = item.Detail.MachineType;
+ }
+ catch (Exception) {
+ // Generally speaking, an exception here means the process is privileged and we cannot
+ // get any information about the process. For those processes, we will just display the
+ // information that the Framework gave us in the Process structure.
+ }
+
+ // If we don't have the machine type, its privilege level is high enough that we won't be
+ // able to attach a debugger to it anyway, so skip it.
+ if (item.MachineType == LowLevelTypes.MachineType.UNKNOWN)
+ continue;
+
+ item.ProcessId = p.Id;
+ item.SessionId = p.SessionId;
+ item.Title = p.MainWindowTitle;
+ item.Exe = p.ProcessName;
+ if (item.CmdLineArgs != null)
+ item.Category = DetermineProcessCategory(item.CmdLineArgs);
+
+ List<ProcessViewItem> items = loadedProcessTable[item.Category];
+ item.Group = processGroups[item.Category];
+ items.Add(item);
+ }
+ }
+
+ // Filter the command line arguments to remove extraneous arguments that we don't wish to
+ // display.
+ private string GetFilteredCommandLineString(string[] args) {
+ if (args == null || args.Length == 0)
+ return string.Empty;
+
+ args = FilterCommandLine(args);
+ return string.Join(" ", args, 0, args.Length);
+ }
+
+ // Using a heuristic based on the command line, tries to determine what type of process this
+ // is.
+ private ProcessCategory DetermineProcessCategory(string[] cmdline) {
+ if (cmdline == null || cmdline.Length == 0)
+ return ProcessCategory.Other;
+
+ string file = Path.GetFileName(cmdline[0]);
+ if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase))
+ return ProcessCategory.DelegateExecute;
+ else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) {
+ if (cmdline.Contains("--type=renderer"))
+ return ProcessCategory.Renderer;
+ else if (cmdline.Contains("--type=plugin") || cmdline.Contains("--type=ppapi"))
+ return ProcessCategory.Plugin;
+ else if (cmdline.Contains("--type=gpu-process"))
+ return ProcessCategory.Gpu;
+ else if (cmdline.Contains("--type=service"))
+ return ProcessCategory.Service;
+ else if (cmdline.Any(arg => arg.StartsWith("-ServerName")))
+ return ProcessCategory.MetroViewer;
+ else
+ return ProcessCategory.Browser;
+ } else
+ return ProcessCategory.Other;
+ }
+
+ private void InsertCategoryItems(ProcessCategory category) {
+ foreach (ProcessViewItem item in loadedProcessTable[category]) {
+ item.SubItems.Add(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);
+ }
+ }
+
+ private void AutoResizeColumns() {
+ // First adjust to the width of the headers, since it's fast.
+ listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
+
+ // Save the widths so we can use them again later.
+ List<int> widths = new List<int>();
+ foreach (ColumnHeader header in listViewProcesses.Columns)
+ widths.Add(header.Width);
+
+ // Now let Windows do the slow adjustment based on the content.
+ 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) {
+ // 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);
+
+ // We do still want to fill up the available space in the list view however, so if we're
+ // under then we can fill.
+ int globalMinWidth = listViewProcesses.Width - SystemInformation.VerticalScrollBarWidth;
+ if (i == listViewProcesses.Columns.Count - 1 && (total + capped) < (globalMinWidth - 4))
+ capped = globalMinWidth - total - 4;
+
+ total += capped;
+ listViewProcesses.Columns[i].Width = capped;
+ }
+ }
+
+ private void RepopulateListView() {
+ listViewProcesses.Items.Clear();
+
+ ReloadNativeProcessInfo();
+
+ InsertCategoryItems(ProcessCategory.Browser);
+ InsertCategoryItems(ProcessCategory.Renderer);
+ InsertCategoryItems(ProcessCategory.Gpu);
+ InsertCategoryItems(ProcessCategory.Plugin);
+ InsertCategoryItems(ProcessCategory.MetroViewer);
+ InsertCategoryItems(ProcessCategory.Service);
+ InsertCategoryItems(ProcessCategory.DelegateExecute);
+ if (!checkBoxOnlyChrome.Checked)
+ InsertCategoryItems(ProcessCategory.Other);
+
+ AutoResizeColumns();
+ }
+
+ private void buttonRefresh_Click(object sender, EventArgs e) {
+ RepopulateListView();
+ }
+
+ private void buttonAttach_Click(object sender, EventArgs e) {
+ System.Diagnostics.Debug.WriteLine("Closing dialog.");
+ this.Close();
+ }
+
+ private void checkBoxOnlyChrome_CheckedChanged(object sender, EventArgs e) {
+ if (!checkBoxOnlyChrome.Checked)
+ InsertCategoryItems(ProcessCategory.Other);
+ else {
+ foreach (ProcessViewItem item in loadedProcessTable[ProcessCategory.Other]) {
+ listViewProcesses.Items.Remove(item);
+ }
+ }
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.csproj b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.csproj
new file mode 100644
index 0000000..97bd38d
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.csproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>4.0</OldToolsVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4CC60BED-569D-481A-B56B-6ECBC23CBC16}</ProjectGuid>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ChromeDebug</RootNamespace>
+ <AssemblyName>ChromeDebug</AssemblyName>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
+ <EmbedInteropTypes>true</EmbedInteropTypes>
+ </Reference>
+ <Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Shell.11.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Design" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Management" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <COMReference Include="EnvDTE">
+ <Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE100">
+ <Guid>{26AD1324-4B7C-44BC-84F8-B86AED45729F}</Guid>
+ <VersionMajor>10</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE80">
+ <Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE90">
+ <Guid>{2CE2370E-D744-4936-A090-3FFFE667B0E1}</Guid>
+ <VersionMajor>9</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE90a1">
+ <Guid>{64A96FE8-CCCF-4EDF-B341-FF7C528B60C9}</Guid>
+ <VersionMajor>9</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="Microsoft.VisualStudio.CommandBars">
+ <Guid>{1CBA492E-7263-47BB-87FE-639000619B15}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="stdole">
+ <Guid>{00020430-0000-0000-C000-000000000046}</Guid>
+ <VersionMajor>2</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AttachDialog.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="AttachDialog.Designer.cs">
+ <DependentUpon>AttachDialog.cs</DependentUpon>
+ </Compile>
+ <Compile Include="ProcessCategory.cs" />
+ <Compile Include="ProcessDetail.cs" />
+ <Compile Include="Utility.cs" />
+ <Compile Include="Guids.cs" />
+ <Compile Include="Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="ChromeDebugPackage.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="PkgCmdID.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="AttachDialog.resx">
+ <DependentUpon>AttachDialog.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="VSPackage.resx">
+ <MergeWithCTO>true</MergeWithCTO>
+ <ManifestResourceName>VSPackage</ManifestResourceName>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Key.snk" />
+ <Content Include="LICENSE">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <None Include="source.extension.vsixmanifest">
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <VSCTCompile Include="ChromeDebug.vsct">
+ <ResourceName>Menus.ctmenu</ResourceName>
+ <SubType>Designer</SubType>
+ </VSCTCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\Images.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Resources\Package.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\LowLevel\LowLevel.csproj">
+ <Project>{998c0725-f123-4ed3-9d44-12c1945f00d1}</Project>
+ <Name>LowLevel</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <PropertyGroup>
+ <UseCodebase>true</UseCodebase>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct
new file mode 100644
index 0000000..ca02527
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- This is the file that defines the actual layout and type of the commands.
+ It is divided in different sections (e.g. command definition, command
+ placement, ...), with each defining a specific set of properties.
+ See the comment before each section for more details about how to
+ use it. -->
+
+ <!-- The VSCT compiler (the tool that translates this file into the binary
+ format that VisualStudio will consume) has the ability to run a preprocessor
+ on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
+ it is possible to define includes and macros with the same syntax used
+ in C++ files. Using this ability of the compiler here, we include some files
+ defining some of the constants that we will use inside the file. -->
+
+ <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
+ <Extern href="stdidcmd.h"/>
+
+ <!--This header contains the command ids for the menus provided by the shell. -->
+ <Extern href="vsshlids.h"/>
+
+
+
+
+ <!--The Commands section is where we the commands, menus and menu groups are defined.
+ This section uses a Guid to identify the package that provides the command defined inside it.
+ -->
+ <Commands package="guidChromeDebugPkg">
+ <!-- Inside this section we have different sub-sections: one for the menus, another
+ for the menu groups, one for the buttons (the actual commands), one for the combos
+ and the last one for the bitmaps used. Each element is identified by a command id that
+ is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
+ called "command set" and is used to group different command inside a logically related
+ group; your package should define its own command set in order to avoid collisions
+ with command ids defined by other packages. -->
+
+
+ <!-- In this section you can define new menu groups. A menu group is a container for
+ other menus or buttons (commands); from a visual point of view you can see the
+ group as the part of a menu contained between two lines. The parent of a group
+ must be a menu. -->
+ <Groups>
+
+ <Group guid="guidChromeDebugCmdSet" id="MyMenuGroup" priority="0x0600">
+ <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
+ </Group>
+
+
+
+ </Groups>
+
+ <!--Buttons section. -->
+ <!--This section defines the elements the user can interact with, like a menu command or a
+ button or combo box in a toolbar. -->
+ <Buttons>
+ <!--To define a menu group you have to specify its ID, the parent menu and its display
+ priority. The command is visible and enabled by default. If you need to change the
+ visibility, status, etc, you can use the CommandFlag node. You can add more than one
+ CommandFlag node e.g.:
+ <CommandFlag>DefaultInvisible</CommandFlag>
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ If you do not want an image next to your command, remove the Icon node /> -->
+
+ <Button guid="guidChromeDebugCmdSet" id="cmdidAttachToProcess" priority="0x0100"
+ type="Button">
+ <Parent guid="guidChromeDebugCmdSet" id="MyMenuGroup" />
+ <Icon guid="guidImages" id="bmpPic1" />
+ <Strings>
+ <ButtonText>Attach to Chrome</ButtonText>
+ </Strings>
+ </Button>
+
+
+
+ </Buttons>
+
+ <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
+ <Bitmaps>
+ <!-- The bitmap id is defined in a way that is a little bit different from the others:
+ the declaration starts with a guid for the bitmap strip, then there is the resource id
+ of the bitmap strip containing the bitmaps and then there are the numeric ids of the
+ elements used inside a button definition. An important aspect of this declaration is
+ that the element id must be the actual index (1-based) of the bitmap inside the bitmap
+ strip. -->
+ <Bitmap guid="guidImages" href="Resources\Images.png"
+ usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
+
+ </Bitmaps>
+
+ </Commands>
+
+
+
+
+
+ <Symbols>
+ <!-- This is the package guid. -->
+ <GuidSymbol name="guidChromeDebugPkg" value="{7de8bbab-82c7-4871-b82c-4d5d44a3979d}" />
+
+ <!-- This is the guid used to group the menu commands together -->
+ <GuidSymbol name="guidChromeDebugCmdSet" value="{6608d840-ce6c-45ab-b856-eb0a0b471ff1}">
+
+ <IDSymbol name="MyMenuGroup" value="0x1020" />
+ <IDSymbol name="cmdidAttachToProcess" value="0x0100" />
+ </GuidSymbol>
+
+
+
+ <GuidSymbol name="guidImages" value="{7142ff8d-aa4e-45a5-a090-2e2ed8c5672b}" >
+ <IDSymbol name="bmpPic1" value="1" />
+ <IDSymbol name="bmpPic2" value="2" />
+ <IDSymbol name="bmpPicSearch" value="3" />
+ <IDSymbol name="bmpPicX" value="4" />
+ <IDSymbol name="bmpPicArrows" value="5" />
+ <IDSymbol name="bmpPicStrikethrough" value="6" />
+ </GuidSymbol>
+ </Symbols>
+
+</CommandTable>
diff --git a/tools/win/ChromeDebug/ChromeDebug/ChromeDebugPackage.cs b/tools/win/ChromeDebug/ChromeDebug/ChromeDebugPackage.cs
new file mode 100644
index 0000000..2a697b6
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/ChromeDebugPackage.cs
@@ -0,0 +1,107 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.ComponentModel.Design;
+using Microsoft.Win32;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.OLE.Interop;
+using Microsoft.VisualStudio.Shell;
+using System.Windows.Forms;
+
+namespace ChromeDebug {
+ /// <summary>
+ /// This is the class that implements the package exposed by this assembly.
+ ///
+ /// The minimum requirement for a class to be considered a valid package for Visual Studio
+ /// is to implement the IVsPackage interface and register itself with the shell.
+ /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
+ /// to do it: it derives from the Package class that provides the implementation of the
+ /// IVsPackage interface and uses the registration attributes defined in the framework to
+ /// register itself and its components with the shell.
+ /// </summary>
+ // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
+ // a package.
+ [PackageRegistration(UseManagedResourcesOnly = true)]
+ // This attribute is used to register the information needed to show this package
+ // in the Help/About dialog of Visual Studio.
+ [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
+ // This attribute is needed to let the shell know that this package exposes some menus.
+ [ProvideMenuResource("Menus.ctmenu", 1)]
+ [Guid(GuidList.guidChromeDebugPkgString)]
+ public sealed class ChromeDebugPackage : Package {
+ /// <summary>
+ /// Default constructor of the package.
+ /// Inside this method you can place any initialization code that does not require
+ /// any Visual Studio service because at this point the package object is created but
+ /// not sited yet inside Visual Studio environment. The place to do all the other
+ /// initialization is the Initialize method.
+ /// </summary>
+ public ChromeDebugPackage() {
+ Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}",
+ this.ToString()));
+ }
+
+
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Overridden Package Implementation
+ #region Package Members
+
+ /// <summary>
+ /// Initialization of the package; this method is called right after the package is sited, so this is the place
+ /// where you can put all the initialization code that rely on services provided by VisualStudio.
+ /// </summary>
+ protected override void Initialize() {
+ Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
+ base.Initialize();
+
+ // Add our command handlers for menu (commands must exist in the .vsct file)
+ OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
+ if (null != mcs) {
+ // Create the command for the menu item.
+ CommandID menuCommandID = new CommandID(GuidList.guidChromeDebugCmdSet, (int)PkgCmdIDList.cmdidAttachToProcess);
+ MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+ mcs.AddCommand(menuItem);
+ }
+ }
+ #endregion
+
+ /// <summary>
+ /// This function is the callback used to execute a command when the a menu item is clicked.
+ /// See the Initialize method to see how the menu item is associated to this function using
+ /// the OleMenuCommandService service and the MenuCommand class.
+ /// </summary>
+ private void MenuItemCallback(object sender, EventArgs e) {
+ // Show a Message Box to prove we were here
+ EnvDTE.DTE dte = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE));
+
+ IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
+ Guid clsid = Guid.Empty;
+ IntPtr parentHwnd = IntPtr.Zero;
+ uiShell.GetDialogOwnerHwnd(out parentHwnd);
+
+ NativeWindow parentShim = new NativeWindow();
+ parentShim.AssignHandle(parentHwnd);
+ AttachDialog dialog = new AttachDialog();
+ DialogResult result = dialog.ShowDialog(parentShim);
+ if (result == DialogResult.OK) {
+ foreach (int selected_id in dialog.SelectedItems) {
+ foreach (EnvDTE90a.Process4 p in dte.Debugger.LocalProcesses) {
+ System.Diagnostics.Debug.WriteLine("Found process {0}", p.ProcessID);
+ if (p.ProcessID != selected_id)
+ continue;
+ p.Attach();
+ System.Diagnostics.Debug.WriteLine("Attaching to process successful.");
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/GlobalSuppressions.cs b/tools/win/ChromeDebug/ChromeDebug/GlobalSuppressions.cs
new file mode 100644
index 0000000..f967862
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/GlobalSuppressions.cs
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project. Project-level
+// suppressions either have no target or are given a specific target
+// and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click "In Project
+// Suppression File". You do not need to add suppressions to this
+// file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
+ "CA1017:MarkAssembliesWithComVisible")]
diff --git a/tools/win/ChromeDebug/ChromeDebug/Guids.cs b/tools/win/ChromeDebug/ChromeDebug/Guids.cs
new file mode 100644
index 0000000..7a7a660
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/Guids.cs
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Guids.cs
+// MUST match guids.h
+using System;
+
+namespace ChromeDebug {
+ static class GuidList {
+ public const string guidChromeDebugPkgString = "7de8bbab-82c7-4871-b82c-4d5d44a3979d";
+ public const string guidChromeDebugCmdSetString = "6608d840-ce6c-45ab-b856-eb0a0b471ff1";
+
+ public static readonly Guid guidChromeDebugCmdSet = new Guid(guidChromeDebugCmdSetString);
+ };
+} \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/LICENSE b/tools/win/ChromeDebug/ChromeDebug/LICENSE
new file mode 100644
index 0000000..8fb3cc2
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/win/ChromeDebug/ChromeDebug/PkgCmdID.cs b/tools/win/ChromeDebug/ChromeDebug/PkgCmdID.cs
new file mode 100644
index 0000000..816b804
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/PkgCmdID.cs
@@ -0,0 +1,13 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// PkgCmdID.cs
+// MUST match PkgCmdID.h
+using System;
+
+namespace ChromeDebug {
+ static class PkgCmdIDList {
+ public const uint cmdidAttachToProcess = 0x100;
+ };
+} \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/ProcessCategory.cs b/tools/win/ChromeDebug/ChromeDebug/ProcessCategory.cs
new file mode 100644
index 0000000..ffcffdd
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/ProcessCategory.cs
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ChromeDebug {
+ internal enum ProcessCategory {
+ Browser,
+ Renderer,
+ Gpu,
+ Plugin,
+ DelegateExecute,
+ MetroViewer,
+ Service,
+ Other
+ }
+
+ // Defines an extension method for the ProcessCategory enum which converts the enum value into
+ // the group title.
+ internal static class ProcessCategoryExtensions {
+ public static string ToGroupTitle(this ProcessCategory category) {
+ switch (category) {
+ case ProcessCategory.DelegateExecute:
+ return "Delegate Execute";
+ case ProcessCategory.MetroViewer:
+ return "Metro Viewer";
+ default:
+ return category.ToString();
+ }
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs
new file mode 100644
index 0000000..fbbb358
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs
@@ -0,0 +1,238 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using ChromeDebug.LowLevel;
+
+namespace ChromeDebug {
+ internal class ProcessDetail : IDisposable {
+ public ProcessDetail(int pid) {
+ // Initialize everything to null in case something fails.
+ this.processId = pid;
+ this.processHandleFlags = LowLevelTypes.ProcessAccessFlags.NONE;
+ this.cachedProcessBasicInfo = null;
+ this.machineTypeIsLoaded = false;
+ this.machineType = LowLevelTypes.MachineType.UNKNOWN;
+ this.cachedPeb = null;
+ this.cachedProcessParams = null;
+ this.cachedCommandLine = null;
+ this.processHandle = IntPtr.Zero;
+
+ OpenAndCacheProcessHandle();
+ }
+
+ // Returns the machine type (x86, x64, etc) of this process. Uses lazy evaluation and caches
+ // the result.
+ public LowLevelTypes.MachineType MachineType {
+ get {
+ if (machineTypeIsLoaded)
+ return machineType;
+ if (!CanQueryProcessInformation)
+ return LowLevelTypes.MachineType.UNKNOWN;
+
+ CacheMachineType();
+ return machineType;
+ }
+ }
+
+ // 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 {
+ get {
+ if (!CanReadPeb)
+ throw new InvalidOperationException();
+ CacheProcessInformation();
+ CachePeb();
+ CacheProcessParams();
+ CacheCommandLine();
+ return cachedCommandLine;
+ }
+ }
+
+ // Determines if we have permission to read the process's PEB.
+ public bool CanReadPeb {
+ get {
+ LowLevelTypes.ProcessAccessFlags required_flags =
+ LowLevelTypes.ProcessAccessFlags.VM_READ
+ | LowLevelTypes.ProcessAccessFlags.QUERY_INFORMATION;
+
+ // In order to read the PEB, we must have *both* of these flags.
+ if ((processHandleFlags & required_flags) != required_flags)
+ return false;
+
+ // If we're on a 64-bit OS, in a 32-bit process, and the target process is not 32-bit,
+ // we can't read its PEB.
+ if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess
+ && (MachineType != LowLevelTypes.MachineType.X86))
+ return false;
+
+ return true;
+ }
+ }
+
+ // If we can't read the process's PEB, we may still be able to get other kinds of information
+ // from the process. This flag determines if we can get lesser information.
+ private bool CanQueryProcessInformation {
+ get {
+ LowLevelTypes.ProcessAccessFlags required_flags =
+ LowLevelTypes.ProcessAccessFlags.QUERY_LIMITED_INFORMATION
+ | LowLevelTypes.ProcessAccessFlags.QUERY_INFORMATION;
+
+ // In order to query the process, we need *either* of these flags.
+ return (processHandleFlags & required_flags) != LowLevelTypes.ProcessAccessFlags.NONE;
+ }
+ }
+
+ // Loads the top-level structure of the process's information block and caches it.
+ private void CacheProcessInformation() {
+ System.Diagnostics.Debug.Assert(CanReadPeb);
+
+ // Fetch the process info and set the fields.
+ LowLevelTypes.PROCESS_BASIC_INFORMATION temp = new LowLevelTypes.PROCESS_BASIC_INFORMATION();
+ int size;
+ LowLevelTypes.NTSTATUS status = NativeMethods.NtQueryInformationProcess(
+ processHandle,
+ LowLevelTypes.PROCESSINFOCLASS.PROCESS_BASIC_INFORMATION,
+ ref temp,
+ Utility.UnmanagedStructSize<LowLevelTypes.PROCESS_BASIC_INFORMATION>(),
+ out size);
+
+ if (status != LowLevelTypes.NTSTATUS.SUCCESS) {
+ throw new Win32Exception();
+ }
+
+ cachedProcessBasicInfo = temp;
+ }
+
+ // Follows a pointer from the PROCESS_BASIC_INFORMATION structure in the target process's
+ // address space to read the PEB.
+ private void CachePeb() {
+ System.Diagnostics.Debug.Assert(CanReadPeb);
+
+ if (cachedPeb == null) {
+ cachedPeb = Utility.ReadUnmanagedStructFromProcess<LowLevelTypes.PEB>(
+ processHandle,
+ cachedProcessBasicInfo.Value.PebBaseAddress);
+ }
+ }
+
+ // Follows a pointer from the PEB structure in the target process's address space to read the
+ // RTL_USER_PROCESS_PARAMETERS structure.
+ private void CacheProcessParams() {
+ System.Diagnostics.Debug.Assert(CanReadPeb);
+
+ if (cachedProcessParams == null) {
+ cachedProcessParams =
+ Utility.ReadUnmanagedStructFromProcess<LowLevelTypes.RTL_USER_PROCESS_PARAMETERS>(
+ processHandle, cachedPeb.Value.ProcessParameters);
+ }
+ }
+
+ private void CacheCommandLine() {
+ System.Diagnostics.Debug.Assert(CanReadPeb);
+
+ if (cachedCommandLine == null) {
+ cachedCommandLine = Utility.ReadStringUniFromProcess(
+ processHandle,
+ cachedProcessParams.Value.CommandLine.Buffer,
+ cachedProcessParams.Value.CommandLine.Length / 2);
+ }
+ }
+
+ 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();
+
+ // 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,
+ LowLevelTypes.FileAccessFlags.GENERIC_READ,
+ LowLevelTypes.FileShareFlags.SHARE_READ,
+ IntPtr.Zero,
+ LowLevelTypes.FileCreationDisposition.OPEN_EXISTING,
+ LowLevelTypes.FileFlagsAndAttributes.NORMAL,
+ IntPtr.Zero)) {
+ FileStream fs = new FileStream(safeHandle, FileAccess.Read);
+ using (BinaryReader br = new BinaryReader(fs)) {
+ fs.Seek(0x3c, SeekOrigin.Begin);
+ Int32 peOffset = br.ReadInt32();
+ fs.Seek(peOffset, SeekOrigin.Begin);
+ UInt32 peHead = br.ReadUInt32();
+ if (peHead != 0x00004550) // "PE\0\0", little-endian
+ throw new Exception("Can't find PE header");
+ machineType = (LowLevelTypes.MachineType)br.ReadUInt16();
+ machineTypeIsLoaded = true;
+ }
+ }
+ }
+
+ private void OpenAndCacheProcessHandle() {
+ // Try to open a handle to the process with the highest level of privilege, but if we can't
+ // do that then fallback to requesting access with a lower privilege level.
+ processHandleFlags = LowLevelTypes.ProcessAccessFlags.QUERY_INFORMATION
+ | LowLevelTypes.ProcessAccessFlags.VM_READ;
+ processHandle = NativeMethods.OpenProcess(processHandleFlags, false, processId);
+ if (processHandle == IntPtr.Zero) {
+ processHandleFlags = LowLevelTypes.ProcessAccessFlags.QUERY_LIMITED_INFORMATION;
+ processHandle = NativeMethods.OpenProcess(processHandleFlags, false, processId);
+ if (processHandle == IntPtr.Zero) {
+ processHandleFlags = LowLevelTypes.ProcessAccessFlags.NONE;
+ throw new Win32Exception();
+ }
+ }
+ }
+
+ // An open handle to the process, along with the set of access flags that the handle was
+ // open with.
+ private int processId;
+ private IntPtr processHandle;
+ LowLevelTypes.ProcessAccessFlags processHandleFlags;
+
+ // The machine type is read by parsing the PE image file of the running process, so we cache
+ // its value since the operation expensive.
+ private bool machineTypeIsLoaded;
+ private LowLevelTypes.MachineType machineType;
+
+ // The following fields exist ultimately so that we can access the command line. However,
+ // each field must be read separately through a pointer into another process's address
+ // space so the access is expensive, hence we cache the values.
+ private Nullable<LowLevelTypes.PROCESS_BASIC_INFORMATION> cachedProcessBasicInfo;
+ private Nullable<LowLevelTypes.PEB> cachedPeb;
+ private Nullable<LowLevelTypes.RTL_USER_PROCESS_PARAMETERS> cachedProcessParams;
+ private string cachedCommandLine;
+
+ public void Dispose() {
+ if (processHandle != IntPtr.Zero)
+ NativeMethods.CloseHandle(processHandle);
+ processHandle = IntPtr.Zero;
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/Properties/AssemblyInfo.cs b/tools/win/ChromeDebug/ChromeDebug/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..29c8203
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ChromeDebug")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Chromium Authors")]
+[assembly: AssemblyProduct("ChromeDebug")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(false)]
+[assembly: NeutralResourcesLanguage("en-US")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+
+
diff --git a/tools/win/ChromeDebug/ChromeDebug/Resources.Designer.cs b/tools/win/ChromeDebug/ChromeDebug/Resources.Designer.cs
new file mode 100644
index 0000000..529a0a7
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.33439
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ChromeDebug {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChromeDebug.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/Resources.resx b/tools/win/ChromeDebug/ChromeDebug/Resources.resx
new file mode 100644
index 0000000..9fa8826
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/Resources.resx
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ VS SDK Notes: This resx file contains the resources that will be consumed directly by your
+ package. For example, if you chose to create a tool window, there is a resource with ID
+ 'CanNotCreateWindow'. This is used in VsPkg.cs to determine the string to show the user if
+ there is an error when attempting to create the tool window.
+
+ Resources that are accessed directly from your package *by Visual Studio* are stored in the
+ VSPackage.resx file.
+-->
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">
+ System.Resources.ResXResourceReader, System.Windows.Forms, ...
+ </resheader>
+ <resheader name="writer">
+ System.Resources.ResXResourceWriter, System.Windows.Forms, ...
+ </resheader>
+ <data name="Name1">
+ <value>this is my long string</value>
+ <comment>this is a comment</comment>
+ </data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing"
+ mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ [base64 mime encoded string representing a byte array form of the .NET Framework object]
+ </value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/Utility.cs b/tools/win/ChromeDebug/ChromeDebug/Utility.cs
new file mode 100644
index 0000000..bdba408
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/Utility.cs
@@ -0,0 +1,85 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+using ChromeDebug.LowLevel;
+
+namespace ChromeDebug {
+ internal static class Utility {
+ public static string[] SplitArgs(string unsplitArgumentLine) {
+ if (unsplitArgumentLine == null)
+ return new string[0];
+
+ int numberOfArgs;
+ IntPtr ptrToSplitArgs;
+ string[] splitArgs;
+
+ ptrToSplitArgs = NativeMethods.CommandLineToArgvW(unsplitArgumentLine, out numberOfArgs);
+
+ // CommandLineToArgvW returns NULL upon failure.
+ if (ptrToSplitArgs == IntPtr.Zero)
+ throw new ArgumentException("Unable to split argument.", new Win32Exception());
+
+ // Make sure the memory ptrToSplitArgs to is freed, even upon failure.
+ try {
+ splitArgs = new string[numberOfArgs];
+
+ // ptrToSplitArgs is an array of pointers to null terminated Unicode strings.
+ // Copy each of these strings into our split argument array.
+ for (int i = 0; i < numberOfArgs; i++)
+ splitArgs[i] = Marshal.PtrToStringUni(
+ Marshal.ReadIntPtr(ptrToSplitArgs, i * IntPtr.Size));
+
+ return splitArgs;
+ }
+ finally {
+ // Free memory obtained by CommandLineToArgW.
+ NativeMethods.LocalFree(ptrToSplitArgs);
+ }
+ }
+
+ public static T ReadUnmanagedStructFromProcess<T>(IntPtr processHandle,
+ IntPtr addressInProcess) {
+ int bytesRead;
+ int bytesToRead = Marshal.SizeOf(typeof(T));
+ IntPtr buffer = Marshal.AllocHGlobal(bytesToRead);
+ if (!NativeMethods.ReadProcessMemory(processHandle, addressInProcess, buffer, bytesToRead,
+ out bytesRead))
+ throw new Win32Exception();
+ T result = (T)Marshal.PtrToStructure(buffer, typeof(T));
+ Marshal.FreeHGlobal(buffer);
+ return result;
+ }
+
+ public static string ReadStringUniFromProcess(IntPtr processHandle,
+ IntPtr addressInProcess,
+ int NumChars) {
+ int bytesRead;
+ IntPtr outBuffer = Marshal.AllocHGlobal(NumChars * 2);
+
+ bool bresult = NativeMethods.ReadProcessMemory(processHandle,
+ addressInProcess,
+ outBuffer,
+ NumChars * 2,
+ out bytesRead);
+ if (!bresult)
+ throw new Win32Exception();
+
+ string result = Marshal.PtrToStringUni(outBuffer, bytesRead / 2);
+ Marshal.FreeHGlobal(outBuffer);
+ return result;
+ }
+
+ public static int UnmanagedStructSize<T>() {
+ return Marshal.SizeOf(typeof(T));
+ }
+ }
+}
diff --git a/tools/win/ChromeDebug/ChromeDebug/VSPackage.resx b/tools/win/ChromeDebug/ChromeDebug/VSPackage.resx
new file mode 100644
index 0000000..36cd9ee
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/VSPackage.resx
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ VS SDK Notes: This resx file contains the resources that will be consumed from your package by
+ Visual Studio. For example, Visual Studio will attempt to load resource '400' from this
+ resource stream when it needs to load your package's icon. Because Visual Studio will always
+ look in the VSPackage.resources stream first for resources it needs, you should put additional
+ resources that Visual Studio will load directly into this resx file.
+
+ Resources that you would like to access directly from your package in a strong-typed fashion
+ should be stored in Resources.resx or another resx file.
+-->
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">
+ System.Resources.ResXResourceReader, System.Windows.Forms, ...
+ </resheader>
+ <resheader name="writer">
+ System.Resources.ResXResourceWriter, System.Windows.Forms, ...
+ </resheader>
+ <data name="Name1">
+ <value>this is my long string</value>
+ <comment>this is a comment</comment>
+ </data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing"
+ mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ [base64 mime encoded string representing a byte array form of the .NET Framework object]
+ </value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="110" xml:space="preserve">
+ <value>ChromeDebug</value>
+ </data>
+ <data name="112" xml:space="preserve">
+ <value>Advanced Debugging Features</value>
+ </data>
+ <data name="400" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/tools/win/ChromeDebug/ChromeDebug/source.extension.vsixmanifest b/tools/win/ChromeDebug/ChromeDebug/source.extension.vsixmanifest
new file mode 100644
index 0000000..c0814aa
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/source.extension.vsixmanifest
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011"
+ xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
+ <Metadata>
+ <Identity Id="7de8bbab-82c7-4871-b82c-4d5d44a3979d" Version="1.0" Language="en-US"
+ Publisher="The Chromium Authors" />
+ <DisplayName>ChromeDebug</DisplayName>
+ <Description xml:space="preserve">Debugging Features for Chromium</Description>
+ <License>LICENSE</License>
+ </Metadata>
+ <Installation InstalledByMsi="false">
+ <InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="[11.0,12.0]" />
+ </Installation>
+ <Dependencies>
+ <Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework"
+ d:Source="Manual" Version="4.5" />
+ <Dependency Id="Microsoft.VisualStudio.MPF.11.0" DisplayName="Visual Studio MPF 11.0"
+ d:Source="Installed" Version="11.0" />
+ </Dependencies>
+ <Assets>
+ <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project"
+ d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
+ </Assets>
+</PackageManifest>
diff --git a/tools/win/ChromeDebug/LowLevel/LowLevel.csproj b/tools/win/ChromeDebug/LowLevel/LowLevel.csproj
new file mode 100644
index 0000000..4649f33
--- /dev/null
+++ b/tools/win/ChromeDebug/LowLevel/LowLevel.csproj
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{998C0725-F123-4ED3-9D44-12C1945F00D1}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>LowLevel</RootNamespace>
+ <AssemblyName>LowLevel</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="NativeMethods.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Types.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Key.snk" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/tools/win/ChromeDebug/LowLevel/NativeMethods.cs b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs
new file mode 100644
index 0000000..4fb46fd
--- /dev/null
+++ b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs
@@ -0,0 +1,65 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ChromeDebug.LowLevel {
+ public static class NativeMethods {
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool ReadProcessMemory(IntPtr hProcess,
+ IntPtr lpBaseAddress,
+ IntPtr lpBuffer,
+ int dwSize,
+ out int lpNumberOfBytesRead);
+
+ [DllImport("ntdll.dll", SetLastError = true)]
+ public static extern LowLevelTypes.NTSTATUS NtQueryInformationProcess(
+ IntPtr hProcess,
+ LowLevelTypes.PROCESSINFOCLASS pic,
+ ref LowLevelTypes.PROCESS_BASIC_INFORMATION pbi,
+ int cb,
+ out int pSize);
+
+ [DllImport("shell32.dll", SetLastError = true)]
+ public static extern IntPtr CommandLineToArgvW(
+ [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine,
+ out int pNumArgs);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr LocalFree(IntPtr hMem);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr OpenProcess(
+ LowLevelTypes.ProcessAccessFlags dwDesiredAccess,
+ [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
+ int dwProcessId);
+
+ [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall,
+ CharSet = CharSet.Unicode)]
+ public static extern uint QueryFullProcessImageName(
+ IntPtr hProcess,
+ [MarshalAs(UnmanagedType.U4)] LowLevelTypes.ProcessQueryImageNameMode flags,
+ [Out] StringBuilder lpImageName, ref int size);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CloseHandle(IntPtr hObject);
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ public static extern SafeFileHandle CreateFile(string lpFileName,
+ LowLevelTypes.FileAccessFlags dwDesiredAccess,
+ LowLevelTypes.FileShareFlags dwShareMode,
+ IntPtr lpSecurityAttributes,
+ LowLevelTypes.FileCreationDisposition dwDisp,
+ LowLevelTypes.FileFlagsAndAttributes dwFlags,
+ IntPtr hTemplateFile);
+ }
+}
diff --git a/tools/win/ChromeDebug/LowLevel/Properties/AssemblyInfo.cs b/tools/win/ChromeDebug/LowLevel/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7a77cff
--- /dev/null
+++ b/tools/win/ChromeDebug/LowLevel/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LowLevel")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LowLevel")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5bfd12c9-dfa1-4994-b31d-755f3e064640")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tools/win/ChromeDebug/LowLevel/Types.cs b/tools/win/ChromeDebug/LowLevel/Types.cs
new file mode 100644
index 0000000..17fc19b
--- /dev/null
+++ b/tools/win/ChromeDebug/LowLevel/Types.cs
@@ -0,0 +1,177 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ChromeDebug.LowLevel {
+ // Defines structures, enumerations, and types used by Win32 API calls. In some cases, the API
+ // calls support (and even document) many more values than what are listed here. Should
+ // additional values be required, they can be added to the respective types.
+ public static class LowLevelTypes {
+
+ #region Constants and Enums
+ // Represents the image format of a DLL or executable.
+ public enum ImageFormat {
+ NATIVE,
+ MANAGED,
+ UNKNOWN
+ }
+
+ // Flags used for opening a file handle (e.g. in a call to CreateFile), that determine the
+ // requested permission level.
+ [Flags]
+ public enum FileAccessFlags : uint {
+ GENERIC_WRITE = 0x40000000,
+ GENERIC_READ = 0x80000000
+ }
+
+ // Value used for CreateFile to determine how to behave in the presence (or absence) of a
+ // file with the requested name. Used only for CreateFile.
+ public enum FileCreationDisposition : uint {
+ CREATE_NEW = 1,
+ CREATE_ALWAYS = 2,
+ OPEN_EXISTING = 3,
+ OPEN_ALWAYS = 4,
+ TRUNCATE_EXISTING = 5
+ }
+
+ // Flags that determine what level of sharing this application requests on the target file.
+ // Used only for CreateFile.
+ [Flags]
+ public enum FileShareFlags : uint {
+ EXCLUSIVE_ACCESS = 0x0,
+ SHARE_READ = 0x1,
+ SHARE_WRITE = 0x2,
+ SHARE_DELETE = 0x4
+ }
+
+ // Flags that control caching and other behavior of the underlying file object. Used only for
+ // CreateFile.
+ [Flags]
+ public enum FileFlagsAndAttributes : uint {
+ NORMAL = 0x80,
+ OPEN_REPARSE_POINT = 0x200000,
+ SEQUENTIAL_SCAN = 0x8000000,
+ RANDOM_ACCESS = 0x10000000,
+ NO_BUFFERING = 0x20000000,
+ OVERLAPPED = 0x40000000
+ }
+
+ // The target architecture of a given executable image. The various values correspond to the
+ // magic numbers defined by the PE Executable Image File Format.
+ // http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
+ public enum MachineType : ushort {
+ UNKNOWN = 0x0,
+ X64 = 0x8664,
+ X86 = 0x14c,
+ IA64 = 0x200
+ }
+
+ // A flag indicating the format of the path string that Windows returns from a call to
+ // QueryFullProcessImageName().
+ public enum ProcessQueryImageNameMode : uint {
+ WIN32_FORMAT = 0,
+ NATIVE_SYSTEM_FORMAT = 1
+ }
+
+ // Flags indicating the level of permission requested when opening a handle to an external
+ // process. Used by OpenProcess().
+ [Flags]
+ public enum ProcessAccessFlags : uint {
+ NONE = 0x0,
+ ALL = 0x001F0FFF,
+ VM_OPERATION = 0x00000008,
+ VM_READ = 0x00000010,
+ QUERY_INFORMATION = 0x00000400,
+ QUERY_LIMITED_INFORMATION = 0x00001000
+ }
+
+ // Defines return value codes used by various Win32 System APIs.
+ public enum NTSTATUS : int {
+ SUCCESS = 0,
+ }
+
+ // Determines the amount of information requested (and hence the type of structure returned)
+ // by a call to NtQueryInformationProcess.
+ public enum PROCESSINFOCLASS : int {
+ PROCESS_BASIC_INFORMATION = 0
+ };
+ #endregion
+
+ #region Structures
+ // In general, for all structures below which contains a pointer (represented here by IntPtr),
+ // the pointers refer to memory in the address space of the process from which the original
+ // structure was read. While this seems obvious, it means we cannot provide an elegant
+ // interface to the various fields in the structure due to the de-reference requiring a
+ // handle to the target process. Instead, that functionality needs to be provided at a
+ // higher level.
+ //
+ // Additionally, since we usually explicitly define the fields that we're interested in along
+ // with their respective offsets, we frequently specify the exact size of the native structure.
+
+ // Win32 UNICODE_STRING structure.
+ [StructLayout(LayoutKind.Sequential)]
+ public struct UNICODE_STRING {
+ // The length in bytes of the string pointed to by buffer, not including the null-terminator.
+ private ushort length;
+ // The total allocated size in memory pointed to by buffer.
+ private ushort maximumLength;
+ // A pointer to the buffer containing the string data.
+ private IntPtr buffer;
+
+ public ushort Length { get { return length; } }
+ public ushort MaximumLength { get { return maximumLength; } }
+ public IntPtr Buffer { get { return buffer; } }
+ }
+
+ // Win32 RTL_USER_PROCESS_PARAMETERS structure.
+ [StructLayout(LayoutKind.Explicit, Size = 72)]
+ public struct RTL_USER_PROCESS_PARAMETERS {
+ [FieldOffset(56)]
+ private UNICODE_STRING imagePathName;
+ [FieldOffset(64)]
+ private UNICODE_STRING commandLine;
+
+ public UNICODE_STRING ImagePathName { get { return imagePathName; } }
+ public UNICODE_STRING CommandLine { get { return commandLine; } }
+ };
+
+ // Win32 PEB structure. Represents the process environment block of a process.
+ [StructLayout(LayoutKind.Explicit, Size = 472)]
+ public struct PEB {
+ [FieldOffset(2), MarshalAs(UnmanagedType.U1)]
+ private bool isBeingDebugged;
+ [FieldOffset(12)]
+ private IntPtr ldr;
+ [FieldOffset(16)]
+ private IntPtr processParameters;
+ [FieldOffset(468)]
+ private uint sessionId;
+
+ public bool IsBeingDebugged { get { return isBeingDebugged; } }
+ public IntPtr Ldr { get { return ldr; } }
+ public IntPtr ProcessParameters { get { return processParameters; } }
+ public uint SessionId { get { return sessionId; } }
+ };
+
+ // Win32 PROCESS_BASIC_INFORMATION. Contains a pointer to the PEB, and various other
+ // information about a process.
+ [StructLayout(LayoutKind.Explicit, Size = 24)]
+ public struct PROCESS_BASIC_INFORMATION {
+ [FieldOffset(4)]
+ private IntPtr pebBaseAddress;
+ [FieldOffset(16)]
+ private UIntPtr uniqueProcessId;
+
+ public IntPtr PebBaseAddress { get { return pebBaseAddress; } }
+ public UIntPtr UniqueProcessId { get { return uniqueProcessId; } }
+ }
+ #endregion
+ }
+}
diff --git a/tools/win/ChromeDebug/README.txt b/tools/win/ChromeDebug/README.txt
new file mode 100644
index 0000000..6039462
--- /dev/null
+++ b/tools/win/ChromeDebug/README.txt
@@ -0,0 +1,5 @@
+Usage Instructions:
+
+1) Compile with VS2012 or VS2013.
+2) Double click the .vsix in the output directory.
+3) Choose the version of VS to install to. \ No newline at end of file