diff --git a/winvnc/VNCServerWin32.cxx b/winvnc/VNCServerWin32.cxx
index 67b3ec5..8d681c2 100644
--- a/winvnc/VNCServerWin32.cxx
+++ b/winvnc/VNCServerWin32.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* 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
@@ -21,8 +21,8 @@
 #include <winvnc/VNCServerWin32.h>
 #include <winvnc/resource.h>
 #include <winvnc/STrayIcon.h>
-
-#include <rfb_win32/Win32Util.h>
+#include <rfb_win32/ComputerName.h>
+#include <rfb_win32/CurrentUser.h>
 #include <rfb_win32/Service.h>
 #include <rfb/SSecurityFactoryStandard.h>
 #include <rfb/Hostname.h>
@@ -38,90 +38,28 @@
 
 const TCHAR* winvnc::VNCServerWin32::RegConfigPath = _T("Software\\TightVNC\\WinVNC4");
 
-const UINT VNCM_REG_CHANGED = WM_USER;
-const UINT VNCM_COMMAND = WM_USER + 1;
-
 
 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", "+");
-static VncAuthPasswdConfigParameter vncAuthPasswd;
+  "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);
-
-
-// -=- ManagedListener
-//     Wrapper class which simplifies the management of a listening socket
-//     on a specified port, attached to a SocketManager and SocketServer.
-//     Ensures that socket and filter are deleted and updated appropriately.
-
-class ManagedListener {
-public:
-  ManagedListener(win32::SocketManager* mgr, SocketServer* svr)
-    : sock(0), filter(0), port(0), manager(mgr),
-      server(svr), localOnly(0) {}
-  ~ManagedListener() {setPort(0);}
-  void setPort(int port, bool localOnly=false);
-  void setFilter(const char* filter);
-  TcpListener* sock;
-protected:
-  TcpFilter* filter;
-  win32::SocketManager* manager;
-  SocketServer* server;
-  int port;
-  bool localOnly;
-};
-
-// - If the port number/localHost setting has changed then tell the
-//   SocketManager to shutdown and delete it.  Also remove &
-//   delete the filter.  Then try to open a socket on the new port.
-void ManagedListener::setPort(int newPort, bool newLocalOnly) {
-  if ((port == newPort) && (localOnly == newLocalOnly) && sock) return;
-  if (sock) {
-    vlog.info("Closed TcpListener on port %d", port);
-    sock->setFilter(0);
-    delete filter;
-    manager->remListener(sock);
-    sock = 0;
-    filter = 0;
-  }
-  port = newPort;
-  localOnly = newLocalOnly;
-  if (port != 0) {
-    try {
-      sock = new TcpListener(port, localOnly);
-      vlog.info("Created TcpListener on port %d%s", port,
-                localOnly ? "(localhost)" : "(any)");
-    } catch (rdr::Exception& e) {
-      vlog.error("TcpListener on port %d failed (%s)", port, e.str());
-    }
-  }
-  if (sock)
-    manager->addListener(sock, server);
-}
-
-void ManagedListener::setFilter(const char* newFilter) {
-  if (!sock) return;
-  vlog.info("Updating TcpListener filter");
-  sock->setFilter(0);
-  delete filter;
-  filter = new TcpFilter(newFilter);
-  sock->setFilter(filter);
-}
+static BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn",
+  "Only prompt for a local user to accept incoming connections if there is a user logged on", false);
 
 
 VNCServerWin32::VNCServerWin32()
-  : vncServer(CStr(ComputerName().buf), &desktop),
-    httpServer(0), runServer(false),
-    isDesktopStarted(false),
-    command(NoCommand), commandSig(commandLock),
-    queryConnectDialog(0) {
-  // Create the Java-viewer HTTP server
-  httpServer = new JavaViewerServer(&vncServer);
-
+  : 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);
 
@@ -130,14 +68,78 @@
 
   // 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);
 }
 
 VNCServerWin32::~VNCServerWin32() {
+  delete trayIcon;
+
   // Stop the SDisplay from updating our state
   desktop.setStatusLocation(0);
 
-  // Destroy the HTTP server
-  delete httpServer;
+  // 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);
 }
 
 
@@ -147,85 +149,37 @@
     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);
-  config.setNotifyThread(Thread::self(), VNCM_REG_CHANGED);
 
-  // - Create the tray icon if possible
-  STrayIconThread trayIcon(*this, IDI_ICON, IDI_CONNECTED, IDI_ICON_DISABLE,
-                            IDI_CONNECTED_DISABLE, IDR_TRAY);
+  // - Set the address-changed handler for the RFB socket
+  rfbSock.setAddressChangeNotifier(this);
 
   DWORD result = 0;
   try {
-    // - Create some managed listening sockets
-    ManagedListener rfb(&sockMgr, &vncServer);
-    ManagedListener http(&sockMgr, httpServer);
+    vlog.debug("Entering message loop");
 
-    // - Continue to operate until WM_QUIT is processed
+    // - Run the server until we're told to quit
     MSG msg;
-    do {
-      // -=- Make sure we're listening on the right ports.
-      rfb.setPort(port_number, localHost);
-      http.setPort(http_port, localHost);
-
-      // -=- Update the Java viewer's web page port number.
-      httpServer->setRFBport(rfb.sock ? port_number : 0);
-
-      // -=- Update the TCP address filter for both ports, if open.
-      CharArray pattern;
-      pattern.buf = hosts.getData();
-      if (!localHost) {
-        rfb.setFilter(pattern.buf);
-        http.setFilter(pattern.buf);
-      }
-
-      // - If there is a listening port then add the address to the
-      //   tray icon's tool-tip text.
-      {
-        const TCHAR* prefix = isServiceProcess() ?
-          _T("VNC Server (Service):") : _T("VNC Server (User):");
-
-        std::list<char*> addrs;
-        if (rfb.sock)
-          rfb.sock->getMyAddresses(&addrs);
-        else
-          addrs.push_front(strDup("Not accepting connections"));
-
-        std::list<char*>::iterator i, next_i;
-        int length = _tcslen(prefix)+1;
-        for (i=addrs.begin(); i!= addrs.end(); i++)
-          length += strlen(*i) + 1;
-
-        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(","));
-        }
-        trayIcon.setToolTip(toolTip.buf);
-      }
-
-      vlog.debug("Entering message loop");
-
-      // - Run the server until the registry changes, or we're told to quit
-      while (sockMgr.getMessage(&msg, NULL, 0, 0)) {
-        if (msg.hwnd == 0) {
-          if (msg.message == VNCM_REG_CHANGED)
-            break;
-          if (msg.message == VNCM_COMMAND)
-            doCommand();
-        }
-        TranslateMessage(&msg);
-        DispatchMessage(&msg);
-      }
-
-    } while ((msg.message != WM_QUIT) || runServer);
+    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;
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
 
     vlog.debug("Server exited cleanly");
   } catch (rdr::SystemException &s) {
@@ -246,7 +200,8 @@
 void VNCServerWin32::stop() {
   Lock l(runLock);
   runServer = false;
-  PostThreadMessage(hostThread->getThreadId(), WM_QUIT, 0, 0);
+  if (hostThread)
+    PostThreadMessage(hostThread->getThreadId(), WM_QUIT, 0, 0);
 }
 
 
@@ -283,6 +238,8 @@
                                             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;
@@ -293,51 +250,49 @@
 }
 
 void VNCServerWin32::queryConnectionComplete() {
-  Thread* qcd = queryConnectDialog;
-  queueCommand(QueryConnectionComplete, 0, 0);
-  delete qcd->join();
+  queueCommand(QueryConnectionComplete, 0, 0, false);
 }
 
 
-bool VNCServerWin32::queueCommand(Command cmd, const void* data, int len) {
+bool VNCServerWin32::queueCommand(Command cmd, const void* data, int len, bool wait) {
   Lock l(commandLock);
-  while (command != NoCommand) commandSig.wait();
+  while (command != NoCommand)
+    commandSig.wait();
   command = cmd;
   commandData = data;
   commandDataLen = len;
-  if (PostThreadMessage(hostThread->getThreadId(), VNCM_COMMAND, 0, 0))
-    while (command != NoCommand) commandSig.wait();
-  else
-    return false;
+  SetEvent(commandEvent);
+  if (wait) {
+    while (command != NoCommand)
+      commandSig.wait();
+    commandSig.signal();
+  }
   return true;
 }
 
-void VNCServerWin32::doCommand() {
-  Lock l(commandLock);
-  if (command == NoCommand) return;
+void VNCServerWin32::processEvent(HANDLE event_) {
+  ResetEvent(event_);
 
-  // Perform the required command
-  switch (command) {
+  if (event_ == commandEvent.h) {
+    // If there is no command queued then return immediately
+    {
+      Lock l(commandLock);
+      if (command == NoCommand)
+        return;
+    }
 
-  case DisconnectClients:
-    // Disconnect all currently active VNC Viewers
-    vncServer.closeClients((const char*)commandData);
-    break;
+    // Perform the required command
+    switch (command) {
 
-  case AddClient:
-    // Make a reverse connection to a VNC Viewer
-    vncServer.addClient((network::Socket*)commandData, true);
-    sockMgr.addSocket((network::Socket*)commandData, &vncServer);
-    break;
+    case DisconnectClients:
+      // Disconnect all currently active VNC Viewers
+      vncServer.closeClients((const char*)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");
-    queryConnectDialog = 0;
-    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;
@@ -345,11 +300,26 @@
     vncServer.setConnStatus((ListConnInfo*)commandData); 
     break;
 
-  default:
-    vlog.error("unknown command %d queued", command);
-  };
+    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;
 
-  // Clear the command and signal completion
-  command = NoCommand;
-  commandSig.signal();
+    default:
+      vlog.error("unknown command %d queued", command);
+    };
+
+    // Clear the command and signal completion
+    {
+      Lock l(commandLock);
+      command = NoCommand;
+      commandSig.signal();
+    }
+  }
 }
+
