Add lint and go generate steps to CI (#254)

* Add lint and go generate stages to CI

Add CI step to verify `go generate` was run on repo.
Add linter stage to CI along with linter config file,
`.golangci.yml`.
Will likely prefer revive over static-check.

Updated README Contributing section on linting requirements.

Added sequence ordering to make sure lint and go generate stages run
before tests and build.
This way, build and tests are not run on code that could potentially:

    1. not build due to `gofmt` issues;
    2. contain bugs;
    3. have to be re-submitted after issues are fixed; or
    4. contain outdated Win32 syscall or other auto-generated files.

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>

* Fixed linter issues

Code changes to satisfy linters:

 - Ran `gofmt -s -w` on repo.
 - Broke up long lines.
 - When possible, changed names with incorrect initialism formatting
   - Added exceptions for exported variables.
 - Added exceptions for ALL_CAPS_WITH_UNDERSCORES code.
   - Switched to using `windows` or `syscall` definitions if possible;
     especially if some constants were unused.
 - Added `_ =` to satisfy error linter, and acknowledge that errors are
   being ignored.
 - Switched to using `errors.Is` and `As` in places, elsewhere added
   exceptions if error value was known to be `syscall.Errno`.
 - Removed bare returns.
 - Prevented variables from being overshadowed in certain places
   (ignoring cases of overshadowing `err`).
 - Renamed variables and functions (eg, `len`, `eventMetadata.bytes`) to
   prevent shadowing pre-built functions and imported pacakges.
 - Removed unused method receivers.
 - Added exceptions to certain unused (unexported) constants and
   functions.
   - Deleted unused `once` from `pkg/etw.providerMap`.
 - Renamed `noop.go` files to `main_other.go` or `doc.go`, to better fit
   style recommendations.
 - Added exceptions for non-secure use of SHA1 and weak crypto
   libraries.
 - Replaced `ioutil` with `io` and `os` (and `t.TempDir` in tests).
 - Added fully exhaustive checks for `switch` statements in `pkg/etw`.
 - Defined constant strings for `tools/mkwinsyscall`.
 - Removed unnecessary conversions.
 - Made sure `context.Cancel` was called.

Additionally, added `//go:build windows" constraints on files with
unexported code, since linter will complain about unused code on
non-Windows platforms.

Added a stub `main() {}` for `mkwinsyscall` for non-Windows builds, just in
case `//go:generate` directives are added to OS-agnostic files.

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>

* PR: spelling, constants, fuzzing

Moved HVSocket fuzzing tests to separate file with go 1.18 build
constraint.

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
This commit is contained in:
Hamza El-Saawy
2022-08-23 15:05:05 -04:00
committed by GitHub
parent 79ae8cea02
commit e268c11e27
67 changed files with 1192 additions and 674 deletions
+8
View File
@@ -0,0 +1,8 @@
// Package etw provides support for TraceLogging-based ETW (Event Tracing
// for Windows). TraceLogging is a format of ETW events that are self-describing
// (the event contains information on its own schema). This allows them to be
// decoded without needing a separate manifest with event information. The
// implementation here is based on the information found in
// TraceLoggingProvider.h in the Windows SDK, which implements TraceLogging as a
// set of C macros.
package etw
+14 -13
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package etw
@@ -14,60 +15,60 @@ type eventData struct {
buffer bytes.Buffer
}
// bytes returns the raw binary data containing the event data. The returned
// toBytes returns the raw binary data containing the event data. The returned
// value is not copied from the internal buffer, so it can be mutated by the
// eventData object after it is returned.
func (ed *eventData) bytes() []byte {
func (ed *eventData) toBytes() []byte {
return ed.buffer.Bytes()
}
// writeString appends a string, including the null terminator, to the buffer.
func (ed *eventData) writeString(data string) {
ed.buffer.WriteString(data)
ed.buffer.WriteByte(0)
_, _ = ed.buffer.WriteString(data)
_ = ed.buffer.WriteByte(0)
}
// writeInt8 appends a int8 to the buffer.
func (ed *eventData) writeInt8(value int8) {
ed.buffer.WriteByte(uint8(value))
_ = ed.buffer.WriteByte(uint8(value))
}
// writeInt16 appends a int16 to the buffer.
func (ed *eventData) writeInt16(value int16) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeInt32 appends a int32 to the buffer.
func (ed *eventData) writeInt32(value int32) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeInt64 appends a int64 to the buffer.
func (ed *eventData) writeInt64(value int64) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeUint8 appends a uint8 to the buffer.
func (ed *eventData) writeUint8(value uint8) {
ed.buffer.WriteByte(value)
_ = ed.buffer.WriteByte(value)
}
// writeUint16 appends a uint16 to the buffer.
func (ed *eventData) writeUint16(value uint16) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeUint32 appends a uint32 to the buffer.
func (ed *eventData) writeUint32(value uint32) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeUint64 appends a uint64 to the buffer.
func (ed *eventData) writeUint64(value uint64) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
// writeFiletime appends a FILETIME to the buffer.
func (ed *eventData) writeFiletime(value syscall.Filetime) {
binary.Write(&ed.buffer, binary.LittleEndian, value)
_ = binary.Write(&ed.buffer, binary.LittleEndian, value)
}
+7 -5
View File
@@ -1,3 +1,5 @@
//go:build windows
package etw
import (
@@ -13,11 +15,11 @@ const (
)
type eventDataDescriptor struct {
ptr ptr64
size uint32
dataType eventDataDescriptorType
reserved1 uint8
reserved2 uint16
ptr ptr64
size uint32
dataType eventDataDescriptorType
_ uint8
_ uint16
}
func newEventDataDescriptor(dataType eventDataDescriptorType, buffer []byte) eventDataDescriptor {
+8
View File
@@ -1,3 +1,5 @@
//go:build windows
package etw
// Channel represents the ETW logging channel that is used. It can be used by
@@ -45,6 +47,8 @@ const (
)
// EventDescriptor represents various metadata for an ETW event.
//
//nolint:structcheck // task is currently unused
type eventDescriptor struct {
id uint16
version uint8
@@ -70,6 +74,8 @@ func newEventDescriptor() *eventDescriptor {
// should uniquely identify the other event metadata (contained in
// EventDescriptor, and field metadata). Only the lower 24 bits of this value
// are relevant.
//
//nolint:unused // keep for future use
func (ed *eventDescriptor) identity() uint32 {
return (uint32(ed.version) << 16) | uint32(ed.id)
}
@@ -78,6 +84,8 @@ func (ed *eventDescriptor) identity() uint32 {
// should uniquely identify the other event metadata (contained in
// EventDescriptor, and field metadata). Only the lower 24 bits of this value
// are relevant.
//
//nolint:unused // keep for future use
func (ed *eventDescriptor) setIdentity(identity uint32) {
ed.id = uint16(identity)
ed.version = uint8(identity >> 16)
+17 -5
View File
@@ -1,3 +1,5 @@
//go:build windows
package etw
import (
@@ -10,6 +12,8 @@ type inType byte
// Various inType definitions for TraceLogging. These must match the definitions
// found in TraceLoggingProvider.h in the Windows SDK.
//
//nolint:deadcode,varcheck // keep unused constants for potential future use
const (
inTypeNull inType = iota
inTypeUnicodeString
@@ -47,6 +51,8 @@ type outType byte
// Various outType definitions for TraceLogging. These must match the
// definitions found in TraceLoggingProvider.h in the Windows SDK.
//
//nolint:deadcode,varcheck // keep unused constants for potential future use
const (
// outTypeDefault indicates that the default formatting for the inType will
// be used by the event decoder.
@@ -81,11 +87,11 @@ type eventMetadata struct {
buffer bytes.Buffer
}
// bytes returns the raw binary data containing the event metadata. Before being
// toBytes returns the raw binary data containing the event metadata. Before being
// returned, the current size of the buffer is written to the start of the
// buffer. The returned value is not copied from the internal buffer, so it can
// be mutated by the eventMetadata object after it is returned.
func (em *eventMetadata) bytes() []byte {
func (em *eventMetadata) toBytes() []byte {
// Finalize the event metadata buffer by filling in the buffer length at the
// beginning.
binary.LittleEndian.PutUint16(em.buffer.Bytes(), uint16(em.buffer.Len()))
@@ -95,7 +101,7 @@ func (em *eventMetadata) bytes() []byte {
// writeEventHeader writes the metadata for the start of an event to the buffer.
// This specifies the event name and tags.
func (em *eventMetadata) writeEventHeader(name string, tags uint32) {
binary.Write(&em.buffer, binary.LittleEndian, uint16(0)) // Length placeholder
_ = binary.Write(&em.buffer, binary.LittleEndian, uint16(0)) // Length placeholder
em.writeTags(tags)
em.buffer.WriteString(name)
em.buffer.WriteByte(0) // Null terminator for name
@@ -118,7 +124,7 @@ func (em *eventMetadata) writeFieldInner(name string, inType inType, outType out
}
if arrSize != 0 {
binary.Write(&em.buffer, binary.LittleEndian, arrSize)
_ = binary.Write(&em.buffer, binary.LittleEndian, arrSize)
}
}
@@ -151,13 +157,17 @@ func (em *eventMetadata) writeTags(tags uint32) {
}
// writeField writes the metadata for a simple field to the buffer.
//
//nolint:unparam // tags is currently always 0, may change in the future
func (em *eventMetadata) writeField(name string, inType inType, outType outType, tags uint32) {
em.writeFieldInner(name, inType, outType, tags, 0)
}
// writeArray writes the metadata for an array field to the buffer. The number
// of elements in the array must be written as a uint16 in the event data,
// immediately preceeding the event data.
// immediately preceding the event data.
//
//nolint:unparam // tags is currently always 0, may change in the future
func (em *eventMetadata) writeArray(name string, inType inType, outType outType, tags uint32) {
em.writeFieldInner(name, inType|inTypeArray, outType, tags, 0)
}
@@ -165,6 +175,8 @@ func (em *eventMetadata) writeArray(name string, inType inType, outType outType,
// writeCountedArray writes the metadata for an array field to the buffer. The
// size of a counted array is fixed, and the size is written into the metadata
// directly.
//
//nolint:unused // keep for future use
func (em *eventMetadata) writeCountedArray(name string, count uint16, inType inType, outType outType, tags uint32) {
em.writeFieldInner(name, inType|inTypeCountedArray, outType, tags, count)
}
+1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package etw
+7 -3
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package etw
@@ -481,7 +482,7 @@ func SmartField(name string, v interface{}) FieldOpt {
case reflect.Int32:
return SmartField(name, int32(rv.Int()))
case reflect.Int64:
return SmartField(name, int64(rv.Int()))
return SmartField(name, int64(rv.Int())) //nolint:unconvert // make look consistent
case reflect.Uint:
return SmartField(name, uint(rv.Uint()))
case reflect.Uint8:
@@ -491,13 +492,13 @@ func SmartField(name string, v interface{}) FieldOpt {
case reflect.Uint32:
return SmartField(name, uint32(rv.Uint()))
case reflect.Uint64:
return SmartField(name, uint64(rv.Uint()))
return SmartField(name, uint64(rv.Uint())) //nolint:unconvert // make look consistent
case reflect.Uintptr:
return SmartField(name, uintptr(rv.Uint()))
case reflect.Float32:
return SmartField(name, float32(rv.Float()))
case reflect.Float64:
return SmartField(name, float64(rv.Float()))
return SmartField(name, float64(rv.Float())) //nolint:unconvert // make look consistent
case reflect.String:
return SmartField(name, rv.String())
case reflect.Struct:
@@ -509,6 +510,9 @@ func SmartField(name string, v interface{}) FieldOpt {
}
}
return Struct(name, fields...)
case reflect.Array, reflect.Chan, reflect.Complex128, reflect.Complex64,
reflect.Func, reflect.Interface, reflect.Invalid, reflect.Map, reflect.Ptr,
reflect.Slice, reflect.UnsafePointer:
}
}
+8 -7
View File
@@ -1,3 +1,4 @@
//go:build windows && (amd64 || arm64 || 386)
// +build windows
// +build amd64 arm64 386
@@ -45,18 +46,18 @@ func NewProviderWithOptions(name string, options ...ProviderOpt) (provider *Prov
trait := &bytes.Buffer{}
if opts.group != (guid.GUID{}) {
binary.Write(trait, binary.LittleEndian, uint16(0)) // Write empty size for buffer (update later)
binary.Write(trait, binary.LittleEndian, uint8(1)) // EtwProviderTraitTypeGroup
traitArray := opts.group.ToWindowsArray() // Append group guid
_ = binary.Write(trait, binary.LittleEndian, uint16(0)) // Write empty size for buffer (update later)
_ = binary.Write(trait, binary.LittleEndian, uint8(1)) // EtwProviderTraitTypeGroup
traitArray := opts.group.ToWindowsArray() // Append group guid
trait.Write(traitArray[:])
binary.LittleEndian.PutUint16(trait.Bytes(), uint16(trait.Len())) // Update size
}
metadata := &bytes.Buffer{}
binary.Write(metadata, binary.LittleEndian, uint16(0)) // Write empty size for buffer (to update later)
_ = 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
trait.WriteTo(metadata) // Add traits if applicable
_, _ = trait.WriteTo(metadata) // Add traits if applicable
binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len())) // Update the size at the beginning of the buffer
provider.metadata = metadata.Bytes()
@@ -64,8 +65,8 @@ func NewProviderWithOptions(name string, options ...ProviderOpt) (provider *Prov
provider.handle,
eventInfoClassProviderSetTraits,
uintptr(unsafe.Pointer(&provider.metadata[0])),
uint32(len(provider.metadata))); err != nil {
uint32(len(provider.metadata)),
); err != nil {
return nil, err
}
+2 -2
View File
@@ -1,5 +1,5 @@
// +build windows
// +build arm
//go:build windows && arm
// +build windows,arm
package etw
+52 -24
View File
@@ -1,9 +1,10 @@
//go:build windows
// +build windows
package etw
import (
"crypto/sha1"
"crypto/sha1" //nolint:gosec // not used for secure application
"encoding/binary"
"strings"
"unicode/utf16"
@@ -27,7 +28,7 @@ type Provider struct {
keywordAll uint64
}
// String returns the `provider`.ID as a string
// String returns the `provider`.ID as a string.
func (provider *Provider) String() string {
if provider == nil {
return "<nil>"
@@ -54,6 +55,7 @@ const (
type eventInfoClass uint32
//nolint:deadcode,varcheck // keep unused constants for potential future use
const (
eventInfoClassProviderBinaryTrackInfo eventInfoClass = iota
eventInfoClassProviderSetReserved1
@@ -65,10 +67,19 @@ const (
// enable/disable notifications from ETW.
type EnableCallback func(guid.GUID, ProviderState, Level, uint64, uint64, uintptr)
func providerCallback(sourceID guid.GUID, state ProviderState, level Level, matchAnyKeyword uint64, matchAllKeyword uint64, filterData uintptr, i uintptr) {
func providerCallback(
sourceID guid.GUID,
state ProviderState,
level Level,
matchAnyKeyword uint64,
matchAllKeyword uint64,
filterData uintptr,
i uintptr,
) {
provider := providers.getProvider(uint(i))
switch state {
case ProviderStateCaptureState:
case ProviderStateDisable:
provider.enabled = false
case ProviderStateEnable:
@@ -90,17 +101,22 @@ func providerCallback(sourceID guid.GUID, state ProviderState, level Level, matc
//
// The algorithm is roughly the RFC 4122 algorithm for a V5 UUID, but differs in
// the following ways:
// - The input name is first upper-cased, UTF16-encoded, and converted to
// big-endian.
// - No variant is set on the result UUID.
// - The result UUID is treated as being in little-endian format, rather than
// big-endian.
// - The input name is first upper-cased, UTF16-encoded, and converted to
// big-endian.
// - No variant is set on the result UUID.
// - The result UUID is treated as being in little-endian format, rather than
// big-endian.
func providerIDFromName(name string) guid.GUID {
buffer := sha1.New()
namespace := guid.GUID{0x482C2DB2, 0xC390, 0x47C8, [8]byte{0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB}}
buffer := sha1.New() //nolint:gosec // not used for secure application
namespace := guid.GUID{
Data1: 0x482C2DB2,
Data2: 0xC390,
Data3: 0x47C8,
Data4: [8]byte{0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB},
}
namespaceBytes := namespace.ToArray()
buffer.Write(namespaceBytes[:])
binary.Write(buffer, binary.BigEndian, utf16.Encode([]rune(strings.ToUpper(name))))
_ = binary.Write(buffer, binary.BigEndian, utf16.Encode([]rune(strings.ToUpper(name))))
sum := buffer.Sum(nil)
sum[7] = (sum[7] & 0xf) | 0x50
@@ -117,25 +133,24 @@ type providerOpts struct {
}
// ProviderOpt allows the caller to specify provider options to
// NewProviderWithOptions
// NewProviderWithOptions.
type ProviderOpt func(*providerOpts)
// WithCallback is used to provide a callback option to NewProviderWithOptions
// WithCallback is used to provide a callback option to NewProviderWithOptions.
func WithCallback(callback EnableCallback) ProviderOpt {
return func(opts *providerOpts) {
opts.callback = callback
}
}
// WithID is used to provide a provider ID option to NewProviderWithOptions
// WithID is used to provide a provider ID option to NewProviderWithOptions.
func WithID(id guid.GUID) ProviderOpt {
return func(opts *providerOpts) {
opts.id = id
}
}
// WithGroup is used to provide a provider group option to
// NewProviderWithOptions
// WithGroup is used to provide a provider group option to NewProviderWithOptions.
func WithGroup(group guid.GUID) ProviderOpt {
return func(opts *providerOpts) {
opts.group = group
@@ -237,11 +252,17 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt
// event metadata (e.g. for the name) so we don't need to do this check for
// the metadata.
dataBlobs := [][]byte{}
if len(ed.bytes()) > 0 {
dataBlobs = [][]byte{ed.bytes()}
if len(ed.toBytes()) > 0 {
dataBlobs = [][]byte{ed.toBytes()}
}
return provider.writeEventRaw(options.descriptor, options.activityID, options.relatedActivityID, [][]byte{em.bytes()}, dataBlobs)
return provider.writeEventRaw(
options.descriptor,
options.activityID,
options.relatedActivityID,
[][]byte{em.toBytes()},
dataBlobs,
)
}
// writeEventRaw writes a single ETW event from the provider. This function is
@@ -257,17 +278,24 @@ func (provider *Provider) writeEventRaw(
relatedActivityID guid.GUID,
metadataBlobs [][]byte,
dataBlobs [][]byte) error {
dataDescriptorCount := uint32(1 + len(metadataBlobs) + len(dataBlobs))
dataDescriptors := make([]eventDataDescriptor, 0, dataDescriptorCount)
dataDescriptors = append(dataDescriptors, newEventDataDescriptor(eventDataDescriptorTypeProviderMetadata, provider.metadata))
dataDescriptors = append(dataDescriptors,
newEventDataDescriptor(eventDataDescriptorTypeProviderMetadata, provider.metadata))
for _, blob := range metadataBlobs {
dataDescriptors = append(dataDescriptors, newEventDataDescriptor(eventDataDescriptorTypeEventMetadata, blob))
dataDescriptors = append(dataDescriptors,
newEventDataDescriptor(eventDataDescriptorTypeEventMetadata, blob))
}
for _, blob := range dataBlobs {
dataDescriptors = append(dataDescriptors, newEventDataDescriptor(eventDataDescriptorTypeUserData, blob))
dataDescriptors = append(dataDescriptors,
newEventDataDescriptor(eventDataDescriptorTypeUserData, blob))
}
return eventWriteTransfer(provider.handle, descriptor, (*windows.GUID)(&activityID), (*windows.GUID)(&relatedActivityID), dataDescriptorCount, &dataDescriptors[0])
return eventWriteTransfer(provider.handle,
descriptor,
(*windows.GUID)(&activityID),
(*windows.GUID)(&relatedActivityID),
dataDescriptorCount,
&dataDescriptors[0])
}
+1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package etw
+3 -1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package etw
@@ -14,7 +15,6 @@ type providerMap struct {
m map[uint]*Provider
i uint
lock sync.Mutex
once sync.Once
}
var providers = providerMap{
@@ -50,5 +50,7 @@ func (p *providerMap) getProvider(index uint) *Provider {
return p.m[index]
}
//todo: combine these into struct, so that "globalProviderCallback" is guaranteed to be initialized through method access
var providerCallbackOnce sync.Once
var globalProviderCallback uintptr
+2
View File
@@ -1,3 +1,5 @@
//go:build windows && (386 || arm)
// +build windows
// +build 386 arm
package etw
+2
View File
@@ -1,3 +1,5 @@
//go:build windows && (amd64 || arm64)
// +build windows
// +build amd64 arm64
package etw
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package main
@@ -1,3 +1,4 @@
//go:build windows
// +build windows
// Shows a sample usage of the ETW logging package.
+3 -8
View File
@@ -1,13 +1,8 @@
// Package etw provides support for TraceLogging-based ETW (Event Tracing
// for Windows). TraceLogging is a format of ETW events that are self-describing
// (the event contains information on its own schema). This allows them to be
// decoded without needing a separate manifest with event information. The
// implementation here is based on the information found in
// TraceLoggingProvider.h in the Windows SDK, which implements TraceLogging as a
// set of C macros.
//go:build windows
package etw
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go etw.go
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go syscall.go
//sys eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) = advapi32.EventRegister
+1
View File
@@ -1,3 +1,4 @@
//go:build windows && (386 || arm)
// +build windows
// +build 386 arm
+17 -4
View File
@@ -1,3 +1,4 @@
//go:build windows && (amd64 || arm64)
// +build windows
// +build amd64 arm64
@@ -19,7 +20,6 @@ func eventWriteTransfer(
relatedActivityID *windows.GUID,
dataDescriptorCount uint32,
dataDescriptors *eventDataDescriptor) (win32err error) {
return eventWriteTransfer_64(
providerHandle,
descriptor,
@@ -34,7 +34,6 @@ func eventSetInformation(
class eventInfoClass,
information uintptr,
length uint32) (win32err error) {
return eventSetInformation_64(
providerHandle,
class,
@@ -46,7 +45,21 @@ func eventSetInformation(
// for provider notifications. Because Go has trouble with callback arguments of
// different size, it has only pointer-sized arguments, which are then cast to
// the appropriate types when calling providerCallback.
func providerCallbackAdapter(sourceID *guid.GUID, state uintptr, level uintptr, matchAnyKeyword uintptr, matchAllKeyword uintptr, filterData uintptr, i uintptr) uintptr {
providerCallback(*sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
func providerCallbackAdapter(
sourceID *guid.GUID,
state uintptr,
level uintptr,
matchAnyKeyword uintptr,
matchAllKeyword uintptr,
filterData uintptr,
i uintptr,
) uintptr {
providerCallback(*sourceID,
ProviderState(state),
Level(level),
uint64(matchAnyKeyword),
uint64(matchAllKeyword),
filterData,
i)
return 0
}