github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/windows/win_eventlog/zsyscall_windows.go (about)

     1  // The MIT License (MIT)
     2  
     3  // Copyright (c) 2015-2020 InfluxData Inc.
     4  
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  
    12  // The above copyright notice and this permission notice shall be included in all
    13  // copies or substantial portions of the Software.
    14  
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    21  // SOFTWARE.
    22  //go:build windows
    23  // +build windows
    24  
    25  //revive:disable-next-line:var-naming
    26  // Package win_eventlog Input plugin to collect Windows Event Log messages
    27  package win_eventlog
    28  
    29  import (
    30  	"syscall"
    31  	"unsafe"
    32  
    33  	"golang.org/x/sys/windows"
    34  )
    35  
    36  var _ unsafe.Pointer
    37  
    38  // EvtHandle uintptr
    39  type EvtHandle uintptr
    40  
    41  // Do the interface allocations only once for common
    42  // Errno values.
    43  const (
    44  	//revive:disable-next-line:var-naming
    45  	errnoERROR_IO_PENDING = 997
    46  )
    47  
    48  var (
    49  	//revive:disable-next-line:var-naming
    50  	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
    51  )
    52  
    53  // EvtFormatMessageFlag defines the values that specify the message string from
    54  // the event to format.
    55  type EvtFormatMessageFlag uint32
    56  
    57  // EVT_FORMAT_MESSAGE_FLAGS enumeration
    58  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385525(v=vs.85).aspx
    59  const (
    60  	//revive:disable:var-naming
    61  	// Format the event's message string.
    62  	EvtFormatMessageEvent EvtFormatMessageFlag = iota + 1
    63  	// Format the message string of the level specified in the event.
    64  	EvtFormatMessageLevel
    65  	// Format the message string of the task specified in the event.
    66  	EvtFormatMessageTask
    67  	// Format the message string of the task specified in the event.
    68  	EvtFormatMessageOpcode
    69  	// Format the message string of the keywords specified in the event. If the
    70  	// event specifies multiple keywords, the formatted string is a list of
    71  	// null-terminated strings. Increment through the strings until your pointer
    72  	// points past the end of the used buffer.
    73  	EvtFormatMessageKeyword
    74  	//revive:enable:var-naming
    75  )
    76  
    77  // errnoErr returns common boxed Errno values, to prevent
    78  // allocations at runtime.
    79  func errnoErr(e syscall.Errno) error {
    80  	switch e {
    81  	case 0:
    82  		return nil
    83  	case errnoERROR_IO_PENDING:
    84  		return errERROR_IO_PENDING
    85  	}
    86  
    87  	return e
    88  }
    89  
    90  var (
    91  	modwevtapi = windows.NewLazySystemDLL("wevtapi.dll")
    92  
    93  	procEvtSubscribe             = modwevtapi.NewProc("EvtSubscribe")
    94  	procEvtRender                = modwevtapi.NewProc("EvtRender")
    95  	procEvtClose                 = modwevtapi.NewProc("EvtClose")
    96  	procEvtNext                  = modwevtapi.NewProc("EvtNext")
    97  	procEvtFormatMessage         = modwevtapi.NewProc("EvtFormatMessage")
    98  	procEvtOpenPublisherMetadata = modwevtapi.NewProc("EvtOpenPublisherMetadata")
    99  	procEvtCreateBookmark        = modwevtapi.NewProc("EvtCreateBookmark")
   100  	procEvtUpdateBookmark        = modwevtapi.NewProc("EvtUpdateBookmark")
   101  )
   102  
   103  func _EvtSubscribe(session EvtHandle, signalEvent uintptr, channelPath *uint16, query *uint16, bookmark EvtHandle, context uintptr, callback syscall.Handle, flags EvtSubscribeFlag) (handle EvtHandle, err error) {
   104  	r0, _, e1 := syscall.Syscall9(procEvtSubscribe.Addr(), 8, uintptr(session), uintptr(signalEvent), uintptr(unsafe.Pointer(channelPath)), uintptr(unsafe.Pointer(query)), uintptr(bookmark), uintptr(context), uintptr(callback), uintptr(flags), 0)
   105  	handle = EvtHandle(r0)
   106  	if handle == 0 {
   107  		if e1 != 0 {
   108  			err = errnoErr(e1)
   109  		} else {
   110  			err = syscall.EINVAL
   111  		}
   112  	}
   113  	return
   114  }
   115  
   116  func _EvtRender(context EvtHandle, fragment EvtHandle, flags EvtRenderFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32, propertyCount *uint32) (err error) {
   117  	r1, _, e1 := syscall.Syscall9(procEvtRender.Addr(), 7, uintptr(context), uintptr(fragment), uintptr(flags), uintptr(bufferSize), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(bufferUsed)), uintptr(unsafe.Pointer(propertyCount)), 0, 0)
   118  	if r1 == 0 {
   119  		if e1 != 0 {
   120  			err = errnoErr(e1)
   121  		} else {
   122  			err = syscall.EINVAL
   123  		}
   124  	}
   125  	return
   126  }
   127  
   128  func _EvtClose(object EvtHandle) (err error) {
   129  	r1, _, e1 := syscall.Syscall(procEvtClose.Addr(), 1, uintptr(object), 0, 0)
   130  	if r1 == 0 {
   131  		if e1 != 0 {
   132  			err = errnoErr(e1)
   133  		} else {
   134  			err = syscall.EINVAL
   135  		}
   136  	}
   137  	return
   138  }
   139  
   140  func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle, timeout uint32, flags uint32, numReturned *uint32) (err error) {
   141  	r1, _, e1 := syscall.Syscall6(procEvtNext.Addr(), 6, uintptr(resultSet), uintptr(eventArraySize), uintptr(unsafe.Pointer(eventArray)), uintptr(timeout), uintptr(flags), uintptr(unsafe.Pointer(numReturned)))
   142  	if r1 == 0 {
   143  		if e1 != 0 {
   144  			err = errnoErr(e1)
   145  		} else {
   146  			err = syscall.EINVAL
   147  		}
   148  	}
   149  	return
   150  }
   151  
   152  func _EvtFormatMessage(publisherMetadata EvtHandle, event EvtHandle, messageID uint32, valueCount uint32, values uintptr, flags EvtFormatMessageFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32) (err error) {
   153  	r1, _, e1 := syscall.Syscall9(procEvtFormatMessage.Addr(), 9, uintptr(publisherMetadata), uintptr(event), uintptr(messageID), uintptr(valueCount), uintptr(values), uintptr(flags), uintptr(bufferSize), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(bufferUsed)))
   154  	if r1 == 0 {
   155  		if e1 != 0 {
   156  			err = errnoErr(e1)
   157  		} else {
   158  			err = syscall.EINVAL
   159  		}
   160  	}
   161  	return
   162  }
   163  
   164  func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity *uint16, logFilePath *uint16, locale uint32, flags uint32) (handle EvtHandle, err error) {
   165  	r0, _, e1 := syscall.Syscall6(procEvtOpenPublisherMetadata.Addr(), 5, uintptr(session), uintptr(unsafe.Pointer(publisherIdentity)), uintptr(unsafe.Pointer(logFilePath)), uintptr(locale), uintptr(flags), 0)
   166  	handle = EvtHandle(r0)
   167  	if handle == 0 {
   168  		if e1 != 0 {
   169  			err = errnoErr(e1)
   170  		} else {
   171  			err = syscall.EINVAL
   172  		}
   173  	}
   174  	return
   175  }
   176  
   177  // CreateBookmark create a new bookmark from a string, if the string is empty a new bookrmak is created.
   178  // Use update the bookmark with an event to save the position, or render to get the bookmark data to store.
   179  func CreateBookmark(bookmark string) (EvtHandle, error) {
   180  	bookmarkPtr, err := stringPointer(bookmark)
   181  	if err != nil {
   182  		return 0, err
   183  	}
   184  	r0, _, e1 := syscall.Syscall(procEvtCreateBookmark.Addr(), 1, bookmarkPtr, 0, 0)
   185  	handle := EvtHandle(r0)
   186  	if handle == 0 {
   187  		if e1 != 0 {
   188  			return 0, errnoErr(e1)
   189  		}
   190  		return 0, syscall.EINVAL
   191  	}
   192  	return handle, nil
   193  }
   194  
   195  func UpdateBookmark(bookmark, event EvtHandle, buf []byte) (string, error) {
   196  	r1, _, e1 := syscall.Syscall(procEvtUpdateBookmark.Addr(), 2, uintptr(bookmark), uintptr(event), 0)
   197  	if r1 == 0 {
   198  		if e1 != 0 {
   199  			return "", errnoErr(e1)
   200  		} else {
   201  			return "", syscall.EINVAL
   202  		}
   203  	}
   204  	var bufferUsed, propertyCount uint32
   205  	err := _EvtRender(0, bookmark, EvtRenderBookmark, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount)
   206  	if err != nil {
   207  		return "", err
   208  	}
   209  
   210  	bookMarkData, err := DecodeUTF16(buf[:bufferUsed])
   211  	if err != nil {
   212  		return "", err
   213  	}
   214  	return string(bookMarkData), nil
   215  }
   216  
   217  func stringPointer(s string) (uintptr, error) {
   218  	if s == "" {
   219  		return 0, nil
   220  	}
   221  	// last character is always nil and causes issue for decoding.
   222  	ptr, err := syscall.UTF16PtrFromString(s[:len(s)-1])
   223  	if err != nil {
   224  		return 0, err
   225  	}
   226  	return uintptr(unsafe.Pointer(ptr)), nil
   227  
   228  }