• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "remoting/host/win/wts_terminal_monitor.h"
6 
7 #include <windows.h>
8 #include <wtsapi32.h>
9 
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/strings/utf_string_conversions.h"
13 
14 namespace remoting {
15 
16 // Session id that does not represent any session.
17 const uint32 kInvalidSessionId = 0xffffffffu;
18 
19 const char* WtsTerminalMonitor::kConsole = "console";
20 
~WtsTerminalMonitor()21 WtsTerminalMonitor::~WtsTerminalMonitor() {
22 }
23 
24 // static
LookupTerminalId(uint32 session_id,std::string * terminal_id)25 bool WtsTerminalMonitor::LookupTerminalId(uint32 session_id,
26                                           std::string* terminal_id) {
27   // Fast path for the case when |session_id| is currently attached to
28   // the physical console.
29   if (session_id == WTSGetActiveConsoleSessionId()) {
30     *terminal_id = kConsole;
31     return true;
32   }
33 
34   // RdpClient sets the terminal ID as the initial program's working directory.
35   DWORD bytes;
36   wchar_t* working_directory;
37   if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
38                                   session_id,
39                                   WTSWorkingDirectory,
40                                   &working_directory,
41                                   &bytes)) {
42     return false;
43   }
44 
45   bool result = base::WideToUTF8(working_directory,
46                                  (bytes / sizeof(wchar_t)) - 1,
47                                  terminal_id);
48   WTSFreeMemory(working_directory);
49   return result;
50 }
51 
52 // static
LookupSessionId(const std::string & terminal_id)53 uint32 WtsTerminalMonitor::LookupSessionId(const std::string& terminal_id) {
54   // Use the fast path if the caller wants to get id of the session attached to
55   // the physical console.
56   if (terminal_id == kConsole)
57     return WTSGetActiveConsoleSessionId();
58 
59   // Enumerate all sessions and try to match the client endpoint.
60   WTS_SESSION_INFO* session_info;
61   DWORD session_info_count;
62   if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &session_info,
63                             &session_info_count)) {
64     PLOG(ERROR) << "Failed to enumerate all sessions";
65     return kInvalidSessionId;
66   }
67   for (DWORD i = 0; i < session_info_count; ++i) {
68     uint32 session_id = session_info[i].SessionId;
69 
70     std::string id;
71     if (LookupTerminalId(session_id, &id) && terminal_id == id) {
72       WTSFreeMemory(session_info);
73       return session_id;
74     }
75   }
76 
77   // |terminal_id| is not associated with any session.
78   WTSFreeMemory(session_info);
79   return kInvalidSessionId;
80 }
81 
WtsTerminalMonitor()82 WtsTerminalMonitor::WtsTerminalMonitor() {
83 }
84 
85 }  // namespace remoting
86