| // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Implementation of a Windows event trace controller class. |
| #include "base/event_trace_controller_win.h" |
| #include "base/logging.h" |
| |
| EtwTraceController::EtwTraceController() : session_(NULL) { |
| } |
| |
| EtwTraceController::~EtwTraceController() { |
| Stop(NULL); |
| } |
| |
| HRESULT EtwTraceController::Start(const wchar_t* session_name, |
| EtwTraceProperties* prop) { |
| DCHECK(NULL == session_ && session_name_.empty()); |
| EtwTraceProperties ignore; |
| if (prop == NULL) |
| prop = &ignore; |
| |
| HRESULT hr = Start(session_name, prop, &session_); |
| if (SUCCEEDED(hr)) |
| session_name_ = session_name; |
| |
| return hr; |
| } |
| |
| HRESULT EtwTraceController::StartFileSession(const wchar_t* session_name, |
| const wchar_t* logfile_path, bool realtime) { |
| DCHECK(NULL == session_ && session_name_.empty()); |
| |
| EtwTraceProperties prop; |
| prop.SetLoggerFileName(logfile_path); |
| EVENT_TRACE_PROPERTIES& p = *prop.get(); |
| p.Wnode.ClientContext = 1; // QPC timer accuracy. |
| p.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL; // Sequential log. |
| if (realtime) |
| p.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE; |
| |
| p.MaximumFileSize = 100; // 100M file size. |
| p.FlushTimer = 30; // 30 seconds flush lag. |
| return Start(session_name, &prop); |
| } |
| |
| HRESULT EtwTraceController::StartRealtimeSession(const wchar_t* session_name, |
| size_t buffer_size) { |
| DCHECK(NULL == session_ && session_name_.empty()); |
| EtwTraceProperties prop; |
| EVENT_TRACE_PROPERTIES& p = *prop.get(); |
| p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY; |
| p.FlushTimer = 1; // flush every second. |
| p.BufferSize = 16; // 16 K buffers. |
| p.LogFileNameOffset = 0; |
| return Start(session_name, &prop); |
| } |
| |
| HRESULT EtwTraceController::EnableProvider(REFGUID provider, UCHAR level, |
| ULONG flags) { |
| ULONG error = ::EnableTrace(TRUE, flags, level, &provider, session_); |
| return HRESULT_FROM_WIN32(error); |
| } |
| |
| HRESULT EtwTraceController::DisableProvider(REFGUID provider) { |
| ULONG error = ::EnableTrace(FALSE, 0, 0, &provider, session_); |
| return HRESULT_FROM_WIN32(error); |
| } |
| |
| HRESULT EtwTraceController::Stop(EtwTraceProperties* properties) { |
| EtwTraceProperties ignore; |
| if (properties == NULL) |
| properties = &ignore; |
| |
| ULONG error = ::ControlTrace(session_, NULL, properties->get(), |
| EVENT_TRACE_CONTROL_STOP); |
| if (ERROR_SUCCESS != error) |
| return HRESULT_FROM_WIN32(error); |
| |
| session_ = NULL; |
| session_name_.clear(); |
| return S_OK; |
| } |
| |
| HRESULT EtwTraceController::Flush(EtwTraceProperties* properties) { |
| EtwTraceProperties ignore; |
| if (properties == NULL) |
| properties = &ignore; |
| |
| ULONG error = ::ControlTrace(session_, NULL, properties->get(), |
| EVENT_TRACE_CONTROL_FLUSH); |
| if (ERROR_SUCCESS != error) |
| return HRESULT_FROM_WIN32(error); |
| |
| return S_OK; |
| } |
| |
| HRESULT EtwTraceController::Start(const wchar_t* session_name, |
| EtwTraceProperties* properties, TRACEHANDLE* session_handle) { |
| ULONG err = ::StartTrace(session_handle, session_name, properties->get()); |
| return HRESULT_FROM_WIN32(err); |
| } |
| |
| HRESULT EtwTraceController::Query(const wchar_t* session_name, |
| EtwTraceProperties* properties) { |
| ULONG err = ::ControlTrace(NULL, session_name, properties->get(), |
| EVENT_TRACE_CONTROL_QUERY); |
| return HRESULT_FROM_WIN32(err); |
| }; |
| |
| HRESULT EtwTraceController::Update(const wchar_t* session_name, |
| EtwTraceProperties* properties) { |
| ULONG err = ::ControlTrace(NULL, session_name, properties->get(), |
| EVENT_TRACE_CONTROL_UPDATE); |
| return HRESULT_FROM_WIN32(err); |
| } |
| |
| HRESULT EtwTraceController::Stop(const wchar_t* session_name, |
| EtwTraceProperties* properties) { |
| ULONG err = ::ControlTrace(NULL, session_name, properties->get(), |
| EVENT_TRACE_CONTROL_STOP); |
| return HRESULT_FROM_WIN32(err); |
| } |
| |
| HRESULT EtwTraceController::Flush(const wchar_t* session_name, |
| EtwTraceProperties* properties) { |
| ULONG err = ::ControlTrace(NULL, session_name, properties->get(), |
| EVENT_TRACE_CONTROL_FLUSH); |
| return HRESULT_FROM_WIN32(err); |
| } |