Exemplo n.º 1
0
        /// <summary>
        /// This retrieves all current TCPIP connections, filters them based on a process id (specified by either ProcessID or ProcessWindowName parameter),
        ///   and updates the connections collection.
        /// </summary>
        /// <param name="connections">List containing prior connections that needs to be maintained</param>
        public unsafe void UpdateTCPIPConnections(List <TCPConnection> connections)
        {
            if (ProcessID > 0)
            {
                _currentProcessID = ProcessID;
            }
            else
            {
                _currentProcessID = GetProcessIDByWindowName(ProcessWindowName);
            }

            if (_currentProcessID == 0)
            {
                if (connections.Count > 0)
                {
                    Trace.WriteLine("ProcessTCPInfo: Process has exited, closing all connections.");

                    connections.Clear();
                }

                return;
            }

            IntPtr ptrTCPTable   = IntPtr.Zero;
            int    bufferLength  = 0;
            int    ret           = 0;
            int    tcpTableCount = 0;
            IntPtr tmpPtr        = IntPtr.Zero;

            // attempt to allocate 5 times, in case there are frequent increases in the # of tcp connections
            for (int i = 0; i < 5; i++)
            {
                ret = GetExtendedTcpTable(ptrTCPTable, ref bufferLength, false, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);

                if (ret == 0)
                {
                    break;
                }
                if (ptrTCPTable != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptrTCPTable);
                    ptrTCPTable = IntPtr.Zero;
                }
                ptrTCPTable = Marshal.AllocHGlobal(bufferLength);
            }

            try
            {
                if (ret == 0)
                {
                    //retrieving numbers of entries
                    tcpTableCount = *(int *)ptrTCPTable;
                    tmpPtr        = ptrTCPTable + sizeof(Int32);

                    for (int i = 0; i <= tcpTableCount - 1; i++)
                    {
                        MIB_TCPROW_EX entry = *(MIB_TCPROW_EX *)tmpPtr;

                        // Process if ProcessID matches
                        if (entry.dwProcessId == _currentProcessID)
                        {
                            bool bFound = false;
                            for (int j = 0; j < connections.Count; j++)
                            {
                                if (connections[j].LocalIP == entry.dwLocalAddr &&
                                    connections[j].RemoteIP == entry.dwRemoteAddr &&
                                    connections[j].LocalPort == (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwLocalPort) &&
                                    connections[j].RemotePort == (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwRemotePort)
                                    )
                                {
                                    bFound = true;
                                    break;
                                }
                            }

                            if (!bFound)
                            {
                                var connection = new TCPConnection()
                                {
                                    LocalIP    = entry.dwLocalAddr,
                                    RemoteIP   = entry.dwRemoteAddr,
                                    LocalPort  = (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwLocalPort),
                                    RemotePort = (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwRemotePort)
                                };

                                connections.Add(connection);

                                Trace.WriteLine("ProcessTCPInfo: New connection detected for Process [" + _currentProcessID.ToString() + "]: " + connection.ToString());
                            }
                        }

                        // increment pointer
                        tmpPtr += sizeof(MIB_TCPROW_EX);
                    }

                    for (int i = connections.Count - 1; i >= 0; i--)
                    {
                        bool bFound = false;
                        tmpPtr = ptrTCPTable + sizeof(Int32);

                        for (int j = 0; j <= tcpTableCount - 1; j++)
                        {
                            MIB_TCPROW_EX entry = *(MIB_TCPROW_EX *)tmpPtr;

                            // Process if ProcessID matches
                            if (entry.dwProcessId == _currentProcessID)
                            {
                                if (connections[i].LocalIP == entry.dwLocalAddr &&
                                    connections[i].RemoteIP == entry.dwRemoteAddr &&
                                    connections[i].LocalPort == (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwLocalPort) &&
                                    connections[i].RemotePort == (ushort)System.Net.IPAddress.NetworkToHostOrder((short)entry.dwRemotePort)
                                    )
                                {
                                    bFound = true;
                                    break;
                                }
                            }
                            // increment pointer
                            tmpPtr += sizeof(MIB_TCPROW_EX);
                        }
                        if (!bFound)
                        {
                            Trace.WriteLine("ProcessTCPInfo: Removed connection " + connections[i].ToString());
                            connections.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    Trace.WriteLine("ProcessTCPInfo: Unable to retrieve TCP table. Return code: " + ret.ToString());
                    throw new System.ComponentModel.Win32Exception(ret);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("ProcessTCPInfo: Exception updating TCP connection list." + ex.ToString());
                throw new System.ComponentModel.Win32Exception(ret, ex.Message);
            }
            finally
            {
                Marshal.FreeHGlobal(ptrTCPTable);
            }
        }