fleet/orbit/pkg/go-paniclog/paniclog_windows.go
Jordan Montgomery c97a0e2363
Fix Windows lint issues and enable linting on Windows (#28704)
For https://github.com/fleetdm/fleet/issues/9943

This will help us avoid issues like this where the log message never
worked right:
https://github.com/fleetdm/fleet/pull/28296#discussion_r2047505191

Most of the changes are no-op type changes like removing unneeded
typecast or disabling gosec on reviewed lines of code

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [x] Added/updated automated tests
- [x] A detailed QA plan exists on the associated ticket (if it isn't
there, work with the product group's QA engineer to add it)
- [x] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [x] Make sure fleetd is compatible with the latest released version of
Fleet (see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/fleetd-development-and-release-strategy.md)).
- [x] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [x] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [x] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2025-05-02 16:11:26 -04:00

87 lines
2.2 KiB
Go

// Log the panic under windows to the log file
//
// Code from minix, via
//
// https://play.golang.org/p/kLtct7lSUg
//go:build windows
// +build windows
package paniclog
import (
"errors"
"os"
"syscall"
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
procGetStdHandle = kernel32.MustFindProc("GetStdHandle")
)
func dupFD(fd uintptr) (syscall.Handle, error) {
// Cribbed from https://github.com/golang/go/blob/go1.8/src/syscall/exec_windows.go#L303.
p, err := syscall.GetCurrentProcess()
if err != nil {
return 0, err
}
var h syscall.Handle
return h, syscall.DuplicateHandle(p, syscall.Handle(fd), p, &h, 0, true, syscall.DUPLICATE_SAME_ACCESS)
}
func getStdHandle(stdHandle int32) (syscall.Handle, error) {
r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 2, uintptr(stdHandle), 0, 0)
rh0 := syscall.Handle(r0)
if rh0 == syscall.InvalidHandle {
if e1 != 0 {
return syscall.InvalidHandle, error(e1)
}
return syscall.InvalidHandle, syscall.EINVAL
}
return syscall.Handle(r0), nil
}
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
if r0 == 0 {
if e1 != 0 {
return error(e1)
}
return syscall.EINVAL
}
return nil
}
func redirectStderr(f *os.File) (UndoFunction, error) {
stderrFd, err := getStdHandle(syscall.STD_ERROR_HANDLE)
if err != nil {
return nil, errors.New("Failed to redirect stderr to file: " + err.Error())
}
// duplicate the handle to match unix behavior
fHandle, err := dupFD(f.Fd())
if err != nil {
return nil, errors.New("Failed to duplicate file: " + err.Error())
}
err = setStdHandle(syscall.STD_ERROR_HANDLE, fHandle)
if err != nil {
return nil, errors.New("Failed to redirect stderr to file: " + err.Error())
}
undo := func() error {
err := setStdHandle(syscall.STD_ERROR_HANDLE, stderrFd)
if err != nil {
return errors.New("Failed to redirect stderr to file: " + err.Error())
}
err = syscall.CloseHandle(fHandle)
if err != nil {
return errors.New("Failed to close STD_ERROR handle: " + err.Error())
}
return nil
}
return undo, nil
}