Mercurial > yakumo_izuru > aya
comparison vendor/golang.org/x/sys/windows/setupapi_windows.go @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author | yakumo.izuru |
---|---|
date | Sun, 23 Jul 2023 13:18:53 +0000 |
parents | |
children | 4b79810863f6 |
comparison
equal
deleted
inserted
replaced
65:6d985efa0f7a | 66:787b5ee0289d |
---|---|
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 } |