Skip to content

Commit

Permalink
Issue #8 Add powershell and shellexecute logic
Browse files Browse the repository at this point in the history
  • Loading branch information
gbraad authored and anjannath committed Aug 5, 2019
1 parent 31867e8 commit 041bdb5
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
85 changes: 85 additions & 0 deletions pkg/os/windows/powershell/powershell_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package powershell

import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"strings"
"syscall"

"os/exec"
)

var (
runAsCmds = []string{
`$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();`,
`$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);`,
`$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;`,
`if (-Not ($myWindowsPrincipal.IsInRole($adminRole))) {`,
` $procInfo = New-Object System.Diagnostics.ProcessStartInfo;`,
` $procInfo.FileName = "` + locatePowerShell() + `"`,
` $procInfo.WindowStyle = [Diagnostics.ProcessWindowStyle]::Hidden`,
` $procInfo.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"`,
` $procInfo.Verb = "runas";`,
` [System.Diagnostics.Process]::Start($procInfo);`,
` Exit;`,
`}`,
}
isAdminCmds = []string{
"$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())",
"$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)",
}
)

func locatePowerShell() string {
ps, _ := exec.LookPath("powershell.exe")
return ps
}

func IsAdmin() bool {
cmd := strings.Join(isAdminCmds, ";")
stdOut, _, err := Execute(cmd)
if err != nil {
return false
}
if strings.TrimSpace(stdOut) == "False" {
return false
}

return true
}

func Execute(args ...string) (stdOut string, stdErr string, err error) {
args = append([]string{"-NoProfile", "-NonInteractive", "-ExecutionPolicy", "RemoteSigned", "-Command"}, args...)
cmd := exec.Command(locatePowerShell(), args...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}

var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

err = cmd.Run()
stdOut, stdErr = stdout.String(), stderr.String()

return
}

func ExecuteAsAdmin(cmd string) (stdOut string, stdErr string, err error) {
scriptContent := strings.Join(append(runAsCmds, cmd), "\n")

tempDir, _ := ioutil.TempDir("", "crcScripts")
psFile, err := os.Create(filepath.Join(tempDir, "runAsAdmin.ps1"))
if err != nil {
return "", "", err
}

// Write a temporary script
psFile.WriteString(scriptContent)
psFile.Close()

return Execute(psFile.Name())

// TODO: cleanup the mess
}
43 changes: 43 additions & 0 deletions pkg/os/windows/win32/shell32_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package win32

import (
"syscall"
"unsafe"

"github.com/code-ready/crc/pkg/crc/errors"
)

var (
shell32Lib = syscall.NewLazyDLL("shell32.dll")
procShellExecute = shell32Lib.NewProc("ShellExecuteW")
)

// Uses "runas" as verb to execute as Elevated privileges
func ShellExecuteAsAdmin(hwnd HWND, file, parameters, directory string, showCmd int) error {
return ShellExecute(hwnd, "runas", file, parameters, directory, showCmd)
}

func toUintptr(input string) uintptr {
return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(input)))
}

func ShellExecute(hwnd HWND, verb, file, parameters, directory string, showCmd int) error {
var op, params, dir uintptr
if len(verb) != 0 {
op = toUintptr(verb)
}
if len(parameters) != 0 {
params = toUintptr(parameters)
}
if len(directory) != 0 {
dir = toUintptr(directory)
}

ret, _, _ := procShellExecute.Call(uintptr(hwnd), op, toUintptr(file), params, dir, uintptr(showCmd))

if ret == 0 {
return nil
}

return errors.Newf("win32 error %v", ret)
}
10 changes: 10 additions & 0 deletions pkg/os/windows/win32/types_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package win32

type (
HANDLE uintptr
HWND HANDLE
)

const (
HWND_DESKTOP = HWND(0)
)

0 comments on commit 041bdb5

Please sign in to comment.