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 <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Jason A. Donenfeld
2019-05-25 15:17:43 +02:00
committed by Alex Brainman
parent 791d8a0f4d
commit 56c252d053
2 changed files with 15 additions and 1 deletions

View File

@@ -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

View File

@@ -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 {