📄 rogateway.cpp
字号:
// Copyright (C) 2006 Teamviewer GmbH. All Rights Reserved.
//
// This file is part of the TeamViewer system.
//
// 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
#include "stdhdrs.h"
#include "roGateway.h"
#include "KilLProcess.h"
#include "vncService.h"
#include "vncmenu.h"
#include "TeamViewerInfo.h"
extern bool isQuickSupport;
CroGateway* CroGateway::mInstance = NULL;
CroGateway::CroGateway()
{
m_Variables[CLIENTID] = "";
m_Variables[NUMERICID] = "0";
m_Variables[GATEWAYNAME] = "";
m_Variables[VERSION] = "";
m_Variables[LICENSETYPE] = "";
m_Variables[LICENSENAME] = "";
m_gwlistenport = 5910;
memset(m_installpath,0,sizeof(m_installpath));
m_installinquired = false;
m_installed = false;
m_sock = INVALID_SOCKET;
m_waitingatmaster = false;
m_connected = 0;
m_connecting = false;
m_destroying = false;
m_polling = false;
m_noRestart = false;
if(isNoSave) // Portable and QuickSupport
{
string sAppDir;
GetApplicationDirectory(sAppDir);
strncpy(m_installpath,sAppDir.c_str(),min(sAppDir.length(),sizeof(m_installpath)));
strncat(m_installpath, "DynGate.exe", __min(255, 255-strlen(m_installpath)));
m_installed = IsValidExe(m_installpath);
if(!m_installed && !isQuickSupport) // QuickSupport does not require file, will auto-download it
{
char buf[300];
_snprintf(buf, 300, "DynGate not found in current directory (%s).", m_installpath);
MessageBox(NULL, buf, "Critical error", MB_ICONERROR);
menu->m_server->SetShutdown(TRUE);
}
}
else
ReadDyngateRegistry();
}
CroGateway::~CroGateway()
{
EndWaitAtMaster(LOGOUT_GATEWAY_CLOSED);
Terminate();
}
void CroGateway::Terminate()
{
// Not really threadsafe, but safe enough...
if (m_destroying)
return;
m_destroying = true;
if (m_connecting || m_waitingatmaster)
{
// Give me some time to shut down safely
Sleep(1000);
}
}
bool CroGateway::Licensed()
{
int lic = atoi(m_Variables[LICENSETYPE].data());
return lic != 0 && lic != 10000;
}
bool CroGateway::ReadDyngateRegistry()
{
HKEY hkey;
DWORD dwData = 0;
if(isNoSave || m_destroying) // Portable and QuickSupport don't use registry
return true;
// ATTENTION: Checking of access rights has to be identical in DynGate!
long result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,ROGATEWAY_REGISTRYKEY,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE|KEY_SET_VALUE,&hkey);
if (result!=ERROR_SUCCESS)
result = RegOpenKeyEx(HKEY_CURRENT_USER,ROGATEWAY_REGISTRYKEY,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE|KEY_SET_VALUE,&hkey);
if (result==ERROR_SUCCESS)
{
DWORD dwSize = sizeof(dwData);
//get Path to DynGate.exe to do the automatic startup
dwSize = 256;
RegQueryValueEx(hkey,"AppPath",NULL,NULL,(BYTE*)m_installpath,&dwSize) ;
//Check version
dwSize = 256;
char version[256];
memset(version, 0, 256);
RegQueryValueEx(hkey,"Version",NULL,NULL,(BYTE*)version,&dwSize) ;
if (strcmp(version, MINIMUM_DYNGATE_REQUIRED)<0)
{
vnclog.Print(LL_INTWARN,VNCLOG("DynGate wrong version %s, required %s"), version, MINIMUM_DYNGATE_REQUIRED);
m_installed = false;
}
else
{
if (!isQuickSupport && strstr(version,"QS")>0)
{
// We must upgrade to full DynGate
m_installed = false;
}
else
m_installed = true;
}
#ifndef _DEBUG // In debug mode the files is sometimes blocked by VS
// Check if given exe is still available (temp-folder may be removed)
if (!IsValidExe(m_installpath))
m_installed = false;
#else
if (!FileExists(m_installpath))
m_installed = false;
#endif
}
else
m_installed = GatewayRunning();
RegCloseKey(hkey);
return true;
}
bool CroGateway::DownloadDynGateFallback(HWND hwnd)
{
if (m_destroying)
return false;
// Also use a different server (www, not download.teamviewer.com
char dynGateUrl[256]="http://www.teamviewer.com/download/";
if(isQuickSupport || isNoInstallation)
{
strcat(dynGateUrl,sz_IDS_DYNGATE_SIMPLE_SETUPNAME);
}
else
{
strcat(dynGateUrl,sz_IDS_DYNGATE_SETUPNAME);
}
ShellExecute(0,"open",dynGateUrl,0,0,SW_SHOW);
return true;
}
bool CroGateway::DownloadDynGate(HWND hwnd)
{
if (m_destroying)
return false;
// Save the file to a temporary folder that should always be available
string sAppPath;
if(!vncService::RunningAsService())
{
GetSpecialFolderPath(CSIDL_DESKTOP,sAppPath);
sAppPath += "\\..\\temp\\";
}
else
{
GetApplicationDirectory(sAppPath);
}
CreateDirectory(sAppPath.c_str(),NULL);
char dynGateServer[256]="download.teamviewer.com";
char dynGateUrl[256]="/download/getfile.aspx?file="; // stream file instead of download: no file extension
#ifdef _DEBUG
// Temporary filenames for download tests
strcpy(sz_IDS_DYNGATE_SIMPLE_SETUPNAME, "DynGateQS_Debug.exe");
strcpy(sz_IDS_DYNGATE_SETUPNAME, "DynGate_Setup_Debug.exe");
#endif
if(isQuickSupport || isNoInstallation)
{
//strcat(apppath,sz_IDS_DYNGATE_SIMPLE_SETUPNAME);
sAppPath += sz_IDS_DYNGATE_SIMPLE_SETUPNAME;
strncat(dynGateUrl,sz_IDS_DYNGATE_SIMPLE_SETUPNAME, strlen(sz_IDS_DYNGATE_SIMPLE_SETUPNAME)-4);
}
else
{
//strcat(apppath,sz_IDS_DYNGATE_SETUPNAME);
sAppPath += sz_IDS_DYNGATE_SETUPNAME;
strncat(dynGateUrl,sz_IDS_DYNGATE_SETUPNAME, strlen(sz_IDS_DYNGATE_SETUPNAME)-4);
}
if (strstr(TEAMVIEWER_VERSION,"RC")!=NULL)
{
// New Release Candidate - add RC to Setup path
//strcpy(&apppath[strlen(apppath)-4],"_RC.exe");
sAppPath.erase(sAppPath.length()-4,4);
sAppPath += "_RC.exe";
strcat(dynGateUrl,"_RC");
}
// Logging
vnclog.Print(LL_INTINFO,VNCLOG("DynGate Download to %s"),sAppPath.c_str());
/* This is the only TeamViewer part that uses WinInet
So: Init an Deinit here */
HINTERNET inetsession = InternetOpen("Mozilla/4.0 (compatible; MSIE 6.0; TeamViewer)" ,INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL );
if (!inetsession)
return false;
HINTERNET inetconn= InternetConnect(inetsession,dynGateServer, INTERNET_INVALID_PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
if (!inetconn)
{
InternetCloseHandle(inetsession);
vnclog.Print(LL_INTERR,VNCLOG("DynGate NoInternetConnect"));
return false;
}
LPCSTR accepttypes[2];
accepttypes[0]=(LPCSTR)"*/*";
accepttypes[1]=0;
HINTERNET ineturl= HttpOpenRequest(inetconn, "GET", dynGateUrl, NULL, NULL, (LPCSTR *)accepttypes, INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_RELOAD, 0 );
resend:
if (! HttpSendRequest(ineturl, NULL,0,NULL,0))
{
InternetCloseHandle(inetconn);
InternetCloseHandle(inetsession);
vnclog.Print(LL_INTERR,VNCLOG("DynGate ErrorSendRequest"));
return false;
}
DWORD dwErrorCode = ineturl ? ERROR_SUCCESS : GetLastError();
DWORD dwError = ERROR_SUCCESS;;
dwError = InternetErrorDlg(hwnd, ineturl, dwErrorCode,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
NULL);
if (dwError==ERROR_INTERNET_FORCE_RETRY)
{
vnclog.Print(LL_INTWARN,VNCLOG("DynGate Resend"));
goto resend;
}
FILE *outfile = fopen(sAppPath.c_str(), "wb");
if (!outfile || m_destroying)
{
InternetCloseHandle(ineturl);
InternetCloseHandle(inetsession);
vnclog.Print(LL_INTERR,VNCLOG("DynGate Error fopen"));
return false;
}
// Download the file
char buffer[32000];
DWORD dwSize;
bool success = true;
do
{
if (! InternetReadFile(ineturl, buffer, sizeof(buffer) - 1, &dwSize))
success = false;
if (! dwSize)
{
break;
}
else
{
size_t write_count = fwrite(buffer, 1, dwSize, outfile);
if (write_count < (int)dwSize)
{
success = false;
break;
}
}
}
while (true && !m_destroying);
fclose (outfile);
InternetCloseHandle(ineturl);
InternetCloseHandle(inetsession);
return success;
}
bool CroGateway::IsValidExe(const char *path)
{
if (m_destroying)
return false;
// Check if file has a minium size of 50kb - otherwise download didn't work
// (Some proxies return a file even if download didn't work)
FILE *file = fopen(path, "r");
bool success = false;
if (file)
{
fseek(file,0,SEEK_END);
fpos_t pos;
fgetpos(file,&pos);
if (pos > 50000)
success = true;
fclose(file);
}
if (!success)
vnclog.Print(LL_INTWARN,VNCLOG("DynGate Invalid Exe %s"),path);
return success;
}
bool CroGateway::InstallDynGate(HWND hwnd)
{
if (m_destroying)
return false;
// Get the name of the temp file
//char apppath[1024];
string sAppPath;
Sleep(10000);
if(!vncService::RunningAsService())
{
GetSpecialFolderPath(CSIDL_DESKTOP,sAppPath);
//strcat(apppath, "\\..\\temp\\");
sAppPath += "\\..\\temp\\";
}
else
{
GetApplicationDirectory(sAppPath);
}
//strcat(apppath, (isQuickSupport||isNoInstallation)?sz_IDS_DYNGATE_SIMPLE_SETUPNAME:sz_IDS_DYNGATE_SETUPNAME);
if (isQuickSupport||isNoInstallation)
sAppPath += sz_IDS_DYNGATE_SIMPLE_SETUPNAME;
else
sAppPath += sz_IDS_DYNGATE_SETUPNAME;
if (strstr(TEAMVIEWER_VERSION,"RC")!=NULL)
{
// New Release Candidate - add RC to Setup path
//strcpy(&apppath[strlen(apppath)-4],"_RC.exe");
sAppPath.erase(sAppPath.length()-4,4);
sAppPath += "_RC.exe";
}
if (IsValidExe(sAppPath.c_str()))
{
vnclog.Print(LL_INTINFO,VNCLOG("DynGate Install to %s"),sAppPath.c_str());
if ((int)ShellExecute(hwnd,"open",sAppPath.c_str(),0,0,SW_SHOW) >32)
{
return true;
}
else
{
vnclog.Print(LL_INTERR,VNCLOG("DynGate InstallFailed"));
return false;
}
}
else // File not found or too small
{
vnclog.Print(LL_INTERR,VNCLOG("DynGate ExeInvalid"));
return false;
}
}
bool CroGateway::isClientID(char *clientid)
{
if (strchr(clientid,'@')!=0)
return true; // additional conditions not checked
// no dots allowed
if (strchr(clientid,'.')!=0)
return false;
// If @ is not present number must be a valid numeric id
if (clientid[0]=='#')
clientid++;
char *endp;
long id=strtol(clientid,&endp,10);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -