]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
setupapi: add DeviceInstanceID()
authorJason A. Donenfeld <Jason@zx2c4.com>
Sun, 9 Jun 2019 15:22:59 +0000 (17:22 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 10 Jun 2019 08:43:01 +0000 (10:43 +0200)
tun/wintun/setupapi/setupapi_windows.go
tun/wintun/setupapi/setupapi_windows_test.go
tun/wintun/setupapi/zsetupapi_windows.go

index 1ac1419b662e2fadbfadc22f089b4935494984a1..6757743f31be61378c260ac2da0bc8376db56c1d 100644 (file)
@@ -364,6 +364,29 @@ func (deviceInfoSet DevInfo) DeviceInstallParams(deviceInfoData *DevInfoData) (*
        return SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData)
 }
 
+//sys  setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceInstanceIdW
+
+// SetupDiGetDeviceInstanceId function retrieves the instance ID of the device
+func SetupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (string, error) {
+       reqSize := uint32(1024)
+       for {
+               buf := make([]uint16, reqSize)
+               err := setupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData, &buf[0], uint32(len(buf)), &reqSize)
+               if err == windows.ERROR_INSUFFICIENT_BUFFER {
+                       continue
+               }
+               if err != nil {
+                       return "", err
+               }
+               return windows.UTF16ToString(buf), nil
+       }
+}
+
+// DeviceInstanceID method retrieves the instance ID of the device.
+func (deviceInfoSet DevInfo) DeviceInstanceID(deviceInfoData *DevInfoData) (string, error) {
+       return SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData)
+}
+
 // SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a particular device information element.
 //sys  SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetClassInstallParamsW
 
index b932d7daa92b0f4dea4e994b0bd2ecd20a348293..48a0f05e047ff34a3b2db68cd0aa41df843f2709 100644 (file)
@@ -139,6 +139,11 @@ func TestSetupDiEnumDeviceInfo(t *testing.T) {
                if data.ClassGUID != deviceClassNetGUID {
                        t.Error("SetupDiEnumDeviceInfo returned different class GUID")
                }
+
+               _, err = devInfoList.DeviceInstanceID(data)
+               if err != nil {
+                       t.Errorf("Error calling SetupDiGetDeviceInstanceId: %s", err.Error())
+               }
        }
 }
 
index 248672e675e116aacc57104f8922ebd79039d408..09497183d556a813fcaa5fd7194c69e5fcf81e9f 100644 (file)
@@ -57,6 +57,7 @@ var (
        procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW")
        procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW")
        procSetupDiGetDeviceInstallParamsW    = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW")
+       procSetupDiGetDeviceInstanceIdW       = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW")
        procSetupDiGetClassInstallParamsW     = modsetupapi.NewProc("SetupDiGetClassInstallParamsW")
        procSetupDiSetDeviceInstallParamsW    = modsetupapi.NewProc("SetupDiSetDeviceInstallParamsW")
        procSetupDiSetClassInstallParamsW     = modsetupapi.NewProc("SetupDiSetClassInstallParamsW")
@@ -285,6 +286,18 @@ func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInf
        return
 }
 
+func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) {
+       r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize)), 0)
+       if r1 == 0 {
+               if e1 != 0 {
+                       err = errnoErr(e1)
+               } else {
+                       err = syscall.EINVAL
+               }
+       }
+       return
+}
+
 func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) {
        r1, _, e1 := syscall.Syscall6(procSetupDiGetClassInstallParamsW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize)), 0)
        if r1 == 0 {