diff --git a/internal/etw/etw.go b/internal/etw/etw.go index da905ec..5bddae2 100644 --- a/internal/etw/etw.go +++ b/internal/etw/etw.go @@ -12,3 +12,4 @@ package etw //sys eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) = advapi32.EventRegister //sys eventUnregister(providerHandle providerHandle) (win32err error) = advapi32.EventUnregister //sys eventWriteTransfer(providerHandle providerHandle, descriptor *EventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) = advapi32.EventWriteTransfer +//sys eventSetInformation(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) = advapi32.EventSetInformation diff --git a/internal/etw/eventopt.go b/internal/etw/eventopt.go index 5c752dc..447cec3 100644 --- a/internal/etw/eventopt.go +++ b/internal/etw/eventopt.go @@ -36,6 +36,12 @@ func WithKeyword(keyword uint64) EventOpt { } } +func WithChannel(channel Channel) EventOpt { + return func(options *eventOptions) { + options.descriptor.Channel = channel + } +} + // WithTags specifies the tags of the event to be written. Tags is a 28-bit // value (top 4 bits are ignored) which are interpreted by the event consumer. func WithTags(newTags uint32) EventOpt { diff --git a/internal/etw/provider.go b/internal/etw/provider.go index 10c2fd6..41abf34 100644 --- a/internal/etw/provider.go +++ b/internal/etw/provider.go @@ -8,6 +8,7 @@ import ( "fmt" "strings" "unicode/utf16" + "unsafe" "golang.org/x/sys/windows" ) @@ -60,6 +61,15 @@ const ( ProviderStateCaptureState ) +type eventInfoClass uint32 + +const ( + eventInfoClassProviderBinaryTrackInfo eventInfoClass = iota + eventInfoClassProviderSetReserved1 + eventInfoClassProviderSetTraits + eventInfoClassProviderUseDescriptorType +) + // EnableCallback is the form of the callback function that receives provider // enable/disable notifications from ETW. type EnableCallback func(*windows.GUID, ProviderState, Level, uint64, uint64, uintptr) @@ -152,6 +162,15 @@ func NewProviderWithID(name string, id *windows.GUID, callback EnableCallback) ( binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len())) // Update the size at the beginning of the buffer provider.metadata = metadata.Bytes() + if err := eventSetInformation( + provider.handle, + eventInfoClassProviderSetTraits, + uintptr(unsafe.Pointer(&provider.metadata[0])), + uint32(len(provider.metadata))); err != nil { + + return nil, err + } + return provider, nil } diff --git a/internal/etw/zsyscall_windows.go b/internal/etw/zsyscall_windows.go index 5b044ca..489a0f9 100644 --- a/internal/etw/zsyscall_windows.go +++ b/internal/etw/zsyscall_windows.go @@ -39,9 +39,10 @@ func errnoErr(e syscall.Errno) error { var ( modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") - procEventRegister = modadvapi32.NewProc("EventRegister") - procEventUnregister = modadvapi32.NewProc("EventUnregister") - procEventWriteTransfer = modadvapi32.NewProc("EventWriteTransfer") + procEventRegister = modadvapi32.NewProc("EventRegister") + procEventUnregister = modadvapi32.NewProc("EventUnregister") + procEventWriteTransfer = modadvapi32.NewProc("EventWriteTransfer") + procEventSetInformation = modadvapi32.NewProc("EventSetInformation") ) func eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) { @@ -67,3 +68,11 @@ func eventWriteTransfer(providerHandle providerHandle, descriptor *EventDescript } return } + +func eventSetInformation(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) { + r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 4, uintptr(providerHandle), uintptr(class), uintptr(information), uintptr(length), 0, 0) + if r0 != 0 { + win32err = syscall.Errno(r0) + } + return +}