mirror of
https://git.zx2c4.com/wireguard-go
synced 2024-11-15 01:05:15 +01:00
setupapi: safer aliasing of slice types
This commit is contained in:
parent
2e988467c2
commit
81ca08f1b3
@ -12,7 +12,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
//sys clsidFromString(lpsz *uint16, pclsid *windows.GUID) (hr int32) = ole32.CLSIDFromString
|
//sys clsidFromString(lpsz *uint16, pclsid *windows.GUID) (err error) [failretval!=0] = ole32.CLSIDFromString
|
||||||
|
|
||||||
//
|
//
|
||||||
// FromString parses "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" string to GUID.
|
// FromString parses "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" string to GUID.
|
||||||
@ -22,14 +22,11 @@ func FromString(str string) (*windows.GUID, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
guid := &windows.GUID{}
|
guid := &windows.GUID{}
|
||||||
|
err = clsidFromString(strUTF16, guid)
|
||||||
hr := clsidFromString(strUTF16, guid)
|
if err != nil {
|
||||||
if hr < 0 {
|
return nil, err
|
||||||
return nil, syscall.Errno(hr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return guid, nil
|
return guid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +42,14 @@ var (
|
|||||||
procCLSIDFromString = modole32.NewProc("CLSIDFromString")
|
procCLSIDFromString = modole32.NewProc("CLSIDFromString")
|
||||||
)
|
)
|
||||||
|
|
||||||
func clsidFromString(lpsz *uint16, pclsid *windows.GUID) (hr int32) {
|
func clsidFromString(lpsz *uint16, pclsid *windows.GUID) (err error) {
|
||||||
r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0)
|
r1, _, e1 := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0)
|
||||||
hr = int32(r0)
|
if r1 != 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
} else {
|
||||||
|
err = syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package setupapi
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -261,9 +262,13 @@ func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev
|
|||||||
func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
||||||
switch dataType {
|
switch dataType {
|
||||||
case windows.REG_SZ:
|
case windows.REG_SZ:
|
||||||
return windows.UTF16ToString(BufToUTF16(buf)), nil
|
ret := windows.UTF16ToString(bufToUTF16(buf))
|
||||||
|
runtime.KeepAlive(buf)
|
||||||
|
return ret, nil
|
||||||
case windows.REG_EXPAND_SZ:
|
case windows.REG_EXPAND_SZ:
|
||||||
return registry.ExpandString(windows.UTF16ToString(BufToUTF16(buf)))
|
ret, err := registry.ExpandString(windows.UTF16ToString(bufToUTF16(buf)))
|
||||||
|
runtime.KeepAlive(buf)
|
||||||
|
return ret, err
|
||||||
case windows.REG_BINARY:
|
case windows.REG_BINARY:
|
||||||
return buf, nil
|
return buf, nil
|
||||||
case windows.REG_DWORD_LITTLE_ENDIAN:
|
case windows.REG_DWORD_LITTLE_ENDIAN:
|
||||||
@ -271,7 +276,7 @@ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
|||||||
case windows.REG_DWORD_BIG_ENDIAN:
|
case windows.REG_DWORD_BIG_ENDIAN:
|
||||||
return binary.BigEndian.Uint32(buf), nil
|
return binary.BigEndian.Uint32(buf), nil
|
||||||
case windows.REG_MULTI_SZ:
|
case windows.REG_MULTI_SZ:
|
||||||
bufW := BufToUTF16(buf)
|
bufW := bufToUTF16(buf)
|
||||||
a := []string{}
|
a := []string{}
|
||||||
for i := 0; i < len(bufW); {
|
for i := 0; i < len(bufW); {
|
||||||
j := i + wcslen(bufW[i:])
|
j := i + wcslen(bufW[i:])
|
||||||
@ -280,6 +285,7 @@ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
i = j + 1
|
i = j + 1
|
||||||
}
|
}
|
||||||
|
runtime.KeepAlive(buf)
|
||||||
return a, nil
|
return a, nil
|
||||||
case windows.REG_QWORD_LITTLE_ENDIAN:
|
case windows.REG_QWORD_LITTLE_ENDIAN:
|
||||||
return binary.LittleEndian.Uint64(buf), nil
|
return binary.LittleEndian.Uint64(buf), nil
|
||||||
@ -288,8 +294,8 @@ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BufToUTF16 function reinterprets []byte buffer as []uint16
|
// bufToUTF16 function reinterprets []byte buffer as []uint16
|
||||||
func BufToUTF16(buf []byte) []uint16 {
|
func bufToUTF16(buf []byte) []uint16 {
|
||||||
sl := struct {
|
sl := struct {
|
||||||
addr *uint16
|
addr *uint16
|
||||||
len int
|
len int
|
||||||
@ -298,8 +304,8 @@ func BufToUTF16(buf []byte) []uint16 {
|
|||||||
return *(*[]uint16)(unsafe.Pointer(&sl))
|
return *(*[]uint16)(unsafe.Pointer(&sl))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF16ToBuf function reinterprets []uint16 as []byte
|
// utf16ToBuf function reinterprets []uint16 as []byte
|
||||||
func UTF16ToBuf(buf []uint16) []byte {
|
func utf16ToBuf(buf []uint16) []byte {
|
||||||
sl := struct {
|
sl := struct {
|
||||||
addr *byte
|
addr *byte
|
||||||
len int
|
len int
|
||||||
@ -334,6 +340,16 @@ func (deviceInfoSet DevInfo) SetDeviceRegistryProperty(deviceInfoData *DevInfoDa
|
|||||||
return SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, propertyBuffers)
|
return SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, propertyBuffers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (deviceInfoSet DevInfo) SetDeviceRegistryPropertyString(deviceInfoData *DevInfoData, property SPDRP, str string) error {
|
||||||
|
str16, err := windows.UTF16FromString(str)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, utf16ToBuf(append(str16, 0)))
|
||||||
|
runtime.KeepAlive(str16)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
//sys setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW
|
//sys setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW
|
||||||
|
|
||||||
// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element.
|
// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element.
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package setupapi
|
package setupapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@ -471,7 +472,7 @@ func TestSetupDiGetSelectedDevice(t *testing.T) {
|
|||||||
|
|
||||||
func TestUTF16ToBuf(t *testing.T) {
|
func TestUTF16ToBuf(t *testing.T) {
|
||||||
buf := []uint16{0x0123, 0x4567, 0x89ab, 0xcdef}
|
buf := []uint16{0x0123, 0x4567, 0x89ab, 0xcdef}
|
||||||
buf2 := UTF16ToBuf(buf)
|
buf2 := utf16ToBuf(buf)
|
||||||
if len(buf)*2 != len(buf2) ||
|
if len(buf)*2 != len(buf2) ||
|
||||||
cap(buf)*2 != cap(buf2) ||
|
cap(buf)*2 != cap(buf2) ||
|
||||||
buf2[0] != 0x23 || buf2[1] != 0x01 ||
|
buf2[0] != 0x23 || buf2[1] != 0x01 ||
|
||||||
@ -480,4 +481,5 @@ func TestUTF16ToBuf(t *testing.T) {
|
|||||||
buf2[6] != 0xef || buf2[7] != 0xcd {
|
buf2[6] != 0xef || buf2[7] != 0xcd {
|
||||||
t.Errorf("SetupDiSetSelectedDevice(nil) should fail with ERROR_INVALID_USER_BUFFER")
|
t.Errorf("SetupDiSetSelectedDevice(nil) should fail with ERROR_INVALID_USER_BUFFER")
|
||||||
}
|
}
|
||||||
|
runtime.KeepAlive(buf)
|
||||||
}
|
}
|
||||||
|
@ -218,11 +218,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set Plug&Play device hardware ID property.
|
// Set Plug&Play device hardware ID property.
|
||||||
hwid, err := syscall.UTF16FromString(hardwareID)
|
err = devInfoList.SetDeviceRegistryPropertyString(deviceData, setupapi.SPDRP_HARDWAREID, hardwareID)
|
||||||
if err != nil {
|
|
||||||
return nil, false, err // syscall.UTF16FromString(hardwareID) should never fail: hardwareID is const string without NUL chars.
|
|
||||||
}
|
|
||||||
err = devInfoList.SetDeviceRegistryProperty(deviceData, setupapi.SPDRP_HARDWAREID, setupapi.UTF16ToBuf(append(hwid, 0)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, errors.New("SetupDiSetDeviceRegistryProperty(SPDRP_HARDWAREID) failed: " + err.Error())
|
return nil, false, errors.New("SetupDiSetDeviceRegistryProperty(SPDRP_HARDWAREID) failed: " + err.Error())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user