diff --git a/trunk/CHANGELOG.txt b/trunk/CHANGELOG.txt
index b650a2fc9..c8c881adb 100644
--- a/trunk/CHANGELOG.txt
+++ b/trunk/CHANGELOG.txt
@@ -8,6 +8,7 @@ Process Hacker
Analyze > Wait to see what a thread is hanging on
* More detailed handle properties
* Event objects can now be modified - set, clear, pulse, reset
+ * Event pair objects can now be modified - set high, set low
* Semaphore objects can now be modified - acquire, release
* FIXED:
* #2795871 - "Hidden Processes window resizing problem"
diff --git a/trunk/ProcessHacker.Native/Objects/EventPairHandle.cs b/trunk/ProcessHacker.Native/Objects/EventPairHandle.cs
index 2cf9275d7..16daaadf0 100644
--- a/trunk/ProcessHacker.Native/Objects/EventPairHandle.cs
+++ b/trunk/ProcessHacker.Native/Objects/EventPairHandle.cs
@@ -74,6 +74,11 @@ namespace ProcessHacker.Native.Objects
return new EventPairHandle(handle, true);
}
+ public static EventPairHandle FromHandle(IntPtr handle)
+ {
+ return new EventPairHandle(handle, false);
+ }
+
private EventPairHandle(IntPtr handle, bool owned)
: base(handle, owned)
{ }
diff --git a/trunk/ProcessHacker/Components/EventPairProperties.Designer.cs b/trunk/ProcessHacker/Components/EventPairProperties.Designer.cs
new file mode 100644
index 000000000..8f6aadedb
--- /dev/null
+++ b/trunk/ProcessHacker/Components/EventPairProperties.Designer.cs
@@ -0,0 +1,75 @@
+namespace ProcessHacker.Components
+{
+ partial class EventPairProperties
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.buttonSetHigh = new System.Windows.Forms.Button();
+ this.buttonSetLow = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // buttonSetHigh
+ //
+ this.buttonSetHigh.FlatStyle = System.Windows.Forms.FlatStyle.System;
+ this.buttonSetHigh.Location = new System.Drawing.Point(6, 6);
+ this.buttonSetHigh.Name = "buttonSetHigh";
+ this.buttonSetHigh.Size = new System.Drawing.Size(75, 23);
+ this.buttonSetHigh.TabIndex = 0;
+ this.buttonSetHigh.Text = "Set High";
+ this.buttonSetHigh.UseVisualStyleBackColor = true;
+ this.buttonSetHigh.Click += new System.EventHandler(this.buttonSetHigh_Click);
+ //
+ // buttonSetLow
+ //
+ this.buttonSetLow.FlatStyle = System.Windows.Forms.FlatStyle.System;
+ this.buttonSetLow.Location = new System.Drawing.Point(87, 6);
+ this.buttonSetLow.Name = "buttonSetLow";
+ this.buttonSetLow.Size = new System.Drawing.Size(75, 23);
+ this.buttonSetLow.TabIndex = 0;
+ this.buttonSetLow.Text = "Set Low";
+ this.buttonSetLow.UseVisualStyleBackColor = true;
+ this.buttonSetLow.Click += new System.EventHandler(this.buttonSetLow_Click);
+ //
+ // EventPairProperties
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.buttonSetLow);
+ this.Controls.Add(this.buttonSetHigh);
+ this.Name = "EventPairProperties";
+ this.Padding = new System.Windows.Forms.Padding(3);
+ this.Size = new System.Drawing.Size(212, 63);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button buttonSetHigh;
+ private System.Windows.Forms.Button buttonSetLow;
+ }
+}
diff --git a/trunk/ProcessHacker/Components/EventPairProperties.cs b/trunk/ProcessHacker/Components/EventPairProperties.cs
new file mode 100644
index 000000000..bc48f5e6d
--- /dev/null
+++ b/trunk/ProcessHacker/Components/EventPairProperties.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using ProcessHacker.Native.Objects;
+using ProcessHacker.Native.Security;
+
+namespace ProcessHacker.Components
+{
+ public partial class EventPairProperties : UserControl
+ {
+ private EventPairHandle _eventPairHandle;
+
+ public EventPairProperties(EventPairHandle eventPairHandle)
+ {
+ InitializeComponent();
+
+ _eventPairHandle = eventPairHandle;
+ }
+
+ private void buttonSetHigh_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ _eventPairHandle.SetHigh();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ private void buttonSetLow_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ _eventPairHandle.SetLow();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ }
+}
diff --git a/trunk/ProcessHacker/Components/EventPairProperties.resx b/trunk/ProcessHacker/Components/EventPairProperties.resx
new file mode 100644
index 000000000..ff31a6db5
--- /dev/null
+++ b/trunk/ProcessHacker/Components/EventPairProperties.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/trunk/ProcessHacker/Components/HandleList.cs b/trunk/ProcessHacker/Components/HandleList.cs
index f3efd3241..01eac4705 100644
--- a/trunk/ProcessHacker/Components/HandleList.cs
+++ b/trunk/ProcessHacker/Components/HandleList.cs
@@ -421,6 +421,14 @@ namespace ProcessHacker.Components
control.Controls.Add(eventProps);
}
break;
+ case "eventpair":
+ {
+ dupHandle = new GenericHandle(phandle, handle, (int)EventPairAccess.All);
+ var eventPairProps = new EventPairProperties(EventPairHandle.FromHandle(dupHandle));
+ eventPairProps.Location = new Point(10, 20);
+ control.Controls.Add(eventPairProps);
+ }
+ break;
case "mutant":
{
dupHandle = new GenericHandle(phandle, handle, (int)MutantAccess.QueryState);
diff --git a/trunk/ProcessHacker/Components/ThreadList.cs b/trunk/ProcessHacker/Components/ThreadList.cs
index b4f7c79e4..39858a09e 100644
--- a/trunk/ProcessHacker/Components/ThreadList.cs
+++ b/trunk/ProcessHacker/Components/ThreadList.cs
@@ -861,6 +861,8 @@ namespace ProcessHacker.Components
using (var thandle = new ThreadHandle(tid, ThreadAccess.GetContext | ThreadAccess.SuspendResume))
{
+ IntPtr[] lastParams = new IntPtr[4];
+
thandle.WalkStack(phandle, (stackFrame) =>
{
uint address = stackFrame.PcAddress.ToUInt32();
@@ -974,6 +976,10 @@ namespace ProcessHacker.Components
IntPtr handle = stackFrame.Params[0];
+ // Use the KiFastSystemCallRet args if the handle we have is wrong.
+ if (handle.ToInt32() % 2 != 0)
+ handle = lastParams[1];
+
sb.AppendLine("Thread " + tid.ToString() + " is waiting (" + name + ") for an event pair:");
sb.AppendLine(this.GetHandleString(_pid, handle));
@@ -1073,6 +1079,8 @@ namespace ProcessHacker.Components
sb.AppendLine(this.GetHandleString(_pid, handle));
}
+ lastParams = stackFrame.Params;
+
return !found;
});
}
diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj
index be175ef68..8689068c4 100644
--- a/trunk/ProcessHacker/ProcessHacker.csproj
+++ b/trunk/ProcessHacker/ProcessHacker.csproj
@@ -125,6 +125,9 @@
ColorModifier.cs
Designer
+
+ EventPairProperties.cs
+
EventProperties.cs
@@ -348,6 +351,12 @@
+
+ UserControl
+
+
+ EventPairProperties.cs
+
UserControl