summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-06-09 17:22:59 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-06-10 10:43:01 +0200
commitbb3f1932faa4f75800a145e7f0476d8a8dcf104a (patch)
tree9f95a25d93817d8d0df62849fdb6ee7e6d125b9e
parenteaf17becfa70c31bcfb6f195e8d68cb5b720ec4a (diff)
setupapi: add DeviceInstanceID()
-rw-r--r--tun/wintun/setupapi/setupapi_windows.go23
-rw-r--r--tun/wintun/setupapi/setupapi_windows_test.go5
-rw-r--r--tun/wintun/setupapi/zsetupapi_windows.go13
3 files changed, 41 insertions, 0 deletions
diff --git a/tun/wintun/setupapi/setupapi_windows.go b/tun/wintun/setupapi/setupapi_windows.go
index 1ac1419..6757743 100644
--- a/tun/wintun/setupapi/setupapi_windows.go
+++ b/tun/wintun/setupapi/setupapi_windows.go
@@ -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
diff --git a/tun/wintun/setupapi/setupapi_windows_test.go b/tun/wintun/setupapi/setupapi_windows_test.go
index b932d7d..48a0f05 100644
--- a/tun/wintun/setupapi/setupapi_windows_test.go
+++ b/tun/wintun/setupapi/setupapi_windows_test.go
@@ -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())
+ }
}
}
diff --git a/tun/wintun/setupapi/zsetupapi_windows.go b/tun/wintun/setupapi/zsetupapi_windows.go
index 248672e..0949718 100644
--- a/tun/wintun/setupapi/zsetupapi_windows.go
+++ b/tun/wintun/setupapi/zsetupapi_windows.go
@@ -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 {