setupapi: Add support for driver info lists
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
		
							parent
							
								
									7b636380e5
								
							
						
					
					
						commit
						3e8f2e3fa5
					
				@ -100,6 +100,101 @@ func (DeviceInfoSet DevInfo) Close() error {
 | 
				
			|||||||
	return SetupDiDestroyDeviceInfoList(DeviceInfoSet)
 | 
						return SetupDiDestroyDeviceInfoList(DeviceInfoSet)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//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
 | 
					//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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer.
 | 
					// SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer.
 | 
				
			||||||
 | 
				
			|||||||
@ -136,6 +136,69 @@ func TestSetupDiEnumDeviceInfo(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestDevInfo_BuildDriverInfoList(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++ {
 | 
				
			||||||
 | 
							deviceData, err := devInfoList.EnumDeviceInfo(i)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const driverType SPDIT = SPDIT_COMPATDRIVER
 | 
				
			||||||
 | 
							err = devInfoList.BuildDriverInfoList(deviceData, driverType)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Errorf("Error calling SetupDiBuildDriverInfoList: %s", err.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							defer devInfoList.DestroyDriverInfoList(deviceData, driverType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var selectedDriverData *SP_DRVINFO_DATA
 | 
				
			||||||
 | 
							for j := 0; true; j++ {
 | 
				
			||||||
 | 
								driverData, err := devInfoList.EnumDriverInfo(deviceData, driverType, j)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if driverData2, err2 := driverData.ToGo().ToWindows(); err2 != nil || *driverData2 != *driverData {
 | 
				
			||||||
 | 
									t.Error("Error converting between SP_DRVINFO_DATA and DrvInfoData")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if driverData.DriverType == 0 {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								err = devInfoList.SetSelectedDriver(deviceData, driverData)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									t.Errorf("Error calling SetupDiSetSelectedDriver: %s", err.Error())
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									selectedDriverData = driverData
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								_, err = devInfoList.GetDriverInfoDetail(deviceData, driverData)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									t.Errorf("Error calling SetupDiGetDriverInfoDetail: %s", err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							selectedDriverData2, err := devInfoList.GetSelectedDriver(deviceData)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Errorf("Error calling SetupDiGetSelectedDriver: %s", err.Error())
 | 
				
			||||||
 | 
							} else if *selectedDriverData != *selectedDriverData2 {
 | 
				
			||||||
 | 
								t.Error("SetupDiGetSelectedDriver should return driver selected with SetupDiSetSelectedDriver")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestSetupDiGetClassDevsEx(t *testing.T) {
 | 
					func TestSetupDiGetClassDevsEx(t *testing.T) {
 | 
				
			||||||
	devInfoList, err := SetupDiGetClassDevsEx(&deviceClassNetGUID, "PCI", 0, DIGCF_PRESENT, DevInfo(0), computerName)
 | 
						devInfoList, err := SetupDiGetClassDevsEx(&deviceClassNetGUID, "PCI", 0, DIGCF_PRESENT, DevInfo(0), computerName)
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,20 @@ const (
 | 
				
			|||||||
	CONFIGMG_VERSION    = 0x0400
 | 
						CONFIGMG_VERSION    = 0x0400
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Define maximum string length constants
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LINE_LEN                    = 256  // Windows 9x-compatible maximum for displayable strings coming from a device INF.
 | 
				
			||||||
 | 
						MAX_INF_STRING_LENGTH       = 4096 // Actual maximum size of an INF string (including string substitutions).
 | 
				
			||||||
 | 
						MAX_INF_SECTION_NAME_LENGTH = 255  // For Windows 9x compatibility, INF section names should be constrained to 32 characters.
 | 
				
			||||||
 | 
						MAX_TITLE_LEN               = 60
 | 
				
			||||||
 | 
						MAX_INSTRUCTION_LEN         = 256
 | 
				
			||||||
 | 
						MAX_LABEL_LEN               = 30
 | 
				
			||||||
 | 
						MAX_SERVICE_NAME_LEN        = 256
 | 
				
			||||||
 | 
						MAX_SUBTITLE_LEN            = 256
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// SP_MAX_MACHINENAME_LENGTH defines maximum length of a machine name in the format expected by ConfigMgr32 CM_Connect_Machine (i.e., "\\\\MachineName\0").
 | 
						// SP_MAX_MACHINENAME_LENGTH defines maximum length of a machine name in the format expected by ConfigMgr32 CM_Connect_Machine (i.e., "\\\\MachineName\0").
 | 
				
			||||||
	SP_MAX_MACHINENAME_LENGTH = windows.MAX_PATH + 3
 | 
						SP_MAX_MACHINENAME_LENGTH = windows.MAX_PATH + 3
 | 
				
			||||||
@ -285,6 +299,128 @@ const (
 | 
				
			|||||||
	DICS_FLAG_CONFIGGENERAL  DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow
 | 
						DICS_FLAG_CONFIGGENERAL  DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SP_DRVINFO_DATA struct {
 | 
				
			||||||
 | 
						Size          uint32
 | 
				
			||||||
 | 
						DriverType    uint32
 | 
				
			||||||
 | 
						_             uintptr
 | 
				
			||||||
 | 
						Description   [LINE_LEN]uint16
 | 
				
			||||||
 | 
						MfgName       [LINE_LEN]uint16
 | 
				
			||||||
 | 
						ProviderName  [LINE_LEN]uint16
 | 
				
			||||||
 | 
						DriverDate    windows.Filetime
 | 
				
			||||||
 | 
						DriverVersion uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data SP_DRVINFO_DATA) ToGo() *DrvInfoData {
 | 
				
			||||||
 | 
						return &DrvInfoData{
 | 
				
			||||||
 | 
							DriverType:    data.DriverType,
 | 
				
			||||||
 | 
							Description:   windows.UTF16ToString(data.Description[:]),
 | 
				
			||||||
 | 
							MfgName:       windows.UTF16ToString(data.MfgName[:]),
 | 
				
			||||||
 | 
							ProviderName:  windows.UTF16ToString(data.ProviderName[:]),
 | 
				
			||||||
 | 
							DriverDate:    data.DriverDate,
 | 
				
			||||||
 | 
							DriverVersion: data.DriverVersion,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DrvInfoData is driver information structure (member of a driver info list that may be associated with a particular device instance, or (globally) with a device information set)
 | 
				
			||||||
 | 
					type DrvInfoData struct {
 | 
				
			||||||
 | 
						DriverType    uint32
 | 
				
			||||||
 | 
						Description   string
 | 
				
			||||||
 | 
						MfgName       string
 | 
				
			||||||
 | 
						ProviderName  string
 | 
				
			||||||
 | 
						DriverDate    windows.Filetime
 | 
				
			||||||
 | 
						DriverVersion uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (DriverInfoData DrvInfoData) ToWindows() (data *SP_DRVINFO_DATA, err error) {
 | 
				
			||||||
 | 
						data = &SP_DRVINFO_DATA{
 | 
				
			||||||
 | 
							DriverType:    DriverInfoData.DriverType,
 | 
				
			||||||
 | 
							DriverDate:    DriverInfoData.DriverDate,
 | 
				
			||||||
 | 
							DriverVersion: DriverInfoData.DriverVersion,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						data.Size = uint32(unsafe.Sizeof(*data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DescriptionUTF16, err := syscall.UTF16FromString(DriverInfoData.Description)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						copy(data.Description[:], DescriptionUTF16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MfgNameUTF16, err := syscall.UTF16FromString(DriverInfoData.MfgName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						copy(data.MfgName[:], MfgNameUTF16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ProviderNameUTF16, err := syscall.UTF16FromString(DriverInfoData.ProviderName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						copy(data.ProviderName[:], ProviderNameUTF16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type _SP_DRVINFO_DETAIL_DATA struct {
 | 
				
			||||||
 | 
						Size            uint32
 | 
				
			||||||
 | 
						InfDate         windows.Filetime
 | 
				
			||||||
 | 
						CompatIDsOffset uint32
 | 
				
			||||||
 | 
						CompatIDsLength uint32
 | 
				
			||||||
 | 
						_               uintptr
 | 
				
			||||||
 | 
						SectionName     [LINE_LEN]uint16
 | 
				
			||||||
 | 
						InfFileName     [windows.MAX_PATH]uint16
 | 
				
			||||||
 | 
						DrvDescription  [LINE_LEN]uint16
 | 
				
			||||||
 | 
						HardwareID      [1]uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_data _SP_DRVINFO_DETAIL_DATA) toGo(bufLen uint32) (DriverInfoDetailData *DrvInfoDetailData) {
 | 
				
			||||||
 | 
						DriverInfoDetailData = &DrvInfoDetailData{
 | 
				
			||||||
 | 
							InfDate:        _data.InfDate,
 | 
				
			||||||
 | 
							SectionName:    windows.UTF16ToString(_data.SectionName[:]),
 | 
				
			||||||
 | 
							InfFileName:    windows.UTF16ToString(_data.InfFileName[:]),
 | 
				
			||||||
 | 
							DrvDescription: windows.UTF16ToString(_data.DrvDescription[:]),
 | 
				
			||||||
 | 
							CompatIDs:      []string{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bufW := _data.getBuf(bufLen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if _data.CompatIDsOffset > 1 {
 | 
				
			||||||
 | 
							DriverInfoDetailData.HardwareID = windows.UTF16ToString(bufW[:wcslen(bufW)])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if _data.CompatIDsLength > 0 {
 | 
				
			||||||
 | 
							bufW = bufW[_data.CompatIDsOffset : _data.CompatIDsOffset+_data.CompatIDsLength]
 | 
				
			||||||
 | 
							for i := 0; i < len(bufW); {
 | 
				
			||||||
 | 
								j := i + wcslen(bufW[i:])
 | 
				
			||||||
 | 
								if i < j {
 | 
				
			||||||
 | 
									DriverInfoDetailData.CompatIDs = append(DriverInfoDetailData.CompatIDs, windows.UTF16ToString(bufW[i:j]))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i = j + 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_data _SP_DRVINFO_DETAIL_DATA) getBuf(bufLen uint32) []uint16 {
 | 
				
			||||||
 | 
						len := (bufLen - uint32(unsafe.Offsetof(_data.HardwareID))) / 2
 | 
				
			||||||
 | 
						sl := struct {
 | 
				
			||||||
 | 
							addr *uint16
 | 
				
			||||||
 | 
							len  int
 | 
				
			||||||
 | 
							cap  int
 | 
				
			||||||
 | 
						}{&_data.HardwareID[0], int(len), int(len)}
 | 
				
			||||||
 | 
						return *(*[]uint16)(unsafe.Pointer(&sl))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure)
 | 
				
			||||||
 | 
					type DrvInfoDetailData struct {
 | 
				
			||||||
 | 
						InfDate        windows.Filetime
 | 
				
			||||||
 | 
						SectionName    string
 | 
				
			||||||
 | 
						InfFileName    string
 | 
				
			||||||
 | 
						DrvDescription string
 | 
				
			||||||
 | 
						HardwareID     string
 | 
				
			||||||
 | 
						CompatIDs      []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DICD flags control SetupDiCreateDeviceInfo
 | 
					// DICD flags control SetupDiCreateDeviceInfo
 | 
				
			||||||
type DICD uint32
 | 
					type DICD uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -293,6 +429,19 @@ const (
 | 
				
			|||||||
	DICD_INHERIT_CLASSDRVS DICD = 0x00000002
 | 
						DICD_INHERIT_CLASSDRVS DICD = 0x00000002
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// SPDIT flags to distinguish between class drivers and
 | 
				
			||||||
 | 
					// device drivers.
 | 
				
			||||||
 | 
					// (Passed in 'DriverType' parameter of driver information list APIs)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					type SPDIT uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						SPDIT_NODRIVER     SPDIT = 0x00000000
 | 
				
			||||||
 | 
						SPDIT_CLASSDRIVER  SPDIT = 0x00000001
 | 
				
			||||||
 | 
						SPDIT_COMPATDRIVER SPDIT = 0x00000002
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DIGCF flags control what is included in the device information set built by SetupDiGetClassDevs
 | 
					// DIGCF flags control what is included in the device information set built by SetupDiGetClassDevs
 | 
				
			||||||
type DIGCF uint32
 | 
					type DIGCF uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,13 @@ var (
 | 
				
			|||||||
	procSetupDiCreateDeviceInfoW          = modsetupapi.NewProc("SetupDiCreateDeviceInfoW")
 | 
						procSetupDiCreateDeviceInfoW          = modsetupapi.NewProc("SetupDiCreateDeviceInfoW")
 | 
				
			||||||
	procSetupDiEnumDeviceInfo             = modsetupapi.NewProc("SetupDiEnumDeviceInfo")
 | 
						procSetupDiEnumDeviceInfo             = modsetupapi.NewProc("SetupDiEnumDeviceInfo")
 | 
				
			||||||
	procSetupDiDestroyDeviceInfoList      = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList")
 | 
						procSetupDiDestroyDeviceInfoList      = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList")
 | 
				
			||||||
 | 
						procSetupDiBuildDriverInfoList        = modsetupapi.NewProc("SetupDiBuildDriverInfoList")
 | 
				
			||||||
 | 
						procSetupDiCancelDriverInfoSearch     = modsetupapi.NewProc("SetupDiCancelDriverInfoSearch")
 | 
				
			||||||
 | 
						procSetupDiEnumDriverInfoW            = modsetupapi.NewProc("SetupDiEnumDriverInfoW")
 | 
				
			||||||
 | 
						procSetupDiGetSelectedDriverW         = modsetupapi.NewProc("SetupDiGetSelectedDriverW")
 | 
				
			||||||
 | 
						procSetupDiSetSelectedDriverW         = modsetupapi.NewProc("SetupDiSetSelectedDriverW")
 | 
				
			||||||
 | 
						procSetupDiGetDriverInfoDetailW       = modsetupapi.NewProc("SetupDiGetDriverInfoDetailW")
 | 
				
			||||||
 | 
						procSetupDiDestroyDriverInfoList      = modsetupapi.NewProc("SetupDiDestroyDriverInfoList")
 | 
				
			||||||
	procSetupDiGetClassDevsExW            = modsetupapi.NewProc("SetupDiGetClassDevsExW")
 | 
						procSetupDiGetClassDevsExW            = modsetupapi.NewProc("SetupDiGetClassDevsExW")
 | 
				
			||||||
	procSetupDiCallClassInstaller         = modsetupapi.NewProc("SetupDiCallClassInstaller")
 | 
						procSetupDiCallClassInstaller         = modsetupapi.NewProc("SetupDiCallClassInstaller")
 | 
				
			||||||
	procSetupDiOpenDevRegKey              = modsetupapi.NewProc("SetupDiOpenDevRegKey")
 | 
						procSetupDiOpenDevRegKey              = modsetupapi.NewProc("SetupDiOpenDevRegKey")
 | 
				
			||||||
@ -120,6 +127,90 @@ func SetupDiDestroyDeviceInfoList(DeviceInfoSet DevInfo) (err error) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SetupDiBuildDriverInfoList(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall(procSetupDiBuildDriverInfoList.Addr(), 3, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(DriverType))
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SetupDiCancelDriverInfoSearch(DeviceInfoSet DevInfo) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall(procSetupDiCancelDriverInfoSearch.Addr(), 1, uintptr(DeviceInfoSet), 0, 0)
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setupDiEnumDriverInfo(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT, MemberIndex uint32, DriverInfoData *SP_DRVINFO_DATA) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall6(procSetupDiEnumDriverInfoW.Addr(), 5, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(DriverType), uintptr(MemberIndex), uintptr(unsafe.Pointer(DriverInfoData)), 0)
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setupDiGetSelectedDriver(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDriverW.Addr(), 3, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(unsafe.Pointer(DriverInfoData)))
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SetupDiSetSelectedDriver(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDriverW.Addr(), 3, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(unsafe.Pointer(DriverInfoData)))
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setupDiGetDriverInfoDetail(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverInfoData *SP_DRVINFO_DATA, DriverInfoDetailData *_SP_DRVINFO_DETAIL_DATA, DriverInfoDetailDataSize uint32, RequiredSize *uint32) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall6(procSetupDiGetDriverInfoDetailW.Addr(), 6, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(unsafe.Pointer(DriverInfoData)), uintptr(unsafe.Pointer(DriverInfoDetailData)), uintptr(DriverInfoDetailDataSize), uintptr(unsafe.Pointer(RequiredSize)))
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SetupDiDestroyDriverInfoList(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, DriverType SPDIT) (err error) {
 | 
				
			||||||
 | 
						r1, _, e1 := syscall.Syscall(procSetupDiDestroyDriverInfoList.Addr(), 3, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(DriverType))
 | 
				
			||||||
 | 
						if r1 == 0 {
 | 
				
			||||||
 | 
							if e1 != 0 {
 | 
				
			||||||
 | 
								err = errnoErr(e1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								err = syscall.EINVAL
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func setupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName *uint16, reserved uintptr) (handle DevInfo, err error) {
 | 
					func setupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName *uint16, reserved uintptr) (handle DevInfo, err error) {
 | 
				
			||||||
	r0, _, e1 := syscall.Syscall9(procSetupDiGetClassDevsExW.Addr(), 7, uintptr(unsafe.Pointer(ClassGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(MachineName)), uintptr(reserved), 0, 0)
 | 
						r0, _, e1 := syscall.Syscall9(procSetupDiGetClassDevsExW.Addr(), 7, uintptr(unsafe.Pointer(ClassGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(MachineName)), uintptr(reserved), 0, 0)
 | 
				
			||||||
	handle = DevInfo(r0)
 | 
						handle = DevInfo(r0)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user