📄 clientconnection.cpp
字号:
}
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 + -