fix: admin-version in second window on windoof (incl build)
This commit is contained in:
Binary file not shown.
+93
-28
@@ -6,19 +6,32 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
shell32 = syscall.NewLazyDLL("shell32.dll")
|
shell32 = syscall.NewLazyDLL("shell32.dll")
|
||||||
shellExecuteExW = shell32.NewProc("ShellExecuteExW")
|
shellExecuteExW = shell32.NewProc("ShellExecuteExW")
|
||||||
|
|
||||||
|
advapi32 = syscall.NewLazyDLL("advapi32.dll")
|
||||||
|
openProcessToken = advapi32.NewProc("OpenProcessToken")
|
||||||
|
getTokenInformation = advapi32.NewProc("GetTokenInformation")
|
||||||
|
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
closeHandle = kernel32.NewProc("CloseHandle")
|
||||||
|
waitForSingleObject = kernel32.NewProc("WaitForSingleObject")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
seeMaskNocloseprocess = 0x00000040
|
tokenQuery = 0x0008
|
||||||
|
tokenElevationClass = 20
|
||||||
|
seeMaskNoCloseProcess = 0x00000040
|
||||||
|
swShow = 1
|
||||||
|
infinite = 0xFFFFFFFF
|
||||||
|
errorCancelled = 1223
|
||||||
)
|
)
|
||||||
|
|
||||||
type shellExecuteInfo struct {
|
type shellExecuteInfo struct {
|
||||||
@@ -39,6 +52,10 @@ type shellExecuteInfo struct {
|
|||||||
hProcess uintptr
|
hProcess uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tokenElevationData struct {
|
||||||
|
TokenIsElevated uint32
|
||||||
|
}
|
||||||
|
|
||||||
func getInstallDir() (string, error) {
|
func getInstallDir() (string, error) {
|
||||||
programFiles := os.Getenv("ProgramFiles")
|
programFiles := os.Getenv("ProgramFiles")
|
||||||
|
|
||||||
@@ -50,32 +67,70 @@ func getInstallDir() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func platformRunPrivileged(config Config, action string) error {
|
func platformRunPrivileged(config Config, action string) error {
|
||||||
if isWindowsAdmin() {
|
if isWindowsElevated() {
|
||||||
return runAction(config, action)
|
return runAction(config, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Für diese Aktion werden Administratorrechte benötigt.")
|
||||||
|
fmt.Print("Jetzt Administratorrechte anfordern? [J/n]: ")
|
||||||
|
|
||||||
|
var answer string
|
||||||
|
if _, err := fmt.Scanln(&answer); err != nil {
|
||||||
|
// Enter ohne Eingabe = Ja
|
||||||
|
answer = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
answer = strings.ToLower(strings.TrimSpace(answer))
|
||||||
|
|
||||||
|
if answer != "" && answer != "j" && answer != "ja" {
|
||||||
|
fmt.Println("Abgebrochen.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return runElevated(action)
|
return runElevated(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWindowsAdmin() bool {
|
func isWindowsElevated() bool {
|
||||||
// Ein einfacher und robuster Test:
|
var token uintptr
|
||||||
// Versuch, in das Windows-Systemverzeichnis zu schreiben.
|
|
||||||
//
|
|
||||||
// Da wir dort natürlich nichts verändern wollen, verwenden wir
|
|
||||||
// stattdessen "net session". Der Befehl funktioniert nur mit
|
|
||||||
// Administratorrechten.
|
|
||||||
|
|
||||||
cmd := exec.Command("net", "session")
|
ret, _, _ := openProcessToken.Call(
|
||||||
cmd.Stdout = nil
|
uintptr(^uint(0)>>1),
|
||||||
cmd.Stderr = nil
|
tokenQuery,
|
||||||
|
uintptr(unsafe.Pointer(&token)),
|
||||||
|
)
|
||||||
|
|
||||||
return cmd.Run() == nil
|
if ret == 0 || token == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closeHandle.Call(token)
|
||||||
|
|
||||||
|
var elevation tokenElevationData
|
||||||
|
var returned uint32
|
||||||
|
|
||||||
|
ret, _, _ = getTokenInformation.Call(
|
||||||
|
token,
|
||||||
|
tokenElevationClass,
|
||||||
|
uintptr(unsafe.Pointer(&elevation)),
|
||||||
|
uintptr(unsafe.Sizeof(elevation)),
|
||||||
|
uintptr(unsafe.Pointer(&returned)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if ret == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return elevation.TokenIsElevated != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func runElevated(action string) error {
|
func runElevated(action string) error {
|
||||||
exe, err := os.Executable()
|
exe, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Pfad des Installers konnte nicht ermittelt werden: %w", err)
|
return fmt.Errorf(
|
||||||
|
"Pfad des Installers konnte nicht ermittelt werden: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
verb, err := syscall.UTF16PtrFromString("runas")
|
verb, err := syscall.UTF16PtrFromString("runas")
|
||||||
@@ -95,34 +150,44 @@ func runElevated(action string) error {
|
|||||||
|
|
||||||
info := shellExecuteInfo{
|
info := shellExecuteInfo{
|
||||||
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
|
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
|
||||||
fMask: seeMaskNocloseprocess,
|
fMask: seeMaskNoCloseProcess,
|
||||||
lpVerb: verb,
|
lpVerb: verb,
|
||||||
lpFile: file,
|
lpFile: file,
|
||||||
lpParameters: parameters,
|
lpParameters: parameters,
|
||||||
nShow: 1, // SW_SHOWNORMAL
|
nShow: swShow,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, _, callErr := shellExecuteExW.Call(uintptr(unsafe.Pointer(&info)))
|
ret, _, callErr := shellExecuteExW.Call(
|
||||||
|
uintptr(unsafe.Pointer(&info)),
|
||||||
|
)
|
||||||
|
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
// ERROR_CANCELLED = 1223:
|
if errno, ok := callErr.(syscall.Errno); ok &&
|
||||||
// Benutzer hat den UAC-Dialog abgebrochen.
|
errno == errorCancelled {
|
||||||
if errno, ok := callErr.(syscall.Errno); ok && errno == 1223 {
|
|
||||||
fmt.Println("Administratorrechte wurden nicht erteilt.")
|
fmt.Println("Administratorrechte wurden nicht erteilt.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Administratorrechte konnten nicht angefordert werden: %w", callErr)
|
return fmt.Errorf(
|
||||||
|
"Administratorrechte konnten nicht angefordert werden: %w",
|
||||||
|
callErr,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auf die erhöhte Instanz warten.
|
|
||||||
if info.hProcess != 0 {
|
if info.hProcess != 0 {
|
||||||
handle := syscall.Handle(info.hProcess)
|
handle := syscall.Handle(info.hProcess)
|
||||||
defer syscall.CloseHandle(handle)
|
defer syscall.CloseHandle(handle)
|
||||||
|
|
||||||
_, err := syscall.WaitForSingleObject(handle, syscall.INFINITE)
|
ret, _, err := waitForSingleObject.Call(
|
||||||
if err != nil {
|
uintptr(handle),
|
||||||
return fmt.Errorf("auf erhöhte Instanz konnte nicht gewartet werden: %w", err)
|
infinite,
|
||||||
|
)
|
||||||
|
|
||||||
|
if ret == 0xFFFFFFFF {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"auf erhöhte Instanz konnte nicht gewartet werden: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ import (
|
|||||||
func platformInstallIntegration(installDir string) error {
|
func platformInstallIntegration(installDir string) error {
|
||||||
binaryPath := filepath.Join(
|
binaryPath := filepath.Join(
|
||||||
installDir,
|
installDir,
|
||||||
"Logof Client",
|
"Logofclient",
|
||||||
)
|
)
|
||||||
|
|
||||||
linkPath := "/usr/local/bin/logofclient"
|
linkPath := "/usr/local/bin/logofclient"
|
||||||
@@ -56,7 +56,7 @@ func platformInstallIntegration(installDir string) error {
|
|||||||
|
|
||||||
desktopEntry := fmt.Sprintf(`[Desktop Entry]
|
desktopEntry := fmt.Sprintf(`[Desktop Entry]
|
||||||
Name=Logof Client
|
Name=Logof Client
|
||||||
Comment=Logof Client
|
Comment=Logofclient
|
||||||
Exec=%s
|
Exec=%s
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
|
|||||||
+3
-3
@@ -26,7 +26,7 @@ func platformInstallIntegration(installDir string) error {
|
|||||||
|
|
||||||
shortcutPath := filepath.Join(
|
shortcutPath := filepath.Join(
|
||||||
startMenuDir,
|
startMenuDir,
|
||||||
"Logof Client.lnk",
|
"Logofclient.lnk",
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := os.MkdirAll(startMenuDir, 0755); err != nil {
|
if err := os.MkdirAll(startMenuDir, 0755); err != nil {
|
||||||
@@ -58,7 +58,7 @@ func platformRemoveIntegration() error {
|
|||||||
|
|
||||||
shortcutPath := filepath.Join(
|
shortcutPath := filepath.Join(
|
||||||
startMenuDir,
|
startMenuDir,
|
||||||
"Logof Client.lnk",
|
"Logofclient.lnk",
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := os.Remove(shortcutPath); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(shortcutPath); err != nil && !os.IsNotExist(err) {
|
||||||
@@ -117,7 +117,7 @@ func platformCreateShortcut(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Beschreibung.
|
// Beschreibung.
|
||||||
if _, err := oleutil.PutProperty(shortcut, "Description", "Logof Client"); err != nil {
|
if _, err := oleutil.PutProperty(shortcut, "Description", "Logofclient"); err != nil {
|
||||||
return fmt.Errorf("Description konnte nicht gesetzt werden: %w", err)
|
return fmt.Errorf("Description konnte nicht gesetzt werden: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user