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. 4// 5#include "base/win/event_trace_provider.h" 6#include <windows.h> 7#include <cguid.h> 8 9namespace base { 10namespace win { 11 12TRACE_GUID_REGISTRATION EtwTraceProvider::obligatory_guid_registration_ = { 13 &GUID_NULL, 14 NULL 15}; 16 17EtwTraceProvider::EtwTraceProvider(const GUID& provider_name) 18 : provider_name_(provider_name), registration_handle_(NULL), 19 session_handle_(NULL), enable_flags_(0), enable_level_(0) { 20} 21 22EtwTraceProvider::EtwTraceProvider() 23 : provider_name_(GUID_NULL), registration_handle_(NULL), 24 session_handle_(NULL), enable_flags_(0), enable_level_(0) { 25} 26 27EtwTraceProvider::~EtwTraceProvider() { 28 Unregister(); 29} 30 31ULONG EtwTraceProvider::EnableEvents(void* buffer) { 32 session_handle_ = ::GetTraceLoggerHandle(buffer); 33 if (NULL == session_handle_) { 34 return ::GetLastError(); 35 } 36 37 enable_flags_ = ::GetTraceEnableFlags(session_handle_); 38 enable_level_ = ::GetTraceEnableLevel(session_handle_); 39 40 // Give subclasses a chance to digest the state change. 41 OnEventsEnabled(); 42 43 return ERROR_SUCCESS; 44} 45 46ULONG EtwTraceProvider::DisableEvents() { 47 // Give subclasses a chance to digest the state change. 48 OnEventsDisabled(); 49 50 enable_level_ = 0; 51 enable_flags_ = 0; 52 session_handle_ = NULL; 53 54 PostEventsDisabled(); 55 56 return ERROR_SUCCESS; 57} 58 59ULONG EtwTraceProvider::Callback(WMIDPREQUESTCODE request, void* buffer) { 60 switch (request) { 61 case WMI_ENABLE_EVENTS: 62 return EnableEvents(buffer); 63 case WMI_DISABLE_EVENTS: 64 return DisableEvents(); 65 default: 66 return ERROR_INVALID_PARAMETER; 67 } 68 // Not reached. 69} 70 71ULONG WINAPI EtwTraceProvider::ControlCallback(WMIDPREQUESTCODE request, 72 void* context, ULONG *reserved, void* buffer) { 73 EtwTraceProvider *provider = reinterpret_cast<EtwTraceProvider*>(context); 74 75 return provider->Callback(request, buffer); 76} 77 78ULONG EtwTraceProvider::Register() { 79 if (provider_name_ == GUID_NULL) 80 return ERROR_INVALID_NAME; 81 82 return ::RegisterTraceGuids(ControlCallback, this, &provider_name_, 83 1, &obligatory_guid_registration_, NULL, NULL, ®istration_handle_); 84} 85 86ULONG EtwTraceProvider::Unregister() { 87 ULONG ret = ::UnregisterTraceGuids(registration_handle_); 88 89 // Make sure we don't log anything from here on. 90 enable_level_ = 0; 91 enable_flags_ = 0; 92 session_handle_ = NULL; 93 registration_handle_ = NULL; 94 95 return ret; 96} 97 98ULONG EtwTraceProvider::Log(const EtwEventClass& event_class, 99 EtwEventType type, EtwEventLevel level, const char *message) { 100 if (NULL == session_handle_ || enable_level_ < level) 101 return ERROR_SUCCESS; // No one listening. 102 103 EtwMofEvent<1> event(event_class, type, level); 104 105 event.fields[0].DataPtr = reinterpret_cast<ULONG64>(message); 106 event.fields[0].Length = message ? 107 static_cast<ULONG>(sizeof(message[0]) * (1 + strlen(message))) : 0; 108 109 return ::TraceEvent(session_handle_, &event.header); 110} 111 112ULONG EtwTraceProvider::Log(const EtwEventClass& event_class, 113 EtwEventType type, EtwEventLevel level, const wchar_t *message) { 114 if (NULL == session_handle_ || enable_level_ < level) 115 return ERROR_SUCCESS; // No one listening. 116 117 EtwMofEvent<1> event(event_class, type, level); 118 119 event.fields[0].DataPtr = reinterpret_cast<ULONG64>(message); 120 event.fields[0].Length = message ? 121 static_cast<ULONG>(sizeof(message[0]) * (1 + wcslen(message))) : 0; 122 123 return ::TraceEvent(session_handle_, &event.header); 124} 125 126ULONG EtwTraceProvider::Log(EVENT_TRACE_HEADER* event) { 127 if (enable_level_ < event->Class.Level) 128 return ERROR_SUCCESS; 129 130 return ::TraceEvent(session_handle_, event); 131} 132 133} // namespace win 134} // namespace base 135