📄 clientconnection.cpp
字号:
// 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.
// This is the main source for a ClientConnection object.
// It handles almost everything to do with a connection to a server.
// The decoding of specific rectangle encodings is done in separate files.
//#define _WIN32_WINDOWS 0x0410
//#define WINVER 0x0400
#include "stdhdrs.h"
#include "vncviewer.h"
#include "ConnectionLog.h"
#include "ClientConnection.h"
#include "SessionDialog.h"
#include "AuthDialog.h"
#include "LowLevelHook.h"
#include "vncviewerauth.h"
#include "..\winvnc\winvnc\vncmenu.h"
#include "..\winvnc\winvnc\roGateway.h"
#include "..\winvnc\winvnc\vsocket.h"
#include "..\winvnc\winvnc\Global.h"
#include "VNCOptions.h"
#include "..\winvnc\winvnc\localization.h"
#include "CustomSettings.h"
#include "..\winvnc\winvnc\localization.h"
#define BUTTON_WIDTH 26
#define INITIALNETBUFSIZE 4096
#define MAX_ENCODINGS (LASTENCODING+10)
#define VWR_WND_CLASS_NAME _T("VNCviewer")
#define VWR_WND_CLASS_NAME_VIEWER _T("VNCviewerwindow")
#define SESSION_MRU_KEY_NAME _T("Software\\TeamViewer\\MRU")
const UINT FileTransferSendPacketMessage = RegisterWindowMessage("UltraVNC.Viewer.FileTransferSendPacketMessage");
const UINT ShowSecureWindowMsg = WM_APP+1;
extern bool g_passwordfailed;
/*
* Macro to compare pixel formats.
*/
const rfbPixelFormat vnc8bitFormat = {8,8,0,1,7,7,3,0,3,6, 0, 0}; // 256 colors
const rfbPixelFormat vnc8bitFormat_64 = {8,6,0,1,3,3,3,4,2,0, 0, 0} ; // 64 colors
const rfbPixelFormat vnc8bitFormat_8 = {8,3,0,1,1,1,1,2,1,0, 0, 0} ; // 8 colors
const rfbPixelFormat vnc8bitFormat_8Grey = {8,8,0,1,7,7,3,0,3,6, 1, 0} ; // 8 colors-Dark Scale
const rfbPixelFormat vnc8bitFormat_4Grey = {8,6,0,1,3,3,3,4,2,0, 1, 0} ; // 4 colors-Grey Scale
const rfbPixelFormat vnc8bitFormat_2Grey = {8,3,0,1,1,1,1,2,1,0, 1, 0} ; // 2 colors-Grey Scale
const rfbPixelFormat vnc16bitFormat = {16,16,0,1,63,31,31,0,6,11, 0, 0};
extern HWND currentHWND;
extern bool command_line;
extern bool isQuickSupport;
// Lizard - stall avoidance
//void MousePointerMotionDelayThread::Init(void *c)
//{
// m_ClientConnection = c;
// m_pointerX = m_lastpointerX = 0;
// m_pointerY = m_lastpointerY = 0;
// m_buttonMask = m_lastbuttonMask = 0;
// m_running = FALSE;
// m_enablesend = TRUE;
// start_undetached();
//}
//MousePointerMotionDelayThread::~MousePointerMotionDelayThread(void)
//{
// if (m_running)
// {
// m_running = FALSE;
// void *returnval;
// join(&returnval);
// }
//}
//
//void *MousePointerMotionDelayThread::run_undetached(void *arg)
//{
// m_running = TRUE;
//
// DWORD lastsent = 0;
// while(m_running)
// {
// bool sendnow = false;
//
// // mouse moves are sent after 333ms, clicks immediately
// // Send only moves >1 pixel, mouse flickers on some displays
// if (GetTickCount()>lastsent+333 && (abs(m_pointerX-m_lastpointerX)>1 || abs(m_pointerY-m_lastpointerY)>1))
// sendnow = true;
//
// if (m_buttonMask!=m_lastbuttonMask)
// sendnow = true;
//
// if (sendnow && m_enablesend)
// {
// lastsent = GetTickCount();
//
// m_lastpointerX = m_pointerX;
// m_lastpointerY = m_pointerY;
// m_lastbuttonMask = m_buttonMask;
//
// // Position has changed - send data
// send();
// }
// else
// Sleep(5); // We might lose double clicks if time span too long
// }
//
// m_running = FALSE;
//
// return NULL;
//}
//
//void MousePointerMotionDelayThread::MouseEvent(int x, int y, int buttonMask)
//{
// m_pointerX = x;
// m_pointerY = y;
// m_buttonMask = buttonMask;
//}
//
//void MousePointerMotionDelayThread::send()
//{
// ((ClientConnection *)m_ClientConnection)->ExternalSendPointerEvent(m_lastpointerX, m_lastpointerY, m_lastbuttonMask);
//}
// End Lizard
// *************************************************************************
// A Client connection involves two threads - the main one which sets up
// connections and processes window messages and inputs, and a
// client-specific one which receives, decodes and draws output data
// from the remote server.
// This first section contains bits which are generally called by the main
// program thread.
// *************************************************************************
ClientConnection::ClientConnection(VNCviewerApp *pApp, ConnectionType ct)
: fis(0), zis(0)
{
Init(pApp);
m_ConnectionType = ct;
}
ClientConnection::ClientConnection(VNCviewerApp *pApp, SOCKET sock, int connectionmode)
: fis(0), zis(0)
{
Init(pApp);
m_opts.m_ActiveMode = connectionmode;
switch (m_opts.m_ActiveMode)
{
case rfbMC_TeamworkClient:
case rfbMC_RemotecontrolClient:
m_opts.m_ShowToolbar = true;
break;
case rfbMC_PresentationClient:
m_opts.m_ShowToolbar = false;
break;
}
m_sock = sock;
m_serverInitiated = true;
struct sockaddr_in svraddr;
int sasize = sizeof(svraddr);
if (getpeername(sock, (struct sockaddr *) &svraddr,
&sasize) != SOCKET_ERROR) {
_stprintf(m_host, _T("%d.%d.%d.%d"),
svraddr.sin_addr.S_un.S_un_b.s_b1,
svraddr.sin_addr.S_un.S_un_b.s_b2,
svraddr.sin_addr.S_un.S_un_b.s_b3,
svraddr.sin_addr.S_un.S_un_b.s_b4);
m_port = svraddr.sin_port;
} else {
_tcscpy(m_host,sz_L1);
m_port = 0;
};
}
ClientConnection::ClientConnection(VNCviewerApp *pApp, LPTSTR host, int port)
: fis(0), zis(0)
{
Init(pApp);
m_opts.SetActiveMode(menu->m_properties.GetConnectionMode());
_tcsncpy(m_host, host, MAX_HOST_NAME_LEN);
GetSystemTime(&connectionLogStartTime);
connectionLogUser = m_host;
if(port != RFB_PORT_OFFSET) // non-Standard-Port auch in Connectionlog schreiben
{
ostringstream os;
os << connectionLogUser << ":" << port;
connectionLogUser = os.str();
}
m_port = port;
}
void ClientConnection::Init(VNCviewerApp *pApp)
{
logConnection=false;
keepSocket = FALSE;
modeChangeRequested = FALSE;
m_ConnectionType = CC_OUTGOING_INTERNET;
Pressed_Cancel=false;
saved_set=false;
m_hwnd = 0;
m_desktopName = NULL;
m_port = -1;
m_serverInitiated = false;
m_netbuf = NULL;
m_netbufsize = 0;
m_zlibbuf = NULL;
m_zlibbufsize = 0;
m_decompStreamInited = false;
m_hwndNextViewer = NULL;
m_pApp = pApp;
m_dormant = false;
m_hBitmapDC = NULL;
m_hBitmap = NULL;
m_hCacheBitmapDC = NULL;
m_hCacheBitmap = NULL;
m_hPalette = NULL;
m_encPasswd[0] = '\0';
m_clearPasswd[0] = '\0'; // Modif sf@2002
// static window
m_BytesSend=0;
m_lConnectionTime = 0;
// We take the initial conn options from the application defaults
m_opts = m_pApp->m_options;
//Lizard mousedelay
//mpmd_thread = NULL;
m_sock = INVALID_SOCKET;
m_bKillThread = false;
m_threadStarted = true;
m_running = false;
m_pendingFormatChange = false;
// sf@2002 - v1.1.2 - Data Stream Modification Plugin handling
m_nTO = 1;
m_pNetRectBuf = NULL;
m_fReadFromNetRectBuf = false; //
m_nNetRectBufOffset = 0;
m_nReadSize = 0;
m_nNetRectBufSize = 0;
m_pZRLENetRectBuf = NULL;
m_fReadFromZRLENetRectBuf = false; //
m_nZRLENetRectBufOffset = 0;
m_nZRLEReadSize = 0;
m_nZRLENetRectBufSize = 0;
// ZlibHex
m_decompStreamInited = false;
m_decompStreamRaw.total_in = ZLIBHEX_DECOMP_UNINITED;
m_decompStreamEncoded.total_in = ZLIBHEX_DECOMP_UNINITED;
// Initialise a few fields that will be properly set when the
// connection has been negotiated
m_fullwinwidth = m_fullwinheight = 0;
m_si.framebufferWidth = m_si.framebufferHeight = 0;
m_hScrollPos = 0; m_vScrollPos = 0;
oldPointerX = oldPointerY = oldButtonMask = 0;
// Create a buffer for various network operations
CheckBufferSize(INITIALNETBUFSIZE);
m_pApp->RegisterConnection(this);
kbitsPerSecond = 0;
minKB = 100000000;
maxKB = 0;
sumKB = 0;
nrKB = 0;
m_lLastChangeTime = 0; // 0 because we want the first encoding switching to occur quickly
// (in Auto mode, ZRLE is used: pointless over a LAN)
m_fScalingDone = false;
zis = new rdr::ZlibInStream;
// tight cusorhandling
prevCursorSet = false;
rcCursorX = 0;
rcCursorY = 0;
// Modif sf@2002 - FileTransfer
m_pFileTransfer = new FileTransfer(m_pApp, this);
m_filezipbuf = NULL;
m_filezipbufsize = 0;
m_filechunkbuf = NULL;
m_filechunkbufsize = 0;
// Modif sf@2002 - Text Chat
m_pTextChat = new TextChatViewer(m_pApp, this);
// Modif sf@2002 - Scaling
m_pendingScaleChange = false;
m_pendingCacheInit = false;
//ms logon
m_ms_logon=false;
// sf@2002 - FileTransfer on server
m_fServerKnowsFileTransfer = false;
// TR@2003 - ModeChange
m_ServerKnowsModeChange = false;
m_server = pApp->m_server;
//TR@2003: roGateway
m_roGateway = FALSE;
if (pApp->m_server->UseDynGate())
roGateway = CroGateway::Instance();
else
roGateway = NULL;
// Auto Mode
m_nConfig = 0;
// sf@2002 - Options window flag
m_fOptionsOpen = false;
// Tight encoding
for (int i = 0; i < 4; i++)
m_tightZlibStreamActive[i] = false;
m_hwnd=NULL;
m_hbands=NULL;
m_hwndTB=NULL;
m_hwndTBwin=NULL;
m_hwndMain=NULL;
m_SWselect=false;
EncodingStatusWindow = -1;
OldEncodingStatusWindow = -2;
m_nStatusTimer = 0;
// m_FTtimer = 0;
skipprompt2=true;
m_hmemdc=NULL;
m_DIBbits=NULL;
m_membitmap=NULL;
m_BigToolbar=false;
KillEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
newtick=0;
oldtick=0;
m_zipbuf=NULL;
m_filezipbuf=NULL;
m_filechunkbuf=NULL;
m_zlibbuf=NULL;
rcSource=NULL;
rcMask=NULL;
m_tvinfo = new TeamviewerInfo(TI_CLIENTCONNECTION, this);
m_sizing = false;
m_ClosedByRemote = false;
m_abort_connection = false;
m_borderWidth = m_borderHeight = 0;
m_fHasSingleWindow = false;
m_hTBImageList = NULL;
m_hTBHottrack = NULL;
m_bmpToolbarBackground = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_BITMAP_TOOLBAR_BKGND),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_bmpToolbarHandle = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_HANDLE_OPEN),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_bmpToolbarHandleClosed = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_HANDLE_CLOSED),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_send_incremental = true;
m_moveToolbar = 0;
if(m_msimg = LoadLibrary("Msimg32.dll"))
m_AlphaBlend = (AlphaBlendFn)GetProcAddress(m_msimg, "AlphaBlend");
else
m_AlphaBlend = NULL;
m_fServerIsUltra = FALSE;
m_lastServermode = 0;
m_WaitForFullUpdate = false;
m_SecureDesktopDialog = NULL;
}
//
// Run() creates the connection if necessary, does the initial negotiations
// and then starts the thread running which does the output (update) processing.
// If Run throws an Exception, the caller must delete the ClientConnection object.
//
// returns 0: connection failure
// -1: succeeded and changed to viewer mode, no clientconnection
// 1: succeeded
int ClientConnection::Run(bool internet)
{
bool connected = false;
SessionDialog::SetStatus(sz_IDS_MSG_CONNECTING);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -