vendor/golang.org/x/sys/windows/setupapi_windows.go
changeset 265 05c40b36d3b2
equal deleted inserted replaced
264:8f478162d991 265:05c40b36d3b2
       
     1 // Copyright 2021 The Go Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style
       
     3 // license that can be found in the LICENSE file.
       
     4 
       
     5 package windows
       
     6 
       
     7 import (
       
     8 	"encoding/binary"
       
     9 	"errors"
       
    10 	"fmt"
       
    11 	"runtime"
       
    12 	"strings"
       
    13 	"syscall"
       
    14 	"unsafe"
       
    15 )
       
    16 
       
    17 // This file contains functions that wrap SetupAPI.dll and CfgMgr32.dll,
       
    18 // core system functions for managing hardware devices, drivers, and the PnP tree.
       
    19 // Information about these APIs can be found at:
       
    20 //     https://docs.microsoft.com/en-us/windows-hardware/drivers/install/setupapi
       
    21 //     https://docs.microsoft.com/en-us/windows/win32/devinst/cfgmgr32-
       
    22 
       
    23 const (
       
    24 	ERROR_EXPECTED_SECTION_NAME                  Errno = 0x20000000 | 0xC0000000 | 0
       
    25 	ERROR_BAD_SECTION_NAME_LINE                  Errno = 0x20000000 | 0xC0000000 | 1
       
    26 	ERROR_SECTION_NAME_TOO_LONG                  Errno = 0x20000000 | 0xC0000000 | 2
       
    27 	ERROR_GENERAL_SYNTAX                         Errno = 0x20000000 | 0xC0000000 | 3
       
    28 	ERROR_WRONG_INF_STYLE                        Errno = 0x20000000 | 0xC0000000 | 0x100
       
    29 	ERROR_SECTION_NOT_FOUND                      Errno = 0x20000000 | 0xC0000000 | 0x101
       
    30 	ERROR_LINE_NOT_FOUND                         Errno = 0x20000000 | 0xC0000000 | 0x102
       
    31 	ERROR_NO_BACKUP                              Errno = 0x20000000 | 0xC0000000 | 0x103
       
    32 	ERROR_NO_ASSOCIATED_CLASS                    Errno = 0x20000000 | 0xC0000000 | 0x200
       
    33 	ERROR_CLASS_MISMATCH                         Errno = 0x20000000 | 0xC0000000 | 0x201
       
    34 	ERROR_DUPLICATE_FOUND                        Errno = 0x20000000 | 0xC0000000 | 0x202
       
    35 	ERROR_NO_DRIVER_SELECTED                     Errno = 0x20000000 | 0xC0000000 | 0x203
       
    36 	ERROR_KEY_DOES_NOT_EXIST                     Errno = 0x20000000 | 0xC0000000 | 0x204
       
    37 	ERROR_INVALID_DEVINST_NAME                   Errno = 0x20000000 | 0xC0000000 | 0x205
       
    38 	ERROR_INVALID_CLASS                          Errno = 0x20000000 | 0xC0000000 | 0x206
       
    39 	ERROR_DEVINST_ALREADY_EXISTS                 Errno = 0x20000000 | 0xC0000000 | 0x207
       
    40 	ERROR_DEVINFO_NOT_REGISTERED                 Errno = 0x20000000 | 0xC0000000 | 0x208
       
    41 	ERROR_INVALID_REG_PROPERTY                   Errno = 0x20000000 | 0xC0000000 | 0x209
       
    42 	ERROR_NO_INF                                 Errno = 0x20000000 | 0xC0000000 | 0x20A
       
    43 	ERROR_NO_SUCH_DEVINST                        Errno = 0x20000000 | 0xC0000000 | 0x20B
       
    44 	ERROR_CANT_LOAD_CLASS_ICON                   Errno = 0x20000000 | 0xC0000000 | 0x20C
       
    45 	ERROR_INVALID_CLASS_INSTALLER                Errno = 0x20000000 | 0xC0000000 | 0x20D
       
    46 	ERROR_DI_DO_DEFAULT                          Errno = 0x20000000 | 0xC0000000 | 0x20E
       
    47 	ERROR_DI_NOFILECOPY                          Errno = 0x20000000 | 0xC0000000 | 0x20F
       
    48 	ERROR_INVALID_HWPROFILE                      Errno = 0x20000000 | 0xC0000000 | 0x210
       
    49 	ERROR_NO_DEVICE_SELECTED                     Errno = 0x20000000 | 0xC0000000 | 0x211
       
    50 	ERROR_DEVINFO_LIST_LOCKED                    Errno = 0x20000000 | 0xC0000000 | 0x212
       
    51 	ERROR_DEVINFO_DATA_LOCKED                    Errno = 0x20000000 | 0xC0000000 | 0x213
       
    52 	ERROR_DI_BAD_PATH                            Errno = 0x20000000 | 0xC0000000 | 0x214
       
    53 	ERROR_NO_CLASSINSTALL_PARAMS                 Errno = 0x20000000 | 0xC0000000 | 0x215
       
    54 	ERROR_FILEQUEUE_LOCKED                       Errno = 0x20000000 | 0xC0000000 | 0x216
       
    55 	ERROR_BAD_SERVICE_INSTALLSECT                Errno = 0x20000000 | 0xC0000000 | 0x217
       
    56 	ERROR_NO_CLASS_DRIVER_LIST                   Errno = 0x20000000 | 0xC0000000 | 0x218
       
    57 	ERROR_NO_ASSOCIATED_SERVICE                  Errno = 0x20000000 | 0xC0000000 | 0x219
       
    58 	ERROR_NO_DEFAULT_DEVICE_INTERFACE            Errno = 0x20000000 | 0xC0000000 | 0x21A
       
    59 	ERROR_DEVICE_INTERFACE_ACTIVE                Errno = 0x20000000 | 0xC0000000 | 0x21B
       
    60 	ERROR_DEVICE_INTERFACE_REMOVED               Errno = 0x20000000 | 0xC0000000 | 0x21C
       
    61 	ERROR_BAD_INTERFACE_INSTALLSECT              Errno = 0x20000000 | 0xC0000000 | 0x21D
       
    62 	ERROR_NO_SUCH_INTERFACE_CLASS                Errno = 0x20000000 | 0xC0000000 | 0x21E
       
    63 	ERROR_INVALID_REFERENCE_STRING               Errno = 0x20000000 | 0xC0000000 | 0x21F
       
    64 	ERROR_INVALID_MACHINENAME                    Errno = 0x20000000 | 0xC0000000 | 0x220
       
    65 	ERROR_REMOTE_COMM_FAILURE                    Errno = 0x20000000 | 0xC0000000 | 0x221
       
    66 	ERROR_MACHINE_UNAVAILABLE                    Errno = 0x20000000 | 0xC0000000 | 0x222
       
    67 	ERROR_NO_CONFIGMGR_SERVICES                  Errno = 0x20000000 | 0xC0000000 | 0x223
       
    68 	ERROR_INVALID_PROPPAGE_PROVIDER              Errno = 0x20000000 | 0xC0000000 | 0x224
       
    69 	ERROR_NO_SUCH_DEVICE_INTERFACE               Errno = 0x20000000 | 0xC0000000 | 0x225
       
    70 	ERROR_DI_POSTPROCESSING_REQUIRED             Errno = 0x20000000 | 0xC0000000 | 0x226
       
    71 	ERROR_INVALID_COINSTALLER                    Errno = 0x20000000 | 0xC0000000 | 0x227
       
    72 	ERROR_NO_COMPAT_DRIVERS                      Errno = 0x20000000 | 0xC0000000 | 0x228
       
    73 	ERROR_NO_DEVICE_ICON                         Errno = 0x20000000 | 0xC0000000 | 0x229
       
    74 	ERROR_INVALID_INF_LOGCONFIG                  Errno = 0x20000000 | 0xC0000000 | 0x22A
       
    75 	ERROR_DI_DONT_INSTALL                        Errno = 0x20000000 | 0xC0000000 | 0x22B
       
    76 	ERROR_INVALID_FILTER_DRIVER                  Errno = 0x20000000 | 0xC0000000 | 0x22C
       
    77 	ERROR_NON_WINDOWS_NT_DRIVER                  Errno = 0x20000000 | 0xC0000000 | 0x22D
       
    78 	ERROR_NON_WINDOWS_DRIVER                     Errno = 0x20000000 | 0xC0000000 | 0x22E
       
    79 	ERROR_NO_CATALOG_FOR_OEM_INF                 Errno = 0x20000000 | 0xC0000000 | 0x22F
       
    80 	ERROR_DEVINSTALL_QUEUE_NONNATIVE             Errno = 0x20000000 | 0xC0000000 | 0x230
       
    81 	ERROR_NOT_DISABLEABLE                        Errno = 0x20000000 | 0xC0000000 | 0x231
       
    82 	ERROR_CANT_REMOVE_DEVINST                    Errno = 0x20000000 | 0xC0000000 | 0x232
       
    83 	ERROR_INVALID_TARGET                         Errno = 0x20000000 | 0xC0000000 | 0x233
       
    84 	ERROR_DRIVER_NONNATIVE                       Errno = 0x20000000 | 0xC0000000 | 0x234
       
    85 	ERROR_IN_WOW64                               Errno = 0x20000000 | 0xC0000000 | 0x235
       
    86 	ERROR_SET_SYSTEM_RESTORE_POINT               Errno = 0x20000000 | 0xC0000000 | 0x236
       
    87 	ERROR_SCE_DISABLED                           Errno = 0x20000000 | 0xC0000000 | 0x238
       
    88 	ERROR_UNKNOWN_EXCEPTION                      Errno = 0x20000000 | 0xC0000000 | 0x239
       
    89 	ERROR_PNP_REGISTRY_ERROR                     Errno = 0x20000000 | 0xC0000000 | 0x23A
       
    90 	ERROR_REMOTE_REQUEST_UNSUPPORTED             Errno = 0x20000000 | 0xC0000000 | 0x23B
       
    91 	ERROR_NOT_AN_INSTALLED_OEM_INF               Errno = 0x20000000 | 0xC0000000 | 0x23C
       
    92 	ERROR_INF_IN_USE_BY_DEVICES                  Errno = 0x20000000 | 0xC0000000 | 0x23D
       
    93 	ERROR_DI_FUNCTION_OBSOLETE                   Errno = 0x20000000 | 0xC0000000 | 0x23E
       
    94 	ERROR_NO_AUTHENTICODE_CATALOG                Errno = 0x20000000 | 0xC0000000 | 0x23F
       
    95 	ERROR_AUTHENTICODE_DISALLOWED                Errno = 0x20000000 | 0xC0000000 | 0x240
       
    96 	ERROR_AUTHENTICODE_TRUSTED_PUBLISHER         Errno = 0x20000000 | 0xC0000000 | 0x241
       
    97 	ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED     Errno = 0x20000000 | 0xC0000000 | 0x242
       
    98 	ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED     Errno = 0x20000000 | 0xC0000000 | 0x243
       
    99 	ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH         Errno = 0x20000000 | 0xC0000000 | 0x244
       
   100 	ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE         Errno = 0x20000000 | 0xC0000000 | 0x245
       
   101 	ERROR_DEVICE_INSTALLER_NOT_READY             Errno = 0x20000000 | 0xC0000000 | 0x246
       
   102 	ERROR_DRIVER_STORE_ADD_FAILED                Errno = 0x20000000 | 0xC0000000 | 0x247
       
   103 	ERROR_DEVICE_INSTALL_BLOCKED                 Errno = 0x20000000 | 0xC0000000 | 0x248
       
   104 	ERROR_DRIVER_INSTALL_BLOCKED                 Errno = 0x20000000 | 0xC0000000 | 0x249
       
   105 	ERROR_WRONG_INF_TYPE                         Errno = 0x20000000 | 0xC0000000 | 0x24A
       
   106 	ERROR_FILE_HASH_NOT_IN_CATALOG               Errno = 0x20000000 | 0xC0000000 | 0x24B
       
   107 	ERROR_DRIVER_STORE_DELETE_FAILED             Errno = 0x20000000 | 0xC0000000 | 0x24C
       
   108 	ERROR_UNRECOVERABLE_STACK_OVERFLOW           Errno = 0x20000000 | 0xC0000000 | 0x300
       
   109 	EXCEPTION_SPAPI_UNRECOVERABLE_STACK_OVERFLOW Errno = ERROR_UNRECOVERABLE_STACK_OVERFLOW
       
   110 	ERROR_NO_DEFAULT_INTERFACE_DEVICE            Errno = ERROR_NO_DEFAULT_DEVICE_INTERFACE
       
   111 	ERROR_INTERFACE_DEVICE_ACTIVE                Errno = ERROR_DEVICE_INTERFACE_ACTIVE
       
   112 	ERROR_INTERFACE_DEVICE_REMOVED               Errno = ERROR_DEVICE_INTERFACE_REMOVED
       
   113 	ERROR_NO_SUCH_INTERFACE_DEVICE               Errno = ERROR_NO_SUCH_DEVICE_INTERFACE
       
   114 )
       
   115 
       
   116 const (
       
   117 	MAX_DEVICE_ID_LEN   = 200
       
   118 	MAX_DEVNODE_ID_LEN  = MAX_DEVICE_ID_LEN
       
   119 	MAX_GUID_STRING_LEN = 39 // 38 chars + terminator null
       
   120 	MAX_CLASS_NAME_LEN  = 32
       
   121 	MAX_PROFILE_LEN     = 80
       
   122 	MAX_CONFIG_VALUE    = 9999
       
   123 	MAX_INSTANCE_VALUE  = 9999
       
   124 	CONFIGMG_VERSION    = 0x0400
       
   125 )
       
   126 
       
   127 // Maximum string length constants
       
   128 const (
       
   129 	LINE_LEN                    = 256  // Windows 9x-compatible maximum for displayable strings coming from a device INF.
       
   130 	MAX_INF_STRING_LENGTH       = 4096 // Actual maximum size of an INF string (including string substitutions).
       
   131 	MAX_INF_SECTION_NAME_LENGTH = 255  // For Windows 9x compatibility, INF section names should be constrained to 32 characters.
       
   132 	MAX_TITLE_LEN               = 60
       
   133 	MAX_INSTRUCTION_LEN         = 256
       
   134 	MAX_LABEL_LEN               = 30
       
   135 	MAX_SERVICE_NAME_LEN        = 256
       
   136 	MAX_SUBTITLE_LEN            = 256
       
   137 )
       
   138 
       
   139 const (
       
   140 	// SP_MAX_MACHINENAME_LENGTH defines maximum length of a machine name in the format expected by ConfigMgr32 CM_Connect_Machine (i.e., "\\\\MachineName\0").
       
   141 	SP_MAX_MACHINENAME_LENGTH = MAX_PATH + 3
       
   142 )
       
   143 
       
   144 // HSPFILEQ is type for setup file queue
       
   145 type HSPFILEQ uintptr
       
   146 
       
   147 // DevInfo holds reference to device information set
       
   148 type DevInfo Handle
       
   149 
       
   150 // DEVINST is a handle usually recognized by cfgmgr32 APIs
       
   151 type DEVINST uint32
       
   152 
       
   153 // DevInfoData is a device information structure (references a device instance that is a member of a device information set)
       
   154 type DevInfoData struct {
       
   155 	size      uint32
       
   156 	ClassGUID GUID
       
   157 	DevInst   DEVINST
       
   158 	_         uintptr
       
   159 }
       
   160 
       
   161 // DevInfoListDetailData is a structure for detailed information on a device information set (used for SetupDiGetDeviceInfoListDetail which supersedes the functionality of SetupDiGetDeviceInfoListClass).
       
   162 type DevInfoListDetailData struct {
       
   163 	size                uint32 // Use unsafeSizeOf method
       
   164 	ClassGUID           GUID
       
   165 	RemoteMachineHandle Handle
       
   166 	remoteMachineName   [SP_MAX_MACHINENAME_LENGTH]uint16
       
   167 }
       
   168 
       
   169 func (*DevInfoListDetailData) unsafeSizeOf() uint32 {
       
   170 	if unsafe.Sizeof(uintptr(0)) == 4 {
       
   171 		// Windows declares this with pshpack1.h
       
   172 		return uint32(unsafe.Offsetof(DevInfoListDetailData{}.remoteMachineName) + unsafe.Sizeof(DevInfoListDetailData{}.remoteMachineName))
       
   173 	}
       
   174 	return uint32(unsafe.Sizeof(DevInfoListDetailData{}))
       
   175 }
       
   176 
       
   177 func (data *DevInfoListDetailData) RemoteMachineName() string {
       
   178 	return UTF16ToString(data.remoteMachineName[:])
       
   179 }
       
   180 
       
   181 func (data *DevInfoListDetailData) SetRemoteMachineName(remoteMachineName string) error {
       
   182 	str, err := UTF16FromString(remoteMachineName)
       
   183 	if err != nil {
       
   184 		return err
       
   185 	}
       
   186 	copy(data.remoteMachineName[:], str)
       
   187 	return nil
       
   188 }
       
   189 
       
   190 // DI_FUNCTION is function type for device installer
       
   191 type DI_FUNCTION uint32
       
   192 
       
   193 const (
       
   194 	DIF_SELECTDEVICE                   DI_FUNCTION = 0x00000001
       
   195 	DIF_INSTALLDEVICE                  DI_FUNCTION = 0x00000002
       
   196 	DIF_ASSIGNRESOURCES                DI_FUNCTION = 0x00000003
       
   197 	DIF_PROPERTIES                     DI_FUNCTION = 0x00000004
       
   198 	DIF_REMOVE                         DI_FUNCTION = 0x00000005
       
   199 	DIF_FIRSTTIMESETUP                 DI_FUNCTION = 0x00000006
       
   200 	DIF_FOUNDDEVICE                    DI_FUNCTION = 0x00000007
       
   201 	DIF_SELECTCLASSDRIVERS             DI_FUNCTION = 0x00000008
       
   202 	DIF_VALIDATECLASSDRIVERS           DI_FUNCTION = 0x00000009
       
   203 	DIF_INSTALLCLASSDRIVERS            DI_FUNCTION = 0x0000000A
       
   204 	DIF_CALCDISKSPACE                  DI_FUNCTION = 0x0000000B
       
   205 	DIF_DESTROYPRIVATEDATA             DI_FUNCTION = 0x0000000C
       
   206 	DIF_VALIDATEDRIVER                 DI_FUNCTION = 0x0000000D
       
   207 	DIF_DETECT                         DI_FUNCTION = 0x0000000F
       
   208 	DIF_INSTALLWIZARD                  DI_FUNCTION = 0x00000010
       
   209 	DIF_DESTROYWIZARDDATA              DI_FUNCTION = 0x00000011
       
   210 	DIF_PROPERTYCHANGE                 DI_FUNCTION = 0x00000012
       
   211 	DIF_ENABLECLASS                    DI_FUNCTION = 0x00000013
       
   212 	DIF_DETECTVERIFY                   DI_FUNCTION = 0x00000014
       
   213 	DIF_INSTALLDEVICEFILES             DI_FUNCTION = 0x00000015
       
   214 	DIF_UNREMOVE                       DI_FUNCTION = 0x00000016
       
   215 	DIF_SELECTBESTCOMPATDRV            DI_FUNCTION = 0x00000017
       
   216 	DIF_ALLOW_INSTALL                  DI_FUNCTION = 0x00000018
       
   217 	DIF_REGISTERDEVICE                 DI_FUNCTION = 0x00000019
       
   218 	DIF_NEWDEVICEWIZARD_PRESELECT      DI_FUNCTION = 0x0000001A
       
   219 	DIF_NEWDEVICEWIZARD_SELECT         DI_FUNCTION = 0x0000001B
       
   220 	DIF_NEWDEVICEWIZARD_PREANALYZE     DI_FUNCTION = 0x0000001C
       
   221 	DIF_NEWDEVICEWIZARD_POSTANALYZE    DI_FUNCTION = 0x0000001D
       
   222 	DIF_NEWDEVICEWIZARD_FINISHINSTALL  DI_FUNCTION = 0x0000001E
       
   223 	DIF_INSTALLINTERFACES              DI_FUNCTION = 0x00000020
       
   224 	DIF_DETECTCANCEL                   DI_FUNCTION = 0x00000021
       
   225 	DIF_REGISTER_COINSTALLERS          DI_FUNCTION = 0x00000022
       
   226 	DIF_ADDPROPERTYPAGE_ADVANCED       DI_FUNCTION = 0x00000023
       
   227 	DIF_ADDPROPERTYPAGE_BASIC          DI_FUNCTION = 0x00000024
       
   228 	DIF_TROUBLESHOOTER                 DI_FUNCTION = 0x00000026
       
   229 	DIF_POWERMESSAGEWAKE               DI_FUNCTION = 0x00000027
       
   230 	DIF_ADDREMOTEPROPERTYPAGE_ADVANCED DI_FUNCTION = 0x00000028
       
   231 	DIF_UPDATEDRIVER_UI                DI_FUNCTION = 0x00000029
       
   232 	DIF_FINISHINSTALL_ACTION           DI_FUNCTION = 0x0000002A
       
   233 )
       
   234 
       
   235 // DevInstallParams is device installation parameters structure (associated with a particular device information element, or globally with a device information set)
       
   236 type DevInstallParams struct {
       
   237 	size                     uint32
       
   238 	Flags                    DI_FLAGS
       
   239 	FlagsEx                  DI_FLAGSEX
       
   240 	hwndParent               uintptr
       
   241 	InstallMsgHandler        uintptr
       
   242 	InstallMsgHandlerContext uintptr
       
   243 	FileQueue                HSPFILEQ
       
   244 	_                        uintptr
       
   245 	_                        uint32
       
   246 	driverPath               [MAX_PATH]uint16
       
   247 }
       
   248 
       
   249 func (params *DevInstallParams) DriverPath() string {
       
   250 	return UTF16ToString(params.driverPath[:])
       
   251 }
       
   252 
       
   253 func (params *DevInstallParams) SetDriverPath(driverPath string) error {
       
   254 	str, err := UTF16FromString(driverPath)
       
   255 	if err != nil {
       
   256 		return err
       
   257 	}
       
   258 	copy(params.driverPath[:], str)
       
   259 	return nil
       
   260 }
       
   261 
       
   262 // DI_FLAGS is SP_DEVINSTALL_PARAMS.Flags values
       
   263 type DI_FLAGS uint32
       
   264 
       
   265 const (
       
   266 	// Flags for choosing a device
       
   267 	DI_SHOWOEM       DI_FLAGS = 0x00000001 // support Other... button
       
   268 	DI_SHOWCOMPAT    DI_FLAGS = 0x00000002 // show compatibility list
       
   269 	DI_SHOWCLASS     DI_FLAGS = 0x00000004 // show class list
       
   270 	DI_SHOWALL       DI_FLAGS = 0x00000007 // both class & compat list shown
       
   271 	DI_NOVCP         DI_FLAGS = 0x00000008 // don't create a new copy queue--use caller-supplied FileQueue
       
   272 	DI_DIDCOMPAT     DI_FLAGS = 0x00000010 // Searched for compatible devices
       
   273 	DI_DIDCLASS      DI_FLAGS = 0x00000020 // Searched for class devices
       
   274 	DI_AUTOASSIGNRES DI_FLAGS = 0x00000040 // No UI for resources if possible
       
   275 
       
   276 	// Flags returned by DiInstallDevice to indicate need to reboot/restart
       
   277 	DI_NEEDRESTART DI_FLAGS = 0x00000080 // Reboot required to take effect
       
   278 	DI_NEEDREBOOT  DI_FLAGS = 0x00000100 // ""
       
   279 
       
   280 	// Flags for device installation
       
   281 	DI_NOBROWSE DI_FLAGS = 0x00000200 // no Browse... in InsertDisk
       
   282 
       
   283 	// Flags set by DiBuildDriverInfoList
       
   284 	DI_MULTMFGS DI_FLAGS = 0x00000400 // Set if multiple manufacturers in class driver list
       
   285 
       
   286 	// Flag indicates that device is disabled
       
   287 	DI_DISABLED DI_FLAGS = 0x00000800 // Set if device disabled
       
   288 
       
   289 	// Flags for Device/Class Properties
       
   290 	DI_GENERALPAGE_ADDED  DI_FLAGS = 0x00001000
       
   291 	DI_RESOURCEPAGE_ADDED DI_FLAGS = 0x00002000
       
   292 
       
   293 	// Flag to indicate the setting properties for this Device (or class) caused a change so the Dev Mgr UI probably needs to be updated.
       
   294 	DI_PROPERTIES_CHANGE DI_FLAGS = 0x00004000
       
   295 
       
   296 	// Flag to indicate that the sorting from the INF file should be used.
       
   297 	DI_INF_IS_SORTED DI_FLAGS = 0x00008000
       
   298 
       
   299 	// Flag to indicate that only the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched.
       
   300 	DI_ENUMSINGLEINF DI_FLAGS = 0x00010000
       
   301 
       
   302 	// Flag that prevents ConfigMgr from removing/re-enumerating devices during device
       
   303 	// registration, installation, and deletion.
       
   304 	DI_DONOTCALLCONFIGMG DI_FLAGS = 0x00020000
       
   305 
       
   306 	// The following flag can be used to install a device disabled
       
   307 	DI_INSTALLDISABLED DI_FLAGS = 0x00040000
       
   308 
       
   309 	// Flag that causes SetupDiBuildDriverInfoList to build a device's compatible driver
       
   310 	// list from its existing class driver list, instead of the normal INF search.
       
   311 	DI_COMPAT_FROM_CLASS DI_FLAGS = 0x00080000
       
   312 
       
   313 	// This flag is set if the Class Install params should be used.
       
   314 	DI_CLASSINSTALLPARAMS DI_FLAGS = 0x00100000
       
   315 
       
   316 	// This flag is set if the caller of DiCallClassInstaller does NOT want the internal default action performed if the Class installer returns ERROR_DI_DO_DEFAULT.
       
   317 	DI_NODI_DEFAULTACTION DI_FLAGS = 0x00200000
       
   318 
       
   319 	// Flags for device installation
       
   320 	DI_QUIETINSTALL        DI_FLAGS = 0x00800000 // don't confuse the user with questions or excess info
       
   321 	DI_NOFILECOPY          DI_FLAGS = 0x01000000 // No file Copy necessary
       
   322 	DI_FORCECOPY           DI_FLAGS = 0x02000000 // Force files to be copied from install path
       
   323 	DI_DRIVERPAGE_ADDED    DI_FLAGS = 0x04000000 // Prop provider added Driver page.
       
   324 	DI_USECI_SELECTSTRINGS DI_FLAGS = 0x08000000 // Use Class Installer Provided strings in the Select Device Dlg
       
   325 	DI_OVERRIDE_INFFLAGS   DI_FLAGS = 0x10000000 // Override INF flags
       
   326 	DI_PROPS_NOCHANGEUSAGE DI_FLAGS = 0x20000000 // No Enable/Disable in General Props
       
   327 
       
   328 	DI_NOSELECTICONS DI_FLAGS = 0x40000000 // No small icons in select device dialogs
       
   329 
       
   330 	DI_NOWRITE_IDS DI_FLAGS = 0x80000000 // Don't write HW & Compat IDs on install
       
   331 )
       
   332 
       
   333 // DI_FLAGSEX is SP_DEVINSTALL_PARAMS.FlagsEx values
       
   334 type DI_FLAGSEX uint32
       
   335 
       
   336 const (
       
   337 	DI_FLAGSEX_CI_FAILED                DI_FLAGSEX = 0x00000004 // Failed to Load/Call class installer
       
   338 	DI_FLAGSEX_FINISHINSTALL_ACTION     DI_FLAGSEX = 0x00000008 // Class/co-installer wants to get a DIF_FINISH_INSTALL action in client context.
       
   339 	DI_FLAGSEX_DIDINFOLIST              DI_FLAGSEX = 0x00000010 // Did the Class Info List
       
   340 	DI_FLAGSEX_DIDCOMPATINFO            DI_FLAGSEX = 0x00000020 // Did the Compat Info List
       
   341 	DI_FLAGSEX_FILTERCLASSES            DI_FLAGSEX = 0x00000040
       
   342 	DI_FLAGSEX_SETFAILEDINSTALL         DI_FLAGSEX = 0x00000080
       
   343 	DI_FLAGSEX_DEVICECHANGE             DI_FLAGSEX = 0x00000100
       
   344 	DI_FLAGSEX_ALWAYSWRITEIDS           DI_FLAGSEX = 0x00000200
       
   345 	DI_FLAGSEX_PROPCHANGE_PENDING       DI_FLAGSEX = 0x00000400 // One or more device property sheets have had changes made to them, and need to have a DIF_PROPERTYCHANGE occur.
       
   346 	DI_FLAGSEX_ALLOWEXCLUDEDDRVS        DI_FLAGSEX = 0x00000800
       
   347 	DI_FLAGSEX_NOUIONQUERYREMOVE        DI_FLAGSEX = 0x00001000
       
   348 	DI_FLAGSEX_USECLASSFORCOMPAT        DI_FLAGSEX = 0x00002000 // Use the device's class when building compat drv list. (Ignored if DI_COMPAT_FROM_CLASS flag is specified.)
       
   349 	DI_FLAGSEX_NO_DRVREG_MODIFY         DI_FLAGSEX = 0x00008000 // Don't run AddReg and DelReg for device's software (driver) key.
       
   350 	DI_FLAGSEX_IN_SYSTEM_SETUP          DI_FLAGSEX = 0x00010000 // Installation is occurring during initial system setup.
       
   351 	DI_FLAGSEX_INET_DRIVER              DI_FLAGSEX = 0x00020000 // Driver came from Windows Update
       
   352 	DI_FLAGSEX_APPENDDRIVERLIST         DI_FLAGSEX = 0x00040000 // Cause SetupDiBuildDriverInfoList to append a new driver list to an existing list.
       
   353 	DI_FLAGSEX_PREINSTALLBACKUP         DI_FLAGSEX = 0x00080000 // not used
       
   354 	DI_FLAGSEX_BACKUPONREPLACE          DI_FLAGSEX = 0x00100000 // not used
       
   355 	DI_FLAGSEX_DRIVERLIST_FROM_URL      DI_FLAGSEX = 0x00200000 // build driver list from INF(s) retrieved from URL specified in SP_DEVINSTALL_PARAMS.DriverPath (empty string means Windows Update website)
       
   356 	DI_FLAGSEX_EXCLUDE_OLD_INET_DRIVERS DI_FLAGSEX = 0x00800000 // Don't include old Internet drivers when building a driver list. Ignored on Windows Vista and later.
       
   357 	DI_FLAGSEX_POWERPAGE_ADDED          DI_FLAGSEX = 0x01000000 // class installer added their own power page
       
   358 	DI_FLAGSEX_FILTERSIMILARDRIVERS     DI_FLAGSEX = 0x02000000 // only include similar drivers in class list
       
   359 	DI_FLAGSEX_INSTALLEDDRIVER          DI_FLAGSEX = 0x04000000 // only add the installed driver to the class or compat driver list.  Used in calls to SetupDiBuildDriverInfoList
       
   360 	DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE  DI_FLAGSEX = 0x08000000 // Don't remove identical driver nodes from the class list
       
   361 	DI_FLAGSEX_ALTPLATFORM_DRVSEARCH    DI_FLAGSEX = 0x10000000 // Build driver list based on alternate platform information specified in associated file queue
       
   362 	DI_FLAGSEX_RESTART_DEVICE_ONLY      DI_FLAGSEX = 0x20000000 // only restart the device drivers are being installed on as opposed to restarting all devices using those drivers.
       
   363 	DI_FLAGSEX_RECURSIVESEARCH          DI_FLAGSEX = 0x40000000 // Tell SetupDiBuildDriverInfoList to do a recursive search
       
   364 	DI_FLAGSEX_SEARCH_PUBLISHED_INFS    DI_FLAGSEX = 0x80000000 // Tell SetupDiBuildDriverInfoList to do a "published INF" search
       
   365 )
       
   366 
       
   367 // ClassInstallHeader is the first member of any class install parameters structure. It contains the device installation request code that defines the format of the rest of the install parameters structure.
       
   368 type ClassInstallHeader struct {
       
   369 	size            uint32
       
   370 	InstallFunction DI_FUNCTION
       
   371 }
       
   372 
       
   373 func MakeClassInstallHeader(installFunction DI_FUNCTION) *ClassInstallHeader {
       
   374 	hdr := &ClassInstallHeader{InstallFunction: installFunction}
       
   375 	hdr.size = uint32(unsafe.Sizeof(*hdr))
       
   376 	return hdr
       
   377 }
       
   378 
       
   379 // DICS_STATE specifies values indicating a change in a device's state
       
   380 type DICS_STATE uint32
       
   381 
       
   382 const (
       
   383 	DICS_ENABLE     DICS_STATE = 0x00000001 // The device is being enabled.
       
   384 	DICS_DISABLE    DICS_STATE = 0x00000002 // The device is being disabled.
       
   385 	DICS_PROPCHANGE DICS_STATE = 0x00000003 // The properties of the device have changed.
       
   386 	DICS_START      DICS_STATE = 0x00000004 // The device is being started (if the request is for the currently active hardware profile).
       
   387 	DICS_STOP       DICS_STATE = 0x00000005 // The device is being stopped. The driver stack will be unloaded and the CSCONFIGFLAG_DO_NOT_START flag will be set for the device.
       
   388 )
       
   389 
       
   390 // DICS_FLAG specifies the scope of a device property change
       
   391 type DICS_FLAG uint32
       
   392 
       
   393 const (
       
   394 	DICS_FLAG_GLOBAL         DICS_FLAG = 0x00000001 // make change in all hardware profiles
       
   395 	DICS_FLAG_CONFIGSPECIFIC DICS_FLAG = 0x00000002 // make change in specified profile only
       
   396 	DICS_FLAG_CONFIGGENERAL  DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow (obsolete)
       
   397 )
       
   398 
       
   399 // PropChangeParams is a structure corresponding to a DIF_PROPERTYCHANGE install function.
       
   400 type PropChangeParams struct {
       
   401 	ClassInstallHeader ClassInstallHeader
       
   402 	StateChange        DICS_STATE
       
   403 	Scope              DICS_FLAG
       
   404 	HwProfile          uint32
       
   405 }
       
   406 
       
   407 // DI_REMOVEDEVICE specifies the scope of the device removal
       
   408 type DI_REMOVEDEVICE uint32
       
   409 
       
   410 const (
       
   411 	DI_REMOVEDEVICE_GLOBAL         DI_REMOVEDEVICE = 0x00000001 // Make this change in all hardware profiles. Remove information about the device from the registry.
       
   412 	DI_REMOVEDEVICE_CONFIGSPECIFIC DI_REMOVEDEVICE = 0x00000002 // Make this change to only the hardware profile specified by HwProfile. this flag only applies to root-enumerated devices. When Windows removes the device from the last hardware profile in which it was configured, Windows performs a global removal.
       
   413 )
       
   414 
       
   415 // RemoveDeviceParams is a structure corresponding to a DIF_REMOVE install function.
       
   416 type RemoveDeviceParams struct {
       
   417 	ClassInstallHeader ClassInstallHeader
       
   418 	Scope              DI_REMOVEDEVICE
       
   419 	HwProfile          uint32
       
   420 }
       
   421 
       
   422 // 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)
       
   423 type DrvInfoData struct {
       
   424 	size          uint32
       
   425 	DriverType    uint32
       
   426 	_             uintptr
       
   427 	description   [LINE_LEN]uint16
       
   428 	mfgName       [LINE_LEN]uint16
       
   429 	providerName  [LINE_LEN]uint16
       
   430 	DriverDate    Filetime
       
   431 	DriverVersion uint64
       
   432 }
       
   433 
       
   434 func (data *DrvInfoData) Description() string {
       
   435 	return UTF16ToString(data.description[:])
       
   436 }
       
   437 
       
   438 func (data *DrvInfoData) SetDescription(description string) error {
       
   439 	str, err := UTF16FromString(description)
       
   440 	if err != nil {
       
   441 		return err
       
   442 	}
       
   443 	copy(data.description[:], str)
       
   444 	return nil
       
   445 }
       
   446 
       
   447 func (data *DrvInfoData) MfgName() string {
       
   448 	return UTF16ToString(data.mfgName[:])
       
   449 }
       
   450 
       
   451 func (data *DrvInfoData) SetMfgName(mfgName string) error {
       
   452 	str, err := UTF16FromString(mfgName)
       
   453 	if err != nil {
       
   454 		return err
       
   455 	}
       
   456 	copy(data.mfgName[:], str)
       
   457 	return nil
       
   458 }
       
   459 
       
   460 func (data *DrvInfoData) ProviderName() string {
       
   461 	return UTF16ToString(data.providerName[:])
       
   462 }
       
   463 
       
   464 func (data *DrvInfoData) SetProviderName(providerName string) error {
       
   465 	str, err := UTF16FromString(providerName)
       
   466 	if err != nil {
       
   467 		return err
       
   468 	}
       
   469 	copy(data.providerName[:], str)
       
   470 	return nil
       
   471 }
       
   472 
       
   473 // IsNewer method returns true if DrvInfoData date and version is newer than supplied parameters.
       
   474 func (data *DrvInfoData) IsNewer(driverDate Filetime, driverVersion uint64) bool {
       
   475 	if data.DriverDate.HighDateTime > driverDate.HighDateTime {
       
   476 		return true
       
   477 	}
       
   478 	if data.DriverDate.HighDateTime < driverDate.HighDateTime {
       
   479 		return false
       
   480 	}
       
   481 
       
   482 	if data.DriverDate.LowDateTime > driverDate.LowDateTime {
       
   483 		return true
       
   484 	}
       
   485 	if data.DriverDate.LowDateTime < driverDate.LowDateTime {
       
   486 		return false
       
   487 	}
       
   488 
       
   489 	if data.DriverVersion > driverVersion {
       
   490 		return true
       
   491 	}
       
   492 	if data.DriverVersion < driverVersion {
       
   493 		return false
       
   494 	}
       
   495 
       
   496 	return false
       
   497 }
       
   498 
       
   499 // DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure)
       
   500 type DrvInfoDetailData struct {
       
   501 	size            uint32 // Use unsafeSizeOf method
       
   502 	InfDate         Filetime
       
   503 	compatIDsOffset uint32
       
   504 	compatIDsLength uint32
       
   505 	_               uintptr
       
   506 	sectionName     [LINE_LEN]uint16
       
   507 	infFileName     [MAX_PATH]uint16
       
   508 	drvDescription  [LINE_LEN]uint16
       
   509 	hardwareID      [1]uint16
       
   510 }
       
   511 
       
   512 func (*DrvInfoDetailData) unsafeSizeOf() uint32 {
       
   513 	if unsafe.Sizeof(uintptr(0)) == 4 {
       
   514 		// Windows declares this with pshpack1.h
       
   515 		return uint32(unsafe.Offsetof(DrvInfoDetailData{}.hardwareID) + unsafe.Sizeof(DrvInfoDetailData{}.hardwareID))
       
   516 	}
       
   517 	return uint32(unsafe.Sizeof(DrvInfoDetailData{}))
       
   518 }
       
   519 
       
   520 func (data *DrvInfoDetailData) SectionName() string {
       
   521 	return UTF16ToString(data.sectionName[:])
       
   522 }
       
   523 
       
   524 func (data *DrvInfoDetailData) InfFileName() string {
       
   525 	return UTF16ToString(data.infFileName[:])
       
   526 }
       
   527 
       
   528 func (data *DrvInfoDetailData) DrvDescription() string {
       
   529 	return UTF16ToString(data.drvDescription[:])
       
   530 }
       
   531 
       
   532 func (data *DrvInfoDetailData) HardwareID() string {
       
   533 	if data.compatIDsOffset > 1 {
       
   534 		bufW := data.getBuf()
       
   535 		return UTF16ToString(bufW[:wcslen(bufW)])
       
   536 	}
       
   537 
       
   538 	return ""
       
   539 }
       
   540 
       
   541 func (data *DrvInfoDetailData) CompatIDs() []string {
       
   542 	a := make([]string, 0)
       
   543 
       
   544 	if data.compatIDsLength > 0 {
       
   545 		bufW := data.getBuf()
       
   546 		bufW = bufW[data.compatIDsOffset : data.compatIDsOffset+data.compatIDsLength]
       
   547 		for i := 0; i < len(bufW); {
       
   548 			j := i + wcslen(bufW[i:])
       
   549 			if i < j {
       
   550 				a = append(a, UTF16ToString(bufW[i:j]))
       
   551 			}
       
   552 			i = j + 1
       
   553 		}
       
   554 	}
       
   555 
       
   556 	return a
       
   557 }
       
   558 
       
   559 func (data *DrvInfoDetailData) getBuf() []uint16 {
       
   560 	len := (data.size - uint32(unsafe.Offsetof(data.hardwareID))) / 2
       
   561 	sl := struct {
       
   562 		addr *uint16
       
   563 		len  int
       
   564 		cap  int
       
   565 	}{&data.hardwareID[0], int(len), int(len)}
       
   566 	return *(*[]uint16)(unsafe.Pointer(&sl))
       
   567 }
       
   568 
       
   569 // IsCompatible method tests if given hardware ID matches the driver or is listed on the compatible ID list.
       
   570 func (data *DrvInfoDetailData) IsCompatible(hwid string) bool {
       
   571 	hwidLC := strings.ToLower(hwid)
       
   572 	if strings.ToLower(data.HardwareID()) == hwidLC {
       
   573 		return true
       
   574 	}
       
   575 	a := data.CompatIDs()
       
   576 	for i := range a {
       
   577 		if strings.ToLower(a[i]) == hwidLC {
       
   578 			return true
       
   579 		}
       
   580 	}
       
   581 
       
   582 	return false
       
   583 }
       
   584 
       
   585 // DICD flags control SetupDiCreateDeviceInfo
       
   586 type DICD uint32
       
   587 
       
   588 const (
       
   589 	DICD_GENERATE_ID       DICD = 0x00000001
       
   590 	DICD_INHERIT_CLASSDRVS DICD = 0x00000002
       
   591 )
       
   592 
       
   593 // SUOI flags control SetupUninstallOEMInf
       
   594 type SUOI uint32
       
   595 
       
   596 const (
       
   597 	SUOI_FORCEDELETE SUOI = 0x0001
       
   598 )
       
   599 
       
   600 // SPDIT flags to distinguish between class drivers and
       
   601 // device drivers. (Passed in 'DriverType' parameter of
       
   602 // driver information list APIs)
       
   603 type SPDIT uint32
       
   604 
       
   605 const (
       
   606 	SPDIT_NODRIVER     SPDIT = 0x00000000
       
   607 	SPDIT_CLASSDRIVER  SPDIT = 0x00000001
       
   608 	SPDIT_COMPATDRIVER SPDIT = 0x00000002
       
   609 )
       
   610 
       
   611 // DIGCF flags control what is included in the device information set built by SetupDiGetClassDevs
       
   612 type DIGCF uint32
       
   613 
       
   614 const (
       
   615 	DIGCF_DEFAULT         DIGCF = 0x00000001 // only valid with DIGCF_DEVICEINTERFACE
       
   616 	DIGCF_PRESENT         DIGCF = 0x00000002
       
   617 	DIGCF_ALLCLASSES      DIGCF = 0x00000004
       
   618 	DIGCF_PROFILE         DIGCF = 0x00000008
       
   619 	DIGCF_DEVICEINTERFACE DIGCF = 0x00000010
       
   620 )
       
   621 
       
   622 // DIREG specifies values for SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and SetupDiDeleteDevRegKey.
       
   623 type DIREG uint32
       
   624 
       
   625 const (
       
   626 	DIREG_DEV  DIREG = 0x00000001 // Open/Create/Delete device key
       
   627 	DIREG_DRV  DIREG = 0x00000002 // Open/Create/Delete driver key
       
   628 	DIREG_BOTH DIREG = 0x00000004 // Delete both driver and Device key
       
   629 )
       
   630 
       
   631 // SPDRP specifies device registry property codes
       
   632 // (Codes marked as read-only (R) may only be used for
       
   633 // SetupDiGetDeviceRegistryProperty)
       
   634 //
       
   635 // These values should cover the same set of registry properties
       
   636 // as defined by the CM_DRP codes in cfgmgr32.h.
       
   637 //
       
   638 // Note that SPDRP codes are zero based while CM_DRP codes are one based!
       
   639 type SPDRP uint32
       
   640 
       
   641 const (
       
   642 	SPDRP_DEVICEDESC                  SPDRP = 0x00000000 // DeviceDesc (R/W)
       
   643 	SPDRP_HARDWAREID                  SPDRP = 0x00000001 // HardwareID (R/W)
       
   644 	SPDRP_COMPATIBLEIDS               SPDRP = 0x00000002 // CompatibleIDs (R/W)
       
   645 	SPDRP_SERVICE                     SPDRP = 0x00000004 // Service (R/W)
       
   646 	SPDRP_CLASS                       SPDRP = 0x00000007 // Class (R--tied to ClassGUID)
       
   647 	SPDRP_CLASSGUID                   SPDRP = 0x00000008 // ClassGUID (R/W)
       
   648 	SPDRP_DRIVER                      SPDRP = 0x00000009 // Driver (R/W)
       
   649 	SPDRP_CONFIGFLAGS                 SPDRP = 0x0000000A // ConfigFlags (R/W)
       
   650 	SPDRP_MFG                         SPDRP = 0x0000000B // Mfg (R/W)
       
   651 	SPDRP_FRIENDLYNAME                SPDRP = 0x0000000C // FriendlyName (R/W)
       
   652 	SPDRP_LOCATION_INFORMATION        SPDRP = 0x0000000D // LocationInformation (R/W)
       
   653 	SPDRP_PHYSICAL_DEVICE_OBJECT_NAME SPDRP = 0x0000000E // PhysicalDeviceObjectName (R)
       
   654 	SPDRP_CAPABILITIES                SPDRP = 0x0000000F // Capabilities (R)
       
   655 	SPDRP_UI_NUMBER                   SPDRP = 0x00000010 // UiNumber (R)
       
   656 	SPDRP_UPPERFILTERS                SPDRP = 0x00000011 // UpperFilters (R/W)
       
   657 	SPDRP_LOWERFILTERS                SPDRP = 0x00000012 // LowerFilters (R/W)
       
   658 	SPDRP_BUSTYPEGUID                 SPDRP = 0x00000013 // BusTypeGUID (R)
       
   659 	SPDRP_LEGACYBUSTYPE               SPDRP = 0x00000014 // LegacyBusType (R)
       
   660 	SPDRP_BUSNUMBER                   SPDRP = 0x00000015 // BusNumber (R)
       
   661 	SPDRP_ENUMERATOR_NAME             SPDRP = 0x00000016 // Enumerator Name (R)
       
   662 	SPDRP_SECURITY                    SPDRP = 0x00000017 // Security (R/W, binary form)
       
   663 	SPDRP_SECURITY_SDS                SPDRP = 0x00000018 // Security (W, SDS form)
       
   664 	SPDRP_DEVTYPE                     SPDRP = 0x00000019 // Device Type (R/W)
       
   665 	SPDRP_EXCLUSIVE                   SPDRP = 0x0000001A // Device is exclusive-access (R/W)
       
   666 	SPDRP_CHARACTERISTICS             SPDRP = 0x0000001B // Device Characteristics (R/W)
       
   667 	SPDRP_ADDRESS                     SPDRP = 0x0000001C // Device Address (R)
       
   668 	SPDRP_UI_NUMBER_DESC_FORMAT       SPDRP = 0x0000001D // UiNumberDescFormat (R/W)
       
   669 	SPDRP_DEVICE_POWER_DATA           SPDRP = 0x0000001E // Device Power Data (R)
       
   670 	SPDRP_REMOVAL_POLICY              SPDRP = 0x0000001F // Removal Policy (R)
       
   671 	SPDRP_REMOVAL_POLICY_HW_DEFAULT   SPDRP = 0x00000020 // Hardware Removal Policy (R)
       
   672 	SPDRP_REMOVAL_POLICY_OVERRIDE     SPDRP = 0x00000021 // Removal Policy Override (RW)
       
   673 	SPDRP_INSTALL_STATE               SPDRP = 0x00000022 // Device Install State (R)
       
   674 	SPDRP_LOCATION_PATHS              SPDRP = 0x00000023 // Device Location Paths (R)
       
   675 	SPDRP_BASE_CONTAINERID            SPDRP = 0x00000024 // Base ContainerID (R)
       
   676 
       
   677 	SPDRP_MAXIMUM_PROPERTY SPDRP = 0x00000025 // Upper bound on ordinals
       
   678 )
       
   679 
       
   680 // DEVPROPTYPE represents the property-data-type identifier that specifies the
       
   681 // data type of a device property value in the unified device property model.
       
   682 type DEVPROPTYPE uint32
       
   683 
       
   684 const (
       
   685 	DEVPROP_TYPEMOD_ARRAY DEVPROPTYPE = 0x00001000
       
   686 	DEVPROP_TYPEMOD_LIST  DEVPROPTYPE = 0x00002000
       
   687 
       
   688 	DEVPROP_TYPE_EMPTY                      DEVPROPTYPE = 0x00000000
       
   689 	DEVPROP_TYPE_NULL                       DEVPROPTYPE = 0x00000001
       
   690 	DEVPROP_TYPE_SBYTE                      DEVPROPTYPE = 0x00000002
       
   691 	DEVPROP_TYPE_BYTE                       DEVPROPTYPE = 0x00000003
       
   692 	DEVPROP_TYPE_INT16                      DEVPROPTYPE = 0x00000004
       
   693 	DEVPROP_TYPE_UINT16                     DEVPROPTYPE = 0x00000005
       
   694 	DEVPROP_TYPE_INT32                      DEVPROPTYPE = 0x00000006
       
   695 	DEVPROP_TYPE_UINT32                     DEVPROPTYPE = 0x00000007
       
   696 	DEVPROP_TYPE_INT64                      DEVPROPTYPE = 0x00000008
       
   697 	DEVPROP_TYPE_UINT64                     DEVPROPTYPE = 0x00000009
       
   698 	DEVPROP_TYPE_FLOAT                      DEVPROPTYPE = 0x0000000A
       
   699 	DEVPROP_TYPE_DOUBLE                     DEVPROPTYPE = 0x0000000B
       
   700 	DEVPROP_TYPE_DECIMAL                    DEVPROPTYPE = 0x0000000C
       
   701 	DEVPROP_TYPE_GUID                       DEVPROPTYPE = 0x0000000D
       
   702 	DEVPROP_TYPE_CURRENCY                   DEVPROPTYPE = 0x0000000E
       
   703 	DEVPROP_TYPE_DATE                       DEVPROPTYPE = 0x0000000F
       
   704 	DEVPROP_TYPE_FILETIME                   DEVPROPTYPE = 0x00000010
       
   705 	DEVPROP_TYPE_BOOLEAN                    DEVPROPTYPE = 0x00000011
       
   706 	DEVPROP_TYPE_STRING                     DEVPROPTYPE = 0x00000012
       
   707 	DEVPROP_TYPE_STRING_LIST                DEVPROPTYPE = DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST
       
   708 	DEVPROP_TYPE_SECURITY_DESCRIPTOR        DEVPROPTYPE = 0x00000013
       
   709 	DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING DEVPROPTYPE = 0x00000014
       
   710 	DEVPROP_TYPE_DEVPROPKEY                 DEVPROPTYPE = 0x00000015
       
   711 	DEVPROP_TYPE_DEVPROPTYPE                DEVPROPTYPE = 0x00000016
       
   712 	DEVPROP_TYPE_BINARY                     DEVPROPTYPE = DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY
       
   713 	DEVPROP_TYPE_ERROR                      DEVPROPTYPE = 0x00000017
       
   714 	DEVPROP_TYPE_NTSTATUS                   DEVPROPTYPE = 0x00000018
       
   715 	DEVPROP_TYPE_STRING_INDIRECT            DEVPROPTYPE = 0x00000019
       
   716 
       
   717 	MAX_DEVPROP_TYPE    DEVPROPTYPE = 0x00000019
       
   718 	MAX_DEVPROP_TYPEMOD DEVPROPTYPE = 0x00002000
       
   719 
       
   720 	DEVPROP_MASK_TYPE    DEVPROPTYPE = 0x00000FFF
       
   721 	DEVPROP_MASK_TYPEMOD DEVPROPTYPE = 0x0000F000
       
   722 )
       
   723 
       
   724 // DEVPROPGUID specifies a property category.
       
   725 type DEVPROPGUID GUID
       
   726 
       
   727 // DEVPROPID uniquely identifies the property within the property category.
       
   728 type DEVPROPID uint32
       
   729 
       
   730 const DEVPROPID_FIRST_USABLE DEVPROPID = 2
       
   731 
       
   732 // DEVPROPKEY represents a device property key for a device property in the
       
   733 // unified device property model.
       
   734 type DEVPROPKEY struct {
       
   735 	FmtID DEVPROPGUID
       
   736 	PID   DEVPROPID
       
   737 }
       
   738 
       
   739 // CONFIGRET is a return value or error code from cfgmgr32 APIs
       
   740 type CONFIGRET uint32
       
   741 
       
   742 func (ret CONFIGRET) Error() string {
       
   743 	if win32Error, ok := ret.Unwrap().(Errno); ok {
       
   744 		return fmt.Sprintf("%s (CfgMgr error: 0x%08x)", win32Error.Error(), uint32(ret))
       
   745 	}
       
   746 	return fmt.Sprintf("CfgMgr error: 0x%08x", uint32(ret))
       
   747 }
       
   748 
       
   749 func (ret CONFIGRET) Win32Error(defaultError Errno) Errno {
       
   750 	return cm_MapCrToWin32Err(ret, defaultError)
       
   751 }
       
   752 
       
   753 func (ret CONFIGRET) Unwrap() error {
       
   754 	const noMatch = Errno(^uintptr(0))
       
   755 	win32Error := ret.Win32Error(noMatch)
       
   756 	if win32Error == noMatch {
       
   757 		return nil
       
   758 	}
       
   759 	return win32Error
       
   760 }
       
   761 
       
   762 const (
       
   763 	CR_SUCCESS                  CONFIGRET = 0x00000000
       
   764 	CR_DEFAULT                  CONFIGRET = 0x00000001
       
   765 	CR_OUT_OF_MEMORY            CONFIGRET = 0x00000002
       
   766 	CR_INVALID_POINTER          CONFIGRET = 0x00000003
       
   767 	CR_INVALID_FLAG             CONFIGRET = 0x00000004
       
   768 	CR_INVALID_DEVNODE          CONFIGRET = 0x00000005
       
   769 	CR_INVALID_DEVINST                    = CR_INVALID_DEVNODE
       
   770 	CR_INVALID_RES_DES          CONFIGRET = 0x00000006
       
   771 	CR_INVALID_LOG_CONF         CONFIGRET = 0x00000007
       
   772 	CR_INVALID_ARBITRATOR       CONFIGRET = 0x00000008
       
   773 	CR_INVALID_NODELIST         CONFIGRET = 0x00000009
       
   774 	CR_DEVNODE_HAS_REQS         CONFIGRET = 0x0000000A
       
   775 	CR_DEVINST_HAS_REQS                   = CR_DEVNODE_HAS_REQS
       
   776 	CR_INVALID_RESOURCEID       CONFIGRET = 0x0000000B
       
   777 	CR_DLVXD_NOT_FOUND          CONFIGRET = 0x0000000C
       
   778 	CR_NO_SUCH_DEVNODE          CONFIGRET = 0x0000000D
       
   779 	CR_NO_SUCH_DEVINST                    = CR_NO_SUCH_DEVNODE
       
   780 	CR_NO_MORE_LOG_CONF         CONFIGRET = 0x0000000E
       
   781 	CR_NO_MORE_RES_DES          CONFIGRET = 0x0000000F
       
   782 	CR_ALREADY_SUCH_DEVNODE     CONFIGRET = 0x00000010
       
   783 	CR_ALREADY_SUCH_DEVINST               = CR_ALREADY_SUCH_DEVNODE
       
   784 	CR_INVALID_RANGE_LIST       CONFIGRET = 0x00000011
       
   785 	CR_INVALID_RANGE            CONFIGRET = 0x00000012
       
   786 	CR_FAILURE                  CONFIGRET = 0x00000013
       
   787 	CR_NO_SUCH_LOGICAL_DEV      CONFIGRET = 0x00000014
       
   788 	CR_CREATE_BLOCKED           CONFIGRET = 0x00000015
       
   789 	CR_NOT_SYSTEM_VM            CONFIGRET = 0x00000016
       
   790 	CR_REMOVE_VETOED            CONFIGRET = 0x00000017
       
   791 	CR_APM_VETOED               CONFIGRET = 0x00000018
       
   792 	CR_INVALID_LOAD_TYPE        CONFIGRET = 0x00000019
       
   793 	CR_BUFFER_SMALL             CONFIGRET = 0x0000001A
       
   794 	CR_NO_ARBITRATOR            CONFIGRET = 0x0000001B
       
   795 	CR_NO_REGISTRY_HANDLE       CONFIGRET = 0x0000001C
       
   796 	CR_REGISTRY_ERROR           CONFIGRET = 0x0000001D
       
   797 	CR_INVALID_DEVICE_ID        CONFIGRET = 0x0000001E
       
   798 	CR_INVALID_DATA             CONFIGRET = 0x0000001F
       
   799 	CR_INVALID_API              CONFIGRET = 0x00000020
       
   800 	CR_DEVLOADER_NOT_READY      CONFIGRET = 0x00000021
       
   801 	CR_NEED_RESTART             CONFIGRET = 0x00000022
       
   802 	CR_NO_MORE_HW_PROFILES      CONFIGRET = 0x00000023
       
   803 	CR_DEVICE_NOT_THERE         CONFIGRET = 0x00000024
       
   804 	CR_NO_SUCH_VALUE            CONFIGRET = 0x00000025
       
   805 	CR_WRONG_TYPE               CONFIGRET = 0x00000026
       
   806 	CR_INVALID_PRIORITY         CONFIGRET = 0x00000027
       
   807 	CR_NOT_DISABLEABLE          CONFIGRET = 0x00000028
       
   808 	CR_FREE_RESOURCES           CONFIGRET = 0x00000029
       
   809 	CR_QUERY_VETOED             CONFIGRET = 0x0000002A
       
   810 	CR_CANT_SHARE_IRQ           CONFIGRET = 0x0000002B
       
   811 	CR_NO_DEPENDENT             CONFIGRET = 0x0000002C
       
   812 	CR_SAME_RESOURCES           CONFIGRET = 0x0000002D
       
   813 	CR_NO_SUCH_REGISTRY_KEY     CONFIGRET = 0x0000002E
       
   814 	CR_INVALID_MACHINENAME      CONFIGRET = 0x0000002F
       
   815 	CR_REMOTE_COMM_FAILURE      CONFIGRET = 0x00000030
       
   816 	CR_MACHINE_UNAVAILABLE      CONFIGRET = 0x00000031
       
   817 	CR_NO_CM_SERVICES           CONFIGRET = 0x00000032
       
   818 	CR_ACCESS_DENIED            CONFIGRET = 0x00000033
       
   819 	CR_CALL_NOT_IMPLEMENTED     CONFIGRET = 0x00000034
       
   820 	CR_INVALID_PROPERTY         CONFIGRET = 0x00000035
       
   821 	CR_DEVICE_INTERFACE_ACTIVE  CONFIGRET = 0x00000036
       
   822 	CR_NO_SUCH_DEVICE_INTERFACE CONFIGRET = 0x00000037
       
   823 	CR_INVALID_REFERENCE_STRING CONFIGRET = 0x00000038
       
   824 	CR_INVALID_CONFLICT_LIST    CONFIGRET = 0x00000039
       
   825 	CR_INVALID_INDEX            CONFIGRET = 0x0000003A
       
   826 	CR_INVALID_STRUCTURE_SIZE   CONFIGRET = 0x0000003B
       
   827 	NUM_CR_RESULTS              CONFIGRET = 0x0000003C
       
   828 )
       
   829 
       
   830 const (
       
   831 	CM_GET_DEVICE_INTERFACE_LIST_PRESENT     = 0 // only currently 'live' device interfaces
       
   832 	CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES = 1 // all registered device interfaces, live or not
       
   833 )
       
   834 
       
   835 const (
       
   836 	DN_ROOT_ENUMERATED       = 0x00000001        // Was enumerated by ROOT
       
   837 	DN_DRIVER_LOADED         = 0x00000002        // Has Register_Device_Driver
       
   838 	DN_ENUM_LOADED           = 0x00000004        // Has Register_Enumerator
       
   839 	DN_STARTED               = 0x00000008        // Is currently configured
       
   840 	DN_MANUAL                = 0x00000010        // Manually installed
       
   841 	DN_NEED_TO_ENUM          = 0x00000020        // May need reenumeration
       
   842 	DN_NOT_FIRST_TIME        = 0x00000040        // Has received a config
       
   843 	DN_HARDWARE_ENUM         = 0x00000080        // Enum generates hardware ID
       
   844 	DN_LIAR                  = 0x00000100        // Lied about can reconfig once
       
   845 	DN_HAS_MARK              = 0x00000200        // Not CM_Create_DevInst lately
       
   846 	DN_HAS_PROBLEM           = 0x00000400        // Need device installer
       
   847 	DN_FILTERED              = 0x00000800        // Is filtered
       
   848 	DN_MOVED                 = 0x00001000        // Has been moved
       
   849 	DN_DISABLEABLE           = 0x00002000        // Can be disabled
       
   850 	DN_REMOVABLE             = 0x00004000        // Can be removed
       
   851 	DN_PRIVATE_PROBLEM       = 0x00008000        // Has a private problem
       
   852 	DN_MF_PARENT             = 0x00010000        // Multi function parent
       
   853 	DN_MF_CHILD              = 0x00020000        // Multi function child
       
   854 	DN_WILL_BE_REMOVED       = 0x00040000        // DevInst is being removed
       
   855 	DN_NOT_FIRST_TIMEE       = 0x00080000        // Has received a config enumerate
       
   856 	DN_STOP_FREE_RES         = 0x00100000        // When child is stopped, free resources
       
   857 	DN_REBAL_CANDIDATE       = 0x00200000        // Don't skip during rebalance
       
   858 	DN_BAD_PARTIAL           = 0x00400000        // This devnode's log_confs do not have same resources
       
   859 	DN_NT_ENUMERATOR         = 0x00800000        // This devnode's is an NT enumerator
       
   860 	DN_NT_DRIVER             = 0x01000000        // This devnode's is an NT driver
       
   861 	DN_NEEDS_LOCKING         = 0x02000000        // Devnode need lock resume processing
       
   862 	DN_ARM_WAKEUP            = 0x04000000        // Devnode can be the wakeup device
       
   863 	DN_APM_ENUMERATOR        = 0x08000000        // APM aware enumerator
       
   864 	DN_APM_DRIVER            = 0x10000000        // APM aware driver
       
   865 	DN_SILENT_INSTALL        = 0x20000000        // Silent install
       
   866 	DN_NO_SHOW_IN_DM         = 0x40000000        // No show in device manager
       
   867 	DN_BOOT_LOG_PROB         = 0x80000000        // Had a problem during preassignment of boot log conf
       
   868 	DN_NEED_RESTART          = DN_LIAR           // System needs to be restarted for this Devnode to work properly
       
   869 	DN_DRIVER_BLOCKED        = DN_NOT_FIRST_TIME // One or more drivers are blocked from loading for this Devnode
       
   870 	DN_LEGACY_DRIVER         = DN_MOVED          // This device is using a legacy driver
       
   871 	DN_CHILD_WITH_INVALID_ID = DN_HAS_MARK       // One or more children have invalid IDs
       
   872 	DN_DEVICE_DISCONNECTED   = DN_NEEDS_LOCKING  // The function driver for a device reported that the device is not connected.  Typically this means a wireless device is out of range.
       
   873 	DN_QUERY_REMOVE_PENDING  = DN_MF_PARENT      // Device is part of a set of related devices collectively pending query-removal
       
   874 	DN_QUERY_REMOVE_ACTIVE   = DN_MF_CHILD       // Device is actively engaged in a query-remove IRP
       
   875 	DN_CHANGEABLE_FLAGS      = DN_NOT_FIRST_TIME | DN_HARDWARE_ENUM | DN_HAS_MARK | DN_DISABLEABLE | DN_REMOVABLE | DN_MF_CHILD | DN_MF_PARENT | DN_NOT_FIRST_TIMEE | DN_STOP_FREE_RES | DN_REBAL_CANDIDATE | DN_NT_ENUMERATOR | DN_NT_DRIVER | DN_SILENT_INSTALL | DN_NO_SHOW_IN_DM
       
   876 )
       
   877 
       
   878 //sys	setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(InvalidHandle)] = setupapi.SetupDiCreateDeviceInfoListExW
       
   879 
       
   880 // 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.
       
   881 func SetupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName string) (deviceInfoSet DevInfo, err error) {
       
   882 	var machineNameUTF16 *uint16
       
   883 	if machineName != "" {
       
   884 		machineNameUTF16, err = UTF16PtrFromString(machineName)
       
   885 		if err != nil {
       
   886 			return
       
   887 		}
       
   888 	}
       
   889 	return setupDiCreateDeviceInfoListEx(classGUID, hwndParent, machineNameUTF16, 0)
       
   890 }
       
   891 
       
   892 //sys	setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) = setupapi.SetupDiGetDeviceInfoListDetailW
       
   893 
       
   894 // SetupDiGetDeviceInfoListDetail function retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name.
       
   895 func SetupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo) (deviceInfoSetDetailData *DevInfoListDetailData, err error) {
       
   896 	data := &DevInfoListDetailData{}
       
   897 	data.size = data.unsafeSizeOf()
       
   898 
       
   899 	return data, setupDiGetDeviceInfoListDetail(deviceInfoSet, data)
       
   900 }
       
   901 
       
   902 // DeviceInfoListDetail method retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name.
       
   903 func (deviceInfoSet DevInfo) DeviceInfoListDetail() (*DevInfoListDetailData, error) {
       
   904 	return SetupDiGetDeviceInfoListDetail(deviceInfoSet)
       
   905 }
       
   906 
       
   907 //sys	setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCreateDeviceInfoW
       
   908 
       
   909 // SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the specified device information set.
       
   910 func SetupDiCreateDeviceInfo(deviceInfoSet DevInfo, deviceName string, classGUID *GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (deviceInfoData *DevInfoData, err error) {
       
   911 	deviceNameUTF16, err := UTF16PtrFromString(deviceName)
       
   912 	if err != nil {
       
   913 		return
       
   914 	}
       
   915 
       
   916 	var deviceDescriptionUTF16 *uint16
       
   917 	if deviceDescription != "" {
       
   918 		deviceDescriptionUTF16, err = UTF16PtrFromString(deviceDescription)
       
   919 		if err != nil {
       
   920 			return
       
   921 		}
       
   922 	}
       
   923 
       
   924 	data := &DevInfoData{}
       
   925 	data.size = uint32(unsafe.Sizeof(*data))
       
   926 
       
   927 	return data, setupDiCreateDeviceInfo(deviceInfoSet, deviceNameUTF16, classGUID, deviceDescriptionUTF16, hwndParent, creationFlags, data)
       
   928 }
       
   929 
       
   930 // CreateDeviceInfo method creates a new device information element and adds it as a new member to the specified device information set.
       
   931 func (deviceInfoSet DevInfo) CreateDeviceInfo(deviceName string, classGUID *GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (*DevInfoData, error) {
       
   932 	return SetupDiCreateDeviceInfo(deviceInfoSet, deviceName, classGUID, deviceDescription, hwndParent, creationFlags)
       
   933 }
       
   934 
       
   935 //sys	setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiEnumDeviceInfo
       
   936 
       
   937 // SetupDiEnumDeviceInfo function returns a DevInfoData structure that specifies a device information element in a device information set.
       
   938 func SetupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex int) (*DevInfoData, error) {
       
   939 	data := &DevInfoData{}
       
   940 	data.size = uint32(unsafe.Sizeof(*data))
       
   941 
       
   942 	return data, setupDiEnumDeviceInfo(deviceInfoSet, uint32(memberIndex), data)
       
   943 }
       
   944 
       
   945 // EnumDeviceInfo method returns a DevInfoData structure that specifies a device information element in a device information set.
       
   946 func (deviceInfoSet DevInfo) EnumDeviceInfo(memberIndex int) (*DevInfoData, error) {
       
   947 	return SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex)
       
   948 }
       
   949 
       
   950 // SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory.
       
   951 //sys	SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiDestroyDeviceInfoList
       
   952 
       
   953 // Close method deletes a device information set and frees all associated memory.
       
   954 func (deviceInfoSet DevInfo) Close() error {
       
   955 	return SetupDiDestroyDeviceInfoList(deviceInfoSet)
       
   956 }
       
   957 
       
   958 //sys	SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiBuildDriverInfoList
       
   959 
       
   960 // 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.
       
   961 func (deviceInfoSet DevInfo) BuildDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error {
       
   962 	return SetupDiBuildDriverInfoList(deviceInfoSet, deviceInfoData, driverType)
       
   963 }
       
   964 
       
   965 //sys	SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiCancelDriverInfoSearch
       
   966 
       
   967 // CancelDriverInfoSearch method cancels a driver list search that is currently in progress in a different thread.
       
   968 func (deviceInfoSet DevInfo) CancelDriverInfoSearch() error {
       
   969 	return SetupDiCancelDriverInfoSearch(deviceInfoSet)
       
   970 }
       
   971 
       
   972 //sys	setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiEnumDriverInfoW
       
   973 
       
   974 // SetupDiEnumDriverInfo function enumerates the members of a driver list.
       
   975 func SetupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) {
       
   976 	data := &DrvInfoData{}
       
   977 	data.size = uint32(unsafe.Sizeof(*data))
       
   978 
       
   979 	return data, setupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, uint32(memberIndex), data)
       
   980 }
       
   981 
       
   982 // EnumDriverInfo method enumerates the members of a driver list.
       
   983 func (deviceInfoSet DevInfo) EnumDriverInfo(deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) {
       
   984 	return SetupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, memberIndex)
       
   985 }
       
   986 
       
   987 //sys	setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiGetSelectedDriverW
       
   988 
       
   989 // SetupDiGetSelectedDriver function retrieves the selected driver for a device information set or a particular device information element.
       
   990 func SetupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DrvInfoData, error) {
       
   991 	data := &DrvInfoData{}
       
   992 	data.size = uint32(unsafe.Sizeof(*data))
       
   993 
       
   994 	return data, setupDiGetSelectedDriver(deviceInfoSet, deviceInfoData, data)
       
   995 }
       
   996 
       
   997 // SelectedDriver method retrieves the selected driver for a device information set or a particular device information element.
       
   998 func (deviceInfoSet DevInfo) SelectedDriver(deviceInfoData *DevInfoData) (*DrvInfoData, error) {
       
   999 	return SetupDiGetSelectedDriver(deviceInfoSet, deviceInfoData)
       
  1000 }
       
  1001 
       
  1002 //sys	SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiSetSelectedDriverW
       
  1003 
       
  1004 // SetSelectedDriver method sets, or resets, the selected driver for a device information element or the selected class driver for a device information set.
       
  1005 func (deviceInfoSet DevInfo) SetSelectedDriver(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) error {
       
  1006 	return SetupDiSetSelectedDriver(deviceInfoSet, deviceInfoData, driverInfoData)
       
  1007 }
       
  1008 
       
  1009 //sys	setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW
       
  1010 
       
  1011 // SetupDiGetDriverInfoDetail function retrieves driver information detail for a device information set or a particular device information element in the device information set.
       
  1012 func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) {
       
  1013 	reqSize := uint32(2048)
       
  1014 	for {
       
  1015 		buf := make([]byte, reqSize)
       
  1016 		data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
       
  1017 		data.size = data.unsafeSizeOf()
       
  1018 		err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, uint32(len(buf)), &reqSize)
       
  1019 		if err == ERROR_INSUFFICIENT_BUFFER {
       
  1020 			continue
       
  1021 		}
       
  1022 		if err != nil {
       
  1023 			return nil, err
       
  1024 		}
       
  1025 		data.size = reqSize
       
  1026 		return data, nil
       
  1027 	}
       
  1028 }
       
  1029 
       
  1030 // DriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set.
       
  1031 func (deviceInfoSet DevInfo) DriverInfoDetail(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) {
       
  1032 	return SetupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData)
       
  1033 }
       
  1034 
       
  1035 //sys	SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiDestroyDriverInfoList
       
  1036 
       
  1037 // DestroyDriverInfoList method deletes a driver list.
       
  1038 func (deviceInfoSet DevInfo) DestroyDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error {
       
  1039 	return SetupDiDestroyDriverInfoList(deviceInfoSet, deviceInfoData, driverType)
       
  1040 }
       
  1041 
       
  1042 //sys	setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(InvalidHandle)] = setupapi.SetupDiGetClassDevsExW
       
  1043 
       
  1044 // SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer.
       
  1045 func SetupDiGetClassDevsEx(classGUID *GUID, enumerator string, hwndParent uintptr, flags DIGCF, deviceInfoSet DevInfo, machineName string) (handle DevInfo, err error) {
       
  1046 	var enumeratorUTF16 *uint16
       
  1047 	if enumerator != "" {
       
  1048 		enumeratorUTF16, err = UTF16PtrFromString(enumerator)
       
  1049 		if err != nil {
       
  1050 			return
       
  1051 		}
       
  1052 	}
       
  1053 	var machineNameUTF16 *uint16
       
  1054 	if machineName != "" {
       
  1055 		machineNameUTF16, err = UTF16PtrFromString(machineName)
       
  1056 		if err != nil {
       
  1057 			return
       
  1058 		}
       
  1059 	}
       
  1060 	return setupDiGetClassDevsEx(classGUID, enumeratorUTF16, hwndParent, flags, deviceInfoSet, machineNameUTF16, 0)
       
  1061 }
       
  1062 
       
  1063 // SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code).
       
  1064 //sys	SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCallClassInstaller
       
  1065 
       
  1066 // CallClassInstaller member calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code).
       
  1067 func (deviceInfoSet DevInfo) CallClassInstaller(installFunction DI_FUNCTION, deviceInfoData *DevInfoData) error {
       
  1068 	return SetupDiCallClassInstaller(installFunction, deviceInfoSet, deviceInfoData)
       
  1069 }
       
  1070 
       
  1071 // SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information.
       
  1072 //sys	SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key Handle, err error) [failretval==InvalidHandle] = setupapi.SetupDiOpenDevRegKey
       
  1073 
       
  1074 // OpenDevRegKey method opens a registry key for device-specific configuration information.
       
  1075 func (deviceInfoSet DevInfo) OpenDevRegKey(DeviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (Handle, error) {
       
  1076 	return SetupDiOpenDevRegKey(deviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired)
       
  1077 }
       
  1078 
       
  1079 //sys	setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY, propertyType *DEVPROPTYPE, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32, flags uint32) (err error) = setupapi.SetupDiGetDevicePropertyW
       
  1080 
       
  1081 // SetupDiGetDeviceProperty function retrieves a specified device instance property.
       
  1082 func SetupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY) (value interface{}, err error) {
       
  1083 	reqSize := uint32(256)
       
  1084 	for {
       
  1085 		var dataType DEVPROPTYPE
       
  1086 		buf := make([]byte, reqSize)
       
  1087 		err = setupDiGetDeviceProperty(deviceInfoSet, deviceInfoData, propertyKey, &dataType, &buf[0], uint32(len(buf)), &reqSize, 0)
       
  1088 		if err == ERROR_INSUFFICIENT_BUFFER {
       
  1089 			continue
       
  1090 		}
       
  1091 		if err != nil {
       
  1092 			return
       
  1093 		}
       
  1094 		switch dataType {
       
  1095 		case DEVPROP_TYPE_STRING:
       
  1096 			ret := UTF16ToString(bufToUTF16(buf))
       
  1097 			runtime.KeepAlive(buf)
       
  1098 			return ret, nil
       
  1099 		}
       
  1100 		return nil, errors.New("unimplemented property type")
       
  1101 	}
       
  1102 }
       
  1103 
       
  1104 //sys	setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceRegistryPropertyW
       
  1105 
       
  1106 // SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
       
  1107 func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP) (value interface{}, err error) {
       
  1108 	reqSize := uint32(256)
       
  1109 	for {
       
  1110 		var dataType uint32
       
  1111 		buf := make([]byte, reqSize)
       
  1112 		err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(len(buf)), &reqSize)
       
  1113 		if err == ERROR_INSUFFICIENT_BUFFER {
       
  1114 			continue
       
  1115 		}
       
  1116 		if err != nil {
       
  1117 			return
       
  1118 		}
       
  1119 		return getRegistryValue(buf[:reqSize], dataType)
       
  1120 	}
       
  1121 }
       
  1122 
       
  1123 func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
       
  1124 	switch dataType {
       
  1125 	case REG_SZ:
       
  1126 		ret := UTF16ToString(bufToUTF16(buf))
       
  1127 		runtime.KeepAlive(buf)
       
  1128 		return ret, nil
       
  1129 	case REG_EXPAND_SZ:
       
  1130 		value := UTF16ToString(bufToUTF16(buf))
       
  1131 		if value == "" {
       
  1132 			return "", nil
       
  1133 		}
       
  1134 		p, err := syscall.UTF16PtrFromString(value)
       
  1135 		if err != nil {
       
  1136 			return "", err
       
  1137 		}
       
  1138 		ret := make([]uint16, 100)
       
  1139 		for {
       
  1140 			n, err := ExpandEnvironmentStrings(p, &ret[0], uint32(len(ret)))
       
  1141 			if err != nil {
       
  1142 				return "", err
       
  1143 			}
       
  1144 			if n <= uint32(len(ret)) {
       
  1145 				return UTF16ToString(ret[:n]), nil
       
  1146 			}
       
  1147 			ret = make([]uint16, n)
       
  1148 		}
       
  1149 	case REG_BINARY:
       
  1150 		return buf, nil
       
  1151 	case REG_DWORD_LITTLE_ENDIAN:
       
  1152 		return binary.LittleEndian.Uint32(buf), nil
       
  1153 	case REG_DWORD_BIG_ENDIAN:
       
  1154 		return binary.BigEndian.Uint32(buf), nil
       
  1155 	case REG_MULTI_SZ:
       
  1156 		bufW := bufToUTF16(buf)
       
  1157 		a := []string{}
       
  1158 		for i := 0; i < len(bufW); {
       
  1159 			j := i + wcslen(bufW[i:])
       
  1160 			if i < j {
       
  1161 				a = append(a, UTF16ToString(bufW[i:j]))
       
  1162 			}
       
  1163 			i = j + 1
       
  1164 		}
       
  1165 		runtime.KeepAlive(buf)
       
  1166 		return a, nil
       
  1167 	case REG_QWORD_LITTLE_ENDIAN:
       
  1168 		return binary.LittleEndian.Uint64(buf), nil
       
  1169 	default:
       
  1170 		return nil, fmt.Errorf("Unsupported registry value type: %v", dataType)
       
  1171 	}
       
  1172 }
       
  1173 
       
  1174 // bufToUTF16 function reinterprets []byte buffer as []uint16
       
  1175 func bufToUTF16(buf []byte) []uint16 {
       
  1176 	sl := struct {
       
  1177 		addr *uint16
       
  1178 		len  int
       
  1179 		cap  int
       
  1180 	}{(*uint16)(unsafe.Pointer(&buf[0])), len(buf) / 2, cap(buf) / 2}
       
  1181 	return *(*[]uint16)(unsafe.Pointer(&sl))
       
  1182 }
       
  1183 
       
  1184 // utf16ToBuf function reinterprets []uint16 as []byte
       
  1185 func utf16ToBuf(buf []uint16) []byte {
       
  1186 	sl := struct {
       
  1187 		addr *byte
       
  1188 		len  int
       
  1189 		cap  int
       
  1190 	}{(*byte)(unsafe.Pointer(&buf[0])), len(buf) * 2, cap(buf) * 2}
       
  1191 	return *(*[]byte)(unsafe.Pointer(&sl))
       
  1192 }
       
  1193 
       
  1194 func wcslen(str []uint16) int {
       
  1195 	for i := 0; i < len(str); i++ {
       
  1196 		if str[i] == 0 {
       
  1197 			return i
       
  1198 		}
       
  1199 	}
       
  1200 	return len(str)
       
  1201 }
       
  1202 
       
  1203 // DeviceRegistryProperty method retrieves a specified Plug and Play device property.
       
  1204 func (deviceInfoSet DevInfo) DeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP) (interface{}, error) {
       
  1205 	return SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property)
       
  1206 }
       
  1207 
       
  1208 //sys	setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) = setupapi.SetupDiSetDeviceRegistryPropertyW
       
  1209 
       
  1210 // SetupDiSetDeviceRegistryProperty function sets a Plug and Play device property for a device.
       
  1211 func SetupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error {
       
  1212 	return setupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &propertyBuffers[0], uint32(len(propertyBuffers)))
       
  1213 }
       
  1214 
       
  1215 // SetDeviceRegistryProperty function sets a Plug and Play device property for a device.
       
  1216 func (deviceInfoSet DevInfo) SetDeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error {
       
  1217 	return SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, propertyBuffers)
       
  1218 }
       
  1219 
       
  1220 // SetDeviceRegistryPropertyString method sets a Plug and Play device property string for a device.
       
  1221 func (deviceInfoSet DevInfo) SetDeviceRegistryPropertyString(deviceInfoData *DevInfoData, property SPDRP, str string) error {
       
  1222 	str16, err := UTF16FromString(str)
       
  1223 	if err != nil {
       
  1224 		return err
       
  1225 	}
       
  1226 	err = SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, utf16ToBuf(append(str16, 0)))
       
  1227 	runtime.KeepAlive(str16)
       
  1228 	return err
       
  1229 }
       
  1230 
       
  1231 //sys	setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW
       
  1232 
       
  1233 // SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element.
       
  1234 func SetupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DevInstallParams, error) {
       
  1235 	params := &DevInstallParams{}
       
  1236 	params.size = uint32(unsafe.Sizeof(*params))
       
  1237 
       
  1238 	return params, setupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, params)
       
  1239 }
       
  1240 
       
  1241 // DeviceInstallParams method retrieves device installation parameters for a device information set or a particular device information element.
       
  1242 func (deviceInfoSet DevInfo) DeviceInstallParams(deviceInfoData *DevInfoData) (*DevInstallParams, error) {
       
  1243 	return SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData)
       
  1244 }
       
  1245 
       
  1246 //sys	setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceInstanceIdW
       
  1247 
       
  1248 // SetupDiGetDeviceInstanceId function retrieves the instance ID of the device.
       
  1249 func SetupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (string, error) {
       
  1250 	reqSize := uint32(1024)
       
  1251 	for {
       
  1252 		buf := make([]uint16, reqSize)
       
  1253 		err := setupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData, &buf[0], uint32(len(buf)), &reqSize)
       
  1254 		if err == ERROR_INSUFFICIENT_BUFFER {
       
  1255 			continue
       
  1256 		}
       
  1257 		if err != nil {
       
  1258 			return "", err
       
  1259 		}
       
  1260 		return UTF16ToString(buf), nil
       
  1261 	}
       
  1262 }
       
  1263 
       
  1264 // DeviceInstanceID method retrieves the instance ID of the device.
       
  1265 func (deviceInfoSet DevInfo) DeviceInstanceID(deviceInfoData *DevInfoData) (string, error) {
       
  1266 	return SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData)
       
  1267 }
       
  1268 
       
  1269 // SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a particular device information element.
       
  1270 //sys	SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetClassInstallParamsW
       
  1271 
       
  1272 // ClassInstallParams method retrieves class installation parameters for a device information set or a particular device information element.
       
  1273 func (deviceInfoSet DevInfo) ClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) error {
       
  1274 	return SetupDiGetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize, requiredSize)
       
  1275 }
       
  1276 
       
  1277 //sys	SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiSetDeviceInstallParamsW
       
  1278 
       
  1279 // SetDeviceInstallParams member sets device installation parameters for a device information set or a particular device information element.
       
  1280 func (deviceInfoSet DevInfo) SetDeviceInstallParams(deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) error {
       
  1281 	return SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams)
       
  1282 }
       
  1283 
       
  1284 // SetupDiSetClassInstallParams function sets or clears class install parameters for a device information set or a particular device information element.
       
  1285 //sys	SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) = setupapi.SetupDiSetClassInstallParamsW
       
  1286 
       
  1287 // SetClassInstallParams method sets or clears class install parameters for a device information set or a particular device information element.
       
  1288 func (deviceInfoSet DevInfo) SetClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) error {
       
  1289 	return SetupDiSetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize)
       
  1290 }
       
  1291 
       
  1292 //sys	setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassNameFromGuidExW
       
  1293 
       
  1294 // SetupDiClassNameFromGuidEx function retrieves the class name associated with a class GUID. The class can be installed on a local or remote computer.
       
  1295 func SetupDiClassNameFromGuidEx(classGUID *GUID, machineName string) (className string, err error) {
       
  1296 	var classNameUTF16 [MAX_CLASS_NAME_LEN]uint16
       
  1297 
       
  1298 	var machineNameUTF16 *uint16
       
  1299 	if machineName != "" {
       
  1300 		machineNameUTF16, err = UTF16PtrFromString(machineName)
       
  1301 		if err != nil {
       
  1302 			return
       
  1303 		}
       
  1304 	}
       
  1305 
       
  1306 	err = setupDiClassNameFromGuidEx(classGUID, &classNameUTF16[0], MAX_CLASS_NAME_LEN, nil, machineNameUTF16, 0)
       
  1307 	if err != nil {
       
  1308 		return
       
  1309 	}
       
  1310 
       
  1311 	className = UTF16ToString(classNameUTF16[:])
       
  1312 	return
       
  1313 }
       
  1314 
       
  1315 //sys	setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassGuidsFromNameExW
       
  1316 
       
  1317 // 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.
       
  1318 func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]GUID, error) {
       
  1319 	classNameUTF16, err := UTF16PtrFromString(className)
       
  1320 	if err != nil {
       
  1321 		return nil, err
       
  1322 	}
       
  1323 
       
  1324 	var machineNameUTF16 *uint16
       
  1325 	if machineName != "" {
       
  1326 		machineNameUTF16, err = UTF16PtrFromString(machineName)
       
  1327 		if err != nil {
       
  1328 			return nil, err
       
  1329 		}
       
  1330 	}
       
  1331 
       
  1332 	reqSize := uint32(4)
       
  1333 	for {
       
  1334 		buf := make([]GUID, reqSize)
       
  1335 		err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], uint32(len(buf)), &reqSize, machineNameUTF16, 0)
       
  1336 		if err == ERROR_INSUFFICIENT_BUFFER {
       
  1337 			continue
       
  1338 		}
       
  1339 		if err != nil {
       
  1340 			return nil, err
       
  1341 		}
       
  1342 		return buf[:reqSize], nil
       
  1343 	}
       
  1344 }
       
  1345 
       
  1346 //sys	setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice
       
  1347 
       
  1348 // SetupDiGetSelectedDevice function retrieves the selected device information element in a device information set.
       
  1349 func SetupDiGetSelectedDevice(deviceInfoSet DevInfo) (*DevInfoData, error) {
       
  1350 	data := &DevInfoData{}
       
  1351 	data.size = uint32(unsafe.Sizeof(*data))
       
  1352 
       
  1353 	return data, setupDiGetSelectedDevice(deviceInfoSet, data)
       
  1354 }
       
  1355 
       
  1356 // SelectedDevice method retrieves the selected device information element in a device information set.
       
  1357 func (deviceInfoSet DevInfo) SelectedDevice() (*DevInfoData, error) {
       
  1358 	return SetupDiGetSelectedDevice(deviceInfoSet)
       
  1359 }
       
  1360 
       
  1361 // 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.
       
  1362 //sys	SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiSetSelectedDevice
       
  1363 
       
  1364 // 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.
       
  1365 func (deviceInfoSet DevInfo) SetSelectedDevice(deviceInfoData *DevInfoData) error {
       
  1366 	return SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData)
       
  1367 }
       
  1368 
       
  1369 //sys	setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (err error) = setupapi.SetupUninstallOEMInfW
       
  1370 
       
  1371 // SetupUninstallOEMInf uninstalls the specified driver.
       
  1372 func SetupUninstallOEMInf(infFileName string, flags SUOI) error {
       
  1373 	infFileName16, err := UTF16PtrFromString(infFileName)
       
  1374 	if err != nil {
       
  1375 		return err
       
  1376 	}
       
  1377 	return setupUninstallOEMInf(infFileName16, flags, 0)
       
  1378 }
       
  1379 
       
  1380 //sys cm_MapCrToWin32Err(configRet CONFIGRET, defaultWin32Error Errno) (ret Errno) = CfgMgr32.CM_MapCrToWin32Err
       
  1381 
       
  1382 //sys cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *GUID, deviceID *uint16, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_Device_Interface_List_SizeW
       
  1383 //sys cm_Get_Device_Interface_List(interfaceClass *GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_Device_Interface_ListW
       
  1384 
       
  1385 func CM_Get_Device_Interface_List(deviceID string, interfaceClass *GUID, flags uint32) ([]string, error) {
       
  1386 	deviceID16, err := UTF16PtrFromString(deviceID)
       
  1387 	if err != nil {
       
  1388 		return nil, err
       
  1389 	}
       
  1390 	var buf []uint16
       
  1391 	var buflen uint32
       
  1392 	for {
       
  1393 		if ret := cm_Get_Device_Interface_List_Size(&buflen, interfaceClass, deviceID16, flags); ret != CR_SUCCESS {
       
  1394 			return nil, ret
       
  1395 		}
       
  1396 		buf = make([]uint16, buflen)
       
  1397 		if ret := cm_Get_Device_Interface_List(interfaceClass, deviceID16, &buf[0], buflen, flags); ret == CR_SUCCESS {
       
  1398 			break
       
  1399 		} else if ret != CR_BUFFER_SMALL {
       
  1400 			return nil, ret
       
  1401 		}
       
  1402 	}
       
  1403 	var interfaces []string
       
  1404 	for i := 0; i < len(buf); {
       
  1405 		j := i + wcslen(buf[i:])
       
  1406 		if i < j {
       
  1407 			interfaces = append(interfaces, UTF16ToString(buf[i:j]))
       
  1408 		}
       
  1409 		i = j + 1
       
  1410 	}
       
  1411 	if interfaces == nil {
       
  1412 		return nil, ERROR_NO_SUCH_DEVICE_INTERFACE
       
  1413 	}
       
  1414 	return interfaces, nil
       
  1415 }
       
  1416 
       
  1417 //sys cm_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_DevNode_Status
       
  1418 
       
  1419 func CM_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) error {
       
  1420 	ret := cm_Get_DevNode_Status(status, problemNumber, devInst, flags)
       
  1421 	if ret == CR_SUCCESS {
       
  1422 		return nil
       
  1423 	}
       
  1424 	return ret
       
  1425 }