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

📄 vncserver.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//  Copyright (C) 2006 Teamviewer GmbH. All Rights Reserved.
//  Copyright (C) 2002 Ultr@Vnc Team Members. All Rights Reserved.
//  Copyright (C) 2000-2002 Const Kaplinsky. All Rights Reserved.
//  Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
//  This file is part of TeamViewer.
//
//  TeamViewer is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//
//  If the source code for TeamViewer is not available from the place 
//  whence you received this file, check http://www.teamviewer.com
//  for information on obtaining it.


// vncServer.cpp

// vncServer class implementation

// Includes
#include "stdhdrs.h"

// Custom
#include "vncServer.h"
#include "vncSockConnect.h"
#include "vncClient.h"
#include "vncService.h"
#include "vncTimedMsgBox.h"
#include "vncMenu.h"
#include "Global.h"
#include "../../vncviewer/SessionDialog.h"

#include "localization.h" // ACT : Add localization on messages
bool g_Server_running;
extern bool g_Desktop_running;
extern bool isQuickSupport;
extern vncMenu* menu;

using namespace std;
// vncServer::UpdateTracker routines

void
vncServer::ServerUpdateTracker::add_changed(const rfb::Region2D &rgn) {
	vncClientList::iterator i;
	
	omni_mutex_lock l(m_server->m_clientsLock);

	// Post this update to all the connected clients
	for (i = m_server->m_authClients.begin(); i != m_server->m_authClients.end(); i++)
	{
		// Post the update
		// REalVNC 336 change
		// m_server->GetClient(*i)->GetUpdateTracker().add_changed(rgn);
		vncClient* client = m_server->GetClient(*i);
		omni_mutex_lock l(client->GetUpdateLock());
		client->GetUpdateTracker().add_changed(rgn);

	}
}

void
vncServer::ServerUpdateTracker::add_cached(const rfb::Region2D &rgn) {
	vncClientList::iterator i;
	
	omni_mutex_lock l(m_server->m_clientsLock);

	// Post this update to all the connected clients
	for (i = m_server->m_authClients.begin(); i != m_server->m_authClients.end(); i++)
	{
		// Post the update
		// RealVNC 336 change
		// m_server->GetClient(*i)->GetUpdateTracker().add_cached(rgn);
		vncClient* client = m_server->GetClient(*i);
		omni_mutex_lock l(client->GetUpdateLock());
		client->GetUpdateTracker().add_cached(rgn);
	}
}





void
vncServer::ServerUpdateTracker::add_copied(const rfb::Region2D &dest, const rfb::Point &delta) {
	vncClientList::iterator i;
	
	omni_mutex_lock l(m_server->m_clientsLock);

	// Post this update to all the connected clients
	for (i = m_server->m_authClients.begin(); i != m_server->m_authClients.end(); i++)
	{
		// Post the update
		// RealVNC 336 change
		//m_server->GetClient(*i)->GetUpdateTracker().add_copied(dest, delta);
		vncClient* client = m_server->GetClient(*i);
		omni_mutex_lock l(client->GetUpdateLock());
		client->GetUpdateTracker().add_copied(dest, delta);

	}
}



// Constructor/destructor
vncServer::vncServer()
{
	// Initialise some important stuffs...
	g_Server_running=true;

	m_socketConn = NULL;
	m_httpConn = NULL;
	m_enableHttpConn = false;
	m_desktop = NULL;
	m_name = NULL;
	m_port = DISPLAY_TO_PORT(0);
	m_port_http = DISPLAY_TO_HPORT(0); // TightVNC 1.2.7
	m_autoportselect = TRUE;
	m_passwd_required = TRUE;
	m_auth_hosts = 0;
	m_blacklist = 0;
	{
	    vncPasswd::FromClear clearPWD;
	    memcpy(m_password, clearPWD, MAXPWLEN);
	}

	m_querysetting = 4;
	m_queryaccept = 0;
	m_querytimeout = 10;


	// Autolock settings
	m_lock_on_exit = 0;

	// Set the polling mode options
	m_poll_fullscreen = TRUE;
	m_poll_foreground = FALSE;
	m_poll_undercursor = FALSE;

	m_poll_oneventonly = FALSE;
	m_poll_consoleonly = TRUE;

	m_driver = false;
	m_hook = true;
	sethook=false;
	
	// General options
	m_loopbackOnly = FALSE;
	m_loopback_allowed = true;
	m_lock_on_exit = 0;
	m_connect_pri = 0;
	m_disableTrayIcon = FALSE;
	m_AllowEditClients = FALSE;

	// Set the input options
	m_enable_remote_inputs = TRUE;
	m_disable_local_inputs = FALSE;

	// Clear the client mapping table
	for (int x=0; x<MAX_CLIENTS; x++)
		m_clientmap[x] = NULL;
	m_nextid = 0;

	// Initialise the update tracker
	m_update_tracker.init(this);

	// Signal set when a client quits
	m_clientquitsig = new omni_condition(&m_clientsLock);

	// Modif sf@2002
	m_SingleWindow = FALSE;
	strcpy(m_szWindowName, "");

	// Modif sf@2002
	m_TurboMode = false;
	// m_fCursorMoved = false;

	// TR@2003
	m_AcceptDialog = false;
	m_shutdown = false;
	//m_autostartsetting = 1;

	// sf@2002 - v1.1.2
	// m_fQueuingEnabled = false;
	m_fFileTransferEnabled = 2; // TR@2004 - defaults to allowed after query
	m_nDefaultScale = 1;

	m_fMSLogonRequired = false;

	m_fXRichCursor = false;

	// sf@2003 - Autoreconnect
	m_fAutoReconnect = false;
	m_AutoReconnectPort = 0;
	strcpy(m_szAutoReconnectAdr, "");

	// sf@2005 - No FT User Impersonnation
	m_fFTUserImpersonation = true;
	m_fBlackAlphaBlending = false;

	// Staudenmeyer@2005
	m_displayQuality = 1;  // autoselect
	m_incomingConnections=ConnectionNone;
	m_sessionDialogShown=false;
	m_hSessionDialog = NULL;
	m_updateHandling=UpdateHandlingOptimizeQuality;
	//m_keepDialogOpen=false;
	m_useDynGate=true;

	m_serverMode=false;
	m_logging=false;
	m_connectionLogging=true;

	m_identity[0] = '\0';
	m_remove_wallpaper = FALSE;
	m_sessionPassword=GenerateSessionPassword();

	m_idle_timeout = 0;
	m_DesktopLocked = false;
}
std::string vncServer::GenerateSessionPassword()
{
	srand((unsigned int)time(NULL));
	const int passwordLength=4;
	string chars="1234567890";
	string password="";
	for(int i=0;i<passwordLength;i++)
	{
		int index=rand()%chars.length();
		password=password+chars[index];
	}
#ifdef _DEBUG
	password = "0";
#endif

	return password;
}

vncServer::~vncServer()
{
	vnclog.Print(LL_STATE, VNCLOG("shutting down server object"));

	// If there is a socket_conn object then delete it
	if (m_socketConn != NULL)
	{
		delete m_socketConn;
		m_socketConn = NULL;
	}

	if (m_httpConn != NULL)
	{
		delete m_httpConn;
		m_httpConn = NULL;
	}

	// Remove any active clients!
	KillAuthClients();
	KillUnauthClients();

	// Wait for all the clients to die
	WaitUntilAuthEmpty();
	WaitUntilUnauthEmpty();

	// Don't free the desktop until no KillClient is likely to free it
	{	omni_mutex_lock l(m_desktopLock);

		if (m_desktop != NULL)
		{
			delete m_desktop;
			m_desktop = NULL;
		}
	}
	while (g_Desktop_running)
	{
		Sleep(100);
		vnclog.Print(LL_STATE, VNCLOG("Waiting for desktop to shutdown"));
	}

	// Don't free the authhosts string until no more connections are possible
	if (m_auth_hosts != 0)
	{
		free(m_auth_hosts);
		m_auth_hosts = 0;
	}

	if (m_name != NULL)
	{
		free(m_name);
		m_name = NULL;
	}

	if (m_clientquitsig != NULL)
	{
		delete m_clientquitsig;
		m_clientquitsig = NULL;
	}

	// Free the host blacklist
	while (m_blacklist) {
		vncServer::BlacklistEntry *current = m_blacklist;
		m_blacklist=m_blacklist->_next;

		free (current->_machineName);
		delete current;
	}
	//We need to give the client thread to give some time to close
	// bad hack
	Sleep(500);
	//sometimes crash, vnclog seems already removed
//	vnclog.Print(LL_STATE, VNCLOG("shutting down server object(4)"));
	g_Server_running=false;
}


// Client handling functions
vncClientId
vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared)
{
	SYSTEMTIME dummyTime;
	GetSystemTime(&dummyTime);
	return AddClient(socket, auth, shared, 0, NULL, "", dummyTime); 
}

vncClientId
vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared, string clientname, SYSTEMTIME start)
{
	return AddClient(socket, auth, shared,0, NULL, clientname, start); 
}

vncClientId
vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared, rfbProtocolVersionMsg *protocolMsg)
{
	SYSTEMTIME dummyTime;
	GetSystemTime(&dummyTime);
	return AddClient(socket, auth, shared, 0, protocolMsg, "", dummyTime); 
}


vncClientId
vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared,
					  int capability, rfbProtocolVersionMsg *protocolMsg, string clientname, SYSTEMTIME start)
{
	vncClient *client;

	omni_mutex_lock l(m_clientsLock);

	// Try to allocate a client id...
	vncClientId clientid = m_nextid;
	do
	{
		clientid = (clientid+1) % MAX_CLIENTS;
		if (clientid == m_nextid)
		{
			delete socket;
			return -1;
		}
	}
	while (m_clientmap[clientid] != NULL);

	// Create a new client and add it to the relevant client list
	client = new vncClient();
	if (client == NULL) {
		delete socket;
		return -1;
	}

	// Set the client's settings
	client->SetProtocolVersion(protocolMsg);
	client->SetCapability(capability);
	client->EnableKeyboard(/*keysenabled &&*/ m_enable_remote_inputs);
	client->EnablePointer(/*ptrenabled &&*/ m_enable_remote_inputs);

	// Start the client
	if (!client->Init(this, socket, auth, shared, clientid))
	{
		// The client will delete the socket for us...
		vnclog.Print(LL_CONNERR, VNCLOG("failed to initialise client object"));
		delete client;
		return -1;
	}

	client->connectionLogUser = clientname;
	client->connectionLogStartTime = start;

	m_clientmap[clientid] = client;

	// Add the client to unauth the client list
	
	m_unauthClients.push_back(clientid);

	// Notify anyone interested about this event
	DoNotify(WM_SRV_CLIENT_CONNECT, 0, 0);

	// after start of a new connection input is not disabled and the monitor is never blank
	m_fInputIsDisabled = false;
	m_fMonitorIsBlanked = false;

	vnclog.Print(LL_INTINFO, VNCLOG("AddClient() done"));

	return clientid;
}

BOOL
vncServer::Authenticated(vncClientId clientid)
{
	vncClientList::iterator i;
	BOOL authok = TRUE;
//	vnclog.Print(LL_INTINFO, VNCLOG("Lock2"));
	omni_mutex_lock l1(m_desktopLock);
//	vnclog.Print(LL_INTINFO, VNCLOG("Lock3"));
	omni_mutex_lock l2(m_clientsLock);

	// Search the unauthenticated client list
	for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++)
	{
		// Is this the right client?
		if ((*i) == clientid)
		{
			vncClient *client = GetClient(clientid);
			

			// Yes, so remove the client and add it to the auth list
			m_unauthClients.erase(i);

            //CW@2004
            //Client zum l鰏chen freigeben 
			client->m_IsAuthed = TRUE;

			// Create the screen handler if necessary
			if (m_desktop == NULL)
			{
				m_desktop = new vncDesktop();
				if (m_desktop == NULL)
				{
					client->Kill();
					authok = FALSE;
					break;
				}
				if (!m_desktop->Init(this))
				{
					vnclog.Print(LL_INTINFO, VNCLOG("Desktop init failed, unlock in application mode ? "));

					if(TeamviewerInfo::getLocalInfo(tvError) == "")	// if TeamViewer-Error is set kill client later
					{
						client->Kill();
						authok = FALSE;
					}
					delete m_desktop;								// but delete m_desktop so that it is created again next time
					m_desktop = NULL;
					break;
				}
			}
			else if(m_DesktopLocked)
			{
				vnclog.Print(LL_INTINFO, VNCLOG("Desktop is locked"));
				TeamviewerInfo::setLocalInfo(tvError, "WORKSTATION_LOCKED");
				break;
			}

			// Tell the client about this new buffer
			client->SetBuffer(&(m_desktop->m_buffer));

			// Add the client to the auth list
			m_authClients.push_back(clientid);

			break;
		}
	}

	// Notify anyone interested of this event
	DoNotify(WM_SRV_CLIENT_AUTHENTICATED, 0, 0);

	vnclog.Print(LL_INTINFO, VNCLOG("Authenticated() done"));

	return authok;
}

void
vncServer::KillClient(vncClientId clientid)
{
	vncClientList::iterator i;
	BOOL done = FALSE;

	omni_mutex_lock l(m_clientsLock);

	// Find the client in one of the two lists
	for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++)
	{
		// Is this the right client?
		if ((*i) == clientid)
		{
			vnclog.Print(LL_INTINFO, VNCLOG("killing unauth client"));

			// Ask the client to die
			vncClient *client = GetClient(clientid);
			client->Kill();

			done = TRUE;
			break;
		}
	}
	if (!done)
	{
		for (i = m_authClients.begin(); i != m_authClients.end(); i++)
		{
			// Is this the right client?
			if ((*i) == clientid)
			{
				vnclog.Print(LL_INTINFO, VNCLOG("killing auth client"));

				// Yes, so kill it
				vncClient *client = GetClient(clientid);
				client->Kill();

				done = TRUE;
				break;
			}
		}

⌨️ 快捷键说明

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