You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			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;
 | 
						|
}
 |