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