]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Add support for setupapi.SetupDiOpenDevRegKey()
authorSimon Rozman <simon@rozman.si>
Fri, 1 Feb 2019 12:00:44 +0000 (13:00 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Tue, 5 Feb 2019 11:59:42 +0000 (12:59 +0100)
Furthermore setupapi.DevInfoData has been obsoleted.
SetupDiEnumDeviceInfo() fills existing SP_DEVINFO_DATA structure now.
As other functions of SetupAPI use SP_DEVINFO_DATA, converting it to
DevInfoData and back would hurt performance.

Signed-off-by: Simon Rozman <simon@rozman.si>
setupapi/setupapi_windows.go
setupapi/setupapi_windows_test.go
setupapi/types_windows.go
setupapi/zsetupapi_windows.go

index dad096761a599f88929900b133d711afa569ce0e..282b9d0cef2bcac03c39b942a40c2ace173114af 100644 (file)
@@ -10,12 +10,14 @@ import (
        "unsafe"
 
        "golang.org/x/sys/windows"
+       "golang.org/x/sys/windows/registry"
 )
 
 //sys  setupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiGetClassDevsExW
 //sys  SetupDiDestroyDeviceInfoList(DeviceInfoSet DevInfo) (err error) = setupapi.SetupDiDestroyDeviceInfoList
 //sys  setupDiGetDeviceInfoListDetail(DeviceInfoSet DevInfo, DeviceInfoSetDetailData *_SP_DEVINFO_LIST_DETAIL_DATA) (err error) = setupapi.SetupDiGetDeviceInfoListDetailW
-//sys  setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfoData *_SP_DEVINFO_DATA) (err error) = setupapi.SetupDiEnumDeviceInfo
+//sys  setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfoData *SP_DEVINFO_DATA) (err error) = setupapi.SetupDiEnumDeviceInfo
+//sys  setupDiOpenDevRegKey(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key windows.Handle, err error) [failretval==windows.InvalidHandle] = setupapi.SetupDiOpenDevRegKey
 
 // SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer.
 func SetupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator string, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName string) (handle DevInfo, err error) {
@@ -55,18 +57,13 @@ func SetupDiGetDeviceInfoListDetail(DeviceInfoSet DevInfo) (data *DevInfoListDet
 }
 
 // SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set.
-func SetupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex int) (data *DevInfoData, err error) {
-       var _p0 _SP_DEVINFO_DATA
-       _p0.Size = uint32(unsafe.Sizeof(_p0))
-
-       err = setupDiEnumDeviceInfo(DeviceInfoSet, uint32(MemberIndex), &_p0)
-       if err != nil {
-               return
-       }
+func SetupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex int, data *SP_DEVINFO_DATA) error {
+       data.Size = uint32(unsafe.Sizeof(*data))
+       return setupDiEnumDeviceInfo(DeviceInfoSet, uint32(MemberIndex), data)
+}
 
-       data = &DevInfoData{
-               ClassGUID: _p0.ClassGUID,
-               DevInst:   _p0.DevInst,
-       }
-       return
+// SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information.
+func SetupDiOpenDevRegKey(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key registry.Key, err error) {
+       handle, err := setupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired)
+       return registry.Key(handle), err
 }
index 8aa72211067742de356c9291923fa17da4176d21..25e712f48620e558fbcf313cfb4594f5898f4ca1 100644 (file)
@@ -43,7 +43,7 @@ func TestSetupDiGetDeviceInfoListDetailLocal(t *testing.T) {
        if err != nil {
                t.Errorf("Error calling SetupDiGetClassDevsEx: %s", err.Error())
        }
-       defer SetupDiDestroyDeviceInfoList(devInfoList)
+       defer devInfoList.Close()
 
        data, err := SetupDiGetDeviceInfoListDetail(devInfoList)
        if err != nil {
@@ -68,7 +68,7 @@ func TestSetupDiGetDeviceInfoListDetailRemote(t *testing.T) {
        if err != nil {
                t.Errorf("Error calling SetupDiGetClassDevsEx: %s", err.Error())
        }
-       defer SetupDiDestroyDeviceInfoList(devInfoList)
+       defer devInfoList.Close()
 
        data, err := SetupDiGetDeviceInfoListDetail(devInfoList)
        if err != nil {
@@ -93,10 +93,11 @@ func TestSetupDiEnumDeviceInfo(t *testing.T) {
        if err != nil {
                t.Errorf("Error calling SetupDiGetClassDevsEx: %s", err.Error())
        }
-       defer SetupDiDestroyDeviceInfoList(devInfoList)
+       defer devInfoList.Close()
 
+       var data SP_DEVINFO_DATA
        for i := 0; true; i++ {
-               data, err := SetupDiEnumDeviceInfo(devInfoList, i)
+               err := SetupDiEnumDeviceInfo(devInfoList, i, &data)
                if err != nil {
                        if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
                                break
@@ -109,3 +110,28 @@ func TestSetupDiEnumDeviceInfo(t *testing.T) {
                }
        }
 }
+
+func TestSetupDiOpenDevRegKey(t *testing.T) {
+       devInfoList, err := SetupDiGetClassDevsEx(&deviceClassNetGUID, "", 0, DIGCF_PRESENT, DevInfo(0), "")
+       if err != nil {
+               t.Errorf("Error calling SetupDiGetClassDevsEx: %s", err.Error())
+       }
+       defer devInfoList.Close()
+
+       var data SP_DEVINFO_DATA
+       for i := 0; true; i++ {
+               err := SetupDiEnumDeviceInfo(devInfoList, i, &data)
+               if err != nil {
+                       if errWin, ok := err.(syscall.Errno); ok && errWin == 259 /*ERROR_NO_MORE_ITEMS*/ {
+                               break
+                       }
+                       continue
+               }
+
+               key, err := SetupDiOpenDevRegKey(devInfoList, &data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, windows.KEY_READ)
+               if err != nil {
+                       t.Errorf("Error calling SetupDiOpenDevRegKey: %s", err.Error())
+               }
+               defer key.Close()
+       }
+}
index e94d112dea8317983802b00820871b878f5bd903..ef0725ae397f028035ef9cbc4dbb70cf97ddf15c 100644 (file)
@@ -51,15 +51,28 @@ type DevInfoListDetailData struct {
        RemoteMachineName   string
 }
 
-type _SP_DEVINFO_DATA struct {
+// SP_DEVINFO_DATA is a device information structure (references a device instance that is a member of a device information set)
+type SP_DEVINFO_DATA struct {
        Size      uint32
        ClassGUID windows.GUID
        DevInst   uint32 // DEVINST handle
        _         uintptr
 }
 
-// DevInfoData is a device information structure (references a device instance that is a member of a device information set)
-type DevInfoData struct {
-       ClassGUID windows.GUID
-       DevInst   uint32 // DEVINST handle
-}
+// DICS_FLAG specifies the scope of a device property change
+type DICS_FLAG uint32
+
+const (
+       DICS_FLAG_GLOBAL         DICS_FLAG = 0x00000001 // make change in all hardware profiles
+       DICS_FLAG_CONFIGSPECIFIC DICS_FLAG = 0x00000002 // make change in specified profile only
+       DICS_FLAG_CONFIGGENERAL  DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow
+)
+
+// DIREG specifies values for SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and SetupDiDeleteDevRegKey.
+type DIREG uint32
+
+const (
+       DIREG_DEV  DIREG = 0x00000001 // Open/Create/Delete device key
+       DIREG_DRV  DIREG = 0x00000002 // Open/Create/Delete driver key
+       DIREG_BOTH DIREG = 0x00000004 // Delete both driver and Device key
+)
index 0896d45c59e9f2ce6564768e1f3146b86e46816c..e8bf8c252381ec8153a27600fd186a7206af6337 100644 (file)
@@ -43,6 +43,7 @@ var (
        procSetupDiDestroyDeviceInfoList    = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList")
        procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW")
        procSetupDiEnumDeviceInfo           = modsetupapi.NewProc("SetupDiEnumDeviceInfo")
+       procSetupDiOpenDevRegKey            = modsetupapi.NewProc("SetupDiOpenDevRegKey")
 )
 
 func setupDiGetClassDevsEx(ClassGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, DeviceInfoSet DevInfo, MachineName *uint16, reserved uintptr) (handle DevInfo, err error) {
@@ -82,7 +83,7 @@ func setupDiGetDeviceInfoListDetail(DeviceInfoSet DevInfo, DeviceInfoSetDetailDa
        return
 }
 
-func setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfoData *_SP_DEVINFO_DATA) (err error) {
+func setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfoData *SP_DEVINFO_DATA) (err error) {
        r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(DeviceInfoSet), uintptr(MemberIndex), uintptr(unsafe.Pointer(DeviceInfoData)))
        if r1 == 0 {
                if e1 != 0 {
@@ -93,3 +94,16 @@ func setupDiEnumDeviceInfo(DeviceInfoSet DevInfo, MemberIndex uint32, DeviceInfo
        }
        return
 }
+
+func setupDiOpenDevRegKey(DeviceInfoSet DevInfo, DeviceInfoData *SP_DEVINFO_DATA, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key windows.Handle, err error) {
+       r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(DeviceInfoSet), uintptr(unsafe.Pointer(DeviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired))
+       key = windows.Handle(r0)
+       if key == windows.InvalidHandle {
+               if e1 != 0 {
+                       err = errnoErr(e1)
+               } else {
+                       err = syscall.EINVAL
+               }
+       }
+       return
+}