Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@591 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/win/winvnc/AddNewClientDialog.h b/win/winvnc/AddNewClientDialog.h
new file mode 100644
index 0000000..9bf5135
--- /dev/null
+++ b/win/winvnc/AddNewClientDialog.h
@@ -0,0 +1,56 @@
+/* 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.
+ */
+
+// -=- AddnewClientDialog.h
+
+#ifndef __WINVNC_ADD_NEW_CLIENT_DIALOG_H__
+#define __WINVNC_ADD_NEW_CLIENT_DIALOG_H__
+
+#include <winvnc/resource.h>
+#include <rfb_win32/Dialog.h>
+//#include <rfb_win32/TCharArray.h>
+
+namespace winvnc {
+
+  class AddNewClientDialog : public rfb::win32::Dialog {
+  public:
+    AddNewClientDialog() : Dialog(GetModuleHandle(0)) {}
+    // - Show the dialog and return true if OK was clicked,
+    //   false in case of error or Cancel
+    virtual bool showDialog() {
+      return Dialog::showDialog(MAKEINTRESOURCE(IDD_ADD_NEW_CLIENT));
+    }
+    const char* getHostName() const {return hostName.buf;}
+  protected:
+
+    // Dialog methods (protected)
+    virtual void initDialog() {
+      if (hostName.buf)
+        setItemString(IDC_HOST, rfb::TStr(hostName.buf));
+    }
+    virtual bool onOk() {
+      hostName.replaceBuf(rfb::strDup(rfb::CStr(getItemString(IDC_HOST))));
+      return true;
+    }
+
+    rfb::CharArray hostName;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/ControlPanel.cxx b/win/winvnc/ControlPanel.cxx
new file mode 100644
index 0000000..7428230
--- /dev/null
+++ b/win/winvnc/ControlPanel.cxx
@@ -0,0 +1,161 @@
+// ControlPanel.cxx: implementation of the ControlPanel class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ControlPanel.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+using namespace winvnc;
+
+bool ControlPanel::showDialog()
+{
+  return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONTROL_PANEL), NULL);
+}
+
+void ControlPanel::initDialog()
+{
+  TCHAR *ColumnsStrings[] = {
+    "IP address",
+    "Time connected",
+    "Status"
+  };
+  InitLVColumns(IDC_LIST_CONNECTIONS, handle, 120, 3, ColumnsStrings,
+                LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM,
+                LVS_EX_FULLROWSELECT, LVCFMT_LEFT);
+  SendCommand(4, -1);
+}
+
+bool ControlPanel::onCommand(int cmd)
+{
+  switch (cmd) {
+  case IDC_PROPERTIES:
+    SendMessage(m_hSTIcon, WM_COMMAND, ID_OPTIONS, 0);
+    return false;
+  case IDC_ADD_CLIENT:
+    SendMessage(m_hSTIcon, WM_COMMAND, ID_CONNECT, 0);
+    return false;
+  case IDC_KILL_ALL:
+    {
+      SendCommand(2, -1);
+      return false;
+    }
+  case IDC_KILL_SEL_CLIENT:
+    {     
+      SendCommand(3, 3);
+      return false;
+    }
+  case IDC_VIEW_ONLY:
+    {     
+      SendCommand(3, 1);
+      return false;
+    }
+  case IDC_FULL_CONTROL:
+    {     
+      SendCommand(3, 0);
+      return false;
+    }
+  case IDC_STOP_UPDATE:
+    {     
+      stop_updating = true;
+      EndDialog(handle, 0);
+      return false;
+    }
+  case IDC_DISABLE_CLIENTS:
+    {   
+      ListConnStatus.setDisable(isItemChecked(IDC_DISABLE_CLIENTS));
+      SendCommand(3, -1);
+      return false;
+    }
+  }
+  return false;
+  
+}
+
+void ControlPanel::UpdateListView(rfb::ListConnInfo* LCInfo)
+{
+  getSelConnInfo();
+  DeleteAllLVItem(IDC_LIST_CONNECTIONS, handle);
+  setItemChecked(IDC_DISABLE_CLIENTS, LCInfo->getDisable());
+
+  if(LCInfo->Empty()) 
+    return;
+
+  ListConn.Copy(LCInfo);
+
+  char* ItemString[3];
+  int i = 0;
+
+  for (ListConn.iBegin(); !ListConn.iEnd(); ListConn.iNext()) {
+    ListConn.iGetCharInfo(ItemString);
+    InsertLVItem(IDC_LIST_CONNECTIONS, handle, i, ItemString, 3);
+    for (ListSelConn.iBegin(); !ListSelConn.iEnd(); ListSelConn.iNext()) {
+      if (ListSelConn.iGetConn() == ListConn.iGetConn())
+        SelectLVItem(IDC_LIST_CONNECTIONS, handle, i);
+    }
+    i++;
+  } 
+}
+
+BOOL ControlPanel::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+  switch (msg) {
+  case WM_INITDIALOG:
+    handle = hwnd;
+    initDialog();
+    return TRUE;
+  case WM_DESTROY:
+    if (stop_updating) {
+      stop_updating = false;
+      SendCommand(3, 2);
+    }
+    return TRUE;
+  case WM_COMMAND:
+    switch (LOWORD(wParam)) {
+    case IDCANCEL:
+      handle = NULL;
+      EndDialog(hwnd, 0);
+      return TRUE;
+    default:
+      return onCommand(LOWORD(wParam));
+    }
+  }
+  return FALSE;
+}
+
+void ControlPanel::getSelConnInfo()
+{
+  int i = 0;
+  ListSelConn.Clear();
+  if(ListConn.Empty()) return;
+  for (ListConn.iBegin(); !ListConn.iEnd(); ListConn.iNext()) {
+    if (IsSelectedLVItem(IDC_LIST_CONNECTIONS, handle, i))
+      ListSelConn.iAdd(&ListConn);
+    i++;
+  }
+}
+
+void ControlPanel::SendCommand(DWORD command, int data)
+{
+  COPYDATASTRUCT copyData;
+  copyData.dwData = command;
+  copyData.lpData = 0;
+  getSelConnInfo();
+  if (data != -1) {
+    ListConnStatus.Copy(&ListSelConn);
+    ListConnStatus.setAllStatus(data);
+    ListConnStatus.setDisable(isItemChecked(IDC_DISABLE_CLIENTS));
+    copyData.cbData = (DWORD)&ListConnStatus;
+  } else {
+    ListConnStatus.Clear();
+  }
+  copyData.cbData = (DWORD)&ListConnStatus;
+  SendMessage(m_hSTIcon, WM_COPYDATA, 0, (LPARAM)&copyData);
+}
+
+ControlPanel::~ControlPanel()
+{
+  
+}
diff --git a/win/winvnc/ControlPanel.h b/win/winvnc/ControlPanel.h
new file mode 100644
index 0000000..73b859f
--- /dev/null
+++ b/win/winvnc/ControlPanel.h
@@ -0,0 +1,45 @@
+// ControlPanel.h: interface for the ControlPanel class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef AFX_CONTROLPANEL_H__
+#define AFX_CONTROLPANEL_H__
+
+
+#pragma once
+
+
+#include <list>
+#include <winvnc/resource.h>
+#include <rfb_win32/Dialog.h>
+#include <rfb_win32/ListViewControl.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb/ListConnInfo.h>
+
+namespace winvnc {
+  
+  class ControlPanel : rfb::win32::Dialog, rfb::win32::ListViewControl {
+  public:
+    ControlPanel(HWND hSTIcon) : Dialog(GetModuleHandle(0)), ListViewControl(){
+      m_hSTIcon = hSTIcon;
+      stop_updating = false;
+    };
+    virtual bool showDialog();
+    virtual void initDialog();
+    virtual bool onCommand(int cmd);
+    void UpdateListView(rfb::ListConnInfo* LCInfo);
+    HWND GetHandle() {return handle;};
+    void SendCommand(DWORD command, int data);
+    ~ControlPanel();
+    rfb::ListConnInfo ListConnStatus;
+  protected: 
+    virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+    void getSelConnInfo();
+    HWND m_hSTIcon;
+    rfb::ListConnInfo ListConn;
+    rfb::ListConnInfo ListSelConn;
+    bool stop_updating;
+  };
+};
+
+#endif  
\ No newline at end of file
diff --git a/win/winvnc/JavaViewer.cxx b/win/winvnc/JavaViewer.cxx
new file mode 100644
index 0000000..15c05c4
--- /dev/null
+++ b/win/winvnc/JavaViewer.cxx
@@ -0,0 +1,98 @@
+/* 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.
+ */
+
+#include <windows.h>
+#include <winvnc/JavaViewer.h>
+#include <winvnc/resource.h>
+#include <rdr/MemInStream.h>
+#include <rfb/LogWriter.h>
+#include <rfb/VNCserverST.h>
+#include <rfb_win32/TCharArray.h>
+
+#define strcasecmp _stricmp
+
+using namespace winvnc;
+using namespace rfb;
+
+
+static rfb::LogWriter vlog("JavaViewerServer");
+
+JavaViewerServer::JavaViewerServer(rfb::VNCServerST* svr) : server(svr) {
+}
+
+JavaViewerServer::~JavaViewerServer() {
+}
+
+rdr::InStream* JavaViewerServer::getFile(const char* name,
+                                         const char** contentType,
+                                         int* contentLength,
+                                         time_t* lastModified)
+{
+  if (strcmp(name, "/") == 0)
+    name = "/index.vnc";
+
+  HRSRC resource = FindResource(0, TStr(name), _T("HTTPFILE"));
+  if (!resource) return 0;
+  HGLOBAL handle = LoadResource(0, resource);
+  if (!handle) return 0;
+  void* buf = LockResource(handle);
+  int len = SizeofResource(0, resource);
+
+  rdr::InStream* is = new rdr::MemInStream(buf, len);
+  if (strlen(name) > 4 && strcasecmp(&name[strlen(name)-4], ".vnc") == 0) {
+    is = new rdr::SubstitutingInStream(is, this, 20);
+    *contentType = "text/html";
+  }
+  return is;
+}
+
+char* JavaViewerServer::substitute(const char* varName)
+{
+  if (strcmp(varName, "$$") == 0) {
+    return rfb::strDup("$");
+  }
+  if (strcmp(varName, "$PORT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", rfbPort);
+    return str;
+  }
+  if (strcmp(varName, "$WIDTH") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", server->getDesktopSize().x);
+    return str;
+  }
+  if (strcmp(varName, "$HEIGHT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", server->getDesktopSize().y);
+    return str;
+  }
+  if (strcmp(varName, "$APPLETWIDTH") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", server->getDesktopSize().x);
+    return str;
+  }
+  if (strcmp(varName, "$APPLETHEIGHT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", server->getDesktopSize().y + 32);
+    return str;
+  }
+  if (strcmp(varName, "$DESKTOP") == 0) {
+    return rfb::strDup(server->getName());
+  }
+  return 0;
+}
diff --git a/win/winvnc/JavaViewer.h b/win/winvnc/JavaViewer.h
new file mode 100644
index 0000000..ecda4d3
--- /dev/null
+++ b/win/winvnc/JavaViewer.h
@@ -0,0 +1,55 @@
+/* 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.
+ */
+
+// -=- JavaViewer.h
+
+// Custom HTTPServer-derived class which serves the Java VNC Viewer
+// to clients, using resource files compiled in to the WinVNC executable.
+
+#ifndef WINVNC_JAVA_VIEWER
+#define WINVNC_JAVA_VIEWER
+
+#include <rfb/HTTPServer.h>
+#include <rfb/VNCServerST.h>
+#include <rdr/SubstitutingInStream.h>
+
+namespace winvnc {
+
+  class JavaViewerServer : public rfb::HTTPServer, public rdr::Substitutor {
+  public:
+    JavaViewerServer(rfb::VNCServerST* desktop);
+    virtual ~JavaViewerServer();
+
+    virtual rdr::InStream* getFile(const char* name, const char** contentType,
+                                   int* contentLength, time_t* lastModified);
+
+    // rdr::Substitutor callback
+    virtual char* substitute(const char* varName);
+
+    void setRFBport(int port) {
+      rfbPort = port;
+    }
+  protected:
+    int rfbPort;
+    rfb::VNCServerST* server;
+  };
+
+};
+
+#endif
+
diff --git a/win/winvnc/ManagedListener.cxx b/win/winvnc/ManagedListener.cxx
new file mode 100644
index 0000000..9bf1b9a
--- /dev/null
+++ b/win/winvnc/ManagedListener.cxx
@@ -0,0 +1,94 @@
+/* Copyright (C) 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.
+ */
+#include <winvnc/ManagedListener.h>
+#include <rfb/LogWriter.h>
+
+using namespace winvnc;
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("ManagedListener");
+
+
+ManagedListener::ManagedListener(SocketManager* mgr)
+: sock(0), filter(0), manager(mgr), addrChangeNotifier(0), server(0), port(0), localOnly(false) {
+}
+
+ManagedListener::~ManagedListener() {
+  if (sock)
+    manager->remListener(sock);
+  delete filter;
+}
+
+
+void ManagedListener::setServer(network::SocketServer* svr) {
+  if (svr == server)
+    return;
+  vlog.info("set server to %p", svr);
+  server = svr;
+  refresh();
+}
+
+void ManagedListener::setPort(int port_, bool localOnly_) {
+  if ((port_ == port) && (localOnly == localOnly_))
+    return;
+  vlog.info("set port to %d", port_);
+  port = port_;
+  localOnly = localOnly_;
+  refresh();
+}
+
+void ManagedListener::setFilter(const char* filterStr) {
+  vlog.info("set filter to %s", filterStr);
+  delete filter;
+  filter = new network::TcpFilter(filterStr);
+  if (sock && !localOnly)
+    sock->setFilter(filter);
+}
+
+void ManagedListener::setAddressChangeNotifier(SocketManager::AddressChangeNotifier* acn) {
+  if (acn == addrChangeNotifier)
+    return;
+  addrChangeNotifier = acn;
+  refresh();
+}
+
+
+void ManagedListener::refresh() {
+  if (sock)
+    manager->remListener(sock);
+  sock = 0;
+  if (!server)
+    return;
+  try {
+    if (port)
+      sock = new network::TcpListener(port, localOnly);
+  } catch (rdr::Exception& e) {
+    vlog.error(e.str());
+  }
+  if (sock) {
+    if (!localOnly)
+      sock->setFilter(filter);
+    try {
+      manager->addListener(sock, server, addrChangeNotifier);
+    } catch (...) {
+      sock = 0;
+      throw;
+    }
+  }
+}
diff --git a/win/winvnc/ManagedListener.h b/win/winvnc/ManagedListener.h
new file mode 100644
index 0000000..e83aa0b
--- /dev/null
+++ b/win/winvnc/ManagedListener.h
@@ -0,0 +1,57 @@
+/* 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.
+ */
+
+#ifndef __VNCSERVER_MANAGED_LISTENER_H__
+#define __VNCSERVER_MANAGED_LISTENER_H__
+
+#include <winsock2.h>
+#include <network/TcpSocket.h>
+#include <rfb_win32/SocketManager.h>
+
+namespace winvnc {
+
+  // -=- ManagedListener
+  //     Wrapper class which simplifies the management of a listening socket
+  //     on a specified port, attached to a SocketManager and SocketServer.
+  //     Reopens sockets & reconfigures filters & callbacks as appropriate.
+  //     Handles addition/removal of Listeners from SocketManager internally.
+
+  class ManagedListener {
+  public:
+    ManagedListener(rfb::win32::SocketManager* mgr);
+    ~ManagedListener();
+    
+    void setServer(network::SocketServer* svr);
+    void setPort(int port, bool localOnly=false);
+    void setFilter(const char* filter);
+    void setAddressChangeNotifier(rfb::win32::SocketManager::AddressChangeNotifier* acn);
+  
+    network::TcpListener* sock;
+  protected:
+    void refresh();
+    network::TcpFilter* filter;
+    rfb::win32::SocketManager* manager;
+    rfb::win32::SocketManager::AddressChangeNotifier* addrChangeNotifier;
+    network::SocketServer* server;
+    int port;
+    bool localOnly;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/QueryConnectDialog.cxx b/win/winvnc/QueryConnectDialog.cxx
new file mode 100644
index 0000000..dc50eab
--- /dev/null
+++ b/win/winvnc/QueryConnectDialog.cxx
@@ -0,0 +1,100 @@
+/* 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.
+ */
+
+#include <winvnc/QueryConnectDialog.h>
+#include <winvnc/VNCServerWin32.h>
+#include <winvnc/resource.h>
+#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/TCharArray.h>
+#include <rfb_win32/Service.h>
+#include <rfb/LogWriter.h>
+
+using namespace rfb;
+using namespace win32;
+using namespace winvnc;
+
+static LogWriter vlog("QueryConnectDialog");
+
+static IntParameter timeout("QueryConnectTimeout",
+                            "Number of seconds to show the Accept Connection dialog before "
+                            "rejecting the connection",
+                            10);
+
+
+// - Visible methods
+
+QueryConnectDialog::QueryConnectDialog(network::Socket* sock_,
+                                       const char* userName_,
+                                       VNCServerWin32* s)
+: Thread("QueryConnectDialog"), Dialog(GetModuleHandle(0)),
+  sock(sock_), approve(false), server(s) {
+  peerIp.buf = sock->getPeerAddress();
+  userName.buf = strDup(userName_);
+}
+
+void QueryConnectDialog::startDialog() {
+  start();
+}
+
+
+// - Thread overrides
+
+void QueryConnectDialog::run() {
+  countdown = timeout;
+  try {
+    if (desktopChangeRequired() && !changeDesktop())
+      throw rdr::Exception("changeDesktop failed");
+    approve = Dialog::showDialog(MAKEINTRESOURCE(IDD_QUERY_CONNECT));
+    server->queryConnectionComplete();
+  } catch (...) {
+    server->queryConnectionComplete();
+    throw;
+  }
+}
+
+
+// - Dialog overrides
+
+void QueryConnectDialog::initDialog() {
+  if (!SetTimer(handle, 1, 1000, 0))
+    throw rdr::SystemException("SetTimer", GetLastError());
+  setItemString(IDC_QUERY_HOST, TStr(peerIp.buf));
+  if (!userName.buf)
+    userName.buf = strDup("(anonymous)");
+  setItemString(IDC_QUERY_USER, TStr(userName.buf));
+  setCountdownLabel();
+}
+
+void QueryConnectDialog::setCountdownLabel() {
+  TCHAR buf[16];
+  _stprintf(buf, _T("%d"), countdown);
+  setItemString(IDC_QUERY_COUNTDOWN, buf);
+}
+
+BOOL QueryConnectDialog::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+  if (msg == WM_TIMER) {
+    if (--countdown == 0 || desktopChangeRequired()) {
+      DestroyWindow(hwnd);
+    } else {
+      setCountdownLabel();
+    }
+    return TRUE;
+  } else {
+    return Dialog::dialogProc(hwnd, msg, wParam, lParam);
+  }
+}
diff --git a/win/winvnc/QueryConnectDialog.h b/win/winvnc/QueryConnectDialog.h
new file mode 100644
index 0000000..b28de19
--- /dev/null
+++ b/win/winvnc/QueryConnectDialog.h
@@ -0,0 +1,60 @@
+/* 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.
+ */
+
+// -=- QueryConnectDialog.h
+
+#ifndef __WINVNC_QUERY_CONNECT_DIALOG_H__
+#define __WINVNC_QUERY_CONNECT_DIALOG_H__
+
+#include <rfb/Threading.h>
+#include <rfb_win32/Dialog.h>
+#include <rfb/util.h>
+
+namespace network { class Socket; }
+
+namespace winvnc {
+
+  class VNCServerWin32;
+
+  class QueryConnectDialog : public rfb::Thread, rfb::win32::Dialog {
+  public:
+    QueryConnectDialog(network::Socket* sock, const char* userName, VNCServerWin32* s);
+    virtual void startDialog();
+    virtual void run();
+    network::Socket* getSock() {return sock;}
+    bool isAccepted() const {return approve;}
+  protected:
+
+    // Dialog methods (protected)
+    virtual void initDialog();
+    virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+    // Custom internal methods
+    void setCountdownLabel();
+
+    int countdown;
+    network::Socket* sock;
+    rfb::CharArray peerIp;
+    rfb::CharArray userName;
+    bool approve;
+    VNCServerWin32* server;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx
new file mode 100644
index 0000000..0b10fa5
--- /dev/null
+++ b/win/winvnc/STrayIcon.cxx
@@ -0,0 +1,280 @@
+/* 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.
+ */
+
+// -=- WinVNC Version 4.0 Tray Icon implementation
+
+#include <winvnc/STrayIcon.h>
+#include <winvnc/VNCServerService.h>
+#include <winvnc/resource.h>
+
+#include <rfb/LogWriter.h>
+#include <rfb/Configuration.h>
+#include <rfb_win32/LaunchProcess.h>
+#include <rfb_win32/TrayIcon.h>
+#include <rfb_win32/AboutDialog.h>
+#include <rfb_win32/MsgBox.h>
+#include <rfb_win32/Service.h>
+#include <rfb_win32/CurrentUser.h>
+#include <winvnc/ControlPanel.h>
+
+using namespace rfb;
+using namespace win32;
+using namespace winvnc;
+
+static LogWriter vlog("STrayIcon");
+
+BoolParameter STrayIconThread::disableOptions("DisableOptions", "Disable the Options entry in the VNC Server tray menu.", false);
+BoolParameter STrayIconThread::disableClose("DisableClose", "Disable the Close entry in the VNC Server tray menu.", false);
+
+
+//
+// -=- AboutDialog global values
+//
+
+const WORD rfb::win32::AboutDialog::DialogId = IDD_ABOUT;
+const WORD rfb::win32::AboutDialog::Copyright = IDC_COPYRIGHT;
+const WORD rfb::win32::AboutDialog::Version = IDC_VERSION;
+const WORD rfb::win32::AboutDialog::BuildTime = IDC_BUILDTIME;
+const WORD rfb::win32::AboutDialog::Description = IDC_DESCRIPTION;
+
+
+//
+// -=- Internal tray icon class
+//
+
+const UINT WM_SET_TOOLTIP = WM_USER + 1;
+
+
+class winvnc::STrayIcon : public TrayIcon {
+public:
+  STrayIcon(STrayIconThread& t) : thread(t),
+    vncConfig(_T("vncconfig.exe"), isServiceProcess() ? _T("-noconsole -service") : _T("-noconsole")),
+    vncConnect(_T("winvnc4.exe"), _T("-noconsole -connect")) {
+
+    // ***
+    SetWindowText(getHandle(), _T("winvnc::IPC_Interface"));
+    // ***
+
+    SetTimer(getHandle(), 1, 3000, 0);
+    PostMessage(getHandle(), WM_TIMER, 1, 0);
+    PostMessage(getHandle(), WM_SET_TOOLTIP, 0, 0);
+    CPanel = new ControlPanel(getHandle());
+  }
+
+  virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+    switch(msg) {
+
+    case WM_USER:
+      {
+        bool userKnown = CurrentUserToken().canImpersonate();
+        bool allowOptions = !STrayIconThread::disableOptions && userKnown;
+        bool allowClose = !STrayIconThread::disableClose && userKnown;
+
+        switch (lParam) {
+        case WM_LBUTTONDBLCLK:
+          SendMessage(getHandle(), WM_COMMAND, ID_CONTR0L_PANEL, 0);
+          break;
+        case WM_RBUTTONUP:
+          HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(thread.menu));
+          HMENU trayMenu = GetSubMenu(menu, 0);
+
+
+          // Default item is Options, if available, or About if not
+          SetMenuDefaultItem(trayMenu, ID_CONTR0L_PANEL, FALSE);
+          
+          // Enable/disable options as required
+          EnableMenuItem(trayMenu, ID_OPTIONS, (!allowOptions ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND);
+          EnableMenuItem(trayMenu, ID_CONNECT, (!userKnown ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND);
+          EnableMenuItem(trayMenu, ID_CLOSE, (!allowClose ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND);
+
+          thread.server.getClientsInfo(&LCInfo);
+          CheckMenuItem(trayMenu, ID_DISABLE_NEW_CLIENTS, (LCInfo.getDisable() ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
+
+          // SetForegroundWindow is required, otherwise Windows ignores the
+          // TrackPopupMenu because the window isn't the foreground one, on
+          // some older Windows versions...
+          SetForegroundWindow(getHandle());
+
+          // Display the menu
+          POINT pos;
+          GetCursorPos(&pos);
+          TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0);
+
+          break;
+		} 
+        return 0;
+      }
+    
+      // Handle tray icon menu commands
+    case WM_COMMAND:
+      switch (LOWORD(wParam)) {
+      case ID_CONTR0L_PANEL:
+        CPanel->showDialog();
+        break;
+      case ID_DISABLE_NEW_CLIENTS:
+        {
+          thread.server.getClientsInfo(&LCInfo);
+          LCInfo.setDisable(!LCInfo.getDisable());
+          thread.server.setClientsStatus(&LCInfo);
+          CPanel->UpdateListView(&LCInfo);
+        }
+        break;
+      case ID_OPTIONS:
+        {
+          CurrentUserToken token;
+          if (token.canImpersonate())
+            vncConfig.start(isServiceProcess() ? (HANDLE)token : INVALID_HANDLE_VALUE);
+          else
+            vlog.error("Options: unknown current user");
+        }
+        break;
+      case ID_CONNECT:
+        {
+          CurrentUserToken token;
+          if (token.canImpersonate())
+            vncConnect.start(isServiceProcess() ? (HANDLE)token : INVALID_HANDLE_VALUE);
+          else
+            vlog.error("Options: unknown current user");
+        }
+        break;
+      case ID_DISCONNECT:
+        thread.server.disconnectClients("tray menu disconnect");
+        break;
+      case ID_CLOSE:
+        if (MsgBox(0, _T("Are you sure you want to close the server?"),
+                   MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) {
+          if (isServiceProcess()) {
+            ImpersonateCurrentUser icu;
+            try {
+              rfb::win32::stopService(VNCServerService::Name);
+            } catch (rdr::Exception& e) {
+              MsgBox(0, TStr(e.str()), MB_ICONERROR | MB_OK);
+            }
+          } else {
+            thread.server.stop();
+          }
+        }
+        break;
+      case ID_ABOUT:
+        AboutDialog::instance.showDialog();
+        break;
+      }
+      return 0;
+
+      // Handle commands send by other processes
+    case WM_COPYDATA:
+      {
+        COPYDATASTRUCT* command = (COPYDATASTRUCT*)lParam;
+        switch (command->dwData) {
+        case 1:
+          {
+            CharArray viewer = new char[command->cbData + 1];
+            memcpy(viewer.buf, command->lpData, command->cbData);
+            viewer.buf[command->cbData] = 0;
+            return thread.server.addNewClient(viewer.buf) ? 1 : 0;
+          }
+        case 2:
+          return thread.server.disconnectClients("IPC disconnect") ? 1 : 0;
+        case 3:
+          thread.server.setClientsStatus((rfb::ListConnInfo *)command->cbData);
+        case 4:
+          thread.server.getClientsInfo(&LCInfo);
+          CPanel->UpdateListView(&LCInfo);
+          break;
+        };
+      };
+      break;
+
+    case WM_CLOSE:
+      PostQuitMessage(0);
+      break;
+
+    case WM_TIMER:
+      if (rfb::win32::desktopChangeRequired()) {
+        SendMessage(getHandle(), WM_CLOSE, 0, 0);
+        return 0;
+      }
+
+      thread.server.getClientsInfo(&LCInfo);
+      CPanel->UpdateListView(&LCInfo);
+
+      setIcon(thread.server.isServerInUse() ?
+              (!LCInfo.getDisable() ? thread.activeIcon : thread.dis_activeIcon) : 
+              (!LCInfo.getDisable() ? thread.inactiveIcon : thread.dis_inactiveIcon));
+
+      return 0;
+
+    case WM_SET_TOOLTIP:
+      {
+        rfb::Lock l(thread.lock);
+        if (thread.toolTip.buf)
+          setToolTip(thread.toolTip.buf);
+      }
+      return 0;
+
+    }
+
+    return TrayIcon::processMessage(msg, wParam, lParam);
+  }
+
+protected:
+  LaunchProcess vncConfig;
+  LaunchProcess vncConnect;
+  STrayIconThread& thread;
+  ControlPanel * CPanel;
+  rfb::ListConnInfo LCInfo;
+};
+
+
+STrayIconThread::STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon_, UINT activeIcon_, 
+                                 UINT dis_inactiveIcon_, UINT dis_activeIcon_, UINT menu_)
+: Thread("TrayIcon"), server(sm), inactiveIcon(inactiveIcon_), activeIcon(activeIcon_),
+  dis_inactiveIcon(dis_inactiveIcon_), dis_activeIcon(dis_activeIcon_),menu(menu_),
+  windowHandle(0), runTrayIcon(true) {
+  start();
+}
+
+
+void STrayIconThread::run() {
+  while (runTrayIcon) {
+    if (rfb::win32::desktopChangeRequired() && 
+      !rfb::win32::changeDesktop())
+      Sleep(2000);
+
+    STrayIcon icon(*this);
+    windowHandle = icon.getHandle();
+
+    MSG msg;
+    while (runTrayIcon && ::GetMessage(&msg, 0, 0, 0) > 0) {
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+
+    windowHandle = 0;
+  }
+}
+
+void STrayIconThread::setToolTip(const TCHAR* text) {
+  if (!windowHandle) return;
+  Lock l(lock);
+  delete [] toolTip.buf;
+  toolTip.buf = tstrDup(text);
+  PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0);
+}
+
+
diff --git a/win/winvnc/STrayIcon.h b/win/winvnc/STrayIcon.h
new file mode 100644
index 0000000..309d3f4
--- /dev/null
+++ b/win/winvnc/STrayIcon.h
@@ -0,0 +1,61 @@
+/* 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.
+ */
+
+#ifndef WINVNC_TRAYICON_H
+#define WINVNC_TRAYICON_H
+
+#include <winvnc/VNCServerWin32.h>
+#include <rfb_win32/TCharArray.h>
+#include <rfb/Configuration.h>
+#include <rfb/Threading.h>
+
+namespace winvnc {
+
+  class STrayIconThread : rfb::Thread {
+  public:
+    STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon,
+      UINT activeIcon, UINT dis_inactiveIcon, UINT dis_activeIcon, UINT menu);
+    virtual ~STrayIconThread() {
+      runTrayIcon = false;
+      PostThreadMessage(getThreadId(), WM_QUIT, 0, 0);
+    }
+
+    virtual void run();
+
+    void setToolTip(const TCHAR* text);
+
+    static rfb::BoolParameter disableOptions;
+    static rfb::BoolParameter disableClose;
+
+    friend class STrayIcon;
+  protected:
+    rfb::Mutex lock;
+    HWND windowHandle;
+    rfb::TCharArray toolTip;
+    VNCServerWin32& server;
+    UINT inactiveIcon;
+    UINT activeIcon;
+    UINT dis_inactiveIcon;
+    UINT dis_activeIcon;
+    UINT menu;
+    bool runTrayIcon;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/VNCServerService.cxx b/win/winvnc/VNCServerService.cxx
new file mode 100644
index 0000000..2ef2ee0
--- /dev/null
+++ b/win/winvnc/VNCServerService.cxx
@@ -0,0 +1,52 @@
+/* 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.
+ */
+
+// -=- WinVNC Version 4.0 Service-Mode implementation
+
+#include <winvnc/VNCServerService.h>
+#include <rfb_win32/OSVersion.h>
+
+using namespace winvnc;
+using namespace rfb;
+using namespace win32;
+
+const TCHAR* winvnc::VNCServerService::Name = _T("WinVNC4");
+
+
+VNCServerService::VNCServerService(VNCServerWin32& s)
+  : Service(Name), server(s) {
+  // - Set the service-mode logging defaults
+  //   These will be overridden by the Log option in the
+  //   registry, if present.
+  if (osVersion.isPlatformNT)
+    logParams.setParam("*:EventLog:0,Connections:EventLog:100");
+  else
+    logParams.setParam("*:file:0,Connections:file:100");
+}
+
+
+DWORD VNCServerService::serviceMain(int argc, TCHAR* argv[]) {
+  setStatus(SERVICE_RUNNING);
+  int result = server.run();
+  setStatus(SERVICE_STOP_PENDING);
+  return result;
+}
+
+void VNCServerService::stop() {
+  server.stop();
+}
diff --git a/win/winvnc/VNCServerService.h b/win/winvnc/VNCServerService.h
new file mode 100644
index 0000000..c7a76cc
--- /dev/null
+++ b/win/winvnc/VNCServerService.h
@@ -0,0 +1,41 @@
+/* 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.
+ */
+
+#ifndef __WINVNC_SERVICEMODE_H__
+#define __WINVNC_SERVICEMODE_H__
+
+#include <winvnc/VNCServerWin32.h>
+#include <rfb_win32/Service.h>
+
+namespace winvnc {
+
+  class VNCServerService : public rfb::win32::Service {
+  public:
+    VNCServerService(VNCServerWin32& s);
+
+    DWORD serviceMain(int argc, TCHAR* argv[]);
+    void stop();
+
+    static const TCHAR* Name;
+  protected:
+    VNCServerWin32& server;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx
new file mode 100644
index 0000000..3b0e1a0
--- /dev/null
+++ b/win/winvnc/VNCServerWin32.cxx
@@ -0,0 +1,333 @@
+/* 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.
+ */
+
+// -=- WinVNC Version 4.0 Main Routine
+
+#include <winvnc/VNCServerWin32.h>
+#include <winvnc/resource.h>
+#include <winvnc/STrayIcon.h>
+#include <rfb_win32/ComputerName.h>
+#include <rfb_win32/CurrentUser.h>
+#include <rfb_win32/Service.h>
+#include <rfb/SSecurityFactoryStandard.h>
+#include <rfb/Hostname.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/SFileTransferWin32.h>
+
+using namespace rfb;
+using namespace win32;
+using namespace winvnc;
+using namespace network;
+
+static LogWriter vlog("VNCServerWin32");
+
+
+const TCHAR* winvnc::VNCServerWin32::RegConfigPath = _T("Software\\TightVNC\\WinVNC4");
+
+// FIXME: Move into an .h file?
+extern const UINT VNCM_FT_DOWNLOAD;
+
+
+static IntParameter http_port("HTTPPortNumber",
+  "TCP/IP port on which the server will serve the Java applet VNC Viewer ", 5800);
+static IntParameter port_number("PortNumber",
+  "TCP/IP port on which the server will accept connections", 5900);
+static StringParameter hosts("Hosts",
+  "Filter describing which hosts are allowed access to this server", "+0.0.0.0/0.0.0.0");
+static BoolParameter localHost("LocalHost",
+  "Only accept connections from via the local loop-back network interface", false);
+static BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn",
+  "Only prompt for a local user to accept incoming connections if there is a user logged on", false);
+
+
+VNCServerWin32::VNCServerWin32()
+  : command(NoCommand), commandSig(commandLock),
+    commandEvent(CreateEvent(0, TRUE, FALSE, 0)),
+    vncServer(CStr(ComputerName().buf), &desktop),
+    hostThread(0), runServer(false), isDesktopStarted(false),
+    httpServer(&vncServer), config(&sockMgr), trayIcon(0),
+    rfbSock(&sockMgr), httpSock(&sockMgr),
+    queryConnectDialog(0)
+{
+  // Initialise the desktop
+  desktop.setStatusLocation(&isDesktopStarted);
+
+  // Initialise the VNC server
+  vncServer.setQueryConnectionHandler(this);
+
+  // Register the desktop's event to be handled
+  sockMgr.addEvent(desktop.getUpdateEvent(), &desktop);
+
+  // Register the queued command event to be handled
+  sockMgr.addEvent(commandEvent, this);
+
+  vncServer.setFTManager((rfb::SFileTransferManager *)&m_FTManager);
+}
+
+VNCServerWin32::~VNCServerWin32() {
+  delete trayIcon;
+
+  // Stop the SDisplay from updating our state
+  desktop.setStatusLocation(0);
+
+  // Join the Accept/Reject dialog thread
+  if (queryConnectDialog)
+    delete queryConnectDialog->join();
+}
+
+
+void VNCServerWin32::processAddressChange(network::SocketListener* sock_) {
+  if (!trayIcon || (sock_ != rfbSock.sock))
+    return;
+
+  // Tool-tip prefix depends on server mode
+  const TCHAR* prefix = _T("VNC Server (User):");
+  if (isServiceProcess())
+    prefix = _T("VNC Server (Service):");
+
+  // Fetch the list of addresses
+  std::list<char*> addrs;
+  if (rfbSock.sock)
+    rfbSock.sock->getMyAddresses(&addrs);
+  else
+    addrs.push_front(strDup("Not accepting connections"));
+
+  // Allocate space for the new tip
+  std::list<char*>::iterator i, next_i;
+  int length = _tcslen(prefix)+1;
+  for (i=addrs.begin(); i!= addrs.end(); i++)
+    length += strlen(*i) + 1;
+
+  // Build the new tip
+  TCharArray toolTip(length);
+  _tcscpy(toolTip.buf, prefix);
+  for (i=addrs.begin(); i!= addrs.end(); i=next_i) {
+    next_i = i; next_i ++;
+    TCharArray addr = *i;    // Assumes ownership of string
+    _tcscat(toolTip.buf, addr.buf);
+    if (next_i != addrs.end())
+      _tcscat(toolTip.buf, _T(","));
+  }
+  
+  // Pass the new tip to the tray icon
+  vlog.info("Refreshing tray icon");
+  trayIcon->setToolTip(toolTip.buf);
+}
+
+void VNCServerWin32::regConfigChanged() {
+  // -=- Make sure we're listening on the right ports.
+  rfbSock.setServer(&vncServer);
+  rfbSock.setPort(port_number, localHost);
+  httpSock.setServer(&httpServer);
+  httpSock.setPort(http_port, localHost);
+
+  // -=- Update the Java viewer's web page port number.
+  httpServer.setRFBport(rfbSock.sock ? port_number : 0);
+
+  // -=- Update the TCP address filter for both ports, if open.
+  CharArray pattern(hosts.getData());
+  rfbSock.setFilter(pattern.buf);
+  httpSock.setFilter(pattern.buf);
+
+  // -=- Update the tray icon tooltip text with IP addresses
+  processAddressChange(rfbSock.sock);
+}
+
+
+int VNCServerWin32::run() {
+  { Lock l(runLock);
+    hostThread = Thread::self();
+    runServer = true;
+  }
+
+  // - Create the tray icon (if possible)
+  trayIcon = new STrayIconThread(*this, IDI_ICON, IDI_CONNECTED,
+                                 IDI_ICON_DISABLE, IDI_CONNECTED_DISABLE,
+                                 IDR_TRAY);
+
+  // - Register for notification of configuration changes
+  config.setCallback(this);
+  if (isServiceProcess())
+    config.setKey(HKEY_LOCAL_MACHINE, RegConfigPath);
+  else
+    config.setKey(HKEY_CURRENT_USER, RegConfigPath);
+
+  // - Set the address-changed handler for the RFB socket
+  rfbSock.setAddressChangeNotifier(this);
+
+  DWORD result = 0;
+  try {
+    vlog.debug("Entering message loop");
+
+    // - Run the server until we're told to quit
+    MSG msg;
+    int result = 0;
+    while (runServer) {
+      result = sockMgr.getMessage(&msg, NULL, 0, 0);
+      if (result < 0)
+        throw rdr::SystemException("getMessage", GetLastError());
+      if (!isServiceProcess() && (result == 0))
+        break;
+      if (msg.message == VNCM_FT_DOWNLOAD)
+        m_FTManager.processDownloadMsg(msg);
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+
+    vlog.debug("Server exited cleanly");
+  } catch (rdr::SystemException &s) {
+    vlog.error(s.str());
+    result = s.err;
+  } catch (rdr::Exception &e) {
+    vlog.error(e.str());
+  }
+
+  { Lock l(runLock);
+    runServer = false;
+    hostThread = 0;
+  }
+
+  return result;
+}
+
+void VNCServerWin32::stop() {
+  Lock l(runLock);
+  runServer = false;
+  if (hostThread)
+    PostThreadMessage(hostThread->getThreadId(), WM_QUIT, 0, 0);
+}
+
+
+bool VNCServerWin32::disconnectClients(const char* reason) {
+  return queueCommand(DisconnectClients, reason, 0);
+}
+
+bool VNCServerWin32::addNewClient(const char* client) {
+  TcpSocket* sock = 0;
+  try {
+    CharArray hostname;
+    int port;
+    getHostAndPort(client, &hostname.buf, &port, 5500);
+    vlog.error("port=%d", port);
+    sock = new TcpSocket(hostname.buf, port);
+    if (queueCommand(AddClient, sock, 0))
+      return true;
+    delete sock;
+  } catch (...) {
+    delete sock;
+  }
+  return false;
+}
+
+bool VNCServerWin32::getClientsInfo(rfb::ListConnInfo* LCInfo) {
+  return queueCommand(GetClientsInfo, LCInfo, 0);
+}
+
+bool VNCServerWin32::setClientsStatus(rfb::ListConnInfo* LCInfo) {
+  return queueCommand(SetClientsStatus, LCInfo, 0);
+}
+
+VNCServerST::queryResult VNCServerWin32::queryConnection(network::Socket* sock,
+                                            const char* userName,
+                                            char** reason)
+{
+  if (queryOnlyIfLoggedOn && CurrentUserToken().noUserLoggedOn())
+    return VNCServerST::ACCEPT;
+  if (queryConnectDialog) {
+    *reason = rfb::strDup("Another connection is currently being queried.");
+    return VNCServerST::REJECT;
+  }
+  queryConnectDialog = new QueryConnectDialog(sock, userName, this);
+  queryConnectDialog->startDialog();
+  return VNCServerST::PENDING;
+}
+
+void VNCServerWin32::queryConnectionComplete() {
+  queueCommand(QueryConnectionComplete, 0, 0, false);
+}
+
+
+bool VNCServerWin32::queueCommand(Command cmd, const void* data, int len, bool wait) {
+  Lock l(commandLock);
+  while (command != NoCommand)
+    commandSig.wait();
+  command = cmd;
+  commandData = data;
+  commandDataLen = len;
+  SetEvent(commandEvent);
+  if (wait) {
+    while (command != NoCommand)
+      commandSig.wait();
+    commandSig.signal();
+  }
+  return true;
+}
+
+void VNCServerWin32::processEvent(HANDLE event_) {
+  ResetEvent(event_);
+
+  if (event_ == commandEvent.h) {
+    // If there is no command queued then return immediately
+    {
+      Lock l(commandLock);
+      if (command == NoCommand)
+        return;
+    }
+
+    // Perform the required command
+    switch (command) {
+
+    case DisconnectClients:
+      // Disconnect all currently active VNC Viewers
+      vncServer.closeClients((const char*)commandData);
+      break;
+
+    case AddClient:
+      // Make a reverse connection to a VNC Viewer
+      sockMgr.addSocket((network::Socket*)commandData, &vncServer);
+      break;
+  case GetClientsInfo:
+    vncServer.getConnInfo((ListConnInfo*)commandData); 
+    break;
+  case SetClientsStatus:
+    vncServer.setConnStatus((ListConnInfo*)commandData); 
+    break;
+
+    case QueryConnectionComplete:
+      // The Accept/Reject dialog has completed
+      // Get the result, then clean it up
+      vncServer.approveConnection(queryConnectDialog->getSock(),
+                                  queryConnectDialog->isAccepted(),
+                                  "Connection rejected by user");
+      delete queryConnectDialog->join();
+      queryConnectDialog = 0;
+      break;
+
+    default:
+      vlog.error("unknown command %d queued", command);
+    };
+
+    // Clear the command and signal completion
+    {
+      Lock l(commandLock);
+      command = NoCommand;
+      commandSig.signal();
+    }
+  }
+}
+
diff --git a/win/winvnc/VNCServerWin32.h b/win/winvnc/VNCServerWin32.h
new file mode 100644
index 0000000..579a6a0
--- /dev/null
+++ b/win/winvnc/VNCServerWin32.h
@@ -0,0 +1,130 @@
+/* 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.
+ */
+
+#ifndef __VNCSERVER_WIN32_H__
+#define __VNCSERVER_WIN32_H__
+
+#include <winsock2.h>
+#include <network/TcpSocket.h>
+#include <rfb/VNCServerST.h>
+#include <rfb_win32/RegConfig.h>
+#include <rfb_win32/SDisplay.h>
+#include <rfb_win32/SocketManager.h>
+#include <rfb_win32/TCharArray.h>
+#include <rfb_win32/SFileTransferManagerWin32.h>
+#include <winvnc/QueryConnectDialog.h>
+#include <winvnc/JavaViewer.h>
+#include <winvnc/ManagedListener.h>
+
+namespace winvnc {
+
+  class STrayIconThread;
+
+  class VNCServerWin32 : rfb::VNCServerST::QueryConnectionHandler,
+                         rfb::win32::SocketManager::AddressChangeNotifier,
+                         rfb::win32::RegConfig::Callback,
+                         rfb::win32::EventHandler {
+  public:
+    VNCServerWin32();
+    virtual ~VNCServerWin32();
+
+    // Run the server in the current thread
+    int run();
+
+    // Cause the run() call to return
+    // THREAD-SAFE
+    void stop();
+
+    // Determine whether a viewer is active
+    // THREAD-SAFE
+    bool isServerInUse() const {return isDesktopStarted;}
+
+    // Connect out to the specified VNC Viewer
+    // THREAD-SAFE
+    bool addNewClient(const char* client);
+
+    // Disconnect all connected clients
+    // THREAD-SAFE
+    bool disconnectClients(const char* reason=0);
+
+    // Call used to notify VNCServerST of user accept/reject query completion
+    // CALLED FROM AcceptConnectDialog THREAD
+    void queryConnectionComplete();
+
+    // Where to read the configuration settings from
+    static const TCHAR* RegConfigPath;
+
+    bool getClientsInfo(rfb::ListConnInfo* LCInfo);
+
+    bool setClientsStatus(rfb::ListConnInfo* LCInfo);
+
+  protected:
+    // VNCServerST::QueryConnectionHandler interface
+    // Callback used to prompt user to accept or reject a connection.
+    // CALLBACK IN VNCServerST "HOST" THREAD
+    virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
+                                                          const char* userName,
+                                                          char** reason);
+
+    // SocketManager::AddressChangeNotifier interface
+    // Used to keep tray icon up to date
+    virtual void processAddressChange(network::SocketListener* sl);
+
+    // RegConfig::Callback interface
+    // Called via the EventManager whenver RegConfig sees the registry change
+    virtual void regConfigChanged();
+
+    // EventHandler interface
+    // Used to perform queued commands
+    virtual void processEvent(HANDLE event);
+
+  protected:
+    // Perform a particular internal function in the server thread
+    typedef enum {NoCommand, DisconnectClients, AddClient, QueryConnectionComplete, SetClientsStatus, GetClientsInfo} Command;
+    bool queueCommand(Command cmd, const void* data, int len, bool wait=true);
+    Command command;
+    const void* commandData;
+    int commandDataLen;
+    rfb::Mutex commandLock;
+    rfb::Condition commandSig;
+    rfb::win32::Handle commandEvent;
+
+    // VNCServerWin32 Server-internal state
+    rfb::win32::SDisplay desktop;
+    rfb::VNCServerST vncServer;
+    rfb::Mutex runLock;
+    rfb::Thread* hostThread;
+    bool runServer;
+    bool isDesktopStarted;
+    JavaViewerServer httpServer;
+    rfb::win32::SocketManager sockMgr;
+    rfb::win32::RegConfig config;
+
+    ManagedListener rfbSock;
+    ManagedListener httpSock;
+    STrayIconThread* trayIcon;
+
+    //rfb::SSecurityFactoryStandard securityFactory;
+
+    QueryConnectDialog* queryConnectDialog;
+    rfb::win32::SFileTransferManagerWin32 m_FTManager;
+  };
+
+};
+
+#endif
diff --git a/win/winvnc/buildTime.cxx b/win/winvnc/buildTime.cxx
new file mode 100644
index 0000000..9f37b38
--- /dev/null
+++ b/win/winvnc/buildTime.cxx
@@ -0,0 +1,18 @@
+/* Copyright (C) 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.
+ */
+const char* buildTime = "Built on " __DATE__ " at " __TIME__;
diff --git a/win/winvnc/connecte.ico b/win/winvnc/connecte.ico
new file mode 100644
index 0000000..8f814b3
--- /dev/null
+++ b/win/winvnc/connecte.ico
Binary files differ
diff --git a/win/winvnc/connected.ico b/win/winvnc/connected.ico
new file mode 100644
index 0000000..44ce3c9
--- /dev/null
+++ b/win/winvnc/connected.ico
Binary files differ
diff --git a/win/winvnc/icon_dis.ico b/win/winvnc/icon_dis.ico
new file mode 100644
index 0000000..0a6ea15
--- /dev/null
+++ b/win/winvnc/icon_dis.ico
Binary files differ
diff --git a/win/winvnc/resource.h b/win/winvnc/resource.h
new file mode 100644
index 0000000..68316be
--- /dev/null
+++ b/win/winvnc/resource.h
@@ -0,0 +1,54 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by winvnc.rc
+//
+#define IDR_MANIFEST                    1
+#define IDI_ICON                        101
+#define IDR_TRAY                        102
+#define IDD_DIALOG1                     103
+#define IDD_ABOUT                       104
+#define IDI_CONNECTED                   105
+#define IDR_VNCVIEWER_JAR               106
+#define IDD_QUERY_CONNECT               107
+#define IDD_ADD_NEW_CLIENT              108
+#define IDB_BITMAP                      109
+#define IDD_CONTROL_PANEL               110
+#define IDI_ICON_DISABLE                111
+#define IDI_CONNECTED_DISABLE           112
+#define IDC_DESCRIPTION                 1000
+#define IDC_BUILDTIME                   1001
+#define IDC_VERSION                     1002
+#define IDC_COPYRIGHT                   1003
+#define IDC_QUERY_COUNTDOWN             1008
+#define IDC_QUERY_USER                  1009
+#define IDC_QUERY_HOST                  1010
+#define IDC_HOST                        1011
+#define IDC_LIST_CONNECTIONS            1012
+#define IDC_STATIC_KLIENTS_LIST         1013
+#define IDC_STATIC_SELECTED_KLIENTS     1014
+#define IDC_VIEW_ONLY                   1015
+#define IDC_FULL_CONTROL                1016
+#define IDC_STOP_UPDATE                 1017
+#define IDC_KILL_SEL_CLIENT             1018
+#define IDC_PROPERTIES                  1019
+#define IDC_ADD_CLIENT                  1020
+#define IDC_KILL_ALL                    1021
+#define IDC_DISABLE_CLIENTS             1022
+#define ID_CONTR0L_PANEL                40001
+#define ID_CLOSE                        40002
+#define ID_ABOUT                        40003
+#define ID_DISCONNECT                   40004
+#define ID_CONNECT                      40005
+#define ID_OPTIONS                      40006
+#define ID_DISABLE_NEW_CLIENTS          40007
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        113
+#define _APS_NEXT_COMMAND_VALUE         40008
+#define _APS_NEXT_CONTROL_VALUE         1023
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/win/winvnc/winvnc.bmp b/win/winvnc/winvnc.bmp
new file mode 100644
index 0000000..90c02f8
--- /dev/null
+++ b/win/winvnc/winvnc.bmp
Binary files differ
diff --git a/win/winvnc/winvnc.cxx b/win/winvnc/winvnc.cxx
new file mode 100644
index 0000000..2d01f89
--- /dev/null
+++ b/win/winvnc/winvnc.cxx
@@ -0,0 +1,262 @@
+/* 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>
+#ifdef WIN32
+#define strcasecmp _stricmp
+#endif
+
+#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("VNC Server");
+
+
+static bool runAsService = false;
+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();
+}
+
+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(msg);
+        return;
+      } catch (...) {
+      }
+    }
+    fprintf(stderr, "%s\n", msg);
+  }
+}
+
+static void processParams(int argc, const 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)&copyData))
+            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)&copyData))
+          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;
+        DWORD state = rfb::win32::getServiceState(VNCServerService::Name);
+        CharArray stateStr(rfb::win32::serviceStateName(state));
+        const char* stateMsg = "The %s Service is in the %s state.";
+        CharArray result(strlen(stateStr.buf) + _tcslen(VNCServerService::Name) + strlen(stateMsg) + 1);
+        sprintf(result.buf, stateMsg, (const char*)CStr(VNCServerService::Name), stateStr.buf);
+        MsgBoxOrLog(result.buf);
+      } else if (strcasecmp(argv[i], "-service") == 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;
+        if (rfb::win32::registerService(VNCServerService::Name,
+                                        _T("VNC Server Version 4"),
+                                        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:%u", 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 main(int argc, const char* argv[]) {
+  int result = 0;
+
+  try {
+    // - Initialise the available loggers
+    //freopen("\\\\drupe\\tjr\\WinVNC4.log","ab",stderr);
+    //setbuf(stderr, 0);
+    initStdIOLoggers();
+    initFileLogger("C:\\temp\\WinVNC4.log");
+    rfb::win32::initEventLogLogger(VNCServerService::Name);
+
+    // - By default, just log errors to stderr
+    logParams.setParam("*:stderr:0");
+
+    // - Print program details and process the command line
+    programInfo();
+    processParams(argc, argv);
+
+    // - Run the server if required
+    if (runServer) {
+      // Start the network subsystem and run the server
+      VNCServerWin32 server;
+
+      if (runAsService) {
+        printf("Starting Service-Mode VNC Server.\n");
+        VNCServerService service(server);
+        service.start();
+        result = service.getStatus().dwWin32ExitCode;
+      } else {
+        printf("Starting User-Mode VNC Server.\n");
+        result = server.run();
+      }
+    }
+
+    vlog.debug("WinVNC service destroyed");
+  } catch (rdr::Exception& e) {
+    MsgBoxOrLog(e.str(), true);
+  }
+
+  vlog.debug("WinVNC process quitting");
+  return result;
+}
diff --git a/win/winvnc/winvnc.dsp b/win/winvnc/winvnc.dsp
new file mode 100644
index 0000000..ec76f3f
--- /dev/null
+++ b/win/winvnc/winvnc.dsp
@@ -0,0 +1,252 @@
+# Microsoft Developer Studio Project File - Name="winvnc" - Package Owner=<4>

+# Microsoft Developer Studio Generated Build File, Format Version 6.00

+# ** DO NOT EDIT **

+

+# TARGTYPE "Win32 (x86) Console Application" 0x0103

+

+CFG=winvnc - Win32 Debug Unicode

+!MESSAGE This is not a valid makefile. To build this project using NMAKE,

+!MESSAGE use the Export Makefile command and run

+!MESSAGE 

+!MESSAGE NMAKE /f "winvnc.mak".

+!MESSAGE 

+!MESSAGE You can specify a configuration when running NMAKE

+!MESSAGE by defining the macro CFG on the command line. For example:

+!MESSAGE 

+!MESSAGE NMAKE /f "winvnc.mak" CFG="winvnc - Win32 Debug Unicode"

+!MESSAGE 

+!MESSAGE Possible choices for configuration are:

+!MESSAGE 

+!MESSAGE "winvnc - Win32 Release" (based on "Win32 (x86) Console Application")

+!MESSAGE "winvnc - Win32 Debug" (based on "Win32 (x86) Console Application")

+!MESSAGE "winvnc - Win32 Debug Unicode" (based on "Win32 (x86) Console Application")

+!MESSAGE 

+

+# Begin Project

+# PROP AllowPerConfigDependencies 0

+# PROP Scc_ProjName ""

+# PROP Scc_LocalPath ""

+CPP=cl.exe

+RSC=rc.exe

+

+!IF  "$(CFG)" == "winvnc - Win32 Release"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 0

+# PROP BASE Output_Dir "Release"

+# PROP BASE Intermediate_Dir "Release"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 0

+# PROP Output_Dir "..\Release"

+# PROP Intermediate_Dir "..\Release\winvnc"

+# PROP Ignore_Export_Lib 0

+# PROP Target_Dir ""

+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c

+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../../common" /FI"rdr/msvcwarning.h" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /FR /YX /FD /c

+# ADD BASE RSC /l 0x809 /d "NDEBUG"

+# ADD RSC /l 0x809 /d "NDEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

+# ADD LINK32 advapi32.lib user32.lib gdi32.lib ws2_32.lib version.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:console /machine:I386 /out:"../Release/winvnc4.exe"

+# SUBTRACT LINK32 /profile

+# Begin Special Build Tool

+SOURCE="$(InputPath)"

+PreLink_Desc=Updating buildTime

+PreLink_Cmds=cl /c /nologo /Fo..\Release\ /Fd..\Release\winvnc /MT buildTime.cxx

+# End Special Build Tool

+

+!ELSEIF  "$(CFG)" == "winvnc - Win32 Debug"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 1

+# PROP BASE Output_Dir "Debug"

+# PROP BASE Intermediate_Dir "Debug"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 1

+# PROP Output_Dir "..\Debug"

+# PROP Intermediate_Dir "..\Debug\winvnc"

+# PROP Ignore_Export_Lib 0

+# PROP Target_Dir ""

+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c

+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../../common" /FI"rdr/msvcwarning.h" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c

+# ADD BASE RSC /l 0x809 /d "_DEBUG"

+# ADD RSC /l 0x809 /d "_DEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept

+# ADD LINK32 advapi32.lib user32.lib gdi32.lib ws2_32.lib version.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../Debug/winvnc4.exe" /fixed:no

+# SUBTRACT LINK32 /profile

+# Begin Special Build Tool

+SOURCE="$(InputPath)"

+PreLink_Desc=Updating buildTime

+PreLink_Cmds=cl /c /nologo /Fo..\Debug\ /Fd..\Debug\winvnc /MTd buildTime.cxx

+# End Special Build Tool

+

+!ELSEIF  "$(CFG)" == "winvnc - Win32 Debug Unicode"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 1

+# PROP BASE Output_Dir "winvnc___Win32_Debug_Unicode"

+# PROP BASE Intermediate_Dir "winvnc___Win32_Debug_Unicode"

+# PROP BASE Ignore_Export_Lib 0

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 1

+# PROP Output_Dir "..\Debug_Unicode"

+# PROP Intermediate_Dir "..\Debug_Unicode\winvnc"

+# PROP Ignore_Export_Lib 0

+# PROP Target_Dir ""

+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /FI"msvcwarning.h" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c

+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../../common" /FI"rdr/msvcwarning.h" /D "_CONSOLE" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c

+# ADD BASE RSC /l 0x809 /d "_DEBUG"

+# ADD RSC /l 0x809 /d "_DEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib ws2_32.lib version.lib comctl32.lib shell32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../Debug/winvnc4.exe" /fixed:no

+# SUBTRACT BASE LINK32 /pdb:none

+# ADD LINK32 advapi32.lib user32.lib gdi32.lib ws2_32.lib version.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\Debug_Unicode/winvnc4.exe" /fixed:no

+# SUBTRACT LINK32 /pdb:none

+# Begin Special Build Tool

+SOURCE="$(InputPath)"

+PreLink_Desc=Updating buildTime

+PreLink_Cmds=cl /c /nologo /Fo..\Debug_Unicode /Fd..\Debug_Unicode\winvnc /MTd buildTime.cxx

+# End Special Build Tool

+

+!ENDIF 

+

+# Begin Target

+

+# Name "winvnc - Win32 Release"

+# Name "winvnc - Win32 Debug"

+# Name "winvnc - Win32 Debug Unicode"

+# Begin Group "Source Files"

+

+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+# Begin Source File

+

+SOURCE=.\buildTime.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\ControlPanel.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\JavaViewer.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\ManagedListener.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\QueryConnectDialog.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\STrayIcon.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\VNCServerService.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\VNCServerWin32.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\winvnc.cxx

+# End Source File

+# Begin Source File

+

+SOURCE=.\winvnc.rc

+# End Source File

+# End Group

+# Begin Group "Header Files"

+

+# PROP Default_Filter "h;hpp;hxx;hm;inl"

+# Begin Source File

+

+SOURCE=.\AddNewClientDialog.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\ControlPanel.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\JavaViewer.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\ManagedListener.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\QueryConnectDialog.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\STrayIcon.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\VNCServerService.h

+# End Source File

+# Begin Source File

+

+SOURCE=.\VNCServerWin32.h

+# End Source File

+# End Group

+# Begin Group "Resource Files"

+

+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+# Begin Source File

+

+SOURCE=.\connecte.ico

+# End Source File

+# Begin Source File

+

+SOURCE=.\connected.ico

+# End Source File

+# Begin Source File

+

+SOURCE=.\icon_dis.ico

+# End Source File

+# Begin Source File

+

+SOURCE=..\..\common\javabin\logo150x150.gif

+# End Source File

+# Begin Source File

+

+SOURCE=.\winvnc.bmp

+# End Source File

+# Begin Source File

+

+SOURCE=.\winvnc.ico

+# End Source File

+# End Group

+# Begin Source File

+

+SOURCE=..\..\common\javabin\index.vnc

+# End Source File

+# Begin Source File

+

+SOURCE=..\..\common\javabin\vncviewer.jar

+# End Source File

+# Begin Source File

+

+SOURCE=.\winvnc4.exe.manifest

+# End Source File

+# End Target

+# End Project

diff --git a/win/winvnc/winvnc.ico b/win/winvnc/winvnc.ico
new file mode 100644
index 0000000..1b42416
--- /dev/null
+++ b/win/winvnc/winvnc.ico
Binary files differ
diff --git a/win/winvnc/winvnc.rc b/win/winvnc/winvnc.rc
new file mode 100644
index 0000000..143b0d6
--- /dev/null
+++ b/win/winvnc/winvnc.rc
@@ -0,0 +1,328 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,1,1,0
+ PRODUCTVERSION 4,1,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "080904b0"
+        BEGIN
+            VALUE "Comments", "\0"
+            VALUE "CompanyName", "Constantin Kaplinsky\0"
+            VALUE "FileDescription", "TightVNC Server for Win32\0"
+            VALUE "FileVersion", "4.1.1\0"
+            VALUE "InternalName", "winvnc\0"
+            VALUE "LegalCopyright", "Copyright (C) 1998-2005 [many holders]\0"
+            VALUE "LegalTrademarks", "TightVNC\0"
+            VALUE "OriginalFilename", "winvnc4.exe\0"
+            VALUE "PrivateBuild", "\0"
+            VALUE "ProductName", "TightVNC Server\0"
+            VALUE "ProductVersion", "4.1.1\0"
+            VALUE "SpecialBuild", "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x809, 1200
+    END
+END
+
+#endif    // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON                ICON    DISCARDABLE     "winvnc.ico"
+IDI_CONNECTED           ICON    DISCARDABLE     "connected.ico"
+IDI_ICON_DISABLE        ICON    DISCARDABLE     "icon_dis.ico"
+IDI_CONNECTED_DISABLE   ICON    DISCARDABLE     "connecte.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_TRAY MENU DISCARDABLE 
+BEGIN
+    POPUP "Tray Menu"
+    BEGIN
+        MENUITEM "Control &Panel",              ID_CONTR0L_PANEL
+        MENUITEM SEPARATOR
+        MENUITEM "&Options...",                 ID_OPTIONS
+        MENUITEM "Add &New Client...",          ID_CONNECT
+        MENUITEM "&Disconnect Clients",         ID_DISCONNECT
+        MENUITEM "D&isable New Clients",        ID_DISABLE_NEW_CLIENTS
+        MENUITEM SEPARATOR
+        MENUITEM "&Close VNC Server",           ID_CLOSE
+        MENUITEM "&About...",                   ID_ABOUT
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUT DIALOG DISCARDABLE  0, 0, 249, 92
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "About VNC Server for Windows"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,195,70,47,15
+    CONTROL         109,IDC_STATIC,"Static",SS_BITMAP,5,10,33,31
+    LTEXT           ">appname<",IDC_DESCRIPTION,45,10,125,15
+    LTEXT           ">version<",IDC_VERSION,170,10,72,15
+    LTEXT           ">buildtime<",IDC_BUILDTIME,45,25,202,15
+    LTEXT           ">copyright<",IDC_COPYRIGHT,45,40,202,15
+    LTEXT           "See http://www.tightvnc.com for more information on VNC.",
+                    IDC_STATIC,45,55,202,15
+END
+
+IDD_QUERY_CONNECT DIALOG DISCARDABLE  0, 0, 164, 93
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "VNC Server : Accept Connection?"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "&Reject",IDCANCEL,105,72,52,14
+    PUSHBUTTON      "&Accept",IDOK,7,72,53,14
+    RTEXT           "User:",IDC_STATIC,7,10,28,15,SS_CENTERIMAGE
+    RTEXT           "Host:",IDC_STATIC,7,30,28,15,SS_CENTERIMAGE
+    CTEXT           "Seconds until automatic reject:",IDC_STATIC,7,50,113,15,
+                    SS_CENTERIMAGE
+    LTEXT           "-",IDC_QUERY_COUNTDOWN,125,50,32,15,SS_CENTERIMAGE
+    LTEXT           "-",IDC_QUERY_USER,40,10,117,15,SS_CENTERIMAGE
+    LTEXT           "-",IDC_QUERY_HOST,40,30,117,15,SS_CENTERIMAGE
+END
+
+IDD_ADD_NEW_CLIENT DIALOG DISCARDABLE  0, 0, 177, 52
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | 
+    WS_CAPTION | WS_SYSMENU
+CAPTION "VNC Server : Add New Client"
+FONT 8, "MS Sans Serif"
+BEGIN
+    EDITTEXT        IDC_HOST,80,10,90,15,ES_AUTOHSCROLL
+    DEFPUSHBUTTON   "OK",IDOK,80,31,40,14
+    PUSHBUTTON      "Cancel",IDCANCEL,125,31,45,14
+    CONTROL         109,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE,7,
+                    10,33,31
+    RTEXT           "Viewer:",IDC_STATIC,45,10,30,15,SS_CENTERIMAGE
+END
+
+IDD_CONTROL_PANEL DIALOG DISCARDABLE  0, 0, 267, 238
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | DS_CONTEXTHELP | 
+    WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Control Panel"
+FONT 8, "MS Sans Serif"
+BEGIN
+    CONTROL         "List1",IDC_LIST_CONNECTIONS,"SysListView32",LVS_REPORT | 
+                    LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | 
+                    WS_BORDER | WS_TABSTOP,7,25,253,76
+    LTEXT           "Authorised clients list",IDC_STATIC_KLIENTS_LIST,87,7,
+                    74,11,SS_CENTERIMAGE
+    GROUPBOX        "Control of selected clients",
+                    IDC_STATIC_SELECTED_KLIENTS,7,108,124,103
+    PUSHBUTTON      "View-only",IDC_VIEW_ONLY,13,121,111,14
+    PUSHBUTTON      "Full control ",IDC_FULL_CONTROL,13,145,112,14
+    PUSHBUTTON      "Stop updating",IDC_STOP_UPDATE,13,167,111,14
+    PUSHBUTTON      "Kill Clients",IDC_KILL_SEL_CLIENT,13,190,111,14
+    PUSHBUTTON      "Properties",IDC_PROPERTIES,144,121,111,14
+    PUSHBUTTON      "Add New Client",IDC_ADD_CLIENT,144,145,111,14
+    PUSHBUTTON      "Kill All Clients",IDC_KILL_ALL,144,167,111,14
+    CONTROL         "Disable New Clients",IDC_DISABLE_CLIENTS,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,144,191,111,13
+    PUSHBUTTON      "Close",IDCANCEL,144,217,111,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// HTTPFILE
+//
+
+/VNCVIEWER.JAR          HTTPFILE DISCARDABLE    "..\\..\\common\\javabin\\vncviewer.jar"
+/LOGO150X150.GIF        HTTPFILE DISCARDABLE    "..\\..\\common\\javabin\\logo150x150.gif"
+/INDEX.VNC              HTTPFILE DISCARDABLE    "..\\..\\common\\javabin\\index.vnc"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 24
+//
+
+IDR_MANIFEST            24      DISCARDABLE     "winvnc4.exe.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_ABOUT, DIALOG
+    BEGIN
+        LEFTMARGIN, 5
+        VERTGUIDE, 45
+        VERTGUIDE, 170
+        VERTGUIDE, 195
+        VERTGUIDE, 242
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 85
+        HORZGUIDE, 10
+        HORZGUIDE, 25
+        HORZGUIDE, 40
+        HORZGUIDE, 55
+        HORZGUIDE, 70
+    END
+
+    IDD_QUERY_CONNECT, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 157
+        VERTGUIDE, 35
+        VERTGUIDE, 40
+        VERTGUIDE, 60
+        VERTGUIDE, 120
+        VERTGUIDE, 125
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 86
+        HORZGUIDE, 10
+        HORZGUIDE, 25
+        HORZGUIDE, 30
+        HORZGUIDE, 45
+        HORZGUIDE, 50
+        HORZGUIDE, 65
+    END
+
+    IDD_ADD_NEW_CLIENT, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 170
+        VERTGUIDE, 45
+        VERTGUIDE, 75
+        VERTGUIDE, 80
+        VERTGUIDE, 120
+        VERTGUIDE, 125
+        VERTGUIDE, 170
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 45
+        HORZGUIDE, 10
+        HORZGUIDE, 25
+        HORZGUIDE, 30
+        HORZGUIDE, 45
+    END
+
+    IDD_CONTROL_PANEL, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 260
+        VERTGUIDE, 13
+        VERTGUIDE, 124
+        VERTGUIDE, 144
+        VERTGUIDE, 255
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 231
+        HORZGUIDE, 121
+        HORZGUIDE, 135
+        HORZGUIDE, 145
+        HORZGUIDE, 159
+        HORZGUIDE, 181
+        HORZGUIDE, 191
+        HORZGUIDE, 204
+        HORZGUIDE, 217
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP              BITMAP  DISCARDABLE     "winvnc.bmp"
+#endif    // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/win/winvnc/winvnc4.exe.manifest b/win/winvnc/winvnc4.exe.manifest
new file mode 100644
index 0000000..69be5a0
--- /dev/null
+++ b/win/winvnc/winvnc4.exe.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+   version="4.0.0.26"
+   processorArchitecture="X86"
+   name="TightVNC.winvnc4.exe"
+   type="win32"
+/>
+<description>.NET control deployment tool</description>
+<dependency>
+   <dependentAssembly>
+     <assemblyIdentity
+       type="win32"
+       name="Microsoft.Windows.Common-Controls"
+       version="6.0.0.0"
+       processorArchitecture="X86"
+       publicKeyToken="6595b64144ccf1df"
+       language="*"
+     />
+   </dependentAssembly>
+</dependency>
+</assembly>