summaryrefslogtreecommitdiffhomepage
path: root/tun/wintun
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-06-09 19:20:17 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-06-10 10:43:02 +0200
commite924280baa36f6fd80f4a65f2fb6223a4965b281 (patch)
treef1d8f36e9282b6bf5cb3b3aa888f07ecb20fc790 /tun/wintun
parentbb3f1932faa4f75800a145e7f0476d8a8dcf104a (diff)
wintun: allow controlling GUID
Diffstat (limited to 'tun/wintun')
-rw-r--r--tun/wintun/wintun_windows.go21
1 files changed, 20 insertions, 1 deletions
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index ec7f8ea..9e71581 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -176,6 +176,13 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
// description is a string that supplies the text description of the device.
// description is optional and can be "".
//
+// requestedGUID is the GUID of the created network interface, which then
+// influences NLA generation deterministically. If it is set to nil, the GUID
+// is chosen by the system at random, and hence a new NLA entry is created for
+// each new interface. It is called "requested" GUID because the API it uses
+// is completely undocumented, and so there could be minor interesting
+// complications with its usage.
+//
// hwndParent is a handle to the top-level window to use for any user
// interface that is related to non-device-specific actions (such as a select-
// device dialog box that uses the global class driver list). This handle is
@@ -184,7 +191,7 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
//
// Function returns the network interface ID and a flag if reboot is required.
//
-func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, error) {
+func CreateInterface(description string, requestedGUID *windows.GUID, hwndParent uintptr) (*Wintun, bool, error) {
// Create an empty device info set for network adapter device class.
devInfoList, err := setupapi.SetupDiCreateDeviceInfoListEx(&deviceClassNetGUID, hwndParent, machineName)
if err != nil {
@@ -280,6 +287,18 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
// Register device co-installers if any. (Ignore errors)
devInfoList.CallClassInstaller(setupapi.DIF_REGISTER_COINSTALLERS, deviceData)
+ if requestedGUID != nil {
+ key, err := devInfoList.OpenDevRegKey(deviceData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.SET_VALUE)
+ if err != nil {
+ return nil, false, fmt.Errorf("OpenDevRegKey failed: %v", err)
+ }
+ err = key.SetStringValue("NetSetupAnticipatedInstanceId", requestedGUID.String())
+ key.Close()
+ if err != nil {
+ return nil, false, fmt.Errorf("SetStringValue(NetSetupAnticipatedInstanceId) failed: %v", err)
+ }
+ }
+
// Install interfaces if any. (Ignore errors)
devInfoList.CallClassInstaller(setupapi.DIF_INSTALLINTERFACES, deviceData)