// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "remoting/host/win/wts_terminal_monitor.h" #include #include #include "base/basictypes.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" namespace remoting { // Session id that does not represent any session. const uint32 kInvalidSessionId = 0xffffffffu; const char* WtsTerminalMonitor::kConsole = "console"; WtsTerminalMonitor::~WtsTerminalMonitor() { } // static bool WtsTerminalMonitor::LookupTerminalId(uint32 session_id, std::string* terminal_id) { // Fast path for the case when |session_id| is currently attached to // the physical console. if (session_id == WTSGetActiveConsoleSessionId()) { *terminal_id = kConsole; return true; } // RdpClient sets the terminal ID as the initial program's working directory. DWORD bytes; wchar_t* working_directory; if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id, WTSWorkingDirectory, &working_directory, &bytes)) { return false; } bool result = base::WideToUTF8(working_directory, (bytes / sizeof(wchar_t)) - 1, terminal_id); WTSFreeMemory(working_directory); return result; } // static uint32 WtsTerminalMonitor::LookupSessionId(const std::string& terminal_id) { // Use the fast path if the caller wants to get id of the session attached to // the physical console. if (terminal_id == kConsole) return WTSGetActiveConsoleSessionId(); // Enumerate all sessions and try to match the client endpoint. WTS_SESSION_INFO* session_info; DWORD session_info_count; if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &session_info, &session_info_count)) { LOG_GETLASTERROR(ERROR) << "Failed to enumerate all sessions"; return kInvalidSessionId; } for (DWORD i = 0; i < session_info_count; ++i) { uint32 session_id = session_info[i].SessionId; std::string id; if (LookupTerminalId(session_id, &id) && terminal_id == id) { WTSFreeMemory(session_info); return session_id; } } // |terminal_id| is not associated with any session. WTSFreeMemory(session_info); return kInvalidSessionId; } WtsTerminalMonitor::WtsTerminalMonitor() { } } // namespace remoting