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/host_event_logger.h"
6
7 #include <windows.h>
8 #include <string>
9 #include <vector>
10
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "net/base/ip_endpoint.h"
16 #include "remoting/host/host_status_monitor.h"
17 #include "remoting/host/host_status_observer.h"
18 #include "remoting/protocol/transport.h"
19
20 #include "remoting_host_messages.h"
21
22 namespace remoting {
23
24 namespace {
25
26 class HostEventLoggerWin : public HostEventLogger, public HostStatusObserver {
27 public:
28 HostEventLoggerWin(base::WeakPtr<HostStatusMonitor> monitor,
29 const std::string& application_name);
30
31 virtual ~HostEventLoggerWin();
32
33 // HostStatusObserver implementation. These methods will be called from the
34 // network thread.
35 virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE;
36 virtual void OnClientDisconnected(const std::string& jid) OVERRIDE;
37 virtual void OnAccessDenied(const std::string& jid) OVERRIDE;
38 virtual void OnClientRouteChange(
39 const std::string& jid,
40 const std::string& channel_name,
41 const protocol::TransportRoute& route) OVERRIDE;
42 virtual void OnStart(const std::string& xmpp_login) OVERRIDE;
43 virtual void OnShutdown() OVERRIDE;
44
45 private:
46 void LogString(WORD type, DWORD event_id, const std::string& string);
47 void Log(WORD type, DWORD event_id, const std::vector<std::string>& strings);
48
49 base::WeakPtr<HostStatusMonitor> monitor_;
50
51 // The handle of the application event log.
52 HANDLE event_log_;
53
54 DISALLOW_COPY_AND_ASSIGN(HostEventLoggerWin);
55 };
56
57 } //namespace
58
HostEventLoggerWin(base::WeakPtr<HostStatusMonitor> monitor,const std::string & application_name)59 HostEventLoggerWin::HostEventLoggerWin(base::WeakPtr<HostStatusMonitor> monitor,
60 const std::string& application_name)
61 : monitor_(monitor),
62 event_log_(NULL) {
63 event_log_ = RegisterEventSourceW(
64 NULL, base::UTF8ToUTF16(application_name).c_str());
65 if (event_log_ != NULL) {
66 monitor_->AddStatusObserver(this);
67 } else {
68 PLOG(ERROR) << "Failed to register the event source: " << application_name;
69 }
70 }
71
~HostEventLoggerWin()72 HostEventLoggerWin::~HostEventLoggerWin() {
73 if (event_log_ != NULL) {
74 if (monitor_)
75 monitor_->RemoveStatusObserver(this);
76 DeregisterEventSource(event_log_);
77 }
78 }
79
OnClientAuthenticated(const std::string & jid)80 void HostEventLoggerWin::OnClientAuthenticated(const std::string& jid) {
81 LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_CONNECTED, jid);
82 }
83
OnClientDisconnected(const std::string & jid)84 void HostEventLoggerWin::OnClientDisconnected(const std::string& jid) {
85 LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_DISCONNECTED, jid);
86 }
87
OnAccessDenied(const std::string & jid)88 void HostEventLoggerWin::OnAccessDenied(const std::string& jid) {
89 LogString(EVENTLOG_ERROR_TYPE, MSG_HOST_CLIENT_ACCESS_DENIED, jid);
90 }
91
OnClientRouteChange(const std::string & jid,const std::string & channel_name,const protocol::TransportRoute & route)92 void HostEventLoggerWin::OnClientRouteChange(
93 const std::string& jid,
94 const std::string& channel_name,
95 const protocol::TransportRoute& route) {
96 std::vector<std::string> strings(5);
97 strings[0] = jid;
98 strings[1] = route.remote_address.ToString();
99 strings[2] = route.local_address.ToString();
100 strings[3] = channel_name;
101 strings[4] = protocol::TransportRoute::GetTypeString(route.type);
102 Log(EVENTLOG_INFORMATION_TYPE, MSG_HOST_CLIENT_ROUTING_CHANGED, strings);
103 }
104
OnShutdown()105 void HostEventLoggerWin::OnShutdown() {
106 // TODO(rmsousa): Fix host shutdown to actually call this, and add a log line.
107 }
108
OnStart(const std::string & xmpp_login)109 void HostEventLoggerWin::OnStart(const std::string& xmpp_login) {
110 LogString(EVENTLOG_INFORMATION_TYPE, MSG_HOST_STARTED, xmpp_login);
111 }
112
Log(WORD type,DWORD event_id,const std::vector<std::string> & strings)113 void HostEventLoggerWin::Log(WORD type,
114 DWORD event_id,
115 const std::vector<std::string>& strings) {
116 if (event_log_ == NULL)
117 return;
118
119 // ReportEventW() takes an array of raw string pointers. They should stay
120 // valid for the duration of the call.
121 std::vector<const WCHAR*> raw_strings(strings.size());
122 std::vector<base::string16> utf16_strings(strings.size());
123 for (size_t i = 0; i < strings.size(); ++i) {
124 utf16_strings[i] = base::UTF8ToUTF16(strings[i]);
125 raw_strings[i] = utf16_strings[i].c_str();
126 }
127
128 if (!ReportEventW(event_log_,
129 type,
130 HOST_CATEGORY,
131 event_id,
132 NULL,
133 static_cast<WORD>(raw_strings.size()),
134 0,
135 &raw_strings[0],
136 NULL)) {
137 PLOG(ERROR) << "Failed to write an event to the event log";
138 }
139 }
140
LogString(WORD type,DWORD event_id,const std::string & string)141 void HostEventLoggerWin::LogString(WORD type,
142 DWORD event_id,
143 const std::string& string) {
144 std::vector<std::string> strings;
145 strings.push_back(string);
146 Log(type, event_id, strings);
147 }
148
149 // static
Create(base::WeakPtr<HostStatusMonitor> monitor,const std::string & application_name)150 scoped_ptr<HostEventLogger> HostEventLogger::Create(
151 base::WeakPtr<HostStatusMonitor> monitor,
152 const std::string& application_name) {
153 return scoped_ptr<HostEventLogger>(
154 new HostEventLoggerWin(monitor, application_name));
155 }
156
157 } // namespace remoting
158