Exemplo n.º 1
0
 public static int NumberOfActiveConnections(int processId, AddressVersion addressVersion)
 {
     try
     {
         return(TryFindNumberOfActiveConnectionsOfProcess(processId, addressVersion));
     }
     catch (Exception)
     {
         return(0);
     }
 }
Exemplo n.º 2
0
 public static int MapLocalPortToProcessId(ushort port, AddressVersion addressVersion)
 {
     try
     {
         return(TryMapLocalPortToProcessId(port, addressVersion));
     }
     catch (Exception)
     {
         return(0);
     }
 }
Exemplo n.º 3
0
        private static int TryMapLocalPortToProcessId(ushort port, AddressVersion addressVersion)
        {
            var ptrTcpTable    = IntPtr.Zero;
            var tcpTableLength = 0u;

            var offsetToFirstPort = 12;
            var offsetToPIDInRow  = 12;
            var tableRowSize      = 24; // 24 == Marshal.SizeOf(typeof(TcpRow));

            // IPv6 tables are a different size, so adjust the offsets accordingly
            if (addressVersion == AddressVersion.IPv6)
            {
                offsetToFirstPort = 24;
                offsetToPIDInRow  = 32;
                tableRowSize      = 56;
            }

            // Determine the size of the memory block to allocate
            if (ERROR_INSUFFICIENT_BUFFER != GetExtendedTcpTable(ptrTcpTable, ref tcpTableLength, false, (uint)addressVersion, TcpTableType.OwnerPidConnections, 0))
            {
                return(0);
            }

            try
            {
                ptrTcpTable = Marshal.AllocHGlobal((int)tcpTableLength);

                // Would it be faster to set the SORTED argument to true, and then iterate the table in reverse order?
                if (NO_ERROR == GetExtendedTcpTable(ptrTcpTable, ref tcpTableLength, false, (uint)addressVersion, TcpTableType.OwnerPidConnections, 0))
                {
                    // Convert port we're looking for into Network byte order
                    var portReversed = port.ReverseBytes();

                    // ISSUE: This function APPEARS to work fine, but might blow up on Itanium or exotic architectures like that. As noted in the docs:
                    // The MIB_TCPTABLE_OWNER_PID structure may contain padding for alignment between the dwNumEntries member and the first MIB_TCPROW_OWNER_PID
                    // array entry in the table  member. Padding for alignment may also be present between the MIB_TCPROW_OWNER_PID array entries in the table member.
                    // Any access to a MIB_TCPROW_OWNER_PID array entry should assume padding may exist.
                    //
                    // I have absolutely no idea how to detect such padding, or if .NET handles it automatically if I use PtrToStructure rather than the direct pointer
                    // manipulation calls this function is now using.
                    //
                    var tableLen = Marshal.ReadInt32(ptrTcpTable);          // Get table row count
                    if (tableLen == 0)
                    {
                        Debug.Assert(false, "How is it possible that the API succeeded and there are really no network connections? Maybe pure IPv6 environment?");
                        return(0);
                    }
                    var ptrRow = (IntPtr)(ptrTcpTable.ToInt64() + offsetToFirstPort);       // Advance pointer to first Port in the table

                    // Iterate each row of the table, looking to see if localPortInNetworkOrder matches. If it does, return the owningPid
                    for (var i = 0; i < tableLen; ++i)
                    {
                        // Check for matching local port
                        if (portReversed == Marshal.ReadInt32(ptrRow))
                        {
                            return(Marshal.ReadInt32(ptrRow, offsetToPIDInRow));
                            // Note: the finally clause below will clean up memory
                        }

                        // Move to the next row
                        ptrRow = (IntPtr)(ptrRow.ToInt64() + tableRowSize);
                    }
                }
                else
                {
                    return(0);
                }
            }
            finally
            {
                // Clean up unmanaged memory block. Call succeeds even if tcpTable == 0.
                Marshal.FreeHGlobal(ptrTcpTable);
            }
            return(0);
        }