1. TCP端口
函数
DWORD GetExtendedTcpTable(
PVOID pTcpTable,
PDWORD pdwSize,
BOOL bOrder,
ULONG ulAf,
TCP_TABLE_CLASS TableClass,
ULONG Reserved
);
功能
获取当前所有TCP端口的列表
参数
PVOID pTcpTable:接收缓冲区,接收返回的TCP端口列表,表类型由参数TableClass决定
PDWORD pdwSize:pTcpTable缓冲区字节数,若缓冲区过小则返回所需大小
BOOL bOrder:端口列表是否排序
ULONG ulAf:AF_INET表IPv4,AF_INET6表IPv6
TCP_TABLE_CLASS TableClass:类型TCP_TABLE_CLASS的枚举值,指定TCP_TABLE_OWNER_PID_ALL即可
ULONG Reserved:0
指定Table类型为TCP_TABLE_OWNER_PID_ALL,则获取到的TCP Table类型为MIB_TCPTABLE_OWNER_PID结构体
typedef struct { DWORD dwNumEntries; MIB_TCPROW_OWNER_PID table[ANY_SIZE]; } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID; typedef struct _MIB_TCPROW_OWNER_PID { DWORD dwState; DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwRemoteAddr; DWORD dwRemotePort; DWORD dwOwningPid; } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;
返回值
成功返回NO_ERROR,否则返回值即错误码
使用方法
#include <IPHlpApi.h> #pragma comment(lib, "IPHlpApi.lib") /*获取缓冲区大小*/ DWORD dwBufferSize = 0; GetExtendedTcpTable(NULL, &dwBufferSize, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); /*创建缓冲区*/ MIB_TCPTABLE_OWNER_PID *pMibTcpTable = (MIB_TCPTABLE_OWNER_PID*)malloc(dwBufferSize); /*取Tcp Table*/ DWORD dwRet = GetExtendedTcpTable(pMibTcpTable, &dwBufferSize, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); if(dwRet != NO_ERROR) { printf("GetExtendedTcpTable != ERROR_SUCCESS, ErrorCode=%d ", dwRet); free(pMibTcpTable); return false; }
结果
for(DWORD i = 0; i != pMibTcpTable->dwNumEntries; ++i) { /*获取端口状态*/ DWORD dwState = pMibTcpTable->table[i].dwState; /*生成IP*/ in_addr inAddrLocal, inAddrRemote; memcpy(&inAddrLocal, &(pMibTcpTable->table[i].dwLocalAddr), sizeof(DWORD)); memcpy(&inAddrRemote, &(pMibTcpTable->table[i].dwRemoteAddr), sizeof(DWORD)); std::string sIpLocal = inet_ntoa(inAddrLocal); std::string sIpRemote = inet_ntoa(inAddrRemote); /*获取Port*/ DWORD dwPortLocal = ntohs(pMibTcpTable->table[i].dwLocalPort); DWORD dwPortRemote = ntohs(pMibTcpTable->table[i].dwRemotePort); /*获取PID*/ DWORD dwPid = pMibTcpTable->table[i].dwOwningPid; printf("端口状态=%d, 本地地址=%s, 本地端口=%d, 远端地址=%s, 远端端口=%d, 进程号=%d ", dwState, sIpLocal.c_str(), dwPortLocal, sIpRemote.c_str(), dwPortRemote, dwPid); }
2. UDP端口
函数
DWORD GetExtendedUdpTable(
PVOID pUdpTable,
PDWORD pdwSize,
BOOL bOrder,
ULONG ulAf,
UDP_TABLE_CLASS TableClass,
ULONG Reserved
);
功能
获取当前所有UDP端口的列表
参数
同上
UDP_TABLE_CLASS TableClass:类型UDP_TABLE_CLASS的枚举值,指定UDP_TABLE_OWNER_PID即可。
指定Table类型为UDP_TABLE_OWNER_PID,则获取到的UDP Table类型为MIB_UDPTABLE_OWNER_PID结构体
typedef struct _MIB_UDPTABLE_OWNER_PID { DWORD dwNumEntries; MIB_UDPROW_OWNER_PID table[ANY_SIZE]; } MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID; typedef struct _MIB_UDPROW_OWNER_PID { DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwOwningPid; } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
返回值
成功返回NO_ERROR,否则返回值即错误码
使用方法
#include <IPHlpApi.h> #pragma comment(lib, "IPHlpApi.lib") /*获取缓冲区大小*/ DWORD dwBufferSize = 0; GetExtendedUdpTable(NULL, &dwBufferSize, true, AF_INET, UDP_TABLE_OWNER_PID, 0); /*创建缓冲区*/ MIB_UDPTABLE_OWNER_PID *pMibUdpTable = (MIB_UDPTABLE_OWNER_PID*)malloc(dwBufferSize); /*取Udp Table*/ DWORD dwRet = GetExtendedUdpTable(pMibUdpTable, &dwBufferSize, true, AF_INET, UDP_TABLE_OWNER_PID, 0); if(dwRet != NO_ERROR) { printf("GetExtendedUdpTable != ERROR_SUCCESS, ErrorCode=%d ", dwRet); free(pMibUdpTable); return false; }
结果
for(DWORD i = 0; i != pMibUdpTable->dwNumEntries; ++i) { /*获取IP*/ in_addr inAddrLocal; memcpy(&inAddrLocal, &(pMibUdpTable->table[i].dwLocalAddr), sizeof(DWORD)); std::string sIpLocal = inet_ntoa(inAddrLocal); /*获取Port*/ DWORD dwPortLocal = ntohs(pMibUdpTable->table[i].dwLocalPort); /*获取PID*/ DWORD dwPid = pMibUdpTable->table[i].dwOwningPid; printf("本地地址=%s, 本地端口=%d, 进程号=%d ", sIpLocal.c_str(), dwPortLocal, dwPid); }
3. 进程句柄、进程名、PID转换
进程句柄——>PID
DWORD GetProcessId(HANDLE hProcess) ;
进程名——>进程句柄
HANDLE GetProcessHandle(const std::string &sNameProc) { /*获取进程快照句柄*/ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); /*遍历进程*/ PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); BOOL bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if(!sNameProc.compare(pe32.szExeFile)) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); return hProcess; } bMore = ::Process32Next(hProcessSnap, &pe32); } /*进程不存在*/ printf("GetProcessHandle: sNameProc=%s Not Exist", sNameProc.c_str()); return INVALID_HANDLE_VALUE; }
进程名——>PID
bool GetPidFromProcName(const std::string &sNameProc, std::set<DWORD> &setPid) { /*获取进程快照*/ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); /*遍历进程*/ PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); BOOL bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if(!sNameProc.compare(pe32.szExeFile)) setPid.insert(pe32.th32ProcessID); bMore=::Process32Next(hProcessSnap,&pe32); } return true; }
系统允许进程名重复。
PID——>进程名
bool GetProcNameByPid(const DWORD dwPid, std::string &sNameProc) { /*获取进程快照句柄*/ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); /*遍历进程*/ PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); bool bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if(pe32.th32ProcessID == dwPid) { sNameProc = pe32.szExeFile; return true; } bMore=::Process32Next(hProcessSnap, &pe32); } /*进程不存在*/ return false; }