aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2020-07-24 10:54:47 +0200
committerSimon Rozman <simon@rozman.si>2020-07-24 10:54:47 +0200
commit6755f3bc5e7cb446778f60e565c133cd20d4365e (patch)
tree13c0e5b4794518db0a44b1a8d24ab43049df91eb
parentwintun: cleanup (diff)
downloadwireguard-go-sr/wintun-api-wip.tar.xz
wireguard-go-sr/wintun-api-wip.zip
wintun: add support for rundll32 calls from WoW64 processessr/wintun-api-wip
WoW64 processes can't use some of the SetupAPI functions because of registry and filesystem reflection. Wintun-API introduced rundll32 wrappers around those functions and this commit adopts them. Signed-off-by: Simon Rozman <simon@rozman.si>
-rw-r--r--tun/wintun/wintun_windows.go55
1 files changed, 50 insertions, 5 deletions
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index 502f4a3..f1b0896 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -7,8 +7,10 @@ package wintun
import (
"fmt"
+ "os/exec"
"golang.org/x/sys/windows"
+ "golang.org/x/sys/windows/registry"
)
const (
@@ -19,6 +21,21 @@ const (
type Pool [MAX_POOL]uint16
type Adapter uintptr
+var (
+ isWow64 bool
+ rundll32Path string
+)
+
+func init() {
+ err := windows.IsWow64Process(windows.CurrentProcess(), &isWow64)
+ isWow64 = err == nil && isWow64
+
+ rundll32Path, err = registry.ExpandString("%SystemRoot%\\Sysnative\\rundll32.exe")
+ if err != nil {
+ panic(err)
+ }
+}
+
func MakePool(poolName string) (pool Pool) {
poolName16 := windows.StringToUTF16(poolName)
if len(poolName16) > MAX_POOL {
@@ -28,6 +45,10 @@ func MakePool(poolName string) (pool Pool) {
return
}
+func (pool Pool) String() string {
+ return windows.UTF16ToString(pool[:])
+}
+
//sys wintunFreeAdapter(adapter Adapter) = wintun.WintunFreeAdapter
// Close releases the Wintun adapter resources.
@@ -59,11 +80,27 @@ func (pool Pool) Adapter(ifname string) (adapter Adapter, err error) {
// uses is completely undocumented, and so there could be minor interesting complications with its
// usage. This function returns the network adapter ID and a flag if reboot is required.
func (pool Pool) CreateAdapter(ifname string, requestedGUID *windows.GUID) (wintun Adapter, rebootRequired bool, err error) {
- ifname16, err := windows.UTF16PtrFromString(ifname)
- if err != nil {
- return
+ if isWow64 {
+ var cmd *exec.Cmd
+ if requestedGUID != nil {
+ cmd = exec.Command(rundll32Path, "wintun.dll,CreateAdapter", pool.String(), ifname, requestedGUID.String())
+ } else {
+ cmd = exec.Command(rundll32Path, "wintun.dll,CreateAdapter", pool.String(), ifname)
+ }
+ err = cmd.Run()
+ if err != nil {
+ err = fmt.Errorf("Error executing rundll32 wintun.dll,CreateAdapter: %v", err)
+ return
+ }
+ wintun, err = pool.Adapter(ifname)
+ } else {
+ var ifname16 *uint16
+ ifname16, err = windows.UTF16PtrFromString(ifname)
+ if err != nil {
+ return
+ }
+ err = wintunCreateAdapter(&pool[0], ifname16, requestedGUID, &wintun, &rebootRequired)
}
- err = wintunCreateAdapter(&pool[0], ifname16, requestedGUID, &wintun, &rebootRequired)
return
}
@@ -72,7 +109,15 @@ func (pool Pool) CreateAdapter(ifname string, requestedGUID *windows.GUID) (wint
// Delete deletes a Wintun adapter. This function succeeds if the adapter was not found. It returns
// a bool indicating whether a reboot is required.
func (wintun Adapter) Delete() (rebootRequired bool, err error) {
- err = wintunDeleteAdapter(wintun, &rebootRequired)
+ if isWow64 {
+ err = exec.Command(rundll32Path, "wintun.dll,DeleteAdapter", wintun.GUID().String()).Run()
+ if err != nil {
+ err = fmt.Errorf("Error executing rundll32 wintun.dll,CreateAdapter: %v", err)
+ return
+ }
+ } else {
+ err = wintunDeleteAdapter(wintun, &rebootRequired)
+ }
return
}