diff --git a/setupapi/setupapi_windows.go b/setupapi/setupapi_windows.go index 84d324d..740b81b 100644 --- a/setupapi/setupapi_windows.go +++ b/setupapi/setupapi_windows.go @@ -264,9 +264,9 @@ func SetupDiGetDeviceRegistryProperty(DeviceInfoSet DevInfo, DeviceInfoData *SP_ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) { switch dataType { case windows.REG_SZ: - return windows.UTF16ToString(toUTF16(buf)), nil + return windows.UTF16ToString(BufToUTF16(buf)), nil case windows.REG_EXPAND_SZ: - return registry.ExpandString(windows.UTF16ToString(toUTF16(buf))) + return registry.ExpandString(windows.UTF16ToString(BufToUTF16(buf))) case windows.REG_BINARY: return buf, nil case windows.REG_DWORD_LITTLE_ENDIAN: @@ -274,7 +274,7 @@ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) { case windows.REG_DWORD_BIG_ENDIAN: return binary.BigEndian.Uint32(buf), nil case windows.REG_MULTI_SZ: - bufW := toUTF16(buf) + bufW := BufToUTF16(buf) a := []string{} for i := 0; i < len(bufW); { j := i + wcslen(bufW[i:]) @@ -291,7 +291,8 @@ func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) { } } -func toUTF16(buf []byte) []uint16 { +// BufToUTF16 function reinterprets []byte buffer as []uint16 +func BufToUTF16(buf []byte) []uint16 { sl := struct { addr *uint16 len int @@ -300,6 +301,16 @@ func toUTF16(buf []byte) []uint16 { return *(*[]uint16)(unsafe.Pointer(&sl)) } +// UTF16ToBuf function reinterprets []uint16 as []byte +func UTF16ToBuf(buf []uint16) []byte { + sl := struct { + addr *byte + len int + cap int + }{(*byte)(unsafe.Pointer(&buf[0])), len(buf) * 2, cap(buf) * 2} + return *(*[]byte)(unsafe.Pointer(&sl)) +} + func wcslen(str []uint16) int { for i := 0; i < len(str); i++ { if str[i] == 0 { diff --git a/setupapi/setupapi_windows_test.go b/setupapi/setupapi_windows_test.go index 12b5fe1..3d9abd6 100644 --- a/setupapi/setupapi_windows_test.go +++ b/setupapi/setupapi_windows_test.go @@ -403,3 +403,16 @@ func TestSetupDiGetSelectedDevice(t *testing.T) { } } } + +func TestUTF16ToBuf(t *testing.T) { + buf := []uint16{0x0123, 0x4567, 0x89ab, 0xcdef} + buf2 := UTF16ToBuf(buf) + if len(buf)*2 != len(buf2) || + cap(buf)*2 != cap(buf2) || + buf2[0] != 0x23 || buf2[1] != 0x01 || + buf2[2] != 0x67 || buf2[3] != 0x45 || + buf2[4] != 0xab || buf2[5] != 0x89 || + buf2[6] != 0xef || buf2[7] != 0xcd { + t.Errorf("SetupDiSetSelectedDevice(nil) should fail with ERROR_INVALID_USER_BUFFER") + } +}