pipelist.psm1

using namespace System.IO
using namespace System.Reflection
using namespace System.Linq.Expressions
using namespace System.Runtime.InteropServices

$keys, $types = ($x = [PSObject].Assembly.GetType(
  'System.Management.Automation.TypeAccelerators'
))::Get.Keys, @{
  buf = [Byte[]]
  ptr = [IntPtr]
  sfh = [Microsoft.Win32.SafeHandles.SafeFileHandle]
}
$types.Keys.ForEach{ if ($_ -notin $keys) { $x::Add($_, $types.$_) } }

Add-Member -InputObject ([buf]) -Name Uni -MemberType ScriptMethod -Value {
  param([String]$str) [Text.Encoding]::Unicode.GetBytes($str)
} -Force

function New-Delegate {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory, Position=0)]
    [ValidateNotNullOrEmpty()]
    [String]$Module,

    [Parameter(Mandatory, Position=1)]
    [ValidateScript({![String]::IsNullOrEmpty($_)})]
    [ScriptBlock]$Signature
  )

  begin {
    $kernel32 = @{}
    [Array]::Find((
      Add-Type -AssemblyName Microsoft.Win32.SystemEvents -PassThru
    ), [Predicate[Type]]{$args[0].Name -eq 'kernel32'}
    ).GetMethods([BindingFlags]'NonPublic, Static, Public').Where{
      $_.Name -cmatch '\AGet(P|M)'
    }.ForEach{ $kernel32[$_.Name] = $_ }

    if ((
      $mod = $kernel32.GetModuleHandle.Invoke($null, @($Module))
    ) -eq [IntPtr]::Zero) {
      throw [DllNotFoundException]::new("Can not find $Module library.")
    }
  }
  process {}
  end {
    $funcs = @{}
    for ($i, $m, $fn, $p = 0, ([Expression].Assembly.GetType(
        'System.Linq.Expressions.Compiler.DelegateHelpers'
      ).GetMethod('MakeNewCustomDelegate', [BindingFlags]'NonPublic, Static')
      ), [Marshal].GetMethod('GetDelegateForFunctionPointer', ([IntPtr])),
      $Signature.Ast.FindAll({$args[0].CommandElements}, $true).ToArray();
      $i -lt $p.Length; $i++
    ) {
      $fnret, $fname = ($def = $p[$i].CommandElements).Value

      if ((
        $fnsig = $kernel32.GetProcAddress.Invoke($null, @($mod, $fname))
      ) -eq [IntPtr]::Zero) {
        throw [InvalidOperationException]::new("Can not find $fname signature.")
      }

      $fnargs = $def.Pipeline.Extent.Text
      [Object[]]$fnargs = ((
        ($fnargs -replace '\[|\]' -split ',\s+?') + $fnret
      ), $fnret)[[String]::IsNullOrEmpty($fnargs)]

      $funcs[$fname] = $fn.MakeGenericMethod(
        [Delegate]::CreateDelegate([Func[[Type[]], Type]], $m).Invoke($fnargs)
      ).Invoke([Marshal], $fnsig)
    }
    Set-Variable $Module -Value $funcs -Scope Script -Force
  }
}

Set-Alias -Name pipelist -Value Get-PipeList
function Get-PipeList {
  [CmdletBinding()]param()

  process {
    New-Delegate kernel32 {
      sfh CreateFileW([buf, int, FileShare, ptr, FileMode, int, ptr])
    }

    New-Delegate ntdll {
      int NtQueryDirectoryFile([sfh, ptr, ptr, ptr, buf, ptr, uint, uint, bool, ptr, uint])
    }

    $to_i = "ToInt$([IntPtr]::Size * 8)"

    if (($pipes = $kernel32.CreateFileW.Invoke(
      [buf].Uni('\\.\pipe\'), 0x80000000, [FileShare]::Read,
      [IntPtr]::Zero, [FileMode]::Open, 0, [IntPtr]::Zero
    )).IsInvalid) {
      throw [InvalidOperationException]::new('\\.\pipe\ is unavailable.')
    }

    $query, $isb = $true, [Byte[]]::new([IntPtr]::Size * 2)
    try {
      $dir = [Marshal]::AllocHGlobal(0x1000)
      while (1) {
        if ($ntdll.NtQueryDirectoryFile.Invoke(
          $pipes, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero,
          $isb, $dir, 0x1000, 1, $false, [IntPtr]::Zero, $query
        ) -ne 0) { break }

        $tmp = $dir
        while (1) {
          $NextEntryOffset = [Marshal]::ReadInt32($tmp)
          $FileNameLength = [Marshal]::ReadInt32($tmp, 0x3C) / 2
          [PSCustomObject]@{
            PipeName = [Marshal]::PtrToStringUni([IntPtr]($tmp.$to_i() + 0x40), $FileNameLength)
            Instances = [Marshal]::ReadInt64($tmp, 0x28)
            MaxInstances = [BitConverter]::ToInt32(
              [BitConverter]::GetBytes([Marshal]::ReadInt64($tmp, 0x30))[0..3], 0
            )
          }

          if (!$NextEntryOffset) { break }
          $tmp = [IntPtr]($tmp.$to_i() + $NextEntryOffset)
        }

        $query = $false
      }
    }
    catch { Write-Verbose $_ }
    finally { if ($dir) { [Marshal]::FreeHGlobal($dir) } }

    $pipes.Dispose()
    Write-Verbose "$($pipes.IsClosed)"
  }
}

Export-ModuleMember -Alias pipelist -Function Get-PipeList