15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/host_event_logger.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "remoting/host/host_status_monitor.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/host_status_observer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/transport.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting_host_messages.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HostEventLoggerWin : public HostEventLogger, public HostStatusObserver {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HostEventLoggerWin(base::WeakPtr<HostStatusMonitor> monitor,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const std::string& application_name);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HostEventLoggerWin();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostStatusObserver implementation.  These methods will be called from the
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // network thread.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClientDisconnected(const std::string& jid) OVERRIDE;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAccessDenied(const std::string& jid) OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClientRouteChange(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& jid,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& channel_name,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const protocol::TransportRoute& route) OVERRIDE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnStart(const std::string& xmpp_login) OVERRIDE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnShutdown() OVERRIDE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LogString(WORD type, DWORD event_id, const std::string& string);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Log(WORD type, DWORD event_id, const std::vector<std::string>& strings);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtr<HostStatusMonitor> monitor_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The handle of the application event log.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE event_log_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HostEventLoggerWin);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} //namespace
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostEventLoggerWin::HostEventLoggerWin(base::WeakPtr<HostStatusMonitor> monitor,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const std::string& application_name)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : monitor_(monitor),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_log_(NULL) {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  event_log_ = RegisterEventSourceW(
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NULL, base::UTF8ToUTF16(application_name).c_str());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event_log_ != NULL) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    monitor_->AddStatusObserver(this);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to register the event source: " << application_name;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostEventLoggerWin::~HostEventLoggerWin() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event_log_ != NULL) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (monitor_)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      monitor_->RemoveStatusObserver(this);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeregisterEventSource(event_log_);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnClientAuthenticated(const std::string& jid) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_CONNECTED, jid);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnClientDisconnected(const std::string& jid) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_DISCONNECTED, jid);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnAccessDenied(const std::string& jid) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogString(EVENTLOG_ERROR_TYPE, MSG_HOST_CLIENT_ACCESS_DENIED, jid);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnClientRouteChange(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& jid,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& channel_name,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const protocol::TransportRoute& route) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> strings(5);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings[0] = jid;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings[1] = route.remote_address.ToString();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings[2] = route.local_address.ToString();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings[3] = channel_name;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings[4] = protocol::TransportRoute::GetTypeString(route.type);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Log(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_ROUTING_CHANGED, strings);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnShutdown() {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(rmsousa): Fix host shutdown to actually call this, and add a log line.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::OnStart(const std::string& xmpp_login) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_STARTED, xmpp_login);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::Log(WORD type,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             DWORD event_id,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::vector<std::string>& strings) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event_log_ == NULL)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ReportEventW() takes an array of raw string pointers. They should stay
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // valid for the duration of the call.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<const WCHAR*> raw_strings(strings.size());
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<base::string16> utf16_strings(strings.size());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < strings.size(); ++i) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    utf16_strings[i] = base::UTF8ToUTF16(strings[i]);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    raw_strings[i] = utf16_strings[i].c_str();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReportEventW(event_log_,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    type,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    HOST_CATEGORY,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    event_id,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NULL,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    static_cast<WORD>(raw_strings.size()),
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    0,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &raw_strings[0],
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NULL)) {
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PLOG(ERROR) << "Failed to write an event to the event log";
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostEventLoggerWin::LogString(WORD type,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   DWORD event_id,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const std::string& string) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> strings;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strings.push_back(string);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Log(type, event_id, strings);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<HostEventLogger> HostEventLogger::Create(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<HostStatusMonitor> monitor,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& application_name) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<HostEventLogger>(
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HostEventLoggerWin(monitor, application_name));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
158