private void TJ1() { //if (KProcessHacker.Instance != null) //{ // try // { // using (ProcessHandle phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights)) // { // JobObjectHandle jhandle = phandle.GetJobObject(JobObjectAccess.Query | JobObjectAccess.Terminate); // // Make sure we're not terminating more than one process // if (jhandle.ProcessIdList.Length == 1) // { // jhandle.Terminate(); // } // } // } // catch // { } //} using (JobObjectHandle jhandle = JobObjectHandle.Create(JobObjectAccess.AssignProcess | JobObjectAccess.Terminate)) { using (ProcessHandle phandle = new ProcessHandle(_pid, ProcessAccess.SetQuota | ProcessAccess.Terminate)) { phandle.AssignToJobObject(jhandle); } jhandle.Terminate(); } }
public static void Main(string[] args) { string filepath = Path.Combine(typeof(TestProgramMemoryUsage.Program).Assembly.Location); var process1 = Process.Start(filepath); var process2 = Process.Start(filepath); var security = new JobObjectSecurity(true); security.AddAccessRule(new NTAccount("Everyone"), JobObjectAccessRights.AllAccess, AccessControlType.Allow); using (var job = JobObjectHandle.Create(security, "Foobar")) { var extendedLimitInformation = new ExtendedLimitInformation { KillOnJobClose = true, JobMemoryLimit = 3 * 1024 * 1024 * 1024UL, ProcessMemoryLimit = 100 * 1024 * 1024, }; job.SetInformation(extendedLimitInformation); job.AssignProcess(process1); using (var job2 = JobObjectHandle.Open("Foobar")) { job2.AssignProcess(process2); var extendedLimitInformation2 = job2.GetInformation <ExtendedLimitInformation>(); var basicAccountingInformation = job2.GetInformation <BasicAndIoAccountingInformation>(); var basicUiRestrictions = job2.GetInformation <BasicUiRestrictions>(); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(intercept: true); } }
public JobWindow(JobObjectHandle jobHandle) { InitializeComponent(); this.AddEscapeToClose(); this.SetTopMost(); _jobProps = new JobProperties(jobHandle); _jobProps.Dock = DockStyle.Fill; panelJob.Controls.Add(_jobProps); }
public void GivenJobWithKillOnJobClose_WhenDisposingJob_ThenProcessIsStopped() { Process process = Process.Start(typeof(Program).Assembly.Location); using (var job = JobObjectHandle.Create()) { job.SetInformation(new ExtendedLimitInformation { KillOnJobClose = true, }); job.AssignProcess(process); } Assert.True(process.HasExited); Assert.Equal(0, process.ExitCode); }
public void GivenJobObjectWithoutMemoryLimit_ThenOutOfMemoryIsNotThrown() { Process process = Process.Start(typeof(TestProgramMemoryUsage.Program).Assembly.Location); using (var job = JobObjectHandle.Create()) { job.SetInformation(new ExtendedLimitInformation { }); job.AssignProcess(process); } process.WaitForExit(); Assert.Equal(0, process.ExitCode); }
private void buttonTerminate_Click(object sender, EventArgs e) { if (OSVersion.HasTaskDialogs) { TaskDialog td = new TaskDialog { WindowTitle = "Process Hacker", MainInstruction = "Do you want to terminate the job?", Content = "Terminating a job will terminate all processes assigned to it. Are you sure " + "you want to continue?", MainIcon = TaskDialogIcon.Warning, DefaultButton = (int)DialogResult.No, Buttons = new TaskDialogButton[] { new TaskDialogButton((int)DialogResult.Yes, "Terminate"), new TaskDialogButton((int)DialogResult.No, "Cancel") } }; if (td.Show(this) == (int)DialogResult.No) { return; } } else { if (MessageBox.Show( "Are you sure you want to terminate the job? This action will " + "terminate all processes associated with the job.", "Process Hacker", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No) { return; } } try { using (NativeHandle <JobObjectAccess> jhandle2 = _jobObject.Duplicate(JobObjectAccess.Terminate)) JobObjectHandle.FromHandle(jhandle2).Terminate(); } catch (Exception ex) { PhUtils.ShowException("Unable to terminate the job", ex); } }
private void TJ1() { if (KProcessHacker.Instance != null) { try { using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights)) { var jhandle = phandle.GetJobObject(JobObjectAccess.Query | JobObjectAccess.Terminate); if (jhandle != null) { // Make sure we're not terminating more than one process if (jhandle.GetProcessIdList().Length == 1) { jhandle.Terminate(); return; } } } } catch { } } using (var jhandle = JobObjectHandle.Create(JobObjectAccess.AssignProcess | JobObjectAccess.Terminate)) { using (ProcessHandle phandle = new ProcessHandle(_pid, ProcessAccess.SetQuota | ProcessAccess.Terminate)) { phandle.AssignToJobObject(jhandle); } jhandle.Terminate(); } }
public IJobObject Create(string name = null) { var handle = JobObjectHandle.Create(name); return(new JobObject(handle)); }
public IJobObject Open(string name, bool inheritHandle = false, JobObjectAccessRights desiredAccess = JobObjectAccessRights.AllAccess) { var handle = JobObjectHandle.Open(name, inheritHandle, desiredAccess); return(new JobObject(handle)); }
public IJobObject Create(JobObjectSecurity jobObjectSecurity, string name = null) { var handle = JobObjectHandle.Create(jobObjectSecurity, name); return(new JobObject(handle)); }
public JobObjectSecurity(JobObjectHandle handle, AccessControlSections includeSections, bool isContainer = false) : base(isContainer, ResourceType.KernelObject, handle, includeSections) { }
public static extern bool IsProcessInJob(ProcessHandle processHandle, JobObjectHandle jobHandle, out bool result);
public bool IsProcessInJob(JobObjectHandle jobHandle) { bool result; if (!NativeMethods.IsProcessInJob(this, jobHandle, out result)) { ErrorHelper.ThrowCustomWin32Exception(); } return result; }
public static extern bool AssignProcessToJobObject(JobObjectHandle hJob, IntPtr hProcess);
public JobProperties(JobObjectHandle jobObject) { InitializeComponent(); listProcesses.SetTheme("explorer"); listProcesses.AddShortcuts(); listProcesses.ContextMenu = listProcesses.GetCopyMenu(); listLimits.SetTheme("explorer"); listLimits.AddShortcuts(); listLimits.ContextMenu = listLimits.GetCopyMenu(); _jobObject = jobObject; _jobObject.Reference(); timerUpdate.Interval = Settings.Instance.RefreshInterval; this.UpdateStatistics(); try { string name = _jobObject.GetObjectName(); if (string.IsNullOrEmpty(name)) { textJobName.Text = "(unnamed job)"; } else { textJobName.Text = name; } } catch { } try { foreach (int pid in _jobObject.GetProcessIdList()) { ListViewItem item = new ListViewItem(); if (Program.ProcessProvider.Dictionary.ContainsKey(pid)) { item.Text = Program.ProcessProvider.Dictionary[pid].Name; } else { item.Text = "(unknown)"; } item.SubItems.Add(new ListViewItem.ListViewSubItem(item, pid.ToString())); listProcesses.Items.Add(item); } } catch { } try { var extendedLimits = _jobObject.GetExtendedLimitInformation(); var uiRestrictions = _jobObject.GetBasicUiRestrictions(); var flags = extendedLimits.BasicLimitInformation.LimitFlags; if ((flags & JobObjectLimitFlags.ActiveProcess) != 0) { this.AddLimit("Active Processes", extendedLimits.BasicLimitInformation.ActiveProcessLimit.ToString()); } if ((flags & JobObjectLimitFlags.Affinity) != 0) { this.AddLimit("Affinity", extendedLimits.BasicLimitInformation.Affinity.ToString("x")); } if ((flags & JobObjectLimitFlags.BreakawayOk) != 0) { this.AddLimit("Breakaway OK", "Enabled"); } if ((flags & JobObjectLimitFlags.DieOnUnhandledException) != 0) { this.AddLimit("Die on Unhandled Exception", "Enabled"); } if ((flags & JobObjectLimitFlags.JobMemory) != 0) { this.AddLimit("Job Memory", Utils.FormatSize(extendedLimits.JobMemoryLimit)); } if ((flags & JobObjectLimitFlags.JobTime) != 0) { this.AddLimit("Job Time", Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerJobUserTimeLimit))); } if ((flags & JobObjectLimitFlags.KillOnJobClose) != 0) { this.AddLimit("Kill on Job Close", "Enabled"); } if ((flags & JobObjectLimitFlags.PriorityClass) != 0) { this.AddLimit("Priority Class", ((System.Diagnostics.ProcessPriorityClass)extendedLimits.BasicLimitInformation.PriorityClass).ToString()); } if ((flags & JobObjectLimitFlags.ProcessMemory) != 0) { this.AddLimit("Process Memory", Utils.FormatSize(extendedLimits.ProcessMemoryLimit)); } if ((flags & JobObjectLimitFlags.ProcessTime) != 0) { this.AddLimit("Process Time", Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit))); } if ((flags & JobObjectLimitFlags.SchedulingClass) != 0) { this.AddLimit("Scheduling Class", extendedLimits.BasicLimitInformation.SchedulingClass.ToString()); } if ((flags & JobObjectLimitFlags.SilentBreakawayOk) != 0) { this.AddLimit("Silent Breakaway OK", "Enabled"); } if ((flags & JobObjectLimitFlags.WorkingSet) != 0) { this.AddLimit("Minimum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize)); this.AddLimit("Maximum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize)); } if ((uiRestrictions & JobObjectBasicUiRestrictions.Desktop) != 0) { this.AddLimit("Desktop", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.DisplaySettings) != 0) { this.AddLimit("Display Settings", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.ExitWindows) != 0) { this.AddLimit("Exit Windows", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.GlobalAtoms) != 0) { this.AddLimit("Global Atoms", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.Handles) != 0) { this.AddLimit("Handles", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.ReadClipboard) != 0) { this.AddLimit("Read Clipboard", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.SystemParameters) != 0) { this.AddLimit("System Parameters", "Limited"); } if ((uiRestrictions & JobObjectBasicUiRestrictions.WriteClipboard) != 0) { this.AddLimit("Write Clipboard", "Limited"); } } catch { } }
public static extern bool IsProcessInJob(IntPtr Process, JobObjectHandle hJob, [MarshalAs(UnmanagedType.Bool)] out bool Result);
public static void ShowHandleProperties(SystemHandleEntry handleInfo) { try { HandlePropertiesWindow window = new HandlePropertiesWindow(handleInfo); IntPtr handle = new IntPtr(handleInfo.Handle); ProcessHandle phandle = new ProcessHandle(handleInfo.ProcessId, ProcessAccess.DupHandle); GenericHandle dupHandle = null; window.HandlePropertiesCallback += (control, name, typeName) => { switch (typeName.ToLowerInvariant()) { // Objects with separate property windows: case "file": case "job": case "key": case "token": case "process": { Button b = new Button(); b.FlatStyle = FlatStyle.System; b.Text = "Properties"; b.Click += (sender, e) => { try { switch (typeName.ToLowerInvariant()) { case "file": { FileUtils.ShowProperties(name); } break; case "job": { dupHandle = new GenericHandle( phandle, handle, (int)JobObjectAccess.Query); (new JobWindow(JobObjectHandle.FromHandle(dupHandle))).ShowDialog(); } break; case "key": { try { PhUtils.OpenKeyInRegedit(PhUtils.GetForegroundWindow(), name); } catch (Exception ex) { PhUtils.ShowException("Unable to open the Registry Editor", ex); } } break; case "token": { (new TokenWindow(new RemoteTokenHandle(phandle, handle))).ShowDialog(); } break; case "process": { int pid; if (KProcessHacker.Instance != null) { pid = KProcessHacker.Instance.KphGetProcessId(phandle, handle); } else { dupHandle = new GenericHandle( phandle, handle, (int)OSVersion.MinProcessQueryInfoAccess); pid = ProcessHandle.FromHandle(dupHandle).GetProcessId(); } Program.GetProcessWindow(Program.ProcessProvider.Dictionary[pid], (f) => Program.FocusWindow(f)); } break; } } catch (Exception ex) { PhUtils.ShowException("Unable to show object properties", ex); } }; control.Controls.Add(b); } break; case "event": { dupHandle = new GenericHandle(phandle, handle, (int)EventAccess.QueryState); var eventProps = new EventProperties(EventHandle.FromHandle(dupHandle)); control.Controls.Add(eventProps); } break; case "eventpair": { dupHandle = new GenericHandle(phandle, handle, (int)EventPairAccess.All); var eventPairProps = new EventPairProperties(EventPairHandle.FromHandle(dupHandle)); control.Controls.Add(eventPairProps); } break; case "mutant": { dupHandle = new GenericHandle(phandle, handle, (int)MutantAccess.QueryState); var mutantProps = new MutantProperties(MutantHandle.FromHandle(dupHandle)); control.Controls.Add(mutantProps); } break; case "section": { dupHandle = new GenericHandle(phandle, handle, (int)SectionAccess.Query); var sectionProps = new SectionProperties(SectionHandle.FromHandle(dupHandle)); control.Controls.Add(sectionProps); } break; case "semaphore": { dupHandle = new GenericHandle(phandle, handle, (int)SemaphoreAccess.QueryState); var semaphoreProps = new SemaphoreProperties(SemaphoreHandle.FromHandle(dupHandle)); control.Controls.Add(semaphoreProps); } break; case "timer": { dupHandle = new GenericHandle(phandle, handle, (int)TimerAccess.QueryState); var timerProps = new TimerProperties(TimerHandle.FromHandle(dupHandle)); control.Controls.Add(timerProps); } break; case "tmrm": { dupHandle = new GenericHandle(phandle, handle, (int)ResourceManagerAccess.QueryInformation); var tmRmProps = new TmRmProperties(ResourceManagerHandle.FromHandle(dupHandle)); control.Controls.Add(tmRmProps); } break; case "tmtm": { dupHandle = new GenericHandle(phandle, handle, (int)TmAccess.QueryInformation); var tmTmProps = new TmTmProperties(TmHandle.FromHandle(dupHandle)); control.Controls.Add(tmTmProps); } break; } }; if (dupHandle == null) { // Try to get a handle, since we need one for security editing. try { dupHandle = new GenericHandle(phandle, handle, 0); } catch { } } window.ObjectHandle = dupHandle; window.ShowDialog(); if (dupHandle != null) { dupHandle.Dispose(); } } catch (Exception ex) { PhUtils.ShowException("Unable to show handle properties", ex); } }
public static extern bool TerminateJobObject(JobObjectHandle hJob, uint uExitCode);
public bool IsProcessInJob(JobObjectHandle jobObject) { return _handle.IsProcessInJob(jobObject); }
public static extern bool QueryInformationJobObject(JobObjectHandle hJob, JobObjectInfoClass JobObjectInformationClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength, IntPtr lpReturnLength);
public static extern bool SetInformationJobObject(JobObjectHandle hJob, JobObjectInfoClass JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
public JobProperties(JobObjectHandle jobObject) { InitializeComponent(); _jobObject = jobObject; _jobObject.Reference(); timerUpdate.Interval = Properties.Settings.Default.RefreshInterval; this.UpdateStatistics(); try { string name = _jobObject.GetObjectName(); if (string.IsNullOrEmpty(name)) textJobName.Text = "(unnamed job)"; else textJobName.Text = name; } catch { } try { foreach (int pid in _jobObject.GetProcessIdList()) { ListViewItem item = new ListViewItem(); if (Program.ProcessProvider.Dictionary.ContainsKey(pid)) item.Text = Program.ProcessProvider.Dictionary[pid].Name; else item.Text = "(unknown)"; item.SubItems.Add(new ListViewItem.ListViewSubItem(item, pid.ToString())); listProcesses.Items.Add(item); } } catch { } try { var extendedLimits = _jobObject.GetExtendedLimitInformation(); var uiRestrictions = _jobObject.GetBasicUiRestrictions(); var flags = extendedLimits.BasicLimitInformation.LimitFlags; if ((flags & JobObjectLimitFlags.ActiveProcess) != 0) this.AddLimit("Active Processes", extendedLimits.BasicLimitInformation.ActiveProcessLimit.ToString()); if ((flags & JobObjectLimitFlags.Affinity) != 0) this.AddLimit("Affinity", extendedLimits.BasicLimitInformation.Affinity.ToString("x")); if ((flags & JobObjectLimitFlags.BreakawayOk) != 0) this.AddLimit("Breakaway OK", "Enabled"); if ((flags & JobObjectLimitFlags.DieOnUnhandledException) != 0) this.AddLimit("Die on Unhandled Exception", "Enabled"); if ((flags & JobObjectLimitFlags.JobMemory) != 0) this.AddLimit("Job Memory", Utils.FormatSize(extendedLimits.JobMemoryLimit)); if ((flags & JobObjectLimitFlags.JobTime) != 0) this.AddLimit("Job Time", Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerJobUserTimeLimit))); if ((flags & JobObjectLimitFlags.KillOnJobClose) != 0) this.AddLimit("Kill on Job Close", "Enabled"); if ((flags & JobObjectLimitFlags.PriorityClass) != 0) this.AddLimit("Priority Class", ((System.Diagnostics.ProcessPriorityClass)extendedLimits.BasicLimitInformation.PriorityClass).ToString()); if ((flags & JobObjectLimitFlags.ProcessMemory) != 0) this.AddLimit("Process Memory", Utils.FormatSize(extendedLimits.ProcessMemoryLimit)); if ((flags & JobObjectLimitFlags.ProcessTime) != 0) this.AddLimit("Process Time", Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit))); if ((flags & JobObjectLimitFlags.SchedulingClass) != 0) this.AddLimit("Scheduling Class", extendedLimits.BasicLimitInformation.SchedulingClass.ToString()); if ((flags & JobObjectLimitFlags.SilentBreakawayOk) != 0) this.AddLimit("Silent Breakaway OK", "Enabled"); if ((flags & JobObjectLimitFlags.WorkingSet) != 0) { this.AddLimit("Minimum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize)); this.AddLimit("Maximum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize)); } if ((uiRestrictions & JobObjectBasicUiRestrictions.Desktop) != 0) this.AddLimit("Desktop", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.DisplaySettings) != 0) this.AddLimit("Display Settings", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.ExitWindows) != 0) this.AddLimit("Exit Windows", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.GlobalAtoms) != 0) this.AddLimit("Global Atoms", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.Handles) != 0) this.AddLimit("Handles", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.ReadClipboard) != 0) this.AddLimit("Read Clipboard", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.SystemParameters) != 0) this.AddLimit("System Parameters", "Limited"); if ((uiRestrictions & JobObjectBasicUiRestrictions.WriteClipboard) != 0) this.AddLimit("Write Clipboard", "Limited"); } catch { } }
public static void ShowHandleProperties(SystemHandleEntry handleInfo) { try { IntPtr handle = new IntPtr(handleInfo.Handle); ProcessHandle phandle = new ProcessHandle(handleInfo.ProcessId, ProcessAccess.DupHandle); GenericHandle dupHandle = null; // Try to get a handle, since we need one for security editing. try { dupHandle = new GenericHandle(phandle, handle, 0); } catch { } PropSheetHeader64 header = new PropSheetHeader64 { dwSize = (uint)PropSheetHeader64.SizeOf, nPages = 2, dwFlags = (uint)PropSheetFlags.PSH_DEFAULT, pszCaption = "Handle Properties" }; using (HandleDetails hw = new HandleDetails()) { hw.ObjectHandle = handleInfo; hw.HandlePropertiesCallback += (control, name, typeName) => { switch (typeName.ToLowerInvariant()) { // Objects with separate property windows: case "file": case "job": case "key": case "token": case "process": { Button b = new Button { FlatStyle = FlatStyle.System, Text = "Properties" }; b.Click += (sender, e) => { try { switch (typeName.ToLowerInvariant()) { case "file": { FileUtils.ShowProperties(name); } break; case "job": { dupHandle = new GenericHandle(phandle, handle, (int)JobObjectAccess.Query); (new JobWindow(JobObjectHandle.FromHandle(dupHandle))).ShowDialog(); } break; case "key": { try { PhUtils.OpenKeyInRegedit(PhUtils.GetForegroundWindow(), name); } catch (Exception ex) { PhUtils.ShowException("Unable to open the Registry Editor", ex); } } break; case "token": { using (TokenWindow twindow = new TokenWindow(new RemoteTokenHandle(phandle, handle))) { twindow.ShowDialog(); } } break; case "process": { dupHandle = new GenericHandle(phandle, handle, (int)OSVersion.MinProcessQueryInfoAccess); int pid = ProcessHandle.FromHandle(dupHandle).ProcessId; Program.GetProcessWindow(Program.ProcessProvider.Dictionary[pid], Program.FocusWindow); } break; } } catch (Exception ex) { PhUtils.ShowException("Unable to show object properties", ex); } }; control.Controls.Add(b); } break; case "event": { dupHandle = new GenericHandle(phandle, handle, (int)EventAccess.QueryState); var eventProps = new EventProperties(EventHandle.FromHandle(dupHandle)); control.Controls.Add(eventProps); } break; case "eventpair": { dupHandle = new GenericHandle(phandle, handle, (int)EventPairAccess.All); var eventPairProps = new EventPairProperties(EventPairHandle.FromHandle(dupHandle)); control.Controls.Add(eventPairProps); } break; case "mutant": { dupHandle = new GenericHandle(phandle, handle, (int)MutantAccess.QueryState); var mutantProps = new MutantProperties(MutantHandle.FromHandle(dupHandle)); control.Controls.Add(mutantProps); } break; case "section": { dupHandle = new GenericHandle(phandle, handle, (int)SectionAccess.Query); var sectionProps = new SectionProperties(SectionHandle.FromHandle(dupHandle)); control.Controls.Add(sectionProps); } break; case "semaphore": { dupHandle = new GenericHandle(phandle, handle, (int)SemaphoreAccess.QueryState); var semaphoreProps = new SemaphoreProperties(SemaphoreHandle.FromHandle(dupHandle)); control.Controls.Add(semaphoreProps); } break; case "timer": { dupHandle = new GenericHandle(phandle, handle, (int)TimerAccess.QueryState); var timerProps = new TimerProperties(TimerHandle.FromHandle(dupHandle)); control.Controls.Add(timerProps); } break; case "tmrm": { dupHandle = new GenericHandle(phandle, handle, (int)ResourceManagerAccess.QueryInformation); var tmRmProps = new TmRmProperties(ResourceManagerHandle.FromHandle(dupHandle)); control.Controls.Add(tmRmProps); } break; case "tmtm": { dupHandle = new GenericHandle(phandle, handle, (int)TmAccess.QueryInformation); var tmTmProps = new TmTmProperties(TmHandle.FromHandle(dupHandle)); control.Controls.Add(tmTmProps); } break; } }; hw.Init(); IntPtr[] pages = new IntPtr[2]; pages[0] = hw.CreatePageHandle(); pages[1] = CreateSecurityPage(SecurityEditor.EditSecurity2( null, SecurityEditor.GetSecurableWrapper(dupHandle), hw._name, NativeTypeFactory.GetAccessEntries(NativeTypeFactory.GetObjectType(hw._typeName)) )); GCHandle gch = GCHandle.Alloc(pages, GCHandleType.Pinned); header.phpage = gch.AddrOfPinnedObject(); PropertySheetW(ref header); if (dupHandle != null) { dupHandle.Dispose(); } } } catch (Exception ex) { PhUtils.ShowException("Unable to show handle properties", ex); } }