setupapi_windows.go 67 KB

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