Files
go-winio/pkg/etw/newprovider.go
T
Kevin Parsons 0112307ab4 Fix ETW package to work on 386
The ETW registration handle is defined to be 64-bits on all platforms. The Go
type previously used a uintptr which created problems on 32-bit systems. This
change adds a new wrapper file which receives a 64-bit handle for the functions
defined in it, and correctly passes it to the native ETW functions either as-is
(on 64-bit) or as two 32-bit values (on 32-bit).

This required a minor change in mksyscall_windows.go, to allow multiple syscalls
that map to the same underlying function without causing a duplicate definition
error in the generated file.
2019-04-22 10:28:49 -07:00

54 lines
1.6 KiB
Go

// +build amd64 arm64 386
package etw
import (
"bytes"
"encoding/binary"
"unsafe"
"github.com/Microsoft/go-winio/pkg/guid"
"golang.org/x/sys/windows"
)
// NewProviderWithID creates and registers a new ETW provider, allowing the
// provider ID to be manually specified. This is most useful when there is an
// existing provider ID that must be used to conform to existing diagnostic
// infrastructure.
func NewProviderWithID(name string, id *guid.GUID, callback EnableCallback) (provider *Provider, err error) {
providerCallbackOnce.Do(func() {
globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
})
provider = providers.newProvider()
defer func(provider *Provider) {
if err != nil {
providers.removeProvider(provider)
}
}(provider)
provider.ID = id
provider.callback = callback
if err := eventRegister((*windows.GUID)(provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
return nil, err
}
metadata := &bytes.Buffer{}
binary.Write(metadata, binary.LittleEndian, uint16(0)) // Write empty size for buffer (to update later)
metadata.WriteString(name)
metadata.WriteByte(0) // Null terminator for name
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
}