mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-21 23:53:24 +01:00
289 lines
9.8 KiB
C++
289 lines
9.8 KiB
C++
|
/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
|
||
|
*/
|
||
|
|
||
|
// -=- VNC Server 4.0 for Windows (WinVNC4)
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <winvnc/VNCServerWin32.h>
|
||
|
#include <winvnc/VNCServerService.h>
|
||
|
#include <winvnc/AddNewClientDialog.h>
|
||
|
|
||
|
#include <rfb/Logger_stdio.h>
|
||
|
#include <rfb/Logger_file.h>
|
||
|
#include <rfb/LogWriter.h>
|
||
|
#include <rfb_win32/AboutDialog.h>
|
||
|
#include <rfb_win32/MsgBox.h>
|
||
|
#include <network/TcpSocket.h>
|
||
|
|
||
|
using namespace winvnc;
|
||
|
using namespace rfb;
|
||
|
using namespace win32;
|
||
|
|
||
|
static LogWriter vlog("main");
|
||
|
|
||
|
TStr rfb::win32::AppName("KasmVNC Server");
|
||
|
|
||
|
|
||
|
extern bool runAsService;
|
||
|
static bool runServer = true;
|
||
|
static bool close_console = false;
|
||
|
|
||
|
|
||
|
//
|
||
|
// -=- processParams
|
||
|
// Read in the command-line parameters and interpret them.
|
||
|
//
|
||
|
|
||
|
static void programInfo() {
|
||
|
win32::FileVersionInfo inf;
|
||
|
_tprintf(_T("%s - %s, Version %s\n"),
|
||
|
inf.getVerString(_T("ProductName")),
|
||
|
inf.getVerString(_T("FileDescription")),
|
||
|
inf.getVerString(_T("FileVersion")));
|
||
|
printf("%s\n", buildTime);
|
||
|
_tprintf(_T("%s\n\n"), inf.getVerString(_T("LegalCopyright")));
|
||
|
}
|
||
|
|
||
|
static void programUsage() {
|
||
|
printf("Command-line options:\n");
|
||
|
printf(" -connect [<host[::port]>] - Connect an existing WinVNC server to a listening viewer.\n");
|
||
|
printf(" -disconnect - Disconnect all clients from an existing WinVNC server.\n");
|
||
|
printf(" -register <options...> - Register WinVNC server as a system service.\n");
|
||
|
printf(" -unregister - Remove WinVNC server from the list of system services.\n");
|
||
|
printf(" -start - Start the WinVNC server system service.\n");
|
||
|
printf(" -stop - Stop the WinVNC server system service.\n");
|
||
|
printf(" -status - Query the WinVNC service status.\n");
|
||
|
printf(" -help - Provide usage information.\n");
|
||
|
printf(" -noconsole - Run without a console (i.e. no stderr/stdout)\n");
|
||
|
printf(" <setting>=<value> - Set the named configuration parameter.\n");
|
||
|
printf(" (Parameter values specified on the command-line override those specified by other configuration methods.)\n");
|
||
|
printf("\nLog names:\n");
|
||
|
LogWriter::listLogWriters();
|
||
|
printf("\nLog destinations:\n");
|
||
|
Logger::listLoggers();
|
||
|
printf("\nAvailable configuration parameters:\n");
|
||
|
Configuration::listParams(79, 14);
|
||
|
}
|
||
|
|
||
|
static void MsgBoxOrLog(const char* msg, bool isError=false) {
|
||
|
if (close_console) {
|
||
|
MsgBox(0, TStr(msg), (isError ? MB_ICONERROR : MB_ICONINFORMATION) | MB_OK);
|
||
|
} else {
|
||
|
if (isError) {
|
||
|
try {
|
||
|
vlog.error("%s", msg);
|
||
|
return;
|
||
|
} catch (...) {
|
||
|
}
|
||
|
}
|
||
|
fprintf(stderr, "%s\n", msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void processParams(int argc, char** argv) {
|
||
|
for (int i=1; i<argc; i++) {
|
||
|
try {
|
||
|
|
||
|
if (strcasecmp(argv[i], "-connect") == 0) {
|
||
|
runServer = false;
|
||
|
CharArray host;
|
||
|
if (i+1 < argc) {
|
||
|
host.buf = strDup(argv[i+1]);
|
||
|
i++;
|
||
|
} else {
|
||
|
AddNewClientDialog ancd;
|
||
|
if (ancd.showDialog())
|
||
|
host.buf = strDup(ancd.getHostName());
|
||
|
}
|
||
|
if (host.buf) {
|
||
|
HWND hwnd = FindWindow(0, _T("winvnc::IPC_Interface"));
|
||
|
if (!hwnd)
|
||
|
throw rdr::Exception("Unable to locate existing VNC Server.");
|
||
|
COPYDATASTRUCT copyData;
|
||
|
copyData.dwData = 1; // *** AddNewClient
|
||
|
copyData.cbData = strlen(host.buf);
|
||
|
copyData.lpData = (void*)host.buf;
|
||
|
printf("Sending connect request to VNC Server...\n");
|
||
|
if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)©Data))
|
||
|
MsgBoxOrLog("Connection failed.", true);
|
||
|
}
|
||
|
} else if (strcasecmp(argv[i], "-disconnect") == 0) {
|
||
|
runServer = false;
|
||
|
HWND hwnd = FindWindow(0, _T("winvnc::IPC_Interface"));
|
||
|
if (!hwnd)
|
||
|
throw rdr::Exception("Unable to locate existing VNC Server.");
|
||
|
COPYDATASTRUCT copyData;
|
||
|
copyData.dwData = 2; // *** DisconnectClients
|
||
|
copyData.lpData = 0;
|
||
|
copyData.cbData = 0;
|
||
|
printf("Sending disconnect request to VNC Server...\n");
|
||
|
if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)©Data))
|
||
|
MsgBoxOrLog("Failed to disconnect clients.", true);
|
||
|
} else if (strcasecmp(argv[i], "-start") == 0) {
|
||
|
printf("Attempting to start service...\n");
|
||
|
runServer = false;
|
||
|
if (rfb::win32::startService(VNCServerService::Name))
|
||
|
MsgBoxOrLog("Started service successfully");
|
||
|
} else if (strcasecmp(argv[i], "-stop") == 0) {
|
||
|
printf("Attempting to stop service...\n");
|
||
|
runServer = false;
|
||
|
if (rfb::win32::stopService(VNCServerService::Name))
|
||
|
MsgBoxOrLog("Stopped service successfully");
|
||
|
} else if (strcasecmp(argv[i], "-status") == 0) {
|
||
|
printf("Querying service status...\n");
|
||
|
runServer = false;
|
||
|
CharArray result;
|
||
|
DWORD state = rfb::win32::getServiceState(VNCServerService::Name);
|
||
|
result.format("The %s Service is in the %s state.",
|
||
|
(const char*)CStr(VNCServerService::Name),
|
||
|
rfb::win32::serviceStateName(state));
|
||
|
MsgBoxOrLog(result.buf);
|
||
|
} else if (strcasecmp(argv[i], "-service") == 0) {
|
||
|
printf("Run in service mode\n");
|
||
|
runServer = false;
|
||
|
runAsService = true;
|
||
|
|
||
|
} else if (strcasecmp(argv[i], "-service_run") == 0) {
|
||
|
printf("Run in service mode\n");
|
||
|
runAsService = true;
|
||
|
|
||
|
} else if (strcasecmp(argv[i], "-register") == 0) {
|
||
|
printf("Attempting to register service...\n");
|
||
|
runServer = false;
|
||
|
int j = i;
|
||
|
i = argc;
|
||
|
|
||
|
// Try to clean up earlier services we've had
|
||
|
try {
|
||
|
rfb::win32::unregisterService("WinVNC4");
|
||
|
} catch (rdr::SystemException&) {
|
||
|
// Do nothing as we might fail simply because there was no
|
||
|
// service to remove
|
||
|
}
|
||
|
try {
|
||
|
rfb::win32::unregisterService("KasmVNC Server");
|
||
|
} catch (rdr::SystemException&) {
|
||
|
}
|
||
|
|
||
|
if (rfb::win32::registerService(VNCServerService::Name,
|
||
|
_T("KasmVNC Server"),
|
||
|
_T("Provides remote access to this machine via the VNC/RFB protocol."),
|
||
|
argc-(j+1), &argv[j+1]))
|
||
|
MsgBoxOrLog("Registered service successfully");
|
||
|
} else if (strcasecmp(argv[i], "-unregister") == 0) {
|
||
|
printf("Attempting to unregister service...\n");
|
||
|
runServer = false;
|
||
|
if (rfb::win32::unregisterService(VNCServerService::Name))
|
||
|
MsgBoxOrLog("Unregistered service successfully");
|
||
|
|
||
|
} else if (strcasecmp(argv[i], "-noconsole") == 0) {
|
||
|
close_console = true;
|
||
|
vlog.info("closing console");
|
||
|
if (!FreeConsole())
|
||
|
vlog.info("unable to close console:%lu", GetLastError());
|
||
|
|
||
|
} else if ((strcasecmp(argv[i], "-help") == 0) ||
|
||
|
(strcasecmp(argv[i], "--help") == 0) ||
|
||
|
(strcasecmp(argv[i], "-h") == 0) ||
|
||
|
(strcasecmp(argv[i], "/?") == 0)) {
|
||
|
runServer = false;
|
||
|
programUsage();
|
||
|
break;
|
||
|
|
||
|
} else {
|
||
|
// Try to process <option>=<value>, or -<bool>
|
||
|
if (Configuration::setParam(argv[i], true))
|
||
|
continue;
|
||
|
// Try to process -<option> <value>
|
||
|
if ((argv[i][0] == '-') && (i+1 < argc)) {
|
||
|
if (Configuration::setParam(&argv[i][1], argv[i+1], true)) {
|
||
|
i++;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
// Nope. Show them usage and don't run the server
|
||
|
runServer = false;
|
||
|
programUsage();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} catch (rdr::Exception& e) {
|
||
|
MsgBoxOrLog(e.str(), true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// -=- main
|
||
|
//
|
||
|
|
||
|
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, char* cmdLine, int cmdShow) {
|
||
|
int result = 0;
|
||
|
|
||
|
try {
|
||
|
// - Initialise the available loggers
|
||
|
//freopen("\\\\drupe\\tjr\\WinVNC4.log","ab",stderr);
|
||
|
#ifdef _DEBUG
|
||
|
AllocConsole();
|
||
|
freopen("CONIN$", "rb", stdin);
|
||
|
freopen("CONOUT$", "wb", stdout);
|
||
|
freopen("CONOUT$", "wb", stderr);
|
||
|
setbuf(stderr, 0);
|
||
|
initStdIOLoggers();
|
||
|
initFileLogger("C:\\temp\\WinVNC4.log");
|
||
|
logParams.setParam("*:stderr:100");
|
||
|
#else
|
||
|
initFileLogger("C:\\temp\\WinVNC4.log");
|
||
|
logParams.setParam("*:stderr:0");
|
||
|
#endif
|
||
|
rfb::win32::initEventLogLogger(VNCServerService::Name);
|
||
|
|
||
|
Configuration::enableServerParams();
|
||
|
|
||
|
// - By default, just log errors to stderr
|
||
|
|
||
|
|
||
|
// - Print program details and process the command line
|
||
|
programInfo();
|
||
|
|
||
|
int argc = __argc;
|
||
|
char **argv = __argv;
|
||
|
processParams(argc, argv);
|
||
|
|
||
|
// - Run the server if required
|
||
|
if (runServer) {
|
||
|
// Start the network subsystem and run the server
|
||
|
VNCServerWin32 server;
|
||
|
result = server.run();
|
||
|
} else if (runAsService) {
|
||
|
VNCServerService service;
|
||
|
service.start();
|
||
|
result = service.getStatus().dwWin32ExitCode;
|
||
|
}
|
||
|
|
||
|
vlog.debug("WinVNC service destroyed");
|
||
|
} catch (rdr::Exception& e) {
|
||
|
MsgBoxOrLog(e.str(), true);
|
||
|
}
|
||
|
|
||
|
vlog.debug("WinVNC process quitting");
|
||
|
return result;
|
||
|
}
|