2019-01-31 15:20:11 +01:00
/ * SPDX - License - Identifier : MIT
*
* Copyright ( C ) 2019 WireGuard LLC . All Rights Reserved .
* /
package setupapi
import (
2019-02-05 11:44:47 +01:00
"encoding/binary"
"fmt"
2019-02-01 10:58:06 +01:00
"syscall"
2019-02-01 11:39:57 +01:00
"unsafe"
2019-02-01 10:58:06 +01:00
2019-01-31 15:20:11 +01:00
"golang.org/x/sys/windows"
2019-02-01 13:00:44 +01:00
"golang.org/x/sys/windows/registry"
2019-01-31 15:20:11 +01:00
)
2019-02-04 11:49:26 +01:00
//sys setupDiCreateDeviceInfoListEx(ClassGUID *windows.GUID, hwndParent uintptr, MachineName *uint16, Reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiCreateDeviceInfoListExW
2019-02-04 08:23:55 +01:00
2019-02-04 15:21:19 +01:00
// SetupDiCreateDeviceInfoListEx function creates an empty device information set on a remote or a local computer and optionally associates the set with a device setup class.
2019-02-05 08:45:44 +01:00
func SetupDiCreateDeviceInfoListEx ( ClassGUID * windows . GUID , hwndParent uintptr , MachineName string ) ( DeviceInfoSet DevInfo , err error ) {
2019-02-04 09:51:19 +01:00
var machineNameUTF16 * uint16
2019-02-04 08:39:31 +01:00
if MachineName != "" {
2019-02-04 09:51:19 +01:00
machineNameUTF16 , err = syscall . UTF16PtrFromString ( MachineName )
2019-02-04 08:39:31 +01:00
if err != nil {
return
}
}
2019-02-04 15:21:19 +01:00
return setupDiCreateDeviceInfoListEx ( ClassGUID , hwndParent , machineNameUTF16 , 0 )
}
2019-02-04 08:39:31 +01:00
2019-02-04 15:21:19 +01:00
//sys setupDiGetDeviceInfoListDetail(DeviceInfoSet DevInfo, DeviceInfoSetDetailData *_SP_DEVINFO_LIST_DETAIL_DATA) (err error) = setupapi.SetupDiGetDeviceInfoListDetailW
2019-02-04 08:23:55 +01:00
2019-02-04 15:21:19 +01:00
// SetupDiGetDeviceInfoListDetail function retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name.
func SetupDiGetDeviceInfoListDetail ( DeviceInfoSet DevInfo ) ( DeviceInfoSetDetailData * DevInfoListDetailData , err error ) {
var _data _SP_DEVINFO_LIST_DETAIL_DATA
_data . Size = uint32 ( unsafe . Sizeof ( _data ) )
2019-02-04 08:23:55 +01:00
2019-02-04 15:21:19 +01:00
err = setupDiGetDeviceInfoListDetail ( DeviceInfoSet , & _data )
2019-02-04 09:36:42 +01:00
if err != nil {
return
}
2019-02-05 14:03:28 +01:00
return _data . toGo ( ) , nil
2019-02-04 09:36:42 +01:00
}
2019-02-05 08:45:44 +01:00
// GetDeviceInfoListDetail method retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name.
func ( DeviceInfoSet DevInfo ) GetDeviceInfoListDetail ( ) ( DeviceInfoSetDetailData * DevInfoListDetailData , err error ) {
return SetupDiGetDeviceInfoListDetail ( DeviceInfoSet )
}
2019-02-04 15:21:19 +01:00
//sys setupDiCreateDeviceInfo(DeviceInfoSet DevInfo, DeviceName *uint16, ClassGUID *windows.GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiCreateDeviceInfoW
2019-02-04 11:52:42 +01:00
// SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the specified device information set.
func SetupDiCreateDeviceInfo ( DeviceInfoSet DevInfo , DeviceName string , ClassGUID * windows . GUID , DeviceDescription string , hwndParent uintptr , CreationFlags DICD ) ( DeviceInfoData * SP_DEVINFO_DATA , err error ) {
deviceNameUTF16 , err := syscall . UTF16PtrFromString ( DeviceName )
if err != nil {
return
}
var deviceDescriptionUTF16 * uint16
if DeviceDescription != "" {
deviceDescriptionUTF16 , err = syscall . UTF16PtrFromString ( DeviceDescription )
if err != nil {
return
}
}
data := SP_DEVINFO_DATA { }
data . Size = uint32 ( unsafe . Sizeof ( data ) )
return & data , setupDiCreateDeviceInfo ( DeviceInfoSet , deviceNameUTF16 , ClassGUID , deviceDescriptionUTF16 , hwndParent , CreationFlags , & data )
}
2019-02-05 08:45:44 +01:00
// CreateDeviceInfo method creates a new device information element and adds it as a new member to the specified device information set.
func ( DeviceInfoSet DevInfo ) CreateDeviceInfo ( DeviceName string , ClassGUID * windows . GUID , DeviceDescription string , hwndParent uintptr , CreationFlags DICD ) ( DeviceInfoData * SP_DEVINFO_DATA , err error ) {
return SetupDiCreateDeviceInfo ( DeviceInfoSet , DeviceName , ClassGUID , DeviceDescription , hwndParent , CreationFlags )
}
2019-02-04 15:21:19 +01:00
//sys setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiEnumDeviceInfo
// SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set.
func SetupDiEnumDeviceInfo ( DeviceInfoSet DevInfo , MemberIndex int ) ( DeviceInfoData * SP_DEVINFO_DATA , err error ) {
data := SP_DEVINFO_DATA { }
data . Size = uint32 ( unsafe . Sizeof ( data ) )
return & data , setupDiEnumDeviceInfo ( DeviceInfoSet , uint32 ( MemberIndex ) , & data )
2019-02-04 11:49:26 +01:00
}
2019-02-05 08:45:44 +01:00
// EnumDeviceInfo method returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set.
func ( DeviceInfoSet DevInfo ) EnumDeviceInfo ( MemberIndex int ) ( DeviceInfoData * SP_DEVINFO_DATA , err error ) {
return SetupDiEnumDeviceInfo ( DeviceInfoSet , MemberIndex )
}
2019-02-04 15:21:19 +01:00
// SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory.
//sys SetupDiDestroyDeviceInfoList(DeviceInfoSet DevInfo) (err error) = setupapi.SetupDiDestroyDeviceInfoList
2019-02-05 08:45:44 +01:00
// Close method deletes a device information set and frees all associated memory.
func ( DeviceInfoSet DevInfo ) Close ( ) error {
return SetupDiDestroyDeviceInfoList ( DeviceInfoSet )
}
2019-02-05 16:29:17 +01:00
//sys SetupDiBuildDriverInfoList(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT) (err error) = setupapi.SetupDiBuildDriverInfoList
// BuildDriverInfoList method builds a list of drivers that is associated with a specific device or with the global class driver list for a device information set.
func ( DeviceInfoSet DevInfo ) BuildDriverInfoList ( DeviceInfoData * SP_DEVINFO_DATA , DriverType SPDIT ) ( err error ) {
return SetupDiBuildDriverInfoList ( DeviceInfoSet , DeviceInfoData , DriverType )
}
//sys SetupDiCancelDriverInfoSearch(DeviceInfoSet DevInfo) (err error) = setupapi.SetupDiCancelDriverInfoSearch
// CancelDriverInfoSearch method cancels a driver list search that is currently in progress in a different thread.
func ( DeviceInfoSet DevInfo ) CancelDriverInfoSearch ( ) ( err error ) {
return SetupDiCancelDriverInfoSearch ( DeviceInfoSet )
}
//sys setupDiEnumDriverInfo(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT, MemberIndex uint32, DriverInfoData *SP_DRVINFO_DATA) (err error) = setupapi.SetupDiEnumDriverInfoW
// SetupDiEnumDriverInfo function enumerates the members of a driver list.
func SetupDiEnumDriverInfo ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , DriverType SPDIT , MemberIndex int ) ( DriverInfoData * SP_DRVINFO_DATA , err error ) {
data := & SP_DRVINFO_DATA { }
data . Size = uint32 ( unsafe . Sizeof ( * data ) )
return data , setupDiEnumDriverInfo ( DeviceInfoSet , DeviceInfoData , DriverType , uint32 ( MemberIndex ) , data )
}
// EnumDriverInfo method enumerates the members of a driver list.
func ( DeviceInfoSet DevInfo ) EnumDriverInfo ( DeviceInfoData * SP_DEVINFO_DATA , DriverType SPDIT , MemberIndex int ) ( DriverInfoData * SP_DRVINFO_DATA , err error ) {
return SetupDiEnumDriverInfo ( DeviceInfoSet , DeviceInfoData , DriverType , MemberIndex )
}
//sys setupDiGetSelectedDriver(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA) (err error) = setupapi.SetupDiGetSelectedDriverW
// SetupDiGetSelectedDriver function retrieves the selected driver for a device information set or a particular device information element.
func SetupDiGetSelectedDriver ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA ) ( DriverInfoData * SP_DRVINFO_DATA , err error ) {
data := & SP_DRVINFO_DATA { }
data . Size = uint32 ( unsafe . Sizeof ( * data ) )
return data , setupDiGetSelectedDriver ( DeviceInfoSet , DeviceInfoData , data )
}
// GetSelectedDriver method retrieves the selected driver for a device information set or a particular device information element.
func ( DeviceInfoSet DevInfo ) GetSelectedDriver ( DeviceInfoData * SP_DEVINFO_DATA ) ( DriverInfoData * SP_DRVINFO_DATA , err error ) {
return SetupDiGetSelectedDriver ( DeviceInfoSet , DeviceInfoData )
}
//sys SetupDiSetSelectedDriver(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA) (err error) = setupapi.SetupDiSetSelectedDriverW
// SetSelectedDriver method sets, or resets, the selected driver for a device information element or the selected class driver for a device information set.
func ( DeviceInfoSet DevInfo ) SetSelectedDriver ( DeviceInfoData * SP_DEVINFO_DATA , DriverInfoData * SP_DRVINFO_DATA ) ( err error ) {
return SetupDiSetSelectedDriver ( DeviceInfoSet , DeviceInfoData , DriverInfoData )
}
//sys setupDiGetDriverInfoDetail(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA, DriverInfoDetailData *_SP_DRVINFO_DETAIL_DATA, DriverInfoDetailDataSize uint32, RequiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW
// SetupDiGetDriverInfoDetail function retrieves driver information detail for a device information set or a particular device information element in the device information set.
func SetupDiGetDriverInfoDetail ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , DriverInfoData * SP_DRVINFO_DATA ) ( DriverInfoDetailData * DrvInfoDetailData , err error ) {
const bufCapacity = 0x800
buf := [ bufCapacity ] byte { }
var bufLen uint32
_data := ( * _SP_DRVINFO_DETAIL_DATA ) ( unsafe . Pointer ( & buf [ 0 ] ) )
_data . Size = uint32 ( unsafe . Sizeof ( * _data ) )
err = setupDiGetDriverInfoDetail ( DeviceInfoSet , DeviceInfoData , DriverInfoData , _data , bufCapacity , & bufLen )
if err == nil {
// The buffer was was sufficiently big.
return _data . toGo ( bufLen ) , nil
}
if errWin , ok := err . ( syscall . Errno ) ; ok && errWin == windows . ERROR_INSUFFICIENT_BUFFER {
// The buffer was too small. Now that we got the required size, create another one big enough and retry.
buf := make ( [ ] byte , bufLen )
_data := ( * _SP_DRVINFO_DETAIL_DATA ) ( unsafe . Pointer ( & buf [ 0 ] ) )
_data . Size = uint32 ( unsafe . Sizeof ( * _data ) )
err = setupDiGetDriverInfoDetail ( DeviceInfoSet , DeviceInfoData , DriverInfoData , _data , bufLen , & bufLen )
if err == nil {
return _data . toGo ( bufLen ) , nil
}
}
return
}
// GetDriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set.
func ( DeviceInfoSet DevInfo ) GetDriverInfoDetail ( DeviceInfoData * SP_DEVINFO_DATA , DriverInfoData * SP_DRVINFO_DATA ) ( DriverInfoDetailData * DrvInfoDetailData , err error ) {
return SetupDiGetDriverInfoDetail ( DeviceInfoSet , DeviceInfoData , DriverInfoData )
}
//sys SetupDiDestroyDriverInfoList(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT) (err error) = setupapi.SetupDiDestroyDriverInfoList
// DestroyDriverInfoList method deletes a driver list.
func ( DeviceInfoSet DevInfo ) DestroyDriverInfoList ( DeviceInfoData * SP_DEVINFO_DATA , DriverType SPDIT ) ( err error ) {
return SetupDiDestroyDriverInfoList ( DeviceInfoSet , DeviceInfoData , DriverType )
}
2019-02-04 15:21:19 +01:00
//sys setupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiGetClassDevsExW
2019-02-01 11:39:57 +01:00
// SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer.
func SetupDiGetClassDevsEx ( ClassGUID * windows . GUID , Enumerator string , hwndParent uintptr , Flags DIGCF , DeviceInfoSet DevInfo , MachineName string ) ( handle DevInfo , err error ) {
2019-02-04 09:51:19 +01:00
var enumeratorUTF16 * uint16
2019-02-01 10:58:06 +01:00
if Enumerator != "" {
2019-02-04 09:51:19 +01:00
enumeratorUTF16 , err = syscall . UTF16PtrFromString ( Enumerator )
2019-02-01 10:58:06 +01:00
if err != nil {
return
}
}
2019-02-04 09:51:19 +01:00
var machineNameUTF16 * uint16
2019-02-01 10:58:06 +01:00
if MachineName != "" {
2019-02-04 09:51:19 +01:00
machineNameUTF16 , err = syscall . UTF16PtrFromString ( MachineName )
2019-02-01 10:58:06 +01:00
if err != nil {
return
}
}
2019-02-04 09:51:19 +01:00
return setupDiGetClassDevsEx ( ClassGUID , enumeratorUTF16 , hwndParent , Flags , DeviceInfoSet , machineNameUTF16 , 0 )
2019-02-01 11:39:57 +01:00
}
2019-02-04 15:21:19 +01:00
// SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code).
//sys SetupDiCallClassInstaller(InstallFunction DI_FUNCTION, DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiCallClassInstaller
2019-02-04 11:40:44 +01:00
2019-02-05 08:45:44 +01:00
// CallClassInstaller member calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code).
func ( DeviceInfoSet DevInfo ) CallClassInstaller ( InstallFunction DI_FUNCTION , DeviceInfoData * SP_DEVINFO_DATA ) ( err error ) {
return SetupDiCallClassInstaller ( InstallFunction , DeviceInfoSet , DeviceInfoData )
}
2019-02-04 15:21:19 +01:00
//sys setupDiOpenDevRegKey(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key windows.Handle, err error) [failretval==windows.InvalidHandle] = setupapi.SetupDiOpenDevRegKey
2019-02-01 12:17:09 +01:00
2019-02-01 13:00:44 +01:00
// SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information.
func SetupDiOpenDevRegKey ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , Scope DICS_FLAG , HwProfile uint32 , KeyType DIREG , samDesired uint32 ) ( key registry . Key , err error ) {
handle , err := setupDiOpenDevRegKey ( DeviceInfoSet , DeviceInfoData , Scope , HwProfile , KeyType , samDesired )
return registry . Key ( handle ) , err
2019-02-01 12:17:09 +01:00
}
2019-02-01 13:59:53 +01:00
2019-02-05 08:45:44 +01:00
// OpenDevRegKey method opens a registry key for device-specific configuration information.
func ( DeviceInfoSet DevInfo ) OpenDevRegKey ( DeviceInfoData * SP_DEVINFO_DATA , Scope DICS_FLAG , HwProfile uint32 , KeyType DIREG , samDesired uint32 ) ( key registry . Key , err error ) {
return SetupDiOpenDevRegKey ( DeviceInfoSet , DeviceInfoData , Scope , HwProfile , KeyType , samDesired )
}
2019-02-05 11:44:47 +01:00
//sys setupDiGetDeviceRegistryProperty(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Property SPDRP, PropertyRegDataType *uint32, PropertyBuffer *byte, PropertyBufferSize uint32, RequiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceRegistryPropertyW
// SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
func SetupDiGetDeviceRegistryProperty ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , Property SPDRP ) ( value interface { } , err error ) {
buf := make ( [ ] byte , 0x100 )
var dataType , bufLen uint32
err = setupDiGetDeviceRegistryProperty ( DeviceInfoSet , DeviceInfoData , Property , & dataType , & buf [ 0 ] , uint32 ( cap ( buf ) ) , & bufLen )
if err == nil {
// The buffer was sufficiently big.
return getRegistryValue ( buf [ : bufLen ] , dataType )
}
if errWin , ok := err . ( syscall . Errno ) ; ok && errWin == windows . ERROR_INSUFFICIENT_BUFFER {
// The buffer was too small. Now that we got the required size, create another one big enough and retry.
buf = make ( [ ] byte , bufLen )
err = setupDiGetDeviceRegistryProperty ( DeviceInfoSet , DeviceInfoData , Property , & dataType , & buf [ 0 ] , uint32 ( cap ( buf ) ) , & bufLen )
if err == nil {
return getRegistryValue ( buf [ : bufLen ] , dataType )
}
}
return
}
func getRegistryValue ( buf [ ] byte , dataType uint32 ) ( interface { } , error ) {
switch dataType {
case windows . REG_SZ :
2019-02-06 20:15:40 +01:00
return windows . UTF16ToString ( BufToUTF16 ( buf ) ) , nil
2019-02-05 11:44:47 +01:00
case windows . REG_EXPAND_SZ :
2019-02-06 20:15:40 +01:00
return registry . ExpandString ( windows . UTF16ToString ( BufToUTF16 ( buf ) ) )
2019-02-05 11:44:47 +01:00
case windows . REG_BINARY :
return buf , nil
case windows . REG_DWORD_LITTLE_ENDIAN :
return binary . LittleEndian . Uint32 ( buf ) , nil
case windows . REG_DWORD_BIG_ENDIAN :
return binary . BigEndian . Uint32 ( buf ) , nil
case windows . REG_MULTI_SZ :
2019-02-06 20:15:40 +01:00
bufW := BufToUTF16 ( buf )
2019-02-05 11:44:47 +01:00
a := [ ] string { }
for i := 0 ; i < len ( bufW ) ; {
j := i + wcslen ( bufW [ i : ] )
if i < j {
a = append ( a , windows . UTF16ToString ( bufW [ i : j ] ) )
}
i = j + 1
}
return a , nil
case windows . REG_QWORD_LITTLE_ENDIAN :
return binary . LittleEndian . Uint64 ( buf ) , nil
default :
return nil , fmt . Errorf ( "Unsupported registry value type: %v" , dataType )
}
}
2019-02-06 20:15:40 +01:00
// BufToUTF16 function reinterprets []byte buffer as []uint16
func BufToUTF16 ( buf [ ] byte ) [ ] uint16 {
2019-02-05 11:44:47 +01:00
sl := struct {
addr * uint16
len int
cap int
} { ( * uint16 ) ( unsafe . Pointer ( & buf [ 0 ] ) ) , len ( buf ) / 2 , cap ( buf ) / 2 }
return * ( * [ ] uint16 ) ( unsafe . Pointer ( & sl ) )
}
2019-02-06 20:15:40 +01:00
// 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 ) )
}
2019-02-05 11:44:47 +01:00
func wcslen ( str [ ] uint16 ) int {
for i := 0 ; i < len ( str ) ; i ++ {
if str [ i ] == 0 {
return i
}
}
return len ( str )
}
// GetDeviceRegistryProperty method retrieves a specified Plug and Play device property.
func ( DeviceInfoSet DevInfo ) GetDeviceRegistryProperty ( DeviceInfoData * SP_DEVINFO_DATA , Property SPDRP ) ( value interface { } , err error ) {
return SetupDiGetDeviceRegistryProperty ( DeviceInfoSet , DeviceInfoData , Property )
}
//sys setupDiSetDeviceRegistryProperty(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Property SPDRP, PropertyBuffer *byte, PropertyBufferSize uint32) (err error) = setupapi.SetupDiSetDeviceRegistryPropertyW
// SetupDiSetDeviceRegistryProperty function sets a Plug and Play device property for a device.
func SetupDiSetDeviceRegistryProperty ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , Property SPDRP , PropertyBuffer [ ] byte ) ( err error ) {
return setupDiSetDeviceRegistryProperty ( DeviceInfoSet , DeviceInfoData , Property , & PropertyBuffer [ 0 ] , uint32 ( len ( PropertyBuffer ) ) )
}
// SetDeviceRegistryProperty function sets a Plug and Play device property for a device.
func ( DeviceInfoSet DevInfo ) SetDeviceRegistryProperty ( DeviceInfoData * SP_DEVINFO_DATA , Property SPDRP , PropertyBuffer [ ] byte ) ( err error ) {
return SetupDiSetDeviceRegistryProperty ( DeviceInfoSet , DeviceInfoData , Property , PropertyBuffer )
}
2019-02-04 15:21:19 +01:00
//sys setupDiGetDeviceInstallParams(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DeviceInstallParams *_SP_DEVINSTALL_PARAMS) (err error) = setupapi.SetupDiGetDeviceInstallParamsW
2019-02-01 13:59:53 +01:00
// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element.
2019-02-04 11:42:51 +01:00
func SetupDiGetDeviceInstallParams ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA ) ( DeviceInstallParams * DevInstallParams , err error ) {
2019-02-04 09:51:19 +01:00
var _data _SP_DEVINSTALL_PARAMS
_data . Size = uint32 ( unsafe . Sizeof ( _data ) )
2019-02-01 13:59:53 +01:00
2019-02-04 09:51:19 +01:00
err = setupDiGetDeviceInstallParams ( DeviceInfoSet , DeviceInfoData , & _data )
2019-02-01 13:59:53 +01:00
if err != nil {
return
}
2019-02-05 14:03:28 +01:00
return _data . toGo ( ) , nil
2019-02-01 13:59:53 +01:00
}
2019-02-05 08:45:44 +01:00
// GetDeviceInstallParams method retrieves device installation parameters for a device information set or a particular device information element.
func ( DeviceInfoSet DevInfo ) GetDeviceInstallParams ( DeviceInfoData * SP_DEVINFO_DATA ) ( DeviceInstallParams * DevInstallParams , err error ) {
return SetupDiGetDeviceInstallParams ( DeviceInfoSet , DeviceInfoData )
}
2019-02-04 15:21:19 +01:00
// SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a particular device information element.
//sys SetupDiGetClassInstallParams(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, ClassInstallParams *SP_CLASSINSTALL_HEADER, ClassInstallParamsSize uint32, RequiredSize *uint32) (err error) = setupapi.SetupDiGetClassInstallParamsW
2019-02-05 08:45:44 +01:00
// GetClassInstallParams method retrieves class installation parameters for a device information set or a particular device information element.
func ( DeviceInfoSet DevInfo ) GetClassInstallParams ( DeviceInfoData * SP_DEVINFO_DATA , ClassInstallParams * SP_CLASSINSTALL_HEADER , ClassInstallParamsSize uint32 , RequiredSize * uint32 ) ( err error ) {
return SetupDiGetClassInstallParams ( DeviceInfoSet , DeviceInfoData , ClassInstallParams , ClassInstallParamsSize , RequiredSize )
}
2019-02-04 15:21:19 +01:00
//sys setupDiSetDeviceInstallParams(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DeviceInstallParams *_SP_DEVINSTALL_PARAMS) (err error) = setupapi.SetupDiSetDeviceInstallParamsW
2019-02-01 13:59:53 +01:00
// SetupDiSetDeviceInstallParams function sets device installation parameters for a device information set or a particular device information element.
func SetupDiSetDeviceInstallParams ( DeviceInfoSet DevInfo , DeviceInfoData * SP_DEVINFO_DATA , DeviceInstallParams * DevInstallParams ) ( err error ) {
2019-02-05 14:03:28 +01:00
_data , err := DeviceInstallParams . toWindows ( )
2019-02-01 13:59:53 +01:00
if err != nil {
return
}
2019-02-05 14:03:28 +01:00
return setupDiSetDeviceInstallParams ( DeviceInfoSet , DeviceInfoData , _data )
2019-02-01 13:59:53 +01:00
}
2019-02-04 15:21:19 +01:00
2019-02-05 08:45:44 +01:00
// SetDeviceInstallParams member sets device installation parameters for a device information set or a particular device information element.
func ( DeviceInfoSet DevInfo ) SetDeviceInstallParams ( DeviceInfoData * SP_DEVINFO_DATA , DeviceInstallParams * DevInstallParams ) ( err error ) {
return SetupDiSetDeviceInstallParams ( DeviceInfoSet , DeviceInfoData , DeviceInstallParams )
}
2019-02-04 15:21:19 +01:00
// SetupDiSetClassInstallParams function sets or clears class install parameters for a device information set or a particular device information element.
//sys SetupDiSetClassInstallParams(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, ClassInstallParams *SP_CLASSINSTALL_HEADER, ClassInstallParamsSize uint32) (err error) = setupapi.SetupDiSetClassInstallParamsW
2019-02-05 08:45:44 +01:00
// SetClassInstallParams method sets or clears class install parameters for a device information set or a particular device information element.
func ( DeviceInfoSet DevInfo ) SetClassInstallParams ( DeviceInfoData * SP_DEVINFO_DATA , ClassInstallParams * SP_CLASSINSTALL_HEADER , ClassInstallParamsSize uint32 ) ( err error ) {
return SetupDiSetClassInstallParams ( DeviceInfoSet , DeviceInfoData , ClassInstallParams , ClassInstallParamsSize )
}
2019-02-04 15:21:19 +01:00
//sys setupDiClassNameFromGuidEx(ClassGUID *windows.GUID, ClassName *uint16, ClassNameSize uint32, RequiredSize *uint32, MachineName *uint16, Reserved uintptr) (err error) = setupapi.SetupDiClassNameFromGuidExW
// SetupDiClassNameFromGuidEx function retrieves the class name associated with a class GUID. The class can be installed on a local or remote computer.
func SetupDiClassNameFromGuidEx ( ClassGUID * windows . GUID , MachineName string ) ( ClassName string , err error ) {
var classNameUTF16 [ MAX_CLASS_NAME_LEN ] uint16
var machineNameUTF16 * uint16
if MachineName != "" {
machineNameUTF16 , err = syscall . UTF16PtrFromString ( MachineName )
if err != nil {
return
}
}
err = setupDiClassNameFromGuidEx ( ClassGUID , & classNameUTF16 [ 0 ] , MAX_CLASS_NAME_LEN , nil , machineNameUTF16 , 0 )
if err != nil {
return
}
ClassName = windows . UTF16ToString ( classNameUTF16 [ : ] )
return
}
//sys setupDiClassGuidsFromNameEx(ClassName *uint16, ClassGuidList *windows.GUID, ClassGuidListSize uint32, RequiredSize *uint32, MachineName *uint16, Reserved uintptr) (err error) = setupapi.SetupDiClassGuidsFromNameExW
// SetupDiClassGuidsFromNameEx function retrieves the GUIDs associated with the specified class name. This resulting list contains the classes currently installed on a local or remote computer.
func SetupDiClassGuidsFromNameEx ( ClassName string , MachineName string ) ( ClassGuidList [ ] windows . GUID , err error ) {
classNameUTF16 , err := syscall . UTF16PtrFromString ( ClassName )
if err != nil {
return
}
2019-02-05 11:44:47 +01:00
const bufCapacity = 4
var buf [ bufCapacity ] windows . GUID
var bufLen uint32
2019-02-04 15:21:19 +01:00
var machineNameUTF16 * uint16
if MachineName != "" {
machineNameUTF16 , err = syscall . UTF16PtrFromString ( MachineName )
if err != nil {
return
}
}
2019-02-05 11:44:47 +01:00
err = setupDiClassGuidsFromNameEx ( classNameUTF16 , & buf [ 0 ] , bufCapacity , & bufLen , machineNameUTF16 , 0 )
2019-02-04 15:21:19 +01:00
if err == nil {
// The GUID array was sufficiently big. Return its slice.
2019-02-05 11:44:47 +01:00
return buf [ : bufLen ] , nil
2019-02-04 15:21:19 +01:00
}
if errWin , ok := err . ( syscall . Errno ) ; ok && errWin == windows . ERROR_INSUFFICIENT_BUFFER {
// The GUID array was too small. Now that we got the required size, create another one big enough and retry.
2019-02-05 11:44:47 +01:00
buf := make ( [ ] windows . GUID , bufLen )
err = setupDiClassGuidsFromNameEx ( classNameUTF16 , & buf [ 0 ] , bufLen , & bufLen , machineNameUTF16 , 0 )
2019-02-04 15:21:19 +01:00
if err == nil {
2019-02-05 11:44:47 +01:00
return buf [ : bufLen ] , nil
2019-02-04 15:21:19 +01:00
}
}
return
}
2019-02-04 15:50:59 +01:00
//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 )
}
2019-02-05 08:45:44 +01:00
// GetSelectedDevice method retrieves the selected device information element in a device information set.
func ( DeviceInfoSet DevInfo ) GetSelectedDevice ( ) ( DeviceInfoData * SP_DEVINFO_DATA , err error ) {
return SetupDiGetSelectedDevice ( DeviceInfoSet )
}
2019-02-04 15:50:59 +01:00
// 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
2019-02-05 08:45:44 +01:00
// SetSelectedDevice method sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard.
func ( DeviceInfoSet DevInfo ) SetSelectedDevice ( DeviceInfoData * SP_DEVINFO_DATA ) ( err error ) {
return SetupDiSetSelectedDevice ( DeviceInfoSet , DeviceInfoData )
}