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

📄 clientconnection.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	m_minorVersion = rfbProtocolMinorVersion;#else    if (sscanf(pv,rfbProtocolVersionFormat,&m_majorVersion,&m_minorVersion) != 2) {		throw WarningException(_T("Invalid protocol"));    }    log.Print(0, _T("RFB server supports protocol version %d.%d\n"),	    m_majorVersion,m_minorVersion);    if ((m_majorVersion == 3) && (m_minorVersion < 3)) {		        /* if server is 3.2 we can't use the new authentication */		log.Print(0, _T("Can't use IDEA authentication\n"));        /* This will be reported later if authentication is requested*/    } else {		        /* any other server version, just tell the server what we want */		m_majorVersion = rfbProtocolMajorVersion;		m_minorVersion = rfbProtocolMinorVersion;    }    sprintf(pv,rfbProtocolVersionFormat,m_majorVersion,m_minorVersion);#endif    WriteExact(pv, sz_rfbProtocolVersionMsg);	log.Print(0, _T("Connected to RFB server, using protocol version %d.%d\n"),		rfbProtocolMajorVersion, rfbProtocolMinorVersion);}void ClientConnection::Authenticate(){	CARD32 authScheme, reasonLen, authResult;    CARD8 challenge[CHALLENGESIZE];		ReadExact((char *)&authScheme, 4);    authScheme = Swap32IfLE(authScheme);	    switch (authScheme) {		    case rfbConnFailed:		ReadExact((char *)&reasonLen, 4);		reasonLen = Swap32IfLE(reasonLen);				CheckBufferSize(reasonLen+1);		ReadString(m_netbuf, reasonLen);				log.Print(0, _T("RFB connection failed, reason: %s\n"), m_netbuf);		throw WarningException(m_netbuf);        break;		    case rfbNoAuth:		log.Print(0, _T("No authentication needed\n"));		break;		    case rfbVncAuth:		{            if ((m_majorVersion == 3) && (m_minorVersion < 3)) {                /* if server is 3.2 we can't use the new authentication */                log.Print(0, _T("Can't use IDEA authentication\n"));                MessageBox(NULL,                     _T("Sorry - this server uses an older authentication scheme\n\r")                    _T("which is no longer supported."),                     _T("Protocol Version error"),                     MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST);                throw WarningException("Can't use IDEA authentication any more!");            }			ReadExact((char *)challenge, CHALLENGESIZE);						char passwd[256];			// Was the password already specified in a config file?			if (strlen((const char *) m_encPasswd)>0) {				char *pw = vncDecryptPasswd(m_encPasswd);				strcpy(passwd, pw);				free(pw);			} else {				AuthDialog ad;				if (ad.DoDialog()) {	#ifndef UNDER_CE					strcpy(passwd, ad.m_passwd);#else					int origlen = _tcslen(ad.m_passwd);					int newlen = WideCharToMultiByte(						CP_ACP,    // code page						0,         // performance and mapping flags						ad.m_passwd, // address of wide-character string						origlen,   // number of characters in string						passwd,    // address of buffer for new string						255,       // size of buffer						NULL, NULL );										passwd[newlen]= '\0';#endif					if (strlen(passwd) == 0) {						log.Print(0, _T("Password had zero length\n"));						throw WarningException("Empty password");					}					if (strlen(passwd) > 8) {						passwd[8] = '\0';					}					vncEncryptPasswd(m_encPasswd, passwd);				} else {					throw QuietException("Authentication cancelled");				}			}								vncEncryptBytes(challenge, passwd);			/* Lose the plain-text password from memory */			for (int i=0; i< (int) strlen(passwd); i++) {				passwd[i] = '\0';			}						WriteExact((char *) challenge, CHALLENGESIZE);			ReadExact((char *) &authResult, 4);						authResult = Swap32IfLE(authResult);						switch (authResult) {			case rfbVncAuthOK:				log.Print(0, _T("VNC authentication succeeded\n"));				break;			case rfbVncAuthFailed:				log.Print(0, _T("VNC authentication failed!"));				throw WarningException("VNC authentication failed!");			case rfbVncAuthTooMany:				throw WarningException(					"VNC authentication failed - too many tries!");			default:				log.Print(0, _T("Unknown VNC authentication result: %d\n"),					(int)authResult);				throw ErrorException("Unknown VNC authentication result!");			}			break;		}			default:		log.Print(0, _T("Unknown authentication scheme from RFB server: %d\n"),			(int)authScheme);		throw ErrorException("Unknown authentication scheme!");    }}void ClientConnection::SendClientInit(){    rfbClientInitMsg ci;	ci.shared = m_opts.m_Shared;    WriteExact((char *)&ci, sz_rfbClientInitMsg);}void ClientConnection::ReadServerInit(){    ReadExact((char *)&m_si, sz_rfbServerInitMsg);	    m_si.framebufferWidth = Swap16IfLE(m_si.framebufferWidth);    m_si.framebufferHeight = Swap16IfLE(m_si.framebufferHeight);    m_si.format.redMax = Swap16IfLE(m_si.format.redMax);    m_si.format.greenMax = Swap16IfLE(m_si.format.greenMax);    m_si.format.blueMax = Swap16IfLE(m_si.format.blueMax);    m_si.nameLength = Swap32IfLE(m_si.nameLength);	    m_desktopName = new TCHAR[m_si.nameLength + 2];#ifdef UNDER_CE    char *deskNameBuf = new char[m_si.nameLength + 2];	ReadString(deskNameBuf, m_si.nameLength);    	MultiByteToWideChar( CP_ACP,   MB_PRECOMPOSED, 			     deskNameBuf, m_si.nameLength,			     m_desktopName, m_si.nameLength+1);    delete deskNameBuf;#else    ReadString(m_desktopName, m_si.nameLength);#endif    	SetWindowText(m_hwnd, m_desktopName);		log.Print(0, _T("Desktop name \"%s\"\n"),m_desktopName);	log.Print(1, _T("Geometry %d x %d depth %d\n"),		m_si.framebufferWidth, m_si.framebufferHeight, m_si.format.depth );	SetWindowText(m_hwnd, m_desktopName);		SizeWindow();}void ClientConnection::SizeWindow(){	// Find how large the desktop work area is	RECT workrect;	SystemParametersInfo(SPI_GETWORKAREA, 0, &workrect, 0);	int workwidth = workrect.right -  workrect.left;	int workheight = workrect.bottom - workrect.top;	log.Print(2, _T("Screen work area is %d x %d\n"), workwidth, workheight);	// Size the window.	// Let's find out how big a window would be needed to display the	// whole desktop (assuming no scrollbars).	RECT fullwinrect;	SetRect(&fullwinrect, 0, 0, m_si.framebufferWidth * m_opts.m_scale_num / m_opts.m_scale_den, 								m_si.framebufferHeight* m_opts.m_scale_num / m_opts.m_scale_den);	AdjustWindowRectEx(&fullwinrect, 			   GetWindowLong(m_hwnd, GWL_STYLE) & ~WS_VSCROLL & ~WS_HSCROLL, 			   FALSE, GetWindowLong(m_hwnd, GWL_EXSTYLE));	m_fullwinwidth = fullwinrect.right - fullwinrect.left;	m_fullwinheight = fullwinrect.bottom - fullwinrect.top;	m_winwidth  = min(m_fullwinwidth,  workwidth);	m_winheight = min(m_fullwinheight, workheight);	SetWindowPos(m_hwnd, HWND_TOP,		workrect.left + (workwidth-m_winwidth) / 2,		workrect.top + (workheight-m_winheight) / 2,		m_winwidth, m_winheight, SWP_SHOWWINDOW);	SetForegroundWindow(m_hwnd);}// We keep a local copy of the whole screen.  This is not strictly necessary// for VNC, but makes scrolling & deiconifying much smoother.void ClientConnection::CreateLocalFramebuffer() {	omni_mutex_lock l(m_bitmapdcMutex);		// We create a bitmap which has the same pixel characteristics as	// the local display, in the hope that blitting will be faster.		TempDC hdc(m_hwnd);	m_hBitmap = ::CreateCompatibleBitmap(hdc, 		m_si.framebufferWidth, 		m_si.framebufferHeight);		if (m_hBitmap == NULL)		throw WarningException("Error creating local image of screen.");		// Select this bitmap into the DC with an appropriate palette	ObjectSelector b(m_hBitmapDC, m_hBitmap);	PaletteSelector p(m_hBitmapDC, m_hPalette);		// Put a "please wait" message up initially	RECT rect;	SetRect(&rect, 0,0, m_si.framebufferWidth, m_si.framebufferHeight);	COLORREF bgcol = RGB(0xcc, 0xcc, 0xcc);	FillSolidRect(&rect, bgcol);		COLORREF oldbgcol  = SetBkColor(  m_hBitmapDC, bgcol);	COLORREF oldtxtcol = SetTextColor(m_hBitmapDC, RGB(0,0,64));	rect.right = m_si.framebufferWidth / 2;	rect.bottom = m_si.framebufferHeight / 2;		DrawText (m_hBitmapDC, _T("Please wait - initial screen loading"), -1, &rect,		DT_SINGLELINE | DT_CENTER | DT_VCENTER);	SetBkColor(  m_hBitmapDC, oldbgcol);	SetTextColor(m_hBitmapDC, oldtxtcol);		InvalidateRect(m_hwnd, NULL, FALSE);}void ClientConnection::SetupPixelFormat() {	// Have we requested a reduction to 8-bit?    if (m_opts.m_Use8Bit) {		      		log.Print(2, _T("Requesting 8-bit truecolour\n"));  		m_myFormat = vnc8bitFormat;    		// We don't support colormaps so we'll ask the server to convert    } else if (!m_si.format.trueColour) {                // We'll just request a standard 16-bit truecolor        log.Print(2, _T("Requesting 16-bit truecolour\n"));        m_myFormat = vnc16bitFormat;            } else {		// Normally we just use the sever's format suggestion		m_myFormat = m_si.format;                m_myFormat.bigEndian = 0; // except always little endian		// It's silly requesting more bits than our current display has, but		// in fact it doesn't usually amount to much on the network.		// Windows doesn't support 8-bit truecolour.		// If our display is palette-based, we want more than 8 bit anyway,		// unless we're going to start doing palette stuff at the server.		// So the main use would be a 24-bit true-colour desktop being viewed		// on a 16-bit true-colour display, and unless you have lots of images		// and hence lots of raw-encoded stuff, the size of the pixel is not		// going to make much difference.		//   We therefore don't bother with any restrictions, but here's the		// start of the code if we wanted to do it.		if (false) {					// Get a DC for the root window			TempDC hrootdc(NULL);			int localBitsPerPixel = GetDeviceCaps(hrootdc, BITSPIXEL);			int localRasterCaps	  = GetDeviceCaps(hrootdc, RASTERCAPS);			log.Print(2, _T("Memory DC has depth of %d and %s pallete-based.\n"), 				localBitsPerPixel, (localRasterCaps & RC_PALETTE) ? "is" : "is not");						// If we're using truecolor, and the server has more bits than we do			if ( (localBitsPerPixel > m_myFormat.depth) && 				! (localRasterCaps & RC_PALETTE)) {				m_myFormat.depth = localBitsPerPixel;				// create a bitmap compatible with the current display				// call GetDIBits twice to get the colour info.				// set colour masks and shifts							}		}	}	// The endian will be set before sending}void ClientConnection::SetFormatAndEncodings(){	// Set pixel format to myFormat    	rfbSetPixelFormatMsg spf;    spf.type = rfbSetPixelFormat;    spf.format = m_myFormat;    spf.format.redMax = Swap16IfLE(spf.format.redMax);    spf.format.greenMax = Swap16IfLE(spf.format.greenMax);    spf.format.blueMax = Swap16IfLE(spf.format.blueMax);    WriteExact((char *)&spf, sz_rfbSetPixelFormatMsg);    // The number of bytes required to hold at least one pixel.	m_minPixelBytes = (m_myFormat.bitsPerPixel + 7) >> 3;	// Set encodings    char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];    rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;    CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);    int len = 0;	    se->type = rfbSetEncodings;    se->nEncodings = 0;	// Put the preferred encoding first, and change it if the	// preferred encoding is not actually usable.	for (int i = LASTENCODING; i >= rfbEncodingRaw; i--)	{		if (m_opts.m_PreferredEncoding == i) {			if (m_opts.m_UseEnc[i]) {				encs[se->nEncodings++] = Swap32IfLE(i);			} else {				m_opts.m_PreferredEncoding--;			}		}	}	// Now we go through and put in all the other encodings in order.	// We do rather assume that the most recent encoding is the most	// desirable!	for (i = LASTENCODING; i >= rfbEncodingRaw; i--)	{		if ( (m_opts.m_PreferredEncoding != i) &&			 (m_opts.m_UseEnc[i]))		{			encs[se->nEncodings++] = Swap32IfLE(i);		}	}    len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;	    se->nEncodings = Swap16IfLE(se->nEncodings);	    WriteExact((char *) buf, len);}// Closing down the connection.// Close the socket, kill the thread.void ClientConnection::KillThread(){	m_bKillThread = true;	m_running = false;	if (m_sock != INVALID_SOCKET) {		shutdown(m_sock, SD_BOTH);		closesocket(m_sock);		m_sock = INVALID_SOCKET;	}}ClientConnection::~ClientConnection(){	if (m_hwnd != 0)		DestroyWindow(m_hwnd);        if (zis)          delete zis;        if (fis)          delete fis;	if (m_sock != INVALID_SOCKET) {		shutdown(m_sock, SD_BOTH);		closesocket(m_sock);		m_sock = INVALID_SOCKET;	}	if (m_desktopName != NULL) delete [] m_desktopName;	delete [] m_netbuf;	DeleteDC(m_hBitmapDC);	if (m_hBitmap != NULL)		DeleteObject(m_hBitmap);	if (m_hBitmapDC != NULL)		DeleteObject(m_hBitmapDC);	if (m_hPalette != NULL)		DeleteObject(m_hPalette);		m_pApp->DeregisterConnection(this);}// You can specify a dx & dy outside the limits; the return value will// tell you whether it actually scrolled.bool ClientConnection::ScrollScreen(int dx, int dy) {	dx = max(dx, -m_hScrollPos);	//dx = min(dx, m_hScrollMax-(m_cliwidth-1)-m_hScrollPos);	dx = min(dx, m_hScrollMax-(m_cliwidth)-m_hScrollPos);	dy = max(dy, -m_vScrollPos);	//dy = min(dy, m_vScrollMax-(m_cliheight-1)-m_vScrollPos);	dy = min(dy, m_vScrollMax-(m_cliheight)-m_vScrollPos);	if (dx || dy) {		m_hScrollPos += dx;

⌨️ 快捷键说明

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