usr/Get-PipeList.ps1
using namespace System.Runtime.InteropServices Set-Alias -Name pipelist -Value Get-PipeList function Get-PipeList { [CmdletBinding()]param() begin { New-Structure LARGE_INTEGER { Int64 'QuadPart 0' UInt32 'LowPart 0' Int32 'iLowPart 0' Int32 'HighPart 4' UInt32 'dwHighPart 4' } -Explicit -PackingSize Size8 New-Structure FILE_DIRECTORY_INFORMATION { UInt32 NextEntryOffset UInt32 FileIndex LARGE_INTEGER CreationTime LARGE_INTEGER LastAccessTime LARGE_INTEGER LastWriteTime LARGE_INTEGER ChangeTime LARGE_INTEGER EndOfFile LARGE_INTEGER AllocationSize UInt32 FileAttributes UInt32 FileNameLength String 'FileName ByValTStr 1' } -CharSet Unicode New-Structure PROCESS_BASIC_INFORMATION { Int32 ExitStatus IntPtr PebAddress UIntPtr AffinityMask Int32 BasePriorirty IntPtr UniqueProcessId IntPtr InheritedFromUniqueProcessId } New-Structure FILE_PROCESS_IDS_USING_FILE_INFORMATION { UInt32 NumberOfProcessIdsInList IntPtr[] 'ProcessIdList ByValArray 1' } $out_, $to_i = [PROCESS_BASIC_INFORMATION].MakeByRefType(), "ToInt$(($psz = [IntPtr]::Size) * 8)" New-Delegate kernelbase { sfh CreateFileW([buf, int, IO.FileShare, ptr, IO.FileMode, int, ptr]) } New-Delegate ntdll { int NtQueryDirectoryFile([sfh, ptr, ptr, ptr, buf, ptr, uint, uint, bool, ptr, bool]) int NtQueryInformationFile([sfh, buf, buf, uint, uint]) int NtQueryInformationProcess([ptr, uint, _out_, uint, buf]) } $WithoutSysPrivileges = { end { $sihost, $out = (Get-Process sihost), [PROCESS_BASIC_INFORMATION]::new() [void]$ntdll.NtQueryInformationProcess.Invoke( # getting without check status $sihost.Handle, 0, [ref]$out, $out::GetSize(), $null ) $sihost.Dispose() $out.InheritedFromUniqueProcessId.$to_i() } } } process {} end { if (($pipes = $kernelbase.CreateFileW.Invoke( [buf].Uni('\\.\pipe\'), 0x80000000, [IO.FileShare]::Read, [IntPtr]::Zero, [IO.FileMode]::Open, 0, [IntPtr]::Zero )).IsInvalid) { throw [InvalidOperationException]::new('\\.\pipe\ is unavailable.') } $query, $isb = $true, [Byte[]]::new($psz * 2) # IO_STATUS_BLOCK try { $dir = [Marshal]::AllocHGlobal(0x1000) $lst = 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.$to_i() while (1) { $fdi = [IntPtr]$tmp -as [FILE_DIRECTORY_INFORMATION] [PSCustomObject]@{ PipeName = ($name = [Marshal]::PtrToStringUni( [IntPtr]($tmp + $fdi::OfsOf('FileName')), $fdi.FileNameLength / 2 )) CI = $fdi.EndOfFile.LowPart # instances MI = $fdi.AllocationSize.iLowPart # maximum of instances Handler = $($who = switch -regex ($name) { '.*mojo\.(\d+)\.\S+' {$matches[1]} 'msys-\S+-(\S+)-.+' { $nop, $res = $matches[1], 0 [Int32]::TryParse($nop, [ref]$res) ? $( Remove-Variable msys -ErrorAction 0 -Force $local:msys = $nop $res ) : $msys } 'pipe_eventroot' { & $WithoutSysPrivileges } 'winsock2\\.+-(\S+)-0' {[Int32]"0x$($matches[1])"} default { try { if (($file = $kernelbase.CreateFileW.Invoke( [buf].Uni("\\.\pipe\$($name)"), 0, [IO.FileShare]::None, [IntPtr]::Zero, [IO.FileMode]::Open, 0, [IntPtr]::Zero )).IsInvalid) { throw [InvalidOperationException]::new('Pipe is not available.') } $ids = [Byte[]]::new([FILE_PROCESS_IDS_USING_FILE_INFORMATION]::GetSize()) do { if (($nts = $ntdll.NtQueryInformationFile.Invoke( $file, $isb, $ids, $ids.Length, 47 )) -ne 0xC0000004) { break } [Array]::Resize([ref]$ids, $ids.Length * 2) } while ($nts -eq 0xC0000004) # STATUS_INFO_LENGTH_MISMATCH (ConvertTo-PointerOrStructure $ids ( [FILE_PROCESS_IDS_USING_FILE_INFORMATION] )).ProcessIdList.$to_i() } catch { Write-Verbose $_ } finally { if ($file) { $file.Dispose() } Write-Verbose "$($file.IsClosed)" } } };'{0} ({1})' -f ($who = Get-Process -Id $who).ProcessName, $who.Id) } # pipe if (!$fdi.NextEntryOffset) {break} $tmp += $fdi.NextEntryOffset } $query = $false } } catch { Write-Verbose $_ } finally { if ($dir) {[Marshal]::FreeHGlobal($dir)}} $pipes.Dispose() Write-Verbose "$($pipes.IsClosed)" Format-Table -InputObject $lst -AutoSize } } Export-ModuleMember -Alias pipelist -Function Get-PipeList |