Home | History | Annotate | Download | only in base
      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, &registration_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