aboutsummaryrefslogtreecommitdiff
path: root/pkg/goexec/tsch/demand.go
blob: c397453c51ff4eda254c5731293f1cff6cbaae5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package tschexec

import (
  "context"
  "fmt"
  "github.com/FalconOpsLLC/goexec/pkg/goexec"
  "github.com/oiweiwei/go-msrpc/msrpc/tsch/itaskschedulerservice/v1"
  "github.com/rs/zerolog"
)

const (
  MethodDemand = "Demand"
)

type TschDemand struct {
  Tsch
  goexec.Executor
  goexec.Cleaner

  IO goexec.ExecutionIO

  NoDelete  bool
  NoStart   bool
  SessionId uint32
}

func (m *TschDemand) Execute(ctx context.Context, in *goexec.ExecutionIO) (err error) {

  log := zerolog.Ctx(ctx).With().
    Str("module", ModuleName).
    Str("method", MethodDemand).
    Str("task", m.TaskPath).
    Logger()

  path, err := m.registerTask(ctx,
    &registerOptions{
      AllowStartOnDemand: true,
      AllowHardTerminate: true,
      Hidden:             !m.NotHidden,
      triggers:           taskTriggers{},
    },
    in,
  )
  if err != nil {
    return err
  }

  log.Info().Msg("Task registered")

  if !m.NoDelete {
    m.AddCleaners(func(ctxInner context.Context) error {
      return m.deleteTask(ctxInner, path)
    })
  }

  if !m.NoStart {

    var flags uint32
    if m.SessionId != 0 {
      flags |= 4
    }

    runResponse, err := m.tsch.Run(ctx, &itaskschedulerservice.RunRequest{
      Path:      path,
      Flags:     flags,
      SessionID: m.SessionId,
    })

    if err != nil {
      log.Error().Err(err).Msg("Failed to run task")
      return fmt.Errorf("run task: %w", err)
    }
    if ret := uint32(runResponse.Return); ret != 0 {
      log.Error().Str("code", fmt.Sprintf("0x%08x", ret)).Msg("Task returned non-zero exit code")
      return fmt.Errorf("task returned non-zero exit code: 0x%08x", ret)
    }

    log.Info().Msg("Task started successfully")
  }
  return
}