Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

advapi32.RegSetString Not Setting Entire String #60

Open
nogilnick opened this issue Dec 9, 2016 · 1 comment
Open

advapi32.RegSetString Not Setting Entire String #60

nogilnick opened this issue Dec 9, 2016 · 1 comment

Comments

@nogilnick
Copy link

nogilnick commented Dec 9, 2016

Hi,

First of all, thanks for the library.

It seems that there are a few bugs in the advapi32.RegSetString function. The result is that RegSetString will not write the correct amount of characters to the registry entry. See the below comments:

func RegSetString(hKey HKEY, subKey string, value string) (errno int) {
    var lptr, vptr unsafe.Pointer
    if len(subKey) > 0 {
        lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))
    }
    var buf []uint16
    //Is this size check needed? UTF16FromString always adds a null
    if len(value) > 0 {
        //New buf variable defined for if-statement scope
        buf, err := syscall.UTF16FromString(value)
        if err != nil {
            return ERROR_BAD_FORMAT
        }
        vptr = unsafe.Pointer(&buf[0])
    }
    //If you fmt.Println(buf) right here it is empty
    ret, _, _ := procRegSetValueEx.Call(
        uintptr(hKey),
        uintptr(lptr),
        uintptr(0),
        uintptr(REG_SZ),
        uintptr(vptr),
        //unsafe.Sizeof(buf) returns the size of the slice descriptor not the memory referenced
        //the slice descriptor is always of size 12 so this is always 14
        uintptr(unsafe.Sizeof(buf) + 2)) // 2 is the size of the terminating null character
    return int(ret)
}

I suggest changing to something more like this:

func RegSetString(hKey HKEY, subKey string, value string) (errno int) {
    var lptr, vptr unsafe.Pointer
    if len(subKey) > 0 {
        lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))
    }
    buf, err := syscall.UTF16FromString(value)
    if err != nil {
        return ERROR_BAD_FORMAT
    }
    //Buf will at least containing 1 element (the null)
    vptr = unsafe.Pointer(&buf[0])
    ret, _, _ := procRegSetValueEx.Call(
        uintptr(hKey),
        uintptr(lptr),
        uintptr(0),
        uintptr(REG_SZ),
        uintptr(vptr),
        uintptr(int(unsafe.Sizeof(buf[0])) * len(buf))
    return int(ret)
}

Hope this helps,

N

@gonutz
Copy link

gonutz commented Sep 27, 2017

I found this bug as well, I fixed it in my pull request in this commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants