blob: 1a244853e94a9d12468128333722069ff2a22e76 [file] [log] [blame]
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001/* Copyright (C) 2002-2004 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// -=- Currentuser.cxx
20
21#include <windows.h>
22#include <lmcons.h>
23#include <rfb_win32/CurrentUser.h>
24#include <rfb_win32/Service.h>
25#include <rfb_win32/OSVersion.h>
26
27using namespace rfb;
28using namespace win32;
29
30
31CurrentUserToken::CurrentUserToken() : isValid_(false) {
32 // - If the OS doesn't support security, ignore it
33 if (!isServiceProcess()) {
34 // - Running in User-Mode - just get our current token
35 if (!OpenProcessToken(GetCurrentProcess(), GENERIC_ALL, &h)) {
36 DWORD err = GetLastError();
37 if (err != ERROR_CALL_NOT_IMPLEMENTED)
38 throw rdr::SystemException("OpenProcessToken failed", GetLastError());
39 }
40 isValid_ = true;
41 } else {
42 // - Under XP/2003 and above, we can just ask the operating system
43 typedef BOOL (WINAPI *WTSQueryUserToken_proto)(ULONG, PHANDLE);
44 DynamicFn<WTSQueryUserToken_proto> _WTSQueryUserToken(_T("wtsapi32.dll"), "WTSQueryUserToken");
45 if (_WTSQueryUserToken.isValid()) {
46 (*_WTSQueryUserToken)(-1, &h);
47 isValid_ = true;
48 } else {
49 // - Under NT/2K we have to resort to a nasty hack...
50 HWND tray = FindWindow(_T("Shell_TrayWnd"), 0);
51 if (!tray)
52 return;
53 DWORD processId = 0;
54 GetWindowThreadProcessId(tray, &processId);
55 if (!processId)
56 return;
57 Handle process = OpenProcess(MAXIMUM_ALLOWED, FALSE, processId);
58 if (!process.h)
59 return;
60 OpenProcessToken(process, MAXIMUM_ALLOWED, &h);
61 isValid_ = true;
62 }
63 }
64}
65
66
67ImpersonateCurrentUser::ImpersonateCurrentUser() {
68 RegCloseKey(HKEY_CURRENT_USER);
69 if (!isServiceProcess())
70 return;
71 if (!token.isValid())
72 throw rdr::Exception("CurrentUserToken is not valid");
73 if (!ImpersonateLoggedOnUser(token)) {
74 DWORD err = GetLastError();
75 if (err != ERROR_CALL_NOT_IMPLEMENTED)
76 throw rdr::SystemException("Failed to impersonate user", GetLastError());
77 }
78}
79
80ImpersonateCurrentUser::~ImpersonateCurrentUser() {
81 if (!RevertToSelf()) {
82 DWORD err = GetLastError();
83 if (err != ERROR_CALL_NOT_IMPLEMENTED)
84 exit(err);
85 }
86}
87
88
89UserName::UserName() : TCharArray(UNLEN+1) {
90 DWORD len = UNLEN+1;
91 if (!GetUserName(buf, &len))
92 throw rdr::SystemException("GetUserName failed", GetLastError());
93}