1 // Licensed under the Apache License, Version 2.0
2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
4 // All files in the project carrying such notice may not be copied, modified, or distributed
5 // except according to those terms.
6 use shared::basetsd::ULONG64;
7 use shared::evntprov::EVENT_DESCRIPTOR;
8 use shared::evntrace::ETW_BUFFER_CONTEXT;
9 use shared::guiddef::{GUID, LPGUID};
10 use shared::minwindef::{PUCHAR, PULONG, PUSHORT, UCHAR, ULONG, USHORT};
11 use um::winnt::{
12     ANYSIZE_ARRAY, BOOLEAN, LARGE_INTEGER, PCSTR, PSECURITY_DESCRIPTOR, PSID, PVOID, ULONGLONG,
13 };
14 pub const EVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID: USHORT = 0x0001;
15 pub const EVENT_HEADER_EXT_TYPE_SID: USHORT = 0x0002;
16 pub const EVENT_HEADER_EXT_TYPE_TS_ID: USHORT = 0x0003;
17 pub const EVENT_HEADER_EXT_TYPE_INSTANCE_INFO: USHORT = 0x0004;
18 pub const EVENT_HEADER_EXT_TYPE_STACK_TRACE32: USHORT = 0x0005;
19 pub const EVENT_HEADER_EXT_TYPE_STACK_TRACE64: USHORT = 0x0006;
20 pub const EVENT_HEADER_EXT_TYPE_PEBS_INDEX: USHORT = 0x0007;
21 pub const EVENT_HEADER_EXT_TYPE_PMC_COUNTERS: USHORT = 0x0008;
22 pub const EVENT_HEADER_EXT_TYPE_PSM_KEY: USHORT = 0x0009;
23 pub const EVENT_HEADER_EXT_TYPE_EVENT_KEY: USHORT = 0x000A;
24 pub const EVENT_HEADER_EXT_TYPE_EVENT_SCHEMA_TL: USHORT = 0x000B;
25 pub const EVENT_HEADER_EXT_TYPE_PROV_TRAITS: USHORT = 0x000C;
26 pub const EVENT_HEADER_EXT_TYPE_PROCESS_START_KEY: USHORT = 0x000D;
27 pub const EVENT_HEADER_EXT_TYPE_CONTROL_GUID: USHORT = 0x000E;
28 pub const EVENT_HEADER_EXT_TYPE_MAX: USHORT = 0x000F;
29 STRUCT!{struct EVENT_HEADER_EXTENDED_DATA_ITEM_s {
30     bitfield: USHORT,
31 }}
32 BITFIELD!{EVENT_HEADER_EXTENDED_DATA_ITEM_s bitfield: USHORT [
33     Linkage set_Linkage[0..1],
34     Reserved2 set_Reserved2[1..16],
35 ]}
36 STRUCT!{struct EVENT_HEADER_EXTENDED_DATA_ITEM {
37     Reserved1: USHORT,
38     ExtType: USHORT,
39     s: EVENT_HEADER_EXTENDED_DATA_ITEM_s,
40     DataSize: USHORT,
41     DataPtr: ULONGLONG,
42 }}
43 pub type PEVENT_HEADER_EXTENDED_DATA_ITEM = *mut EVENT_HEADER_EXTENDED_DATA_ITEM;
44 STRUCT!{struct EVENT_EXTENDED_ITEM_INSTANCE {
45     InstanceId: ULONG,
46     ParentInstanceId: ULONG,
47     ParentGuid: GUID,
48 }}
49 pub type PEVENT_EXTENDED_ITEM_INSTANCE = *mut EVENT_EXTENDED_ITEM_INSTANCE;
tts_params()50 STRUCT!{struct EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID {
51     RelatedActivityId: GUID,
52 }}
53 pub type PEVENT_EXTENDED_ITEM_RELATED_ACTIVITYID = *mut EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID;
54 STRUCT!{struct EVENT_EXTENDED_ITEM_TS_ID {
55     SessionId: ULONG,
56 }}
57 pub type PEVENT_EXTENDED_ITEM_TS_ID = *mut EVENT_EXTENDED_ITEM_TS_ID;
58 STRUCT!{struct EVENT_EXTENDED_ITEM_STACK_TRACE32 {
59     MatchId: ULONG64,
60     Address: [ULONG; ANYSIZE_ARRAY],
61 }}
62 pub type PEVENT_EXTENDED_ITEM_STACK_TRACE32 = *mut EVENT_EXTENDED_ITEM_STACK_TRACE32;
63 STRUCT!{struct EVENT_EXTENDED_ITEM_STACK_TRACE64 {
64     MatchId: ULONG64,
65     Address: [ULONG64; ANYSIZE_ARRAY],
66 }}
67 pub type PEVENT_EXTENDED_ITEM_STACK_TRACE64 = *mut EVENT_EXTENDED_ITEM_STACK_TRACE64;
68 STRUCT!{struct EVENT_EXTENDED_ITEM_PEBS_INDEX {
69     PebsIndex: ULONG64,
70 }}
71 pub type PEVENT_EXTENDED_ITEM_PEBS_INDEX = *mut EVENT_EXTENDED_ITEM_PEBS_INDEX;
72 STRUCT!{struct EVENT_EXTENDED_ITEM_PMC_COUNTERS {
73     Counter: [ULONG64; ANYSIZE_ARRAY],
74 }}
register_self(config & conf)75 pub type PEVENT_EXTENDED_ITEM_PMC_COUNTERS = *mut EVENT_EXTENDED_ITEM_PMC_COUNTERS;
76 STRUCT!{struct EVENT_EXTENDED_ITEM_PROCESS_START_KEY {
77     ProcessStartKey: ULONG64,
78 }}
79 pub type PEVENT_EXTENDED_ITEM_PROCESS_START_KEY = *mut EVENT_EXTENDED_ITEM_PROCESS_START_KEY;
80 STRUCT!{struct EVENT_EXTENDED_ITEM_EVENT_KEY {
81     Key: ULONG64,
82 }}
83 pub type PEVENT_EXTENDED_ITEM_EVENT_KEY = *mut EVENT_EXTENDED_ITEM_EVENT_KEY;
84 pub const EVENT_HEADER_PROPERTY_XML: USHORT = 0x0001;
85 pub const EVENT_HEADER_PROPERTY_FORWARDED_XML: USHORT = 0x0002;
86 pub const EVENT_HEADER_PROPERTY_LEGACY_EVENTLOG: USHORT = 0x0004;
87 pub const EVENT_HEADER_PROPERTY_RELOGGABLE: USHORT = 0x0008;
88 pub const EVENT_HEADER_FLAG_EXTENDED_INFO: USHORT = 0x0001;
89 pub const EVENT_HEADER_FLAG_PRIVATE_SESSION: USHORT = 0x0002;
90 pub const EVENT_HEADER_FLAG_STRING_ONLY: USHORT = 0x0004;
91 pub const EVENT_HEADER_FLAG_TRACE_MESSAGE: USHORT = 0x0008;
92 pub const EVENT_HEADER_FLAG_NO_CPUTIME: USHORT = 0x0010;
93 pub const EVENT_HEADER_FLAG_32_BIT_HEADER: USHORT = 0x0020;
94 pub const EVENT_HEADER_FLAG_64_BIT_HEADER: USHORT = 0x0040;
95 pub const EVENT_HEADER_FLAG_CLASSIC_HEADER: USHORT = 0x0100;
96 pub const EVENT_HEADER_FLAG_PROCESSOR_INDEX: USHORT = 0x0200;
97 STRUCT!{struct EVENT_HEADER_u_s {
98     KernelTime: ULONG,
99     UserTime: ULONG,
100 }}
101 UNION!{union EVENT_HEADER_u {
102     [u64; 1],
103     s s_mut: EVENT_HEADER_u_s,
104     ProcessorTime ProcessorTime_mut: ULONG64,
105 }}
106 STRUCT!{struct EVENT_HEADER {
107     Size: USHORT,
108     HeaderType: USHORT,
109     Flags: USHORT,
110     EventProperty: USHORT,
111     ThreadId: ULONG,
112     ProcessId: ULONG,
113     TimeStamp: LARGE_INTEGER,
114     ProviderId: GUID,
115     EventDescriptor: EVENT_DESCRIPTOR,
116     u: EVENT_HEADER_u,
117     ActivityId: GUID,
118 }}
119 pub type PEVENT_HEADER = *mut EVENT_HEADER;
120 STRUCT!{struct EVENT_RECORD {
121     EventHeader: EVENT_HEADER,
122     BufferContext: ETW_BUFFER_CONTEXT,
123     ExtendedDataCount: USHORT,
124     UserDataLength: USHORT,
125     ExtendedData: PEVENT_HEADER_EXTENDED_DATA_ITEM,
126     UserData: PVOID,
127     UserContext: PVOID,
128 }}
129 pub type PEVENT_RECORD = *mut EVENT_RECORD;
130 pub type PCEVENT_RECORD = *const EVENT_RECORD;
131 pub const EVENT_ENABLE_PROPERTY_SID: USHORT = 0x00000001;
132 pub const EVENT_ENABLE_PROPERTY_TS_ID: USHORT = 0x00000002;
133 pub const EVENT_ENABLE_PROPERTY_STACK_TRACE: USHORT = 0x00000004;
134 pub const EVENT_ENABLE_PROPERTY_PSM_KEY: USHORT = 0x00000008;
135 pub const EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0: USHORT = 0x00000010;
136 pub const EVENT_ENABLE_PROPERTY_PROVIDER_GROUP: USHORT = 0x00000020;
137 pub const EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0: USHORT = 0x00000040;
138 pub const EVENT_ENABLE_PROPERTY_PROCESS_START_KEY: USHORT = 0x00000080;
139 pub const EVENT_ENABLE_PROPERTY_EVENT_KEY: USHORT = 0x00000100;
140 pub const EVENT_ENABLE_PROPERTY_EXCLUDE_INPRIVATE: USHORT = 0x00000200;
141 pub const PROCESS_TRACE_MODE_REAL_TIME: ULONG = 0x00000100;
142 pub const PROCESS_TRACE_MODE_RAW_TIMESTAMP: ULONG = 0x00001000;
143 pub const PROCESS_TRACE_MODE_EVENT_RECORD: ULONG = 0x10000000;
144 #[inline]
145 pub unsafe fn GetEventProcessorIndex(EventRecord: PCEVENT_RECORD) -> ULONG {
146     if (*EventRecord).EventHeader.Flags & EVENT_HEADER_FLAG_PROCESSOR_INDEX != 0 {
147         *(*EventRecord).BufferContext.u.ProcessorIndex() as ULONG
148     } else {
149         (*EventRecord).BufferContext.u.s().ProcessorNumber as ULONG
150     }
151 }
152 ENUM!{enum ETW_PROVIDER_TRAIT_TYPE {
153     EtwProviderTraitTypeGroup = 1,
154     EtwProviderTraitDecodeGuid = 2,
155     EtwProviderTraitTypeMax,
156 }}
157 #[inline]
158 unsafe fn strnlen(s: PCSTR, max_len: isize) -> isize {
159     let mut len = 0;
160     while *s.offset(len) != 0 && len < max_len {
161         len += 1
162     }
163     len
164 }
165 // Taken from Rust 1.17.0 sources
166 #[inline]
167 unsafe fn read_unaligned<T>(src: *const T) -> T {
168     use core::{mem, ptr};
169     let mut tmp: T = mem::uninitialized();
170     ptr::copy_nonoverlapping(
171         src as *const u8,
172         &mut tmp as *mut T as *mut u8,
173         mem::size_of::<T>(),
174     );
175     tmp
176 }
177 #[inline]
178 pub unsafe fn EtwGetTraitFromProviderTraits(
179     ProviderTraits: PVOID, TraitType: UCHAR, Trait: *mut PVOID, Size: PUSHORT,
180 ) {
181     use core::ptr::null_mut;
182     let ByteCount = read_unaligned(ProviderTraits as *mut USHORT) as isize;
183     let mut Ptr = ProviderTraits as PUCHAR;
184     let PtrEnd = Ptr.offset(ByteCount);
185     *Trait = null_mut();
186     *Size = 0;
187     if ByteCount < 3 {
188         return;
189     }
190     Ptr = Ptr.offset(2);
191     Ptr = Ptr.offset(strnlen(Ptr as PCSTR, (ByteCount - 3) as isize));
192     Ptr = Ptr.offset(1);
193     while Ptr < PtrEnd {
194         let TraitByteCount = read_unaligned(Ptr as *const USHORT);
195         if TraitByteCount < 3 {
196             return;
197         }
198         if *Ptr.offset(2) == TraitType && Ptr.offset(TraitByteCount as isize) <= PtrEnd {
199             *Trait = Ptr.offset(3) as PVOID;
200             *Size = TraitByteCount - 3;
201             return;
202         }
203         Ptr = Ptr.offset(TraitByteCount as isize);
204     }
205 }
206 ENUM!{enum EVENTSECURITYOPERATION {
207     EventSecuritySetDACL,
208     EventSecuritySetSACL,
209     EventSecurityAddDACL,
210     EventSecurityAddSACL,
211     EventSecurityMax,
212 }}
213 extern "system" {
214     pub fn EventAccessControl(
215         Guid: LPGUID,
216         Operation: ULONG,
217         Sid: PSID,
218         Rights: ULONG,
219         AllowOrDeny: BOOLEAN,
220     ) -> ULONG;
221     pub fn EventAccessQuery(
222         Guid: LPGUID,
223         Buffer: PSECURITY_DESCRIPTOR,
224         BufferSize: PULONG,
225     ) -> ULONG;
226     pub fn EventAccessRemove(
227         Guid: LPGUID,
228     ) -> ULONG;
229 }
230