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 }