event_trace_provider.cc 3.8 KB

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