blob: b02f6195fe7e0bd3f2cb68f8456d607d69d78660 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19#include <rfb_win32/TsSessions.h>
20#include <rfb_win32/DynamicFn.h>
21#include <rfb/LogWriter.h>
22#include <rdr/Exception.h>
23#include <tchar.h>
24
25#ifdef ERROR_CTX_WINSTATION_BUSY
26#define RFB_HAVE_WINSTATION_CONNECT
27#else
28#pragma message(" NOTE: Not building WinStationConnect support.")
29#endif
30
31static rfb::LogWriter vlog("TsSessions");
32
33namespace rfb {
34namespace win32 {
35
36 // Windows XP (and later) functions used to handle session Ids
37 typedef BOOLEAN (WINAPI *_WinStationConnect_proto) (HANDLE,ULONG,ULONG,PCWSTR,ULONG);
38 DynamicFn<_WinStationConnect_proto> _WinStationConnect(_T("winsta.dll"), "WinStationConnectW");
39 typedef DWORD (WINAPI *_WTSGetActiveConsoleSessionId_proto) ();
40 DynamicFn<_WTSGetActiveConsoleSessionId_proto> _WTSGetActiveConsoleSessionId(_T("kernel32.dll"), "WTSGetActiveConsoleSessionId");
41 typedef BOOL (WINAPI *_ProcessIdToSessionId_proto) (DWORD, DWORD*);
42 DynamicFn<_ProcessIdToSessionId_proto> _ProcessIdToSessionId(_T("kernel32.dll"), "ProcessIdToSessionId");
43 typedef BOOL (WINAPI *_LockWorkStation_proto)();
44 DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");
45
46
47 ProcessSessionId::ProcessSessionId(DWORD processId) {
48 id = 0;
49 if (!_ProcessIdToSessionId.isValid())
50 return;
Pierre Ossman5c23b9e2015-03-03 16:26:03 +010051 if (processId == (DWORD)-1)
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000052 processId = GetCurrentProcessId();
53 if (!(*_ProcessIdToSessionId)(GetCurrentProcessId(), &id))
54 throw rdr::SystemException("ProcessIdToSessionId", GetLastError());
55 }
56
57 ProcessSessionId mySessionId;
58
59 ConsoleSessionId::ConsoleSessionId() {
60 if (_WTSGetActiveConsoleSessionId.isValid())
61 id = (*_WTSGetActiveConsoleSessionId)();
62 else
63 id = 0;
64 }
65
66 bool inConsoleSession() {
67 ConsoleSessionId console;
68 return console.id == mySessionId.id;
69 }
70
71 void setConsoleSession(DWORD sessionId) {
72#ifdef RFB_HAVE_WINSTATION_CONNECT
73 if (!_WinStationConnect.isValid())
74 throw rdr::Exception("WinSta APIs missing");
Pierre Ossman5c23b9e2015-03-03 16:26:03 +010075 if (sessionId == (DWORD)-1)
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000076 sessionId = mySessionId.id;
77
78 // Try to reconnect our session to the console
79 ConsoleSessionId console;
Pierre Ossmanfb450fb2015-03-03 16:34:56 +010080 vlog.info("Console session is %lu", console.id);
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000081 if (!(*_WinStationConnect)(0, sessionId, console.id, L"", 0))
82 throw rdr::SystemException("Unable to connect session to Console", GetLastError());
83
84 // Lock the newly connected session, for security
85 if (_LockWorkStation.isValid())
86 (*_LockWorkStation)();
87#else
88 throw rdr::Exception("setConsoleSession not implemented");
89#endif
90 }
91
92};
93};