Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/golang.org/x/sys/windows/setupapi_windows.go
2880 views
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
}
1426
1427