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

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