Upgrade the pinned driver, validate menu and taskbar focus ownership, patch untitled Shell resolution, and remove duplicate scroll scaling. Publish package provenance, verification boundaries and matching marketplace checksum. Go tests, vet, build and byte-level package verification passed.
94 lines
3.1 KiB
Go
94 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"runtime"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
var user32 = syscall.NewLazyDLL("user32.dll")
|
|
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
|
|
func foregroundWindow() int64 {
|
|
hwnd, _, _ := user32.NewProc("GetForegroundWindow").Call()
|
|
return int64(hwnd)
|
|
}
|
|
|
|
func configureProcess(c *exec.Cmd) {
|
|
c.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
|
}
|
|
func windowOwned(pid, hwnd int64) bool {
|
|
var actual uint32
|
|
r, _, _ := user32.NewProc("IsWindow").Call(uintptr(hwnd))
|
|
if r == 0 {
|
|
return false
|
|
}
|
|
user32.NewProc("GetWindowThreadProcessId").Call(uintptr(hwnd), uintptr(unsafe.Pointer(&actual)))
|
|
return int64(actual) == pid
|
|
}
|
|
func verifyWindow(pid, hwnd int64, b obj) (obj, bool) {
|
|
// DPI context belongs to an OS thread, not a Go goroutine. Apply it around
|
|
// the actual geometry reads; setting it once while starting a child leaks
|
|
// context and later GetSystemMetrics can return virtualized dimensions.
|
|
runtime.LockOSThread()
|
|
defer runtime.UnlockOSThread()
|
|
setDPI := user32.NewProc("SetThreadDpiAwarenessContext")
|
|
previous, _, _ := setDPI.Call(^uintptr(3))
|
|
if previous == 0 {
|
|
return nil, false
|
|
}
|
|
defer setDPI.Call(previous)
|
|
if !windowOwned(pid, hwnd) {
|
|
return nil, false
|
|
}
|
|
var r struct{ L, T, R, B int32 }
|
|
code, _, _ := syscall.NewLazyDLL("dwmapi.dll").NewProc("DwmGetWindowAttribute").Call(uintptr(hwnd), 9, uintptr(unsafe.Pointer(&r)), unsafe.Sizeof(r))
|
|
if code != 0 || r.R <= r.L || r.B <= r.T {
|
|
// Shell menus/taskbars can lack a DWM extended frame. Match their
|
|
// actual HWND rectangle; never substitute desktop or another window.
|
|
if shellKind(windowClass(hwnd)) == "" {
|
|
return nil, false
|
|
}
|
|
ok, _, _ := user32.NewProc("GetWindowRect").Call(uintptr(hwnd), uintptr(unsafe.Pointer(&r)))
|
|
if ok == 0 {
|
|
return nil, false
|
|
}
|
|
}
|
|
// Cua uses DWM physical bounds; refuse evidence after a window move/resize.
|
|
if int64(r.L) != num(b["left"]) || int64(r.T) != num(b["top"]) || int64(r.R-r.L) != num(b["width"]) || int64(r.B-r.T) != num(b["height"]) {
|
|
return nil, false
|
|
}
|
|
metric := func(n uintptr) int64 { x, _, _ := user32.NewProc("GetSystemMetrics").Call(n); return int64(int32(x)) }
|
|
return obj{"left": metric(76), "top": metric(77), "width": metric(78), "height": metric(79)}, true
|
|
}
|
|
func ownProcess(pid int) (uintptr, error) {
|
|
job, _, e := kernel32.NewProc("CreateJobObjectW").Call(0, 0)
|
|
if job == 0 {
|
|
return 0, e
|
|
}
|
|
// JOBOBJECT_EXTENDED_LIMIT_INFORMATION, Windows x64. Kill the entire owned
|
|
// child tree when the adapter dies, including Cua's UIA helper.
|
|
data := make([]byte, 144)
|
|
*(*uint32)(unsafe.Pointer(&data[16])) = 0x2000
|
|
ok, _, _ := kernel32.NewProc("SetInformationJobObject").Call(job, 9, uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)))
|
|
h, _, _ := kernel32.NewProc("OpenProcess").Call(0x0101, 0, uintptr(pid))
|
|
if h == 0 || ok == 0 {
|
|
closeJob(job)
|
|
return 0, fmt.Errorf("cannot own driver process")
|
|
}
|
|
defer kernel32.NewProc("CloseHandle").Call(h)
|
|
ok, _, e = kernel32.NewProc("AssignProcessToJobObject").Call(job, h)
|
|
if ok == 0 {
|
|
closeJob(job)
|
|
return 0, e
|
|
}
|
|
return job, nil
|
|
}
|
|
func closeJob(h uintptr) {
|
|
if h != 0 {
|
|
kernel32.NewProc("CloseHandle").Call(h)
|
|
}
|
|
}
|