获取进程占用端口
// RemoteThread.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <Windows.h> #include <excpt.h> #include <psapi.h> #pragma comment(lib, "Wsock32.lib") #pragma comment(lib, "Psapi.lib") using namespace std; #define ANY_SIZE 1 enum TcpOrUdp { TcpType = 0, UdpType }; // TCP typedef struct { DWORD dwState; //连接状态 DWORD dwLocalAddr; //本地地址 DWORD dwLocalPort; //本地端口 DWORD dwRemoteAddr; //远程地址 DWORD dwRemotePort; //远程端口 DWORD dwProcessId; //进程ID } MIB_TCPEXROW, * PMIB_TCPEXROW; typedef struct { DWORD dwNumEntries; MIB_TCPEXROW table[255]; } MIB_TCPEXTABLE, * PMIB_TCPEXTABLE; typedef struct { DWORD dwState; //连接状态 DWORD dwLocalAddr; //本地地址 DWORD dwLocalPort; //本地端口 DWORD dwRemoteAddr; //远程地址 DWORD dwRemotePort; //远程端口 DWORD dwProcessId; //进程标识 DWORD Unknown; //待定标识 }MIB_TCPEXROW_VISTA, * PMIB_TCPEXROW_VISTA; typedef struct { DWORD dwNumEntries; MIB_TCPEXROW_VISTA table[ANY_SIZE]; }MIB_TCPEXTABLE_VISTA, * PMIB_TCPEXTABLE_VISTA; typedef DWORD(WINAPI* PFNInternalGetTcpTable2)( PMIB_TCPEXTABLE_VISTA * pTcpTable_Vista, HANDLE heap, DWORD flags ); typedef DWORD(WINAPI* PFNAllocateAndGetTcpExTableFromStack)( PMIB_TCPEXTABLE* pTcpTable, BOOL bOrder, HANDLE heap, DWORD zero, DWORD flags ); // UDP typedef struct tagMIB_UDPEXROW { DWORD dwLocalAddr; // 本地计算机地址. DWORD dwLocalPort; // 本地计算机端口. DWORD dwProcessId; } MIB_UDPEXROW, * PMIB_UDPEXROW; typedef struct tagMIB_UDPEXTABLE { DWORD dwNumEntries; MIB_UDPEXROW table[100]; // 任意大小数组变量. } MIB_UDPEXTABLE, * PMIB_UDPEXTABLE; typedef DWORD(WINAPI* PFNAllocateAndGetUdpExTableFromStack)( PVOID* ppUdpTable, BOOL bOrder, HANDLE hHeap, DWORD dwFlags, DWORD dwFamily ); typedef DWORD(WINAPI* PFNInternalGetUdpTableWithOwnerPid)( PMIB_UDPEXTABLE* pUdpTable, HANDLE heap, DWORD flags ); DWORD GetAllPortByProcessId(TcpOrUdp type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen) { DWORD dwPortCount = 0; HMODULE hModule = LoadLibraryW(L"iphlpapi.dll"); if (hModule == NULL) { return dwPortCount; } if(type == TcpType) { // 表明查询的是 UDP 信息 PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack; pAllocateAndGetTcpExTableFromStack = (PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack"); if (pAllocateAndGetTcpExTableFromStack != NULL) { // 表明为 XP 或者 Server 2003 操作系统 PMIB_TCPEXTABLE pTcpExTable = NULL; if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0) { if (pTcpExTable) { HeapFree(GetProcessHeap(), 0, pTcpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++) { // 过滤掉数据,只获取我们要查询的进程的 Port 信息 if(dwProcessId == pTcpExTable->table[i].dwProcessId) { if(dwPortCount < dwMaxLen) { dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort); dwPortCount++; } } } if (pTcpExTable) { HeapFree(GetProcessHeap(), 0, pTcpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } else { // 表明为 Vista 或者 7 操作系统 PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL; PFNInternalGetTcpTable2 pInternalGetTcpTable2 = (PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2"); if (pInternalGetTcpTable2 == NULL) { if (pTcpExTable) { HeapFree(GetProcessHeap(), 0, pTcpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1)) { if (pTcpExTable) { HeapFree(GetProcessHeap(), 0, pTcpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++) { // 过滤掉数据,只获取我们要查询的进程的 TCP Port 信息 if(dwProcessId == pTcpExTable->table[i].dwProcessId) { if(dwPortCount < dwMaxLen) { dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort); struct sockaddr_in local; local.sin_family = AF_INET; local.sin_addr.s_addr = pTcpExTable->table[i].dwRemoteAddr; char* ip = inet_ntoa(local.sin_addr); dwPortCount++; } } } if (pTcpExTable) { HeapFree(GetProcessHeap(), 0, pTcpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } } else if(type == UdpType) { // 表明查询的是 UDP 信息 PMIB_UDPEXTABLE pUdpExTable = NULL; PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack; pAllocateAndGetUdpExTableFromStack = (PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack"); if (pAllocateAndGetUdpExTableFromStack != NULL) { // 表明为 XP 或者 Server 2003 操作系统 if (pAllocateAndGetUdpExTableFromStack((PVOID*)&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0) { if (pUdpExTable) { HeapFree(GetProcessHeap(), 0, pUdpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++) { // 过滤掉数据,只获取我们要查询的进程的 UDP Port信息 if(dwProcessId == pUdpExTable->table[i].dwProcessId) { if(dwPortCount < dwMaxLen) { dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort); dwPortCount++; } } } if (pUdpExTable) { HeapFree(GetProcessHeap(), 0, pUdpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } else { // 表明为 Vista 或者 7 操作系统 PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid; pInternalGetUdpTableWithOwnerPid = (PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid"); if (pInternalGetUdpTableWithOwnerPid != NULL) { if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1)) { if (pUdpExTable) { HeapFree(GetProcessHeap(), 0, pUdpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++) { // 过滤掉数据,只获取我们要查询的进程的 UDP Port信息 if(dwProcessId == pUdpExTable->table[i].dwProcessId) { if(dwPortCount < dwMaxLen) { dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort); dwPortCount++; } } } } if (pUdpExTable) { HeapFree(GetProcessHeap(), 0, pUdpExTable); } FreeLibrary(hModule); hModule = NULL; return dwPortCount; } } else { FreeLibrary(hModule); hModule = NULL; return dwPortCount; } } int _tmain(int argc, _TCHAR* argv[]) { DWORD dwRet = 0; DWORD allPort[10240] = { 0 }; DWORD dwMaxLen = 10240; dwRet = GetAllPortByProcessId(TcpType, 16368, allPort, dwMaxLen); return 0; }