//go:build windows package win_eventlog import ( "syscall" "unsafe" "golang.org/x/sys/windows" ) var _ unsafe.Pointer // evtHandle uintptr type evtHandle uintptr // Do the interface allocations only once for common errno values. const ( errnoErrorIOPending = 997 ) var ( errErrorIOPending error = syscall.Errno(errnoErrorIOPending) ) // evtFormatMessageFlag defines the values that specify the message string from the event to format. type evtFormatMessageFlag uint32 // EVT_FORMAT_MESSAGE_FLAGS enumeration // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385525(v=vs.85).aspx const ( // evtFormatMessageEvent - Format the event's message string. evtFormatMessageEvent evtFormatMessageFlag = iota + 1 // evtFormatMessageLevel - Format the message string of the level specified in the event. evtFormatMessageLevel // evtFormatMessageTask - Format the message string of the task specified in the event. evtFormatMessageTask // evtFormatMessageOpcode - Format the message string of the task specified in the event. evtFormatMessageOpcode // evtFormatMessageKeyword - Format the message string of the keywords specified in the event. If the // event specifies multiple keywords, the formatted string is a list of null-terminated strings. // Increment through the strings until your pointer points past the end of the used buffer. evtFormatMessageKeyword ) // errnoErr returns common boxed Errno values, to prevent allocations at runtime. func errnoErr(e syscall.Errno) error { switch e { case 0: return nil case errnoErrorIOPending: return errErrorIOPending } return e } var ( modwevtapi = windows.NewLazySystemDLL("wevtapi.dll") procEvtSubscribe = modwevtapi.NewProc("EvtSubscribe") procEvtRender = modwevtapi.NewProc("EvtRender") procEvtClose = modwevtapi.NewProc("EvtClose") procEvtNext = modwevtapi.NewProc("EvtNext") procEvtFormatMessage = modwevtapi.NewProc("EvtFormatMessage") procEvtOpenPublisherMetadata = modwevtapi.NewProc("EvtOpenPublisherMetadata") procEvtCreateBookmark = modwevtapi.NewProc("EvtCreateBookmark") procEvtUpdateBookmark = modwevtapi.NewProc("EvtUpdateBookmark") ) //nolint:revive //argument-limit conditionally more arguments allowed func evtSubscribe( session evtHandle, signalEvent uintptr, channelPath *uint16, query *uint16, bookmark evtHandle, context uintptr, callback syscall.Handle, flags evtSubscribeFlag, ) (evtHandle, error) { r0, _, e1 := syscall.SyscallN( procEvtSubscribe.Addr(), uintptr(session), signalEvent, uintptr(unsafe.Pointer(channelPath)), //nolint:gosec // G103: Valid use of unsafe call to pass channelPath uintptr(unsafe.Pointer(query)), //nolint:gosec // G103: Valid use of unsafe call to pass query uintptr(bookmark), context, uintptr(callback), uintptr(flags), ) var err error handle := evtHandle(r0) if handle == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return handle, err } func evtRender( fragment evtHandle, flags evtRenderFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32, ) error { r1, _, e1 := syscall.SyscallN( procEvtRender.Addr(), uintptr(0), // context uintptr(fragment), uintptr(flags), uintptr(bufferSize), uintptr(unsafe.Pointer(buffer)), //nolint:gosec // G103: Valid use of unsafe call to pass buffer uintptr(unsafe.Pointer(bufferUsed)), //nolint:gosec // G103: Valid use of unsafe call to pass bufferUsed uintptr(unsafe.Pointer(nil)), //nolint:gosec // G103: Valid use of unsafe call to pass propertyCount ) var err error if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } func evtClose(object evtHandle) error { r1, _, e1 := syscall.SyscallN(procEvtClose.Addr(), uintptr(object)) var err error if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } func evtNext(resultSet evtHandle, eventArraySize uint32, eventArray *evtHandle, timeout, flags uint32, numReturned *uint32) error { r1, _, e1 := syscall.SyscallN( procEvtNext.Addr(), uintptr(resultSet), uintptr(eventArraySize), uintptr(unsafe.Pointer(eventArray)), //nolint:gosec // G103: Valid use of unsafe call to pass eventArray uintptr(timeout), uintptr(flags), uintptr(unsafe.Pointer(numReturned)), //nolint:gosec // G103: Valid use of unsafe call to pass numReturned ) var err error if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } //nolint:revive //argument-limit conditionally more arguments allowed func evtFormatMessage( publisherMetadata evtHandle, event evtHandle, messageID uint32, valueCount uint32, values uintptr, flags evtFormatMessageFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32, ) error { r1, _, e1 := syscall.SyscallN( procEvtFormatMessage.Addr(), uintptr(publisherMetadata), uintptr(event), uintptr(messageID), uintptr(valueCount), values, uintptr(flags), uintptr(bufferSize), uintptr(unsafe.Pointer(buffer)), //nolint:gosec // G103: Valid use of unsafe call to pass buffer uintptr(unsafe.Pointer(bufferUsed)), //nolint:gosec // G103: Valid use of unsafe call to pass bufferUsed ) var err error if r1 == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return err } func evtOpenPublisherMetadata(session evtHandle, publisherIdentity, logFilePath *uint16, locale, flags uint32) (evtHandle, error) { r0, _, e1 := syscall.SyscallN( procEvtOpenPublisherMetadata.Addr(), uintptr(session), uintptr(unsafe.Pointer(publisherIdentity)), //nolint:gosec // G103: Valid use of unsafe call to pass publisherIdentity uintptr(unsafe.Pointer(logFilePath)), //nolint:gosec // G103: Valid use of unsafe call to pass logFilePath uintptr(locale), uintptr(flags), ) var err error handle := evtHandle(r0) if handle == 0 { if e1 != 0 { err = errnoErr(e1) } else { err = syscall.EINVAL } } return handle, err } func evtCreateBookmark(bookmarkXML *uint16) (evtHandle, error) { //nolint:gosec // G103: Valid use of unsafe call to pass bookmarkXML r0, _, e1 := syscall.SyscallN(procEvtCreateBookmark.Addr(), uintptr(unsafe.Pointer(bookmarkXML))) handle := evtHandle(r0) if handle != 0 { return handle, nil } if e1 != 0 { return handle, errnoErr(e1) } return handle, syscall.EINVAL } func evtUpdateBookmark(bookmark, event evtHandle) error { r0, _, e1 := syscall.SyscallN(procEvtUpdateBookmark.Addr(), uintptr(bookmark), uintptr(event)) if r0 != 0 { return nil } if e1 != 0 { return errnoErr(e1) } return syscall.EINVAL }