1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/win/event_trace_provider.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,180 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 +// 1.8 +// Declaration of a Windows event trace provider class, to allow using 1.9 +// Windows Event Tracing for logging transport and control. 1.10 +#ifndef BASE_WIN_EVENT_TRACE_PROVIDER_H_ 1.11 +#define BASE_WIN_EVENT_TRACE_PROVIDER_H_ 1.12 + 1.13 +#include <windows.h> 1.14 +#include <wmistr.h> 1.15 +#include <evntrace.h> 1.16 + 1.17 +#include "base/base_export.h" 1.18 +#include "base/basictypes.h" 1.19 + 1.20 +namespace base { 1.21 +namespace win { 1.22 + 1.23 +typedef GUID EtwEventClass; 1.24 +typedef UCHAR EtwEventType; 1.25 +typedef UCHAR EtwEventLevel; 1.26 +typedef USHORT EtwEventVersion; 1.27 +typedef ULONG EtwEventFlags; 1.28 + 1.29 +// Base class is a POD for correctness. 1.30 +template <size_t N> struct EtwMofEventBase { 1.31 + EVENT_TRACE_HEADER header; 1.32 + MOF_FIELD fields[N]; 1.33 +}; 1.34 + 1.35 +// Utility class to auto-initialize event trace header structures. 1.36 +template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> { 1.37 + public: 1.38 + typedef EtwMofEventBase<N> Super; 1.39 + 1.40 + // Clang and the C++ standard don't allow unqualified lookup into dependent 1.41 + // bases, hence these using decls to explicitly pull the names out. 1.42 + using EtwMofEventBase<N>::header; 1.43 + using EtwMofEventBase<N>::fields; 1.44 + 1.45 + EtwMofEvent() { 1.46 + memset(static_cast<Super*>(this), 0, sizeof(Super)); 1.47 + } 1.48 + 1.49 + EtwMofEvent(const EtwEventClass& event_class, EtwEventType type, 1.50 + EtwEventLevel level) { 1.51 + memset(static_cast<Super*>(this), 0, sizeof(Super)); 1.52 + header.Size = sizeof(Super); 1.53 + header.Guid = event_class; 1.54 + header.Class.Type = type; 1.55 + header.Class.Level = level; 1.56 + header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR; 1.57 + } 1.58 + 1.59 + EtwMofEvent(const EtwEventClass& event_class, EtwEventType type, 1.60 + EtwEventVersion version, EtwEventLevel level) { 1.61 + memset(static_cast<Super*>(this), 0, sizeof(Super)); 1.62 + header.Size = sizeof(Super); 1.63 + header.Guid = event_class; 1.64 + header.Class.Type = type; 1.65 + header.Class.Version = version; 1.66 + header.Class.Level = level; 1.67 + header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR; 1.68 + } 1.69 + 1.70 + void SetField(int field, size_t size, const void *data) { 1.71 + // DCHECK(field < N); 1.72 + if ((field < N) && (size <= kuint32max)) { 1.73 + fields[field].DataPtr = reinterpret_cast<ULONG64>(data); 1.74 + fields[field].Length = static_cast<ULONG>(size); 1.75 + } 1.76 + } 1.77 + 1.78 + EVENT_TRACE_HEADER* get() { return& header; } 1.79 + 1.80 + private: 1.81 + DISALLOW_COPY_AND_ASSIGN(EtwMofEvent); 1.82 +}; 1.83 + 1.84 +// Trace provider with Event Tracing for Windows. The trace provider 1.85 +// registers with ETW by its name which is a GUID. ETW calls back to 1.86 +// the object whenever the trace level or enable flags for this provider 1.87 +// name changes. 1.88 +// Users of this class can test whether logging is currently enabled at 1.89 +// a particular trace level, and whether particular enable flags are set, 1.90 +// before other resources are consumed to generate and issue the log 1.91 +// messages themselves. 1.92 +class BASE_EXPORT EtwTraceProvider { 1.93 + public: 1.94 + // Creates an event trace provider identified by provider_name, which 1.95 + // will be the name registered with Event Tracing for Windows (ETW). 1.96 + explicit EtwTraceProvider(const GUID& provider_name); 1.97 + 1.98 + // Creates an unnamed event trace provider, the provider must be given 1.99 + // a name before registration. 1.100 + EtwTraceProvider(); 1.101 + virtual ~EtwTraceProvider(); 1.102 + 1.103 + // Registers the trace provider with Event Tracing for Windows. 1.104 + // Note: from this point forward ETW may call the provider's control 1.105 + // callback. If the provider's name is enabled in some trace session 1.106 + // already, the callback may occur recursively from this call, so 1.107 + // call this only when you're ready to handle callbacks. 1.108 + ULONG Register(); 1.109 + // Unregisters the trace provider with ETW. 1.110 + ULONG Unregister(); 1.111 + 1.112 + // Accessors. 1.113 + void set_provider_name(const GUID& provider_name) { 1.114 + provider_name_ = provider_name; 1.115 + } 1.116 + const GUID& provider_name() const { return provider_name_; } 1.117 + TRACEHANDLE registration_handle() const { return registration_handle_; } 1.118 + TRACEHANDLE session_handle() const { return session_handle_; } 1.119 + EtwEventFlags enable_flags() const { return enable_flags_; } 1.120 + EtwEventLevel enable_level() const { return enable_level_; } 1.121 + 1.122 + // Returns true iff logging should be performed for "level" and "flags". 1.123 + // Note: flags is treated as a bitmask, and should normally have a single 1.124 + // bit set, to test whether to log for a particular sub "facility". 1.125 + bool ShouldLog(EtwEventLevel level, EtwEventFlags flags) { 1.126 + return NULL != session_handle_ && level >= enable_level_ && 1.127 + (0 != (flags & enable_flags_)); 1.128 + } 1.129 + 1.130 + // Simple wrappers to log Unicode and ANSI strings. 1.131 + // Do nothing if !ShouldLog(level, 0xFFFFFFFF). 1.132 + ULONG Log(const EtwEventClass& event_class, EtwEventType type, 1.133 + EtwEventLevel level, const char *message); 1.134 + ULONG Log(const EtwEventClass& event_class, EtwEventType type, 1.135 + EtwEventLevel level, const wchar_t *message); 1.136 + 1.137 + // Log the provided event. 1.138 + ULONG Log(EVENT_TRACE_HEADER* event); 1.139 + 1.140 + protected: 1.141 + // Called after events have been enabled, override in subclasses 1.142 + // to set up state or log at the start of a session. 1.143 + // Note: This function may be called ETW's thread and may be racy, 1.144 + // bring your own locking if needed. 1.145 + virtual void OnEventsEnabled() {} 1.146 + 1.147 + // Called just before events are disabled, override in subclasses 1.148 + // to tear down state or log at the end of a session. 1.149 + // Note: This function may be called ETW's thread and may be racy, 1.150 + // bring your own locking if needed. 1.151 + virtual void OnEventsDisabled() {} 1.152 + 1.153 + // Called just after events have been disabled, override in subclasses 1.154 + // to tear down state at the end of a session. At this point it's 1.155 + // to late to log anything to the session. 1.156 + // Note: This function may be called ETW's thread and may be racy, 1.157 + // bring your own locking if needed. 1.158 + virtual void PostEventsDisabled() {} 1.159 + 1.160 + private: 1.161 + ULONG EnableEvents(PVOID buffer); 1.162 + ULONG DisableEvents(); 1.163 + ULONG Callback(WMIDPREQUESTCODE request, PVOID buffer); 1.164 + static ULONG WINAPI ControlCallback(WMIDPREQUESTCODE request, PVOID context, 1.165 + ULONG *reserved, PVOID buffer); 1.166 + 1.167 + GUID provider_name_; 1.168 + TRACEHANDLE registration_handle_; 1.169 + TRACEHANDLE session_handle_; 1.170 + EtwEventFlags enable_flags_; 1.171 + EtwEventLevel enable_level_; 1.172 + 1.173 + // We don't use this, but on XP we're obliged to pass one in to 1.174 + // RegisterTraceGuids. Non-const, because that's how the API needs it. 1.175 + static TRACE_GUID_REGISTRATION obligatory_guid_registration_; 1.176 + 1.177 + DISALLOW_COPY_AND_ASSIGN(EtwTraceProvider); 1.178 +}; 1.179 + 1.180 +} // namespace win 1.181 +} // namespace base 1.182 + 1.183 +#endif // BASE_WIN_EVENT_TRACE_PROVIDER_H_