Skip to content

Commit

Permalink
Improve ProcessExtensions
Browse files Browse the repository at this point in the history
  • Loading branch information
nxtn committed Jan 2, 2021
1 parent 3c5d67e commit d771e47
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/WinSW.Core/Native/Handle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace WinSW.Native
{
[StructLayout(LayoutKind.Sequential)]
internal readonly ref struct Handle
internal readonly struct Handle : IDisposable
{
private readonly IntPtr handle;

Expand Down
8 changes: 8 additions & 0 deletions src/WinSW.Core/Native/ProcessApis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,20 @@ internal static extern int NtQueryInformationProcess(
int processInformationLength,
IntPtr returnLength = default);

[DllImport(Libraries.Kernel32)]
internal static extern Handle OpenProcess(ProcessAccess desiredAccess, bool inheritHandle, int processId);

[DllImport(Libraries.Advapi32, SetLastError = true)]
internal static extern bool OpenProcessToken(
IntPtr processHandle,
TokenAccessLevels desiredAccess,
out Handle tokenHandle);

internal enum ProcessAccess : uint
{
QueryInformation = 0x0400,
}

internal enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
Expand Down
68 changes: 38 additions & 30 deletions src/WinSW.Core/Util/ProcessExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ public static void StopTree(this Process process, int millisecondsTimeout)

foreach (var child in GetChildren(process))
{
using (child)
using (child.Process)
using (child.Handle)
{
StopTree(child, millisecondsTimeout);
StopTree(child.Process, millisecondsTimeout);
}
}
}
Expand All @@ -31,54 +32,61 @@ internal static void StopDescendants(this Process process, int millisecondsTimeo
{
foreach (var child in GetChildren(process))
{
using (child)
using (child.Process)
using (child.Handle)
{
StopTree(child, millisecondsTimeout);
StopTree(child.Process, millisecondsTimeout);
}
}
}

internal static unsafe List<Process> GetChildren(this Process process)
// The handle is to keep a reference to the process.
internal static unsafe List<(Process Process, Handle Handle)> GetChildren(this Process process)
{
var startTime = process.StartTime;
int processId = process.Id;

var children = new List<Process>();
var children = new List<(Process Process, Handle Handle)>();

foreach (var other in Process.GetProcesses())
{
var handle = OpenProcess(ProcessAccess.QueryInformation, false, other.Id);
if (handle == IntPtr.Zero)
{
goto Next;
}

try
{
if (other.StartTime <= startTime)
{
goto Next;
}

var handle = other.Handle;

if (NtQueryInformationProcess(
handle,
PROCESSINFOCLASS.ProcessBasicInformation,
out var information,
sizeof(PROCESS_BASIC_INFORMATION)) != 0)
{
goto Next;
}

if ((int)information.InheritedFromUniqueProcessId == processId)
{
Log.Debug($"Found child process '{other.Format()}'.");
children.Add(other);
continue;
}

Next:
other.Dispose();
}
catch (Exception e) when (e is InvalidOperationException || e is Win32Exception)
{
other.Dispose();
goto Next;
}

if (NtQueryInformationProcess(
handle,
PROCESSINFOCLASS.ProcessBasicInformation,
out var information,
sizeof(PROCESS_BASIC_INFORMATION)) != 0)
{
goto Next;
}

if ((int)information.InheritedFromUniqueProcessId == processId)
{
Log.Debug($"Found child process '{other.Format()}'.");
children.Add((other, handle));
continue;
}

Next:
other.Dispose();
handle.Dispose();
}

return children;
Expand All @@ -94,7 +102,7 @@ internal static unsafe List<Process> GetChildren(this Process process)
return null;
}

if (!(SendCtrlC(process) is bool sent))
if (SendCtrlC(process) is not bool sent)
{
return null;
}
Expand Down Expand Up @@ -143,7 +151,7 @@ private static void StopPrivate(Process process, int millisecondsTimeout)
goto Exited;
}

if (!(SendCtrlC(process) is bool sent))
if (SendCtrlC(process) is not bool sent)
{
goto Exited;
}
Expand Down
8 changes: 6 additions & 2 deletions src/WinSW/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -880,8 +880,12 @@ static void Draw(Process process, string indentation, bool isLastChild)
int count = children.Count;
for (int i = 0; i < count; i++)
{
using var child = children[i];
Draw(child, indentation, i == count - 1);
var child = children[i];
using (child.Process)
using (child.Handle)
{
Draw(child.Process, indentation, i == count - 1);
}
}
}
}
Expand Down

0 comments on commit d771e47

Please sign in to comment.