1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include "remoting/host/win/wts_terminal_monitor.h"
#include <windows.h>
#include <wtsapi32.h>
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
namespace remoting {
// Session id that does not represent any session.
const uint32_t kInvalidSessionId = 0xffffffffu;
const char WtsTerminalMonitor::kConsole[] = "console";
WtsTerminalMonitor::~WtsTerminalMonitor() {}
// static
bool WtsTerminalMonitor::LookupTerminalId(uint32_t 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_t 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)) {
PLOG(ERROR) << "Failed to enumerate all sessions";
return kInvalidSessionId;
}
for (DWORD i = 0; i < session_info_count; ++i) {
uint32_t 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
|