1 // Copyright (c) 2009 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.
5 // Implementation of a Windows event trace controller class.
6 #include "base/win/event_trace_controller.h"
7 #include "base/logging.h"
12 EtwTraceProperties::EtwTraceProperties() {
13 memset(buffer_
, 0, sizeof(buffer_
));
14 EVENT_TRACE_PROPERTIES
* prop
= get();
16 prop
->Wnode
.BufferSize
= sizeof(buffer_
);
17 prop
->Wnode
.Flags
= WNODE_FLAG_TRACED_GUID
;
18 prop
->LoggerNameOffset
= sizeof(EVENT_TRACE_PROPERTIES
);
19 prop
->LogFileNameOffset
= sizeof(EVENT_TRACE_PROPERTIES
) +
20 sizeof(wchar_t) * kMaxStringLen
;
23 HRESULT
EtwTraceProperties::SetLoggerName(const wchar_t* logger_name
) {
24 size_t len
= wcslen(logger_name
) + 1;
25 if (kMaxStringLen
< len
)
28 memcpy(buffer_
+ get()->LoggerNameOffset
,
30 sizeof(wchar_t) * len
);
34 HRESULT
EtwTraceProperties::SetLoggerFileName(const wchar_t* logger_file_name
) {
35 size_t len
= wcslen(logger_file_name
) + 1;
36 if (kMaxStringLen
< len
)
39 memcpy(buffer_
+ get()->LogFileNameOffset
,
41 sizeof(wchar_t) * len
);
45 EtwTraceController::EtwTraceController() : session_(NULL
) {
48 EtwTraceController::~EtwTraceController() {
52 HRESULT
EtwTraceController::Start(const wchar_t* session_name
,
53 EtwTraceProperties
* prop
) {
54 DCHECK(NULL
== session_
&& session_name_
.empty());
55 EtwTraceProperties ignore
;
59 HRESULT hr
= Start(session_name
, prop
, &session_
);
61 session_name_
= session_name
;
66 HRESULT
EtwTraceController::StartFileSession(const wchar_t* session_name
,
67 const wchar_t* logfile_path
, bool realtime
) {
68 DCHECK(NULL
== session_
&& session_name_
.empty());
70 EtwTraceProperties prop
;
71 prop
.SetLoggerFileName(logfile_path
);
72 EVENT_TRACE_PROPERTIES
& p
= *prop
.get();
73 p
.Wnode
.ClientContext
= 1; // QPC timer accuracy.
74 p
.LogFileMode
= EVENT_TRACE_FILE_MODE_SEQUENTIAL
; // Sequential log.
76 p
.LogFileMode
|= EVENT_TRACE_REAL_TIME_MODE
;
78 p
.MaximumFileSize
= 100; // 100M file size.
79 p
.FlushTimer
= 30; // 30 seconds flush lag.
80 return Start(session_name
, &prop
);
83 HRESULT
EtwTraceController::StartRealtimeSession(const wchar_t* session_name
,
85 DCHECK(NULL
== session_
&& session_name_
.empty());
86 EtwTraceProperties prop
;
87 EVENT_TRACE_PROPERTIES
& p
= *prop
.get();
88 p
.LogFileMode
= EVENT_TRACE_REAL_TIME_MODE
| EVENT_TRACE_USE_PAGED_MEMORY
;
89 p
.FlushTimer
= 1; // flush every second.
90 p
.BufferSize
= 16; // 16 K buffers.
91 p
.LogFileNameOffset
= 0;
92 return Start(session_name
, &prop
);
95 HRESULT
EtwTraceController::EnableProvider(REFGUID provider
, UCHAR level
,
97 ULONG error
= ::EnableTrace(TRUE
, flags
, level
, &provider
, session_
);
98 return HRESULT_FROM_WIN32(error
);
101 HRESULT
EtwTraceController::DisableProvider(REFGUID provider
) {
102 ULONG error
= ::EnableTrace(FALSE
, 0, 0, &provider
, session_
);
103 return HRESULT_FROM_WIN32(error
);
106 HRESULT
EtwTraceController::Stop(EtwTraceProperties
* properties
) {
107 EtwTraceProperties ignore
;
108 if (properties
== NULL
)
109 properties
= &ignore
;
111 ULONG error
= ::ControlTrace(session_
, NULL
, properties
->get(),
112 EVENT_TRACE_CONTROL_STOP
);
113 if (ERROR_SUCCESS
!= error
)
114 return HRESULT_FROM_WIN32(error
);
117 session_name_
.clear();
121 HRESULT
EtwTraceController::Flush(EtwTraceProperties
* properties
) {
122 EtwTraceProperties ignore
;
123 if (properties
== NULL
)
124 properties
= &ignore
;
126 ULONG error
= ::ControlTrace(session_
, NULL
, properties
->get(),
127 EVENT_TRACE_CONTROL_FLUSH
);
128 if (ERROR_SUCCESS
!= error
)
129 return HRESULT_FROM_WIN32(error
);
134 HRESULT
EtwTraceController::Start(const wchar_t* session_name
,
135 EtwTraceProperties
* properties
, TRACEHANDLE
* session_handle
) {
136 DCHECK(properties
!= NULL
);
137 ULONG err
= ::StartTrace(session_handle
, session_name
, properties
->get());
138 return HRESULT_FROM_WIN32(err
);
141 HRESULT
EtwTraceController::Query(const wchar_t* session_name
,
142 EtwTraceProperties
* properties
) {
143 ULONG err
= ::ControlTrace(NULL
, session_name
, properties
->get(),
144 EVENT_TRACE_CONTROL_QUERY
);
145 return HRESULT_FROM_WIN32(err
);
148 HRESULT
EtwTraceController::Update(const wchar_t* session_name
,
149 EtwTraceProperties
* properties
) {
150 DCHECK(properties
!= NULL
);
151 ULONG err
= ::ControlTrace(NULL
, session_name
, properties
->get(),
152 EVENT_TRACE_CONTROL_UPDATE
);
153 return HRESULT_FROM_WIN32(err
);
156 HRESULT
EtwTraceController::Stop(const wchar_t* session_name
,
157 EtwTraceProperties
* properties
) {
158 DCHECK(properties
!= NULL
);
159 ULONG err
= ::ControlTrace(NULL
, session_name
, properties
->get(),
160 EVENT_TRACE_CONTROL_STOP
);
161 return HRESULT_FROM_WIN32(err
);
164 HRESULT
EtwTraceController::Flush(const wchar_t* session_name
,
165 EtwTraceProperties
* properties
) {
166 DCHECK(properties
!= NULL
);
167 ULONG err
= ::ControlTrace(NULL
, session_name
, properties
->get(),
168 EVENT_TRACE_CONTROL_FLUSH
);
169 return HRESULT_FROM_WIN32(err
);