Compare commits

...
2 Commits
Author SHA1 Message Date
fierke 373359116c windwows's architecture is still shitty 2026-09-27 16:30:46 +02:00
fierke 1cb2296480 windowss architecture is shitty 2026-09-27 16:30:02 +02:00
4 changed files with 111 additions and 107 deletions
Binary file not shown.
+9
View File
@@ -47,8 +47,17 @@ func main() {
Repo: envOrDefault("GITEA_REPO", defaultRepo), Repo: envOrDefault("GITEA_REPO", defaultRepo),
} }
if err := platformEnsureElevated(); err != nil {
printError(err)
os.Exit(1)
}
args := os.Args[1:] args := os.Args[1:]
if len(args) > 0 && args[0] == "--elevated" {
args = args[1:]
}
if len(args) == 0 { if len(args) == 0 {
runTUI(config) runTUI(config)
return return
+4
View File
@@ -13,6 +13,10 @@ func getInstallDir() (string, error) {
return "/opt/logofclient", nil return "/opt/logofclient", nil
} }
func platformEnsureElevated() error {
return nil
}
func platformRunPrivileged(config Config, action string) error { func platformRunPrivileged(config Config, action string) error {
// Bereits als root gestartet. // Bereits als root gestartet.
if os.Geteuid() == 0 { if os.Geteuid() == 0 {
+91 -100
View File
@@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@@ -22,16 +21,15 @@ var (
kernel32 = syscall.NewLazyDLL("kernel32.dll") kernel32 = syscall.NewLazyDLL("kernel32.dll")
closeHandle = kernel32.NewProc("CloseHandle") closeHandle = kernel32.NewProc("CloseHandle")
waitForSingleObject = kernel32.NewProc("WaitForSingleObject")
) )
const ( const (
tokenQuery = 0x0008 tokenQuery = 0x0008
tokenElevationClass = 20 tokenElevationClass = 20
seeMaskNoCloseProcess = 0x00000040
swShow = 1
infinite = 0xFFFFFFFF
errorCancelled = 1223 errorCancelled = 1223
swShow = 1
) )
type shellExecuteInfo struct { type shellExecuteInfo struct {
@@ -56,46 +54,94 @@ type tokenElevationData struct {
TokenIsElevated uint32 TokenIsElevated uint32
} }
func getInstallDir() (string, error) { func platformEnsureElevated() error {
programFiles := os.Getenv("ProgramFiles") // Die erhöhte Instanz wurde bereits gestartet.
// Sie darf sich nicht noch einmal selbst per runas starten.
if programFiles == "" { if hasElevatedFlag() {
return "", errors.New("ProgramFiles ist nicht gesetzt")
}
return filepath.Join(programFiles, "logofclient"), nil
}
func platformRunPrivileged(config Config, action string) error {
if isWindowsElevated() {
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 nil
} }
return runElevated(action) if isWindowsElevated() {
return nil
}
return restartElevated()
}
func hasElevatedFlag() bool {
for _, arg := range os.Args[1:] {
if arg == "--elevated" {
return true
}
}
return false
}
func restartElevated() error {
exe, err := os.Executable()
if err != nil {
return fmt.Errorf(
"Pfad des Installers konnte nicht ermittelt werden: %w",
err,
)
}
verb, err := syscall.UTF16PtrFromString("runas")
if err != nil {
return err
}
file, err := syscall.UTF16PtrFromString(exe)
if err != nil {
return err
}
// Die erhöhte Instanz bekommt nur das interne Flag.
parameters, err := syscall.UTF16PtrFromString("--elevated")
if err != nil {
return err
}
info := shellExecuteInfo{
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
lpVerb: verb,
lpFile: file,
lpParameters: parameters,
nShow: swShow,
}
ret, _, callErr := shellExecuteExW.Call(
uintptr(unsafe.Pointer(&info)),
)
if ret == 0 {
if errno, ok := callErr.(syscall.Errno); ok &&
errno == errorCancelled {
fmt.Println("Administratorrechte wurden nicht erteilt.")
return errors.New("Administratorrechte erforderlich")
}
return fmt.Errorf(
"Administratorrechte konnten nicht angefordert werden: %w",
callErr,
)
}
// WICHTIG:
// Die ursprüngliche Instanz beendet sich sofort.
// Nur die erhöhte Instanz führt danach main() weiter aus.
os.Exit(0)
return nil
} }
func isWindowsElevated() bool { func isWindowsElevated() bool {
var token uintptr var token uintptr
// GetCurrentProcess() = -1
ret, _, _ := openProcessToken.Call( ret, _, _ := openProcessToken.Call(
uintptr(^uint(0)>>1), uintptr(^uint(0)),
tokenQuery, tokenQuery,
uintptr(unsafe.Pointer(&token)), uintptr(unsafe.Pointer(&token)),
) )
@@ -124,72 +170,17 @@ func isWindowsElevated() bool {
return elevation.TokenIsElevated != 0 return elevation.TokenIsElevated != 0
} }
func runElevated(action string) error { func platformRunPrivileged(config Config, action string) error {
exe, err := os.Executable() // Die komplette Windows-Anwendung läuft bereits erhöht.
if err != nil { return runAction(config, action)
return fmt.Errorf( }
"Pfad des Installers konnte nicht ermittelt werden: %w",
err,
)
}
verb, err := syscall.UTF16PtrFromString("runas")
if err != nil {
return err
}
file, err := syscall.UTF16PtrFromString(exe)
if err != nil {
return err
}
parameters, err := syscall.UTF16PtrFromString(action)
if err != nil {
return err
}
info := shellExecuteInfo{
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
fMask: seeMaskNoCloseProcess,
lpVerb: verb,
lpFile: file,
lpParameters: parameters,
nShow: swShow,
}
ret, _, callErr := shellExecuteExW.Call(
uintptr(unsafe.Pointer(&info)),
)
if ret == 0 {
if errno, ok := callErr.(syscall.Errno); ok &&
errno == errorCancelled {
fmt.Println("Administratorrechte wurden nicht erteilt.")
return nil
}
return fmt.Errorf( func getInstallDir() (string, error) {
"Administratorrechte konnten nicht angefordert werden: %w", programFiles := os.Getenv("ProgramFiles")
callErr,
)
}
if info.hProcess != 0 {
handle := syscall.Handle(info.hProcess)
defer syscall.CloseHandle(handle)
ret, _, err := waitForSingleObject.Call( if programFiles == "" {
uintptr(handle), return "", errors.New("ProgramFiles ist nicht gesetzt")
infinite,
)
if ret == 0xFFFFFFFF {
return fmt.Errorf(
"auf erhöhte Instanz konnte nicht gewartet werden: %w",
err,
)
}
} }
return nil return filepath.Join(programFiles, "logofclient"), nil
} }