From 56c252d0536b66a4e871d36a8c207d9420c588b0 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 25 May 2019 15:17:43 +0200 Subject: [PATCH] windows: add ShellExecute This is the way to do things like execute a process elevated with UAC and interact with that whole system. It turns out to be quite important for writing Windows software. Change-Id: I5e05dc9b89ea308d42ac86ba563fd01922fc940c Reviewed-on: https://go-review.googlesource.com/c/sys/+/178898 Run-TryBot: Jason Donenfeld TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- windows/syscall_windows.go | 1 + windows/zsyscall_windows.go | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index c37fbccd..bba1e9e1 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -172,6 +172,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CancelIoEx(s Handle, o *Overlapped) (err error) //sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW //sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) +//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) = shell32.ShellExecuteW //sys TerminateProcess(handle Handle, exitcode uint32) (err error) //sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) //sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index 25e88389..4f35a028 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -37,8 +37,8 @@ func errnoErr(e syscall.Errno) error { var ( modadvapi32 = NewLazySystemDLL("advapi32.dll") modkernel32 = NewLazySystemDLL("kernel32.dll") - moduserenv = NewLazySystemDLL("userenv.dll") modshell32 = NewLazySystemDLL("shell32.dll") + moduserenv = NewLazySystemDLL("userenv.dll") modmswsock = NewLazySystemDLL("mswsock.dll") modcrypt32 = NewLazySystemDLL("crypt32.dll") modws2_32 = NewLazySystemDLL("ws2_32.dll") @@ -110,6 +110,7 @@ var ( procCancelIoEx = modkernel32.NewProc("CancelIoEx") procCreateProcessW = modkernel32.NewProc("CreateProcessW") procOpenProcess = modkernel32.NewProc("OpenProcess") + procShellExecuteW = modshell32.NewProc("ShellExecuteW") procTerminateProcess = modkernel32.NewProc("TerminateProcess") procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") @@ -1075,6 +1076,18 @@ func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err return } +func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { + r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + func TerminateProcess(handle Handle, exitcode uint32) (err error) { r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) if r1 == 0 {