// readString reads a pointer using the reader then parses the UTF-16 string // that the pointer addresses within the buffer. func readString(buffer []byte, reader io.Reader) (string, error) { offset, err := offset(buffer, reader) if err != nil { // Ignore NULL values. if err == ErrorEvtVarTypeNull { return "", nil } return "", err } str, _, err := eventlogging.UTF16BytesToString(buffer[offset:]) return str, err }
// FormatEventString formats part of the event as a string. // messageFlag determines what part of the event is formatted as as string. // eventHandle is the handle to the event. // publisher is the name of the event's publisher. // publisherHandle is a handle to the publisher's metadata as provided by // EvtOpenPublisherMetadata. // lang is the language ID. // buffer is optional and if not provided it will be allocated. If the provided // buffer is not large enough then an InsufficientBufferError will be returned. func FormatEventString( messageFlag EvtFormatMessageFlag, eventHandle EvtHandle, publisher string, publisherHandle EvtHandle, lang uint32, buffer []byte, ) ([]string, error) { p, err := syscall.UTF16PtrFromString(publisher) if err != nil { return nil, err } // Open a publisher handle if one was not provided. ph := publisherHandle if ph == 0 { ph, err = _EvtOpenPublisherMetadata(0, p, nil, lang, 0) if err != nil { return nil, err } defer _EvtClose(ph) } // Create a buffer if one was not provider. var bufferUsed uint32 if buffer == nil { err = _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, 0, nil, &bufferUsed) bufferUsed *= 2 // It returns the number of utf-16 chars. if err != nil && err != ERROR_INSUFFICIENT_BUFFER { return nil, err } buffer = make([]byte, bufferUsed) bufferUsed = 0 } err = _EvtFormatMessage(ph, eventHandle, 0, 0, 0, messageFlag, uint32(len(buffer)/2), &buffer[0], &bufferUsed) bufferUsed *= 2 // It returns the number of utf-16 chars. if err == ERROR_INSUFFICIENT_BUFFER { return nil, eventlogging.InsufficientBufferError{err, int(bufferUsed)} } if err != nil { return nil, err } var value string var offset int var size int var values []string for { value, size, err = eventlogging.UTF16BytesToString(buffer[offset:bufferUsed]) if err != nil { return nil, err } offset += size values = append(values, eventlogging.RemoveWindowsLineEndings(value)) if offset >= int(bufferUsed) { break } } return values, nil }