-1

The documentation in the registry package for GetValue() says :

GetValue retrieves the type and data for the specified value associated with an open key k. It fills up buffer buf and returns the retrieved byte count n. If buf is too small to fit the stored value it returns ErrShortBuffer error along with the required buffer size n. If no buffer is provided, it returns true and actual buffer size n. If no buffer is provided, GetValue returns the value's type only. If the value does not exist, the error returned is ErrNotExist.

GetValue is a low level function. If value's type is known, use the appropriate Get*Value function instead."

In my case, I don't know the value type of the registry key. However, I only need to print the value as a string. GetValue() takes in the value name and a "buffer" but the buffer is of type []byte. It is not passed by reference so I can't just create var buf []byte, pass that in and read it. I can't pass it in with &buf (type *[]byte). I can't use byte.Buffer (also type mismatch). I feel like there is something really simple I'm missing.

Code:

var buf []byte //????
_, _, e := myKey.GetValue(valuename, buf)
if e != nil {
    panic(e)
}
fmt.Printf("Value: %s\n", string(buf)) // Prints blank
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
WarBro
  • 305
  • 2
  • 10
  • "It is not passed by reference so I can't just create var buf []byte, pass that in and read it" - yes, that's exactly what you need to do, but you need to use `make` to initialize it with a size (which is what most of the quoted doc is talking about). – Adrian Nov 07 '19 at 21:00

1 Answers1

0

I suppose the registry API you mention is the Windows registry. To use these kinds of APIs, you have to take your best guess on the size of output you expect from the call:

buf:=make([]byte,1024)
typ, n, e := myKey.GetValue(valuename, buf)
if e==ErrShortBuffer {
   // Go back, try with a larger buffer size
   buf=make([]byte,n)
   typ, n, e = myKey.GetValue(valuename, buf)
}
Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
  • This still prints blank: `typ: 4` `n: 4` `err==nil: true` `buf: ` – WarBro Nov 07 '19 at 20:25
  • It's not passed by reference so wouldn't any modifications to buf be confined to the scope of GetValue()? – WarBro Nov 07 '19 at 20:26
  • 3
    A slice contains a reference to the array, so GetValue can put values into the slice you passed in. Maybe the data you got back is not printable as string? What is type 4? – Burak Serdar Nov 07 '19 at 20:28
  • For the particular case I am trying it happens to be REG_DWORD, I believe, i.e. an integer. If I use `val, _, e := myKey.GetIntegerValue(valuename)` it actually prints correctly: `err==nil: true` `val: 0` – WarBro Nov 07 '19 at 20:32
  • I could call GetValue first, and then do a switch..case on type and then call the appropriate getter, but that seems like double work and there's something simple I'm missing. – WarBro Nov 07 '19 at 20:34
  • 1
    @WarBro Use fmt.Printf("Value: %x\n", but[:n]) to view the data. There may be unprintable bytes. – Charlie Tumahai Nov 07 '19 at 20:36
  • 1
    If what you got back is a DWORD, then you need to decode it. Use encoding/binary package, BigEndian or LittleEndian, depending on the encoding of the value, and decode it as an int32. – Burak Serdar Nov 07 '19 at 20:36
  • AH! Of course! I knew it was something simple. `%x: 00000000` which will print blank! I think I will still have to do a switch..case on type to decode it properly, yes? – WarBro Nov 07 '19 at 20:40
  • 3
    Yes, you need to decode and interpret those bytes based on type. – Burak Serdar Nov 07 '19 at 20:43