Enumerating Registry Values in Go (Golang)

go, windows

Solution

A member of the Golang sub-reddit pointed out that I was not actually allocating any memory to the buffers passed in to `RegEnumValue`. As such, I've corrected the above example to the following:

var name_length uint32 = 72
var key_type uint32
var lpDataLength uint32 = 72
var zero_uint uint32 = 0
name := make([]uint16, 72)
lpData := make([]byte, 72)

win.RegEnumValue(root, zero_uint, &name[0], &name_length, nil, &key_type, &lpData[0], &lpDataLength)

Obviously, the "magic number" of 72 should probably be replaced with something else. There is another method called `RegQueryInfoKey` that can retrieve information about the registry key to allocate the correct number of bytes for the largest name and value in the key.

Problem

I'm trying to enumerate over a list of values in the Windows registry using Go, but I'm running into some trouble. I've tried two approaches: using both the Go-provided `syscall` library to call into `RegEnumValue`, as well as using a Windows API wrapper by lxn. In both cases, I'm having the same issue. This is the code I'm using (which is currently using the win library from lxn): ``` var root win.HKEY rootpath, _ := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM") fmt.Println(win.RegOpenKeyEx(win.HKEY_LOCAL_MACHINE, rootpath, 0, win.KEY_READ, &root)) var name_length uint32 = 72 var name *uint16 var key_type uint32 var lpData *byte var lpDataLength uint32 = 72 var zero_uint uint32 = 0 fmt.Println(win.RegEnumValue(root, zero_uint, name, &name_length, nil, &key_type, lpData, &lpDataLength)) win.RegCloseKey(root) ``` In this case, `RegEnumValue` always returns code 87, which MSDN's only explanation is "The parameter is incorrect." Does anyone have any ideas that can point me in the right direction for this?

Original source