aboutsummaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2016-01-12 12:32:15 +0100
committerPierre Ossman <ossman@cendio.se>2016-01-12 12:32:15 +0100
commitfc08bee5afdb07830d6c6fb28359a020a5c305c5 (patch)
treee2009681235886e7c9e6669f0939b679815fcfab /win
parent4ab1e5d4b5ebaac0c410eedcc76865736aaa6ae4 (diff)
downloadtigervnc-fc08bee5afdb07830d6c6fb28359a020a5c305c5.tar.gz
tigervnc-fc08bee5afdb07830d6c6fb28359a020a5c305c5.zip
Remove legacy Windows code
We have lots of code that deals with Windows versions that we no longer support anyway. Clean out all of this old cruft.
Diffstat (limited to 'win')
-rw-r--r--win/rfb_win32/CMakeLists.txt4
-rw-r--r--win/rfb_win32/CleanDesktop.cxx57
-rw-r--r--win/rfb_win32/CurrentUser.cxx37
-rw-r--r--win/rfb_win32/CurrentUser.h22
-rw-r--r--win/rfb_win32/DeviceFrameBuffer.cxx8
-rw-r--r--win/rfb_win32/DynamicFn.cxx45
-rw-r--r--win/rfb_win32/DynamicFn.h51
-rw-r--r--win/rfb_win32/MonitorInfo.cxx105
-rw-r--r--win/rfb_win32/MonitorInfo.h17
-rw-r--r--win/rfb_win32/OSVersion.cxx47
-rw-r--r--win/rfb_win32/OSVersion.h53
-rw-r--r--win/rfb_win32/Registry.cxx7
-rw-r--r--win/rfb_win32/SDisplay.cxx20
-rw-r--r--win/rfb_win32/SDisplay.h2
-rw-r--r--win/rfb_win32/SInput.cxx66
-rw-r--r--win/rfb_win32/Security.cxx12
-rw-r--r--win/rfb_win32/Service.cxx411
-rw-r--r--win/rfb_win32/Service.h6
-rw-r--r--win/rfb_win32/TsSessions.cxx39
-rw-r--r--win/rfb_win32/WMCursor.cxx72
-rw-r--r--win/rfb_win32/WMCursor.h2
-rw-r--r--win/rfb_win32/WMHooks.cxx207
-rw-r--r--win/rfb_win32/WMHooks.h14
-rw-r--r--win/vncconfig/Authentication.h3
-rw-r--r--win/vncconfig/Desktop.h14
-rw-r--r--win/vncconfig/Hooking.h8
-rw-r--r--win/vncconfig/Inputs.h2
-rw-r--r--win/vncconfig/Legacy.cxx3
-rw-r--r--win/vncconfig/resource.h1
-rw-r--r--win/vncconfig/vncconfig.cxx1
-rw-r--r--win/vncconfig/vncconfig.rc14
-rw-r--r--win/winvnc/VNCServerService.cxx22
-rw-r--r--win/winvnc/VNCServerService.h2
33 files changed, 288 insertions, 1086 deletions
diff --git a/win/rfb_win32/CMakeLists.txt b/win/rfb_win32/CMakeLists.txt
index 99d52779..047b0d86 100644
--- a/win/rfb_win32/CMakeLists.txt
+++ b/win/rfb_win32/CMakeLists.txt
@@ -6,13 +6,11 @@ set(RFB_WIN32_SOURCES
DeviceFrameBuffer.cxx
Dialog.cxx
DIBSectionBuffer.cxx
- DynamicFn.cxx
EventManager.cxx
LaunchProcess.cxx
ListViewControl.cxx
MonitorInfo.cxx
MsgWindow.cxx
- OSVersion.cxx
RegConfig.cxx
Registry.cxx
SecurityPage.cxx
@@ -40,4 +38,4 @@ endif()
add_library(rfb_win32 STATIC ${RFB_WIN32_SOURCES})
-target_link_libraries(rfb_win32 user32.lib comctl32.lib version.lib)
+target_link_libraries(rfb_win32 user32.lib comctl32.lib wtsapi32.lib version.lib)
diff --git a/win/rfb_win32/CleanDesktop.cxx b/win/rfb_win32/CleanDesktop.cxx
index 8009fc8b..69fa6667 100644
--- a/win/rfb_win32/CleanDesktop.cxx
+++ b/win/rfb_win32/CleanDesktop.cxx
@@ -24,18 +24,11 @@
#include <rfb_win32/CleanDesktop.h>
#include <rfb_win32/CurrentUser.h>
#include <rfb_win32/Registry.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb/LogWriter.h>
#include <rdr/Exception.h>
#include <os/os.h>
#include <set>
-#ifdef SPI_GETUIEFFECTS
-#define RFB_HAVE_SPI_UIEFFECTS
-#else
-#pragma message(" NOTE: Not building Get/Set UI Effects support.")
-#endif
-
using namespace rfb;
using namespace rfb::win32;
@@ -154,14 +147,14 @@ DWORD SysParamsInfo(UINT action, UINT param, PVOID ptr, UINT ini) {
}
-CleanDesktop::CleanDesktop() : restoreActiveDesktop(false), restoreWallpaper(false),
- restorePattern(false), restoreEffects(false) {
+CleanDesktop::CleanDesktop() : restoreActiveDesktop(false),
+ restoreWallpaper(false),
+ restoreEffects(false) {
CoInitialize(0);
}
CleanDesktop::~CleanDesktop() {
enableEffects();
- enablePattern();
enableWallpaper();
CoUninitialize();
}
@@ -221,42 +214,6 @@ void CleanDesktop::enableWallpaper() {
}
-void CleanDesktop::disablePattern() {
- try {
- ImpersonateCurrentUser icu;
-
- vlog.debug("disable desktop pattern");
- SysParamsInfo(SPI_SETDESKPATTERN, 0, (PVOID) "", SPIF_SENDCHANGE);
- restorePattern = true;
-
- } catch (rdr::Exception& e) {
- vlog.info("%s", e.str());
- }
-}
-
-void CleanDesktop::enablePattern() {
- try {
- if (restorePattern) {
- ImpersonateCurrentUser icu;
-
- vlog.debug("restoring pattern...");
-
- TCharArray pattern;
- if (osVersion.isPlatformWindows) {
- RegKey cfgKey;
- cfgKey.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"));
- pattern.buf = cfgKey.getString(_T("Pattern"));
- }
- SysParamsInfo(SPI_SETDESKPATTERN, 0, pattern.buf, SPIF_SENDCHANGE);
- restorePattern = false;
- }
-
- } catch (rdr::Exception& e) {
- vlog.info("%s", e.str());
- }
-}
-
-
void CleanDesktop::disableEffects() {
try {
ImpersonateCurrentUser icu;
@@ -264,7 +221,6 @@ void CleanDesktop::disableEffects() {
vlog.debug("disable desktop effects");
SysParamsInfo(SPI_SETFONTSMOOTHING, FALSE, 0, SPIF_SENDCHANGE);
-#ifdef RFB_HAVE_SPI_UIEFFECTS
if (SysParamsInfo(SPI_GETUIEFFECTS, 0, &uiEffects, 0) == ERROR_CALL_NOT_IMPLEMENTED) {
SysParamsInfo(SPI_GETCOMBOBOXANIMATION, 0, &comboBoxAnim, 0);
SysParamsInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradientCaptions, 0);
@@ -282,9 +238,6 @@ void CleanDesktop::disableEffects() {
// We *always* restore UI effects overall, since there is no Windows GUI to do it
uiEffects = TRUE;
}
-#else
- vlog.debug(" not supported");
-#endif
restoreEffects = true;
} catch (rdr::Exception& e) {
@@ -302,7 +255,6 @@ void CleanDesktop::enableEffects() {
RegKey desktopCfg;
desktopCfg.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"));
SysParamsInfo(SPI_SETFONTSMOOTHING, desktopCfg.getInt(_T("FontSmoothing"), 0) != 0, 0, SPIF_SENDCHANGE);
-#ifdef RFB_HAVE_SPI_UIEFFECTS
if (SysParamsInfo(SPI_SETUIEFFECTS, 0, (void*)(intptr_t)uiEffects, SPIF_SENDCHANGE) == ERROR_CALL_NOT_IMPLEMENTED) {
SysParamsInfo(SPI_SETCOMBOBOXANIMATION, 0, (void*)(intptr_t)comboBoxAnim, SPIF_SENDCHANGE);
SysParamsInfo(SPI_SETGRADIENTCAPTIONS, 0, (void*)(intptr_t)gradientCaptions, SPIF_SENDCHANGE);
@@ -311,9 +263,6 @@ void CleanDesktop::enableEffects() {
SysParamsInfo(SPI_SETMENUANIMATION, 0, (void*)(intptr_t)menuAnim, SPIF_SENDCHANGE);
}
restoreEffects = false;
-#else
- vlog.info(" not supported");
-#endif
}
} catch (rdr::Exception& e) {
diff --git a/win/rfb_win32/CurrentUser.cxx b/win/rfb_win32/CurrentUser.cxx
index 21531de8..6be3f9ab 100644
--- a/win/rfb_win32/CurrentUser.cxx
+++ b/win/rfb_win32/CurrentUser.cxx
@@ -21,10 +21,9 @@
#include <stdlib.h>
#include <rfb/LogWriter.h>
#include <rfb_win32/CurrentUser.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb_win32/Service.h>
-#include <rfb_win32/OSVersion.h>
#include <lmcons.h>
+#include <wtsapi32.h>
using namespace rfb;
using namespace win32;
@@ -68,48 +67,18 @@ BOOL CALLBACK enumDesktops(LPTSTR lpszDesktop, LPARAM lParam) {
}
-CurrentUserToken::CurrentUserToken() : isSafe_(false) {
+CurrentUserToken::CurrentUserToken() {
if (isServiceProcess()) {
- // If the platform is Windows 95/98/Me then we must fake the token's presence
- if (osVersion.isPlatformWindows) {
- try {
- UserName un;
- h = INVALID_HANDLE_VALUE;
- } catch (rdr::SystemException& e) {
- if (e.err != ERROR_NOT_LOGGED_ON)
- throw;
- if (FindWindow(shellIconClass, 0))
- h = INVALID_HANDLE_VALUE;
- }
- isSafe_ = (h != 0);
- return;
- }
-
// Try to get the user token using the Terminal Services APIs
- // NB: This will only work under XP/2003 and later
- typedef BOOL (WINAPI *WTSQueryUserToken_proto)(ULONG, PHANDLE);
- DynamicFn<WTSQueryUserToken_proto> _WTSQueryUserToken(_T("wtsapi32.dll"), "WTSQueryUserToken");
- if (_WTSQueryUserToken.isValid()) {
- (*_WTSQueryUserToken)(-1, &h);
- isSafe_ = true;
- return;
- }
-
- // Try to find the Shell Tray Icon window and take its token
- // NB: This will only work under NT/2K (and later, but they're dealt with above)
- // NB: If the shell is not running then this will return an Unsafe Null token.
- EnumDesktops(GetProcessWindowStation(), enumDesktops, (LPARAM)&h);
- isSafe_ = (h != 0);
+ WTSQueryUserToken(-1, &h);
} else {
// Try to open the security token for the User-Mode process
if (!OpenProcessToken(GetCurrentProcess(), GENERIC_ALL, &h)) {
DWORD err = GetLastError();
if (err != ERROR_CALL_NOT_IMPLEMENTED)
throw rdr::SystemException("OpenProcessToken failed", err);
- // Under Windows 95/98/Me, we fake the handle value...
h = INVALID_HANDLE_VALUE;
}
- isSafe_ = true;
}
}
diff --git a/win/rfb_win32/CurrentUser.h b/win/rfb_win32/CurrentUser.h
index 794f27c6..9c020887 100644
--- a/win/rfb_win32/CurrentUser.h
+++ b/win/rfb_win32/CurrentUser.h
@@ -38,17 +38,6 @@ namespace rfb {
// for the currently logged-on user, or null if no user is
// logged on.
//
- // Under Windows 95/98/Me, which don't support security tokens,
- // the token will be INVALID_HANDLE_VALUE if a user is logged on.
- //
- // Under Windows NT/2K, it may be the case that the token is
- // null even when a user *is* logged on, because we use some hacks
- // to detect the user's token and sometimes they fail. On these
- // platforms, isSafe() will return False if the token is null.
- //
- // Under Windows XP, etc, isSafe() will always be True, and the token
- // will always be set to the currently logged on user's token.
- //
// canImpersonate() tests whether there is a user token that is safe
// to impersonate.
//
@@ -56,18 +45,15 @@ namespace rfb {
struct CurrentUserToken : public Handle {
CurrentUserToken();
- bool isSafe() const { return isSafe_; };
- bool canImpersonate() const { return h && isSafe(); }
- bool noUserLoggedOn() const { return !h && isSafe(); }
- private:
- bool isSafe_;
+ bool canImpersonate() const { return h; }
+ bool noUserLoggedOn() const { return !h; }
};
// ImpersonateCurrentUser
// Throws an exception on failure.
// Succeeds (trivially) if process is not running as service.
// Fails if CurrentUserToken is not valid.
- // Fails if platform is NT AND cannot impersonate token.
+ // Fails if cannot impersonate token.
// Succeeds otherwise.
struct ImpersonateCurrentUser {
@@ -79,8 +65,6 @@ namespace rfb {
// UserName
// Returns the name of the user the thread is currently running as.
// Raises a SystemException in case of error.
- // NB: Raises a SystemException with err == ERROR_NOT_LOGGED_ON if
- // running under Windows 9x/95/Me and no user is logged on.
struct UserName : public TCharArray {
UserName();
diff --git a/win/rfb_win32/DeviceFrameBuffer.cxx b/win/rfb_win32/DeviceFrameBuffer.cxx
index d075c259..22841f7e 100644
--- a/win/rfb_win32/DeviceFrameBuffer.cxx
+++ b/win/rfb_win32/DeviceFrameBuffer.cxx
@@ -25,7 +25,6 @@
#include <vector>
#include <rfb_win32/DeviceFrameBuffer.h>
#include <rfb_win32/DeviceContext.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb_win32/IconInfo.h>
#include <rfb/VNCServer.h>
#include <rfb/LogWriter.h>
@@ -108,10 +107,9 @@ DeviceFrameBuffer::grabRect(const Rect &rect) {
// Map the rectangle coords from VNC Desktop-relative to device relative - usually (0,0)
Point src = desktopToDevice(rect.tl);
- // Note: Microsoft's documentation lies directly about CAPTUREBLT and claims it works on 98/ME
- // If you try CAPTUREBLT on 98 then you get blank output...
- if (!::BitBlt(tmpDC, rect.tl.x, rect.tl.y, rect.width(), rect.height(), device, src.x, src.y,
- (osVersion.isPlatformNT && useCaptureBlt) ? (CAPTUREBLT | SRCCOPY) : SRCCOPY)) {
+ if (!::BitBlt(tmpDC, rect.tl.x, rect.tl.y,
+ rect.width(), rect.height(), device, src.x, src.y,
+ useCaptureBlt ? (CAPTUREBLT | SRCCOPY) : SRCCOPY)) {
if (ignoreGrabErrors)
vlog.error("BitBlt failed:%ld", GetLastError());
else
diff --git a/win/rfb_win32/DynamicFn.cxx b/win/rfb_win32/DynamicFn.cxx
deleted file mode 100644
index 97d17ff7..00000000
--- a/win/rfb_win32/DynamicFn.cxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 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 <rfb_win32/DynamicFn.h>
-#include <rfb_win32/TCharArray.h>
-#include <rfb/LogWriter.h>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("DynamicFn");
-
-
-DynamicFnBase::DynamicFnBase(const TCHAR* dllName, const char* fnName) : fnPtr(0), dllHandle(0) {
- dllHandle = LoadLibrary(dllName);
- if (!dllHandle) {
- vlog.info("DLL %s not found (%lu)", (const char*)CStr(dllName), GetLastError());
- return;
- }
- fnPtr = (void*) GetProcAddress(dllHandle, fnName);
- if (!fnPtr)
- vlog.info("proc %s not found in %s (%lu)", fnName, (const char*)CStr(dllName), GetLastError());
-}
-
-DynamicFnBase::~DynamicFnBase() {
- if (dllHandle)
- FreeLibrary(dllHandle);
-}
-
-
diff --git a/win/rfb_win32/DynamicFn.h b/win/rfb_win32/DynamicFn.h
deleted file mode 100644
index 57fdbec5..00000000
--- a/win/rfb_win32/DynamicFn.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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.
- */
-
-// Helper class managing dynamic linkage to DLL functions.
-
-#ifndef __RFB_WIN32_DYNAMICFN_H__
-#define __RFB_WIN32_DYNAMICFN_H__
-
-#include <windows.h>
-
-namespace rfb {
- namespace win32 {
-
- class DynamicFnBase {
- public:
- DynamicFnBase(const TCHAR* dllName, const char* fnName);
- ~DynamicFnBase();
- bool isValid() const {return fnPtr != 0;}
- protected:
- void* fnPtr;
- HMODULE dllHandle;
- private:
- DynamicFnBase(const DynamicFnBase&);
- DynamicFnBase operator=(const DynamicFnBase&);
- };
-
- template<class T> class DynamicFn : public DynamicFnBase {
- public:
- DynamicFn(const TCHAR* dllName, const char* fnName) : DynamicFnBase(dllName, fnName) {}
- T operator *() const {return (T)fnPtr;};
- };
-
- };
-};
-
-#endif
diff --git a/win/rfb_win32/MonitorInfo.cxx b/win/rfb_win32/MonitorInfo.cxx
index d639ac56..551017bd 100644
--- a/win/rfb_win32/MonitorInfo.cxx
+++ b/win/rfb_win32/MonitorInfo.cxx
@@ -16,7 +16,7 @@
* USA.
*/
-#include <rfb_win32/DynamicFn.h>
+#include <tchar.h>
#include <rfb_win32/MonitorInfo.h>
#include <rfb_win32/Win32Util.h>
#include <rdr/Exception.h>
@@ -36,91 +36,39 @@ using namespace win32;
static LogWriter vlog("MonitorInfo");
-// If we are building in multi-monitor support (i.e. the headers support it)
-// then do dynamic imports of the required system calls, and provide any
-// other code that wouldn't otherwise compile.
-#ifdef RFB_HAVE_MONITORINFO
-#include <tchar.h>
-typedef HMONITOR (WINAPI *_MonitorFromWindow_proto)(HWND,DWORD);
-static rfb::win32::DynamicFn<_MonitorFromWindow_proto> _MonitorFromWindow(_T("user32.dll"), "MonitorFromWindow");
-typedef HMONITOR (WINAPI *_MonitorFromRect_proto)(LPCRECT,DWORD);
-static rfb::win32::DynamicFn<_MonitorFromRect_proto> _MonitorFromRect(_T("user32.dll"), "MonitorFromRect");
-typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
-static rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
-typedef BOOL (WINAPI *_EnumDisplayMonitors_proto)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
-static rfb::win32::DynamicFn<_EnumDisplayMonitors_proto> _EnumDisplayMonitors(_T("user32.dll"), "EnumDisplayMonitors");
static void fillMonitorInfo(HMONITOR monitor, MonitorInfo* mi) {
vlog.debug("monitor=%p", monitor);
- if (!_GetMonitorInfo.isValid())
- throw rdr::Exception("no GetMonitorInfo");
memset(mi, 0, sizeof(MONITORINFOEXA));
mi->cbSize = sizeof(MONITORINFOEXA);
- if (!(*_GetMonitorInfo)(monitor, mi))
+ if (!GetMonitorInfo(monitor, mi))
throw rdr::SystemException("failed to GetMonitorInfo", GetLastError());
vlog.debug("monitor is %ld,%ld-%ld,%ld", mi->rcMonitor.left, mi->rcMonitor.top, mi->rcMonitor.right, mi->rcMonitor.bottom);
vlog.debug("work area is %ld,%ld-%ld,%ld", mi->rcWork.left, mi->rcWork.top, mi->rcWork.right, mi->rcWork.bottom);
vlog.debug("device is \"%s\"", mi->szDevice);
}
-#else
-#pragma message(" NOTE: Not building Multi-Monitor support.")
-#endif
MonitorInfo::MonitorInfo(HWND window) {
cbSize = sizeof(MonitorInfo);
szDevice[0] = 0;
-#ifdef RFB_HAVE_MONITORINFO
- try {
- if (_MonitorFromWindow.isValid()) {
- HMONITOR monitor = (*_MonitorFromWindow)(window, MONITOR_DEFAULTTONEAREST);
- if (!monitor)
- throw rdr::SystemException("failed to get monitor", GetLastError());
- fillMonitorInfo(monitor, this);
- return;
- }
- } catch (rdr::Exception& e) {
- vlog.error("%s", e.str());
- }
-#endif
-
- // Legacy fallbacks - just return the desktop settings
- vlog.debug("using legacy fall-backs");
- HWND desktop = GetDesktopWindow();
- GetWindowRect(desktop, &rcMonitor);
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
- dwFlags = 0;
+ HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
+ if (!monitor)
+ throw rdr::SystemException("failed to get monitor", GetLastError());
+ fillMonitorInfo(monitor, this);
}
MonitorInfo::MonitorInfo(const RECT& r) {
cbSize = sizeof(MonitorInfo);
szDevice[0] = 0;
-#ifdef RFB_HAVE_MONITORINFO
- try {
- if (_MonitorFromRect.isValid()) {
- HMONITOR monitor = (*_MonitorFromRect)(&r, MONITOR_DEFAULTTONEAREST);
- if (!monitor)
- throw rdr::SystemException("failed to get monitor", GetLastError());
- fillMonitorInfo(monitor, this);
- return;
- }
- } catch (rdr::Exception& e) {
- vlog.error("%s", e.str());
- }
-#endif
-
- // Legacy fallbacks - just return the desktop settings
- vlog.debug("using legacy fall-backs");
- HWND desktop = GetDesktopWindow();
- GetWindowRect(desktop, &rcMonitor);
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
- dwFlags = 0;
+ HMONITOR monitor = MonitorFromRect(&r, MONITOR_DEFAULTTONEAREST);
+ if (!monitor)
+ throw rdr::SystemException("failed to get monitor", GetLastError());
+ fillMonitorInfo(monitor, this);
}
-#ifdef RFB_HAVE_MONITORINFO
-
struct monitorByNameData {
MonitorInfo* info;
const char* monitorName;
@@ -133,7 +81,7 @@ static BOOL CALLBACK monitorByNameEnumProc(HMONITOR monitor,
monitorByNameData* data = (monitorByNameData*)d;
memset(data->info, 0, sizeof(MONITORINFOEXA));
data->info->cbSize = sizeof(MONITORINFOEXA);
- if ((*_GetMonitorInfo)(monitor, data->info)) {
+ if (GetMonitorInfo(monitor, data->info)) {
if (stricmp(data->monitorName, data->info->szDevice) == 0)
return FALSE;
}
@@ -141,44 +89,21 @@ static BOOL CALLBACK monitorByNameEnumProc(HMONITOR monitor,
return TRUE;
}
-#endif
-
MonitorInfo::MonitorInfo(const char* devName) {
-#ifdef RFB_HAVE_MONITORINFO
- if (!_EnumDisplayMonitors.isValid()) {
- vlog.debug("EnumDisplayMonitors not found");
- } else {
- monitorByNameData data;
- data.info = this;
- data.monitorName = devName;
-
- (*_EnumDisplayMonitors)(0, 0, &monitorByNameEnumProc, (LPARAM)&data);
- if (stricmp(data.monitorName, szDevice) == 0)
- return;
- }
-#endif
- // If multi-monitor is not built, or not supported by the OS,
- // or if the named monitor is not found, revert to the primary monitor.
- vlog.debug("reverting to primary monitor");
- cbSize = sizeof(MonitorInfo);
- szDevice[0] = 0;
-
- HWND desktop = GetDesktopWindow();
- GetWindowRect(desktop, &rcMonitor);
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
- dwFlags = 0;
+ monitorByNameData data;
+ data.info = this;
+ data.monitorName = devName;
+ EnumDisplayMonitors(0, 0, &monitorByNameEnumProc, (LPARAM)&data);
}
void MonitorInfo::moveTo(HWND handle) {
vlog.debug("moveTo monitor=%s", szDevice);
-#ifdef RFB_HAVE_MONITORINFO
MonitorInfo mi(handle);
if (strcmp(szDevice, mi.szDevice) != 0) {
centerWindow(handle, rcWork);
clipTo(handle);
}
-#endif
}
void MonitorInfo::clipTo(RECT* r) {
diff --git a/win/rfb_win32/MonitorInfo.h b/win/rfb_win32/MonitorInfo.h
index acf27755..2179b9b2 100644
--- a/win/rfb_win32/MonitorInfo.h
+++ b/win/rfb_win32/MonitorInfo.h
@@ -17,35 +17,18 @@
*/
// Helper class used to obtain information about a particular monitor.
-// This class wraps the Windows MONITORINFOEX ASCII structure, providing
-// methods that can safely be called on both multi-monitor aware systems
-// and older "legacy" systems.
#ifndef __RFB_WIN32_MONITORINFO_H__
#define __RFB_WIN32_MONITORINFO_H__
#include <windows.h>
-#ifdef MONITOR_DEFAULTTONULL
-#define RFB_HAVE_MONITORINFO
-#endif
namespace rfb {
namespace win32 {
// Structure containing info on the monitor nearest the window.
- // Copes with multi-monitor OSes and older ones.
-#ifdef RFB_HAVE_MONITORINFO
struct MonitorInfo : MONITORINFOEXA {
-#else
- struct MonitorInfo {
- DWORD cbSize;
- RECT rcMonitor;
- RECT rcWork;
- DWORD dwFlags;
- char szDevice[1]; // Always null...
-#endif
-
// Constructor: Obtains monitor info for the monitor that has the
// greatest overlap with the supplied window or rectangle.
MonitorInfo(HWND hwnd);
diff --git a/win/rfb_win32/OSVersion.cxx b/win/rfb_win32/OSVersion.cxx
deleted file mode 100644
index 3d74c956..00000000
--- a/win/rfb_win32/OSVersion.cxx
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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.
- */
-
-// -=- OSVersion.cxx
-
-#include <rfb_win32/OSVersion.h>
-#include <rdr/Exception.h>
-#include <tchar.h>
-
-using namespace rfb;
-using namespace win32;
-
-
-OSVersionInfo::OSVersionInfo() {
- // Get OS Version Info
- ZeroMemory(static_cast<OSVERSIONINFO*>(this), sizeof(this));
- dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (!GetVersionEx(this))
- throw rdr::SystemException("unable to get system version info", GetLastError());
-
- // Set the special extra flags
- isPlatformNT = dwPlatformId == VER_PLATFORM_WIN32_NT;
- isPlatformWindows = dwPlatformId == VER_PLATFORM_WIN32_WINDOWS;
-
- cannotSwitchDesktop = isPlatformNT && (dwMajorVersion==4) &&
- ((_tcscmp(szCSDVersion, _T("")) == 0) ||
- (_tcscmp(szCSDVersion, _T("Service Pack 1")) == 0) ||
- (_tcscmp(szCSDVersion, _T("Service Pack 2")) == 0));
-
-}
-
-OSVersionInfo rfb::win32::osVersion;
diff --git a/win/rfb_win32/OSVersion.h b/win/rfb_win32/OSVersion.h
deleted file mode 100644
index 18ec003e..00000000
--- a/win/rfb_win32/OSVersion.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 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.
- */
-
-// -=- OSVersion.h
-
-// Operating system version info.
-// GetVersionInfo is called once at process initialisation, and any
-// extra flags (such as isWinNT) are calculated and saved at that
-// point. It is assumed that the OS Version seldom changes during a
-// program's execution...
-
-#ifndef __RFB_WIN32_OS_VERSION_H__
-#define __RFB_WIN32_OS_VERSION_H__
-
-#include <windows.h>
-
-namespace rfb {
-
- namespace win32 {
-
- extern struct OSVersionInfo : OSVERSIONINFO {
- OSVersionInfo();
-
- // Is the OS one of the NT family (NT 3.51, NT4.0, 2K, XP, etc.)?
- bool isPlatformNT;
- // Is one of the Windows family?
- bool isPlatformWindows;
-
- // Is this OS one of those that blue-screens when grabbing another desktop (NT4 pre SP3)?
- bool cannotSwitchDesktop;
-
- } osVersion;
-
- };
-
-};
-
-#endif // __RFB_WIN32_OS_VERSION_H__
diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx
index 70083f4a..afbdd067 100644
--- a/win/rfb_win32/Registry.cxx
+++ b/win/rfb_win32/Registry.cxx
@@ -20,7 +20,6 @@
#include <rfb_win32/Registry.h>
#include <rfb_win32/Security.h>
-#include <rfb_win32/DynamicFn.h>
#include <rdr/MemOutStream.h>
#include <rdr/HexOutStream.h>
#include <rdr/HexInStream.h>
@@ -100,11 +99,7 @@ void RegKey::openKey(const RegKey& root, const TCHAR* name, bool readOnly) {
void RegKey::setDACL(const PACL acl, bool inherit) {
DWORD result;
- typedef DWORD (WINAPI *_SetSecurityInfo_proto) (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
- DynamicFn<_SetSecurityInfo_proto> _SetSecurityInfo(_T("advapi32.dll"), "SetSecurityInfo");
- if (!_SetSecurityInfo.isValid())
- throw rdr::SystemException("RegKey::setDACL failed", ERROR_CALL_NOT_IMPLEMENTED);
- if ((result = (*_SetSecurityInfo)(key, SE_REGISTRY_KEY,
+ if ((result = SetSecurityInfo(key, SE_REGISTRY_KEY,
DACL_SECURITY_INFORMATION |
(inherit ? UNPROTECTED_DACL_SECURITY_INFORMATION : PROTECTED_DACL_SECURITY_INFORMATION),
0, 0, acl, 0)) != ERROR_SUCCESS)
diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx
index d4cedf8c..ac64e3ef 100644
--- a/win/rfb_win32/SDisplay.cxx
+++ b/win/rfb_win32/SDisplay.cxx
@@ -25,7 +25,6 @@
#include <rfb_win32/TsSessions.h>
#include <rfb_win32/CleanDesktop.h>
#include <rfb_win32/CurrentUser.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb_win32/MonitorInfo.h>
#include <rfb_win32/SDisplayCorePolling.h>
#include <rfb_win32/SDisplayCoreWMHooks.h>
@@ -51,8 +50,6 @@ StringParameter displayDevice("DisplayDevice",
"Display device name of the monitor to be remoted, or empty to export the whole desktop.", "");
BoolParameter rfb::win32::SDisplay::removeWallpaper("RemoveWallpaper",
"Remove the desktop wallpaper when the server is in use.", false);
-BoolParameter rfb::win32::SDisplay::removePattern("RemovePattern",
- "Remove the desktop background pattern when the server is in use.", false);
BoolParameter rfb::win32::SDisplay::disableEffects("DisableEffects",
"Disable desktop user interface effects when the server is in use.", false);
@@ -62,9 +59,6 @@ BoolParameter rfb::win32::SDisplay::disableEffects("DisableEffects",
// SDisplay
//
-typedef BOOL (WINAPI *_LockWorkStation_proto)();
-DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");
-
// -=- Constructor/Destructor
SDisplay::SDisplay()
@@ -127,10 +121,7 @@ void SDisplay::stop()
if (!cut.h) {
vlog.info("ignoring DisconnectAction=Lock - no current user");
} else {
- if (_LockWorkStation.isValid())
- (*_LockWorkStation)();
- else
- ExitWindowsEx(EWX_LOGOFF, 0);
+ LockWorkStation();
}
}
}
@@ -199,14 +190,11 @@ void SDisplay::startCore() {
// Apply desktop optimisations
cleanDesktop = new CleanDesktop;
- if (removePattern)
- cleanDesktop->disablePattern();
if (removeWallpaper)
cleanDesktop->disableWallpaper();
if (disableEffects)
cleanDesktop->disableEffects();
isWallpaperRemoved = removeWallpaper;
- isPatternRemoved = removePattern;
areEffectsDisabled = disableEffects;
}
@@ -227,11 +215,6 @@ void SDisplay::stopCore() {
}
-bool SDisplay::areHooksAvailable() {
- return WMHooks::areAvailable();
-}
-
-
bool SDisplay::isRestartRequired() {
// - We must restart the SDesktop if:
// 1. We are no longer in the input desktop.
@@ -255,7 +238,6 @@ bool SDisplay::isRestartRequired() {
// - Check that the desktop optimisation settings haven't changed
// This isn't very efficient, but it shouldn't change very often!
if ((isWallpaperRemoved != removeWallpaper) ||
- (isPatternRemoved != removePattern) ||
(areEffectsDisabled != disableEffects))
return true;
diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h
index 70208a7d..b0217822 100644
--- a/win/rfb_win32/SDisplay.h
+++ b/win/rfb_win32/SDisplay.h
@@ -93,7 +93,6 @@ namespace rfb {
static BoolParameter disableLocalInputs;
static StringParameter disconnectAction;
static BoolParameter removeWallpaper;
- static BoolParameter removePattern;
static BoolParameter disableEffects;
// -=- Use by VNC Config to determine whether hooks are available
@@ -139,7 +138,6 @@ namespace rfb {
// Desktop optimisation
CleanDesktop* cleanDesktop;
bool isWallpaperRemoved;
- bool isPatternRemoved;
bool areEffectsDisabled;
// Cursor
diff --git a/win/rfb_win32/SInput.cxx b/win/rfb_win32/SInput.cxx
index 111a4d90..0923118a 100644
--- a/win/rfb_win32/SInput.cxx
+++ b/win/rfb_win32/SInput.cxx
@@ -30,27 +30,14 @@
#include <rfb_win32/SInput.h>
#include <rfb_win32/MonitorInfo.h>
#include <rfb_win32/Service.h>
-#include <rfb_win32/OSVersion.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb_win32/keymap.h>
#include <rdr/Exception.h>
#include <rfb/LogWriter.h>
-#if(defined(INPUT_MOUSE) && defined(RFB_HAVE_MONITORINFO) && defined(MOUSEEVENTF_VIRTUALDESK))
-#define RFB_HAVE_SENDINPUT
-#else
-#pragma message(" NOTE: Not building SendInput support.")
-#endif
-
using namespace rfb;
static LogWriter vlog("SInput");
-#ifdef RFB_HAVE_SENDINPUT
-typedef UINT (WINAPI *_SendInput_proto)(UINT, LPINPUT, int);
-static win32::DynamicFn<_SendInput_proto> _SendInput(_T("user32.dll"), "SendInput");
-#endif
-
//
// -=- Pointer implementation for Win32
//
@@ -125,44 +112,18 @@ win32::SPointer::pointerEvent(const Point& pos, int buttonmask)
// The event lies outside the primary monitor. Under Win2K, we can just use
// SendInput, which allows us to provide coordinates scaled to the virtual desktop.
// SendInput is available on all multi-monitor-aware platforms.
-#ifdef RFB_HAVE_SENDINPUT
- if (osVersion.isPlatformNT) {
- if (!_SendInput.isValid())
- throw rdr::Exception("SendInput not available");
- INPUT evt;
- evt.type = INPUT_MOUSE;
- Point vPos(pos.x-GetSystemMetrics(SM_XVIRTUALSCREEN),
- pos.y-GetSystemMetrics(SM_YVIRTUALSCREEN));
- evt.mi.dx = (vPos.x * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
- evt.mi.dy = (vPos.y * 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
- evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
- evt.mi.dwExtraInfo = 0;
- evt.mi.mouseData = data;
- evt.mi.time = 0;
- if ((*_SendInput)(1, &evt, sizeof(evt)) != 1)
- throw rdr::SystemException("SendInput", GetLastError());
- } else {
- // Under Win9x, this is not addressable by either mouse_event or SendInput
- // *** STUPID KLUDGY HACK ***
- POINT cursorPos; GetCursorPos(&cursorPos);
- ULONG oldSpeed, newSpeed = 10;
- ULONG mouseInfo[3];
- if (flags & MOUSEEVENTF_MOVE) {
- flags &= ~MOUSEEVENTF_ABSOLUTE;
- SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0);
- SystemParametersInfo(SPI_GETMOUSESPEED, 0, &oldSpeed, 0);
- vlog.debug("SPI_GETMOUSE %lu, %lu, %lu, speed %lu", mouseInfo[0], mouseInfo[1], mouseInfo[2], oldSpeed);
- ULONG idealMouseInfo[] = {10, 0, 0};
- SystemParametersInfo(SPI_SETMOUSESPEED, 0, &newSpeed, 0);
- SystemParametersInfo(SPI_SETMOUSE, 0, &idealMouseInfo, 0);
- }
- ::mouse_event(flags, pos.x-cursorPos.x, pos.y-cursorPos.y, data, 0);
- if (flags & MOUSEEVENTF_MOVE) {
- SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0);
- SystemParametersInfo(SPI_SETMOUSESPEED, 0, &oldSpeed, 0);
- }
- }
-#endif
+ INPUT evt;
+ evt.type = INPUT_MOUSE;
+ Point vPos(pos.x-GetSystemMetrics(SM_XVIRTUALSCREEN),
+ pos.y-GetSystemMetrics(SM_YVIRTUALSCREEN));
+ evt.mi.dx = (vPos.x * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
+ evt.mi.dy = (vPos.y * 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
+ evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
+ evt.mi.dwExtraInfo = 0;
+ evt.mi.mouseData = data;
+ evt.mi.time = 0;
+ if (SendInput(1, &evt, sizeof(evt)) != 1)
+ throw rdr::SystemException("SendInput", GetLastError());
}
}
@@ -174,8 +135,6 @@ BoolParameter rfb::win32::SKeyboard::deadKeyAware("DeadKeyAware",
"Whether to assume the viewer has already interpreted dead key sequences "
"into latin-1 characters", true);
-static bool oneShift;
-
// The keysymToAscii table transforms a couple of awkward keysyms into their
// ASCII equivalents.
struct keysymToAscii_t {
@@ -332,7 +291,6 @@ void doKeyEventWithModifiers(BYTE vkCode, BYTE modifierState, bool down)
win32::SKeyboard::SKeyboard()
{
- oneShift = rfb::win32::osVersion.isPlatformWindows;
for (unsigned int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
vkMap[keymap[i].keysym] = keymap[i].vk;
extendedMap[keymap[i].keysym] = keymap[i].extended;
diff --git a/win/rfb_win32/Security.cxx b/win/rfb_win32/Security.cxx
index cad13256..5df20cd7 100644
--- a/win/rfb_win32/Security.cxx
+++ b/win/rfb_win32/Security.cxx
@@ -19,7 +19,6 @@
// -=- Security.cxx
#include <rfb_win32/Security.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb/LogWriter.h>
#include <lmcons.h>
@@ -155,18 +154,9 @@ Sid::FromToken::FromToken(HANDLE h) {
PACL rfb::win32::CreateACL(const AccessEntries& ae, PACL existing_acl) {
- typedef DWORD (WINAPI *_SetEntriesInAcl_proto) (ULONG, PEXPLICIT_ACCESS, PACL, PACL*);
-#ifdef UNICODE
- const char* fnName = "SetEntriesInAclW";
-#else
- const char* fnName = "SetEntriesInAclA";
-#endif
- DynamicFn<_SetEntriesInAcl_proto> _SetEntriesInAcl(_T("advapi32.dll"), fnName);
- if (!_SetEntriesInAcl.isValid())
- throw rdr::SystemException("CreateACL failed; no SetEntriesInAcl", ERROR_CALL_NOT_IMPLEMENTED);
PACL new_dacl;
DWORD result;
- if ((result = (*_SetEntriesInAcl)(ae.entry_count, ae.entries, existing_acl, &new_dacl)) != ERROR_SUCCESS)
+ if ((result = SetEntriesInAcl(ae.entry_count, ae.entries, existing_acl, &new_dacl)) != ERROR_SUCCESS)
throw rdr::SystemException("SetEntriesInAcl", result);
return new_dacl;
}
diff --git a/win/rfb_win32/Service.cxx b/win/rfb_win32/Service.cxx
index c385fa05..d054ce4d 100644
--- a/win/rfb_win32/Service.cxx
+++ b/win/rfb_win32/Service.cxx
@@ -20,10 +20,8 @@
#include <rfb_win32/Service.h>
#include <rfb_win32/MsgWindow.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb_win32/ModuleFileName.h>
#include <rfb_win32/Registry.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb/Threading.h>
#include <logmessages/messages.h>
#include <rdr/Exception.h>
@@ -66,29 +64,7 @@ VOID WINAPI serviceHandler(DWORD control) {
}
-// -=- Message window derived class used under Win9x to implement stopService
-
-#define WM_SMSG_SERVICE_STOP WM_USER
-
-class ServiceMsgWindow : public MsgWindow {
-public:
- ServiceMsgWindow(const TCHAR* name) : MsgWindow(name) {}
- LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
- switch (msg) {
- case WM_SMSG_SERVICE_STOP:
- service->stop();
- return TRUE;
- }
- return MsgWindow::processMessage(msg, wParam, lParam);
- }
-
- static const TCHAR* baseName;
-};
-
-const TCHAR* ServiceMsgWindow::baseName = _T("ServiceWindow:");
-
-
-// -=- Service main procedure, used under WinNT/2K/XP by the SCM
+// -=- Service main procedure
VOID WINAPI serviceProc(DWORD dwArgc, LPTSTR* lpszArgv) {
vlog.debug("entering %s serviceProc", service->getName());
@@ -124,38 +100,17 @@ Service::Service(const TCHAR* name_) : name(name_) {
void
Service::start() {
- if (osVersion.isPlatformNT) {
- SERVICE_TABLE_ENTRY entry[2];
- entry[0].lpServiceName = (TCHAR*)name;
- entry[0].lpServiceProc = serviceProc;
- entry[1].lpServiceName = NULL;
- entry[1].lpServiceProc = NULL;
- vlog.debug("entering dispatcher");
- if (!SetProcessShutdownParameters(0x100, 0))
- vlog.error("unable to set shutdown parameters: %lu", GetLastError());
- service = this;
- if (!StartServiceCtrlDispatcher(entry))
- throw SystemException("unable to start service", GetLastError());
- } else {
-
- // - Create the service window, so the service can be stopped
- TCharArray wndName(_tcslen(getName()) + _tcslen(ServiceMsgWindow::baseName) + 1);
- _tcscpy(wndName.buf, ServiceMsgWindow::baseName);
- _tcscat(wndName.buf, getName());
- ServiceMsgWindow service_window(wndName.buf);
-
- // - Locate the RegisterServiceProcess function
- typedef DWORD (WINAPI * _RegisterServiceProcess_proto)(DWORD, DWORD);
- DynamicFn<_RegisterServiceProcess_proto> _RegisterServiceProcess(_T("kernel32.dll"), "RegisterServiceProcess");
- if (!_RegisterServiceProcess.isValid())
- throw Exception("unable to find RegisterServiceProcess");
-
- // - Run the service
- (*_RegisterServiceProcess)(NULL, 1);
- service = this;
- serviceMain(0, 0);
- (*_RegisterServiceProcess)(NULL, 0);
- }
+ SERVICE_TABLE_ENTRY entry[2];
+ entry[0].lpServiceName = (TCHAR*)name;
+ entry[0].lpServiceProc = serviceProc;
+ entry[1].lpServiceName = NULL;
+ entry[1].lpServiceProc = NULL;
+ vlog.debug("entering dispatcher");
+ if (!SetProcessShutdownParameters(0x100, 0))
+ vlog.error("unable to set shutdown parameters: %lu", GetLastError());
+ service = this;
+ if (!StartServiceCtrlDispatcher(entry))
+ throw SystemException("unable to start service", GetLastError());
}
void
@@ -165,8 +120,6 @@ Service::setStatus() {
void
Service::setStatus(DWORD state) {
- if (!osVersion.isPlatformNT)
- return;
if (status_handle == 0) {
vlog.debug("warning - cannot setStatus");
return;
@@ -282,65 +235,23 @@ selectInputDesktop() {
bool
rfb::win32::desktopChangeRequired() {
- if (!osVersion.isPlatformNT)
- return false;
-
return !inputDesktopSelected();
}
bool
rfb::win32::changeDesktop() {
- if (!osVersion.isPlatformNT)
- return true;
- if (osVersion.cannotSwitchDesktop)
- return false;
-
return selectInputDesktop();
}
// -=- Ctrl-Alt-Del emulation
-class CADThread : public Thread {
-public:
- CADThread() : Thread("CtrlAltDel Emulator"), result(false) {}
- virtual void run() {
- HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());
-
- if (switchToDesktop(OpenDesktop(_T("Winlogon"), 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
- DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
- DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
- DESKTOP_SWITCHDESKTOP | GENERIC_WRITE))) {
- PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
- switchToDesktop(old_desktop);
- result = true;
- }
- }
- bool result;
-};
-
bool
rfb::win32::emulateCtrlAltDel() {
- if (!osVersion.isPlatformNT)
- return false;
-
- if (osVersion.dwMajorVersion >= 6) {
- rfb::win32::Handle sessionEventCad =
- CreateEvent(0, FALSE, FALSE, "Global\\SessionEventTigerVNCCad");
- SetEvent(sessionEventCad);
- return true;
- }
-
- CADThread* cad_thread = new CADThread();
- vlog.debug("emulate Ctrl-Alt-Del");
- if (cad_thread) {
- cad_thread->start();
- cad_thread->join();
- bool result = cad_thread->result;
- delete cad_thread;
- return result;
- }
- return false;
+ rfb::win32::Handle sessionEventCad =
+ CreateEvent(0, FALSE, FALSE, "Global\\SessionEventTigerVNCCad");
+ SetEvent(sessionEventCad);
+ return true;
}
@@ -379,13 +290,9 @@ static Logger_EventLog* logger = 0;
bool rfb::win32::initEventLogLogger(const TCHAR* srcname) {
if (logger)
return false;
- if (osVersion.isPlatformNT) {
- logger = new Logger_EventLog(srcname);
- logger->registerLogger();
- return true;
- } else {
- return false;
- }
+ logger = new Logger_EventLog(srcname);
+ logger->registerLogger();
+ return true;
}
@@ -398,10 +305,7 @@ bool rfb::win32::registerService(const TCHAR* name,
// - Initialise the default service parameters
const TCHAR* defaultcmdline;
- if (osVersion.isPlatformNT)
- defaultcmdline = _T("-service");
- else
- defaultcmdline = _T("-noconsole -service");
+ defaultcmdline = _T("-service");
// - Get the full pathname of our executable
ModuleFileName buffer;
@@ -424,54 +328,44 @@ bool rfb::win32::registerService(const TCHAR* name,
// - Register the service
- if (osVersion.isPlatformNT) {
-
- // - Open the SCM
- ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
- if (!scm)
- throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
-
- // - Add the service
- ServiceHandle service = CreateService(scm,
- name, display, SC_MANAGER_ALL_ACCESS,
- SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
- SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
- cmdline.buf, NULL, NULL, NULL, NULL, NULL);
- if (!service)
- throw rdr::SystemException("unable to create service", GetLastError());
-
- // - Set a description
- SERVICE_DESCRIPTION sdesc = {(LPTSTR)desc};
- ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sdesc);
-
- // - Register the event log source
- RegKey hk, hk2;
-
- hk2.createKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
- hk.createKey(hk2, name);
-
- for (i=_tcslen(buffer.buf); i>0; i--) {
- if (buffer.buf[i] == _T('\\')) {
- buffer.buf[i+1] = 0;
- break;
- }
+ // - Open the SCM
+ ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+ if (!scm)
+ throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+ // - Add the service
+ ServiceHandle service = CreateService(scm,
+ name, display, SC_MANAGER_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
+ cmdline.buf, NULL, NULL, NULL, NULL, NULL);
+ if (!service)
+ throw rdr::SystemException("unable to create service", GetLastError());
+
+ // - Set a description
+ SERVICE_DESCRIPTION sdesc = {(LPTSTR)desc};
+ ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sdesc);
+
+ // - Register the event log source
+ RegKey hk, hk2;
+
+ hk2.createKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
+ hk.createKey(hk2, name);
+
+ for (i=_tcslen(buffer.buf); i>0; i--) {
+ if (buffer.buf[i] == _T('\\')) {
+ buffer.buf[i+1] = 0;
+ break;
}
+ }
- const TCHAR* dllFilename = _T("logmessages.dll");
- TCharArray dllPath(_tcslen(buffer.buf) + _tcslen(dllFilename) + 1);
- _tcscpy(dllPath.buf, buffer.buf);
- _tcscat(dllPath.buf, dllFilename);
-
- hk.setExpandString(_T("EventMessageFile"), dllPath.buf);
- hk.setInt(_T("TypesSupported"), EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE);
-
- } else {
+ const TCHAR* dllFilename = _T("logmessages.dll");
+ TCharArray dllPath(_tcslen(buffer.buf) + _tcslen(dllFilename) + 1);
+ _tcscpy(dllPath.buf, buffer.buf);
+ _tcscat(dllPath.buf, dllFilename);
- RegKey services;
- services.createKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
- services.setString(name, cmdline.buf);
-
- }
+ hk.setExpandString(_T("EventMessageFile"), dllPath.buf);
+ hk.setInt(_T("TypesSupported"), EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE);
Sleep(500);
@@ -479,32 +373,22 @@ bool rfb::win32::registerService(const TCHAR* name,
}
bool rfb::win32::unregisterService(const TCHAR* name) {
- if (osVersion.isPlatformNT) {
-
- // - Open the SCM
- ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
- if (!scm)
- throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
-
- // - Create the service
- ServiceHandle service = OpenService(scm, name, SC_MANAGER_ALL_ACCESS);
- if (!service)
- throw rdr::SystemException("unable to locate the service", GetLastError());
- if (!DeleteService(service))
- throw rdr::SystemException("unable to remove the service", GetLastError());
-
- // - Register the event log source
- RegKey hk;
- hk.openKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
- hk.deleteKey(name);
-
- } else {
-
- RegKey services;
- services.openKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
- services.deleteValue(name);
-
- }
+ // - Open the SCM
+ ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+ if (!scm)
+ throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+ // - Create the service
+ ServiceHandle service = OpenService(scm, name, SC_MANAGER_ALL_ACCESS);
+ if (!service)
+ throw rdr::SystemException("unable to locate the service", GetLastError());
+ if (!DeleteService(service))
+ throw rdr::SystemException("unable to remove the service", GetLastError());
+
+ // - Register the event log source
+ RegKey hk;
+ hk.openKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application"));
+ hk.deleteKey(name);
Sleep(500);
@@ -514,51 +398,21 @@ bool rfb::win32::unregisterService(const TCHAR* name) {
// -=- Starting and stopping the service
-HWND findServiceWindow(const TCHAR* name) {
- TCharArray wndName(_tcslen(ServiceMsgWindow::baseName)+_tcslen(name)+1);
- _tcscpy(wndName.buf, ServiceMsgWindow::baseName);
- _tcscat(wndName.buf, name);
- vlog.debug("searching for %s window", wndName.buf);
- return FindWindow(0, wndName.buf);
-}
-
bool rfb::win32::startService(const TCHAR* name) {
- if (osVersion.isPlatformNT) {
- // - Open the SCM
- ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (!scm)
- throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
-
- // - Locate the service
- ServiceHandle service = OpenService(scm, name, SERVICE_START);
- if (!service)
- throw rdr::SystemException("unable to open the service", GetLastError());
-
- // - Start the service
- if (!StartService(service, 0, NULL))
- throw rdr::SystemException("unable to start the service", GetLastError());
- } else {
- // - Check there is no service window
- if (findServiceWindow(name))
- throw rdr::Exception("the service is already running");
-
- // - Find the RunServices registry key
- RegKey services;
- services.openKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"));
-
- // - Read the command-line from it
- TCharArray cmdLine(services.getString(name));
-
- // - Start the service
- PROCESS_INFORMATION proc_info;
- STARTUPINFO startup_info;
- ZeroMemory(&startup_info, sizeof(startup_info));
- startup_info.cb = sizeof(startup_info);
- if (!CreateProcess(0, cmdLine.buf, 0, 0, FALSE, CREATE_NEW_CONSOLE, 0, 0, &startup_info, &proc_info)) {
- throw SystemException("unable to start service", GetLastError());
- }
- }
+ // - Open the SCM
+ ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (!scm)
+ throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+ // - Locate the service
+ ServiceHandle service = OpenService(scm, name, SERVICE_START);
+ if (!service)
+ throw rdr::SystemException("unable to open the service", GetLastError());
+
+ // - Start the service
+ if (!StartService(service, 0, NULL))
+ throw rdr::SystemException("unable to start the service", GetLastError());
Sleep(500);
@@ -566,52 +420,20 @@ bool rfb::win32::startService(const TCHAR* name) {
}
bool rfb::win32::stopService(const TCHAR* name) {
- if (osVersion.isPlatformNT) {
- // - Open the SCM
- ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (!scm)
- throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
-
- // - Locate the service
- ServiceHandle service = OpenService(scm, name, SERVICE_STOP);
- if (!service)
- throw rdr::SystemException("unable to open the service", GetLastError());
-
- // - Start the service
- SERVICE_STATUS status;
- if (!ControlService(service, SERVICE_CONTROL_STOP, &status))
- throw rdr::SystemException("unable to stop the service", GetLastError());
-
- } else {
- // - Find the service window
- HWND service_window = findServiceWindow(name);
- if (!service_window)
- throw Exception("unable to locate running service");
-
- // Tell it to quit
- vlog.debug("sending service stop request");
- if (!SendMessage(service_window, WM_SMSG_SERVICE_STOP, 0, 0))
- throw Exception("unable to stop service");
-
- // Check it's quitting...
- DWORD process_id = 0;
- HANDLE process = 0;
- if (!GetWindowThreadProcessId(service_window, &process_id))
- throw SystemException("unable to verify service has quit", GetLastError());
- process = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, process_id);
- if (!process)
- throw SystemException("unable to obtain service handle", GetLastError());
- int retries = 5;
- vlog.debug("checking status");
- while (retries-- && (WaitForSingleObject(process, 1000) != WAIT_OBJECT_0)) {}
- if (!retries) {
- vlog.debug("failed to quit - terminating");
- // May not have quit because of silly Win9x registry watching bug..
- if (!TerminateProcess(process, 1))
- throw SystemException("unable to terminate process!", GetLastError());
- throw Exception("service failed to quit - called TerminateProcess");
- }
- }
+ // - Open the SCM
+ ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (!scm)
+ throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+ // - Locate the service
+ ServiceHandle service = OpenService(scm, name, SERVICE_STOP);
+ if (!service)
+ throw rdr::SystemException("unable to open the service", GetLastError());
+
+ // - Start the service
+ SERVICE_STATUS status;
+ if (!ControlService(service, SERVICE_CONTROL_STOP, &status))
+ throw rdr::SystemException("unable to stop the service", GetLastError());
Sleep(500);
@@ -619,27 +441,22 @@ bool rfb::win32::stopService(const TCHAR* name) {
}
DWORD rfb::win32::getServiceState(const TCHAR* name) {
- if (osVersion.isPlatformNT) {
- // - Open the SCM
- ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (!scm)
- throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
-
- // - Locate the service
- ServiceHandle service = OpenService(scm, name, SERVICE_INTERROGATE);
- if (!service)
- throw rdr::SystemException("unable to open the service", GetLastError());
-
- // - Get the service status
- SERVICE_STATUS status;
- if (!ControlService(service, SERVICE_CONTROL_INTERROGATE, (SERVICE_STATUS*)&status))
- throw rdr::SystemException("unable to query the service", GetLastError());
-
- return status.dwCurrentState;
- } else {
- HWND service_window = findServiceWindow(name);
- return service_window ? SERVICE_RUNNING : SERVICE_STOPPED;
- }
+ // - Open the SCM
+ ServiceHandle scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (!scm)
+ throw rdr::SystemException("unable to open Service Control Manager", GetLastError());
+
+ // - Locate the service
+ ServiceHandle service = OpenService(scm, name, SERVICE_INTERROGATE);
+ if (!service)
+ throw rdr::SystemException("unable to open the service", GetLastError());
+
+ // - Get the service status
+ SERVICE_STATUS status;
+ if (!ControlService(service, SERVICE_CONTROL_INTERROGATE, (SERVICE_STATUS*)&status))
+ throw rdr::SystemException("unable to query the service", GetLastError());
+
+ return status.dwCurrentState;
}
char* rfb::win32::serviceStateName(DWORD state) {
diff --git a/win/rfb_win32/Service.h b/win/rfb_win32/Service.h
index cbb6263d..691ad95d 100644
--- a/win/rfb_win32/Service.h
+++ b/win/rfb_win32/Service.h
@@ -21,8 +21,6 @@
// Win32 service-mode code.
// Derive your service from this code and let it handle the annoying Win32
// service API.
-// The underlying implementation takes care of the differences between
-// Windows NT and Windows 95 based systems
#ifndef __RFB_WIN32_SERVICE_H__
#define __RFB_WIN32_SERVICE_H__
@@ -86,18 +84,14 @@ namespace rfb {
// -=- Routines used by desktop back-end code to manage desktops/window stations
- // Returns false under Win9x
bool desktopChangeRequired();
- // Returns true under Win9x
bool changeDesktop();
// -=- Routines used by the SInput Keyboard class to emulate Ctrl-Alt-Del
- // Returns false under Win9x
bool emulateCtrlAltDel();
// -=- Routines to initialise the Event Log target Logger
- // Returns false under Win9x
bool initEventLogLogger(const TCHAR* srcname);
// -=- Routines to register/unregister the service
diff --git a/win/rfb_win32/TsSessions.cxx b/win/rfb_win32/TsSessions.cxx
index b02f6195..6d16adbf 100644
--- a/win/rfb_win32/TsSessions.cxx
+++ b/win/rfb_win32/TsSessions.cxx
@@ -17,50 +17,28 @@
*/
#include <rfb_win32/TsSessions.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb/LogWriter.h>
#include <rdr/Exception.h>
#include <tchar.h>
-
-#ifdef ERROR_CTX_WINSTATION_BUSY
-#define RFB_HAVE_WINSTATION_CONNECT
-#else
-#pragma message(" NOTE: Not building WinStationConnect support.")
-#endif
+#include <wtsapi32.h>
static rfb::LogWriter vlog("TsSessions");
namespace rfb {
namespace win32 {
- // Windows XP (and later) functions used to handle session Ids
- typedef BOOLEAN (WINAPI *_WinStationConnect_proto) (HANDLE,ULONG,ULONG,PCWSTR,ULONG);
- DynamicFn<_WinStationConnect_proto> _WinStationConnect(_T("winsta.dll"), "WinStationConnectW");
- typedef DWORD (WINAPI *_WTSGetActiveConsoleSessionId_proto) ();
- DynamicFn<_WTSGetActiveConsoleSessionId_proto> _WTSGetActiveConsoleSessionId(_T("kernel32.dll"), "WTSGetActiveConsoleSessionId");
- typedef BOOL (WINAPI *_ProcessIdToSessionId_proto) (DWORD, DWORD*);
- DynamicFn<_ProcessIdToSessionId_proto> _ProcessIdToSessionId(_T("kernel32.dll"), "ProcessIdToSessionId");
- typedef BOOL (WINAPI *_LockWorkStation_proto)();
- DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");
-
-
ProcessSessionId::ProcessSessionId(DWORD processId) {
id = 0;
- if (!_ProcessIdToSessionId.isValid())
- return;
if (processId == (DWORD)-1)
processId = GetCurrentProcessId();
- if (!(*_ProcessIdToSessionId)(GetCurrentProcessId(), &id))
+ if (!ProcessIdToSessionId(GetCurrentProcessId(), &id))
throw rdr::SystemException("ProcessIdToSessionId", GetLastError());
}
ProcessSessionId mySessionId;
ConsoleSessionId::ConsoleSessionId() {
- if (_WTSGetActiveConsoleSessionId.isValid())
- id = (*_WTSGetActiveConsoleSessionId)();
- else
- id = 0;
+ id = WTSGetActiveConsoleSessionId();
}
bool inConsoleSession() {
@@ -69,24 +47,17 @@ namespace win32 {
}
void setConsoleSession(DWORD sessionId) {
-#ifdef RFB_HAVE_WINSTATION_CONNECT
- if (!_WinStationConnect.isValid())
- throw rdr::Exception("WinSta APIs missing");
if (sessionId == (DWORD)-1)
sessionId = mySessionId.id;
// Try to reconnect our session to the console
ConsoleSessionId console;
vlog.info("Console session is %lu", console.id);
- if (!(*_WinStationConnect)(0, sessionId, console.id, L"", 0))
+ if (!WTSConnectSession(sessionId, console.id, (PTSTR)_T(""), 0))
throw rdr::SystemException("Unable to connect session to Console", GetLastError());
// Lock the newly connected session, for security
- if (_LockWorkStation.isValid())
- (*_LockWorkStation)();
-#else
- throw rdr::Exception("setConsoleSession not implemented");
-#endif
+ LockWorkStation();
}
};
diff --git a/win/rfb_win32/WMCursor.cxx b/win/rfb_win32/WMCursor.cxx
index fa158335..0ad96f3a 100644
--- a/win/rfb_win32/WMCursor.cxx
+++ b/win/rfb_win32/WMCursor.cxx
@@ -18,12 +18,7 @@
// -=- WMCursor.cxx
-// *** DOESN'T SEEM TO WORK WITH GetCursorInfo POS CODE BUILT-IN UNDER NT4SP6
-// *** INSTEAD, WE LOOK FOR Win2000/Win98 OR ABOVE
-
#include <rfb_win32/WMCursor.h>
-#include <rfb_win32/OSVersion.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
@@ -33,73 +28,22 @@ using namespace rfb::win32;
static LogWriter vlog("WMCursor");
-
-#ifdef CURSOR_SHOWING
-#define RFB_HAVE_GETCURSORINFO
-#else
-#pragma message(" NOTE: Not building GetCursorInfo support.")
-#endif
-
-#ifdef RFB_HAVE_GETCURSORINFO
-typedef BOOL (WINAPI *_GetCursorInfo_proto)(PCURSORINFO pci);
-DynamicFn<_GetCursorInfo_proto> _GetCursorInfo(_T("user32.dll"), "GetCursorInfo");
-#endif
-
-WMCursor::WMCursor() : hooks(0), use_getCursorInfo(false), cursor(0) {
-#ifdef RFB_HAVE_GETCURSORINFO
- // Check the OS version
- bool is_win98 = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
- ((osVersion.dwMajorVersion > 4) ||
- ((osVersion.dwMajorVersion == 4) && (osVersion.dwMinorVersion > 0)));
- bool is_win2K = (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVersion.dwMajorVersion >= 5);
-
- // Use GetCursorInfo if OS version is sufficient
- use_getCursorInfo = (is_win98 || is_win2K) && _GetCursorInfo.isValid();
-#endif
+WMCursor::WMCursor() : cursor(0) {
cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
- if (!use_getCursorInfo) {
- hooks = new WMCursorHooks();
- if (hooks && hooks->start()) {
- vlog.info("falling back to cursor hooking: %p", hooks);
- } else {
- delete hooks;
- hooks = 0;
- vlog.error("unable to monitor cursor shape");
- }
- } else {
- vlog.info("using GetCursorInfo");
- }
}
WMCursor::~WMCursor() {
- vlog.debug("deleting WMCursorHooks (%p)", hooks);
- if (hooks)
- delete hooks;
}
WMCursor::Info
WMCursor::getCursorInfo() {
Info result;
-#ifdef RFB_HAVE_GETCURSORINFO
- if (use_getCursorInfo) {
- CURSORINFO info;
- info.cbSize = sizeof(CURSORINFO);
- if ((*_GetCursorInfo)(&info)) {
- result.cursor = info.hCursor;
- result.position = Point(info.ptScreenPos.x, info.ptScreenPos.y);
- result.visible = info.flags & CURSOR_SHOWING;
- return result;
- }
- }
-#endif
- // Fall back to the old way of doing things
- POINT pos;
- if (hooks)
- cursor = hooks->getCursor();
- result.cursor = cursor;
- result.visible = cursor != 0;
- GetCursorPos(&pos);
- result.position.x = pos.x;
- result.position.y = pos.y;
+ CURSORINFO info;
+ info.cbSize = sizeof(CURSORINFO);
+ if (!GetCursorInfo(&info))
+ throw rdr::SystemException("GetCursorInfo failed", GetLastError());
+ result.cursor = info.hCursor;
+ result.position = Point(info.ptScreenPos.x, info.ptScreenPos.y);
+ result.visible = info.flags & CURSOR_SHOWING;
return result;
}
diff --git a/win/rfb_win32/WMCursor.h b/win/rfb_win32/WMCursor.h
index 41f9ee84..252cb056 100644
--- a/win/rfb_win32/WMCursor.h
+++ b/win/rfb_win32/WMCursor.h
@@ -50,8 +50,6 @@ namespace rfb {
Info getCursorInfo();
protected:
- WMCursorHooks* hooks;
- bool use_getCursorInfo;
HCURSOR cursor;
};
diff --git a/win/rfb_win32/WMHooks.cxx b/win/rfb_win32/WMHooks.cxx
index 2a3da0d9..0e5e70a4 100644
--- a/win/rfb_win32/WMHooks.cxx
+++ b/win/rfb_win32/WMHooks.cxx
@@ -19,7 +19,6 @@
// -=- WMHooks.cxx
#include <rfb_win32/WMHooks.h>
-#include <rfb_win32/DynamicFn.h>
#include <rfb_win32/Service.h>
#include <rfb_win32/MsgWindow.h>
#include <rfb_win32/IntervalTimer.h>
@@ -34,52 +33,106 @@ using namespace rfb::win32;
static LogWriter vlog("WMHooks");
+static HMODULE hooksLibrary;
+
typedef UINT (*WM_Hooks_WMVAL_proto)();
+static WM_Hooks_WMVAL_proto WM_Hooks_WindowChanged;
+static WM_Hooks_WMVAL_proto WM_Hooks_WindowBorderChanged;
+static WM_Hooks_WMVAL_proto WM_Hooks_WindowClientAreaChanged;
+static WM_Hooks_WMVAL_proto WM_Hooks_RectangleChanged;
+#ifdef _DEBUG
+static WM_Hooks_WMVAL_proto WM_Hooks_Diagnostic;
+#endif
+
typedef BOOL (*WM_Hooks_Install_proto)(DWORD owner, DWORD thread);
+static WM_Hooks_Install_proto WM_Hooks_Install;
typedef BOOL (*WM_Hooks_Remove_proto)(DWORD owner);
-typedef BOOL (*WM_Hooks_EnableCursorShape_proto)(BOOL enable);
+static WM_Hooks_Remove_proto WM_Hooks_Remove;
#ifdef _DEBUG
typedef void (*WM_Hooks_SetDiagnosticRange_proto)(UINT min, UINT max);
-DynamicFn<WM_Hooks_SetDiagnosticRange_proto> WM_Hooks_SetDiagnosticRange(_T("wm_hooks.dll"), "WM_Hooks_SetDiagnosticRange");
+static WM_Hooks_SetDiagnosticRange_proto WM_Hooks_SetDiagnosticRange;
+#endif
+
+typedef BOOL (*WM_Hooks_EnableRealInputs_proto)(BOOL pointer, BOOL keyboard);
+static WM_Hooks_EnableRealInputs_proto WM_Hooks_EnableRealInputs;
+
+
+static void LoadHooks()
+{
+ if (hooksLibrary != NULL)
+ return;
+
+ hooksLibrary = LoadLibrary("wm_hooks.dll");
+ if (hooksLibrary == NULL)
+ return;
+
+ WM_Hooks_WindowChanged = (WM_Hooks_WMVAL_proto)GetProcAddress(hooksLibrary, "WM_Hooks_WindowChanged");
+ if (WM_Hooks_WindowChanged == NULL)
+ goto error;
+ WM_Hooks_WindowBorderChanged = (WM_Hooks_WMVAL_proto)GetProcAddress(hooksLibrary, "WM_Hooks_WindowBorderChanged");
+ if (WM_Hooks_WindowBorderChanged == NULL)
+ goto error;
+ WM_Hooks_WindowClientAreaChanged = (WM_Hooks_WMVAL_proto)GetProcAddress(hooksLibrary, "WM_Hooks_WindowClientAreaChanged");
+ if (WM_Hooks_WindowClientAreaChanged == NULL)
+ goto error;
+ WM_Hooks_RectangleChanged = (WM_Hooks_WMVAL_proto)GetProcAddress(hooksLibrary, "WM_Hooks_RectangleChanged");
+ if (WM_Hooks_RectangleChanged == NULL)
+ goto error;
+#ifdef _DEBUG
+ WM_Hooks_Diagnostic = (WM_Hooks_WMVAL_proto)GetProcAddress(hooksLibrary, "WM_Hooks_Diagnostic");
+ if (WM_Hooks_Diagnostic == NULL)
+ goto error;
+#endif
+
+ WM_Hooks_Install = (WM_Hooks_Install_proto)GetProcAddress(hooksLibrary, "WM_Hooks_Install");
+ if (WM_Hooks_Install == NULL)
+ goto error;
+ WM_Hooks_Remove = (WM_Hooks_Remove_proto)GetProcAddress(hooksLibrary, "WM_Hooks_Remove");
+ if (WM_Hooks_Remove == NULL)
+ goto error;
+#ifdef _DEBUG
+ WM_Hooks_SetDiagnosticRange = (WM_Hooks_SetDiagnosticRange_proto)GetProcAddress(hooksLibrary, "WM_Hooks_SetDiagnosticRange");
+ if (WM_Hooks_SetDiagnosticRange == NULL)
+ goto error;
#endif
+ WM_Hooks_EnableRealInputs = (WM_Hooks_EnableRealInputs_proto)GetProcAddress(hooksLibrary, "WM_Hooks_EnableRealInputs");
+ if (WM_Hooks_EnableRealInputs == NULL)
+ goto error;
+
+ return;
+
+error:
+ FreeLibrary(hooksLibrary);
+ hooksLibrary = NULL;
+}
+
class WMHooksThread : public Thread {
public:
WMHooksThread() : Thread("WMHookThread"),
- WM_Hooks_Install(_T("wm_hooks.dll"), "WM_Hooks_Install"),
- WM_Hooks_Remove(_T("wm_hooks.dll"), "WM_Hooks_Remove"),
- WM_Hooks_EnableCursorShape(_T("wm_hooks.dll"), "WM_Hooks_EnableCursorShape"),
active(true) {
}
virtual void run();
virtual Thread* join();
- DynamicFn<WM_Hooks_Install_proto> WM_Hooks_Install;;
- DynamicFn<WM_Hooks_Remove_proto> WM_Hooks_Remove;
- DynamicFn<WM_Hooks_EnableCursorShape_proto> WM_Hooks_EnableCursorShape;
protected:
bool active;
};
-WMHooksThread* hook_mgr = 0;
-std::list<WMHooks*> hooks;
-std::list<WMCursorHooks*> cursor_hooks;
-Mutex hook_mgr_lock;
-HCURSOR hook_cursor = (HCURSOR)LoadImage(0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+static WMHooksThread* hook_mgr = 0;
+static std::list<WMHooks*> hooks;
+static Mutex hook_mgr_lock;
static bool StartHookThread() {
if (hook_mgr)
return true;
+ if (hooksLibrary == NULL)
+ return false;
vlog.debug("creating thread");
hook_mgr = new WMHooksThread();
- if (!hook_mgr->WM_Hooks_Install.isValid() ||
- !hook_mgr->WM_Hooks_Remove.isValid()) {
- vlog.debug("hooks not available");
- return false;
- }
vlog.debug("installing hooks");
- if (!(*hook_mgr->WM_Hooks_Install)(hook_mgr->getThreadId(), 0)) {
+ if (!WM_Hooks_Install(hook_mgr->getThreadId(), 0)) {
vlog.error("failed to initialise hooks");
delete hook_mgr->join();
hook_mgr = 0;
@@ -93,7 +146,7 @@ static bool StartHookThread() {
static void StopHookThread() {
if (!hook_mgr)
return;
- if (!hooks.empty() || !cursor_hooks.empty())
+ if (!hooks.empty())
return;
vlog.debug("closing thread");
delete hook_mgr->join();
@@ -110,19 +163,6 @@ static bool AddHook(WMHooks* hook) {
return true;
}
-static bool AddCursorHook(WMCursorHooks* hook) {
- vlog.debug("adding cursor hook");
- Lock l(hook_mgr_lock);
- if (!StartHookThread())
- return false;
- if (!hook_mgr->WM_Hooks_EnableCursorShape.isValid())
- return false;
- if (cursor_hooks.empty() && !(*hook_mgr->WM_Hooks_EnableCursorShape)(TRUE))
- return false;
- cursor_hooks.push_back(hook);
- return true;
-}
-
static bool RemHook(WMHooks* hook) {
{
vlog.debug("removing hook");
@@ -133,19 +173,6 @@ static bool RemHook(WMHooks* hook) {
return true;
}
-static bool RemCursorHook(WMCursorHooks* hook) {
- {
- vlog.debug("removing cursor hook");
- Lock l(hook_mgr_lock);
- cursor_hooks.remove(hook);
- if (hook_mgr->WM_Hooks_EnableCursorShape.isValid() &&
- cursor_hooks.empty())
- (*hook_mgr->WM_Hooks_EnableCursorShape)(FALSE);
- }
- StopHookThread();
- return true;
-}
-
static void NotifyHooksRegion(const Region& r) {
Lock l(hook_mgr_lock);
std::list<WMHooks*>::iterator i;
@@ -153,34 +180,16 @@ static void NotifyHooksRegion(const Region& r) {
(*i)->NotifyHooksRegion(r);
}
-static void NotifyHooksCursor(HCURSOR c) {
- Lock l(hook_mgr_lock);
- hook_cursor = c;
-}
-
-
-static UINT GetMsgVal(DynamicFn<WM_Hooks_WMVAL_proto>& fn) {
- if (fn.isValid())
- return (*fn)();
- return WM_NULL;
-}
void
WMHooksThread::run() {
// Obtain message ids for all supported hook messages
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_WindowChanged(_T("wm_hooks.dll"), "WM_Hooks_WindowChanged");
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_WindowBorderChanged(_T("wm_hooks.dll"), "WM_Hooks_WindowBorderChanged");
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_WindowClientAreaChanged(_T("wm_hooks.dll"), "WM_Hooks_WindowClientAreaChanged");
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_RectangleChanged(_T("wm_hooks.dll"), "WM_Hooks_RectangleChanged");
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_CursorChanged(_T("wm_hooks.dll"), "WM_Hooks_CursorChanged");
- UINT windowMsg = GetMsgVal(WM_Hooks_WindowChanged);
- UINT clientAreaMsg = GetMsgVal(WM_Hooks_WindowClientAreaChanged);
- UINT borderMsg = GetMsgVal(WM_Hooks_WindowBorderChanged);
- UINT rectangleMsg = GetMsgVal(WM_Hooks_RectangleChanged);
- UINT cursorMsg = GetMsgVal(WM_Hooks_CursorChanged);
+ UINT windowMsg = WM_Hooks_WindowChanged();
+ UINT clientAreaMsg = WM_Hooks_WindowClientAreaChanged();
+ UINT borderMsg = WM_Hooks_WindowBorderChanged();
+ UINT rectangleMsg = WM_Hooks_RectangleChanged();
#ifdef _DEBUG
- DynamicFn<WM_Hooks_WMVAL_proto> WM_Hooks_Diagnostic(_T("wm_hooks.dll"), "WM_Hooks_Diagnostic");
- UINT diagnosticMsg = GetMsgVal(WM_Hooks_Diagnostic);
+ UINT diagnosticMsg = WM_Hooks_Diagnostic();
#endif
MSG msg;
RECT wrect;
@@ -261,8 +270,6 @@ WMHooksThread::run() {
updateDelayTimer.start(updateDelayMs);
}
- } else if (msg.message == cursorMsg) {
- NotifyHooksCursor((HCURSOR)msg.lParam);
#ifdef _DEBUG
} else if (msg.message == diagnosticMsg) {
vlog.info("DIAG msg=%x(%d) wnd=%lx",
@@ -273,7 +280,7 @@ WMHooksThread::run() {
}
vlog.debug("stopping hook thread - processed %d events", count);
- (*WM_Hooks_Remove)(getThreadId());
+ WM_Hooks_Remove(getThreadId());
}
Thread*
@@ -288,6 +295,7 @@ WMHooksThread::join() {
// -=- WMHooks class
rfb::win32::WMHooks::WMHooks() : updateEvent(0) {
+ LoadHooks();
}
rfb::win32::WMHooks::~WMHooks() {
@@ -310,16 +318,10 @@ bool rfb::win32::WMHooks::getUpdates(UpdateTracker* ut) {
return true;
}
-bool rfb::win32::WMHooks::areAvailable() {
- WMHooksThread wmht;
- return wmht.WM_Hooks_Install.isValid();
-}
-
#ifdef _DEBUG
void
rfb::win32::WMHooks::setDiagnosticRange(UINT min, UINT max) {
- if (WM_Hooks_SetDiagnosticRange.isValid())
- (*WM_Hooks_SetDiagnosticRange)(min, max);
+ WM_Hooks_SetDiagnosticRange(min, max);
}
#endif
@@ -334,32 +336,31 @@ void rfb::win32::WMHooks::NotifyHooksRegion(const Region& r) {
// -=- WMBlockInput class
rfb::win32::WMBlockInput::WMBlockInput() : active(false) {
+ LoadHooks();
}
rfb::win32::WMBlockInput::~WMBlockInput() {
blockInputs(false);
}
-typedef BOOL (*WM_Hooks_EnableRealInputs_proto)(BOOL pointer, BOOL keyboard);
-DynamicFn<WM_Hooks_EnableRealInputs_proto>* WM_Hooks_EnableRealInputs = 0;
+static bool blocking = false;
static bool blockRealInputs(bool block_) {
// NB: Requires blockMutex to be held!
+ if (hooksLibrary == NULL)
+ return false;
if (block_) {
- if (WM_Hooks_EnableRealInputs)
+ if (blocking)
return true;
// Enable blocking
- WM_Hooks_EnableRealInputs = new DynamicFn<WM_Hooks_EnableRealInputs_proto>(_T("wm_hooks.dll"), "WM_Hooks_EnableRealInputs");
- if (WM_Hooks_EnableRealInputs->isValid() && (**WM_Hooks_EnableRealInputs)(false, false))
- return true;
+ if (!WM_Hooks_EnableRealInputs(false, false))
+ return false;
+ blocking = true;
}
- if (WM_Hooks_EnableRealInputs) {
- // Clean up the DynamicFn, either if init failed, or block_ is false
- if (WM_Hooks_EnableRealInputs->isValid())
- (**WM_Hooks_EnableRealInputs)(true, true);
- delete WM_Hooks_EnableRealInputs;
- WM_Hooks_EnableRealInputs = 0;
+ if (blocking) {
+ WM_Hooks_EnableRealInputs(true, true);
+ blocking = false;
}
- return block_ == (WM_Hooks_EnableRealInputs != 0);
+ return block_ == blocking;
}
Mutex blockMutex;
@@ -375,23 +376,3 @@ bool rfb::win32::WMBlockInput::blockInputs(bool on) {
active = on;
return true;
}
-
-
-// -=- WMCursorHooks class
-
-rfb::win32::WMCursorHooks::WMCursorHooks() {
-}
-
-rfb::win32::WMCursorHooks::~WMCursorHooks() {
- RemCursorHook(this);
-}
-
-bool
-rfb::win32::WMCursorHooks::start() {
- return AddCursorHook(this);
-}
-
-HCURSOR
-rfb::win32::WMCursorHooks::getCursor() const {
- return hook_cursor;
-}
diff --git a/win/rfb_win32/WMHooks.h b/win/rfb_win32/WMHooks.h
index 4713b416..c1dbd5f3 100644
--- a/win/rfb_win32/WMHooks.h
+++ b/win/rfb_win32/WMHooks.h
@@ -47,9 +47,6 @@ namespace rfb {
// were added, false otherwise.
bool getUpdates(UpdateTracker* ut);
- // Determine whether the hooks DLL is installed on the system
- static bool areAvailable();
-
#ifdef _DEBUG
// Get notifications of any messages in the given range, to any hooked window
void setDiagnosticRange(UINT min, UINT max);
@@ -74,17 +71,6 @@ namespace rfb {
bool active;
};
- // - Legacy cursor handling support
- class WMCursorHooks {
- public:
- WMCursorHooks();
- ~WMCursorHooks();
-
- bool start();
-
- HCURSOR getCursor() const;
- };
-
};
};
diff --git a/win/vncconfig/Authentication.h b/win/vncconfig/Authentication.h
index c2aba91e..7fa85a2f 100644
--- a/win/vncconfig/Authentication.h
+++ b/win/vncconfig/Authentication.h
@@ -21,7 +21,6 @@
#include <vncconfig/PasswordDialog.h>
#include <rfb_win32/Registry.h>
#include <rfb_win32/SecurityPage.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb_win32/MsgBox.h>
#include <rfb/ServerCore.h>
#include <rfb/Security.h>
@@ -87,7 +86,7 @@ namespace rfb {
registryInsecure = warn;
}
bool enableQueryOnlyIfLoggedOn() {
- return isItemChecked(IDC_QUERY_CONNECT) && osVersion.isPlatformNT && (osVersion.dwMajorVersion >= 5);
+ return isItemChecked(IDC_QUERY_CONNECT);
}
diff --git a/win/vncconfig/Desktop.h b/win/vncconfig/Desktop.h
index 6479cb26..1a687d74 100644
--- a/win/vncconfig/Desktop.h
+++ b/win/vncconfig/Desktop.h
@@ -21,7 +21,6 @@
#include <rfb_win32/Registry.h>
#include <rfb_win32/Dialog.h>
#include <rfb_win32/SDisplay.h>
-#include <rfb_win32/DynamicFn.h>
namespace rfb {
@@ -35,20 +34,10 @@ namespace rfb {
CharArray action(rfb::win32::SDisplay::disconnectAction.getData());
bool disconnectLock = stricmp(action.buf, "Lock") == 0;
bool disconnectLogoff = stricmp(action.buf, "Logoff") == 0;
- typedef BOOL (WINAPI *_LockWorkStation_proto)();
- DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");
- if (!_LockWorkStation.isValid()) {
- enableItem(IDC_DISCONNECT_LOCK, false);
- if (disconnectLock) {
- disconnectLogoff = true;
- disconnectLock = false;
- }
- }
setItemChecked(IDC_DISCONNECT_LOGOFF, disconnectLogoff);
setItemChecked(IDC_DISCONNECT_LOCK, disconnectLock);
setItemChecked(IDC_DISCONNECT_NONE, !disconnectLock && !disconnectLogoff);
setItemChecked(IDC_REMOVE_WALLPAPER, rfb::win32::SDisplay::removeWallpaper);
- setItemChecked(IDC_REMOVE_PATTERN, rfb::win32::SDisplay::removePattern);
setItemChecked(IDC_DISABLE_EFFECTS, rfb::win32::SDisplay::disableEffects);
}
bool onCommand(int id, int cmd) {
@@ -57,7 +46,6 @@ namespace rfb {
case IDC_DISCONNECT_LOCK:
case IDC_DISCONNECT_NONE:
case IDC_REMOVE_WALLPAPER:
- case IDC_REMOVE_PATTERN:
case IDC_DISABLE_EFFECTS:
CharArray action(rfb::win32::SDisplay::disconnectAction.getData());
bool disconnectLock = stricmp(action.buf, "Lock") == 0;
@@ -65,7 +53,6 @@ namespace rfb {
setChanged((disconnectLogoff != isItemChecked(IDC_DISCONNECT_LOGOFF)) ||
(disconnectLock != isItemChecked(IDC_DISCONNECT_LOCK)) ||
(isItemChecked(IDC_REMOVE_WALLPAPER) != rfb::win32::SDisplay::removeWallpaper) ||
- (isItemChecked(IDC_REMOVE_PATTERN) != rfb::win32::SDisplay::removePattern) ||
(isItemChecked(IDC_DISABLE_EFFECTS) != rfb::win32::SDisplay::disableEffects));
break;
}
@@ -79,7 +66,6 @@ namespace rfb {
action = _T("Lock");
regKey.setString(_T("DisconnectAction"), action);
regKey.setBool(_T("RemoveWallpaper"), isItemChecked(IDC_REMOVE_WALLPAPER));
- regKey.setBool(_T("RemovePattern"), isItemChecked(IDC_REMOVE_PATTERN));
regKey.setBool(_T("DisableEffects"), isItemChecked(IDC_DISABLE_EFFECTS));
return true;
}
diff --git a/win/vncconfig/Hooking.h b/win/vncconfig/Hooking.h
index b8137ddc..f5ef8b74 100644
--- a/win/vncconfig/Hooking.h
+++ b/win/vncconfig/Hooking.h
@@ -34,13 +34,9 @@ namespace rfb {
: PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_HOOKING)), regKey(rk) {}
void initDialog() {
setItemChecked(IDC_USEPOLLING, rfb::win32::SDisplay::updateMethod == 0);
- setItemChecked(IDC_USEHOOKS, (rfb::win32::SDisplay::updateMethod == 1) &&
- rfb::win32::SDisplay::areHooksAvailable());
- enableItem(IDC_USEHOOKS, rfb::win32::SDisplay::areHooksAvailable());
+ setItemChecked(IDC_USEHOOKS, (rfb::win32::SDisplay::updateMethod == 1));
setItemChecked(IDC_POLLCONSOLES, rfb::win32::WMPoller::poll_console_windows);
- setItemChecked(IDC_CAPTUREBLT, osVersion.isPlatformNT &&
- rfb::win32::DeviceFrameBuffer::useCaptureBlt);
- enableItem(IDC_CAPTUREBLT, osVersion.isPlatformNT);
+ setItemChecked(IDC_CAPTUREBLT, rfb::win32::DeviceFrameBuffer::useCaptureBlt);
onCommand(IDC_USEHOOKS, 0);
}
bool onCommand(int id, int cmd) {
diff --git a/win/vncconfig/Inputs.h b/win/vncconfig/Inputs.h
index 1e0b4bac..2ad3b425 100644
--- a/win/vncconfig/Inputs.h
+++ b/win/vncconfig/Inputs.h
@@ -25,7 +25,6 @@
#include <rfb_win32/Registry.h>
#include <rfb_win32/Dialog.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb/ServerCore.h>
namespace rfb {
@@ -42,7 +41,6 @@ namespace rfb {
setItemChecked(IDC_ACCEPT_CUTTEXT, rfb::Server::acceptCutText);
setItemChecked(IDC_SEND_CUTTEXT, rfb::Server::sendCutText);
setItemChecked(IDC_DISABLE_LOCAL_INPUTS, SDisplay::disableLocalInputs);
- enableItem(IDC_DISABLE_LOCAL_INPUTS, !osVersion.isPlatformWindows);
BOOL blocked = FALSE;
if (SystemParametersInfo(SPI_GETBLOCKSENDINPUTRESETS, 0, &blocked, 0))
setItemChecked(IDC_AFFECT_SCREENSAVER, !blocked);
diff --git a/win/vncconfig/Legacy.cxx b/win/vncconfig/Legacy.cxx
index f8c20280..7d51de81 100644
--- a/win/vncconfig/Legacy.cxx
+++ b/win/vncconfig/Legacy.cxx
@@ -206,8 +206,7 @@ void LegacyPage::LoadPrefs()
regKey.setInt(_T("IdleTimeout"), key.getInt(_T("IdleTimeout"), 0));
regKey.setBool(_T("RemoveWallpaper"), key.getBool(_T("RemoveWallpaper")));
- regKey.setBool(_T("RemovePattern"), key.getBool(_T("RemoveWallpaper")));
- regKey.setBool(_T("DisableEffects"), key.getBool(_T("RemoveWallpaper")));
+ regKey.setBool(_T("DisableEffects"), key.getBool(_T("DisableEffects")));
if (key.getInt(_T("QuerySetting"), 2) != 2) {
regKey.setBool(_T("QueryConnect"), key.getInt(_T("QuerySetting")) > 2);
diff --git a/win/vncconfig/resource.h b/win/vncconfig/resource.h
index 7b8e6479..243f8247 100644
--- a/win/vncconfig/resource.h
+++ b/win/vncconfig/resource.h
@@ -64,7 +64,6 @@
#define IDC_DISCONNECT_LOCK 1057
#define IDC_DISCONNECT_LOGOFF 1058
#define IDC_REMOVE_WALLPAPER 1059
-#define IDC_REMOVE_PATTERN 1060
#define IDC_DISABLE_EFFECTS 1061
#define IDC_CAPTUREBLT 1062
#define IDC_QUERY 1064
diff --git a/win/vncconfig/vncconfig.cxx b/win/vncconfig/vncconfig.cxx
index b1d0eef3..18045c77 100644
--- a/win/vncconfig/vncconfig.cxx
+++ b/win/vncconfig/vncconfig.cxx
@@ -135,7 +135,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, char* cmdLine, int cmdShow) {
} else if (e.err != ERROR_CALL_NOT_IMPLEMENTED &&
e.err != ERROR_NOT_LOGGED_ON) {
// If the call is not implemented, ignore the error and continue
- // If we are on Win9x and no user is logged on, ignore error and continue
throw;
}
warnOnChangePassword = true;
diff --git a/win/vncconfig/vncconfig.rc b/win/vncconfig/vncconfig.rc
index ebcf7209..ae1057a8 100644
--- a/win/vncconfig/vncconfig.rc
+++ b/win/vncconfig/vncconfig.rc
@@ -241,20 +241,18 @@ STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CONTROL | WS_POPUP | WS_CAPTION |
CAPTION "Desktop"
FONT 8, "MS Sans Serif"
BEGIN
- GROUPBOX "While connected",IDC_STATIC,7,5,171,60
+ GROUPBOX "While connected",IDC_STATIC,7,5,171,45
CONTROL "Remove wallpaper",IDC_REMOVE_WALLPAPER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,15,15,155,15
- CONTROL "Remove background pattern",IDC_REMOVE_PATTERN,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,15,30,155,15
CONTROL "Disable user interface effects",IDC_DISABLE_EFFECTS,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,46,155,14
- GROUPBOX "When last client disconnects",IDC_STATIC,7,70,171,60
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,30,155,14
+ GROUPBOX "When last client disconnects",IDC_STATIC,7,55,171,60
CONTROL "Do nothing",IDC_DISCONNECT_NONE,"Button",
- BS_AUTORADIOBUTTON,15,80,155,15
+ BS_AUTORADIOBUTTON,15,65,155,15
CONTROL "Lock workstation",IDC_DISCONNECT_LOCK,"Button",
- BS_AUTORADIOBUTTON,15,95,155,15
+ BS_AUTORADIOBUTTON,15,80,155,15
CONTROL "Logoff user",IDC_DISCONNECT_LOGOFF,"Button",
- BS_AUTORADIOBUTTON,15,110,155,15
+ BS_AUTORADIOBUTTON,15,95,155,15
END
diff --git a/win/winvnc/VNCServerService.cxx b/win/winvnc/VNCServerService.cxx
index 0357677a..5656de04 100644
--- a/win/winvnc/VNCServerService.cxx
+++ b/win/winvnc/VNCServerService.cxx
@@ -19,9 +19,9 @@
// -=- WinVNC Version 4.0 Service-Mode implementation
#include <winvnc/VNCServerService.h>
-#include <rfb_win32/OSVersion.h>
#include <rfb_win32/TsSessions.h>
#include <rfb_win32/ModuleFileName.h>
+#include <windows.h>
#include <wtsapi32.h>
#include <tlhelp32.h>
@@ -31,19 +31,25 @@ using namespace win32;
const TCHAR* winvnc::VNCServerService::Name = _T("TigerVNC");
+// SendSAS is not available until Windows 7, and missing from MinGW
+static HMODULE sasLibrary = NULL;
+typedef void WINAPI (*SendSAS_proto)(BOOL AsUser);
+static SendSAS_proto _SendSAS = NULL;
+
VNCServerService::VNCServerService()
: Service(Name)
- , SendSas(_T("sas.dll"), "SendSAS")
, stopServiceEvent(CreateEvent(0, FALSE, FALSE, 0))
, sessionEvent(CreateEvent(0, FALSE, FALSE, "Global\\SessionEventTigerVNC"))
, sessionEventCad(CreateEvent(0, FALSE, FALSE, "Global\\SessionEventTigerVNCCad")) {
+ if (sasLibrary == NULL) {
+ sasLibrary = LoadLibrary("sas.dll");
+ if (sasLibrary != NULL)
+ _SendSAS = (SendSAS_proto)GetProcAddress(sasLibrary, "SendSAS");
+ }
// - 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");
+ logParams.setParam("*:EventLog:0,Connections:EventLog:100");
}
@@ -136,8 +142,8 @@ DWORD VNCServerService::serviceMain(int argc, TCHAR* argv[])
//cad request
case WAIT_OBJECT_0 + 1:
- if (SendSas.isValid())
- (*SendSas)(FALSE);
+ if (_SendSAS != NULL)
+ _SendSAS(FALSE);
break;
case WAIT_TIMEOUT:
diff --git a/win/winvnc/VNCServerService.h b/win/winvnc/VNCServerService.h
index a55a7294..8cb82c29 100644
--- a/win/winvnc/VNCServerService.h
+++ b/win/winvnc/VNCServerService.h
@@ -21,7 +21,6 @@
#include <winvnc/VNCServerWin32.h>
#include <rfb_win32/Service.h>
-#include <rfb_win32/DynamicFn.h>
namespace winvnc {
@@ -34,7 +33,6 @@ namespace winvnc {
static const TCHAR* Name;
protected:
- rfb::win32::DynamicFn<void (WINAPI *)(BOOL)> SendSas;
rfb::win32::Handle stopServiceEvent;
rfb::win32::Handle sessionEvent;
rfb::win32::Handle sessionEventCad;