📄 connection.cpp
字号:
/* Copyright (C) 2006 Lucas Gomez All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// INCLUDE FILES
#include "Connection.h"
#include "VncViewer.pan"
#include "LogWriter.h"
//LITERALS
_LIT8(KConnErrorNotInitialised,"Not initialised yet?");
_LIT8(KConnErrorInvalidState,"Invalid State");
_LIT8(KConnErrorVersionFailed,"Reading Version Failed: not an RFB server?");
_LIT8(KConnErrorVersionUnsopported,"Server gave unsupported RFB protocol version");
_LIT8(KConnErrorUnknownSecurityType,"Unknown 3.3 security type");
_LIT8(KConnErrorNoMatchingSecurityTypes,"No matching security types");
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CConnection::CConnection()
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CConnection::CConnection()
{
iRfbState=ERfbStateUninitialised;
iSecurity=NULL;
iMsgReader=NULL;
iMsgWriter=NULL;
}
// -----------------------------------------------------------------------------
// CConn::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CConnection::ConstructL()
{
CMsgHandler::ConstructL();
}
// ---------------------------------------------------------------------------
// CConnection::~CConnection()
// Destructor.
// ---------------------------------------------------------------------------
//
CConnection::~CConnection()
{
if(iSecurity)
{
delete iSecurity;
iSecurity=NULL;
}
if(iMsgReader)
{
delete iMsgReader;
iMsgReader=NULL;
}
if(iMsgWriter)
{
delete iMsgWriter;
iMsgWriter=NULL;
}
}
void CConnection::AddSecTypeL(TSecType aSecType)
{
if (iNSecTypes == KMaxSecTypes)
User::Leave(EVncViewerTooManySecTypes);
iSecTypes[iNSecTypes++] = aSecType;
}
void CConnection::InitialiseProtocol()
{
iRfbState=ERfbStateProtocolVersion;
}
void CConnection::ProcessMsg()
{
switch(iRfbState)
{
case ERfbStateProtocolVersion: ProcessVersionMsg(); break;
case ERfbStateSecurityTypes: ProcessSecurityTypesMsg(); break;
case ERfbStateSecurity: ProcessSecurityMsg(); break;
case ERfbStateSecurity_Result: ProcessSecurityResultMsg(); break;
case ERfbStateInitialisation: ProcessInitMsg(); break;
case ERfbStateNormal: iMsgReader->ReadMsg(); break;
case ERfbStateUninitialised:
ConnError(KConnErrorNotInitialised);
case ERfbStateInvalid:
default:
ConnError(KConnErrorInvalidState);
}
}
void CConnection::AuthSuccess()
{
// void method?
}
void CConnection::ProcessVersionMsg()
{
CLogWriter::InstanceL()->LogTrace(_L("reading protocol version"));
if(!iCP->ReadVersion(iIS))
{
iRfbState=ERfbStateInvalid;
ConnError(KConnErrorVersionFailed);
}
TBuf<100> temp;
temp.Copy(_L("Server supports RFB protocol version "));
temp.AppendNum(iCP->GetMajorVersion());
temp.Append('.');
temp.AppendNum(iCP->GetMinorVersion());
CLogWriter::InstanceL()->LogTrace(temp);
if(iCP->BeforeVersion(3,3))
{
iRfbState=ERfbStateInvalid;
TBuf<100> temp;
temp.Copy(_L("Server gave unsupported RFB protocol version "));
temp.AppendNum(iCP->GetMajorVersion());
temp.Append('.');
temp.AppendNum(iCP->GetMinorVersion());
CLogWriter::InstanceL()->LogTrace(temp);
ConnError(KConnErrorVersionUnsopported);
}
else if(iUseProtocol3_3 || iCP->BeforeVersion(3,7))
{
iCP->SetVersion(3,3);
}
else if(iCP->AfterVersion(3,8))
{
iCP->SetVersion(3,8);
}
iCP->WriteVersion(iOS);
iRfbState=ERfbStateSecurityTypes;
temp.Copy(_L("Using RFB protocol version "));
temp.AppendNum(iCP->GetMajorVersion());
temp.Append('.');
temp.AppendNum(iCP->GetMinorVersion());
CLogWriter::InstanceL()->LogTrace(temp);
}
void CConnection::ProcessSecurityTypesMsg()
{
CLogWriter::InstanceL()->LogTrace(_L("processing security types message"));
TSecType secType=ESecTypeInvalid;
if(iCP->GetMajorVersion()==3 && iCP->GetMinorVersion()==3)
{
// legacy 3.3 server may only offer "vnc authentication" or "none"
secType=static_cast<TSecType>(iIS->ReadU32());
if(secType==ESecTypeInvalid)
{
ThrowConnFailedException();
}
else if(secType==ESecTypeNone || secType==ESecTypeVncAuth)
{
TInt j;
for(j=0;j<iNSecTypes;j++)
if(iSecTypes[j]==secType) break;
if(j==iNSecTypes)
secType=ESecTypeInvalid;
}
else
{
CLogWriter::InstanceL()->LogTrace(_L("Unknown 3.3 security type"));
ConnError(KConnErrorUnknownSecurityType);
}
}
else
{
// 3.7 server will offer us a list
TInt nServerSecTypes=iIS->ReadU8();
if(nServerSecTypes==0)
ThrowConnFailedException();
TInt secTypePos=iNSecTypes;
for(TInt i=0;i<nServerSecTypes;i++)
{
TInt serverSecType=iIS->ReadU8();
TBuf<100> temp;
temp.Copy(_L("Server offers security type "));
temp.AppendNum(serverSecType);
CLogWriter::InstanceL()->LogTrace(temp);
// If we haven't already chosen a secType, try this one
if(secType==ESecTypeInvalid || iClientSecTypeOrder)
{
for(TInt j=0;j<iNSecTypes;j++)
{
if(iSecTypes[j]==serverSecType && j<secTypePos)
{
secType=iSecTypes[j];
secTypePos=j;
break;
}
}
// Continue reading the remaining server secTypes, but ignore them
}
}
if(secType!=ESecTypeInvalid)
{
iOS->WriteU8(secType);
iOS->Flush();
TBuf<100> temp;
temp.Copy(_L("Choosing security type "));
temp.AppendNum(secType);
CLogWriter::InstanceL()->LogTrace(temp);
}
}
if(secType==ESecTypeInvalid)
{
iRfbState=ERfbStateInvalid;
CLogWriter::InstanceL()->LogTrace(_L("No matching security types"));
ConnError(KConnErrorNoMatchingSecurityTypes);
}
iRfbState=ERfbStateSecurity;
iSecurity=GetSecurity(secType);
ProcessSecurityMsg();
}
void CConnection::ProcessSecurityMsg()
{
CLogWriter::InstanceL()->LogTrace(_L("processing security message"));
TInt rc=iSecurity->ProcessMsg(this);
if(rc==0)
ThrowAuthFailureException();
if(rc==1)
{
iRfbState=ERfbStateSecurity_Result;
ProcessSecurityResultMsg();
}
}
void CConnection::ProcessSecurityResultMsg()
{
CLogWriter::InstanceL()->LogTrace(_L("processing security result message"));
TInt result;
if(iCP->BeforeVersion(3,8) && iSecurity->GetType()==ESecTypeNone)
{
result=KResultOK;
} else {
//if (!is->checkNoWait(1)) return;
result=iIS->ReadU32();
}
switch (result)
{
case KResultOK:
SecurityCompleted();
break;
case KResultFailed:
CLogWriter::InstanceL()->LogTrace(_L("auth failed"));
ThrowAuthFailureException();
break;
case KResultTooMany:
CLogWriter::InstanceL()->LogTrace(_L("auth failed - too many tries"));
ThrowAuthFailureException();
break;
default:
CLogWriter::InstanceL()->LogTrace(_L("unknown security result"));
ThrowAuthFailureException();
}
}
void CConnection::ProcessInitMsg()
{
CLogWriter::InstanceL()->LogTrace(_L("reading server initialisation"));
iMsgReader->ReadServerInit();
}
void CConnection::ThrowAuthFailureException()
{
TBuf8<100> reason;
if(GetState()==ERfbStateSecurity_Result && !iCP->BeforeVersion(3,8))
{
iIS->ReadString(reason);
}
else
{
reason.Copy(_L("Authentication failure"));
}
iRfbState=ERfbStateInvalid;
ConnError(reason);
}
void CConnection::ThrowConnFailedException()
{
iRfbState=ERfbStateInvalid;
TBuf8<100> reason;
iIS->ReadString(reason);
ConnError(reason);
}
void CConnection::SecurityCompleted()
{
iRfbState=ERfbStateInitialisation;
iMsgReader=new (ELeave) CMsgReaderV3(this,iIS);
iMsgWriter=new (ELeave) CMsgWriterV3(iCP,iOS);
CLogWriter::InstanceL()->LogTrace(_L("Authentication success!"));
AuthSuccess();
iMsgWriter->WriteClientInit(iShared);
}
TInt CConnection::TranslateUnicodeToKeysym(TInt aUnicode)
{
if((aUnicode>=0x20 && aUnicode<=0x7e) ||
(aUnicode>=0xa0 && aUnicode<=0xff))
return aUnicode;
TInt min=0;
TInt max=Keysyms::KKeysymTableSize-1;
TInt mid;
while(max>=min)
{
mid=(min+max)/2;
if(Keysyms::KKeysymTable[mid][1]<aUnicode)
min=mid+1;
else if(Keysyms::KKeysymTable[mid][1]>aUnicode)
max=mid-1;
else
return Keysyms::KKeysymTable[mid][0];
}
/* no matching Unicode value found */
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -