+/**
+ * get pid from localhost tcp connection using peer_port
+ * This function is available on WinXP >= SP3
+ * @param peer_port peers tcp port
+ * @return process id or 0 if connection has not been found
+ */
+static dbus_pid_t
+get_pid_from_extended_tcp_table(int peer_port)
+{
+ dbus_pid_t result;
+ DWORD errorCode, size, i;
+ MIB_TCPTABLE_OWNER_PID *tcp_table;
+
+ if ((errorCode =
+ GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER)
+ {
+ tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size);
+ if (tcp_table == NULL)
+ {
+ _dbus_verbose ("Error allocating memory\n");
+ return 0;
+ }
+ }
+ else
+ {
+ _dbus_win_warn_win_error ("unexpected error returned from GetExtendedTcpTable", errorCode);
+ return 0;
+ }
+
+ if ((errorCode = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR)
+ {
+ _dbus_verbose ("Error fetching tcp table %d\n", (int)errorCode);
+ dbus_free (tcp_table);
+ return 0;
+ }
+
+ result = 0;
+ for (i = 0; i < tcp_table->dwNumEntries; i++)
+ {
+ MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i];
+ int local_address = ntohl (p->dwLocalAddr);
+ int local_port = ntohs (p->dwLocalPort);
+ if (p->dwState == MIB_TCP_STATE_ESTAB
+ && local_address == INADDR_LOOPBACK && local_port == peer_port)
+ result = p->dwOwningPid;
+ }
+
+ dbus_free (tcp_table);
+ _dbus_verbose ("got pid %lu\n", result);
+ return result;
+}
+
+/**
+ * get pid from localhost tcp connection using peer_port
+ * This function is available on all WinXP versions, but
+ * not in wine (at least version <= 1.6.0)
+ * @param peer_port peers tcp port
+ * @return process id or 0 if connection has not been found
+ */
+static dbus_pid_t
+get_pid_from_tcp_ex_table(int peer_port)
+{
+ dbus_pid_t result;
+ DWORD errorCode, i;
+ PMIB_TCPTABLE_EX tcp_table = NULL;
+
+ if (!load_ex_ip_helper_procedures ())
+ {
+ _dbus_verbose
+ ("Error not been able to load iphelper procedures\n");
+ return 0;
+ }
+
+ errorCode = lpfnAllocateAndGetTcpExTableFromStack (&tcp_table, TRUE, GetProcessHeap(), 0, 2);
+
+ if (errorCode != NO_ERROR)
+ {
+ _dbus_verbose
+ ("Error not been able to call AllocateAndGetTcpExTableFromStack()\n");
+ return 0;
+ }
+
+ result = 0;
+ for (i = 0; i < tcp_table->dwNumEntries; i++)
+ {
+ _MIB_TCPROW_EX *p = &tcp_table->table[i];
+ int local_port = ntohs (p->dwLocalPort);
+ int local_address = ntohl (p->dwLocalAddr);
+ if (local_address == INADDR_LOOPBACK && local_port == peer_port)
+ {
+ result = p->dwOwningPid;
+ break;
+ }
+ }
+
+ HeapFree (GetProcessHeap(), 0, tcp_table);
+ _dbus_verbose ("got pid %lu\n", result);
+ return result;