Home | History | Annotate | Download | only in win
      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 
     21 WtsTerminalMonitor::~WtsTerminalMonitor() {
     22 }
     23 
     24 // static
     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
     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 
     82 WtsTerminalMonitor::WtsTerminalMonitor() {
     83 }
     84 
     85 }  // namespace remoting
     86