📄 portproxy.cpp
字号:
// portproxy.cpp: implementation of the CPortProxy class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "common.h"
#include "ntshell.h"
#include "inputdlg.h"
#include "portproxy.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPortProxy::CPortProxy()
{
ppl = NULL;
}
CPortProxy::~CPortProxy()
{
while (ppl != NULL)
{
PPROXY_LIST p = ppl;
ppl = ppl->pNext;
SetEvent(p->hCtrlEvent1);
CloseHandle(p->hWorkThread);
CloseHandle(p->hCtrlEvent1);
CloseHandle(p->hCtrlEvent2);
delete p;
}
}
LRESULT CPortProxy::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
pwip = (PWND_INIT_PARAM)lParam;
connwait = false;
m_hAddProxyDlg.Create(m_hWnd);
m_hAddProxyDlg.ShowWindow(SW_HIDE);
m_hProxyList.Attach(GetDlgItem(IDC_PROXYLIST));
m_hProxyList.InsertColumn(0, "远程端口", LVCFMT_LEFT, 70, 0);
m_hProxyList.InsertColumn(1, "对应端口", LVCFMT_LEFT, 70, 0);
m_hProxyList.InsertColumn(2, "发送次数", LVCFMT_LEFT, 70, 0);
m_hProxyList.InsertColumn(3, "接收次数", LVCFMT_LEFT, 70, 0);
m_hProxyList.InsertColumn(4, "发送数据量", LVCFMT_LEFT, 100, 0);
m_hProxyList.InsertColumn(5, "接收数据量", LVCFMT_LEFT, 100, 0);
DWORD dwStyle = m_hProxyList.GetExtendedListViewStyle();
dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP;
m_hProxyList.SetExtendedListViewStyle(dwStyle);
return TRUE;
}
LRESULT CPortProxy::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
::MoveWindow(GetDlgItem(IDC_PROXYLIST), 7, 7, LOWORD(lParam) - 14, HIWORD(lParam) - 14, TRUE);
return TRUE;
}
LRESULT CPortProxy::OnSocket(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
SOCKET slave_sock = (SOCKET)wParam;
if (WSAGETSELECTERROR(lParam))
{
closesocket(slave_sock);
slave_sock = INVALID_SOCKET;
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
break;
}
return 0;
}
SOCKET CPortProxy::OpenLocalPort(USHORT nPort)
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
MessageBox("创建套接字失败");
return INVALID_SOCKET;
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(nPort);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
{
MessageBox("绑定本机端口失败");
closesocket(s);
return INVALID_SOCKET;
}
if (listen(s, PORT_MAX_CONNECT) == SOCKET_ERROR) //最大连接数量
{
MessageBox("监听端口失败");
closesocket(s);
return INVALID_SOCKET;
}
return s;
}
SOCKET CPortProxy::OpenRemotePort(char *lpHost, USHORT nPort)
{
OPEN_REMOTE_PORT orp;
connwait = true;
orp.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (orp.hEvent == NULL)
return INVALID_SOCKET;
rc.hAcceptWnd = m_hWnd;
rc.funBack = OpenPortSuccess;
rc.lpParam = &orp;
rc.dwWorkType = WORK_SOCKPROXY;
rc.lpCtrlHandle = pwip->lpCtrlHandle;
SendMessage(pwip->hConnMgrWnd, WM_REQUEST_CONNECT, 0, (LPARAM)&rc);
DWORD ret = WaitForSingleObject(orp.hEvent, INFINITE);
if (ret == WAIT_FAILED)
{
SendMessage(pwip->hConnMgrWnd, WM_CANCEL_REQUEST, 0, (LPARAM)&rc);
CloseHandle(orp.hEvent);
return INVALID_SOCKET;
}
CloseHandle(orp.hEvent);
return orp.s;
}
void CPortProxy::OpenPortSuccess(SOCKET s, LPVOID param)
{
((POPEN_REMOTE_PORT)param)->s = s;
SetEvent(((POPEN_REMOTE_PORT)param)->hEvent);
}
BOOL CPortProxy::SockProxyStart(USHORT ListenPort, char *RemoteHost, USHORT RemotePort)
{
PPROXY_LIST p = new PROXY_LIST;
p->nLocalPort = ListenPort;
p->nTargetPort = RemotePort;
p->nSend = 0;
p->nRecv = 0;
p->nSendBytes = 0;
p->nRecvBytes = 0;
p->dwTargetHost = inet_addr(RemoteHost);
if (p->dwTargetHost == INADDR_NONE)
{
struct hostent *host = gethostbyname(RemoteHost); //解析主机域名
if (host == NULL)
{
CString str = "无法解析域名";
MessageBox(str + RemoteHost);
delete p;
return FALSE;
}
else
{
p->dwTargetHost = *(DWORD *)(host->h_addr_list[0]);
}
}
p->sListen = OpenLocalPort(p->nLocalPort);
if (p->sListen == INVALID_SOCKET)
{
delete p;
return FALSE;
}
WSAAsyncSelect(p->sListen, m_hWnd, WM_SOCKET, FD_ACCEPT);
DWORD dwThreadId;
p->hWorkThread = CreateThread(NULL, 0, SockProxyThread, p, 0, &dwThreadId);
p->pNext = ppl;
ppl = p;
return TRUE;
}
DWORD WINAPI CPortProxy::SockProxyThread(LPVOID lpParam)
{
PPROXY_LIST p = (PPROXY_LIST)lpParam;
SOCKET socks[PORT_MAX_CONNECT * 2];
HANDLE events[PORT_MAX_CONNECT * 2 + 2];
PHANDLE sock_events = &events[2];
char *sock_buffer[PORT_MAX_CONNECT * 2];
DWORD buffer_length[PORT_MAX_CONNECT * 2];
DWORD send_pointer[PORT_MAX_CONNECT * 2];
DWORD recv_pointer[PORT_MAX_CONNECT * 2];
int ret, sock_total = 0;
DWORD index;
BOOL done = TRUE;
WSANETWORKEVENTS ns;
events[0] = p->hCtrlEvent1;
events[1] = p->hCtrlEvent2;
while (done)
{
index = WaitForMultipleObjectsEx(sock_total + 2, events, FALSE, INFINITE, FALSE);
switch (index)
{
case WAIT_FAILED:
goto cleanup;
case WAIT_OBJECT_0:
goto cleanup;
case WAIT_OBJECT_0 + 1:
socks[sock_total] = p->local_sock;
socks[sock_total + 1] = p->remote_sock;
sock_events[sock_total] = WSACreateEvent();
if (sock_events[sock_total] == WSA_INVALID_EVENT)
continue;
sock_events[sock_total + 1] = WSACreateEvent();
if (sock_events[sock_total + 1] == WSA_INVALID_EVENT)
{
WSACloseEvent(sock_events[sock_total]);
continue;
}
sock_buffer[sock_total] = (char *)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
if (sock_buffer[sock_total] == NULL)
{
WSACloseEvent(sock_events[sock_total]);
WSACloseEvent(sock_events[sock_total + 1]);
continue;
}
sock_buffer[sock_total + 1] = sock_buffer[sock_total] + 2048;
buffer_length[sock_total] = 0;
buffer_length[sock_total + 1] = 0;
send_pointer[sock_total] = 0;
send_pointer[sock_total + 1] = 0;
recv_pointer[sock_total] = 0;
recv_pointer[sock_total + 1] = 0;
sock_total += 2;
p->nTotal = sock_total / 2;
continue;
default:
index -= 2;
break;
}
ret = WSAEnumNetworkEvents(socks[index], sock_events[index], &ns);
if (ret == SOCKET_ERROR)
goto cleanup;
int src = index;
int dst = index & 1 ? index - 1 : index + 1;
if (ns.lNetworkEvents & FD_READ)
{
if (ns.iErrorCode[FD_READ_BIT])
goto close_sock;
ret = recv(socks[src], sock_buffer[src] + recv_pointer[src], 2048 - recv_pointer[src], 0);
recv_pointer[src] += ret;
buffer_length[src] += ret;
p->nRecv++;
p->nRecvBytes += ret;
ret = send(socks[dst], sock_buffer[src] + send_pointer[src], buffer_length[src] - send_pointer[src], 0);
if (ret != SOCKET_ERROR)
{
send_pointer[src] += ret;
p->nSend++;
p->nSendBytes += ret;
}
if (send_pointer[src] == buffer_length[src])
{
recv_pointer[src] = 0;
send_pointer[src] = 0;
buffer_length[src] = 0;
}
}
if (ns.lNetworkEvents & FD_WRITE)
{
if (ns.iErrorCode[FD_WRITE_BIT])
goto close_sock;
ret = send(socks[src], sock_buffer[dst] + send_pointer[dst], buffer_length[dst] - send_pointer[dst], 0);
send_pointer[dst] += ret;
p->nSend++;
p->nSendBytes += ret;
if (send_pointer[dst] == buffer_length[dst])
{
recv_pointer[dst] = 0;
send_pointer[dst] = 0;
buffer_length[dst] = 0;
}
}
if (ns.lNetworkEvents & FD_CLOSE)
{
close_sock:
int m = index & 0xfffffffe, n = m + 1;
closesocket(socks[m]);
closesocket(socks[n]);
WSACloseEvent(sock_events[m]);
WSACloseEvent(sock_events[n]);
VirtualFree(sock_buffer[m], 0, MEM_RELEASE);
sock_total -= 2;
p->nTotal = sock_total / 2;
socks[m] = socks[sock_total];
socks[n] = socks[sock_total + 1];
sock_events[m] = sock_events[sock_total];
sock_events[n] = sock_events[sock_total + 1];
sock_buffer[m] = sock_buffer[sock_total];
sock_buffer[n] = sock_buffer[sock_total + 1];
buffer_length[m] = buffer_length[sock_total];
buffer_length[n] = buffer_length[sock_total + 1];
send_pointer[m] = send_pointer[sock_total];
send_pointer[n] = send_pointer[sock_total + 1];
recv_pointer[m] = recv_pointer[sock_total];
recv_pointer[n] = recv_pointer[sock_total + 1];
}
}
cleanup:
for (int i = 0; i < sock_total; i += 2)
{
closesocket(socks[i]);
closesocket(socks[i + 1]);
WSACloseEvent(sock_events[i]);
WSACloseEvent(sock_events[i + 1]);
VirtualFree(sock_buffer[i], 0, MEM_RELEASE);
}
p->nTotal = 0;
return 0;
}
LRESULT CPortProxy::OnProxyList(int wParam, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
{
NMLISTVIEW *pNMListView = (NMLISTVIEW *)pNMHDR;
int nItem = pNMListView->iItem;
HMENU hMenu, hPopupMenu;
POINT point;
switch (pNMHDR->code)
{
case NM_RCLICK:
hMenu = LoadMenu(GetModuleHandle(NULL), (LPCTSTR)IDR_SUBMENU);
hPopupMenu = GetSubMenu(hMenu, 0);
if (nItem == -1)
EnableMenuItem(hPopupMenu, IDM_DELPROXY, MF_GRAYED);
else
EnableMenuItem(hPopupMenu, IDM_DELPROXY, MF_ENABLED);
GetCursorPos(&point);
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, point.x, point.y, 0, m_hWnd, NULL);
DestroyMenu(hMenu);
break;
}
return 0;
}
LRESULT CPortProxy::OnAddProxy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CInputDlg<IDD_ADDPROXY, 2> dlg;
TCHAR szMap[INPUT_BUFFER_SIZE] = "127.0.0.1:80-81";
if (dlg.DoModal(m_hWnd, (LPARAM)szMap) == FALSE)
return 0;
return 0;
}
LRESULT CPortProxy::OnAddProxyBtn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -