diff --git a/vendor.conf b/vendor.conf index 0ca8d4fce4..c313dcc300 100644 --- a/vendor.conf +++ b/vendor.conf @@ -1,7 +1,7 @@ # the following lines are in sorted order, FYI github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 github.com/Microsoft/hcsshim ada9cb39f715fb568e1030e7613732bb4f1e4aeb -github.com/Microsoft/go-winio 4de24ed3e8c509e6d1f609a8cb6b1c9fd9816e6d +github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/eventdata.go b/vendor/github.com/Microsoft/go-winio/internal/etw/eventdata.go deleted file mode 100644 index 32cf56818f..0000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/eventdata.go +++ /dev/null @@ -1,65 +0,0 @@ -package etw - -import ( - "bytes" - "encoding/binary" -) - -// EventData maintains a buffer which builds up the data for an ETW event. It -// needs to be paired with EventMetadata which describes the event. -type EventData struct { - buffer bytes.Buffer -} - -// Bytes 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 { - 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) -} - -// WriteInt8 appends a int8 to the buffer. -func (ed *EventData) WriteInt8(value int8) { - 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) -} - -// WriteInt32 appends a int32 to the buffer. -func (ed *EventData) WriteInt32(value int32) { - 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) -} - -// WriteUint8 appends a uint8 to the buffer. -func (ed *EventData) WriteUint8(value uint8) { - ed.buffer.WriteByte(value) -} - -// WriteUint16 appends a uint16 to the buffer. -func (ed *EventData) WriteUint16(value uint16) { - 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) -} - -// WriteUint64 appends a uint64 to the buffer. -func (ed *EventData) WriteUint64(value uint64) { - binary.Write(&ed.buffer, binary.LittleEndian, value) -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/eventmetadata.go b/vendor/github.com/Microsoft/go-winio/internal/etw/eventmetadata.go deleted file mode 100644 index e97ede03ea..0000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/eventmetadata.go +++ /dev/null @@ -1,177 +0,0 @@ -package etw - -import ( - "bytes" - "encoding/binary" -) - -// InType indicates the type of data contained in the ETW event. -type InType byte - -// Various InType definitions for TraceLogging. These must match the definitions -// found in TraceLoggingProvider.h in the Windows SDK. -const ( - InTypeNull InType = iota - InTypeUnicodeString - InTypeANSIString - InTypeInt8 - InTypeUint8 - InTypeInt16 - InTypeUint16 - InTypeInt32 - InTypeUint32 - InTypeInt64 - InTypeUint64 - InTypeFloat - InTypeDouble - InTypeBool32 - InTypeBinary - InTypeGUID - InTypePointerUnsupported - InTypeFileTime - InTypeSystemTime - InTypeSID - InTypeHexInt32 - InTypeHexInt64 - InTypeCountedString - InTypeCountedANSIString - InTypeStruct - InTypeCountedBinary - InTypeCountedArray InType = 32 - InTypeArray InType = 64 -) - -// OutType specifies a hint to the event decoder for how the value should be -// formatted. -type OutType byte - -// Various OutType definitions for TraceLogging. These must match the -// definitions found in TraceLoggingProvider.h in the Windows SDK. -const ( - // OutTypeDefault indicates that the default formatting for the InType will - // be used by the event decoder. - OutTypeDefault OutType = iota - OutTypeNoPrint - OutTypeString - OutTypeBoolean - OutTypeHex - OutTypePID - OutTypeTID - OutTypePort - OutTypeIPv4 - OutTypeIPv6 - OutTypeSocketAddress - OutTypeXML - OutTypeJSON - OutTypeWin32Error - OutTypeNTStatus - OutTypeHResult - OutTypeFileTime - OutTypeSigned - OutTypeUnsigned - OutTypeUTF8 OutType = 35 - OutTypePKCS7WithTypeInfo OutType = 36 - OutTypeCodePointer OutType = 37 - OutTypeDateTimeUTC OutType = 38 -) - -// EventMetadata maintains a buffer which builds up the metadata for an ETW -// event. It needs to be paired with EventData which describes the event. -type EventMetadata struct { - buffer bytes.Buffer -} - -// Bytes 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 { - // Finalize the event metadata buffer by filling in the buffer length at the - // beginning. - binary.LittleEndian.PutUint16(em.buffer.Bytes(), uint16(em.buffer.Len())) - return em.buffer.Bytes() -} - -// 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 - em.writeTags(tags) - em.buffer.WriteString(name) - em.buffer.WriteByte(0) // Null terminator for name -} - -func (em *EventMetadata) writeField(name string, inType InType, outType OutType, tags uint32, arrSize uint16) { - em.buffer.WriteString(name) - em.buffer.WriteByte(0) // Null terminator for name - - if outType == OutTypeDefault && tags == 0 { - em.buffer.WriteByte(byte(inType)) - } else { - em.buffer.WriteByte(byte(inType | 128)) - if tags == 0 { - em.buffer.WriteByte(byte(outType)) - } else { - em.buffer.WriteByte(byte(outType | 128)) - em.writeTags(tags) - } - } - - if arrSize != 0 { - binary.Write(&em.buffer, binary.LittleEndian, arrSize) - } -} - -// writeTags writes out the tags value to the event metadata. Tags is a 28-bit -// value, interpreted as bit flags, which are only relevant to the event -// consumer. The event consumer may choose to attribute special meaning to tags -// (e.g. 0x4 could mean the field contains PII). Tags are written as a series of -// bytes, each containing 7 bits of tag value, with the high bit set if there is -// more tag data in the following byte. This allows for a more compact -// representation when not all of the tag bits are needed. -func (em *EventMetadata) writeTags(tags uint32) { - // Only use the top 28 bits of the tags value. - tags &= 0xfffffff - - for { - // Tags are written with the most significant bits (e.g. 21-27) first. - val := tags >> 21 - - if tags&0x1fffff == 0 { - // If there is no more data to write after this, write this value - // without the high bit set, and return. - em.buffer.WriteByte(byte(val & 0x7f)) - return - } - - em.buffer.WriteByte(byte(val | 0x80)) - - tags <<= 7 - } -} - -// WriteField writes the metadata for a simple field to the buffer. -func (em *EventMetadata) WriteField(name string, inType InType, outType OutType, tags uint32) { - em.writeField(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. -func (em *EventMetadata) WriteArray(name string, inType InType, outType OutType, tags uint32) { - em.writeField(name, inType|InTypeArray, outType, tags, 0) -} - -// 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. -func (em *EventMetadata) WriteCountedArray(name string, count uint16, inType InType, outType OutType, tags uint32) { - em.writeField(name, inType|InTypeCountedArray, outType, tags, count) -} - -// WriteStruct writes the metadata for a nested struct to the buffer. The struct -// contains the next N fields in the metadata, where N is specified by the -// fieldCount argument. -func (em *EventMetadata) WriteStruct(name string, fieldCount uint8, tags uint32) { - em.writeField(name, InTypeStruct, OutType(fieldCount), tags, 0) -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/etw.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/etw.go similarity index 94% rename from vendor/github.com/Microsoft/go-winio/internal/etw/etw.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/etw.go index 88214fbaac..a958b26cd4 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/etw.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/etw.go @@ -11,5 +11,5 @@ 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 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/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdata.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdata.go new file mode 100644 index 0000000000..79dc10a5fa --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdata.go @@ -0,0 +1,65 @@ +package etw + +import ( + "bytes" + "encoding/binary" +) + +// eventData maintains a buffer which builds up the data for an ETW event. It +// needs to be paired with EventMetadata which describes the event. +type eventData struct { + buffer bytes.Buffer +} + +// bytes 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 { + 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) +} + +// writeInt8 appends a int8 to the buffer. +func (ed *eventData) writeInt8(value int8) { + 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) +} + +// writeInt32 appends a int32 to the buffer. +func (ed *eventData) writeInt32(value int32) { + 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) +} + +// writeUint8 appends a uint8 to the buffer. +func (ed *eventData) writeUint8(value uint8) { + ed.buffer.WriteByte(value) +} + +// writeUint16 appends a uint16 to the buffer. +func (ed *eventData) writeUint16(value uint16) { + 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) +} + +// writeUint64 appends a uint64 to the buffer. +func (ed *eventData) writeUint64(value uint64) { + binary.Write(&ed.buffer, binary.LittleEndian, value) +} diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/eventdatadescriptor.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdatadescriptor.go similarity index 100% rename from vendor/github.com/Microsoft/go-winio/internal/etw/eventdatadescriptor.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/eventdatadescriptor.go diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/eventdescriptor.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdescriptor.go similarity index 83% rename from vendor/github.com/Microsoft/go-winio/internal/etw/eventdescriptor.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/eventdescriptor.go index 23980b38ff..b16ad57ecf 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/eventdescriptor.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventdescriptor.go @@ -28,24 +28,24 @@ const ( ) // EventDescriptor represents various metadata for an ETW event. -type EventDescriptor struct { +type eventDescriptor struct { id uint16 version uint8 - Channel Channel - Level Level - Opcode uint8 - Task uint16 - Keyword uint64 + channel Channel + level Level + opcode uint8 + task uint16 + keyword uint64 } // NewEventDescriptor returns an EventDescriptor initialized for use with // TraceLogging. -func NewEventDescriptor() *EventDescriptor { +func newEventDescriptor() *eventDescriptor { // Standard TraceLogging events default to the TraceLogging channel, and // verbose level. - return &EventDescriptor{ - Channel: ChannelTraceLogging, - Level: LevelVerbose, + return &eventDescriptor{ + channel: ChannelTraceLogging, + level: LevelVerbose, } } @@ -53,7 +53,7 @@ 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. -func (ed *EventDescriptor) Identity() uint32 { +func (ed *eventDescriptor) identity() uint32 { return (uint32(ed.version) << 16) | uint32(ed.id) } @@ -61,7 +61,7 @@ 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. -func (ed *EventDescriptor) SetIdentity(identity uint32) { +func (ed *eventDescriptor) setIdentity(identity uint32) { ed.id = uint16(identity) ed.version = uint8(identity >> 16) } diff --git a/vendor/github.com/Microsoft/go-winio/pkg/etw/eventmetadata.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventmetadata.go new file mode 100644 index 0000000000..6fdc126cc9 --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventmetadata.go @@ -0,0 +1,177 @@ +package etw + +import ( + "bytes" + "encoding/binary" +) + +// inType indicates the type of data contained in the ETW event. +type inType byte + +// Various inType definitions for TraceLogging. These must match the definitions +// found in TraceLoggingProvider.h in the Windows SDK. +const ( + inTypeNull inType = iota + inTypeUnicodeString + inTypeANSIString + inTypeInt8 + inTypeUint8 + inTypeInt16 + inTypeUint16 + inTypeInt32 + inTypeUint32 + inTypeInt64 + inTypeUint64 + inTypeFloat + inTypeDouble + inTypeBool32 + inTypeBinary + inTypeGUID + inTypePointerUnsupported + inTypeFileTime + inTypeSystemTime + inTypeSID + inTypeHexInt32 + inTypeHexInt64 + inTypeCountedString + inTypeCountedANSIString + inTypeStruct + inTypeCountedBinary + inTypeCountedArray inType = 32 + inTypeArray inType = 64 +) + +// outType specifies a hint to the event decoder for how the value should be +// formatted. +type outType byte + +// Various outType definitions for TraceLogging. These must match the +// definitions found in TraceLoggingProvider.h in the Windows SDK. +const ( + // outTypeDefault indicates that the default formatting for the inType will + // be used by the event decoder. + outTypeDefault outType = iota + outTypeNoPrint + outTypeString + outTypeBoolean + outTypeHex + outTypePID + outTypeTID + outTypePort + outTypeIPv4 + outTypeIPv6 + outTypeSocketAddress + outTypeXML + outTypeJSON + outTypeWin32Error + outTypeNTStatus + outTypeHResult + outTypeFileTime + outTypeSigned + outTypeUnsigned + outTypeUTF8 outType = 35 + outTypePKCS7WithTypeInfo outType = 36 + outTypeCodePointer outType = 37 + outTypeDateTimeUTC outType = 38 +) + +// eventMetadata maintains a buffer which builds up the metadata for an ETW +// event. It needs to be paired with EventData which describes the event. +type eventMetadata struct { + buffer bytes.Buffer +} + +// bytes 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 { + // Finalize the event metadata buffer by filling in the buffer length at the + // beginning. + binary.LittleEndian.PutUint16(em.buffer.Bytes(), uint16(em.buffer.Len())) + return em.buffer.Bytes() +} + +// 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 + em.writeTags(tags) + em.buffer.WriteString(name) + em.buffer.WriteByte(0) // Null terminator for name +} + +func (em *eventMetadata) writeFieldInner(name string, inType inType, outType outType, tags uint32, arrSize uint16) { + em.buffer.WriteString(name) + em.buffer.WriteByte(0) // Null terminator for name + + if outType == outTypeDefault && tags == 0 { + em.buffer.WriteByte(byte(inType)) + } else { + em.buffer.WriteByte(byte(inType | 128)) + if tags == 0 { + em.buffer.WriteByte(byte(outType)) + } else { + em.buffer.WriteByte(byte(outType | 128)) + em.writeTags(tags) + } + } + + if arrSize != 0 { + binary.Write(&em.buffer, binary.LittleEndian, arrSize) + } +} + +// writeTags writes out the tags value to the event metadata. Tags is a 28-bit +// value, interpreted as bit flags, which are only relevant to the event +// consumer. The event consumer may choose to attribute special meaning to tags +// (e.g. 0x4 could mean the field contains PII). Tags are written as a series of +// bytes, each containing 7 bits of tag value, with the high bit set if there is +// more tag data in the following byte. This allows for a more compact +// representation when not all of the tag bits are needed. +func (em *eventMetadata) writeTags(tags uint32) { + // Only use the top 28 bits of the tags value. + tags &= 0xfffffff + + for { + // Tags are written with the most significant bits (e.g. 21-27) first. + val := tags >> 21 + + if tags&0x1fffff == 0 { + // If there is no more data to write after this, write this value + // without the high bit set, and return. + em.buffer.WriteByte(byte(val & 0x7f)) + return + } + + em.buffer.WriteByte(byte(val | 0x80)) + + tags <<= 7 + } +} + +// writeField writes the metadata for a simple field to the buffer. +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. +func (em *eventMetadata) writeArray(name string, inType inType, outType outType, tags uint32) { + em.writeFieldInner(name, inType|inTypeArray, outType, tags, 0) +} + +// 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. +func (em *eventMetadata) writeCountedArray(name string, count uint16, inType inType, outType outType, tags uint32) { + em.writeFieldInner(name, inType|inTypeCountedArray, outType, tags, count) +} + +// writeStruct writes the metadata for a nested struct to the buffer. The struct +// contains the next N fields in the metadata, where N is specified by the +// fieldCount argument. +func (em *eventMetadata) writeStruct(name string, fieldCount uint8, tags uint32) { + em.writeFieldInner(name, inTypeStruct, outType(fieldCount), tags, 0) +} diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/eventopt.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventopt.go similarity index 90% rename from vendor/github.com/Microsoft/go-winio/internal/etw/eventopt.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/eventopt.go index 2c82eddcc2..33ad6a47f2 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/eventopt.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/eventopt.go @@ -5,7 +5,7 @@ import ( ) type eventOptions struct { - descriptor *EventDescriptor + descriptor *eventDescriptor activityID *windows.GUID relatedActivityID *windows.GUID tags uint32 @@ -24,7 +24,7 @@ func WithEventOpts(opts ...EventOpt) []EventOpt { // WithLevel specifies the level of the event to be written. func WithLevel(level Level) EventOpt { return func(options *eventOptions) { - options.descriptor.Level = level + options.descriptor.level = level } } @@ -32,13 +32,13 @@ func WithLevel(level Level) EventOpt { // of this option are OR'd together. func WithKeyword(keyword uint64) EventOpt { return func(options *eventOptions) { - options.descriptor.Keyword |= keyword + options.descriptor.keyword |= keyword } } func WithChannel(channel Channel) EventOpt { return func(options *eventOptions) { - options.descriptor.Channel = channel + options.descriptor.channel = channel } } diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/fieldopt.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/fieldopt.go similarity index 51% rename from vendor/github.com/Microsoft/go-winio/internal/etw/fieldopt.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/fieldopt.go index 5d5b4254da..630a321268 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/fieldopt.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/fieldopt.go @@ -7,7 +7,7 @@ import ( // FieldOpt defines the option function type that can be passed to // Provider.WriteEvent to add fields to the event. -type FieldOpt func(em *EventMetadata, ed *EventData) +type FieldOpt func(em *eventMetadata, ed *eventData) // WithFields returns the variadic arguments as a single slice. func WithFields(opts ...FieldOpt) []FieldOpt { @@ -16,46 +16,46 @@ func WithFields(opts ...FieldOpt) []FieldOpt { // BoolField adds a single bool field to the event. func BoolField(name string, value bool) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint8, OutTypeBoolean, 0) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint8, outTypeBoolean, 0) bool8 := uint8(0) if value { bool8 = uint8(1) } - ed.WriteUint8(bool8) + ed.writeUint8(bool8) } } // BoolArray adds an array of bool to the event. func BoolArray(name string, values []bool) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint8, OutTypeBoolean, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint8, outTypeBoolean, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { bool8 := uint8(0) if v { bool8 = uint8(1) } - ed.WriteUint8(bool8) + ed.writeUint8(bool8) } } } // StringField adds a single string field to the event. func StringField(name string, value string) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeANSIString, OutTypeUTF8, 0) - ed.WriteString(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeANSIString, outTypeUTF8, 0) + ed.writeString(value) } } // StringArray adds an array of string to the event. func StringArray(name string, values []string) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeANSIString, OutTypeUTF8, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeANSIString, outTypeUTF8, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteString(v) + ed.writeString(v) } } } @@ -74,22 +74,22 @@ func IntField(name string, value int) FieldOpt { // IntArray adds an array of int to the event. func IntArray(name string, values []int) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, int) + inType := inTypeNull + var writeItem func(*eventData, int) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeInt32 - writeItem = func(ed *EventData, item int) { ed.WriteInt32(int32(item)) } + inType = inTypeInt32 + writeItem = func(ed *eventData, item int) { ed.writeInt32(int32(item)) } case 8: - inType = InTypeInt64 - writeItem = func(ed *EventData, item int) { ed.WriteInt64(int64(item)) } + inType = inTypeInt64 + writeItem = func(ed *eventData, item int) { ed.writeInt64(int64(item)) } default: panic("Unsupported int size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -98,76 +98,76 @@ func IntArray(name string, values []int) FieldOpt { // Int8Field adds a single int8 field to the event. func Int8Field(name string, value int8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt8, OutTypeDefault, 0) - ed.WriteInt8(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt8, outTypeDefault, 0) + ed.writeInt8(value) } } // Int8Array adds an array of int8 to the event. func Int8Array(name string, values []int8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt8, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt8, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt8(v) + ed.writeInt8(v) } } } // Int16Field adds a single int16 field to the event. func Int16Field(name string, value int16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt16, OutTypeDefault, 0) - ed.WriteInt16(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt16, outTypeDefault, 0) + ed.writeInt16(value) } } // Int16Array adds an array of int16 to the event. func Int16Array(name string, values []int16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt16, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt16, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt16(v) + ed.writeInt16(v) } } } // Int32Field adds a single int32 field to the event. func Int32Field(name string, value int32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt32, OutTypeDefault, 0) - ed.WriteInt32(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt32, outTypeDefault, 0) + ed.writeInt32(value) } } // Int32Array adds an array of int32 to the event. func Int32Array(name string, values []int32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt32, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt32, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt32(v) + ed.writeInt32(v) } } } // Int64Field adds a single int64 field to the event. func Int64Field(name string, value int64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeInt64, OutTypeDefault, 0) - ed.WriteInt64(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeInt64, outTypeDefault, 0) + ed.writeInt64(value) } } // Int64Array adds an array of int64 to the event. func Int64Array(name string, values []int64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeInt64, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeInt64, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteInt64(v) + ed.writeInt64(v) } } } @@ -186,22 +186,22 @@ func UintField(name string, value uint) FieldOpt { // UintArray adds an array of uint to the event. func UintArray(name string, values []uint) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uint) + inType := inTypeNull + var writeItem func(*eventData, uint) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeUint32 - writeItem = func(ed *EventData, item uint) { ed.WriteUint32(uint32(item)) } + inType = inTypeUint32 + writeItem = func(ed *eventData, item uint) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeUint64 - writeItem = func(ed *EventData, item uint) { ed.WriteUint64(uint64(item)) } + inType = inTypeUint64 + writeItem = func(ed *eventData, item uint) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uint size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -210,119 +210,119 @@ func UintArray(name string, values []uint) FieldOpt { // Uint8Field adds a single uint8 field to the event. func Uint8Field(name string, value uint8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint8, OutTypeDefault, 0) - ed.WriteUint8(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint8, outTypeDefault, 0) + ed.writeUint8(value) } } // Uint8Array adds an array of uint8 to the event. func Uint8Array(name string, values []uint8) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint8, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint8, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint8(v) + ed.writeUint8(v) } } } // Uint16Field adds a single uint16 field to the event. func Uint16Field(name string, value uint16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint16, OutTypeDefault, 0) - ed.WriteUint16(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint16, outTypeDefault, 0) + ed.writeUint16(value) } } // Uint16Array adds an array of uint16 to the event. func Uint16Array(name string, values []uint16) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint16, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint16, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint16(v) + ed.writeUint16(v) } } } // Uint32Field adds a single uint32 field to the event. func Uint32Field(name string, value uint32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint32, OutTypeDefault, 0) - ed.WriteUint32(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint32, outTypeDefault, 0) + ed.writeUint32(value) } } // Uint32Array adds an array of uint32 to the event. func Uint32Array(name string, values []uint32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint32, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint32, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint32(v) + ed.writeUint32(v) } } } // Uint64Field adds a single uint64 field to the event. func Uint64Field(name string, value uint64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeUint64, OutTypeDefault, 0) - ed.WriteUint64(value) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUint64, outTypeDefault, 0) + ed.writeUint64(value) } } // Uint64Array adds an array of uint64 to the event. func Uint64Array(name string, values []uint64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeUint64, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUint64, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint64(v) + ed.writeUint64(v) } } } // UintptrField adds a single uintptr field to the event. func UintptrField(name string, value uintptr) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uintptr) + inType := inTypeNull + var writeItem func(*eventData, uintptr) switch unsafe.Sizeof(value) { case 4: - inType = InTypeHexInt32 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint32(uint32(item)) } + inType = inTypeHexInt32 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeHexInt64 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint64(uint64(item)) } + inType = inTypeHexInt64 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uintptr size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, inType, OutTypeDefault, 0) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inType, outTypeDefault, 0) writeItem(ed, value) } } // UintptrArray adds an array of uintptr to the event. func UintptrArray(name string, values []uintptr) FieldOpt { - inType := InTypeNull - var writeItem func(*EventData, uintptr) + inType := inTypeNull + var writeItem func(*eventData, uintptr) switch unsafe.Sizeof(values[0]) { case 4: - inType = InTypeHexInt32 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint32(uint32(item)) } + inType = inTypeHexInt32 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint32(uint32(item)) } case 8: - inType = InTypeHexInt64 - writeItem = func(ed *EventData, item uintptr) { ed.WriteUint64(uint64(item)) } + inType = inTypeHexInt64 + writeItem = func(ed *eventData, item uintptr) { ed.writeUint64(uint64(item)) } default: panic("Unsupported uintptr size") } - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, inType, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inType, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { writeItem(ed, v) } @@ -331,38 +331,38 @@ func UintptrArray(name string, values []uintptr) FieldOpt { // Float32Field adds a single float32 field to the event. func Float32Field(name string, value float32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeFloat, OutTypeDefault, 0) - ed.WriteUint32(math.Float32bits(value)) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeFloat, outTypeDefault, 0) + ed.writeUint32(math.Float32bits(value)) } } // Float32Array adds an array of float32 to the event. func Float32Array(name string, values []float32) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeFloat, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeFloat, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint32(math.Float32bits(v)) + ed.writeUint32(math.Float32bits(v)) } } } // Float64Field adds a single float64 field to the event. func Float64Field(name string, value float64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteField(name, InTypeDouble, OutTypeDefault, 0) - ed.WriteUint64(math.Float64bits(value)) + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeDouble, outTypeDefault, 0) + ed.writeUint64(math.Float64bits(value)) } } // Float64Array adds an array of float64 to the event. func Float64Array(name string, values []float64) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteArray(name, InTypeDouble, OutTypeDefault, 0) - ed.WriteUint16(uint16(len(values))) + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeDouble, outTypeDefault, 0) + ed.writeUint16(uint16(len(values))) for _, v := range values { - ed.WriteUint64(math.Float64bits(v)) + ed.writeUint64(math.Float64bits(v)) } } } @@ -370,8 +370,8 @@ func Float64Array(name string, values []float64) FieldOpt { // Struct adds a nested struct to the event, the FieldOpts in the opts argument // are used to specify the fields of the struct. func Struct(name string, opts ...FieldOpt) FieldOpt { - return func(em *EventMetadata, ed *EventData) { - em.WriteStruct(name, uint8(len(opts)), 0) + return func(em *eventMetadata, ed *eventData) { + em.writeStruct(name, uint8(len(opts)), 0) for _, opt := range opts { opt(em, ed) } diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/provider.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/provider.go similarity index 94% rename from vendor/github.com/Microsoft/go-winio/internal/etw/provider.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/provider.go index 452c860ffc..a81652f6fb 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/provider.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/provider.go @@ -219,9 +219,9 @@ func (provider *Provider) IsEnabledForLevelAndKeywords(level Level, keywords uin // constructed based on the EventOpt and FieldOpt values that are passed as // opts. func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpts []FieldOpt) error { - options := eventOptions{descriptor: NewEventDescriptor()} - em := &EventMetadata{} - ed := &EventData{} + options := eventOptions{descriptor: newEventDescriptor()} + em := &eventMetadata{} + ed := &eventData{} // We need to evaluate the EventOpts first since they might change tags, and // we write out the tags before evaluating FieldOpts. @@ -229,11 +229,11 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt opt(&options) } - if !provider.IsEnabledForLevelAndKeywords(options.descriptor.Level, options.descriptor.Keyword) { + if !provider.IsEnabledForLevelAndKeywords(options.descriptor.level, options.descriptor.keyword) { return nil } - em.WriteEventHeader(name, options.tags) + em.writeEventHeader(name, options.tags) for _, opt := range fieldOpts { opt(em, ed) @@ -243,22 +243,22 @@ 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.bytes()) > 0 { + dataBlobs = [][]byte{ed.bytes()} } - return provider.WriteEventRaw(options.descriptor, nil, nil, [][]byte{em.Bytes()}, dataBlobs) + return provider.writeEventRaw(options.descriptor, nil, nil, [][]byte{em.bytes()}, dataBlobs) } -// WriteEventRaw writes a single ETW event from the provider. This function is +// writeEventRaw writes a single ETW event from the provider. This function is // less abstracted than WriteEvent, and presents a fairly direct interface to // the event writing functionality. It expects a series of event metadata and // event data blobs to be passed in, which must conform to the TraceLogging // schema. The functions on EventMetadata and EventData can help with creating // these blobs. The blobs of each type are effectively concatenated together by // the ETW infrastructure. -func (provider *Provider) WriteEventRaw( - descriptor *EventDescriptor, +func (provider *Provider) writeEventRaw( + descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, metadataBlobs [][]byte, diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/providerglobal.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/providerglobal.go similarity index 100% rename from vendor/github.com/Microsoft/go-winio/internal/etw/providerglobal.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/providerglobal.go diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/ptr64_32.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/ptr64_32.go similarity index 100% rename from vendor/github.com/Microsoft/go-winio/internal/etw/ptr64_32.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/ptr64_32.go diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/ptr64_64.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/ptr64_64.go similarity index 100% rename from vendor/github.com/Microsoft/go-winio/internal/etw/ptr64_64.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/ptr64_64.go diff --git a/vendor/github.com/Microsoft/go-winio/internal/etw/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/etw/zsyscall_windows.go similarity index 97% rename from vendor/github.com/Microsoft/go-winio/internal/etw/zsyscall_windows.go rename to vendor/github.com/Microsoft/go-winio/pkg/etw/zsyscall_windows.go index 489a0f99ce..802cd69ddf 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/etw/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etw/zsyscall_windows.go @@ -61,7 +61,7 @@ func eventUnregister(providerHandle providerHandle) (win32err error) { return } -func eventWriteTransfer(providerHandle providerHandle, descriptor *EventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { +func eventWriteTransfer(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors))) if r0 != 0 { win32err = syscall.Errno(r0) diff --git a/vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go b/vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go index fe0835b3a1..81c14e428d 100644 --- a/vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go @@ -4,26 +4,31 @@ import ( "fmt" "reflect" - "github.com/Microsoft/go-winio/internal/etw" + "github.com/Microsoft/go-winio/pkg/etw" "github.com/sirupsen/logrus" ) // Hook is a Logrus hook which logs received events to ETW. type Hook struct { - provider *etw.Provider + provider *etw.Provider + closeProvider bool } -// NewHook registers a new ETW provider and returns a hook to log from it. +// NewHook registers a new ETW provider and returns a hook to log from it. The +// provider will be closed when the hook is closed. func NewHook(providerName string) (*Hook, error) { - hook := Hook{} - provider, err := etw.NewProvider(providerName, nil) if err != nil { return nil, err } - hook.provider = provider - return &hook, nil + return &Hook{provider, true}, nil +} + +// NewHookFromProvider creates a new hook based on an existing ETW provider. The +// provider will not be closed when the hook is closed. +func NewHookFromProvider(provider *etw.Provider) (*Hook, error) { + return &Hook{provider, false}, nil } // Levels returns the set of levels that this hook wants to receive log entries @@ -40,9 +45,22 @@ func (h *Hook) Levels() []logrus.Level { } } +var logrusToETWLevelMap = map[logrus.Level]etw.Level{ + logrus.PanicLevel: etw.LevelAlways, + logrus.FatalLevel: etw.LevelCritical, + logrus.ErrorLevel: etw.LevelError, + logrus.WarnLevel: etw.LevelWarning, + logrus.InfoLevel: etw.LevelInfo, + logrus.DebugLevel: etw.LevelVerbose, + logrus.TraceLevel: etw.LevelVerbose, +} + // Fire receives each Logrus entry as it is logged, and logs it to ETW. func (h *Hook) Fire(e *logrus.Entry) error { - level := etw.Level(e.Level) + // Logrus defines more levels than ETW typically uses, but analysis is + // easiest when using a consistent set of levels across ETW providers, so we + // map the Logrus levels to ETW levels. + level := logrusToETWLevelMap[e.Level] if !h.provider.IsEnabledForLevel(level) { return nil } @@ -56,9 +74,6 @@ func (h *Hook) Fire(e *logrus.Entry) error { fields = append(fields, getFieldOpt(k, v)) } - // We could try to map Logrus levels to ETW levels, but we would lose some - // fidelity as there are fewer ETW levels. So instead we use the level - // directly. return h.provider.WriteEvent( "LogrusEntry", etw.WithEventOpts(etw.WithLevel(level)), @@ -186,7 +201,12 @@ func getFieldOpt(k string, v interface{}) etw.FieldOpt { return etw.StringField(k, fmt.Sprintf("(Unsupported: %T) %v", v, v)) } -// Close cleans up the hook and closes the ETW provider. +// Close cleans up the hook and closes the ETW provider. If the provder was +// registered by etwlogrus, it will be closed as part of `Close`. If the +// provider was passed in, it will not be closed. func (h *Hook) Close() error { - return h.provider.Close() + if h.closeProvider { + return h.provider.Close() + } + return nil } diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go b/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go new file mode 100644 index 0000000000..2df31b6601 --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go @@ -0,0 +1,159 @@ +package security + +import ( + "os" + "syscall" + "unsafe" + + "github.com/pkg/errors" +) + +type ( + accessMask uint32 + accessMode uint32 + desiredAccess uint32 + inheritMode uint32 + objectType uint32 + shareMode uint32 + securityInformation uint32 + trusteeForm uint32 + trusteeType uint32 + + explicitAccess struct { + accessPermissions accessMask + accessMode accessMode + inheritance inheritMode + trustee trustee + } + + trustee struct { + multipleTrustee *trustee + multipleTrusteeOperation int32 + trusteeForm trusteeForm + trusteeType trusteeType + name uintptr + } +) + +const ( + accessMaskDesiredPermission accessMask = 1 << 31 // GENERIC_READ + + accessModeGrant accessMode = 1 + + desiredAccessReadControl desiredAccess = 0x20000 + desiredAccessWriteDac desiredAccess = 0x40000 + + gvmga = "GrantVmGroupAccess:" + + inheritModeNoInheritance inheritMode = 0x0 + inheritModeSubContainersAndObjectsInherit inheritMode = 0x3 + + objectTypeFileObject objectType = 0x1 + + securityInformationDACL securityInformation = 0x4 + + shareModeRead shareMode = 0x1 + shareModeWrite shareMode = 0x2 + + sidVmGroup = "S-1-5-83-0" + + trusteeFormIsSid trusteeForm = 0 + + trusteeTypeWellKnownGroup trusteeType = 5 +) + +// GrantVMGroupAccess sets the DACL for a specified file or directory to +// include Grant ACE entries for the VM Group SID. This is a golang re- +// implementation of the same function in vmcompute, just not exported in +// RS5. Which kind of sucks. Sucks a lot :/ +func GrantVmGroupAccess(name string) error { + // Stat (to determine if `name` is a directory). + s, err := os.Stat(name) + if err != nil { + return errors.Wrapf(err, "%s os.Stat %s", gvmga, name) + } + + // Get a handle to the file/directory. Must defer Close on success. + fd, err := createFile(name, s.IsDir()) + if err != nil { + return err // Already wrapped + } + defer syscall.CloseHandle(fd) + + // Get the current DACL and Security Descriptor. Must defer LocalFree on success. + ot := objectTypeFileObject + si := securityInformationDACL + sd := uintptr(0) + origDACL := uintptr(0) + if err := getSecurityInfo(fd, uint32(ot), uint32(si), nil, nil, &origDACL, nil, &sd); err != nil { + return errors.Wrapf(err, "%s GetSecurityInfo %s", gvmga, name) + } + defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(sd))) + + // Generate a new DACL which is the current DACL with the required ACEs added. + // Must defer LocalFree on success. + newDACL, err := generateDACLWithAcesAdded(name, s.IsDir(), origDACL) + if err != nil { + return err // Already wrapped + } + defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(newDACL))) + + // And finally use SetSecurityInfo to apply the updated DACL. + if err := setSecurityInfo(fd, uint32(ot), uint32(si), uintptr(0), uintptr(0), newDACL, uintptr(0)); err != nil { + return errors.Wrapf(err, "%s SetSecurityInfo %s", gvmga, name) + } + + return nil +} + +// createFile is a helper function to call [Nt]CreateFile to get a handle to +// the file or directory. +func createFile(name string, isDir bool) (syscall.Handle, error) { + namep := syscall.StringToUTF16(name) + da := uint32(desiredAccessReadControl | desiredAccessWriteDac) + sm := uint32(shareModeRead | shareModeWrite) + fa := uint32(syscall.FILE_ATTRIBUTE_NORMAL) + if isDir { + fa = uint32(fa | syscall.FILE_FLAG_BACKUP_SEMANTICS) + } + fd, err := syscall.CreateFile(&namep[0], da, sm, nil, syscall.OPEN_EXISTING, fa, 0) + if err != nil { + return 0, errors.Wrapf(err, "%s syscall.CreateFile %s", gvmga, name) + } + return fd, nil +} + +// generateDACLWithAcesAdded generates a new DACL with the two needed ACEs added. +// The caller is responsible for LocalFree of the returned DACL on success. +func generateDACLWithAcesAdded(name string, isDir bool, origDACL uintptr) (uintptr, error) { + // Generate pointers to the SIDs based on the string SIDs + sid, err := syscall.StringToSid(sidVmGroup) + if err != nil { + return 0, errors.Wrapf(err, "%s syscall.StringToSid %s %s", gvmga, name, sidVmGroup) + } + + inheritance := inheritModeNoInheritance + if isDir { + inheritance = inheritModeSubContainersAndObjectsInherit + } + + eaArray := []explicitAccess{ + explicitAccess{ + accessPermissions: accessMaskDesiredPermission, + accessMode: accessModeGrant, + inheritance: inheritance, + trustee: trustee{ + trusteeForm: trusteeFormIsSid, + trusteeType: trusteeTypeWellKnownGroup, + name: uintptr(unsafe.Pointer(sid)), + }, + }, + } + + modifiedDACL := uintptr(0) + if err := setEntriesInAcl(uintptr(uint32(1)), uintptr(unsafe.Pointer(&eaArray[0])), origDACL, &modifiedDACL); err != nil { + return 0, errors.Wrapf(err, "%s SetEntriesInAcl %s", gvmga, name) + } + + return modifiedDACL, nil +} diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go new file mode 100644 index 0000000000..c40c2739b7 --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go @@ -0,0 +1,7 @@ +package security + +//go:generate go run mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go + +//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo +//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) [failretval!=0] = advapi32.SetSecurityInfo +//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) [failretval!=0] = advapi32.SetEntriesInAclW diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go new file mode 100644 index 0000000000..0f0c0deff2 --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go @@ -0,0 +1,81 @@ +// Code generated mksyscall_windows.exe DO NOT EDIT + +package security + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") + + procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo") + procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") + procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") +) + +func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0) + if r1 != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0) + if r1 != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0) + if r1 != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +}