summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2018-11-09 17:21:35 +0100
committerPierre Ossman <ossman@cendio.se>2018-11-09 17:21:35 +0100
commitf9de17665a3549e7e1eb44584ce73d6cafbd4c99 (patch)
tree9b8db530dac34858f202cd9c3bc1479faa221725 /win
parent42d0f5dd74fa0fe3bf3f26a92ecc5846db17895b (diff)
parent7e1093e976dbadfebcce893b943f6b52e1d4f8d5 (diff)
downloadtigervnc-f9de17665a3549e7e1eb44584ce73d6cafbd4c99.tar.gz
tigervnc-f9de17665a3549e7e1eb44584ce73d6cafbd4c99.zip
Merge branch 'vncserver' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'win')
-rw-r--r--win/rfb_win32/SDisplay.cxx18
-rw-r--r--win/rfb_win32/SDisplay.h18
-rw-r--r--win/rfb_win32/SocketManager.cxx29
-rw-r--r--win/rfb_win32/SocketManager.h4
-rw-r--r--win/winvnc/ControlPanel.cxx13
-rw-r--r--win/winvnc/ControlPanel.h12
-rw-r--r--win/winvnc/ListConnInfo.h119
-rw-r--r--win/winvnc/STrayIcon.cxx4
-rw-r--r--win/winvnc/VNCServerService.cxx1
-rw-r--r--win/winvnc/VNCServerWin32.cxx108
-rw-r--r--win/winvnc/VNCServerWin32.h17
11 files changed, 304 insertions, 39 deletions
diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx
index 9b2cbb02..afb72ad7 100644
--- a/win/rfb_win32/SDisplay.cxx
+++ b/win/rfb_win32/SDisplay.cxx
@@ -20,6 +20,8 @@
//
// The SDisplay class encapsulates a particular system display.
+#include <assert.h>
+
#include <rfb_win32/SDisplay.h>
#include <rfb_win32/Service.h>
#include <rfb_win32/TsSessions.h>
@@ -66,7 +68,7 @@ SDisplay::SDisplay()
: server(0), pb(0), device(0),
core(0), ptr(0), kbd(0), clipboard(0),
inputs(0), monitor(0), cleanDesktop(0), cursor(0),
- statusLocation(0), ledState(0)
+ statusLocation(0), queryConnectionHandler(0), ledState(0)
{
updateEvent.h = CreateEvent(0, TRUE, FALSE, 0);
}
@@ -139,6 +141,20 @@ void SDisplay::stop()
}
+void SDisplay::queryConnection(network::Socket* sock,
+ const char* userName)
+{
+ assert(server != NULL);
+
+ if (queryConnectionHandler) {
+ queryConnectionHandler->queryConnection(sock, userName);
+ return;
+ }
+
+ server->approveConnection(sock, true);
+}
+
+
void SDisplay::startCore() {
// Currently, we just check whether we're in the console session, and
diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h
index c1d5c1e2..76ddf50b 100644
--- a/win/rfb_win32/SDisplay.h
+++ b/win/rfb_win32/SDisplay.h
@@ -52,6 +52,13 @@ namespace rfb {
virtual const char* methodName() const = 0;
};
+ class QueryConnectionHandler {
+ public:
+ virtual ~QueryConnectionHandler() {}
+ virtual void queryConnection(network::Socket* sock,
+ const char* userName) = 0;
+ };
+
class SDisplay : public SDesktop,
WMMonitor::Notifier,
Clipboard::Notifier,
@@ -65,6 +72,8 @@ namespace rfb {
virtual void start(VNCServer* vs);
virtual void stop();
+ virtual void queryConnection(network::Socket* sock,
+ const char* userName);
virtual void pointerEvent(const Point& pos, int buttonmask);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
@@ -86,6 +95,12 @@ namespace rfb {
void setStatusLocation(bool* status) {statusLocation = status;}
+ // -=- Set handler for incoming connections
+
+ void setQueryConnectionHandler(QueryConnectionHandler* qch) {
+ queryConnectionHandler = qch;
+ }
+
static IntParameter updateMethod;
static BoolParameter disableLocalInputs;
static StringParameter disconnectAction;
@@ -150,6 +165,9 @@ namespace rfb {
// -=- Where to write the active/inactive indicator to
bool* statusLocation;
+ // -=- Whom to query incoming connections
+ QueryConnectionHandler* queryConnectionHandler;
+
unsigned ledState;
};
diff --git a/win/rfb_win32/SocketManager.cxx b/win/rfb_win32/SocketManager.cxx
index 5b211a0d..aa469e53 100644
--- a/win/rfb_win32/SocketManager.cxx
+++ b/win/rfb_win32/SocketManager.cxx
@@ -78,6 +78,7 @@ void SocketManager::addListener(network::SocketListener* sock_,
li.sock = sock_;
li.server = srvr;
li.notifier = acn;
+ li.disable = false;
listeners[event] = li;
}
@@ -128,6 +129,32 @@ void SocketManager::remSocket(network::Socket* sock_) {
throw rdr::Exception("Socket not registered");
}
+bool SocketManager::getDisable(network::SocketServer* srvr)
+{
+ std::map<HANDLE,ListenInfo>::iterator i;
+ for (i=listeners.begin(); i!=listeners.end(); i++) {
+ if (i->second.server == srvr) {
+ return i->second.disable;
+ }
+ }
+ throw rdr::Exception("Listener not registered");
+}
+
+void SocketManager::setDisable(network::SocketServer* srvr, bool disable)
+{
+ bool found = false;
+ std::map<HANDLE,ListenInfo>::iterator i;
+ for (i=listeners.begin(); i!=listeners.end(); i++) {
+ if (i->second.server == srvr) {
+ i->second.disable = disable;
+ // There might be multiple sockets for the same server, so
+ // continue iterating
+ found = true;
+ }
+ }
+ if (!found)
+ throw rdr::Exception("Listener not registered");
+}
int SocketManager::checkTimeouts() {
int timeout = EventManager::checkTimeouts();
@@ -164,7 +191,7 @@ void SocketManager::processEvent(HANDLE event) {
WSAEnumNetworkEvents(li.sock->getFd(), event, &network_events);
if (network_events.lNetworkEvents & FD_ACCEPT) {
network::Socket* new_sock = li.sock->accept();
- if (new_sock && li.server->getDisable()) {
+ if (new_sock && li.disable) {
delete new_sock;
new_sock = 0;
}
diff --git a/win/rfb_win32/SocketManager.h b/win/rfb_win32/SocketManager.h
index c3c8fafd..e5ca02e6 100644
--- a/win/rfb_win32/SocketManager.h
+++ b/win/rfb_win32/SocketManager.h
@@ -65,6 +65,9 @@ namespace rfb {
// the SocketServer.
void addSocket(network::Socket* sock_, network::SocketServer* srvr, bool outgoing=true);
+ bool getDisable(network::SocketServer* srvr);
+ void setDisable(network::SocketServer* srvr, bool disable);
+
protected:
virtual int checkTimeouts();
virtual void processEvent(HANDLE event);
@@ -78,6 +81,7 @@ namespace rfb {
network::SocketListener* sock;
network::SocketServer* server;
AddressChangeNotifier* notifier;
+ bool disable;
};
std::map<HANDLE, ListenInfo> listeners;
std::map<HANDLE, ConnInfo> connections;
diff --git a/win/winvnc/ControlPanel.cxx b/win/winvnc/ControlPanel.cxx
index ba6cab2c..72831e55 100644
--- a/win/winvnc/ControlPanel.cxx
+++ b/win/winvnc/ControlPanel.cxx
@@ -19,10 +19,9 @@ void ControlPanel::initDialog()
{
TCHAR *ColumnsStrings[] = {
(TCHAR *) "IP address",
- (TCHAR *) "Time connected",
(TCHAR *) "Status"
};
- InitLVColumns(IDC_LIST_CONNECTIONS, handle, 120, 3, ColumnsStrings,
+ InitLVColumns(IDC_LIST_CONNECTIONS, handle, 120, 2, ColumnsStrings,
LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM,
LVS_EX_FULLROWSELECT, LVCFMT_LEFT);
SendCommand(4, -1);
@@ -74,7 +73,7 @@ bool ControlPanel::onCommand(int cmd)
}
-void ControlPanel::UpdateListView(rfb::ListConnInfo* LCInfo)
+void ControlPanel::UpdateListView(ListConnInfo* LCInfo)
{
getSelConnInfo();
DeleteAllLVItem(IDC_LIST_CONNECTIONS, handle);
@@ -85,12 +84,12 @@ void ControlPanel::UpdateListView(rfb::ListConnInfo* LCInfo)
ListConn.Copy(LCInfo);
- char* ItemString[3];
+ char* ItemString[2];
int i = 0;
for (ListConn.iBegin(); !ListConn.iEnd(); ListConn.iNext()) {
ListConn.iGetCharInfo(ItemString);
- InsertLVItem(IDC_LIST_CONNECTIONS, handle, i, (TCHAR **) ItemString, 3);
+ InsertLVItem(IDC_LIST_CONNECTIONS, handle, i, (TCHAR **) ItemString, 2);
for (ListSelConn.iBegin(); !ListSelConn.iEnd(); ListSelConn.iNext()) {
if (ListSelConn.iGetConn() == ListConn.iGetConn())
SelectLVItem(IDC_LIST_CONNECTIONS, handle, i);
@@ -141,6 +140,8 @@ void ControlPanel::SendCommand(DWORD command, int data)
{
COPYDATASTRUCT copyData;
copyData.dwData = command;
+ copyData.cbData = 0;
+ copyData.lpData = 0;
getSelConnInfo();
if (data != -1) {
ListConnStatus.Copy(&ListSelConn);
@@ -149,8 +150,6 @@ void ControlPanel::SendCommand(DWORD command, int data)
} else {
ListConnStatus.Clear();
}
- copyData.cbData = 0;
- copyData.lpData = &ListConnStatus;
SendMessage(m_hSTIcon, WM_COPYDATA, 0, (LPARAM)&copyData);
}
diff --git a/win/winvnc/ControlPanel.h b/win/winvnc/ControlPanel.h
index 73b859f8..f64a6081 100644
--- a/win/winvnc/ControlPanel.h
+++ b/win/winvnc/ControlPanel.h
@@ -11,10 +11,10 @@
#include <list>
#include <winvnc/resource.h>
+#include <winvnc/ListConnInfo.h>
#include <rfb_win32/Dialog.h>
#include <rfb_win32/ListViewControl.h>
#include <rfb_win32/Win32Util.h>
-#include <rfb/ListConnInfo.h>
namespace winvnc {
@@ -27,19 +27,19 @@ namespace winvnc {
virtual bool showDialog();
virtual void initDialog();
virtual bool onCommand(int cmd);
- void UpdateListView(rfb::ListConnInfo* LCInfo);
+ void UpdateListView(ListConnInfo* LCInfo);
HWND GetHandle() {return handle;};
void SendCommand(DWORD command, int data);
~ControlPanel();
- rfb::ListConnInfo ListConnStatus;
+ 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;
+ ListConnInfo ListConn;
+ ListConnInfo ListSelConn;
bool stop_updating;
};
};
-#endif \ No newline at end of file
+#endif
diff --git a/win/winvnc/ListConnInfo.h b/win/winvnc/ListConnInfo.h
new file mode 100644
index 00000000..6ca5b7c7
--- /dev/null
+++ b/win/winvnc/ListConnInfo.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2002-2003 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 __RFB_LISTCONNINFO_INCLUDED__
+#define __RFB_LISTCONNINFO_INCLUDED__
+
+#include <list>
+
+#include <rfb/util.h>
+
+namespace winvnc {
+
+ struct ListConnInfo {
+ ListConnInfo() : disableClients(false) {}
+
+ void Clear() {
+ conn.clear();
+ IP_address.clear();
+ status.clear();
+ }
+
+ bool Empty() { return conn.empty();}
+
+ void iBegin() {
+ ci = conn.begin();
+ Ii = IP_address.begin();
+ si = status.begin();
+ }
+
+ bool iEnd() { return ci == conn.end();}
+
+ void iNext() {
+ ci++;
+ Ii++;
+ si++;
+ }
+
+ void addInfo(void* Conn, char* IP, int Status) {
+ conn.push_back(Conn);
+ IP_address.push_back(rfb::strDup(IP));
+ status.push_back(Status);
+ }
+
+ void iGetCharInfo(char* buf[2]) {
+ buf[0] = *Ii;
+ switch (*si) {
+ case 0:
+ buf[1] = rfb::strDup("Full control");
+ break;
+ case 1:
+ buf[1] = rfb::strDup("View only");
+ break;
+ case 2:
+ buf[1] = rfb::strDup("Stop updating");
+ break;
+ default:
+ buf[1] = rfb::strDup("Unknown");
+ }
+ }
+
+ void* iGetConn() { return *ci;}
+
+ int iGetStatus() { return *si;}
+
+ void iSetStatus(int istatus) { *si = istatus;}
+
+ void Copy(ListConnInfo* InputList) {
+ Clear();
+ if (InputList->Empty()) return;
+ for (InputList->iBegin(); !InputList->iEnd(); InputList->iNext()) {
+ iAdd(InputList);
+ }
+ setDisable(InputList->getDisable());
+ }
+
+ void iAdd (ListConnInfo* InputList) {
+ char* buf[2];
+ InputList->iGetCharInfo(buf);
+ addInfo(InputList->iGetConn(), buf[0], InputList->iGetStatus());
+ }
+
+ void setDisable(bool disable) {disableClients = disable;}
+
+ bool getDisable() {return disableClients;}
+
+ void setAllStatus(int stat) {
+ std::list<int>::iterator st;
+ for (st = status.begin(); st != status.end(); st++)
+ *st = stat;
+ }
+
+ private:
+ std::list<void*> conn;
+ std::list<char*> IP_address;
+ std::list<int> status;
+ std::list<void*>::iterator ci;
+ std::list<char*>::iterator Ii;
+ std::list<int>::iterator si;
+ bool disableClients;
+ };
+};
+#endif
+
diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx
index 05a38d6e..a90819d0 100644
--- a/win/winvnc/STrayIcon.cxx
+++ b/win/winvnc/STrayIcon.cxx
@@ -184,7 +184,7 @@ public:
case 2:
return thread.server.disconnectClients("IPC disconnect") ? 1 : 0;
case 3:
- thread.server.setClientsStatus((rfb::ListConnInfo *)command->lpData);
+ thread.server.setClientsStatus(&CPanel->ListConnStatus);
case 4:
thread.server.getClientsInfo(&LCInfo);
CPanel->UpdateListView(&LCInfo);
@@ -230,7 +230,7 @@ protected:
LaunchProcess vncConnect;
STrayIconThread& thread;
ControlPanel * CPanel;
- rfb::ListConnInfo LCInfo;
+ ListConnInfo LCInfo;
};
diff --git a/win/winvnc/VNCServerService.cxx b/win/winvnc/VNCServerService.cxx
index 5656de04..f5a4dba2 100644
--- a/win/winvnc/VNCServerService.cxx
+++ b/win/winvnc/VNCServerService.cxx
@@ -19,6 +19,7 @@
// -=- WinVNC Version 4.0 Service-Mode implementation
#include <winvnc/VNCServerService.h>
+#include <rfb/LogWriter.h>
#include <rfb_win32/TsSessions.h>
#include <rfb_win32/ModuleFileName.h>
#include <windows.h>
diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx
index 9f6a954d..03b1bca7 100644
--- a/win/winvnc/VNCServerWin32.cxx
+++ b/win/winvnc/VNCServerWin32.cxx
@@ -20,6 +20,7 @@
#include <winvnc/VNCServerWin32.h>
#include <winvnc/resource.h>
+#include <winvnc/ListConnInfo.h>
#include <winvnc/STrayIcon.h>
#include <os/Mutex.h>
@@ -71,9 +72,7 @@ VNCServerWin32::VNCServerWin32()
// Initialise the desktop
desktop.setStatusLocation(&isDesktopStarted);
-
- // Initialise the VNC server
- vncServer.setQueryConnectionHandler(this);
+ desktop.setQueryConnectionHandler(this);
// Register the desktop's event to be handled
sockMgr.addEvent(desktop.getUpdateEvent(), &desktop);
@@ -241,27 +240,27 @@ bool VNCServerWin32::addNewClient(const char* client) {
return false;
}
-bool VNCServerWin32::getClientsInfo(rfb::ListConnInfo* LCInfo) {
+bool VNCServerWin32::getClientsInfo(ListConnInfo* LCInfo) {
return queueCommand(GetClientsInfo, LCInfo, 0);
}
-bool VNCServerWin32::setClientsStatus(rfb::ListConnInfo* LCInfo) {
+bool VNCServerWin32::setClientsStatus(ListConnInfo* LCInfo) {
return queueCommand(SetClientsStatus, LCInfo, 0);
}
-VNCServerST::queryResult VNCServerWin32::queryConnection(network::Socket* sock,
- const char* userName,
- char** reason)
+void VNCServerWin32::queryConnection(network::Socket* sock,
+ const char* userName)
{
- if (queryOnlyIfLoggedOn && CurrentUserToken().noUserLoggedOn())
- return VNCServerST::ACCEPT;
+ if (queryOnlyIfLoggedOn && CurrentUserToken().noUserLoggedOn()) {
+ vncServer.approveConnection(sock, true, NULL);
+ return;
+ }
if (queryConnectDialog) {
- *reason = rfb::strDup("Another connection is currently being queried.");
- return VNCServerST::REJECT;
+ vncServer.approveConnection(sock, false, "Another connection is currently being queried.");
+ return;
}
queryConnectDialog = new QueryConnectDialog(sock, userName, this);
queryConnectDialog->startDialog();
- return VNCServerST::PENDING;
}
void VNCServerWin32::queryConnectionComplete() {
@@ -309,10 +308,10 @@ void VNCServerWin32::processEvent(HANDLE event_) {
sockMgr.addSocket((network::Socket*)commandData, &vncServer);
break;
case GetClientsInfo:
- vncServer.getConnInfo((ListConnInfo*)commandData);
+ getConnInfo((ListConnInfo*)commandData);
break;
case SetClientsStatus:
- vncServer.setConnStatus((ListConnInfo*)commandData);
+ setConnStatus((ListConnInfo*)commandData);
break;
case QueryConnectionComplete:
@@ -341,3 +340,82 @@ void VNCServerWin32::processEvent(HANDLE event_) {
}
}
+void VNCServerWin32::getConnInfo(ListConnInfo * listConn)
+{
+ std::list<network::Socket*> sockets;
+ std::list<network::Socket*>::iterator i;
+
+ listConn->Clear();
+ listConn->setDisable(sockMgr.getDisable(&vncServer));
+
+ vncServer.getSockets(&sockets);
+
+ for (i = sockets.begin(); i != sockets.end(); i++) {
+ rfb::SConnection* conn;
+ int status;
+
+ conn = vncServer.getConnection(*i);
+ if (!conn)
+ continue;
+
+ if (conn->accessCheck(rfb::SConnection::AccessPtrEvents |
+ rfb::SConnection::AccessKeyEvents |
+ rfb::SConnection::AccessView))
+ status = 0;
+ else if (conn->accessCheck(rfb::SConnection::AccessView))
+ status = 1;
+ else
+ status = 2;
+
+ listConn->addInfo((void*)(*i), (*i)->getPeerAddress(), status);
+ }
+}
+
+void VNCServerWin32::setConnStatus(ListConnInfo* listConn)
+{
+ sockMgr.setDisable(&vncServer, listConn->getDisable());
+
+ if (listConn->Empty())
+ return;
+
+ for (listConn->iBegin(); !listConn->iEnd(); listConn->iNext()) {
+ network::Socket* sock;
+ rfb::SConnection* conn;
+ int status;
+
+ sock = (network::Socket*)listConn->iGetConn();
+
+ conn = vncServer.getConnection(sock);
+ if (!conn)
+ continue;
+
+ status = listConn->iGetStatus();
+ if (status == 3) {
+ conn->close(0);
+ } else {
+ rfb::SConnection::AccessRights ar;
+
+ ar = rfb::SConnection::AccessDefault;
+
+ switch (status) {
+ case 0:
+ ar |= rfb::SConnection::AccessPtrEvents |
+ rfb::SConnection::AccessKeyEvents |
+ rfb::SConnection::AccessView;
+ break;
+ case 1:
+ ar |= rfb::SConnection::AccessView;
+ ar &= ~(rfb::SConnection::AccessPtrEvents |
+ rfb::SConnection::AccessKeyEvents);
+ break;
+ case 2:
+ ar &= ~(rfb::SConnection::AccessPtrEvents |
+ rfb::SConnection::AccessKeyEvents |
+ rfb::SConnection::AccessView);
+ break;
+ }
+ conn->setAccessRights(ar);
+ conn->framebufferUpdateRequest(vncServer.getPixelBuffer()->getRect(), false);
+ }
+ }
+}
diff --git a/win/winvnc/VNCServerWin32.h b/win/winvnc/VNCServerWin32.h
index 271cb76a..1a737823 100644
--- a/win/winvnc/VNCServerWin32.h
+++ b/win/winvnc/VNCServerWin32.h
@@ -37,9 +37,10 @@ namespace os {
namespace winvnc {
+ class ListConnInfo;
class STrayIconThread;
- class VNCServerWin32 : rfb::VNCServerST::QueryConnectionHandler,
+ class VNCServerWin32 : rfb::win32::QueryConnectionHandler,
rfb::win32::SocketManager::AddressChangeNotifier,
rfb::win32::RegConfig::Callback,
rfb::win32::EventHandler {
@@ -73,17 +74,16 @@ namespace winvnc {
// Where to read the configuration settings from
static const TCHAR* RegConfigPath;
- bool getClientsInfo(rfb::ListConnInfo* LCInfo);
+ bool getClientsInfo(ListConnInfo* LCInfo);
- bool setClientsStatus(rfb::ListConnInfo* LCInfo);
+ bool setClientsStatus(ListConnInfo* LCInfo);
protected:
- // VNCServerST::QueryConnectionHandler interface
+ // 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);
+ virtual void queryConnection(network::Socket* sock,
+ const char* userName);
// SocketManager::AddressChangeNotifier interface
// Used to keep tray icon up to date
@@ -97,6 +97,9 @@ namespace winvnc {
// Used to perform queued commands
virtual void processEvent(HANDLE event);
+ void getConnInfo(ListConnInfo * listConn);
+ void setConnStatus(ListConnInfo* listConn);
+
protected:
// Perform a particular internal function in the server thread
typedef enum {NoCommand, DisconnectClients, AddClient, QueryConnectionComplete, SetClientsStatus, GetClientsInfo} Command;