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

📄 vncclient.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{		// Send no-auth-required message		CARD32 auth_val = Swap32IfLE(rfbNoAuth);		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))			return FALSE;	}	else	{		// Send auth-required message		CARD32 auth_val = Swap32IfLE(rfbVncAuth);		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))			return FALSE;		BOOL auth_ok = TRUE;		{			// Now create a 16-byte challenge			char challenge[16];			vncRandomBytes((BYTE *)&challenge);			// Send the challenge to the client			if (!m_socket->SendExact(challenge, sizeof(challenge)))				return FALSE;			// Read the response			char response[16];			if (!m_socket->ReadExact(response, sizeof(response)))\				return FALSE;			// Encrypt the challenge bytes			vncEncryptBytes((BYTE *)&challenge, plain);			// Compare them to the response			for (int i=0; i<sizeof(challenge); i++)			{				if (challenge[i] != response[i])				{					auth_ok = FALSE;					break;				}			}		}		// Did the authentication work?		CARD32 authmsg;		if (!auth_ok)		{			vnclog.Print(LL_CONNERR, VNCLOG("authentication failed\n"));			authmsg = Swap32IfLE(rfbVncAuthFailed);			m_socket->SendExact((char *)&authmsg, sizeof(authmsg));			return FALSE;		}		else		{			// Tell the client we're ok			authmsg = Swap32IfLE(rfbVncAuthOK);			if (!m_socket->SendExact((char *)&authmsg, sizeof(authmsg)))				return FALSE;		}	}	// Read the client's initialisation message	rfbClientInitMsg client_ini;	if (!m_socket->ReadExact((char *)&client_ini, sz_rfbClientInitMsg))		return FALSE;	// If the client wishes to have exclusive access then remove other clients	if (!client_ini.shared && !m_shared)	{		// Which client takes priority, existing or incoming?		if (m_server->ConnectPriority() < 1)		{			// Incoming			vnclog.Print(LL_INTINFO, VNCLOG("non-shared connection - disconnecting old clients\n"));			m_server->KillAuthClients();		} else if (m_server->ConnectPriority() > 1)		{			// Existing			if (m_server->AuthClientCount() > 0)			{				vnclog.Print(LL_CLIENTS, VNCLOG("connections already exist - client rejected\n"));				return FALSE;			}		}	}	// Tell the server that this client is ok	return m_server->Authenticated(m_client->GetClientId());}voidClearKeyState(BYTE key){	// This routine is used by the VNC client handler to clear the	// CAPSLOCK, NUMLOCK and SCROLL-LOCK states.	BYTE keyState[256];		GetKeyboardState((LPBYTE)&keyState);	if(keyState[key] & 1)	{		// Simulate the key being pressed		keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY, 0);		// Simulate it being release		keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);	}}voidvncClientThread::run(void *arg){	// All this thread does is go into a socket-recieve loop,	// waiting for stuff on the given socket	// IMPORTANT : ALWAYS call RemoveClient on the server before quitting	// this thread.	vnclog.Print(LL_CLIENTS, VNCLOG("client connected : %s (%hd)\n"),								m_client->GetClientName(),								m_client->GetClientId());	// Save the handle to the thread's original desktop	HDESK home_desktop = GetThreadDesktop(GetCurrentThreadId());		// To avoid people connecting and then halting the connection, set a timeout	if (!m_socket->SetTimeout(30000))		vnclog.Print(LL_INTERR, VNCLOG("failed to set socket timeout(%d)\n"), GetLastError());	// Initially blacklist the client so that excess connections from it get dropped	m_server->AddAuthHostsBlacklist(m_client->GetClientName());	// LOCK INITIAL SETUP	// All clients have the m_protocol_ready flag set to FALSE initially, to prevent	// updates and suchlike interfering with the initial protocol negotiations.	// GET PROTOCOL VERSION	if (!InitVersion())	{		m_server->RemoveClient(m_client->GetClientId());		return;	}	vnclog.Print(LL_INTINFO, VNCLOG("negotiated version\n"));	// AUTHENTICATE LINK	if (!InitAuthenticate())	{		m_server->RemoveClient(m_client->GetClientId());		return;	}	// Authenticated OK - remove from blacklist and remove timeout	m_server->RemAuthHostsBlacklist(m_client->GetClientName());	m_socket->SetTimeout(m_server->AutoIdleDisconnectTimeout()*1000);	vnclog.Print(LL_INTINFO, VNCLOG("authenticated connection\n"));	// INIT PIXEL FORMAT	// Get the screen format	m_client->m_fullscreen = m_client->m_encodemgr.GetSize();	// Get the name of this desktop	char desktopname[MAX_COMPUTERNAME_LENGTH+1];	DWORD desktopnamelen = MAX_COMPUTERNAME_LENGTH + 1;	if (GetComputerName(desktopname, &desktopnamelen))	{		// Make the name lowercase		for (int x=0; x<strlen(desktopname); x++)		{			desktopname[x] = tolower(desktopname[x]);		}	}	else	{		strcpy(desktopname, "WinVNC");	}	// Send the server format message to the client	rfbServerInitMsg server_ini;	server_ini.format = m_client->m_encodemgr.m_buffer->GetLocalFormat();	// Endian swaps	server_ini.framebufferWidth = Swap16IfLE(m_client->m_fullscreen.br.x);	server_ini.framebufferHeight = Swap16IfLE(m_client->m_fullscreen.br.y);	server_ini.format.redMax = Swap16IfLE(server_ini.format.redMax);	server_ini.format.greenMax = Swap16IfLE(server_ini.format.greenMax);	server_ini.format.blueMax = Swap16IfLE(server_ini.format.blueMax);	server_ini.nameLength = Swap32IfLE(strlen(desktopname));	if (!m_socket->SendExact((char *)&server_ini, sizeof(server_ini)))	{		m_server->RemoveClient(m_client->GetClientId());		return;	}	if (!m_socket->SendExact(desktopname, strlen(desktopname)))	{		m_server->RemoveClient(m_client->GetClientId());		return;	}	vnclog.Print(LL_INTINFO, VNCLOG("sent pixel format to client\n"));	// UNLOCK INITIAL SETUP	// Initial negotiation is complete, so set the protocol ready flag	m_client->EnableProtocol();		// Add a fullscreen update to the client's update list  { omni_mutex_lock l(m_client->GetUpdateLock());	  m_client->m_update_tracker.add_changed(m_client->m_fullscreen);  }	// Clear the CapsLock and NumLock keys	if (m_client->m_keyboardenabled)	{		ClearKeyState(VK_CAPITAL);		// *** JNW - removed because people complain it's wrong		//ClearKeyState(VK_NUMLOCK);		ClearKeyState(VK_SCROLL);	}	// MAIN LOOP	// Set the input thread to a high priority	set_priority(omni_thread::PRIORITY_HIGH);	BOOL connected = TRUE;	while (connected)	{		rfbClientToServerMsg msg;		// Ensure that we're running in the correct desktop		if (!vncService::InputDesktopSelected())			if (!vncService::SelectDesktop(NULL))				break;		// Try to read a message ID		if (!m_socket->ReadExact((char *)&msg.type, sizeof(msg.type)))		{			connected = FALSE;			break;		}		// What to do is determined by the message id		switch(msg.type)		{		case rfbSetPixelFormat:			// Read the rest of the message:			if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetPixelFormatMsg-1))			{				connected = FALSE;				break;			}			// Swap the relevant bits.			msg.spf.format.redMax = Swap16IfLE(msg.spf.format.redMax);			msg.spf.format.greenMax = Swap16IfLE(msg.spf.format.greenMax);			msg.spf.format.blueMax = Swap16IfLE(msg.spf.format.blueMax);			// Prevent updates while the pixel format is changed			m_client->DisableProtocol();							// Tell the buffer object of the change						if (!m_client->m_encodemgr.SetClientFormat(msg.spf.format))			{				vnclog.Print(LL_CONNERR, VNCLOG("remote pixel format invalid\n"));				connected = FALSE;			}			// Set the palette-changed flag, just in case...			m_client->m_palettechanged = TRUE;			// Re-enable updates			m_client->EnableProtocol();						break;		case rfbSetEncodings:			// Read the rest of the message:			if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetEncodingsMsg-1))			{				connected = FALSE;				break;			}			// Prevent updates while the encoder is changed			m_client->DisableProtocol();			// Read in the preferred encodings			msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);			{				int x;				BOOL encoding_set = FALSE;				// By default, don't use copyrect!				m_client->m_update_tracker.enable_copyrect(false);				for (x=0; x<msg.se.nEncodings; x++)				{					CARD32 encoding;					// Read an encoding in					if (!m_socket->ReadExact((char *)&encoding, sizeof(encoding)))					{						connected = FALSE;						break;					}					// Is this the CopyRect encoding (a special case)?					if (Swap32IfLE(encoding) == rfbEncodingCopyRect)					{						m_client->m_update_tracker.enable_copyrect(true);						continue;					}					// Have we already found a suitable encoding?					if (!encoding_set)					{						// No, so try the buffer to see if this encoding will work...						if (m_client->m_encodemgr.SetEncoding(Swap32IfLE(encoding)))							encoding_set = TRUE;					}				}				// If no encoding worked then default to RAW!				if (!encoding_set)				{					vnclog.Print(LL_INTINFO, VNCLOG("defaulting to raw encoder\n"));					if (!m_client->m_encodemgr.SetEncoding(Swap32IfLE(rfbEncodingRaw)))					{						vnclog.Print(LL_INTERR, VNCLOG("failed to select raw encoder!\n"));						connected = FALSE;					}				}			}			// Re-enable updates			m_client->EnableProtocol();			break;					case rfbFramebufferUpdateRequest:			// Read the rest of the message:			if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbFramebufferUpdateRequestMsg-1))			{				connected = FALSE;				break;			}			{				rfb::Rect update;				// Get the specified rectangle as the region to send updates for.				update.tl.x = Swap16IfLE(msg.fur.x);				update.tl.y = Swap16IfLE(msg.fur.y);				update.br.x = update.tl.x + Swap16IfLE(msg.fur.w);				update.br.y = update.tl.y + Swap16IfLE(msg.fur.h);				rfb::Region2D update_rgn = update;        if (update_rgn.is_empty()) {          vnclog.Print(LL_INTERR, VNCLOG("FATAL! client update region is empty!\n"));          connected = FALSE;          break;        }				{	omni_mutex_lock l(m_client->GetUpdateLock());					// Add the requested area to the incremental update cliprect					m_client->m_incr_rgn = m_client->m_incr_rgn.union_(update_rgn);					// Is this request for a full update?					if (!msg.fur.incremental)					{						// Yes, so add the region to the update tracker						m_client->m_update_tracker.add_changed(update_rgn);						// Tell the desktop grabber to fetch the region's latest state						m_client->m_encodemgr.m_buffer->m_desktop->QueueRect(update);					}          // Kick the update thread (and create it if not there already)					m_client->TriggerUpdateThread();				}			}			break;		case rfbKeyEvent:			// Read the rest of the message:			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbKeyEventMsg-1))			{								if (m_client->m_keyboardenabled)				{					msg.ke.key = Swap32IfLE(msg.ke.key);					// Get the keymapper to do the work          vncKeymap::keyEvent(msg.ke.key, msg.ke.down);					m_client->m_remoteevent = TRUE;				}			}			break;		case rfbPointerEvent:			// Read the rest of the message:			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbPointerEventMsg-1))			{				if (m_client->m_pointerenabled)				{					// Convert the coords to Big Endian					msg.pe.x = Swap16IfLE(msg.pe.x);					msg.pe.y = Swap16IfLE(msg.pe.y);					// Work out the flags for this event					DWORD flags = MOUSEEVENTF_ABSOLUTE;          long data = 0;					if (msg.pe.x != m_client->m_ptrevent.x ||						msg.pe.y != m_client->m_ptrevent.y)						flags |= MOUSEEVENTF_MOVE;					if ( (msg.pe.buttonMask & rfbButton1Mask) != 						(m_client->m_ptrevent.buttonMask & rfbButton1Mask) )					{					    if (GetSystemMetrics(SM_SWAPBUTTON))						flags |= (msg.pe.buttonMask & rfbButton1Mask) 						    ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;					    else						flags |= (msg.pe.buttonMask & rfbButton1Mask) 						    ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;					}					if ( (msg.pe.buttonMask & rfbButton2Mask) != 						(m_client->m_ptrevent.buttonMask & rfbButton2Mask) )					{						flags |= (msg.pe.buttonMask & rfbButton2Mask) 						    ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;					}					if ( (msg.pe.buttonMask & rfbButton3Mask) != 						(m_client->m_ptrevent.buttonMask & rfbButton3Mask) )					{					    if (GetSystemMetrics(SM_SWAPBUTTON))						flags |= (msg.pe.buttonMask & rfbButton3Mask) 						    ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;					    else						flags |= (msg.pe.buttonMask & rfbButton3Mask) 						    ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;					}          // Mouse wheel support          if (msg.pe.buttonMask & rfbWheelUpMask) {            flags |= MOUSEEVENTF_WHEEL;            data = WHEEL_DELTA;          }          if (msg.pe.buttonMask & rfbWheelDownMask) {            flags |= MOUSEEVENTF_WHEEL;            data = -WHEEL_DELTA;          }					// Generate coordinate values					unsigned long x = (msg.pe.x *  65535) / (m_client->m_fullscreen.br.x);

⌨️ 快捷键说明

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