// Licensed under the Apache License, Version 2.0 // or the MIT license // , 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(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::(), ); 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; }