You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

winvnc.cxx 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. // -=- VNC Server 4.0 for Windows (WinVNC4)
  19. #ifdef HAVE_CONFIG_H
  20. #include <config.h>
  21. #endif
  22. #include <string.h>
  23. #include <winvnc/VNCServerWin32.h>
  24. #include <winvnc/VNCServerService.h>
  25. #include <winvnc/AddNewClientDialog.h>
  26. #include <rfb/Logger_stdio.h>
  27. #include <rfb/Logger_file.h>
  28. #include <rfb/LogWriter.h>
  29. #include <rfb_win32/AboutDialog.h>
  30. #include <rfb_win32/MsgBox.h>
  31. #include <network/TcpSocket.h>
  32. using namespace winvnc;
  33. using namespace rfb;
  34. using namespace win32;
  35. static LogWriter vlog("main");
  36. const char* rfb::win32::AppName = "TigerVNC Server";
  37. extern bool runAsService;
  38. static bool runServer = true;
  39. static bool close_console = false;
  40. //
  41. // -=- processParams
  42. // Read in the command-line parameters and interpret them.
  43. //
  44. static void programInfo() {
  45. win32::FileVersionInfo inf;
  46. printf("%s - %s, Version %s\n",
  47. inf.getVerString("ProductName"),
  48. inf.getVerString("FileDescription"),
  49. inf.getVerString("FileVersion"));
  50. printf("%s\n", buildTime);
  51. printf("%s\n\n", inf.getVerString("LegalCopyright"));
  52. }
  53. static void programUsage() {
  54. printf("Command-line options:\n");
  55. printf(" -connect [<host[::port]>] - Connect an existing WinVNC server to a listening viewer.\n");
  56. printf(" -disconnect - Disconnect all clients from an existing WinVNC server.\n");
  57. printf(" -register <options...> - Register WinVNC server as a system service.\n");
  58. printf(" -unregister - Remove WinVNC server from the list of system services.\n");
  59. printf(" -start - Start the WinVNC server system service.\n");
  60. printf(" -stop - Stop the WinVNC server system service.\n");
  61. printf(" -status - Query the WinVNC service status.\n");
  62. printf(" -help - Provide usage information.\n");
  63. printf(" -noconsole - Run without a console (i.e. no stderr/stdout)\n");
  64. printf(" <setting>=<value> - Set the named configuration parameter.\n");
  65. printf(" (Parameter values specified on the command-line override those specified by other configuration methods.)\n");
  66. printf("\nLog names:\n");
  67. LogWriter::listLogWriters();
  68. printf("\nLog destinations:\n");
  69. Logger::listLoggers();
  70. printf("\nAvailable configuration parameters:\n");
  71. Configuration::listParams(79, 14);
  72. }
  73. static void MsgBoxOrLog(const char* msg, bool isError=false) {
  74. if (close_console) {
  75. MsgBox(0, msg, (isError ? MB_ICONERROR : MB_ICONINFORMATION) | MB_OK);
  76. } else {
  77. if (isError) {
  78. try {
  79. vlog.error("%s", msg);
  80. return;
  81. } catch (...) {
  82. }
  83. }
  84. fprintf(stderr, "%s\n", msg);
  85. }
  86. }
  87. static void processParams(int argc, char** argv) {
  88. for (int i=1; i<argc; i++) {
  89. try {
  90. if (strcasecmp(argv[i], "-connect") == 0) {
  91. runServer = false;
  92. const char *host = NULL;
  93. if (i+1 < argc) {
  94. host = argv[i+1];
  95. i++;
  96. } else {
  97. AddNewClientDialog ancd;
  98. if (ancd.showDialog())
  99. host = ancd.getHostName();
  100. }
  101. if (host != NULL) {
  102. HWND hwnd = FindWindow(0, "winvnc::IPC_Interface");
  103. if (!hwnd)
  104. throw rdr::Exception("Unable to locate existing VNC Server.");
  105. COPYDATASTRUCT copyData;
  106. copyData.dwData = 1; // *** AddNewClient
  107. copyData.cbData = strlen(host);
  108. copyData.lpData = (void*)host;
  109. printf("Sending connect request to VNC Server...\n");
  110. if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&copyData))
  111. MsgBoxOrLog("Connection failed.", true);
  112. }
  113. } else if (strcasecmp(argv[i], "-disconnect") == 0) {
  114. runServer = false;
  115. HWND hwnd = FindWindow(0, "winvnc::IPC_Interface");
  116. if (!hwnd)
  117. throw rdr::Exception("Unable to locate existing VNC Server.");
  118. COPYDATASTRUCT copyData;
  119. copyData.dwData = 2; // *** DisconnectClients
  120. copyData.lpData = 0;
  121. copyData.cbData = 0;
  122. printf("Sending disconnect request to VNC Server...\n");
  123. if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&copyData))
  124. MsgBoxOrLog("Failed to disconnect clients.", true);
  125. } else if (strcasecmp(argv[i], "-start") == 0) {
  126. printf("Attempting to start service...\n");
  127. runServer = false;
  128. if (rfb::win32::startService(VNCServerService::Name))
  129. MsgBoxOrLog("Started service successfully");
  130. } else if (strcasecmp(argv[i], "-stop") == 0) {
  131. printf("Attempting to stop service...\n");
  132. runServer = false;
  133. if (rfb::win32::stopService(VNCServerService::Name))
  134. MsgBoxOrLog("Stopped service successfully");
  135. } else if (strcasecmp(argv[i], "-status") == 0) {
  136. printf("Querying service status...\n");
  137. runServer = false;
  138. std::string result;
  139. DWORD state = rfb::win32::getServiceState(VNCServerService::Name);
  140. result = strFormat("The %s Service is in the %s state.",
  141. VNCServerService::Name,
  142. rfb::win32::serviceStateName(state));
  143. MsgBoxOrLog(result.c_str());
  144. } else if (strcasecmp(argv[i], "-service") == 0) {
  145. printf("Run in service mode\n");
  146. runServer = false;
  147. runAsService = true;
  148. } else if (strcasecmp(argv[i], "-service_run") == 0) {
  149. printf("Run in service mode\n");
  150. runAsService = true;
  151. } else if (strcasecmp(argv[i], "-register") == 0) {
  152. printf("Attempting to register service...\n");
  153. runServer = false;
  154. int j = i;
  155. i = argc;
  156. // Try to clean up earlier services we've had
  157. try {
  158. rfb::win32::unregisterService("WinVNC4");
  159. } catch (rdr::SystemException&) {
  160. // Do nothing as we might fail simply because there was no
  161. // service to remove
  162. }
  163. try {
  164. rfb::win32::unregisterService("TigerVNC Server");
  165. } catch (rdr::SystemException&) {
  166. }
  167. if (rfb::win32::registerService(VNCServerService::Name,
  168. "TigerVNC Server",
  169. "Provides remote access to this machine via the VNC/RFB protocol.",
  170. argc-(j+1), &argv[j+1]))
  171. MsgBoxOrLog("Registered service successfully");
  172. } else if (strcasecmp(argv[i], "-unregister") == 0) {
  173. printf("Attempting to unregister service...\n");
  174. runServer = false;
  175. if (rfb::win32::unregisterService(VNCServerService::Name))
  176. MsgBoxOrLog("Unregistered service successfully");
  177. } else if (strcasecmp(argv[i], "-noconsole") == 0) {
  178. close_console = true;
  179. vlog.info("closing console");
  180. if (!FreeConsole())
  181. vlog.info("unable to close console:%lu", GetLastError());
  182. } else if ((strcasecmp(argv[i], "-help") == 0) ||
  183. (strcasecmp(argv[i], "--help") == 0) ||
  184. (strcasecmp(argv[i], "-h") == 0) ||
  185. (strcasecmp(argv[i], "/?") == 0)) {
  186. runServer = false;
  187. programUsage();
  188. break;
  189. } else {
  190. // Try to process <option>=<value>, or -<bool>
  191. if (Configuration::setParam(argv[i], true))
  192. continue;
  193. // Try to process -<option> <value>
  194. if ((argv[i][0] == '-') && (i+1 < argc)) {
  195. if (Configuration::setParam(&argv[i][1], argv[i+1], true)) {
  196. i++;
  197. continue;
  198. }
  199. }
  200. // Nope. Show them usage and don't run the server
  201. runServer = false;
  202. programUsage();
  203. break;
  204. }
  205. } catch (rdr::Exception& e) {
  206. MsgBoxOrLog(e.str(), true);
  207. }
  208. }
  209. }
  210. //
  211. // -=- main
  212. //
  213. int WINAPI WinMain(HINSTANCE /*inst*/, HINSTANCE /*prevInst*/, char* /*cmdLine*/, int /*cmdShow*/) {
  214. int result = 0;
  215. try {
  216. // - Initialise the available loggers
  217. //freopen("\\\\drupe\\tjr\\WinVNC4.log","ab",stderr);
  218. #ifdef _DEBUG
  219. AllocConsole();
  220. freopen("CONIN$", "rb", stdin);
  221. freopen("CONOUT$", "wb", stdout);
  222. freopen("CONOUT$", "wb", stderr);
  223. setbuf(stderr, 0);
  224. initStdIOLoggers();
  225. initFileLogger("C:\\temp\\WinVNC4.log");
  226. logParams.setParam("*:stderr:100");
  227. #else
  228. initFileLogger("C:\\temp\\WinVNC4.log");
  229. logParams.setParam("*:stderr:0");
  230. #endif
  231. rfb::win32::initEventLogLogger(VNCServerService::Name);
  232. Configuration::enableServerParams();
  233. // - By default, just log errors to stderr
  234. // - Print program details and process the command line
  235. programInfo();
  236. int argc = __argc;
  237. char **argv = __argv;
  238. processParams(argc, argv);
  239. // - Run the server if required
  240. if (runServer) {
  241. // Start the network subsystem and run the server
  242. VNCServerWin32 server;
  243. result = server.run();
  244. } else if (runAsService) {
  245. VNCServerService service;
  246. service.start();
  247. result = service.getStatus().dwWin32ExitCode;
  248. }
  249. vlog.debug("WinVNC service destroyed");
  250. } catch (rdr::Exception& e) {
  251. MsgBoxOrLog(e.str(), true);
  252. }
  253. vlog.debug("WinVNC process quitting");
  254. return result;
  255. }