66
|
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 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 }
|