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