// 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
}