private void UpdateProcessConnections() { // get any active game connections _processTCPInfo.UpdateTCPIPConnections(_connections); if (_connections.Count == 0) { Cleanup(); return; } for (int i = 0; i < _connections.Count; i++) { TCPConnection connection = _connections[i]; if (string.IsNullOrWhiteSpace(connection.ID)) { connection.ID = connection.ToString(); //TODO: In the future there may be a better way to define the ID other than such a long string. // Set up decoders for data sent from local machine connection.IPDecoder_Send = new IPDecoder(connection.LocalIP, connection.RemoteIP, IPProtocol.TCP); connection.TCPDecoder_Send = new TCPDecoder(connection.LocalPort, connection.RemotePort); // set up decoders for data received by local machine connection.IPDecoder_Receive = new IPDecoder(connection.RemoteIP, connection.LocalIP, IPProtocol.TCP); connection.TCPDecoder_Receive = new TCPDecoder(connection.RemotePort, connection.LocalPort); continue; } } }
/// <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); } }