...
1
2
3
4
5 package etw
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "unsafe"
11
12 "github.com/Microsoft/go-winio/pkg/guid"
13 "golang.org/x/sys/windows"
14 )
15
16
17
18
19
20 func NewProviderWithOptions(name string, options ...ProviderOpt) (provider *Provider, err error) {
21 var opts providerOpts
22 for _, opt := range options {
23 opt(&opts)
24 }
25
26 if opts.id == (guid.GUID{}) {
27 opts.id = providerIDFromName(name)
28 }
29
30 providerCallbackOnce.Do(func() {
31 globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
32 })
33
34 provider = providers.newProvider()
35 defer func(provider *Provider) {
36 if err != nil {
37 providers.removeProvider(provider)
38 }
39 }(provider)
40 provider.ID = opts.id
41 provider.callback = opts.callback
42
43 if err := eventRegister((*windows.GUID)(&provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
44 return nil, err
45 }
46
47 trait := &bytes.Buffer{}
48 if opts.group != (guid.GUID{}) {
49 _ = binary.Write(trait, binary.LittleEndian, uint16(0))
50 _ = binary.Write(trait, binary.LittleEndian, uint8(1))
51 traitArray := opts.group.ToWindowsArray()
52 trait.Write(traitArray[:])
53 binary.LittleEndian.PutUint16(trait.Bytes(), uint16(trait.Len()))
54 }
55
56 metadata := &bytes.Buffer{}
57 _ = binary.Write(metadata, binary.LittleEndian, uint16(0))
58 metadata.WriteString(name)
59 metadata.WriteByte(0)
60 _, _ = trait.WriteTo(metadata)
61 binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len()))
62 provider.metadata = metadata.Bytes()
63
64 if err := eventSetInformation(
65 provider.handle,
66 eventInfoClassProviderSetTraits,
67 uintptr(unsafe.Pointer(&provider.metadata[0])),
68 uint32(len(provider.metadata)),
69 ); err != nil {
70 return nil, err
71 }
72
73 return provider, nil
74 }
75
View as plain text