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