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