2026-03-05 00:04:26 -06:00
|
|
|
//go:build windows
|
|
|
|
|
// +build windows
|
|
|
|
|
|
|
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
2026-05-17 00:51:17 -05:00
|
|
|
"syscall"
|
2026-05-21 09:51:12 -05:00
|
|
|
"unsafe"
|
2026-03-05 00:04:26 -06:00
|
|
|
|
|
|
|
|
"overlord-client/cmd/agent/wire"
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-21 09:51:12 -05:00
|
|
|
func DiskUsage(path string) (int64, int64, string, bool) {
|
|
|
|
|
kernel32 := syscall.NewLazyDLL("kernel32.dll")
|
|
|
|
|
getDiskFreeSpaceExW := kernel32.NewProc("GetDiskFreeSpaceExW")
|
|
|
|
|
getVolumeInformationW := kernel32.NewProc("GetVolumeInformationW")
|
|
|
|
|
|
|
|
|
|
root, err := syscall.UTF16PtrFromString(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, 0, "", false
|
|
|
|
|
}
|
|
|
|
|
var freeAvail, totalBytes, totalFree uint64
|
|
|
|
|
r1, _, _ := getDiskFreeSpaceExW.Call(
|
|
|
|
|
uintptr(unsafe.Pointer(root)),
|
|
|
|
|
uintptr(unsafe.Pointer(&freeAvail)),
|
|
|
|
|
uintptr(unsafe.Pointer(&totalBytes)),
|
|
|
|
|
uintptr(unsafe.Pointer(&totalFree)),
|
|
|
|
|
)
|
|
|
|
|
if r1 == 0 {
|
|
|
|
|
return 0, 0, "", false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fsType := ""
|
|
|
|
|
var fsNameBuf [32]uint16
|
|
|
|
|
r2, _, _ := getVolumeInformationW.Call(
|
|
|
|
|
uintptr(unsafe.Pointer(root)),
|
|
|
|
|
0, 0, 0, 0, 0,
|
|
|
|
|
uintptr(unsafe.Pointer(&fsNameBuf[0])),
|
|
|
|
|
uintptr(len(fsNameBuf)),
|
|
|
|
|
)
|
|
|
|
|
if r2 != 0 {
|
|
|
|
|
fsType = syscall.UTF16ToString(fsNameBuf[:])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return int64(freeAvail), int64(totalBytes), fsType, true
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-05 00:04:26 -06:00
|
|
|
func enrichFileEntry(entry *wire.FileEntry, info os.FileInfo) {
|
2026-05-17 00:51:17 -05:00
|
|
|
if d, ok := info.Sys().(*syscall.Win32FileAttributeData); ok {
|
|
|
|
|
entry.Attrs = d.FileAttributes
|
|
|
|
|
}
|
2026-03-05 00:04:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ChangeFilePermissions(path string, mode string) error {
|
|
|
|
|
return fmt.Errorf("chmod not supported on Windows")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ExecuteFile(path string) error {
|
|
|
|
|
|
|
|
|
|
ext := ""
|
|
|
|
|
lastDot := -1
|
|
|
|
|
for i := len(path) - 1; i >= 0; i-- {
|
|
|
|
|
if path[i] == '.' {
|
|
|
|
|
lastDot = i
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if path[i] == '/' || path[i] == '\\' {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if lastDot >= 0 {
|
|
|
|
|
ext = path[lastDot:]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := os.Stat(path); err != nil {
|
|
|
|
|
return fmt.Errorf("file not found: %s", path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch ext {
|
|
|
|
|
case ".exe", ".com":
|
|
|
|
|
|
|
|
|
|
return execCommand(path)
|
|
|
|
|
case ".bat", ".cmd":
|
|
|
|
|
|
|
|
|
|
return execCommand("cmd.exe", "/c", path)
|
|
|
|
|
case ".ps1":
|
|
|
|
|
|
|
|
|
|
return execCommand("powershell.exe", "-ExecutionPolicy", "Bypass", "-File", path)
|
|
|
|
|
case ".vbs":
|
|
|
|
|
|
|
|
|
|
return execCommand("wscript.exe", path)
|
|
|
|
|
case ".py":
|
|
|
|
|
|
|
|
|
|
return execCommand("python", path)
|
|
|
|
|
case ".js":
|
|
|
|
|
|
|
|
|
|
return execCommand("node", path)
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("unsupported file type: %s", ext)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func execCommand(name string, args ...string) error {
|
|
|
|
|
cmd := exec.Command(name, args...)
|
|
|
|
|
|
|
|
|
|
return cmd.Start()
|
|
|
|
|
}
|