From 950c57133fad52b6d33e85d3448c2e9394d86ecf Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM)" Date: Tue, 15 Jan 2019 13:10:02 -0800 Subject: [PATCH] Add a simple tool to generate provider ID's Also implements the Stringer interface for etw.Provider to output the ID Signed-off-by: Justin Terry (VM) --- internal/etw/provider.go | 19 +++++++++++++++++++ internal/etw/sample/sample.go | 20 +------------------- tools/etw-provider-gen/main.go | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 tools/etw-provider-gen/main.go diff --git a/internal/etw/provider.go b/internal/etw/provider.go index 4773a808..10c2fd6d 100644 --- a/internal/etw/provider.go +++ b/internal/etw/provider.go @@ -4,6 +4,8 @@ import ( "bytes" "crypto/sha1" "encoding/binary" + "encoding/hex" + "fmt" "strings" "unicode/utf16" @@ -25,6 +27,23 @@ type Provider struct { keywordAll uint64 } +// String returns the `provider`.ID as a string +func (provider *Provider) String() string { + data1 := make([]byte, 4) + binary.BigEndian.PutUint32(data1, provider.ID.Data1) + data2 := make([]byte, 2) + binary.BigEndian.PutUint16(data2, provider.ID.Data2) + data3 := make([]byte, 2) + binary.BigEndian.PutUint16(data3, provider.ID.Data3) + return fmt.Sprintf( + "%s-%s-%s-%s-%s", + hex.EncodeToString(data1), + hex.EncodeToString(data2), + hex.EncodeToString(data3), + hex.EncodeToString(provider.ID.Data4[:2]), + hex.EncodeToString(provider.ID.Data4[2:])) +} + type providerHandle windows.Handle // ProviderState informs the provider EnableCallback what action is being diff --git a/internal/etw/sample/sample.go b/internal/etw/sample/sample.go index ed544a2b..7766eca3 100644 --- a/internal/etw/sample/sample.go +++ b/internal/etw/sample/sample.go @@ -3,8 +3,6 @@ package main import ( "bufio" - "encoding/binary" - "encoding/hex" "fmt" "os" @@ -18,22 +16,6 @@ func callback(sourceID *windows.GUID, state etw.ProviderState, level etw.Level, fmt.Printf("Callback: isEnabled=%d, level=%d, matchAnyKeyword=%d\n", state, level, matchAnyKeyword) } -func guidToString(guid *windows.GUID) string { - data1 := make([]byte, 4) - binary.BigEndian.PutUint32(data1, guid.Data1) - data2 := make([]byte, 2) - binary.BigEndian.PutUint16(data2, guid.Data2) - data3 := make([]byte, 2) - binary.BigEndian.PutUint16(data3, guid.Data3) - return fmt.Sprintf( - "%s-%s-%s-%s-%s", - hex.EncodeToString(data1), - hex.EncodeToString(data2), - hex.EncodeToString(data3), - hex.EncodeToString(guid.Data4[:2]), - hex.EncodeToString(guid.Data4[2:])) -} - func main() { provider, err := etw.NewProvider("TestProvider", callback) @@ -47,7 +29,7 @@ func main() { } }() - fmt.Println("Provider ID:", guidToString(provider.ID)) + fmt.Printf("Provider ID: %s\n", provider) reader := bufio.NewReader(os.Stdin) diff --git a/tools/etw-provider-gen/main.go b/tools/etw-provider-gen/main.go new file mode 100644 index 00000000..c6d95cf7 --- /dev/null +++ b/tools/etw-provider-gen/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/Microsoft/go-winio/internal/etw" +) + +func main() { + var pn = flag.String("provider-name", "", "The human readable ETW provider name to be converted into GUID format") + flag.Parse() + if pn == nil || *pn == "" { + fmt.Fprint(os.Stderr, "--provider-name is required") + os.Exit(1) + } + p, err := etw.NewProvider(*pn, nil) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to convert provider-name: '%s' with err: '%s", *pn, err) + os.Exit(1) + } + defer p.Close() + fmt.Fprintf(os.Stdout, "%s", p) +}