func walkProvider(cb func(provider string, message_table string) error) error {
	channels_key, err := registry.OpenKey(registry.LOCAL_MACHINE,
		`SYSTEM\CurrentControlSet\Services\EventLog`,
		registry.READ|registry.ENUMERATE_SUB_KEYS|registry.WOW64_64KEY)
	if err != nil {
		return err
	}
	defer channels_key.Close()
	channels, err := channels_key.ReadSubKeyNames(-1)
	if err != nil {
		return err
	}
	for _, channel := range channels {
		providers_key, err := registry.OpenKey(channels_key, channel,
			registry.READ|registry.ENUMERATE_SUB_KEYS|registry.WOW64_64KEY)
		if err != nil {
			return err
		}
		defer providers_key.Close()
		providers, err := providers_key.ReadSubKeyNames(-1)
		if err != nil {
			return err
		}
		for _, provider_name := range providers {
			one_provider_key, err := registry.OpenKey(providers_key, provider_name,
				registry.READ|registry.ENUMERATE_SUB_KEYS|registry.WOW64_64KEY)
			if err != nil {
				fmt.Printf("Unable to read provider %v\n", provider_name)
				continue
			}
			message_files, _, err := one_provider_key.GetStringValue("EventMessageFile")
			if err != nil {
				continue
			}
			for _, message_file := range evtx.ExpandLocations(message_files) {
				err = cb(provider_name, message_file)
				if err != nil {
					fmt.Printf("While processing %v (%v): %v\n",
						provider_name, message_file, err)
					continue
				}
			}
		}
	}
	return nil
}
Walk over all the providers in the registry and call the callback
with potential message files. The message_table paths are not
guaranteed to exists.
package main
import (
	"database/sql"
	"errors"
	"fmt"
	"os"
	"strings"
	_ "github.com/mattn/go-sqlite3"
	"golang.org/x/sys/windows/registry"
	kingpin "gopkg.in/alecthomas/kingpin.v2"
	"www.velocidex.com/golang/binparsergen/reader"
	"www.velocidex.com/golang/evtx"
	pe "www.velocidex.com/golang/go-pe"
)
var (
	extract      = app.Command("extract", "Extract all log messages from all providers.")
	extract_file = extract.Arg("file", "File to write all messages").Required().
			String()
)