//go:build windows /* SPDX-License-Identifier: MIT * * Phobos */ package ui import ( "os" "runtime" "time" "unsafe" "github.com/lxn/win" "golang.org/x/sys/windows" "golang.zx2c4.com/wireguard/windows/l18n" ) const importLinkMessageID = 0x50484f42 type copyDataStruct struct { data uintptr size uint32 ptr unsafe.Pointer } func sendImportLinkTo(hwnd win.HWND, link string) bool { runtime.LockOSThread() defer runtime.UnlockOSThread() utf16, err := windows.UTF16FromString(link) if err != nil { return false } payload := copyDataStruct{ data: importLinkMessageID, size: uint32(len(utf16) * 2), ptr: unsafe.Pointer(&utf16[0]), } delivered := win.SendMessage(hwnd, win.WM_COPYDATA, 0, uintptr(unsafe.Pointer(&payload))) != 0 runtime.KeepAlive(utf16) if delivered { raiseRemote(hwnd) } return delivered } // SendImportLink hands a phobos:// link to an already running Phobos window. func SendImportLink(link string) bool { hwnd := win.FindWindow(windows.StringToUTF16Ptr(manageWindowWindowClass), nil) if hwnd == 0 { return false } return sendImportLinkTo(hwnd, link) } // WaitForUIThenImportLink blocks until the Phobos window shows up, hands it the // link and quits. It gives up after the timeout so a stuck launch cannot leave // the process behind. func WaitForUIThenImportLink(link string, timeout time.Duration) { deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { if SendImportLink(link) { os.Exit(0) } time.Sleep(250 * time.Millisecond) } showErrorCustom(nil, l18n.Sprintf("Phobos Detection Error"), l18n.Sprintf("Phobos did not start in time to import the link.")) os.Exit(1) } func (mtw *ManageTunnelsWindow) onImportLinkMessage(lParam uintptr) uintptr { payload := (*copyDataStruct)(unsafe.Pointer(lParam)) if payload == nil || payload.data != importLinkMessageID || payload.size == 0 { return 0 } link := windows.UTF16ToString(unsafe.Slice((*uint16)(payload.ptr), payload.size/2)) mtw.Synchronize(func() { if mtw.tunnelsPage == nil { return } if mtw.tabs != nil { mtw.tabs.SetCurrentIndex(0) } mtw.tunnelsPage.importLink(link) }) return 1 }