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

📄 client.c

📁 经典远程控制代码
💻 C
字号:
//  从服务器端接收桌面屏幕
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include "client.h"
#include "command.h"
#include "gdi.h"
#include "HuffCompress.h"
#include "RLE.h"
#include "time.h"

#define DEFAULT_PORT        5150
#define REFRESH_MSG			"REFRESH"
#define SETFLAGS			XP1_GUARANTEED_DELIVERY|XP1_GUARANTEED_ORDER
#define NOTSETFLAGS			XP1_CONNECTIONLESS
#define	LPBMIH				LPBITMAPINFOHEADER

UINT    port=DEFAULT_PORT;
BOOL	bSendOnly = FALSE;
BOOL	fSending = FALSE;
BOOL	fReceiving = FALSE;
DWORD	iLen;
char	*pDIBitmap;
int		iScreenWidth,iScreenHeight;
int		iWidth,iHeight,iWidthX,iHeightY;
int		iWidth1,iWidth2,iHeight1,iHeight2;
int		iCompressionLevel;
BOOL	fDIBitmap = FALSE;
LPBMIH	lpBitmapIH;
struct	sockaddr_in	server;
SOCKET	sClient;
BOOL	fRefreshing = FALSE;
BOOL	fConnected = FALSE;
int		nGridX = 8,nGridY = 4;
BOOL	fGridX = FALSE,fGridY = FALSE;
WORD	bmBitsPixel = 4;

struct	GdiList		GdiStart;
struct	GdiList		*pGdiNode;

int SelectProtocols(DWORD dwSetFlags,DWORD dwNotSetFlags,LPWSAPROTOCOL_INFO lpProtocolBuffer,LPDWORD lpdwBufferLength,WSAPROTOCOL_INFO *Protocol);

void InitGrids()
{
	int		iLoop,jLoop,nGrid;
	struct	GdiDS	Gdi;

	Gdi.fDIBitmap = FALSE;
	GdiStart.pNext = NULL;
	pGdiNode = &GdiStart;

	if ((nGridX > 0) && (nGridY > 0))
	{
		for (iLoop = 0;iLoop < nGridX;iLoop++)
		{
			for (jLoop = 0;jLoop < nGridY;jLoop++)
			{
				Gdi.iGridX = iLoop;
				Gdi.iGridY = jLoop;

				pGdiNode = Add_Gdi(pGdiNode,Gdi);
			}
		}
	}
	else
	{
		nGrid = max(nGridX,nGridY);
		for (iLoop = 0;iLoop < nGrid;iLoop++)
		{
			if (nGridX > 0)
				Gdi.iGridX = iLoop;
			else
				Gdi.iGridX = 0;

			if (nGridY > 0)
				Gdi.iGridY = iLoop;
			else
				Gdi.iGridY = 0;

			pGdiNode = Add_Gdi(pGdiNode,Gdi);
		}
	}

	if (nGridX > 0)
		iWidthX = iWidth/nGridX;
	else
		iWidthX = iWidth;

	if (nGridY > 0)
		iHeightY = iHeight/nGridY;
	else
		iHeightY = iHeight;
}

// 装入Winsock然后连接服务器
int LoadWinsock(HWND hWnd,char *szIP)
{
	WSADATA				wsd;
	DWORD				dwLen;
	int					nRet,nZero;
	LPBYTE				pBuf;
	WSAPROTOCOL_INFO	Protocol;
	char				szString[81];
	char				szMessage[81];

	if (WSAStartup(0x202,&wsd) != 0)
	{
		MessageBox(NULL,"hehe","Client Socket Error",MB_OK);
		return 1;
	}

	dwLen = 0;
	nRet = WSAEnumProtocols(NULL,NULL,&dwLen);
	if (nRet == SOCKET_ERROR)
	{
		if (WSAGetLastError() != WSAENOBUFS)
			return 1;
	}

	pBuf = malloc(dwLen);

	nRet = SelectProtocols(SETFLAGS,NOTSETFLAGS,(LPWSAPROTOCOL_INFO)pBuf,&dwLen,&Protocol);

	free(pBuf);

	sClient = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,SOCK_STREAM);
	if (sClient == INVALID_SOCKET)
		return 1;

	nZero = 0;
	setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(nZero));

	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr.s_addr = inet_addr(szIP);

	if (connect(sClient,(struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR)
	{
		memset(szString,'\0',sizeof(szString));
		sprintf(szString,"Connect() failed: %d",WSAGetLastError());
		MessageBox(NULL,szString,"Client Socket Error",MB_OK);
		return 1;
	}

	GetResolution();
	SetGrids(hWnd);

	memset(szMessage,'\0',sizeof(szMessage));
	sprintf(szMessage,"WM_COMP;%d;0;0;0;\0",iCompressionLevel);
	SendCommand(hWnd,1,szMessage);

	UpdateRegionalScreen(hWnd,sClient,TRUE);

	return 0;
}

void SetGrids(HWND hWnd)
{
	char	szMessage[81];
	Clear_Gdi(&GdiStart);
	memset(szMessage,'\0',sizeof(szMessage));
	sprintf(szMessage,"WM_GRID;%d;%d;0;0;\0",nGridX,nGridY);
	SendCommand(hWnd,1,szMessage);
	InitGrids();
}

void GetResolution()
{
	int		iSend,iRecv;
	char	szMessage[81];
	char	szRecv[81];

	memset(szMessage,'\0',sizeof(szMessage));
	sprintf(szMessage,"RESOLUTION\0");
	iSend = Send(sClient,szMessage);

	iRecv = Recv(sClient,szRecv,80);
	iWidth = atoi(szRecv);

	memset(szMessage,'\0',sizeof(szMessage));
	sprintf(szMessage,"OK\0");
	iSend = Send(sClient,szMessage);

	iRecv = Recv(sClient,szRecv,80);
	iHeight = atoi(szRecv);

	memset(szMessage,'\0',sizeof(szMessage));
	sprintf(szMessage,"OK\0");
	iSend = Send(sClient,szMessage);
}

int SendCommand(HWND hWnd,int iParm,char *szWMMessage)
{
	int		iSent;

	if (iParm == 0)
	{
		UpdateRegionalScreen(hWnd,sClient,FALSE);
	}
	else if (iParm == 1)
	{
		iSent = Send(sClient,szWMMessage);
	}
	return 0;
}

int Send(SOCKET Socket,char *szSend)
{
	int		iSent;
	fSending = TRUE;
	iSent = send(Socket,szSend,strlen(szSend),0);
	fSending = FALSE;
	return iSent;
}

int Recv(SOCKET Socket,char *szRecv,int iRecvLen)
{
	int		iRecv;
	fReceiving = TRUE;
	iRecv = recv(Socket,szRecv,iRecvLen,0);
	if (iRecv == SOCKET_ERROR || iRecv == 0)
		MessageBox(NULL,"NO DATA or SOCKET ERROR","Client",MB_OK);
	szRecv[iRecv] = '\0';
	fReceiving = FALSE;
	return iRecv;
}

void UpdateRegionalScreen(HWND hWnd,SOCKET sClient,BOOL fFirstTime)
{
	LPBMIH	lpBMIH;
	char	*pDIB;
	char	*pDIBCompress;
	char	*pStartDIB;
	DWORD	iSent,iRecv;
	DWORD	iCompLen,iNewLen,iRLELen,iStartPos;
	int		iGridX,iGridY;
	int		iUpdates,iLoop,iCompressions,jLoop;
	char	szMessage[81];

	struct	CommandList	CommandStart;
	struct	CommandList	*pCommandNode;
	struct	CommandDS	Command;
	char				*pDest;
	int					iLoc1,iLoc2,nChar;

	char				*pTempDIB;

	if (!fRefreshing)
	{
		CommandStart.pNext = NULL;
		fRefreshing = TRUE;
		strcpy(szMessage,REFRESH_MSG);
		iSent = Send(sClient,szMessage);
		memset(szMessage,'\0',sizeof(szMessage));
		iRecv = Recv(sClient,szMessage,80);
		if (iRecv == SOCKET_ERROR || iRecv == 0)
			MessageBox(NULL,"NO DATA or SOCKET ERROR","Client",MB_OK);
		iUpdates = atoi(szMessage);
		strcpy(szMessage,"OK\0");
		iSent = Send(sClient,szMessage);
		if (iUpdates > 0)
		{
			pGdiNode = GdiStart.pNext;
			for (iLoop = 0;iLoop < iUpdates;iLoop++)
			{
				pCommandNode = &CommandStart;
				memset(szMessage,'\0',sizeof(szMessage));
				iRecv = Recv(sClient,szMessage,80);
				if (iRecv == SOCKET_ERROR || iRecv == 0)
					MessageBox(NULL,"NO DATA or SOCKET ERROR","Client",MB_OK);
				iLoc1 = 0;
				while (pDest = strchr(szMessage,';'))
				{
					iLoc2 = pDest - szMessage;
					nChar = iLoc2 - iLoc1;
					memset(Command.szElement,'\0',sizeof(Command.szElement));
					strncpy(Command.szElement,&szMessage[iLoc1],nChar);
					pCommandNode = Add_Command(pCommandNode,Command);
					memset(&szMessage[iLoc2],':',1);
					iLoc1 = iLoc2 + 1;
				}

				pCommandNode = CommandStart.pNext;
				if (pCommandNode)
				{
					iCompressions = atoi(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;

					iGridX = atoi(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;
					iGridY = atoi(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;

					iStartPos = atol(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;

					iLen = atol(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;

					iCompLen = atol(pCommandNode->Command.szElement);
					pCommandNode = pCommandNode->pNext;
				}

				if (iLen > iCompLen)
					pDIBCompress = (char *)malloc(iLen);
				else
					pDIBCompress = (char *)malloc(iCompLen);

				while (pGdiNode)
				{
					if ((pGdiNode->Gdi.iGridX == iGridX) &&
						(pGdiNode->Gdi.iGridY == iGridY))
					{
						if (!pGdiNode->Gdi.fDIBitmap)
						{
							pGdiNode->Gdi.pDIBitmap = malloc(iLen);
							memset(pGdiNode->Gdi.pDIBitmap,0,iLen);

							pGdiNode->Gdi.lpBitmapIH = (LPBMIH)pGdiNode->Gdi.pDIBitmap;
							pGdiNode->Gdi.iWidth1 = iGridX * iWidthX;
							pGdiNode->Gdi.iWidth2 = iGridX * iWidthX + iWidthX;
							pGdiNode->Gdi.iHeight1 = iGridY * iHeightY;
							pGdiNode->Gdi.iHeight2 = iGridY * iHeightY + iHeightY;

							iScreenWidth = iWidth;
							iScreenHeight = iHeight;

							pGdiNode->Gdi.pDIB = (char *)malloc(iLen);
							pGdiNode->Gdi.pStartDIB = pGdiNode->Gdi.pDIB;
						}

						strcpy(szMessage,"OK\0");
						iSent = Send(sClient,szMessage);
						pStartDIB = pDIBCompress;
						Receive(sClient,pDIBCompress,iCompLen);
						pDIBCompress = pStartDIB;
						pStartDIB = pGdiNode->Gdi.pStartDIB;

						if (iCompressionLevel == 0)
						{
							memblast(pGdiNode->Gdi.pDIB,pDIBCompress,iLen);
							iNewLen = iLen;
						}
						else if (iCompressionLevel == 10)
						{
							iNewLen = HuffmanUnCompress((BYTE *)pDIBCompress,(BYTE *)pGdiNode->Gdi.pDIB);
						}
						else if (iCompressionLevel == 11)
						{
							for (jLoop = 0;jLoop < iCompressions;jLoop++)
							{
								iNewLen = HuffmanUnCompress((BYTE *)pDIBCompress,(BYTE *)pGdiNode->Gdi.pDIB);
								if ((jLoop + 1) < iCompressions)
									memblast(pDIBCompress,pGdiNode->Gdi.pDIB,iNewLen);
							}
						}
						else if (iCompressionLevel == 12) 
						{
							iNewLen = RunLengthDecode((BYTE *)pDIBCompress,(BYTE *)pGdiNode->Gdi.pDIB);
						}
						else if (iCompressionLevel == 13)
						{
							char	*pTempDIB;
							iLen = HuffmanGetSize((BYTE *)pDIBCompress);
							pTempDIB = (char *)malloc(iLen);
							iRLELen = HuffmanUnCompress((BYTE *)pDIBCompress,(BYTE *)pTempDIB);
							iNewLen = RunLengthDecode((BYTE *)pTempDIB,(BYTE *)pGdiNode->Gdi.pDIB);

							free(pTempDIB);
						}

						pGdiNode->Gdi.pDIB = pGdiNode->Gdi.pStartDIB;
						lpBMIH = (LPBMIH)pGdiNode->Gdi.pDIB;

						if (fFirstTime)
						{
							pTempDIB = pGdiNode->Gdi.pDIBitmap;
							memblast(&pGdiNode->Gdi.pDIBitmap[iStartPos],pGdiNode->Gdi.pDIB,iNewLen);

							pGdiNode->Gdi.fDIBitmap = TRUE;
						}
						else
						{
							pTempDIB = pGdiNode->Gdi.pDIBitmap;
							pDIB = pGdiNode->Gdi.pDIB;

							__asm
							{
								MOV		ECX,iNewLen 
								SHR		ECX,2 
								MOV		EDI,pTempDIB
								ADD		EDI,iStartPos
								MOV		ESI,pDIB
								Addition:
								LODSD
								ADD		[EDI],EAX
								ADD		EDI,4
								DEC		ECX
								JNZ		Addition
							}
						}

						Clear_Command(&CommandStart);
						strcpy(szMessage,"OK\0");
						iSent = Send(sClient,szMessage);
						break;
					}
					pGdiNode = pGdiNode->pNext;
				}

				free(pDIBCompress);
			}

			if (fFirstTime)
				fDIBitmap = TRUE;
			InvalidateRect(hWnd,NULL,FALSE);
		}
		fRefreshing = FALSE;
	}
}

DWORD Receive(SOCKET Socket,char *pData,DWORD iLength)
{
	WSAOVERLAPPED	olRecv;
	WSAEVENT	gheventOlSock;
	WSAEVENT	eventArray[2];

	WSABUF		buffRecv;
	DWORD		dwRet,dwNumBytes,dwFlags;
	int			nWSAError;
	DWORD		iNumBytes = 0;

	char		szError[81];

	gheventOlSock = WSACreateEvent();
	eventArray[0] = gheventOlSock;

	ZeroMemory(&olRecv,sizeof(WSAOVERLAPPED));
	olRecv.hEvent= gheventOlSock;
	buffRecv.len = iLength;
	buffRecv.buf = pData;

	fReceiving = TRUE;

	while (TRUE)
	{
		dwFlags = 0;
		dwNumBytes = 0;

		if ((dwRet = WSARecv(Socket,&buffRecv,1,&dwNumBytes,&dwFlags,&olRecv,NULL)) == SOCKET_ERROR) 
		{
			nWSAError = WSAGetLastError();
			if (nWSAError != ERROR_IO_PENDING)
			{
				sprintf(szError,"WSARecv failed with error %d\n",nWSAError);
				MessageBox(NULL,szError,"Client",MB_OK);
				return SOCKET_ERROR;
			}
		}

		if (WSAWaitForMultipleEvents(1,eventArray,FALSE,WSA_INFINITE,FALSE) == WSA_WAIT_FAILED) 
		{
			sprintf(szError,"WSAWaitForMultipleEvents failed %d\n", WSAGetLastError());
			MessageBox(NULL,szError,"Client",MB_OK);
		} 
		WSAResetEvent(eventArray[0]);
		if (WSAGetOverlappedResult(Socket,&olRecv,&dwNumBytes,FALSE,&dwFlags) == TRUE)
		{
			if (dwNumBytes == 0)
				break;
		} 
		else 
		{
			sprintf(szError,"WSAGetOverlappedResult failed with error %d\n", WSAGetLastError());
			MessageBox(NULL,szError,"Client",MB_OK);
			return SOCKET_ERROR;
		}
		buffRecv.len -= dwNumBytes;
		iNumBytes = iNumBytes + dwNumBytes;
		if (buffRecv.len == 0) 
			break;
		else 
			buffRecv.buf += dwNumBytes;
	}
	fReceiving = FALSE;
	return iNumBytes;
}

int SelectProtocols(DWORD dwSetFlags,DWORD dwNotSetFlags,LPWSAPROTOCOL_INFO lpProtocolBuffer,LPDWORD lpdwBufferLength,WSAPROTOCOL_INFO *pProtocol)
{
	LPBYTE				pBuf;
	LPWSAPROTOCOL_INFO	pInfo;
	DWORD				dwNeededLen;
	LPWSAPROTOCOL_INFO	pRetInfo;
	DWORD				dwRetLen;
	int					nCount;
	int					nMatchCount;
	int					nRet;

	dwNeededLen = 0;
	nRet = WSAEnumProtocols(NULL, NULL, &dwNeededLen);
	if (nRet == SOCKET_ERROR)
	{
		if (WSAGetLastError() != WSAENOBUFS)
			return SOCKET_ERROR;
	}

	pBuf = malloc(dwNeededLen);
	if (pBuf == NULL)
	{
		WSASetLastError(WSAENOBUFS);
		return SOCKET_ERROR;
	}

	nRet = WSAEnumProtocols(NULL,(LPWSAPROTOCOL_INFO)pBuf,&dwNeededLen);
	if (nRet == SOCKET_ERROR)
	{
		free(pBuf);
		return SOCKET_ERROR;
	}
	#define REJECTSET(f) \
	    ((dwSetFlags & f) && !(pInfo->dwServiceFlags1 & f))
	#define REJECTNOTSET(f) \
	    ((dwNotSetFlags &f) && (pInfo->dwServiceFlags1 & f))
	#define REJECTEDBY(f) (REJECTSET(f) || REJECTNOTSET(f))

	pInfo = (LPWSAPROTOCOL_INFO)pBuf;	
	pRetInfo = lpProtocolBuffer;
	dwRetLen = 0;
	nMatchCount = 0;
	for(nCount = 0; nCount < nRet; nCount++)
	{
		while(1)
		{
			if (REJECTEDBY(XP1_CONNECTIONLESS))
				break;
			if (REJECTEDBY(XP1_GUARANTEED_DELIVERY))
				break;
			if (REJECTEDBY(XP1_GUARANTEED_ORDER))
				break;
			if (REJECTEDBY(XP1_MESSAGE_ORIENTED))
				break;
			if (REJECTEDBY(XP1_PSEUDO_STREAM))
				break;
			if (REJECTEDBY(XP1_GRACEFUL_CLOSE))
				break;
			if (REJECTEDBY(XP1_EXPEDITED_DATA))
				break;
			if (REJECTEDBY(XP1_CONNECT_DATA))
				break;
			if (REJECTEDBY(XP1_DISCONNECT_DATA))
				break;
			if (REJECTEDBY(XP1_SUPPORT_BROADCAST)) 
				break;
			if (REJECTEDBY(XP1_SUPPORT_MULTIPOINT))
				break;
			if (REJECTEDBY(XP1_MULTIPOINT_DATA_PLANE))
				break;
			if (REJECTEDBY(XP1_QOS_SUPPORTED))
				break;
			if (REJECTEDBY(XP1_UNI_SEND))
				break;
			if (REJECTEDBY(XP1_UNI_RECV))
				break;
			if (REJECTEDBY(XP1_IFS_HANDLES))
				break;
			if (REJECTEDBY(XP1_PARTIAL_MESSAGE))
				break;

			dwRetLen += sizeof(WSAPROTOCOL_INFO);
			if (dwRetLen > *lpdwBufferLength)
			{
				WSASetLastError(WSAENOBUFS);
				*lpdwBufferLength = dwNeededLen;
				free(pBuf);
				return SOCKET_ERROR;
			}
			nMatchCount++;
			memblast(pRetInfo,pInfo,sizeof(WSAPROTOCOL_INFO));
			if (strcmp(pInfo->szProtocol,"MSAFD Tcpip [TCP/IP]") == 0)
				memblast(pProtocol,pInfo, sizeof(WSAPROTOCOL_INFO));

			pRetInfo++;
			break;
		}
		pInfo++;
	}
	free(pBuf);
	*lpdwBufferLength = dwRetLen;
	return(nMatchCount);
}

void memblast(void* dest,void* src,DWORD count)
{
	DWORD	iCount;

	__asm
	{
		MOV		ECX,count
		SHR		ECX,2
		SHL		ECX,2
		MOV		iCount,ECX
		MOV		ESI,src	
		MOV		EDI,dest
		MOV		ECX,iCount
		SHR		ECX,2	
		REP		MOVSD	

		MOV		ECX,count
		MOV		EAX,iCount
		SUB		ECX,EAX

		JZ		Exit
		MOV		ESI,src	
		ADD		ESI,EAX	
		MOV		EDI,dest
		ADD		EDI,EAX
		REP		MOVSB	
		Exit:
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -