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

📄 clientconnection.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}

	if (!dg)
	{
		// Stop a Waitingthread that might be active
		if (roGateway)
			roGateway->EndWaitAtMaster(LOGOUT_TV_CONN_OUT);

		/* Connect using the standard VNC way */
		struct sockaddr_in thataddr;

		m_sock = socket(PF_INET, SOCK_STREAM, 0);

		// The host may be specified as a dotted address "a.b.c.d"
		// Try that first
		thataddr.sin_addr.s_addr = inet_addr(m_host);
		
		// If it wasn't one of those, do gethostbyname
		if (thataddr.sin_addr.s_addr == INADDR_NONE) {
			LPHOSTENT lphost;
			lphost = gethostbyname(m_host);
			
			if (lphost == NULL) { 
				throw WarningException(sz_L46); 
			};
			thataddr.sin_addr.s_addr = ((LPIN_ADDR) lphost->h_addr)->s_addr;
		};

		thataddr.sin_family = AF_INET;
		thataddr.sin_port = htons(m_port);
		
		res = connect(m_sock, (LPSOCKADDR) &thataddr, sizeof(thataddr));
	}
	if(m_abort_connection)
		return false;

	//if (res == SOCKET_ERROR) {SetDlgItemText(m_hwndStatus,IDC_STATUS,sz_L48);throw WarningException(sz_L48);}
	if (res == SOCKET_ERROR) 
	{
		if (!dg)
			MessageBox(NULL,sz_L48,sz_L91,MB_ICONEXCLAMATION|MB_OK);

		return false;
	}
	return true;
}

void ClientConnection::SetSocketOptions() 
{
	// Disable Nagle's algorithm
	BOOL nodelayval = TRUE;
	if (setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &nodelayval, sizeof(BOOL)))
		throw WarningException(sz_L50);

    fis = new rdr::FdInStream(m_sock);
}


void ClientConnection::NegotiateProtocolVersion()
{
	rfbProtocolVersionMsg pv;

   /* if the connection is immediately closed, don't report anything, so
       that pmw's monitor can make test connections */
    try
	{
		ReadExact(pv, sz_rfbProtocolVersionMsg);
	}
	catch (Exception &c)
	{
		vnclog.Print(0, VNCLOG(_T("Error reading protocol version: %s")), c.m_info);

		throw QuietException(c.m_info);
	}

    pv[sz_rfbProtocolVersionMsg] = 0;

    if (sscanf(pv,rfbProtocolVersionFormat,&m_majorVersion,&m_minorVersion) != 2)
	{		
		if (strncmp(pv,"TV",2)==0)		//TeamViewer 3
		{
			sprintf(pv,rfbProtocolVersionFormat, 2, rfbProtocolMinorVersion);
			WriteExact(pv, sz_rfbProtocolVersionMsg);
			
			PostMessage(menu->GetHWND(),WM_REQUEST_UPDATE_TEAMVIEWER,0,0);
						
			throw QuietException("Connection failed - incompatible TeamViewer version!\r\n");
			//throw WarningException(sz_IDS_CONNECTTO_TEAMVIEWER3);
		}
		else
		{
			throw WarningException("Connection failed - Invalid protocol !\r\n");
		}
    }

    vnclog.Print(0, VNCLOG(_T("TV server supports protocol version %d.%d")),
	    m_majorVersion,m_minorVersion);

	// UltraVNC specific functionnalities
	// - ms logon
	// - FileTransfer (TODO: change Minor version in next eSVNC release so it's compatible with Ultra)
	// Minor = 4 means that server supports FileTransfer and requires ms logon
	// Minor = 6 means that server support FileTransfer and requires normal VNC logon
	if (m_minorVersion == 4)
	{
		m_ms_logon = true;
		m_fServerKnowsFileTransfer = true;
	}
	if (m_minorVersion == 6) // 6 because 5 already used in TightVNC viewer for some reason
	{
		m_ms_logon = false;
		m_fServerKnowsFileTransfer = true;
	}

	if (m_minorVersion%200 == 34 || m_minorVersion == 14) // TamViewer alt (14) + neu (34) akzeptieren
	{
		m_ms_logon = true;
		m_fServerKnowsFileTransfer = true;
		m_ServerKnowsModeChange = true;
	}
	if (m_minorVersion%200 == 36 || m_minorVersion == 16 ) // alt + neu akzeptieren
	{
		m_ms_logon = false;
		m_fServerKnowsFileTransfer = true;
		m_ServerKnowsModeChange = true;
	}

	// version 234 oder 236 -> TeamviewerInfo wird unterst黷zt
	if (m_minorVersion == rfbProtocolMinorVersion || m_minorVersion == rfbProtocolMinorVersion+2)
	{
		m_tvinfo->partnerIsTeamviewer = true;
	}

	// Is Server either TeamViewer or UltraVNC?
	m_fServerIsUltra = (m_minorVersion%10==4)||(m_minorVersion%10==6);

    if ((m_majorVersion == 3) && (m_minorVersion < 3)) {
		
        /* if server is 3.2 we can't use the new authentication */
		vnclog.Print(0, VNCLOG(_T("Can't use IDEA authentication")));
        /* This will be reported later if authentication is requested*/

    } else {
		
        /* any other server version, just tell the server what we want */
		m_majorVersion = rfbProtocolMajorVersion;
		if (m_minorVersion != 14 && m_minorVersion != 16) // For backward-compatibility to older TeamViewer servers
		{
			// RealVNC (minorVersion==8) doesn't accept minor version 34 - so we send 6 (UltraVNC) instead
			if (m_minorVersion == 8)			
				m_minorVersion = 6;							// we lie and tell we are UltraVNC with VNC-Logon
			else 
			// lesser of our and servers version number
				m_minorVersion = min(rfbProtocolMinorVersion, m_minorVersion);	
		}
    }

    sprintf(pv,rfbProtocolVersionFormat, m_majorVersion, m_minorVersion);

    WriteExact(pv, sz_rfbProtocolVersionMsg);

	vnclog.Print(0, VNCLOG(_T("Connected to RFB server, using protocol version %d.%d")),
		rfbProtocolMajorVersion, rfbProtocolMinorVersion);
}

void ClientConnection::Authenticate()
{
	CARD32 authScheme, reasonLen, authResult;
    CARD8 challenge[CHALLENGESIZE];
	CARD8 challengems[CHALLENGESIZEMS];
	
	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);
		
		vnclog.Print(0, VNCLOG(_T("RFB connection failed, reason: %s")), m_netbuf);
		throw WarningException(m_netbuf);
        break;
		
    case rfbNoAuth:
		vnclog.Print(0, VNCLOG(_T("No authentication needed")));
		break;
		
    case rfbVncAuth:
		{
            if ((m_majorVersion == 3) && (m_minorVersion < 3)) 
			{
                /* if server is 3.2 we can't use the new authentication */
                vnclog.Print(0, VNCLOG(_T("Can't use IDEA authentication")));

                MessageBox(NULL, 
                    sz_L51, 
                    sz_L52, 
                    MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST);

                throw WarningException("Can't use IDEA authentication any more!");
            }
			// rdv@2002 - v1.1.x
			char passwd[256];
			char domain[256];
			char user[256];

			memset(passwd, 0, sizeof(char)*256);
			memset(domain, 0, sizeof(char)*256);
			memset(user, 0, sizeof(char)*256);

			// We ignore the clear password in case of ms_logon !
			// Todo: Add ms_user & ms_password command line params
			if (m_ms_logon) memset(m_clearPasswd, 0, sizeof(m_clearPasswd));

			// Was the password already specified in a config file or entered for DSMPlugin ?
			// Modif sf@2002 - A clear password can be transmitted via the vncviewer command line
			if (strlen(m_clearPasswd)>0)
			{
				strcpy(passwd, m_clearPasswd);
			} 
			else if (strlen((const char *) m_encPasswd)>0)
			{
				char *pw = vncVDecryptPasswd(m_encPasswd);
				strcpy(passwd, pw);
				free(pw);
			}
			else 
			{
				if (ad.DoDialog(m_ms_logon))
				{
					strncpy(passwd, ad.m_passwd,254);
					strncpy(user, ad.m_user,254);
					strncpy(domain, ad.m_domain,254);
					if (strlen(user)==0 ||!m_ms_logon)//need longer passwd for ms
						{
							if (strlen(passwd) == 0) {
								vnclog.Print(0, VNCLOG(_T("Password had zero length")));
								throw WarningException(sz_L53);
							}
							if (strlen(passwd) > 8) {
								passwd[8] = '\0';
							}
						}
					if (m_ms_logon) vncVEncryptPasswdMs(m_encPasswdMs, passwd);
					vncVEncryptPasswd(m_encPasswd, passwd);
				} 
				else 
				{
					throw QuietException(sz_L54);
				}
			}

			if (m_ms_logon) ReadExact((char *)challengems, CHALLENGESIZEMS);
			ReadExact((char *)challenge, CHALLENGESIZE);

			// MS logon
			if (m_ms_logon) 
			{
				int i=0;
				for (i=0;i<32;i++)
				{
					challengems[i]=m_encPasswdMs[i]^challengems[i];
				}
				WriteExact((char *) user, sizeof(char)*256);
				WriteExact((char *) domain, sizeof(char)*256);
				WriteExact((char *) challengems, CHALLENGESIZEMS);
				vncVEncryptBytes(challenge, passwd);

				/* Lose the plain-text password from memory */
				int nLen = (int)strlen(passwd);
				for ( i=0; i< nLen; i++) {
					passwd[i] = '\0';
				}
			
				WriteExact((char *) challenge, CHALLENGESIZE);
			}
			else // Regular VNC logon
			{
				vncVEncryptBytes(challenge, passwd);

				/* Lose the plain-text password from memory */
				int nLen = (int)strlen(passwd);
				for (int i=0; i< nLen; i++) {
					passwd[i] = '\0';
				}
			
				WriteExact((char *) challenge, CHALLENGESIZE);
			}
			ReadExact((char *) &authResult, 4);
			
			authResult = Swap32IfLE(authResult);
			
			switch (authResult) 
			{
			case rfbVncAuthOK:
				vnclog.Print(0, VNCLOG(_T("VNC authentication succeeded")));
				g_passwordfailed=false;
				break;
			case rfbVncAuthFailed:
				vnclog.Print(0, VNCLOG(_T("VNC authentication failed!")));
				g_passwordfailed=true;
				
				// test if Caps-Lock is active
				if(GetKeyState(VK_CAPITAL) & 1) 
					throw WarningException(sz_L93);		// warning: caps lock active
				else
					throw WarningException(sz_L57);		// wrong password
			case rfbVncAuthTooMany:
				throw WarningException(
					sz_L58);
			default:
				vnclog.Print(0, VNCLOG(_T("Unknown VNC authentication result: %d")),
					(int)authResult);
				throw ErrorException(sz_L59);
			}
			break;
		}
		
	default:
		vnclog.Print(0, VNCLOG(_T("Unknown authentication scheme from RFB server: %d")),
			(int)authScheme);
		throw ErrorException(sz_L60);
    }
}

void ClientConnection::SendClientInit()
{
    rfbClientInitMsg ci;
	ci.shared = TRUE;			// tell server to share the desktop with other clients

    WriteExact((char *)&ci, sz_rfbClientInitMsg); // sf@2002 - RSM Plugin
}

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 + 4 + 256];

    ReadString(m_desktopName, m_si.nameLength);

	if (m_opts.m_ActiveMode  == rfbMC_PresentationClient)
	{
		// Bei Direktwechsel in Servermode Fenster unterdr點ken
		SizeWindow();
		m_WindowTitle = "";
		// Don't set window title to IP address
	}
	else
	{
		// sprintf(tcDummy,"%s ",m_desktopName);
		strcat(m_desktopName, " ");
		m_WindowTitle = m_desktopName;
		SetWindowText(m_hwndMain, m_desktopName);	

		vnclog.Print(0, VNCLOG(_T("Desktop name \"%s\"")),m_desktopName);
		vnclog.Print(1, VNCLOG(_T("Geometry %d x %d depth %d")),
			m_si.framebufferWidth, m_si.framebufferHeight, m_si.format.depth );
	}
	
	if(m_si.framebufferHeight == 0)		// if there was an error don't show viewer window
		ShowWindow(m_hwndMain, SW_HIDE);
}

// start auto scaling
void ClientConnection::BeginAutoScaling() 
{
	int nLocalHeight, nLocalWidth;
	RECT workrect;

	// Find how large the desktop work area is
	SystemParametersInfo(SPI_GETWORKAREA, 0, &workrect, 0);
	int workwidth = workrect.right - workrect.left;
	int workheight = workrect.bottom - workrect.top;
	vnclog.Print(2, VNCLOG(_T("Screen work area is %d x %d")), workwidth, workheight);

	nLocalHeight = workheight - borderHeight();
	nLocalWidth = workwidth - borderWidth();

	if(nLocalHeight > m_si.framebufferHeight && nLocalWidth > m_si.framebufferWidth)
	{
		m_opts.m_scale_num = 1;
		m_opts.m_scale_den = 1;
	}
	else
	{
		if(m_si.framebufferHeight*nLocalWidth > nLocalHeight*m_si.framebufferWidth)
		{
			m_opts.m_scale_num = nLocalHeight;
			m_opts.m_scale_den = m_si.framebufferHeight;
		}
		else
		{
			m_opts.m_scale_num = nLocalWidth;
			m_opts.m_scale_den = m_si.framebufferWidth;
		}
		
		m_opts.m_scale_num = AUTOSCALE_GRANULARITY * m_opts.m_scale_num / m_opts.m_scale_den;

		// denominator should be as small as possible, so that only small rectangles need to
		// be repainted when scaling
		int g = gcd(m_opts.m_scale_num, AUTOSCALE_GRANULARITY);
		m_opts.m_scale_num /= g;
		m_opts.m_scale_den = AUTOSCALE_GRANULARITY / g;
	}
	m_opts.m_scaling = true;
}

// this function is called when window is sized to calculate new scaling
void ClientConnection::AutoScale()
{
	int nLocalHeight, nLocalWidth;
	RECT clientrect;
	GetWindowRect(m_hwndMain, &clientrect);
	nLocalHeight = (clientrect.bottom - clientrect.top) - borderHeight();
	nLocalWidth  = (clientrect.right - clientrect.left) - borderWidth();
	if(m_si.framebufferHeight*nLocalWidth > nLocalHeight*m_si.framebufferWidth)
	{
		m_opts.m_scale_num = nLocalHeight;
		m_opts.m_scale_den = m_si.framebufferHeight;
	}
	else

⌨️ 快捷键说明

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