⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portproxy.cpp

📁 远程控制系统,可以实现局域网内进行远程控制计算机,很方便,并且是学习用的非常好的资料.
💻 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 + -