Add support for setupapi.SetupDi(Get|Set)SelectedDevice()

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-02-04 15:50:59 +01:00 committed by Jason A. Donenfeld
parent c15cbefc12
commit 35f72239ac
3 changed files with 78 additions and 0 deletions

View File

@ -227,3 +227,16 @@ func SetupDiClassGuidsFromNameEx(ClassName string, MachineName string) (ClassGui
return
}
//sys setupDiGetSelectedDevice(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiGetSelectedDevice
// SetupDiGetSelectedDevice function retrieves the selected device information element in a device information set.
func SetupDiGetSelectedDevice(DeviceInfoSet DevInfo) (DeviceInfoData *SP_DEVINFO_DATA, err error) {
data := SP_DEVINFO_DATA{}
data.Size = uint32(unsafe.Sizeof(data))
return &data, setupDiGetSelectedDevice(DeviceInfoSet, &data)
}
// SetupDiSetSelectedDevice function sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard.
//sys SetupDiSetSelectedDevice(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiSetSelectedDevice

View File

@ -251,3 +251,42 @@ func TestSetupDiClassGuidsFromNameEx(t *testing.T) {
t.Errorf("SetupDiClassGuidsFromNameEx(\"foobar-34274a51-a6e6-45f0-80d6-c62be96dd5fe\") should return an empty GUID set")
}
}
func TestSetupDiGetSelectedDevice(t *testing.T) {
devInfoList, err := SetupDiGetClassDevsEx(&deviceClassNetGUID, "", 0, DIGCF_PRESENT, DevInfo(0), "")
if err != nil {
t.Errorf("Error calling SetupDiGetClassDevsEx: %s", err.Error())
}
defer devInfoList.Close()
for i := 0; true; i++ {
data, err := SetupDiEnumDeviceInfo(devInfoList, i)
if err != nil {
if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
break
}
continue
}
err = SetupDiSetSelectedDevice(devInfoList, data)
if err != nil {
t.Errorf("Error calling SetupDiSetSelectedDevice: %s", err.Error())
}
data2, err := SetupDiGetSelectedDevice(devInfoList)
if err != nil {
t.Errorf("Error calling SetupDiGetSelectedDevice: %s", err.Error())
} else if *data != *data2 {
t.Error("SetupDiGetSelectedDevice returned different data than was set by SetupDiSetSelectedDevice")
}
}
err = SetupDiSetSelectedDevice(devInfoList, nil)
if err == nil {
t.Errorf("SetupDiSetSelectedDevice(nil) should fail")
} else {
if errWin, ok := err.(syscall.Errno); !ok || errWin != 87 /*ERROR_INVALID_PARAMETER*/ {
t.Errorf("SetupDiSetSelectedDevice(nil) should fail with ERROR_INVALID_USER_BUFFER")
}
}
}

View File

@ -53,6 +53,8 @@ var (
procSetupDiSetClassInstallParamsW = modsetupapi.NewProc("SetupDiSetClassInstallParamsW")
procSetupDiClassNameFromGuidExW = modsetupapi.NewProc("SetupDiClassNameFromGuidExW")
procSetupDiClassGuidsFromNameExW = modsetupapi.NewProc("SetupDiClassGuidsFromNameExW")
procSetupDiGetSelectedDevice = modsetupapi.NewProc("SetupDiGetSelectedDevice")
procSetupDiSetSelectedDevice = modsetupapi.NewProc("SetupDiSetSelectedDevice")
)
func setupDiCreateDeviceInfoListEx(ClassGUID *windows.GUID, hwndParent uintptr, MachineName *uint16, Reserved uintptr) (handle DevInfo, err error) {
@ -225,3 +227,27 @@ func setupDiClassGuidsFromNameEx(ClassName *uint16, ClassGuidList *windows.GUID,
}
return
}
func setupDiGetSelectedDevice(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA) (err error) {
r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDevice.Addr(), 2, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func SetupDiSetSelectedDevice(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA) (err error) {
r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDevice.Addr(), 2, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}