diff options
Diffstat (limited to 'vendor/golang.org/x/sys/windows/setupapi_windows.go')
-rw-r--r-- | vendor/golang.org/x/sys/windows/setupapi_windows.go | 1425 |
1 files changed, 1425 insertions, 0 deletions
diff --git a/vendor/golang.org/x/sys/windows/setupapi_windows.go b/vendor/golang.org/x/sys/windows/setupapi_windows.go new file mode 100644 index 0000000..f812648 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/setupapi_windows.go | |||
@@ -0,0 +1,1425 @@ | |||
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 | } | ||