update gopsutil@01afd763e6c0 + go mod vendor (#9346)
- This version of gopsutil fixes the build for FreeBSD. - See https://github.com/shirou/gopsutil/pull/895
This commit is contained in:
parent
7a7dd7379f
commit
a9aa4d301f
2
go.mod
2
go.mod
|
@ -125,7 +125,7 @@ require (
|
|||
github.com/ryanuber/go-glob v1.0.0
|
||||
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
|
||||
github.com/sasha-s/go-deadlock v0.2.0
|
||||
github.com/shirou/gopsutil v2.19.9+incompatible
|
||||
github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible
|
||||
github.com/stretchr/testify v1.5.1
|
||||
go.etcd.io/bbolt v1.3.4
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200425165423-262c93980547
|
||||
|
|
2
go.sum
2
go.sum
|
@ -853,6 +853,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
|
|||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shirou/gopsutil v2.19.9+incompatible h1:IrPVlK4nfwW10DF7pW+7YJKws9NkgNzWozwwWv9FsgY=
|
||||
github.com/shirou/gopsutil v2.19.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible h1:IYOqH6sML3rQGNVEQ5foLtpDt4TeW8PIUBuI9f8itkI=
|
||||
github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
|
|
|
@ -14,8 +14,7 @@ import (
|
|||
)
|
||||
|
||||
// TimesStat contains the amounts of time the CPU has spent performing different
|
||||
// kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of
|
||||
// a second). It is based on linux /proc/stat file.
|
||||
// kinds of work. Time units are in seconds. It is based on linux /proc/stat file.
|
||||
type TimesStat struct {
|
||||
CPU string `json:"cpu"`
|
||||
User float64 `json:"user"`
|
||||
|
@ -87,8 +86,8 @@ func (c TimesStat) String() string {
|
|||
|
||||
// Total returns the total number of seconds in a CPUTimesStat
|
||||
func (c TimesStat) Total() float64 {
|
||||
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal +
|
||||
c.Guest + c.GuestNice + c.Idle
|
||||
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq +
|
||||
c.Steal + c.Idle
|
||||
return total
|
||||
}
|
||||
|
||||
|
@ -99,7 +98,7 @@ func (c InfoStat) String() string {
|
|||
|
||||
func getAllBusy(t TimesStat) (float64, float64) {
|
||||
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
|
||||
t.Softirq + t.Steal + t.Guest + t.GuestNice
|
||||
t.Softirq + t.Steal
|
||||
return busy + t.Idle, busy
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package cpu
|
|||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -23,6 +24,21 @@ const (
|
|||
// default value. from time.h
|
||||
var ClocksPerSec = float64(128)
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out, err := invoke.Command(getconf, "CLK_TCK")
|
||||
// ignore errors
|
||||
if err == nil {
|
||||
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
|
||||
if err == nil {
|
||||
ClocksPerSec = float64(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Times(percpu bool) ([]TimesStat, error) {
|
||||
return TimesWithContext(context.Background(), percpu)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
package cpu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var ClocksPerSec = float64(128)
|
||||
var cpuMatch = regexp.MustCompile(`^CPU:`)
|
||||
var originMatch = regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Stepping\s*=\s*(.+)`)
|
||||
var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`)
|
||||
var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`)
|
||||
var cpuEnd = regexp.MustCompile(`^Trying to mount root`)
|
||||
var cpuTimesSize int
|
||||
var emptyTimes cpuTimes
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out, err := invoke.Command(getconf, "CLK_TCK")
|
||||
// ignore errors
|
||||
if err == nil {
|
||||
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
|
||||
if err == nil {
|
||||
ClocksPerSec = float64(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func timeStat(name string, t *cpuTimes) *TimesStat {
|
||||
return &TimesStat{
|
||||
User: float64(t.User) / ClocksPerSec,
|
||||
Nice: float64(t.Nice) / ClocksPerSec,
|
||||
System: float64(t.Sys) / ClocksPerSec,
|
||||
Idle: float64(t.Idle) / ClocksPerSec,
|
||||
Irq: float64(t.Intr) / ClocksPerSec,
|
||||
CPU: name,
|
||||
}
|
||||
}
|
||||
|
||||
func Times(percpu bool) ([]TimesStat, error) {
|
||||
return TimesWithContext(context.Background(), percpu)
|
||||
}
|
||||
|
||||
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
||||
if percpu {
|
||||
buf, err := unix.SysctlRaw("kern.cp_times")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We can't do this in init due to the conflict with cpu.init()
|
||||
if cpuTimesSize == 0 {
|
||||
cpuTimesSize = int(reflect.TypeOf(cpuTimes{}).Size())
|
||||
}
|
||||
|
||||
ncpus := len(buf) / cpuTimesSize
|
||||
ret := make([]TimesStat, 0, ncpus)
|
||||
for i := 0; i < ncpus; i++ {
|
||||
times := (*cpuTimes)(unsafe.Pointer(&buf[i*cpuTimesSize]))
|
||||
if *times == emptyTimes {
|
||||
// CPU not present
|
||||
continue
|
||||
}
|
||||
ret = append(ret, *timeStat(fmt.Sprintf("cpu%d", len(ret)), times))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
buf, err := unix.SysctlRaw("kern.cp_time")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
times := (*cpuTimes)(unsafe.Pointer(&buf[0]))
|
||||
return []TimesStat{*timeStat("cpu-total", times)}, nil
|
||||
}
|
||||
|
||||
// Returns only one InfoStat on DragonflyBSD. The information regarding core
|
||||
// count, however is accurate and it is assumed that all InfoStat attributes
|
||||
// are the same across CPUs.
|
||||
func Info() ([]InfoStat, error) {
|
||||
return InfoWithContext(context.Background())
|
||||
}
|
||||
|
||||
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
||||
const dmesgBoot = "/var/run/dmesg.boot"
|
||||
|
||||
c, err := parseDmesgBoot(dmesgBoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var u32 uint32
|
||||
if u32, err = unix.SysctlUint32("hw.clockrate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Mhz = float64(u32)
|
||||
|
||||
var num int
|
||||
var buf string
|
||||
if buf, err = unix.Sysctl("hw.cpu_topology.tree"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
num = strings.Count(buf, "CHIP")
|
||||
c.Cores = int32(strings.Count(string(buf), "CORE") / num)
|
||||
|
||||
if c.ModelName, err = unix.Sysctl("hw.model"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]InfoStat, num)
|
||||
for i := 0; i < num; i++ {
|
||||
ret[i] = c
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func parseDmesgBoot(fileName string) (InfoStat, error) {
|
||||
c := InfoStat{}
|
||||
lines, _ := common.ReadLines(fileName)
|
||||
for _, line := range lines {
|
||||
if matches := cpuEnd.FindStringSubmatch(line); matches != nil {
|
||||
break
|
||||
} else if matches := originMatch.FindStringSubmatch(line); matches != nil {
|
||||
c.VendorID = matches[1]
|
||||
t, err := strconv.ParseInt(matches[2], 10, 32)
|
||||
if err != nil {
|
||||
return c, fmt.Errorf("unable to parse DragonflyBSD CPU stepping information from %q: %v", line, err)
|
||||
}
|
||||
c.Stepping = int32(t)
|
||||
} else if matches := featuresMatch.FindStringSubmatch(line); matches != nil {
|
||||
for _, v := range strings.Split(matches[1], ",") {
|
||||
c.Flags = append(c.Flags, strings.ToLower(v))
|
||||
}
|
||||
} else if matches := featuresMatch2.FindStringSubmatch(line); matches != nil {
|
||||
for _, v := range strings.Split(matches[1], ",") {
|
||||
c.Flags = append(c.Flags, strings.ToLower(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func CountsWithContext(ctx context.Context, logical bool) (int, error) {
|
||||
return runtime.NumCPU(), nil
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package cpu
|
||||
|
||||
type cpuTimes struct {
|
||||
User uint64
|
||||
Nice uint64
|
||||
Sys uint64
|
||||
Intr uint64
|
||||
Idle uint64
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows
|
||||
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!dragonfly
|
||||
|
||||
package cpu
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package cpu
|
||||
|
||||
type cpuTimes struct {
|
||||
User uint64
|
||||
Nice uint64
|
||||
Sys uint64
|
||||
Intr uint64
|
||||
Idle uint64
|
||||
}
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
||||
var CPUTick = float64(100)
|
||||
var ClocksPerSec = float64(100)
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
|
@ -25,7 +25,7 @@ func init() {
|
|||
if err == nil {
|
||||
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
|
||||
if err == nil {
|
||||
CPUTick = i
|
||||
ClocksPerSec = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func finishCPUInfo(c *InfoStat) error {
|
|||
lines, err = common.ReadLines(sysCPUPath(c.CPU, "cpufreq/cpuinfo_max_freq"))
|
||||
// if we encounter errors below such as there are no cpuinfo_max_freq file,
|
||||
// we just ignore. so let Mhz is 0.
|
||||
if err != nil {
|
||||
if err != nil || len(lines) == 0 {
|
||||
return nil
|
||||
}
|
||||
value, err = strconv.ParseFloat(lines[0], 64)
|
||||
|
@ -250,34 +250,34 @@ func parseStatLine(line string) (*TimesStat, error) {
|
|||
|
||||
ct := &TimesStat{
|
||||
CPU: cpu,
|
||||
User: user / CPUTick,
|
||||
Nice: nice / CPUTick,
|
||||
System: system / CPUTick,
|
||||
Idle: idle / CPUTick,
|
||||
Iowait: iowait / CPUTick,
|
||||
Irq: irq / CPUTick,
|
||||
Softirq: softirq / CPUTick,
|
||||
User: user / ClocksPerSec,
|
||||
Nice: nice / ClocksPerSec,
|
||||
System: system / ClocksPerSec,
|
||||
Idle: idle / ClocksPerSec,
|
||||
Iowait: iowait / ClocksPerSec,
|
||||
Irq: irq / ClocksPerSec,
|
||||
Softirq: softirq / ClocksPerSec,
|
||||
}
|
||||
if len(fields) > 8 { // Linux >= 2.6.11
|
||||
steal, err := strconv.ParseFloat(fields[8], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ct.Steal = steal / CPUTick
|
||||
ct.Steal = steal / ClocksPerSec
|
||||
}
|
||||
if len(fields) > 9 { // Linux >= 2.6.24
|
||||
guest, err := strconv.ParseFloat(fields[9], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ct.Guest = guest / CPUTick
|
||||
ct.Guest = guest / ClocksPerSec
|
||||
}
|
||||
if len(fields) > 10 { // Linux >= 3.2.0
|
||||
guestNice, err := strconv.ParseFloat(fields[10], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ct.GuestNice = guestNice / CPUTick
|
||||
ct.GuestNice = guestNice / ClocksPerSec
|
||||
}
|
||||
|
||||
return ct, nil
|
||||
|
|
|
@ -50,7 +50,7 @@ type Win32_PerfFormattedData_PerfOS_System struct {
|
|||
}
|
||||
|
||||
const (
|
||||
win32_TicksPerSecond = 10000000.0
|
||||
ClocksPerSec = 10000000.0
|
||||
|
||||
// systemProcessorPerformanceInformationClass information class to query with NTQuerySystemInformation
|
||||
// https://processhacker.sourceforge.io/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0
|
||||
|
@ -159,10 +159,10 @@ func perCPUTimes() ([]TimesStat, error) {
|
|||
for core, v := range stats {
|
||||
c := TimesStat{
|
||||
CPU: fmt.Sprintf("cpu%d", core),
|
||||
User: float64(v.UserTime) / win32_TicksPerSecond,
|
||||
System: float64(v.KernelTime-v.IdleTime) / win32_TicksPerSecond,
|
||||
Idle: float64(v.IdleTime) / win32_TicksPerSecond,
|
||||
Irq: float64(v.InterruptTime) / win32_TicksPerSecond,
|
||||
User: float64(v.UserTime) / ClocksPerSec,
|
||||
System: float64(v.KernelTime-v.IdleTime) / ClocksPerSec,
|
||||
Idle: float64(v.IdleTime) / ClocksPerSec,
|
||||
Irq: float64(v.InterruptTime) / ClocksPerSec,
|
||||
}
|
||||
ret = append(ret, c)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package disk
|
|||
import (
|
||||
"context"
|
||||
"path"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"golang.org/x/sys/unix"
|
||||
|
@ -18,63 +17,51 @@ func Partitions(all bool) ([]PartitionStat, error) {
|
|||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||
var ret []PartitionStat
|
||||
|
||||
count, err := Getfsstat(nil, MntWait)
|
||||
count, err := unix.Getfsstat(nil, unix.MNT_WAIT)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
fs := make([]Statfs, count)
|
||||
if _, err = Getfsstat(fs, MntWait); err != nil {
|
||||
fs := make([]unix.Statfs_t, count)
|
||||
if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
for _, stat := range fs {
|
||||
opts := "rw"
|
||||
if stat.Flags&MntReadOnly != 0 {
|
||||
if stat.Flags&unix.MNT_RDONLY != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if stat.Flags&MntSynchronous != 0 {
|
||||
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||
opts += ",sync"
|
||||
}
|
||||
if stat.Flags&MntNoExec != 0 {
|
||||
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
||||
opts += ",noexec"
|
||||
}
|
||||
if stat.Flags&MntNoSuid != 0 {
|
||||
if stat.Flags&unix.MNT_NOSUID != 0 {
|
||||
opts += ",nosuid"
|
||||
}
|
||||
if stat.Flags&MntUnion != 0 {
|
||||
if stat.Flags&unix.MNT_UNION != 0 {
|
||||
opts += ",union"
|
||||
}
|
||||
if stat.Flags&MntAsync != 0 {
|
||||
if stat.Flags&unix.MNT_ASYNC != 0 {
|
||||
opts += ",async"
|
||||
}
|
||||
if stat.Flags&MntSuidDir != 0 {
|
||||
opts += ",suiddir"
|
||||
if stat.Flags&unix.MNT_DONTBROWSE != 0 {
|
||||
opts += ",nobrowse"
|
||||
}
|
||||
if stat.Flags&MntSoftDep != 0 {
|
||||
opts += ",softdep"
|
||||
if stat.Flags&unix.MNT_AUTOMOUNTED != 0 {
|
||||
opts += ",automounted"
|
||||
}
|
||||
if stat.Flags&MntNoSymFollow != 0 {
|
||||
opts += ",nosymfollow"
|
||||
if stat.Flags&unix.MNT_JOURNALED != 0 {
|
||||
opts += ",journaled"
|
||||
}
|
||||
if stat.Flags&MntGEOMJournal != 0 {
|
||||
opts += ",gjounalc"
|
||||
}
|
||||
if stat.Flags&MntMultilabel != 0 {
|
||||
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
||||
opts += ",multilabel"
|
||||
}
|
||||
if stat.Flags&MntACLs != 0 {
|
||||
opts += ",acls"
|
||||
if stat.Flags&unix.MNT_NOATIME != 0 {
|
||||
opts += ",noatime"
|
||||
}
|
||||
if stat.Flags&MntNoATime != 0 {
|
||||
opts += ",noattime"
|
||||
}
|
||||
if stat.Flags&MntClusterRead != 0 {
|
||||
opts += ",nocluster"
|
||||
}
|
||||
if stat.Flags&MntClusterWrite != 0 {
|
||||
opts += ",noclusterw"
|
||||
}
|
||||
if stat.Flags&MntNFS4ACLs != 0 {
|
||||
opts += ",nfs4acls"
|
||||
if stat.Flags&unix.MNT_NODEV != 0 {
|
||||
opts += ",nodev"
|
||||
}
|
||||
d := PartitionStat{
|
||||
Device: common.IntToString(stat.Mntfromname[:]),
|
||||
|
@ -94,25 +81,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
|
||||
return GetfsstatWithContext(context.Background(), buf, flags)
|
||||
}
|
||||
|
||||
func GetfsstatWithContext(ctx context.Context, buf []Statfs, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
var bufsize uintptr
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
|
||||
}
|
||||
r0, _, e1 := unix.Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getFsType(stat unix.Statfs_t) string {
|
||||
return common.IntToString(stat.Fstypename[:])
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
// +build darwin
|
||||
// +build 386
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
MntWait = 1
|
||||
MfsNameLen = 15 /* length of fs type name, not inc. nul */
|
||||
MNameLen = 90 /* length of buffer for returned name */
|
||||
|
||||
MFSTYPENAMELEN = 16 /* length of fs type name including null */
|
||||
MAXPATHLEN = 1024
|
||||
MNAMELEN = MAXPATHLEN
|
||||
|
||||
SYS_GETFSSTAT64 = 347
|
||||
)
|
||||
|
||||
type Fsid struct{ val [2]int32 } /* file system id type */
|
||||
type uid_t int32
|
||||
|
||||
// sys/mount.h
|
||||
const (
|
||||
MntReadOnly = 0x00000001 /* read only filesystem */
|
||||
MntSynchronous = 0x00000002 /* filesystem written synchronously */
|
||||
MntNoExec = 0x00000004 /* can't exec from filesystem */
|
||||
MntNoSuid = 0x00000008 /* don't honor setuid bits on fs */
|
||||
MntUnion = 0x00000020 /* union with underlying filesystem */
|
||||
MntAsync = 0x00000040 /* filesystem written asynchronously */
|
||||
MntSuidDir = 0x00100000 /* special handling of SUID on dirs */
|
||||
MntSoftDep = 0x00200000 /* soft updates being done */
|
||||
MntNoSymFollow = 0x00400000 /* do not follow symlinks */
|
||||
MntGEOMJournal = 0x02000000 /* GEOM journal support enabled */
|
||||
MntMultilabel = 0x04000000 /* MAC support for individual objects */
|
||||
MntACLs = 0x08000000 /* ACL support enabled */
|
||||
MntNoATime = 0x10000000 /* disable update of file access time */
|
||||
MntClusterRead = 0x40000000 /* disable cluster read */
|
||||
MntClusterWrite = 0x80000000 /* disable cluster write */
|
||||
MntNFS4ACLs = 0x00000010
|
||||
)
|
||||
|
||||
// https://github.com/golang/go/blob/master/src/syscall/ztypes_darwin_386.go#L82
|
||||
type Statfs struct {
|
||||
Bsize uint32
|
||||
Iosize int32
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail uint64
|
||||
Files uint64
|
||||
Ffree uint64
|
||||
Fsid Fsid
|
||||
Owner uint32
|
||||
Type uint32
|
||||
Flags uint32
|
||||
Fssubtype uint32
|
||||
Fstypename [16]int8
|
||||
Mntonname [1024]int8
|
||||
Mntfromname [1024]int8
|
||||
Reserved [8]uint32
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// +build darwin
|
||||
// +build amd64
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
MntWait = 1
|
||||
MfsNameLen = 15 /* length of fs type name, not inc. nul */
|
||||
MNameLen = 90 /* length of buffer for returned name */
|
||||
|
||||
MFSTYPENAMELEN = 16 /* length of fs type name including null */
|
||||
MAXPATHLEN = 1024
|
||||
MNAMELEN = MAXPATHLEN
|
||||
|
||||
SYS_GETFSSTAT64 = 347
|
||||
)
|
||||
|
||||
type Fsid struct{ val [2]int32 } /* file system id type */
|
||||
type uid_t int32
|
||||
|
||||
// sys/mount.h
|
||||
const (
|
||||
MntReadOnly = 0x00000001 /* read only filesystem */
|
||||
MntSynchronous = 0x00000002 /* filesystem written synchronously */
|
||||
MntNoExec = 0x00000004 /* can't exec from filesystem */
|
||||
MntNoSuid = 0x00000008 /* don't honor setuid bits on fs */
|
||||
MntUnion = 0x00000020 /* union with underlying filesystem */
|
||||
MntAsync = 0x00000040 /* filesystem written asynchronously */
|
||||
MntSuidDir = 0x00100000 /* special handling of SUID on dirs */
|
||||
MntSoftDep = 0x00200000 /* soft updates being done */
|
||||
MntNoSymFollow = 0x00400000 /* do not follow symlinks */
|
||||
MntGEOMJournal = 0x02000000 /* GEOM journal support enabled */
|
||||
MntMultilabel = 0x04000000 /* MAC support for individual objects */
|
||||
MntACLs = 0x08000000 /* ACL support enabled */
|
||||
MntNoATime = 0x10000000 /* disable update of file access time */
|
||||
MntClusterRead = 0x40000000 /* disable cluster read */
|
||||
MntClusterWrite = 0x80000000 /* disable cluster write */
|
||||
MntNFS4ACLs = 0x00000010
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Bsize uint32
|
||||
Iosize int32
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail uint64
|
||||
Files uint64
|
||||
Ffree uint64
|
||||
Fsid Fsid
|
||||
Owner uint32
|
||||
Type uint32
|
||||
Flags uint32
|
||||
Fssubtype uint32
|
||||
Fstypename [16]int8
|
||||
Mntonname [1024]int8
|
||||
Mntfromname [1024]int8
|
||||
Reserved [8]uint32
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// +build darwin
|
||||
// +build arm64
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
MntWait = 1
|
||||
MfsNameLen = 15 /* length of fs type name, not inc. nul */
|
||||
MNameLen = 90 /* length of buffer for returned name */
|
||||
|
||||
MFSTYPENAMELEN = 16 /* length of fs type name including null */
|
||||
MAXPATHLEN = 1024
|
||||
MNAMELEN = MAXPATHLEN
|
||||
|
||||
SYS_GETFSSTAT64 = 347
|
||||
)
|
||||
|
||||
type Fsid struct{ val [2]int32 } /* file system id type */
|
||||
type uid_t int32
|
||||
|
||||
// sys/mount.h
|
||||
const (
|
||||
MntReadOnly = 0x00000001 /* read only filesystem */
|
||||
MntSynchronous = 0x00000002 /* filesystem written synchronously */
|
||||
MntNoExec = 0x00000004 /* can't exec from filesystem */
|
||||
MntNoSuid = 0x00000008 /* don't honor setuid bits on fs */
|
||||
MntUnion = 0x00000020 /* union with underlying filesystem */
|
||||
MntAsync = 0x00000040 /* filesystem written asynchronously */
|
||||
MntSuidDir = 0x00100000 /* special handling of SUID on dirs */
|
||||
MntSoftDep = 0x00200000 /* soft updates being done */
|
||||
MntNoSymFollow = 0x00400000 /* do not follow symlinks */
|
||||
MntGEOMJournal = 0x02000000 /* GEOM journal support enabled */
|
||||
MntMultilabel = 0x04000000 /* MAC support for individual objects */
|
||||
MntACLs = 0x08000000 /* ACL support enabled */
|
||||
MntNoATime = 0x10000000 /* disable update of file access time */
|
||||
MntClusterRead = 0x40000000 /* disable cluster read */
|
||||
MntClusterWrite = 0x80000000 /* disable cluster write */
|
||||
MntNFS4ACLs = 0x00000010
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Bsize uint32
|
||||
Iosize int32
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail uint64
|
||||
Files uint64
|
||||
Ffree uint64
|
||||
Fsid Fsid
|
||||
Owner uint32
|
||||
Type uint32
|
||||
Flags uint32
|
||||
Fssubtype uint32
|
||||
Fstypename [16]int8
|
||||
Mntonname [1024]int8
|
||||
Mntfromname [1024]int8
|
||||
Reserved [8]uint32
|
||||
}
|
|
@ -7,7 +7,7 @@ package disk
|
|||
#cgo LDFLAGS: -framework CoreFoundation -framework IOKit
|
||||
#include <stdint.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "disk_darwin.h"
|
||||
#include "iostat_darwin.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"encoding/binary"
|
||||
"path"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
|
@ -23,71 +22,71 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
|||
var ret []PartitionStat
|
||||
|
||||
// get length
|
||||
count, err := unix.Getfsstat(nil, MNT_WAIT)
|
||||
count, err := unix.Getfsstat(nil, unix.MNT_WAIT)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
fs := make([]Statfs, count)
|
||||
if _, err = Getfsstat(fs, MNT_WAIT); err != nil {
|
||||
fs := make([]unix.Statfs_t, count)
|
||||
if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, stat := range fs {
|
||||
opts := "rw"
|
||||
if stat.Flags&MNT_RDONLY != 0 {
|
||||
if stat.Flags&unix.MNT_RDONLY != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if stat.Flags&MNT_SYNCHRONOUS != 0 {
|
||||
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||
opts += ",sync"
|
||||
}
|
||||
if stat.Flags&MNT_NOEXEC != 0 {
|
||||
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
||||
opts += ",noexec"
|
||||
}
|
||||
if stat.Flags&MNT_NOSUID != 0 {
|
||||
if stat.Flags&unix.MNT_NOSUID != 0 {
|
||||
opts += ",nosuid"
|
||||
}
|
||||
if stat.Flags&MNT_UNION != 0 {
|
||||
if stat.Flags&unix.MNT_UNION != 0 {
|
||||
opts += ",union"
|
||||
}
|
||||
if stat.Flags&MNT_ASYNC != 0 {
|
||||
if stat.Flags&unix.MNT_ASYNC != 0 {
|
||||
opts += ",async"
|
||||
}
|
||||
if stat.Flags&MNT_SUIDDIR != 0 {
|
||||
if stat.Flags&unix.MNT_SUIDDIR != 0 {
|
||||
opts += ",suiddir"
|
||||
}
|
||||
if stat.Flags&MNT_SOFTDEP != 0 {
|
||||
if stat.Flags&unix.MNT_SOFTDEP != 0 {
|
||||
opts += ",softdep"
|
||||
}
|
||||
if stat.Flags&MNT_NOSYMFOLLOW != 0 {
|
||||
if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 {
|
||||
opts += ",nosymfollow"
|
||||
}
|
||||
if stat.Flags&MNT_GJOURNAL != 0 {
|
||||
opts += ",gjounalc"
|
||||
if stat.Flags&unix.MNT_GJOURNAL != 0 {
|
||||
opts += ",gjournal"
|
||||
}
|
||||
if stat.Flags&MNT_MULTILABEL != 0 {
|
||||
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
||||
opts += ",multilabel"
|
||||
}
|
||||
if stat.Flags&MNT_ACLS != 0 {
|
||||
if stat.Flags&unix.MNT_ACLS != 0 {
|
||||
opts += ",acls"
|
||||
}
|
||||
if stat.Flags&MNT_NOATIME != 0 {
|
||||
opts += ",noattime"
|
||||
if stat.Flags&unix.MNT_NOATIME != 0 {
|
||||
opts += ",noatime"
|
||||
}
|
||||
if stat.Flags&MNT_NOCLUSTERR != 0 {
|
||||
opts += ",nocluster"
|
||||
if stat.Flags&unix.MNT_NOCLUSTERR != 0 {
|
||||
opts += ",noclusterr"
|
||||
}
|
||||
if stat.Flags&MNT_NOCLUSTERW != 0 {
|
||||
if stat.Flags&unix.MNT_NOCLUSTERW != 0 {
|
||||
opts += ",noclusterw"
|
||||
}
|
||||
if stat.Flags&MNT_NFS4ACLS != 0 {
|
||||
opts += ",nfs4acls"
|
||||
if stat.Flags&unix.MNT_NFS4ACLS != 0 {
|
||||
opts += ",nfsv4acls"
|
||||
}
|
||||
|
||||
d := PartitionStat{
|
||||
Device: common.IntToString(stat.Mntfromname[:]),
|
||||
Mountpoint: common.IntToString(stat.Mntonname[:]),
|
||||
Fstype: common.IntToString(stat.Fstypename[:]),
|
||||
Device: common.ByteToString(stat.Mntfromname[:]),
|
||||
Mountpoint: common.ByteToString(stat.Mntonname[:]),
|
||||
Fstype: common.ByteToString(stat.Fstypename[:]),
|
||||
Opts: opts,
|
||||
}
|
||||
if all == false {
|
||||
|
@ -158,27 +157,6 @@ func (b Bintime) Compute() float64 {
|
|||
|
||||
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
|
||||
|
||||
// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
|
||||
// change Statfs_t to Statfs in order to get more information
|
||||
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
|
||||
return GetfsstatWithContext(context.Background(), buf, flags)
|
||||
}
|
||||
|
||||
func GetfsstatWithContext(ctx context.Context, buf []Statfs, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
var bufsize uintptr
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
|
||||
}
|
||||
r0, _, e1 := unix.Syscall(unix.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseDevstat(buf []byte) (Devstat, error) {
|
||||
var ds Devstat
|
||||
br := bytes.NewReader(buf)
|
||||
|
@ -192,5 +170,5 @@ func parseDevstat(buf []byte) (Devstat, error) {
|
|||
}
|
||||
|
||||
func getFsType(stat unix.Statfs_t) string {
|
||||
return common.IntToString(stat.Fstypename[:])
|
||||
return common.ByteToString(stat.Fstypename[:])
|
||||
}
|
||||
|
|
|
@ -15,28 +15,6 @@ const (
|
|||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_UNION = 0x00000020
|
||||
MNT_ASYNC = 0x00000040
|
||||
MNT_SUIDDIR = 0x00100000
|
||||
MNT_SOFTDEP = 0x00200000
|
||||
MNT_NOSYMFOLLOW = 0x00400000
|
||||
MNT_GJOURNAL = 0x02000000
|
||||
MNT_MULTILABEL = 0x04000000
|
||||
MNT_ACLS = 0x08000000
|
||||
MNT_NOATIME = 0x10000000
|
||||
MNT_NOCLUSTERR = 0x40000000
|
||||
MNT_NOCLUSTERW = 0x80000000
|
||||
MNT_NFS4ACLS = 0x00000010
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
MNT_SUSPEND = 4
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -51,34 +29,6 @@ type (
|
|||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Version uint32
|
||||
Type uint32
|
||||
Flags uint64
|
||||
Bsize uint64
|
||||
Iosize uint64
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail int64
|
||||
Files uint64
|
||||
Ffree int64
|
||||
Syncwrites uint64
|
||||
Asyncwrites uint64
|
||||
Syncreads uint64
|
||||
Asyncreads uint64
|
||||
Spare [10]uint64
|
||||
Namemax uint32
|
||||
Owner uint32
|
||||
Fsid Fsid
|
||||
Charspare [80]int8
|
||||
Fstypename [16]int8
|
||||
Mntfromname [88]int8
|
||||
Mntonname [88]int8
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
|
||||
type Devstat struct {
|
||||
Sequence0 uint32
|
||||
Allocated int32
|
||||
|
|
|
@ -15,28 +15,6 @@ const (
|
|||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_UNION = 0x00000020
|
||||
MNT_ASYNC = 0x00000040
|
||||
MNT_SUIDDIR = 0x00100000
|
||||
MNT_SOFTDEP = 0x00200000
|
||||
MNT_NOSYMFOLLOW = 0x00400000
|
||||
MNT_GJOURNAL = 0x02000000
|
||||
MNT_MULTILABEL = 0x04000000
|
||||
MNT_ACLS = 0x08000000
|
||||
MNT_NOATIME = 0x10000000
|
||||
MNT_NOCLUSTERR = 0x40000000
|
||||
MNT_NOCLUSTERW = 0x80000000
|
||||
MNT_NFS4ACLS = 0x00000010
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
MNT_SUSPEND = 4
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -51,34 +29,6 @@ type (
|
|||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Version uint32
|
||||
Type uint32
|
||||
Flags uint64
|
||||
Bsize uint64
|
||||
Iosize uint64
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail int64
|
||||
Files uint64
|
||||
Ffree int64
|
||||
Syncwrites uint64
|
||||
Asyncwrites uint64
|
||||
Syncreads uint64
|
||||
Asyncreads uint64
|
||||
Spare [10]uint64
|
||||
Namemax uint32
|
||||
Owner uint32
|
||||
Fsid Fsid
|
||||
Charspare [80]int8
|
||||
Fstypename [16]int8
|
||||
Mntfromname [88]int8
|
||||
Mntonname [88]int8
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
|
||||
type Devstat struct {
|
||||
Sequence0 uint32
|
||||
Allocated int32
|
||||
|
|
|
@ -15,28 +15,6 @@ const (
|
|||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_UNION = 0x00000020
|
||||
MNT_ASYNC = 0x00000040
|
||||
MNT_SUIDDIR = 0x00100000
|
||||
MNT_SOFTDEP = 0x00200000
|
||||
MNT_NOSYMFOLLOW = 0x00400000
|
||||
MNT_GJOURNAL = 0x02000000
|
||||
MNT_MULTILABEL = 0x04000000
|
||||
MNT_ACLS = 0x08000000
|
||||
MNT_NOATIME = 0x10000000
|
||||
MNT_NOCLUSTERR = 0x40000000
|
||||
MNT_NOCLUSTERW = 0x80000000
|
||||
MNT_NFS4ACLS = 0x00000010
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
MNT_SUSPEND = 4
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -51,34 +29,6 @@ type (
|
|||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Version uint32
|
||||
Type uint32
|
||||
Flags uint64
|
||||
Bsize uint64
|
||||
Iosize uint64
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail int64
|
||||
Files uint64
|
||||
Ffree int64
|
||||
Syncwrites uint64
|
||||
Asyncwrites uint64
|
||||
Syncreads uint64
|
||||
Asyncreads uint64
|
||||
Spare [10]uint64
|
||||
Namemax uint32
|
||||
Owner uint32
|
||||
Fsid Fsid
|
||||
Charspare [80]int8
|
||||
Fstypename [16]int8
|
||||
Mntfromname [88]int8
|
||||
Mntonname [88]int8
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
|
||||
type Devstat struct {
|
||||
Sequence0 uint32
|
||||
Allocated int32
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
// +build freebsd
|
||||
// +build arm64
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs disk/types_freebsd.go
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
sizeofLongDouble = 0x8
|
||||
|
||||
DEVSTAT_NO_DATA = 0x00
|
||||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
)
|
||||
|
||||
const (
|
||||
sizeOfDevstat = 0x120
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Devstat struct {
|
||||
Sequence0 uint32
|
||||
Allocated int32
|
||||
Start_count uint32
|
||||
End_count uint32
|
||||
Busy_from Bintime
|
||||
Dev_links _Ctype_struct___0
|
||||
Device_number uint32
|
||||
Device_name [16]int8
|
||||
Unit_number int32
|
||||
Bytes [4]uint64
|
||||
Operations [4]uint64
|
||||
Duration [4]Bintime
|
||||
Busy_time Bintime
|
||||
Creation_time Bintime
|
||||
Block_size uint32
|
||||
Tag_types [3]uint64
|
||||
Flags uint32
|
||||
Device_type uint32
|
||||
Priority uint32
|
||||
Id *byte
|
||||
Sequence1 uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
}
|
||||
type Bintime struct {
|
||||
Sec int64
|
||||
Frac uint64
|
||||
}
|
||||
|
||||
type _Ctype_struct___0 struct {
|
||||
Empty uint64
|
||||
}
|
|
@ -301,7 +301,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
|||
}
|
||||
|
||||
if strings.HasPrefix(d.Device, "/dev/mapper/") {
|
||||
devpath, err := filepath.EvalSymlinks(d.Device)
|
||||
devpath, err := filepath.EvalSymlinks(common.HostDev(strings.Replace(d.Device, "/dev", "", -1)))
|
||||
if err == nil {
|
||||
d.Device = devpath
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"context"
|
||||
"encoding/binary"
|
||||
"path"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"golang.org/x/sys/unix"
|
||||
|
@ -21,36 +20,45 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
|||
var ret []PartitionStat
|
||||
|
||||
// get length
|
||||
count, err := unix.Getfsstat(nil, MNT_WAIT)
|
||||
count, err := unix.Getfsstat(nil, unix.MNT_WAIT)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
fs := make([]Statfs, count)
|
||||
if _, err = Getfsstat(fs, MNT_WAIT); err != nil {
|
||||
fs := make([]unix.Statfs_t, count)
|
||||
if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for _, stat := range fs {
|
||||
opts := "rw"
|
||||
if stat.F_flags&MNT_RDONLY != 0 {
|
||||
if stat.F_flags&unix.MNT_RDONLY != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if stat.F_flags&MNT_SYNCHRONOUS != 0 {
|
||||
if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||
opts += ",sync"
|
||||
}
|
||||
if stat.F_flags&MNT_NOEXEC != 0 {
|
||||
if stat.F_flags&unix.MNT_NOEXEC != 0 {
|
||||
opts += ",noexec"
|
||||
}
|
||||
if stat.F_flags&MNT_NOSUID != 0 {
|
||||
if stat.F_flags&unix.MNT_NOSUID != 0 {
|
||||
opts += ",nosuid"
|
||||
}
|
||||
if stat.F_flags&MNT_NODEV != 0 {
|
||||
if stat.F_flags&unix.MNT_NODEV != 0 {
|
||||
opts += ",nodev"
|
||||
}
|
||||
if stat.F_flags&MNT_ASYNC != 0 {
|
||||
if stat.F_flags&unix.MNT_ASYNC != 0 {
|
||||
opts += ",async"
|
||||
}
|
||||
if stat.F_flags&unix.MNT_SOFTDEP != 0 {
|
||||
opts += ",softdep"
|
||||
}
|
||||
if stat.F_flags&unix.MNT_NOATIME != 0 {
|
||||
opts += ",noatime"
|
||||
}
|
||||
if stat.F_flags&unix.MNT_WXALLOWED != 0 {
|
||||
opts += ",wxallowed"
|
||||
}
|
||||
|
||||
d := PartitionStat{
|
||||
Device: common.IntToString(stat.F_mntfromname[:]),
|
||||
|
@ -114,27 +122,6 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
|||
|
||||
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
|
||||
|
||||
// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
|
||||
// change Statfs_t to Statfs in order to get more information
|
||||
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
|
||||
return GetfsstatWithContext(context.Background(), buf, flags)
|
||||
}
|
||||
|
||||
func GetfsstatWithContext(ctx context.Context, buf []Statfs, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
var bufsize uintptr
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
|
||||
}
|
||||
r0, _, e1 := unix.Syscall(unix.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseDiskstats(buf []byte) (Diskstats, error) {
|
||||
var ds Diskstats
|
||||
br := bytes.NewReader(buf)
|
||||
|
|
|
@ -4,67 +4,16 @@
|
|||
package disk
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x4
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x4
|
||||
sizeofLongLong = 0x8
|
||||
sizeofLongDouble = 0x8
|
||||
|
||||
DEVSTAT_NO_DATA = 0x00
|
||||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_NODEV = 0x00000010
|
||||
MNT_ASYNC = 0x00000040
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
)
|
||||
|
||||
const (
|
||||
sizeOfDiskstats = 0x60
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int32
|
||||
_C_long_long int64
|
||||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
F_flags uint32
|
||||
F_bsize uint32
|
||||
F_iosize uint32
|
||||
F_blocks uint64
|
||||
F_bfree uint64
|
||||
F_bavail int64
|
||||
F_files uint64
|
||||
F_ffree uint64
|
||||
F_favail int64
|
||||
F_syncwrites uint64
|
||||
F_syncreads uint64
|
||||
F_asyncwrites uint64
|
||||
F_asyncreads uint64
|
||||
F_fsid Fsid
|
||||
F_namemax uint32
|
||||
F_owner uint32
|
||||
F_ctime uint64
|
||||
F_fstypename [16]int8
|
||||
F_mntonname [90]int8
|
||||
F_mntfromname [90]int8
|
||||
F_mntfromspec [90]int8
|
||||
Pad_cgo_0 [2]byte
|
||||
Mount_info [160]byte
|
||||
}
|
||||
type Diskstats struct {
|
||||
Name [16]int8
|
||||
Busy int32
|
||||
|
@ -77,9 +26,6 @@ type Diskstats struct {
|
|||
Timestamp Timeval
|
||||
Time Timeval
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int32
|
||||
|
|
|
@ -1,71 +1,19 @@
|
|||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs types_openbsd.go
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
sizeofLongDouble = 0x8
|
||||
|
||||
DEVSTAT_NO_DATA = 0x00
|
||||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_NODEV = 0x00000010
|
||||
MNT_ASYNC = 0x00000040
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
)
|
||||
|
||||
const (
|
||||
sizeOfDiskstats = 0x70
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
F_flags uint32
|
||||
F_bsize uint32
|
||||
F_iosize uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
F_blocks uint64
|
||||
F_bfree uint64
|
||||
F_bavail int64
|
||||
F_files uint64
|
||||
F_ffree uint64
|
||||
F_favail int64
|
||||
F_syncwrites uint64
|
||||
F_syncreads uint64
|
||||
F_asyncwrites uint64
|
||||
F_asyncreads uint64
|
||||
F_fsid Fsid
|
||||
F_namemax uint32
|
||||
F_owner uint32
|
||||
F_ctime uint64
|
||||
F_fstypename [16]int8
|
||||
F_mntonname [90]int8
|
||||
F_mntfromname [90]int8
|
||||
F_mntfromspec [90]int8
|
||||
Pad_cgo_1 [2]byte
|
||||
Mount_info [160]byte
|
||||
}
|
||||
type Diskstats struct {
|
||||
Name [16]int8
|
||||
Busy int32
|
||||
|
@ -79,9 +27,6 @@ type Diskstats struct {
|
|||
Timestamp Timeval
|
||||
Time Timeval
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int64
|
||||
|
|
|
@ -5,6 +5,8 @@ package disk
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
|
@ -23,18 +25,24 @@ var (
|
|||
FileReadOnlyVolume = int64(524288) // 0x00080000
|
||||
)
|
||||
|
||||
type Win32_PerfFormattedData struct {
|
||||
Name string
|
||||
AvgDiskBytesPerRead uint64
|
||||
AvgDiskBytesPerWrite uint64
|
||||
AvgDiskReadQueueLength uint64
|
||||
AvgDiskWriteQueueLength uint64
|
||||
AvgDisksecPerRead uint64
|
||||
AvgDisksecPerWrite uint64
|
||||
// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API.
|
||||
// https://docs.microsoft.com/fr-fr/windows/win32/api/winioctl/ns-winioctl-disk_performance
|
||||
type diskPerformance struct {
|
||||
BytesRead int64
|
||||
BytesWritten int64
|
||||
ReadTime int64
|
||||
WriteTime int64
|
||||
IdleTime int64
|
||||
ReadCount uint32
|
||||
WriteCount uint32
|
||||
QueueDepth uint32
|
||||
SplitCount uint32
|
||||
QueryTime int64
|
||||
StorageDeviceNumber uint32
|
||||
StorageManagerName [8]uint16
|
||||
alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553
|
||||
}
|
||||
|
||||
const WaitMSec = 500
|
||||
|
||||
func Usage(path string) (*UsageStat, error) {
|
||||
return UsageWithContext(context.Background(), path)
|
||||
}
|
||||
|
@ -136,31 +144,52 @@ func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|||
}
|
||||
|
||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||
ret := make(map[string]IOCountersStat, 0)
|
||||
var dst []Win32_PerfFormattedData
|
||||
// https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83
|
||||
drivemap := make(map[string]IOCountersStat, 0)
|
||||
var diskPerformance diskPerformance
|
||||
|
||||
err := common.WMIQueryWithContext(ctx, "SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk", &dst)
|
||||
lpBuffer := make([]uint16, 254)
|
||||
lpBufferLen, err := windows.GetLogicalDriveStrings(uint32(len(lpBuffer)), &lpBuffer[0])
|
||||
if err != nil {
|
||||
return ret, err
|
||||
return drivemap, err
|
||||
}
|
||||
for _, d := range dst {
|
||||
if len(d.Name) > 3 { // not get _Total or Harddrive
|
||||
continue
|
||||
}
|
||||
for _, v := range lpBuffer[:lpBufferLen] {
|
||||
if 'A' <= v && v <= 'Z' {
|
||||
path := string(v) + ":"
|
||||
typepath, _ := windows.UTF16PtrFromString(path)
|
||||
typeret := windows.GetDriveType(typepath)
|
||||
if typeret == 0 {
|
||||
return drivemap, windows.GetLastError()
|
||||
}
|
||||
if typeret != windows.DRIVE_FIXED {
|
||||
continue
|
||||
}
|
||||
szDevice := fmt.Sprintf(`\\.\%s`, path)
|
||||
const IOCTL_DISK_PERFORMANCE = 0x70020
|
||||
h, err := windows.CreateFile(syscall.StringToUTF16Ptr(szDevice), 0, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0)
|
||||
if err != nil {
|
||||
if err == windows.ERROR_FILE_NOT_FOUND {
|
||||
continue
|
||||
}
|
||||
return drivemap, err
|
||||
}
|
||||
defer windows.CloseHandle(h)
|
||||
|
||||
if len(names) > 0 && !common.StringsHas(names, d.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
ret[d.Name] = IOCountersStat{
|
||||
Name: d.Name,
|
||||
ReadCount: uint64(d.AvgDiskReadQueueLength),
|
||||
WriteCount: d.AvgDiskWriteQueueLength,
|
||||
ReadBytes: uint64(d.AvgDiskBytesPerRead),
|
||||
WriteBytes: uint64(d.AvgDiskBytesPerWrite),
|
||||
ReadTime: d.AvgDisksecPerRead,
|
||||
WriteTime: d.AvgDisksecPerWrite,
|
||||
var diskPerformanceSize uint32
|
||||
err = windows.DeviceIoControl(h, IOCTL_DISK_PERFORMANCE, nil, 0, (*byte)(unsafe.Pointer(&diskPerformance)), uint32(unsafe.Sizeof(diskPerformance)), &diskPerformanceSize, nil)
|
||||
if err != nil {
|
||||
return drivemap, err
|
||||
}
|
||||
drivemap[path] = IOCountersStat{
|
||||
ReadBytes: uint64(diskPerformance.BytesRead),
|
||||
WriteBytes: uint64(diskPerformance.BytesWritten),
|
||||
ReadCount: uint64(diskPerformance.ReadCount),
|
||||
WriteCount: uint64(diskPerformance.WriteCount),
|
||||
ReadTime: uint64(diskPerformance.ReadTime / 10000 / 1000), // convert to ms: https://github.com/giampaolo/psutil/issues/1012
|
||||
WriteTime: uint64(diskPerformance.WriteTime / 10000 / 1000),
|
||||
Name: path,
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
return drivemap, nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.c
|
||||
#include <stdint.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "disk_darwin.h"
|
||||
#include "iostat_darwin.h"
|
||||
|
||||
#define IOKIT 1 /* to get io_name_t in device_types.h */
|
||||
|
|
@ -223,11 +223,3 @@ func KernelVersionWithContext(ctx context.Context) (string, error) {
|
|||
version, err := unix.Sysctl("kern.osrelease")
|
||||
return strings.ToLower(version), err
|
||||
}
|
||||
|
||||
func SensorsTemperatures() ([]TemperatureStat, error) {
|
||||
return SensorsTemperaturesWithContext(context.Background())
|
||||
}
|
||||
|
||||
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
||||
return []TemperatureStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// +build darwin
|
||||
// +build cgo
|
||||
|
||||
package host
|
||||
|
||||
// #cgo LDFLAGS: -framework IOKit
|
||||
// #include "smc_darwin.h"
|
||||
import "C"
|
||||
import "context"
|
||||
|
||||
func SensorsTemperatures() ([]TemperatureStat, error) {
|
||||
return SensorsTemperaturesWithContext(context.Background())
|
||||
}
|
||||
|
||||
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
||||
temperatureKeys := []string{
|
||||
C.AMBIENT_AIR_0,
|
||||
C.AMBIENT_AIR_1,
|
||||
C.CPU_0_DIODE,
|
||||
C.CPU_0_HEATSINK,
|
||||
C.CPU_0_PROXIMITY,
|
||||
C.ENCLOSURE_BASE_0,
|
||||
C.ENCLOSURE_BASE_1,
|
||||
C.ENCLOSURE_BASE_2,
|
||||
C.ENCLOSURE_BASE_3,
|
||||
C.GPU_0_DIODE,
|
||||
C.GPU_0_HEATSINK,
|
||||
C.GPU_0_PROXIMITY,
|
||||
C.HARD_DRIVE_BAY,
|
||||
C.MEMORY_SLOT_0,
|
||||
C.MEMORY_SLOTS_PROXIMITY,
|
||||
C.NORTHBRIDGE,
|
||||
C.NORTHBRIDGE_DIODE,
|
||||
C.NORTHBRIDGE_PROXIMITY,
|
||||
C.THUNDERBOLT_0,
|
||||
C.THUNDERBOLT_1,
|
||||
C.WIRELESS_MODULE,
|
||||
}
|
||||
var temperatures []TemperatureStat
|
||||
|
||||
C.open_smc()
|
||||
defer C.close_smc()
|
||||
|
||||
for _, key := range temperatureKeys {
|
||||
temperatures = append(temperatures, TemperatureStat{
|
||||
SensorKey: key,
|
||||
Temperature: float64(C.get_temperature(C.CString(key))),
|
||||
})
|
||||
}
|
||||
return temperatures, nil
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// +build darwin
|
||||
// +build !cgo
|
||||
|
||||
package host
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
||||
func SensorsTemperatures() ([]TemperatureStat, error) {
|
||||
return SensorsTemperaturesWithContext(context.Background())
|
||||
}
|
||||
|
||||
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
||||
return []TemperatureStat{}, common.ErrNotImplementedError
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// +build freebsd
|
||||
// +build arm64
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs host/types_freebsd.go
|
||||
|
||||
package host
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
sizeOfUtmpx = 0xc5
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
)
|
||||
|
||||
type Utmp struct {
|
||||
Line [8]int8
|
||||
Name [16]int8
|
||||
Host [16]int8
|
||||
Time int32
|
||||
}
|
||||
|
||||
type Utmpx struct {
|
||||
Type uint8
|
||||
Tv uint64
|
||||
Id [8]int8
|
||||
Pid uint32
|
||||
User [32]int8
|
||||
Line [16]int8
|
||||
Host [128]int8
|
||||
}
|
|
@ -280,7 +280,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
|
|||
platform = "debian"
|
||||
}
|
||||
contents, err := common.ReadLines(common.HostEtc("debian_version"))
|
||||
if err == nil {
|
||||
if err == nil && len(contents) > 0 && contents[0] != "" {
|
||||
version = contents[0]
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
|
|||
} else if common.PathExists(common.HostEtc("alpine-release")) {
|
||||
platform = "alpine"
|
||||
contents, err := common.ReadLines(common.HostEtc("alpine-release"))
|
||||
if err == nil && len(contents) > 0 {
|
||||
if err == nil && len(contents) > 0 && contents[0] != "" {
|
||||
version = contents[0]
|
||||
}
|
||||
} else if common.PathExists(common.HostEtc("os-release")) {
|
||||
|
@ -460,6 +460,38 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err
|
|||
}
|
||||
var warns Warnings
|
||||
|
||||
if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files
|
||||
files, err = filepath.Glob(common.HostSys("/class/thermal/thermal_zone*/"))
|
||||
if err != nil {
|
||||
return temperatures, err
|
||||
}
|
||||
for _, file := range files {
|
||||
// Get the name of the temperature you are reading
|
||||
name, err := ioutil.ReadFile(filepath.Join(file, "type"))
|
||||
if err != nil {
|
||||
warns.Add(err)
|
||||
continue
|
||||
}
|
||||
// Get the temperature reading
|
||||
current, err := ioutil.ReadFile(filepath.Join(file, "temp"))
|
||||
if err != nil {
|
||||
warns.Add(err)
|
||||
continue
|
||||
}
|
||||
temperature, err := strconv.ParseInt(strings.TrimSpace(string(current)), 10, 64)
|
||||
if err != nil {
|
||||
warns.Add(err)
|
||||
continue
|
||||
}
|
||||
|
||||
temperatures = append(temperatures, TemperatureStat{
|
||||
SensorKey: strings.TrimSpace(string(name)),
|
||||
Temperature: float64(temperature) / 1000.0,
|
||||
})
|
||||
}
|
||||
return temperatures, warns.Reference()
|
||||
}
|
||||
|
||||
// example directory
|
||||
// device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm
|
||||
// name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "smc_darwin.h"
|
||||
|
||||
#define IOSERVICE_SMC "AppleSMC"
|
||||
#define IOSERVICE_MODEL "IOPlatformExpertDevice"
|
||||
|
||||
#define DATA_TYPE_SP78 "sp78"
|
||||
|
||||
typedef enum {
|
||||
kSMCUserClientOpen = 0,
|
||||
kSMCUserClientClose = 1,
|
||||
kSMCHandleYPCEvent = 2,
|
||||
kSMCReadKey = 5,
|
||||
kSMCWriteKey = 6,
|
||||
kSMCGetKeyCount = 7,
|
||||
kSMCGetKeyFromIndex = 8,
|
||||
kSMCGetKeyInfo = 9,
|
||||
} selector_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
unsigned char build;
|
||||
unsigned char reserved;
|
||||
unsigned short release;
|
||||
} SMCVersion;
|
||||
|
||||
typedef struct {
|
||||
uint16_t version;
|
||||
uint16_t length;
|
||||
uint32_t cpuPLimit;
|
||||
uint32_t gpuPLimit;
|
||||
uint32_t memPLimit;
|
||||
} SMCPLimitData;
|
||||
|
||||
typedef struct {
|
||||
IOByteCount data_size;
|
||||
uint32_t data_type;
|
||||
uint8_t data_attributes;
|
||||
} SMCKeyInfoData;
|
||||
|
||||
typedef struct {
|
||||
uint32_t key;
|
||||
SMCVersion vers;
|
||||
SMCPLimitData p_limit_data;
|
||||
SMCKeyInfoData key_info;
|
||||
uint8_t result;
|
||||
uint8_t status;
|
||||
uint8_t data8;
|
||||
uint32_t data32;
|
||||
uint8_t bytes[32];
|
||||
} SMCParamStruct;
|
||||
|
||||
typedef enum {
|
||||
kSMCSuccess = 0,
|
||||
kSMCError = 1,
|
||||
kSMCKeyNotFound = 0x84,
|
||||
} kSMC_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[32];
|
||||
uint32_t data_type;
|
||||
uint32_t data_size;
|
||||
kSMC_t kSMC;
|
||||
} smc_return_t;
|
||||
|
||||
static const int SMC_KEY_SIZE = 4; // number of characters in an SMC key.
|
||||
static io_connect_t conn; // our connection to the SMC.
|
||||
|
||||
kern_return_t open_smc(void) {
|
||||
kern_return_t result;
|
||||
io_service_t service;
|
||||
|
||||
service = IOServiceGetMatchingService(kIOMasterPortDefault,
|
||||
IOServiceMatching(IOSERVICE_SMC));
|
||||
if (service == 0) {
|
||||
// Note: IOServiceMatching documents 0 on failure
|
||||
printf("ERROR: %s NOT FOUND\n", IOSERVICE_SMC);
|
||||
return kIOReturnError;
|
||||
}
|
||||
|
||||
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
|
||||
IOObjectRelease(service);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
kern_return_t close_smc(void) { return IOServiceClose(conn); }
|
||||
|
||||
static uint32_t to_uint32(char *key) {
|
||||
uint32_t ans = 0;
|
||||
uint32_t shift = 24;
|
||||
|
||||
if (strlen(key) != SMC_KEY_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < SMC_KEY_SIZE; i++) {
|
||||
ans += key[i] << shift;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
static kern_return_t call_smc(SMCParamStruct *input, SMCParamStruct *output) {
|
||||
kern_return_t result;
|
||||
size_t input_cnt = sizeof(SMCParamStruct);
|
||||
size_t output_cnt = sizeof(SMCParamStruct);
|
||||
|
||||
result = IOConnectCallStructMethod(conn, kSMCHandleYPCEvent, input, input_cnt,
|
||||
output, &output_cnt);
|
||||
|
||||
if (result != kIOReturnSuccess) {
|
||||
result = err_get_code(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static kern_return_t read_smc(char *key, smc_return_t *result_smc) {
|
||||
kern_return_t result;
|
||||
SMCParamStruct input;
|
||||
SMCParamStruct output;
|
||||
|
||||
memset(&input, 0, sizeof(SMCParamStruct));
|
||||
memset(&output, 0, sizeof(SMCParamStruct));
|
||||
memset(result_smc, 0, sizeof(smc_return_t));
|
||||
|
||||
input.key = to_uint32(key);
|
||||
input.data8 = kSMCGetKeyInfo;
|
||||
|
||||
result = call_smc(&input, &output);
|
||||
result_smc->kSMC = output.result;
|
||||
|
||||
if (result != kIOReturnSuccess || output.result != kSMCSuccess) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result_smc->data_size = output.key_info.data_size;
|
||||
result_smc->data_type = output.key_info.data_type;
|
||||
|
||||
input.key_info.data_size = output.key_info.data_size;
|
||||
input.data8 = kSMCReadKey;
|
||||
|
||||
result = call_smc(&input, &output);
|
||||
result_smc->kSMC = output.result;
|
||||
|
||||
if (result != kIOReturnSuccess || output.result != kSMCSuccess) {
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(result_smc->data, output.bytes, sizeof(output.bytes));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double get_temperature(char *key) {
|
||||
kern_return_t result;
|
||||
smc_return_t result_smc;
|
||||
|
||||
result = read_smc(key, &result_smc);
|
||||
|
||||
if (!(result == kIOReturnSuccess) && result_smc.data_size == 2 &&
|
||||
result_smc.data_type == to_uint32(DATA_TYPE_SP78)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return (double)result_smc.data[0];
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __SMC_H__
|
||||
#define __SMC_H__ 1
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
#define AMBIENT_AIR_0 "TA0P"
|
||||
#define AMBIENT_AIR_1 "TA1P"
|
||||
#define CPU_0_DIODE "TC0D"
|
||||
#define CPU_0_HEATSINK "TC0H"
|
||||
#define CPU_0_PROXIMITY "TC0P"
|
||||
#define ENCLOSURE_BASE_0 "TB0T"
|
||||
#define ENCLOSURE_BASE_1 "TB1T"
|
||||
#define ENCLOSURE_BASE_2 "TB2T"
|
||||
#define ENCLOSURE_BASE_3 "TB3T"
|
||||
#define GPU_0_DIODE "TG0D"
|
||||
#define GPU_0_HEATSINK "TG0H"
|
||||
#define GPU_0_PROXIMITY "TG0P"
|
||||
#define HARD_DRIVE_BAY "TH0P"
|
||||
#define MEMORY_SLOT_0 "TM0S"
|
||||
#define MEMORY_SLOTS_PROXIMITY "TM0P"
|
||||
#define NORTHBRIDGE "TN0H"
|
||||
#define NORTHBRIDGE_DIODE "TN0D"
|
||||
#define NORTHBRIDGE_PROXIMITY "TN0P"
|
||||
#define THUNDERBOLT_0 "TI0P"
|
||||
#define THUNDERBOLT_1 "TI1P"
|
||||
#define WIRELESS_MODULE "TW0P"
|
||||
|
||||
kern_return_t open_smc(void);
|
||||
kern_return_t close_smc(void);
|
||||
double get_temperature(char *);
|
||||
|
||||
#endif // __SMC_H__
|
|
@ -94,6 +94,17 @@ func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ...
|
|||
|
||||
var ErrNotImplementedError = errors.New("not implemented yet")
|
||||
|
||||
// ReadFile reads contents from a file
|
||||
func ReadFile(filename string) (string, error) {
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(content), nil
|
||||
}
|
||||
|
||||
// ReadLines reads contents from a file and splits them by new lines.
|
||||
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
|
||||
func ReadLines(filename string) ([]string, error) {
|
||||
|
@ -338,6 +349,10 @@ func HostRun(combineWith ...string) string {
|
|||
return GetEnv("HOST_RUN", "/run", combineWith...)
|
||||
}
|
||||
|
||||
func HostDev(combineWith ...string) string {
|
||||
return GetEnv("HOST_DEV", "/dev", combineWith...)
|
||||
}
|
||||
|
||||
// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
|
||||
// sysctl commands (see DoSysctrl).
|
||||
func getSysctrlEnv(env []string) []string {
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -54,14 +53,7 @@ func NumProcs() (uint64, error) {
|
|||
return cnt, nil
|
||||
}
|
||||
|
||||
// cachedBootTime must be accessed via atomic.Load/StoreUint64
|
||||
var cachedBootTime uint64
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
system, role, err := Virtualization()
|
||||
if err != nil {
|
||||
|
@ -94,8 +86,7 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
t = uint64(b)
|
||||
atomic.StoreUint64(&cachedBootTime, t)
|
||||
t := uint64(b)
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
|
@ -108,8 +99,7 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
t = uint64(time.Now().Unix()) - uint64(b)
|
||||
atomic.StoreUint64(&cachedBootTime, t)
|
||||
t := uint64(time.Now().Unix()) - uint64(b)
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
@ -204,6 +194,17 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if PathExists(filepath.Join(filename, "1", "environ")) {
|
||||
contents, err := ReadFile(filepath.Join(filename, "1", "environ"))
|
||||
|
||||
if err == nil {
|
||||
if strings.Contains(contents, "container=lxc") {
|
||||
system = "lxc"
|
||||
role = "guest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if PathExists(filepath.Join(filename, "self", "cgroup")) {
|
||||
contents, err := ReadLines(filepath.Join(filename, "self", "cgroup"))
|
||||
if err == nil {
|
||||
|
|
|
@ -49,21 +49,33 @@ const (
|
|||
PDH_NO_DATA = 0x800007d5
|
||||
)
|
||||
|
||||
const (
|
||||
ProcessBasicInformation = 0
|
||||
ProcessWow64Information = 26
|
||||
)
|
||||
|
||||
var (
|
||||
Modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
ModNt = windows.NewLazySystemDLL("ntdll.dll")
|
||||
ModPdh = windows.NewLazySystemDLL("pdh.dll")
|
||||
ModPsapi = windows.NewLazySystemDLL("psapi.dll")
|
||||
|
||||
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
||||
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
||||
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
||||
ProcRtlGetNativeSystemInformation = ModNt.NewProc("RtlGetNativeSystemInformation")
|
||||
ProcRtlNtStatusToDosError = ModNt.NewProc("RtlNtStatusToDosError")
|
||||
ProcNtQueryInformationProcess = ModNt.NewProc("NtQueryInformationProcess")
|
||||
ProcNtReadVirtualMemory = ModNt.NewProc("NtReadVirtualMemory")
|
||||
ProcNtWow64QueryInformationProcess64 = ModNt.NewProc("NtWow64QueryInformationProcess64")
|
||||
ProcNtWow64ReadVirtualMemory64 = ModNt.NewProc("NtWow64ReadVirtualMemory64")
|
||||
|
||||
procQueryDosDeviceW = Modkernel32.NewProc("QueryDosDeviceW")
|
||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||
|
||||
procQueryDosDeviceW = Modkernel32.NewProc("QueryDosDeviceW")
|
||||
)
|
||||
|
||||
type FILETIME struct {
|
||||
|
|
|
@ -4,6 +4,7 @@ package mem
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -16,6 +17,14 @@ import (
|
|||
type VirtualMemoryExStat struct {
|
||||
ActiveFile uint64 `json:"activefile"`
|
||||
InactiveFile uint64 `json:"inactivefile"`
|
||||
ActiveAnon uint64 `json:"activeanon"`
|
||||
InactiveAnon uint64 `json:"inactiveanon"`
|
||||
Unevictable uint64 `json:"unevictable"`
|
||||
}
|
||||
|
||||
func (v VirtualMemoryExStat) String() string {
|
||||
s, _ := json.Marshal(v)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func VirtualMemory() (*VirtualMemoryStat, error) {
|
||||
|
@ -23,6 +32,26 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
|
|||
}
|
||||
|
||||
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
||||
vm, _, err := fillFromMeminfoWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vm, nil
|
||||
}
|
||||
|
||||
func VirtualMemoryEx() (*VirtualMemoryExStat, error) {
|
||||
return VirtualMemoryExWithContext(context.Background())
|
||||
}
|
||||
|
||||
func VirtualMemoryExWithContext(ctx context.Context) (*VirtualMemoryExStat, error) {
|
||||
_, vmEx, err := fillFromMeminfoWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vmEx, nil
|
||||
}
|
||||
|
||||
func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *VirtualMemoryExStat, error) {
|
||||
filename := common.HostProc("meminfo")
|
||||
lines, _ := common.ReadLines(filename)
|
||||
|
||||
|
@ -46,7 +75,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|||
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
return ret, retEx,err
|
||||
}
|
||||
switch key {
|
||||
case "MemTotal":
|
||||
|
@ -64,12 +93,18 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|||
ret.Active = t * 1024
|
||||
case "Inactive":
|
||||
ret.Inactive = t * 1024
|
||||
case "Active(anon)":
|
||||
retEx.ActiveAnon = t * 1024
|
||||
case "Inactive(anon)":
|
||||
retEx.InactiveAnon = t * 1024
|
||||
case "Active(file)":
|
||||
activeFile = true
|
||||
retEx.ActiveFile = t * 1024
|
||||
case "InActive(file)":
|
||||
case "Inactive(file)":
|
||||
inactiveFile = true
|
||||
retEx.InactiveFile = t * 1024
|
||||
case "Unevictable":
|
||||
retEx.Unevictable = t * 1024
|
||||
case "Writeback":
|
||||
ret.Writeback = t * 1024
|
||||
case "WritebackTmp":
|
||||
|
@ -135,7 +170,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|||
ret.Used = ret.Total - ret.Free - ret.Buffers - ret.Cached
|
||||
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
|
||||
|
||||
return ret, nil
|
||||
return ret, retEx, nil
|
||||
}
|
||||
|
||||
func SwapMemory() (*SwapMemoryStat, error) {
|
||||
|
|
|
@ -84,7 +84,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
|
|||
if tot == 0 {
|
||||
usedPercent = 0
|
||||
} else {
|
||||
usedPercent = float64(used) / float64(tot)
|
||||
usedPercent = float64(used) / float64(tot) * 100
|
||||
}
|
||||
ret := &SwapMemoryStat{
|
||||
Total: tot,
|
||||
|
|
|
@ -3,11 +3,7 @@ package net
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
@ -161,14 +157,6 @@ func (l *ConntrackStatList) Summary() []ConntrackStat {
|
|||
return []ConntrackStat{*summary}
|
||||
}
|
||||
|
||||
var constMap = map[string]int{
|
||||
"unix": syscall.AF_UNIX,
|
||||
"TCP": syscall.SOCK_STREAM,
|
||||
"UDP": syscall.SOCK_DGRAM,
|
||||
"IPv4": syscall.AF_INET,
|
||||
"IPv6": syscall.AF_INET6,
|
||||
}
|
||||
|
||||
func (n IOCountersStat) String() string {
|
||||
s, _ := json.Marshal(n)
|
||||
return string(s)
|
||||
|
@ -273,84 +261,3 @@ func getIOCountersAll(n []IOCountersStat) ([]IOCountersStat, error) {
|
|||
|
||||
return []IOCountersStat{r}, nil
|
||||
}
|
||||
|
||||
func parseNetLine(line string) (ConnectionStat, error) {
|
||||
f := strings.Fields(line)
|
||||
if len(f) < 8 {
|
||||
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
|
||||
}
|
||||
|
||||
if len(f) == 8 {
|
||||
f = append(f, f[7])
|
||||
f[7] = "unix"
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(f[1])
|
||||
if err != nil {
|
||||
return ConnectionStat{}, err
|
||||
}
|
||||
fd, err := strconv.Atoi(strings.Trim(f[3], "u"))
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3])
|
||||
}
|
||||
netFamily, ok := constMap[f[4]]
|
||||
if !ok {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4])
|
||||
}
|
||||
netType, ok := constMap[f[7]]
|
||||
if !ok {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7])
|
||||
}
|
||||
|
||||
var laddr, raddr Addr
|
||||
if f[7] == "unix" {
|
||||
laddr.IP = f[8]
|
||||
} else {
|
||||
laddr, raddr, err = parseNetAddr(f[8])
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8])
|
||||
}
|
||||
}
|
||||
|
||||
n := ConnectionStat{
|
||||
Fd: uint32(fd),
|
||||
Family: uint32(netFamily),
|
||||
Type: uint32(netType),
|
||||
Laddr: laddr,
|
||||
Raddr: raddr,
|
||||
Pid: int32(pid),
|
||||
}
|
||||
if len(f) == 10 {
|
||||
n.Status = strings.Trim(f[9], "()")
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func parseNetAddr(line string) (laddr Addr, raddr Addr, err error) {
|
||||
parse := func(l string) (Addr, error) {
|
||||
host, port, err := net.SplitHostPort(l)
|
||||
if err != nil {
|
||||
return Addr{}, fmt.Errorf("wrong addr, %s", l)
|
||||
}
|
||||
lport, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return Addr{}, err
|
||||
}
|
||||
return Addr{IP: host, Port: uint32(lport)}, nil
|
||||
}
|
||||
|
||||
addrs := strings.Split(line, "->")
|
||||
if len(addrs) == 0 {
|
||||
return laddr, raddr, fmt.Errorf("wrong netaddr, %s", line)
|
||||
}
|
||||
laddr, err = parse(addrs[0])
|
||||
if len(addrs) == 2 { // remote addr exists
|
||||
raddr, err = parse(addrs[1])
|
||||
if err != nil {
|
||||
return laddr, raddr, err
|
||||
}
|
||||
}
|
||||
|
||||
return laddr, raddr, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,425 @@
|
|||
// +build aix
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
||||
func parseNetstatI(output string) ([]IOCountersStat, error) {
|
||||
lines := strings.Split(string(output), "\n")
|
||||
ret := make([]IOCountersStat, 0, len(lines)-1)
|
||||
exists := make([]string, 0, len(ret))
|
||||
|
||||
// Check first line is header
|
||||
if len(lines) > 0 && strings.Fields(lines[0])[0] != "Name" {
|
||||
return nil, fmt.Errorf("not a 'netstat -i' output")
|
||||
}
|
||||
|
||||
for _, line := range lines[1:] {
|
||||
values := strings.Fields(line)
|
||||
if len(values) < 1 || values[0] == "Name" {
|
||||
continue
|
||||
}
|
||||
if common.StringsHas(exists, values[0]) {
|
||||
// skip if already get
|
||||
continue
|
||||
}
|
||||
exists = append(exists, values[0])
|
||||
|
||||
if len(values) < 9 {
|
||||
continue
|
||||
}
|
||||
|
||||
base := 1
|
||||
// sometimes Address is omitted
|
||||
if len(values) < 10 {
|
||||
base = 0
|
||||
}
|
||||
|
||||
parsed := make([]uint64, 0, 5)
|
||||
vv := []string{
|
||||
values[base+3], // Ipkts == PacketsRecv
|
||||
values[base+4], // Ierrs == Errin
|
||||
values[base+5], // Opkts == PacketsSent
|
||||
values[base+6], // Oerrs == Errout
|
||||
values[base+8], // Drops == Dropout
|
||||
}
|
||||
|
||||
for _, target := range vv {
|
||||
if target == "-" {
|
||||
parsed = append(parsed, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
t, err := strconv.ParseUint(target, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parsed = append(parsed, t)
|
||||
}
|
||||
|
||||
n := IOCountersStat{
|
||||
Name: values[0],
|
||||
PacketsRecv: parsed[0],
|
||||
Errin: parsed[1],
|
||||
PacketsSent: parsed[2],
|
||||
Errout: parsed[3],
|
||||
Dropout: parsed[4],
|
||||
}
|
||||
ret = append(ret, n)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func IOCounters(pernic bool) ([]IOCountersStat, error) {
|
||||
return IOCountersWithContext(context.Background(), pernic)
|
||||
}
|
||||
|
||||
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := invoke.CommandWithContext(ctx, netstat, "-idn")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iocounters, err := parseNetstatI(string(out))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pernic == false {
|
||||
return getIOCountersAll(iocounters)
|
||||
}
|
||||
return iocounters, nil
|
||||
|
||||
}
|
||||
|
||||
// NetIOCountersByFile is an method which is added just a compatibility for linux.
|
||||
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
|
||||
return IOCountersByFileWithContext(context.Background(), pernic, filename)
|
||||
}
|
||||
|
||||
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
|
||||
return IOCounters(pernic)
|
||||
}
|
||||
|
||||
func FilterCounters() ([]FilterStat, error) {
|
||||
return FilterCountersWithContext(context.Background())
|
||||
}
|
||||
|
||||
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
|
||||
return ConntrackStatsWithContext(context.Background(), percpu)
|
||||
}
|
||||
|
||||
func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
|
||||
return ProtoCountersWithContext(context.Background(), protocols)
|
||||
}
|
||||
|
||||
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func parseNetstatNetLine(line string) (ConnectionStat, error) {
|
||||
f := strings.Fields(line)
|
||||
if len(f) < 5 {
|
||||
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
|
||||
}
|
||||
|
||||
var netType, netFamily uint32
|
||||
switch f[0] {
|
||||
case "tcp", "tcp4":
|
||||
netType = syscall.SOCK_STREAM
|
||||
netFamily = syscall.AF_INET
|
||||
case "udp", "udp4":
|
||||
netType = syscall.SOCK_DGRAM
|
||||
netFamily = syscall.AF_INET
|
||||
case "tcp6":
|
||||
netType = syscall.SOCK_STREAM
|
||||
netFamily = syscall.AF_INET6
|
||||
case "udp6":
|
||||
netType = syscall.SOCK_DGRAM
|
||||
netFamily = syscall.AF_INET6
|
||||
default:
|
||||
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0])
|
||||
}
|
||||
|
||||
laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily)
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4])
|
||||
}
|
||||
|
||||
n := ConnectionStat{
|
||||
Fd: uint32(0), // not supported
|
||||
Family: uint32(netFamily),
|
||||
Type: uint32(netType),
|
||||
Laddr: laddr,
|
||||
Raddr: raddr,
|
||||
Pid: int32(0), // not supported
|
||||
}
|
||||
if len(f) == 6 {
|
||||
n.Status = f[5]
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`)
|
||||
|
||||
// This function only works for netstat returning addresses with a "."
|
||||
// before the port (0.0.0.0.22 instead of 0.0.0.0:22).
|
||||
func parseNetstatAddr(local string, remote string, family uint32) (laddr Addr, raddr Addr, err error) {
|
||||
parse := func(l string) (Addr, error) {
|
||||
matches := portMatch.FindStringSubmatch(l)
|
||||
if matches == nil {
|
||||
return Addr{}, fmt.Errorf("wrong addr, %s", l)
|
||||
}
|
||||
host := matches[1]
|
||||
port := matches[2]
|
||||
if host == "*" {
|
||||
switch family {
|
||||
case syscall.AF_INET:
|
||||
host = "0.0.0.0"
|
||||
case syscall.AF_INET6:
|
||||
host = "::"
|
||||
default:
|
||||
return Addr{}, fmt.Errorf("unknown family, %d", family)
|
||||
}
|
||||
}
|
||||
lport, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return Addr{}, err
|
||||
}
|
||||
return Addr{IP: host, Port: uint32(lport)}, nil
|
||||
}
|
||||
|
||||
laddr, err = parse(local)
|
||||
if remote != "*.*" { // remote addr exists
|
||||
raddr, err = parse(remote)
|
||||
if err != nil {
|
||||
return laddr, raddr, err
|
||||
}
|
||||
}
|
||||
|
||||
return laddr, raddr, err
|
||||
}
|
||||
|
||||
func parseNetstatUnixLine(f []string) (ConnectionStat, error) {
|
||||
if len(f) < 8 {
|
||||
return ConnectionStat{}, fmt.Errorf("wrong number of fields: expected >=8 got %d", len(f))
|
||||
}
|
||||
|
||||
var netType uint32
|
||||
|
||||
switch f[1] {
|
||||
case "dgram":
|
||||
netType = syscall.SOCK_DGRAM
|
||||
case "stream":
|
||||
netType = syscall.SOCK_STREAM
|
||||
default:
|
||||
return ConnectionStat{}, fmt.Errorf("unknown type: %s", f[1])
|
||||
}
|
||||
|
||||
// Some Unix Socket don't have any address associated
|
||||
addr := ""
|
||||
if len(f) == 9 {
|
||||
addr = f[8]
|
||||
}
|
||||
|
||||
c := ConnectionStat{
|
||||
Fd: uint32(0), // not supported
|
||||
Family: uint32(syscall.AF_UNIX),
|
||||
Type: uint32(netType),
|
||||
Laddr: Addr{
|
||||
IP: addr,
|
||||
},
|
||||
Status: "NONE",
|
||||
Pid: int32(0), // not supported
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Return true if proto is the corresponding to the kind parameter
|
||||
// Only for Inet lines
|
||||
func hasCorrectInetProto(kind, proto string) bool {
|
||||
switch kind {
|
||||
case "all", "inet":
|
||||
return true
|
||||
case "unix":
|
||||
return false
|
||||
case "inet4":
|
||||
return !strings.HasSuffix(proto, "6")
|
||||
case "inet6":
|
||||
return strings.HasSuffix(proto, "6")
|
||||
case "tcp":
|
||||
return proto == "tcp" || proto == "tcp4" || proto == "tcp6"
|
||||
case "tcp4":
|
||||
return proto == "tcp" || proto == "tcp4"
|
||||
case "tcp6":
|
||||
return proto == "tcp6"
|
||||
case "udp":
|
||||
return proto == "udp" || proto == "udp4" || proto == "udp6"
|
||||
case "udp4":
|
||||
return proto == "udp" || proto == "udp4"
|
||||
case "udp6":
|
||||
return proto == "udp6"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseNetstatA(output string, kind string) ([]ConnectionStat, error) {
|
||||
var ret []ConnectionStat
|
||||
lines := strings.Split(string(output), "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(fields[0], "f1") {
|
||||
// Unix lines
|
||||
if len(fields) < 2 {
|
||||
// every unix connections have two lines
|
||||
continue
|
||||
}
|
||||
|
||||
c, err := parseNetstatUnixLine(fields)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Unix Address (%s): %s", line, err)
|
||||
}
|
||||
|
||||
ret = append(ret, c)
|
||||
|
||||
} else if strings.HasPrefix(fields[0], "tcp") || strings.HasPrefix(fields[0], "udp") {
|
||||
// Inet lines
|
||||
if !hasCorrectInetProto(kind, fields[0]) {
|
||||
continue
|
||||
}
|
||||
|
||||
// On AIX, netstat display some connections with "*.*" as local addresses
|
||||
// Skip them as they aren't real connections.
|
||||
if fields[3] == "*.*" {
|
||||
continue
|
||||
}
|
||||
|
||||
c, err := parseNetstatNetLine(line)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Inet Address (%s): %s", line, err)
|
||||
}
|
||||
|
||||
ret = append(ret, c)
|
||||
} else {
|
||||
// Header lines
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
||||
func Connections(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
|
||||
args := []string{"-na"}
|
||||
switch strings.ToLower(kind) {
|
||||
default:
|
||||
fallthrough
|
||||
case "":
|
||||
kind = "all"
|
||||
case "all":
|
||||
// nothing to add
|
||||
case "inet", "inet4", "inet6":
|
||||
args = append(args, "-finet")
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
args = append(args, "-finet")
|
||||
case "udp", "udp4", "udp6":
|
||||
args = append(args, "-finet")
|
||||
case "unix":
|
||||
args = append(args, "-funix")
|
||||
}
|
||||
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := invoke.CommandWithContext(ctx, netstat, args...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret, err := parseNetstatA(string(out), kind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
||||
func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithContext(context.Background(), kind, max)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
// Return a list of network connections opened, omitting `Uids`.
|
||||
// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be
|
||||
// removed from the API in the future.
|
||||
func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithoutUidsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !darwin,!linux,!freebsd,!openbsd,!windows
|
||||
// +build !aix,!darwin,!linux,!freebsd,!openbsd,!windows
|
||||
|
||||
package net
|
||||
|
||||
|
@ -55,3 +55,38 @@ func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
|
|||
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
// Return a list of network connections opened, omitting `Uids`.
|
||||
// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be
|
||||
// removed from the API in the future.
|
||||
func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithoutUidsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) {
|
|||
|
||||
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
|
||||
filename := common.HostProc("net/dev")
|
||||
return IOCountersByFile(pernic, filename)
|
||||
return IOCountersByFileWithContext(ctx, pernic, filename)
|
||||
}
|
||||
|
||||
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
|
||||
|
@ -401,32 +401,36 @@ func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]Con
|
|||
return ConnectionsPidMax(kind, 0, max)
|
||||
}
|
||||
|
||||
// Return a list of network connections opened, omitting `Uids`.
|
||||
// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be
|
||||
// removed from the API in the future.
|
||||
func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithoutUidsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max)
|
||||
}
|
||||
|
||||
// Return a list of network connections opened by a process.
|
||||
func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
tmap, ok := netConnectionKindMap[kind]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid kind, %s", kind)
|
||||
}
|
||||
root := common.HostProc()
|
||||
var err error
|
||||
var inodes map[string][]inodeMap
|
||||
if pid == 0 {
|
||||
inodes, err = getProcInodesAll(root, 0)
|
||||
} else {
|
||||
inodes, err = getProcInodes(root, pid, 0)
|
||||
if len(inodes) == 0 {
|
||||
// no connection for the pid
|
||||
return []ConnectionStat{}, nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err)
|
||||
}
|
||||
return statsFromInodes(root, pid, tmap, inodes)
|
||||
return ConnectionsPidMaxWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
// Return up to `max` network connections opened by a process.
|
||||
|
@ -434,7 +438,19 @@ func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error
|
|||
return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max, false)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max, true)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int, skipUids bool) ([]ConnectionStat, error) {
|
||||
tmap, ok := netConnectionKindMap[kind]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid kind, %s", kind)
|
||||
|
@ -452,12 +468,12 @@ func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, m
|
|||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cound not get pid(s), %d", pid)
|
||||
return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err)
|
||||
}
|
||||
return statsFromInodes(root, pid, tmap, inodes)
|
||||
return statsFromInodes(root, pid, tmap, inodes, skipUids)
|
||||
}
|
||||
|
||||
func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inodes map[string][]inodeMap) ([]ConnectionStat, error) {
|
||||
func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inodes map[string][]inodeMap, skipUids bool) ([]ConnectionStat, error) {
|
||||
dupCheckMap := make(map[string]struct{})
|
||||
var ret []ConnectionStat
|
||||
|
||||
|
@ -504,9 +520,11 @@ func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inode
|
|||
conn.Pid = c.pid
|
||||
}
|
||||
|
||||
// fetch process owner Real, effective, saved set, and filesystem UIDs
|
||||
proc := process{Pid: conn.Pid}
|
||||
conn.Uids, _ = proc.getUids()
|
||||
if !skipUids {
|
||||
// fetch process owner Real, effective, saved set, and filesystem UIDs
|
||||
proc := process{Pid: conn.Pid}
|
||||
conn.Uids, _ = proc.getUids()
|
||||
}
|
||||
|
||||
ret = append(ret, conn)
|
||||
dupCheckMap[connKey] = struct{}{}
|
||||
|
|
|
@ -4,7 +4,11 @@ package net
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
@ -86,6 +90,95 @@ func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]C
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
var constMap = map[string]int{
|
||||
"unix": syscall.AF_UNIX,
|
||||
"TCP": syscall.SOCK_STREAM,
|
||||
"UDP": syscall.SOCK_DGRAM,
|
||||
"IPv4": syscall.AF_INET,
|
||||
"IPv6": syscall.AF_INET6,
|
||||
}
|
||||
|
||||
func parseNetLine(line string) (ConnectionStat, error) {
|
||||
f := strings.Fields(line)
|
||||
if len(f) < 8 {
|
||||
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
|
||||
}
|
||||
|
||||
if len(f) == 8 {
|
||||
f = append(f, f[7])
|
||||
f[7] = "unix"
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(f[1])
|
||||
if err != nil {
|
||||
return ConnectionStat{}, err
|
||||
}
|
||||
fd, err := strconv.Atoi(strings.Trim(f[3], "u"))
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3])
|
||||
}
|
||||
netFamily, ok := constMap[f[4]]
|
||||
if !ok {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4])
|
||||
}
|
||||
netType, ok := constMap[f[7]]
|
||||
if !ok {
|
||||
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7])
|
||||
}
|
||||
|
||||
var laddr, raddr Addr
|
||||
if f[7] == "unix" {
|
||||
laddr.IP = f[8]
|
||||
} else {
|
||||
laddr, raddr, err = parseNetAddr(f[8])
|
||||
if err != nil {
|
||||
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8])
|
||||
}
|
||||
}
|
||||
|
||||
n := ConnectionStat{
|
||||
Fd: uint32(fd),
|
||||
Family: uint32(netFamily),
|
||||
Type: uint32(netType),
|
||||
Laddr: laddr,
|
||||
Raddr: raddr,
|
||||
Pid: int32(pid),
|
||||
}
|
||||
if len(f) == 10 {
|
||||
n.Status = strings.Trim(f[9], "()")
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func parseNetAddr(line string) (laddr Addr, raddr Addr, err error) {
|
||||
parse := func(l string) (Addr, error) {
|
||||
host, port, err := net.SplitHostPort(l)
|
||||
if err != nil {
|
||||
return Addr{}, fmt.Errorf("wrong addr, %s", l)
|
||||
}
|
||||
lport, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return Addr{}, err
|
||||
}
|
||||
return Addr{IP: host, Port: uint32(lport)}, nil
|
||||
}
|
||||
|
||||
addrs := strings.Split(line, "->")
|
||||
if len(addrs) == 0 {
|
||||
return laddr, raddr, fmt.Errorf("wrong netaddr, %s", line)
|
||||
}
|
||||
laddr, err = parse(addrs[0])
|
||||
if len(addrs) == 2 { // remote addr exists
|
||||
raddr, err = parse(addrs[1])
|
||||
if err != nil {
|
||||
return laddr, raddr, err
|
||||
}
|
||||
}
|
||||
|
||||
return laddr, raddr, err
|
||||
}
|
||||
|
||||
// Return up to `max` network connections opened by a process.
|
||||
func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max)
|
||||
|
@ -94,3 +187,38 @@ func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error
|
|||
func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
// Return a list of network connections opened, omitting `Uids`.
|
||||
// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be
|
||||
// removed from the API in the future.
|
||||
func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithoutUidsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
|
|
@ -283,6 +283,41 @@ func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]Con
|
|||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
// Return a list of network connections opened, omitting `Uids`.
|
||||
// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be
|
||||
// removed from the API in the future.
|
||||
func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsWithoutUidsWithContext(context.Background(), kind)
|
||||
}
|
||||
|
||||
func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
|
||||
return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0)
|
||||
}
|
||||
|
||||
func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid)
|
||||
}
|
||||
|
||||
func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max)
|
||||
}
|
||||
|
||||
func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max)
|
||||
}
|
||||
|
||||
func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
|
||||
return []ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func FilterCounters() ([]FilterStat, error) {
|
||||
return FilterCountersWithContext(context.Background())
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math"
|
||||
"runtime"
|
||||
"sort"
|
||||
"time"
|
||||
|
@ -164,7 +163,7 @@ func NewProcess(pid int32) (*Process, error) {
|
|||
if !exists {
|
||||
return p, ErrorProcessNotRunning
|
||||
}
|
||||
go p.CreateTime()
|
||||
p.CreateTime()
|
||||
return p, nil
|
||||
}
|
||||
|
||||
|
@ -265,7 +264,7 @@ func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64
|
|||
}
|
||||
delta_proc := t2.Total() - t1.Total()
|
||||
overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
|
||||
return math.Min(100, math.Max(0, overall_percent))
|
||||
return overall_percent
|
||||
}
|
||||
|
||||
// MemoryPercent returns how many percent of the total RAM this process uses
|
||||
|
@ -286,7 +285,7 @@ func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error)
|
|||
}
|
||||
used := processMemory.RSS
|
||||
|
||||
return float32(math.Min(100, math.Max(0, (100*float64(used)/float64(total))))), nil
|
||||
return (100 * float32(used) / float32(total)), nil
|
||||
}
|
||||
|
||||
// CPU_Percent returns how many percent of the CPU time this process uses
|
||||
|
@ -311,5 +310,5 @@ func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
|
|||
return 0, nil
|
||||
}
|
||||
|
||||
return math.Min(100, math.Max(0, 100*cput.Total()/totalTime)), nil
|
||||
return 100 * cput.Total() / totalTime, nil
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -89,8 +90,24 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
name := common.IntToString(k.Proc.P_comm[:])
|
||||
|
||||
return common.IntToString(k.Proc.P_comm[:]), nil
|
||||
if len(name) >= 15 {
|
||||
cmdlineSlice, err := p.CmdlineSliceWithContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(cmdlineSlice) > 0 {
|
||||
extendedName := filepath.Base(cmdlineSlice[0])
|
||||
if strings.HasPrefix(extendedName, p.name) {
|
||||
name = extendedName
|
||||
} else {
|
||||
name = cmdlineSlice[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
return 0, common.ErrNotImplementedError
|
||||
|
@ -199,7 +216,7 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
return r[0][0], err
|
||||
return r[0][0][0:1], err
|
||||
}
|
||||
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
|
|
|
@ -22,7 +22,7 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
|
|||
}
|
||||
txtFound := 0
|
||||
lines := strings.Split(string(out), "\n")
|
||||
for i := 1; i < len(lines); i += 2 {
|
||||
for i := 1; i < len(lines); i++ {
|
||||
if lines[i] == "ftxt" {
|
||||
txtFound++
|
||||
if txtFound == 2 {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"context"
|
||||
"encoding/binary"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -58,8 +59,24 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
name := common.IntToString(k.Comm[:])
|
||||
|
||||
return common.IntToString(k.Comm[:]), nil
|
||||
if len(name) >= 15 {
|
||||
cmdlineSlice, err := p.CmdlineSliceWithContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(cmdlineSlice) > 0 {
|
||||
extendedName := filepath.Base(cmdlineSlice[0])
|
||||
if strings.HasPrefix(extendedName, p.name) {
|
||||
name = extendedName
|
||||
} else {
|
||||
name = cmdlineSlice[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
return 0, common.ErrNotImplementedError
|
||||
|
|
201
vendor/github.com/shirou/gopsutil/process/process_freebsd_arm64.go
generated
vendored
Normal file
201
vendor/github.com/shirou/gopsutil/process/process_freebsd_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
// +build freebsd
|
||||
// +build arm64
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs process/types_freebsd.go
|
||||
|
||||
package process
|
||||
|
||||
const (
|
||||
CTLKern = 1
|
||||
KernProc = 14
|
||||
KernProcPID = 1
|
||||
KernProcProc = 8
|
||||
KernProcPathname = 12
|
||||
KernProcArgs = 7
|
||||
)
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
)
|
||||
|
||||
const (
|
||||
sizeOfKinfoVmentry = 0x488
|
||||
sizeOfKinfoProc = 0x440
|
||||
)
|
||||
|
||||
const (
|
||||
SIDL = 1
|
||||
SRUN = 2
|
||||
SSLEEP = 3
|
||||
SSTOP = 4
|
||||
SZOMB = 5
|
||||
SWAIT = 6
|
||||
SLOCK = 7
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
)
|
||||
|
||||
type Timespec struct {
|
||||
Sec int64
|
||||
Nsec int64
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int64
|
||||
}
|
||||
|
||||
type Rusage struct {
|
||||
Utime Timeval
|
||||
Stime Timeval
|
||||
Maxrss int64
|
||||
Ixrss int64
|
||||
Idrss int64
|
||||
Isrss int64
|
||||
Minflt int64
|
||||
Majflt int64
|
||||
Nswap int64
|
||||
Inblock int64
|
||||
Oublock int64
|
||||
Msgsnd int64
|
||||
Msgrcv int64
|
||||
Nsignals int64
|
||||
Nvcsw int64
|
||||
Nivcsw int64
|
||||
}
|
||||
|
||||
type Rlimit struct {
|
||||
Cur int64
|
||||
Max int64
|
||||
}
|
||||
|
||||
type KinfoProc struct {
|
||||
Structsize int32
|
||||
Layout int32
|
||||
Args *int64 /* pargs */
|
||||
Paddr *int64 /* proc */
|
||||
Addr *int64 /* user */
|
||||
Tracep *int64 /* vnode */
|
||||
Textvp *int64 /* vnode */
|
||||
Fd *int64 /* filedesc */
|
||||
Vmspace *int64 /* vmspace */
|
||||
Wchan *byte
|
||||
Pid int32
|
||||
Ppid int32
|
||||
Pgid int32
|
||||
Tpgid int32
|
||||
Sid int32
|
||||
Tsid int32
|
||||
Jobc int16
|
||||
Spare_short1 int16
|
||||
Tdev_freebsd11 uint32
|
||||
Siglist [16]byte /* sigset */
|
||||
Sigmask [16]byte /* sigset */
|
||||
Sigignore [16]byte /* sigset */
|
||||
Sigcatch [16]byte /* sigset */
|
||||
Uid uint32
|
||||
Ruid uint32
|
||||
Svuid uint32
|
||||
Rgid uint32
|
||||
Svgid uint32
|
||||
Ngroups int16
|
||||
Spare_short2 int16
|
||||
Groups [16]uint32
|
||||
Size uint64
|
||||
Rssize int64
|
||||
Swrss int64
|
||||
Tsize int64
|
||||
Dsize int64
|
||||
Ssize int64
|
||||
Xstat uint16
|
||||
Acflag uint16
|
||||
Pctcpu uint32
|
||||
Estcpu uint32
|
||||
Slptime uint32
|
||||
Swtime uint32
|
||||
Cow uint32
|
||||
Runtime uint64
|
||||
Start Timeval
|
||||
Childtime Timeval
|
||||
Flag int64
|
||||
Kiflag int64
|
||||
Traceflag int32
|
||||
Stat uint8
|
||||
Nice int8
|
||||
Lock uint8
|
||||
Rqindex uint8
|
||||
Oncpu_old uint8
|
||||
Lastcpu_old uint8
|
||||
Tdname [17]uint8
|
||||
Wmesg [9]uint8
|
||||
Login [18]uint8
|
||||
Lockname [9]uint8
|
||||
Comm [20]int8
|
||||
Emul [17]uint8
|
||||
Loginclass [18]uint8
|
||||
Moretdname [4]uint8
|
||||
Sparestrings [46]uint8
|
||||
Spareints [2]int32
|
||||
Tdev uint64
|
||||
Oncpu int32
|
||||
Lastcpu int32
|
||||
Tracer int32
|
||||
Flag2 int32
|
||||
Fibnum int32
|
||||
Cr_flags uint32
|
||||
Jid int32
|
||||
Numthreads int32
|
||||
Tid int32
|
||||
Pri Priority
|
||||
Rusage Rusage
|
||||
Rusage_ch Rusage
|
||||
Pcb *int64 /* pcb */
|
||||
Kstack *byte
|
||||
Udata *byte
|
||||
Tdaddr *int64 /* thread */
|
||||
Spareptrs [6]*byte
|
||||
Sparelongs [12]int64
|
||||
Sflag int64
|
||||
Tdflags int64
|
||||
}
|
||||
|
||||
type Priority struct {
|
||||
Class uint8
|
||||
Level uint8
|
||||
Native uint8
|
||||
User uint8
|
||||
}
|
||||
|
||||
type KinfoVmentry struct {
|
||||
Structsize int32
|
||||
Type int32
|
||||
Start uint64
|
||||
End uint64
|
||||
Offset uint64
|
||||
Vn_fileid uint64
|
||||
Vn_fsid_freebsd11 uint32
|
||||
Flags int32
|
||||
Resident int32
|
||||
Private_resident int32
|
||||
Protection int32
|
||||
Ref_count int32
|
||||
Shadow_count int32
|
||||
Vn_type int32
|
||||
Vn_size uint64
|
||||
Vn_rdev_freebsd11 uint32
|
||||
Vn_mode uint16
|
||||
Status uint16
|
||||
Vn_fsid uint64
|
||||
Vn_rdev uint64
|
||||
X_kve_ispare [8]int32
|
||||
Path [1024]uint8
|
||||
}
|
|
@ -1157,10 +1157,19 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
|
|||
return 0, 0, nil, 0, 0, 0, nil, err
|
||||
}
|
||||
|
||||
// There is no such thing as iotime in stat file. As an approximation, we
|
||||
// will use delayacct_blkio_ticks (aggregated block I/O delays, as per Linux
|
||||
// docs). Note: I am assuming at least Linux 2.6.18
|
||||
iotime, err := strconv.ParseFloat(fields[i+40], 64)
|
||||
if err != nil {
|
||||
iotime = 0 // Ancient linux version, most likely
|
||||
}
|
||||
|
||||
cpuTimes := &cpu.TimesStat{
|
||||
CPU: "cpu",
|
||||
User: float64(utime / ClockTicks),
|
||||
System: float64(stime / ClockTicks),
|
||||
Iowait: float64(iotime / ClockTicks),
|
||||
}
|
||||
|
||||
bootTime, _ := common.BootTimeWithContext(ctx)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"encoding/binary"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
@ -61,8 +62,24 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
name := common.IntToString(k.Comm[:])
|
||||
|
||||
return common.IntToString(k.Comm[:]), nil
|
||||
if len(name) >= 15 {
|
||||
cmdlineSlice, err := p.CmdlineSliceWithContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(cmdlineSlice) > 0 {
|
||||
extendedName := filepath.Base(cmdlineSlice[0])
|
||||
if strings.HasPrefix(extendedName, p.name) {
|
||||
name = extendedName
|
||||
} else {
|
||||
name = cmdlineSlice[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
return 0, common.ErrNotImplementedError
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
@ -78,6 +79,20 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
|
||||
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
|
||||
// This covers the case when running inside container with a different process namespace (by default)
|
||||
|
||||
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return err == nil, err
|
||||
}
|
||||
|
||||
//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
|
||||
//Make sense only if we run in the same process namespace
|
||||
err = proc.Signal(syscall.Signal(0))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
|
@ -95,6 +110,7 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
|
|||
case syscall.EPERM:
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
|
|
@ -4,18 +4,16 @@ package process
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
cpu "github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
net "github.com/shirou/gopsutil/net"
|
||||
"github.com/shirou/w32"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
|
@ -30,6 +28,10 @@ var (
|
|||
|
||||
procQueryFullProcessImageNameW = common.Modkernel32.NewProc("QueryFullProcessImageNameW")
|
||||
procGetPriorityClass = common.Modkernel32.NewProc("GetPriorityClass")
|
||||
procGetProcessIoCounters = common.Modkernel32.NewProc("GetProcessIoCounters")
|
||||
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
|
||||
|
||||
processorArchitecture uint
|
||||
)
|
||||
|
||||
type SystemProcessInformation struct {
|
||||
|
@ -47,6 +49,28 @@ type SystemProcessInformation struct {
|
|||
Reserved6 [6]uint64
|
||||
}
|
||||
|
||||
type systemProcessorInformation struct {
|
||||
ProcessorArchitecture uint16
|
||||
ProcessorLevel uint16
|
||||
ProcessorRevision uint16
|
||||
Reserved uint16
|
||||
ProcessorFeatureBits uint16
|
||||
}
|
||||
|
||||
type systemInfo struct {
|
||||
wProcessorArchitecture uint16
|
||||
wReserved uint16
|
||||
dwPageSize uint32
|
||||
lpMinimumApplicationAddress uintptr
|
||||
lpMaximumApplicationAddress uintptr
|
||||
dwActiveProcessorMask uintptr
|
||||
dwNumberOfProcessors uint32
|
||||
dwProcessorType uint32
|
||||
dwAllocationGranularity uint32
|
||||
wProcessorLevel uint16
|
||||
wProcessorRevision uint16
|
||||
}
|
||||
|
||||
// Memory_info_ex is different between OSes
|
||||
type MemoryInfoExStat struct {
|
||||
}
|
||||
|
@ -54,43 +78,33 @@ type MemoryInfoExStat struct {
|
|||
type MemoryMapsStat struct {
|
||||
}
|
||||
|
||||
type Win32_Process struct {
|
||||
Name string
|
||||
ExecutablePath *string
|
||||
CommandLine *string
|
||||
Priority uint32
|
||||
CreationDate *time.Time
|
||||
ProcessID uint32
|
||||
ThreadCount uint32
|
||||
Status *string
|
||||
ReadOperationCount uint64
|
||||
ReadTransferCount uint64
|
||||
WriteOperationCount uint64
|
||||
WriteTransferCount uint64
|
||||
CSCreationClassName string
|
||||
CSName string
|
||||
Caption *string
|
||||
CreationClassName string
|
||||
Description *string
|
||||
ExecutionState *uint16
|
||||
HandleCount uint32
|
||||
KernelModeTime uint64
|
||||
MaximumWorkingSetSize *uint32
|
||||
MinimumWorkingSetSize *uint32
|
||||
OSCreationClassName string
|
||||
OSName string
|
||||
OtherOperationCount uint64
|
||||
OtherTransferCount uint64
|
||||
PageFaults uint32
|
||||
PageFileUsage uint32
|
||||
ParentProcessID uint32
|
||||
PeakPageFileUsage uint32
|
||||
PeakVirtualSize uint64
|
||||
PeakWorkingSetSize uint32
|
||||
PrivatePageCount uint64
|
||||
TerminationDate *time.Time
|
||||
UserModeTime uint64
|
||||
WorkingSetSize uint64
|
||||
// ioCounters is an equivalent representation of IO_COUNTERS in the Windows API.
|
||||
// https://docs.microsoft.com/windows/win32/api/winnt/ns-winnt-io_counters
|
||||
type ioCounters struct {
|
||||
ReadOperationCount uint64
|
||||
WriteOperationCount uint64
|
||||
OtherOperationCount uint64
|
||||
ReadTransferCount uint64
|
||||
WriteTransferCount uint64
|
||||
OtherTransferCount uint64
|
||||
}
|
||||
|
||||
type processBasicInformation32 struct {
|
||||
Reserved1 uint32
|
||||
PebBaseAddress uint32
|
||||
Reserved2 uint32
|
||||
Reserved3 uint32
|
||||
UniqueProcessId uint32
|
||||
Reserved4 uint32
|
||||
}
|
||||
|
||||
type processBasicInformation64 struct {
|
||||
Reserved1 uint64
|
||||
PebBaseAddress uint64
|
||||
Reserved2 uint64
|
||||
Reserved3 uint64
|
||||
UniqueProcessId uint64
|
||||
Reserved4 uint64
|
||||
}
|
||||
|
||||
type winLUID struct {
|
||||
|
@ -114,7 +128,10 @@ type winLong int32
|
|||
type winDWord uint32
|
||||
|
||||
func init() {
|
||||
wmi.DefaultClient.AllowMissingFields = true
|
||||
var systemInfo systemInfo
|
||||
|
||||
procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo)))
|
||||
processorArchitecture = uint(systemInfo.wProcessorArchitecture)
|
||||
|
||||
// enable SeDebugPrivilege https://github.com/midstar/proci/blob/6ec79f57b90ba3d9efa2a7b16ef9c9369d4be875/proci_windows.go#L80-L119
|
||||
handle, err := syscall.GetCurrentProcess()
|
||||
|
@ -160,8 +177,8 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
for {
|
||||
ps := make([]uint32, psSize)
|
||||
if !w32.EnumProcesses(ps, uint32(len(ps)), &read) {
|
||||
return nil, fmt.Errorf("could not get w32.EnumProcesses")
|
||||
if err := windows.EnumProcesses(ps, &read); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uint32(len(ps)) == read { // ps buffer was too small to host every results, retry with a bigger one
|
||||
psSize += 1024
|
||||
|
@ -226,26 +243,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
|||
return ppid, nil
|
||||
}
|
||||
|
||||
func GetWin32Proc(pid int32) ([]Win32_Process, error) {
|
||||
return GetWin32ProcWithContext(context.Background(), pid)
|
||||
}
|
||||
|
||||
func GetWin32ProcWithContext(ctx context.Context, pid int32) ([]Win32_Process, error) {
|
||||
var dst []Win32_Process
|
||||
query := fmt.Sprintf("WHERE ProcessId = %d", pid)
|
||||
q := wmi.CreateQuery(&dst, query)
|
||||
err := common.WMIQueryWithContext(ctx, q, &dst)
|
||||
if err != nil {
|
||||
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: %s", err)
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: empty")
|
||||
}
|
||||
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
@ -297,12 +294,12 @@ func (p *Process) Cmdline() (string, error) {
|
|||
return p.CmdlineWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
||||
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
|
||||
func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
|
||||
cmdline, err := getProcessCommandLine(p.Pid)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not get CommandLine: %s", err)
|
||||
}
|
||||
return *dst[0].CommandLine, nil
|
||||
return cmdline, nil
|
||||
}
|
||||
|
||||
// CmdlineSlice returns the command line arguments of the process as a slice with each
|
||||
|
@ -480,18 +477,24 @@ func (p *Process) IOCounters() (*IOCountersStat, error) {
|
|||
}
|
||||
|
||||
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
|
||||
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
|
||||
if err != nil || len(dst) == 0 {
|
||||
return nil, fmt.Errorf("could not get Win32Proc: %s", err)
|
||||
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &IOCountersStat{
|
||||
ReadCount: uint64(dst[0].ReadOperationCount),
|
||||
ReadBytes: uint64(dst[0].ReadTransferCount),
|
||||
WriteCount: uint64(dst[0].WriteOperationCount),
|
||||
WriteBytes: uint64(dst[0].WriteTransferCount),
|
||||
defer windows.CloseHandle(c)
|
||||
var ioCounters ioCounters
|
||||
ret, _, err := procGetProcessIoCounters.Call(uintptr(c), uintptr(unsafe.Pointer(&ioCounters)))
|
||||
if ret == 0 {
|
||||
return nil, err
|
||||
}
|
||||
stats := &IOCountersStat{
|
||||
ReadCount: ioCounters.ReadOperationCount,
|
||||
ReadBytes: ioCounters.ReadTransferCount,
|
||||
WriteCount: ioCounters.WriteOperationCount,
|
||||
WriteBytes: ioCounters.WriteTransferCount,
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
return stats, nil
|
||||
}
|
||||
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
|
||||
return p.NumCtxSwitchesWithContext(context.Background())
|
||||
|
@ -599,24 +602,24 @@ func (p *Process) Children() ([]*Process, error) {
|
|||
|
||||
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
||||
out := []*Process{}
|
||||
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(0))
|
||||
if snap == 0 {
|
||||
return out, windows.GetLastError()
|
||||
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(0))
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
defer w32.CloseHandle(snap)
|
||||
var pe32 w32.PROCESSENTRY32
|
||||
pe32.DwSize = uint32(unsafe.Sizeof(pe32))
|
||||
if !w32.Process32First(snap, &pe32) {
|
||||
return out, windows.GetLastError()
|
||||
defer windows.CloseHandle(snap)
|
||||
var pe32 windows.ProcessEntry32
|
||||
pe32.Size = uint32(unsafe.Sizeof(pe32))
|
||||
if err := windows.Process32First(snap, &pe32); err != nil {
|
||||
return out, err
|
||||
}
|
||||
for {
|
||||
if pe32.Th32ParentProcessID == uint32(p.Pid) {
|
||||
p, err := NewProcess(int32(pe32.Th32ProcessID))
|
||||
if pe32.ParentProcessID == uint32(p.Pid) {
|
||||
p, err := NewProcess(int32(pe32.ProcessID))
|
||||
if err == nil {
|
||||
out = append(out, p)
|
||||
}
|
||||
}
|
||||
if !w32.Process32Next(snap, &pe32) {
|
||||
if err = windows.Process32Next(snap, &pe32); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -692,16 +695,13 @@ func (p *Process) Terminate() error {
|
|||
}
|
||||
|
||||
func (p *Process) TerminateWithContext(ctx context.Context) error {
|
||||
// PROCESS_TERMINATE = 0x0001
|
||||
proc := w32.OpenProcess(0x0001, false, uint32(p.Pid))
|
||||
ret := w32.TerminateProcess(proc, 0)
|
||||
w32.CloseHandle(proc)
|
||||
|
||||
if ret == false {
|
||||
return windows.GetLastError()
|
||||
} else {
|
||||
return nil
|
||||
proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = windows.TerminateProcess(proc, 0)
|
||||
windows.CloseHandle(proc)
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Process) Kill() error {
|
||||
|
@ -714,22 +714,22 @@ func (p *Process) KillWithContext(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func getFromSnapProcess(pid int32) (int32, int32, string, error) {
|
||||
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid))
|
||||
if snap == 0 {
|
||||
return 0, 0, "", windows.GetLastError()
|
||||
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid))
|
||||
if err != nil {
|
||||
return 0, 0, "", err
|
||||
}
|
||||
defer w32.CloseHandle(snap)
|
||||
var pe32 w32.PROCESSENTRY32
|
||||
pe32.DwSize = uint32(unsafe.Sizeof(pe32))
|
||||
if !w32.Process32First(snap, &pe32) {
|
||||
return 0, 0, "", windows.GetLastError()
|
||||
defer windows.CloseHandle(snap)
|
||||
var pe32 windows.ProcessEntry32
|
||||
pe32.Size = uint32(unsafe.Sizeof(pe32))
|
||||
if err = windows.Process32First(snap, &pe32); err != nil {
|
||||
return 0, 0, "", err
|
||||
}
|
||||
for {
|
||||
if pe32.Th32ProcessID == uint32(pid) {
|
||||
szexe := windows.UTF16ToString(pe32.SzExeFile[:])
|
||||
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
|
||||
if pe32.ProcessID == uint32(pid) {
|
||||
szexe := windows.UTF16ToString(pe32.ExeFile[:])
|
||||
return int32(pe32.ParentProcessID), int32(pe32.Threads), szexe, nil
|
||||
}
|
||||
if !w32.Process32Next(snap, &pe32) {
|
||||
if err = windows.Process32Next(snap, &pe32); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -760,28 +760,10 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func getProcInfo(pid int32) (*SystemProcessInformation, error) {
|
||||
initialBufferSize := uint64(0x4000)
|
||||
bufferSize := initialBufferSize
|
||||
buffer := make([]byte, bufferSize)
|
||||
|
||||
var sysProcInfo SystemProcessInformation
|
||||
ret, _, _ := common.ProcNtQuerySystemInformation.Call(
|
||||
uintptr(unsafe.Pointer(&sysProcInfo)),
|
||||
uintptr(unsafe.Pointer(&buffer[0])),
|
||||
uintptr(unsafe.Pointer(&bufferSize)),
|
||||
uintptr(unsafe.Pointer(&bufferSize)))
|
||||
if ret != 0 {
|
||||
return nil, windows.GetLastError()
|
||||
}
|
||||
|
||||
return &sysProcInfo, nil
|
||||
}
|
||||
|
||||
func getRusage(pid int32) (*windows.Rusage, error) {
|
||||
var CPU windows.Rusage
|
||||
|
||||
c, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, uint32(pid))
|
||||
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -846,3 +828,148 @@ func getProcessCPUTimes(pid int32) (SYSTEM_TIMES, error) {
|
|||
|
||||
return times, err
|
||||
}
|
||||
|
||||
func is32BitProcess(procHandle syscall.Handle) bool {
|
||||
var wow64 uint
|
||||
|
||||
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(common.ProcessWow64Information),
|
||||
uintptr(unsafe.Pointer(&wow64)),
|
||||
uintptr(unsafe.Sizeof(wow64)),
|
||||
uintptr(0),
|
||||
)
|
||||
if int(ret) >= 0 {
|
||||
if wow64 != 0 {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
//if the OS does not support the call, we fallback into the bitness of the app
|
||||
if unsafe.Sizeof(wow64) == 4 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getProcessCommandLine(pid int32) (string, error) {
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION | windows.PROCESS_VM_READ, false, uint32(pid))
|
||||
if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER {
|
||||
return "", nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer syscall.CloseHandle(syscall.Handle(h))
|
||||
|
||||
const (
|
||||
PROCESSOR_ARCHITECTURE_INTEL = 0
|
||||
PROCESSOR_ARCHITECTURE_ARM = 5
|
||||
PROCESSOR_ARCHITECTURE_ARM64 = 12
|
||||
PROCESSOR_ARCHITECTURE_IA64 = 6
|
||||
PROCESSOR_ARCHITECTURE_AMD64 = 9
|
||||
)
|
||||
|
||||
procIs32Bits := true
|
||||
switch processorArchitecture {
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
fallthrough
|
||||
case PROCESSOR_ARCHITECTURE_ARM:
|
||||
procIs32Bits = true
|
||||
|
||||
case PROCESSOR_ARCHITECTURE_ARM64:
|
||||
fallthrough
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
fallthrough
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
procIs32Bits = is32BitProcess(syscall.Handle(h))
|
||||
|
||||
default:
|
||||
//for other unknown platforms, we rely on process platform
|
||||
if unsafe.Sizeof(processorArchitecture) == 8 {
|
||||
procIs32Bits = false
|
||||
}
|
||||
}
|
||||
|
||||
pebAddress := queryPebAddress(syscall.Handle(h), procIs32Bits)
|
||||
if pebAddress == 0 {
|
||||
return "", errors.New("cannot locate process PEB")
|
||||
}
|
||||
|
||||
if procIs32Bits {
|
||||
buf := readProcessMemory(syscall.Handle(h), procIs32Bits, pebAddress + uint64(16), 4)
|
||||
if len(buf) != 4 {
|
||||
return "", errors.New("cannot locate process user parameters")
|
||||
}
|
||||
userProcParams := uint64(buf[0]) | (uint64(buf[1]) << 8) | (uint64(buf[2]) << 16) | (uint64(buf[3]) << 24)
|
||||
|
||||
//read CommandLine field from PRTL_USER_PROCESS_PARAMETERS
|
||||
remoteCmdLine := readProcessMemory(syscall.Handle(h), procIs32Bits, userProcParams + uint64(64), 8)
|
||||
if len(remoteCmdLine) != 8 {
|
||||
return "", errors.New("cannot read cmdline field")
|
||||
}
|
||||
|
||||
//remoteCmdLine is actually a UNICODE_STRING32
|
||||
//the first two bytes has the length
|
||||
cmdLineLength := uint(remoteCmdLine[0]) | (uint(remoteCmdLine[1]) << 8)
|
||||
if cmdLineLength > 0 {
|
||||
//and, at offset 4, is the pointer to the buffer
|
||||
bufferAddress := uint32(remoteCmdLine[4]) | (uint32(remoteCmdLine[5]) << 8) |
|
||||
(uint32(remoteCmdLine[6]) << 16) | (uint32(remoteCmdLine[7]) << 24)
|
||||
|
||||
cmdLine := readProcessMemory(syscall.Handle(h), procIs32Bits, uint64(bufferAddress), cmdLineLength)
|
||||
if len(cmdLine) != int(cmdLineLength) {
|
||||
return "", errors.New("cannot read cmdline")
|
||||
}
|
||||
|
||||
return convertUTF16ToString(cmdLine), nil
|
||||
}
|
||||
} else {
|
||||
buf := readProcessMemory(syscall.Handle(h), procIs32Bits, pebAddress + uint64(32), 8)
|
||||
if len(buf) != 8 {
|
||||
return "", errors.New("cannot locate process user parameters")
|
||||
}
|
||||
userProcParams := uint64(buf[0]) | (uint64(buf[1]) << 8) | (uint64(buf[2]) << 16) | (uint64(buf[3]) << 24) |
|
||||
(uint64(buf[4]) << 32) | (uint64(buf[5]) << 40) | (uint64(buf[6]) << 48) | (uint64(buf[7]) << 56)
|
||||
|
||||
//read CommandLine field from PRTL_USER_PROCESS_PARAMETERS
|
||||
remoteCmdLine := readProcessMemory(syscall.Handle(h), procIs32Bits, userProcParams + uint64(112), 16)
|
||||
if len(remoteCmdLine) != 16 {
|
||||
return "", errors.New("cannot read cmdline field")
|
||||
}
|
||||
|
||||
//remoteCmdLine is actually a UNICODE_STRING64
|
||||
//the first two bytes has the length
|
||||
cmdLineLength := uint(remoteCmdLine[0]) | (uint(remoteCmdLine[1]) << 8)
|
||||
if cmdLineLength > 0 {
|
||||
//and, at offset 8, is the pointer to the buffer
|
||||
bufferAddress := uint64(remoteCmdLine[8]) | (uint64(remoteCmdLine[9]) << 8) |
|
||||
(uint64(remoteCmdLine[10]) << 16) | (uint64(remoteCmdLine[11]) << 24) |
|
||||
(uint64(remoteCmdLine[12]) << 32) | (uint64(remoteCmdLine[13]) << 40) |
|
||||
(uint64(remoteCmdLine[14]) << 48) | (uint64(remoteCmdLine[15]) << 56)
|
||||
|
||||
cmdLine := readProcessMemory(syscall.Handle(h), procIs32Bits, bufferAddress, cmdLineLength)
|
||||
if len(cmdLine) != int(cmdLineLength) {
|
||||
return "", errors.New("cannot read cmdline")
|
||||
}
|
||||
|
||||
return convertUTF16ToString(cmdLine), nil
|
||||
}
|
||||
}
|
||||
|
||||
//if we reach here, we have no command line
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func convertUTF16ToString(src []byte) string {
|
||||
srcLen := len(src) / 2
|
||||
|
||||
codePoints := make([]uint16, srcLen)
|
||||
|
||||
srcIdx := 0
|
||||
for i := 0; i < srcLen; i++ {
|
||||
codePoints[i] = uint16(src[srcIdx]) | uint16(src[srcIdx + 1] << 8)
|
||||
srcIdx += 2
|
||||
}
|
||||
return syscall.UTF16ToString(codePoints)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
package process
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
||||
type PROCESS_MEMORY_COUNTERS struct {
|
||||
CB uint32
|
||||
PageFaultCount uint32
|
||||
|
@ -14,3 +21,82 @@ type PROCESS_MEMORY_COUNTERS struct {
|
|||
PagefileUsage uint32
|
||||
PeakPagefileUsage uint32
|
||||
}
|
||||
|
||||
func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) uint64 {
|
||||
if is32BitProcess {
|
||||
//we are on a 32-bit process reading an external 32-bit process
|
||||
var info processBasicInformation32
|
||||
|
||||
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(common.ProcessBasicInformation),
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uintptr(unsafe.Sizeof(info)),
|
||||
uintptr(0),
|
||||
)
|
||||
if int(ret) >= 0 {
|
||||
return uint64(info.PebBaseAddress)
|
||||
}
|
||||
} else {
|
||||
//we are on a 32-bit process reading an external 64-bit process
|
||||
if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic
|
||||
var info processBasicInformation64
|
||||
|
||||
ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(common.ProcessBasicInformation),
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uintptr(unsafe.Sizeof(info)),
|
||||
uintptr(0),
|
||||
)
|
||||
if int(ret) >= 0 {
|
||||
return info.PebBaseAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return 0 on error
|
||||
return 0
|
||||
}
|
||||
|
||||
func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte {
|
||||
if is32BitProcess {
|
||||
var read uint
|
||||
|
||||
buffer := make([]byte, size)
|
||||
|
||||
ret, _, _ := common.ProcNtReadVirtualMemory.Call(
|
||||
uintptr(h),
|
||||
uintptr(address),
|
||||
uintptr(unsafe.Pointer(&buffer[0])),
|
||||
uintptr(size),
|
||||
uintptr(unsafe.Pointer(&read)),
|
||||
)
|
||||
if int(ret) >= 0 && read > 0 {
|
||||
return buffer[:read]
|
||||
}
|
||||
} else {
|
||||
//reading a 64-bit process from a 32-bit one
|
||||
if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic
|
||||
var read uint64
|
||||
|
||||
buffer := make([]byte, size)
|
||||
|
||||
ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call(
|
||||
uintptr(h),
|
||||
uintptr(address & 0xFFFFFFFF), //the call expects a 64-bit value
|
||||
uintptr(address >> 32),
|
||||
uintptr(unsafe.Pointer(&buffer[0])),
|
||||
uintptr(size), //the call expects a 64-bit value
|
||||
uintptr(0), //but size is 32-bit so pass zero as the high dword
|
||||
uintptr(unsafe.Pointer(&read)),
|
||||
)
|
||||
if int(ret) >= 0 && read > 0 {
|
||||
return buffer[:uint(read)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if we reach here, an error happened
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
package process
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
)
|
||||
|
||||
type PROCESS_MEMORY_COUNTERS struct {
|
||||
CB uint32
|
||||
PageFaultCount uint32
|
||||
|
@ -14,3 +21,56 @@ type PROCESS_MEMORY_COUNTERS struct {
|
|||
PagefileUsage uint64
|
||||
PeakPagefileUsage uint64
|
||||
}
|
||||
|
||||
func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) uint64 {
|
||||
if is32BitProcess {
|
||||
//we are on a 64-bit process reading an external 32-bit process
|
||||
var wow64 uint
|
||||
|
||||
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(common.ProcessWow64Information),
|
||||
uintptr(unsafe.Pointer(&wow64)),
|
||||
uintptr(unsafe.Sizeof(wow64)),
|
||||
uintptr(0),
|
||||
)
|
||||
if int(ret) >= 0 {
|
||||
return uint64(wow64)
|
||||
}
|
||||
} else {
|
||||
//we are on a 64-bit process reading an external 64-bit process
|
||||
var info processBasicInformation64
|
||||
|
||||
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(common.ProcessBasicInformation),
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uintptr(unsafe.Sizeof(info)),
|
||||
uintptr(0),
|
||||
)
|
||||
if int(ret) >= 0 {
|
||||
return info.PebBaseAddress
|
||||
}
|
||||
}
|
||||
|
||||
//return 0 on error
|
||||
return 0
|
||||
}
|
||||
|
||||
func readProcessMemory(procHandle syscall.Handle, _ bool, address uint64, size uint) []byte {
|
||||
var read uint
|
||||
|
||||
buffer := make([]byte, size)
|
||||
|
||||
ret, _, _ := common.ProcNtReadVirtualMemory.Call(
|
||||
uintptr(procHandle),
|
||||
uintptr(address),
|
||||
uintptr(unsafe.Pointer(&buffer[0])),
|
||||
uintptr(size),
|
||||
uintptr(unsafe.Pointer(&read)),
|
||||
)
|
||||
if int(ret) >= 0 && read > 0 {
|
||||
return buffer[:read]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# This is the official list of 'w32' authors for copyright purposes.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization <email address>
|
||||
# The email address is not required for organizations.
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
# Contributors
|
||||
# ============
|
||||
|
||||
Allen Dang <allengnr@gmail.com>
|
||||
Benny Siegert <bsiegert@gmail.com>
|
||||
Bruno Bigras <bigras.bruno@gmail.com>
|
||||
Gerald Rosenberg <gerald.rosenberg@gmail.com>
|
||||
Michael Henke
|
|
@ -1,23 +0,0 @@
|
|||
Copyright (c) 2010-2012 The w32 Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,33 +0,0 @@
|
|||
About w32
|
||||
==========
|
||||
|
||||
w32 is a wrapper of windows apis for the Go Programming Language.
|
||||
|
||||
It wraps win32 apis to "Go style" to make them easier to use.
|
||||
|
||||
Setup
|
||||
=====
|
||||
|
||||
1. Make sure you have a working Go installation and build environment,
|
||||
see this go-nuts post for details:
|
||||
http://groups.google.com/group/golang-nuts/msg/5c87630a84f4fd0c
|
||||
|
||||
Updated versions of the Windows Go build are available here:
|
||||
http://code.google.com/p/gomingw/downloads/list
|
||||
|
||||
2. Create a "gopath" directory if you do not have one yet and set the
|
||||
GOPATH variable accordingly. For example:
|
||||
mkdir -p go-externals/src
|
||||
export GOPATH=${PWD}/go-externals
|
||||
|
||||
3. go get github.com/AllenDang/w32
|
||||
|
||||
4. go install github.com/AllenDang/w32...
|
||||
|
||||
Contribute
|
||||
==========
|
||||
|
||||
Contributions in form of design, code, documentation, bug reporting or other
|
||||
ways you see fit are very welcome.
|
||||
|
||||
Thank You!
|
|
@ -1,301 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
||||
|
||||
procRegCreateKeyEx = modadvapi32.NewProc("RegCreateKeyExW")
|
||||
procRegOpenKeyEx = modadvapi32.NewProc("RegOpenKeyExW")
|
||||
procRegCloseKey = modadvapi32.NewProc("RegCloseKey")
|
||||
procRegGetValue = modadvapi32.NewProc("RegGetValueW")
|
||||
procRegEnumKeyEx = modadvapi32.NewProc("RegEnumKeyExW")
|
||||
// procRegSetKeyValue = modadvapi32.NewProc("RegSetKeyValueW")
|
||||
procRegSetValueEx = modadvapi32.NewProc("RegSetValueExW")
|
||||
procOpenEventLog = modadvapi32.NewProc("OpenEventLogW")
|
||||
procReadEventLog = modadvapi32.NewProc("ReadEventLogW")
|
||||
procCloseEventLog = modadvapi32.NewProc("CloseEventLog")
|
||||
procOpenSCManager = modadvapi32.NewProc("OpenSCManagerW")
|
||||
procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle")
|
||||
procOpenService = modadvapi32.NewProc("OpenServiceW")
|
||||
procStartService = modadvapi32.NewProc("StartServiceW")
|
||||
procControlService = modadvapi32.NewProc("ControlService")
|
||||
)
|
||||
|
||||
func RegCreateKey(hKey HKEY, subKey string) HKEY {
|
||||
var result HKEY
|
||||
ret, _, _ := procRegCreateKeyEx.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(0),
|
||||
uintptr(0),
|
||||
uintptr(0),
|
||||
uintptr(KEY_ALL_ACCESS),
|
||||
uintptr(0),
|
||||
uintptr(unsafe.Pointer(&result)),
|
||||
uintptr(0))
|
||||
_ = ret
|
||||
return result
|
||||
}
|
||||
|
||||
func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY {
|
||||
var result HKEY
|
||||
ret, _, _ := procRegOpenKeyEx.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(0),
|
||||
uintptr(samDesired),
|
||||
uintptr(unsafe.Pointer(&result)))
|
||||
|
||||
if ret != ERROR_SUCCESS {
|
||||
panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func RegCloseKey(hKey HKEY) error {
|
||||
var err error
|
||||
ret, _, _ := procRegCloseKey.Call(
|
||||
uintptr(hKey))
|
||||
|
||||
if ret != ERROR_SUCCESS {
|
||||
err = errors.New("RegCloseKey failed")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func RegGetRaw(hKey HKEY, subKey string, value string) []byte {
|
||||
var bufLen uint32
|
||||
var valptr unsafe.Pointer
|
||||
if len(value) > 0 {
|
||||
valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value))
|
||||
}
|
||||
procRegGetValue.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(valptr),
|
||||
uintptr(RRF_RT_ANY),
|
||||
0,
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&bufLen)))
|
||||
|
||||
if bufLen == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
buf := make([]byte, bufLen)
|
||||
ret, _, _ := procRegGetValue.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(valptr),
|
||||
uintptr(RRF_RT_ANY),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(&bufLen)))
|
||||
|
||||
if ret != ERROR_SUCCESS {
|
||||
return nil
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) {
|
||||
var lptr, vptr unsafe.Pointer
|
||||
if len(subKey) > 0 {
|
||||
lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))
|
||||
}
|
||||
if len(value) > 0 {
|
||||
vptr = unsafe.Pointer(&value[0])
|
||||
}
|
||||
ret, _, _ := procRegSetValueEx.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(lptr),
|
||||
uintptr(0),
|
||||
uintptr(REG_BINARY),
|
||||
uintptr(vptr),
|
||||
uintptr(len(value)))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func RegGetString(hKey HKEY, subKey string, value string) string {
|
||||
var bufLen uint32
|
||||
procRegGetValue.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
|
||||
uintptr(RRF_RT_REG_SZ),
|
||||
0,
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&bufLen)))
|
||||
|
||||
if bufLen == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := make([]uint16, bufLen)
|
||||
ret, _, _ := procRegGetValue.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
|
||||
uintptr(RRF_RT_REG_SZ),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(&bufLen)))
|
||||
|
||||
if ret != ERROR_SUCCESS {
|
||||
return ""
|
||||
}
|
||||
|
||||
return syscall.UTF16ToString(buf)
|
||||
}
|
||||
|
||||
/*
|
||||
func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) {
|
||||
ret, _, _ := procRegSetKeyValue.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))),
|
||||
uintptr(dwType),
|
||||
data,
|
||||
uintptr(cbData))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
*/
|
||||
|
||||
func RegEnumKeyEx(hKey HKEY, index uint32) string {
|
||||
var bufLen uint32 = 255
|
||||
buf := make([]uint16, bufLen)
|
||||
procRegEnumKeyEx.Call(
|
||||
uintptr(hKey),
|
||||
uintptr(index),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(&bufLen)),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
return syscall.UTF16ToString(buf)
|
||||
}
|
||||
|
||||
func OpenEventLog(servername string, sourcename string) HANDLE {
|
||||
ret, _, _ := procOpenEventLog.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename))))
|
||||
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool {
|
||||
ret, _, _ := procReadEventLog.Call(
|
||||
uintptr(eventlog),
|
||||
uintptr(readflags),
|
||||
uintptr(recordoffset),
|
||||
uintptr(unsafe.Pointer(&buffer[0])),
|
||||
uintptr(numberofbytestoread),
|
||||
uintptr(unsafe.Pointer(bytesread)),
|
||||
uintptr(unsafe.Pointer(minnumberofbytesneeded)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CloseEventLog(eventlog HANDLE) bool {
|
||||
ret, _, _ := procCloseEventLog.Call(
|
||||
uintptr(eventlog))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) {
|
||||
var p1, p2 uintptr
|
||||
if len(lpMachineName) > 0 {
|
||||
p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName)))
|
||||
}
|
||||
if len(lpDatabaseName) > 0 {
|
||||
p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName)))
|
||||
}
|
||||
ret, _, _ := procOpenSCManager.Call(
|
||||
p1,
|
||||
p2,
|
||||
uintptr(dwDesiredAccess))
|
||||
|
||||
if ret == 0 {
|
||||
return 0, syscall.GetLastError()
|
||||
}
|
||||
|
||||
return HANDLE(ret), nil
|
||||
}
|
||||
|
||||
func CloseServiceHandle(hSCObject HANDLE) error {
|
||||
ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject))
|
||||
if ret == 0 {
|
||||
return syscall.GetLastError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) {
|
||||
ret, _, _ := procOpenService.Call(
|
||||
uintptr(hSCManager),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))),
|
||||
uintptr(dwDesiredAccess))
|
||||
|
||||
if ret == 0 {
|
||||
return 0, syscall.GetLastError()
|
||||
}
|
||||
|
||||
return HANDLE(ret), nil
|
||||
}
|
||||
|
||||
func StartService(hService HANDLE, lpServiceArgVectors []string) error {
|
||||
l := len(lpServiceArgVectors)
|
||||
var ret uintptr
|
||||
if l == 0 {
|
||||
ret, _, _ = procStartService.Call(
|
||||
uintptr(hService),
|
||||
0,
|
||||
0)
|
||||
} else {
|
||||
lpArgs := make([]uintptr, l)
|
||||
for i := 0; i < l; i++ {
|
||||
lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i])))
|
||||
}
|
||||
|
||||
ret, _, _ = procStartService.Call(
|
||||
uintptr(hService),
|
||||
uintptr(l),
|
||||
uintptr(unsafe.Pointer(&lpArgs[0])))
|
||||
}
|
||||
|
||||
if ret == 0 {
|
||||
return syscall.GetLastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool {
|
||||
if lpServiceStatus == nil {
|
||||
panic("ControlService:lpServiceStatus cannot be nil")
|
||||
}
|
||||
|
||||
ret, _, _ := procControlService.Call(
|
||||
uintptr(hService),
|
||||
uintptr(dwControl),
|
||||
uintptr(unsafe.Pointer(lpServiceStatus)))
|
||||
|
||||
return ret != 0
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modcomctl32 = syscall.NewLazyDLL("comctl32.dll")
|
||||
|
||||
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
|
||||
procImageList_Create = modcomctl32.NewProc("ImageList_Create")
|
||||
procImageList_Destroy = modcomctl32.NewProc("ImageList_Destroy")
|
||||
procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount")
|
||||
procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount")
|
||||
procImageList_Add = modcomctl32.NewProc("ImageList_Add")
|
||||
procImageList_ReplaceIcon = modcomctl32.NewProc("ImageList_ReplaceIcon")
|
||||
procImageList_Remove = modcomctl32.NewProc("ImageList_Remove")
|
||||
procTrackMouseEvent = modcomctl32.NewProc("_TrackMouseEvent")
|
||||
)
|
||||
|
||||
func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool {
|
||||
ret, _, _ := procInitCommonControlsEx.Call(
|
||||
uintptr(unsafe.Pointer(lpInitCtrls)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST {
|
||||
ret, _, _ := procImageList_Create.Call(
|
||||
uintptr(cx),
|
||||
uintptr(cy),
|
||||
uintptr(flags),
|
||||
uintptr(cInitial),
|
||||
uintptr(cGrow))
|
||||
|
||||
if ret == 0 {
|
||||
panic("Create image list failed")
|
||||
}
|
||||
|
||||
return HIMAGELIST(ret)
|
||||
}
|
||||
|
||||
func ImageList_Destroy(himl HIMAGELIST) bool {
|
||||
ret, _, _ := procImageList_Destroy.Call(
|
||||
uintptr(himl))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ImageList_GetImageCount(himl HIMAGELIST) int {
|
||||
ret, _, _ := procImageList_GetImageCount.Call(
|
||||
uintptr(himl))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool {
|
||||
ret, _, _ := procImageList_SetImageCount.Call(
|
||||
uintptr(himl),
|
||||
uintptr(uNewCount))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int {
|
||||
ret, _, _ := procImageList_Add.Call(
|
||||
uintptr(himl),
|
||||
uintptr(hbmImage),
|
||||
uintptr(hbmMask))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int {
|
||||
ret, _, _ := procImageList_ReplaceIcon.Call(
|
||||
uintptr(himl),
|
||||
uintptr(i),
|
||||
uintptr(hicon))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int {
|
||||
return ImageList_ReplaceIcon(himl, -1, hicon)
|
||||
}
|
||||
|
||||
func ImageList_Remove(himl HIMAGELIST, i int) bool {
|
||||
ret, _, _ := procImageList_Remove.Call(
|
||||
uintptr(himl),
|
||||
uintptr(i))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ImageList_RemoveAll(himl HIMAGELIST) bool {
|
||||
return ImageList_Remove(himl, -1)
|
||||
}
|
||||
|
||||
func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool {
|
||||
ret, _, _ := procTrackMouseEvent.Call(
|
||||
uintptr(unsafe.Pointer(tme)))
|
||||
|
||||
return ret != 0
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll")
|
||||
|
||||
procGetSaveFileName = modcomdlg32.NewProc("GetSaveFileNameW")
|
||||
procGetOpenFileName = modcomdlg32.NewProc("GetOpenFileNameW")
|
||||
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
|
||||
)
|
||||
|
||||
func GetOpenFileName(ofn *OPENFILENAME) bool {
|
||||
ret, _, _ := procGetOpenFileName.Call(
|
||||
uintptr(unsafe.Pointer(ofn)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetSaveFileName(ofn *OPENFILENAME) bool {
|
||||
ret, _, _ := procGetSaveFileName.Call(
|
||||
uintptr(unsafe.Pointer(ofn)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CommDlgExtendedError() uint {
|
||||
ret, _, _ := procCommDlgExtendedError.Call()
|
||||
|
||||
return uint(ret)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,256 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// DEFINED IN THE DWM API BUT NOT IMPLEMENTED BY MS:
|
||||
// DwmAttachMilContent
|
||||
// DwmDetachMilContent
|
||||
// DwmEnableComposition
|
||||
// DwmGetGraphicsStreamClient
|
||||
// DwmGetGraphicsStreamTransformHint
|
||||
|
||||
var (
|
||||
moddwmapi = syscall.NewLazyDLL("dwmapi.dll")
|
||||
|
||||
procDwmDefWindowProc = moddwmapi.NewProc("DwmDefWindowProc")
|
||||
procDwmEnableBlurBehindWindow = moddwmapi.NewProc("DwmEnableBlurBehindWindow")
|
||||
procDwmEnableMMCSS = moddwmapi.NewProc("DwmEnableMMCSS")
|
||||
procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea")
|
||||
procDwmFlush = moddwmapi.NewProc("DwmFlush")
|
||||
procDwmGetColorizationColor = moddwmapi.NewProc("DwmGetColorizationColor")
|
||||
procDwmGetCompositionTimingInfo = moddwmapi.NewProc("DwmGetCompositionTimingInfo")
|
||||
procDwmGetTransportAttributes = moddwmapi.NewProc("DwmGetTransportAttributes")
|
||||
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
|
||||
procDwmInvalidateIconicBitmaps = moddwmapi.NewProc("DwmInvalidateIconicBitmaps")
|
||||
procDwmIsCompositionEnabled = moddwmapi.NewProc("DwmIsCompositionEnabled")
|
||||
procDwmModifyPreviousDxFrameDuration = moddwmapi.NewProc("DwmModifyPreviousDxFrameDuration")
|
||||
procDwmQueryThumbnailSourceSize = moddwmapi.NewProc("DwmQueryThumbnailSourceSize")
|
||||
procDwmRegisterThumbnail = moddwmapi.NewProc("DwmRegisterThumbnail")
|
||||
procDwmRenderGesture = moddwmapi.NewProc("DwmRenderGesture")
|
||||
procDwmSetDxFrameDuration = moddwmapi.NewProc("DwmSetDxFrameDuration")
|
||||
procDwmSetIconicLivePreviewBitmap = moddwmapi.NewProc("DwmSetIconicLivePreviewBitmap")
|
||||
procDwmSetIconicThumbnail = moddwmapi.NewProc("DwmSetIconicThumbnail")
|
||||
procDwmSetPresentParameters = moddwmapi.NewProc("DwmSetPresentParameters")
|
||||
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
|
||||
procDwmShowContact = moddwmapi.NewProc("DwmShowContact")
|
||||
procDwmTetherContact = moddwmapi.NewProc("DwmTetherContact")
|
||||
procDwmTransitionOwnedWindow = moddwmapi.NewProc("DwmTransitionOwnedWindow")
|
||||
procDwmUnregisterThumbnail = moddwmapi.NewProc("DwmUnregisterThumbnail")
|
||||
procDwmUpdateThumbnailProperties = moddwmapi.NewProc("DwmUpdateThumbnailProperties")
|
||||
)
|
||||
|
||||
func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) {
|
||||
var result uint
|
||||
ret, _, _ := procDwmDefWindowProc.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam,
|
||||
uintptr(unsafe.Pointer(&result)))
|
||||
return ret != 0, result
|
||||
}
|
||||
|
||||
func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT {
|
||||
ret, _, _ := procDwmEnableBlurBehindWindow.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(unsafe.Pointer(pBlurBehind)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT {
|
||||
ret, _, _ := procDwmEnableMMCSS.Call(
|
||||
uintptr(BoolToBOOL(fEnableMMCSS)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT {
|
||||
ret, _, _ := procDwmExtendFrameIntoClientArea.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(unsafe.Pointer(pMarInset)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmFlush() HRESULT {
|
||||
ret, _, _ := procDwmFlush.Call()
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT {
|
||||
ret, _, _ := procDwmGetColorizationColor.Call(
|
||||
uintptr(unsafe.Pointer(pcrColorization)),
|
||||
uintptr(unsafe.Pointer(pfOpaqueBlend)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT {
|
||||
ret, _, _ := procDwmGetCompositionTimingInfo.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(unsafe.Pointer(pTimingInfo)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT {
|
||||
ret, _, _ := procDwmGetTransportAttributes.Call(
|
||||
uintptr(unsafe.Pointer(pfIsRemoting)),
|
||||
uintptr(unsafe.Pointer(pfIsConnected)),
|
||||
uintptr(unsafe.Pointer(pDwGeneration)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
// TODO: verify handling of variable arguments
|
||||
func DwmGetWindowAttribute(hWnd HWND, dwAttribute uint32) (pAttribute interface{}, result HRESULT) {
|
||||
var pvAttribute, pvAttrSize uintptr
|
||||
switch dwAttribute {
|
||||
case DWMWA_NCRENDERING_ENABLED:
|
||||
v := new(BOOL)
|
||||
pAttribute = v
|
||||
pvAttribute = uintptr(unsafe.Pointer(v))
|
||||
pvAttrSize = unsafe.Sizeof(*v)
|
||||
case DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_EXTENDED_FRAME_BOUNDS:
|
||||
v := new(RECT)
|
||||
pAttribute = v
|
||||
pvAttribute = uintptr(unsafe.Pointer(v))
|
||||
pvAttrSize = unsafe.Sizeof(*v)
|
||||
case DWMWA_CLOAKED:
|
||||
panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not currently supported.", dwAttribute))
|
||||
default:
|
||||
panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not valid.", dwAttribute))
|
||||
}
|
||||
|
||||
ret, _, _ := procDwmGetWindowAttribute.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(dwAttribute),
|
||||
pvAttribute,
|
||||
pvAttrSize)
|
||||
result = HRESULT(ret)
|
||||
return
|
||||
}
|
||||
|
||||
func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT {
|
||||
ret, _, _ := procDwmInvalidateIconicBitmaps.Call(
|
||||
uintptr(hWnd))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT {
|
||||
ret, _, _ := procDwmIsCompositionEnabled.Call(
|
||||
uintptr(unsafe.Pointer(pfEnabled)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT {
|
||||
ret, _, _ := procDwmModifyPreviousDxFrameDuration.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(cRefreshes),
|
||||
uintptr(BoolToBOOL(fRelative)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT {
|
||||
ret, _, _ := procDwmQueryThumbnailSourceSize.Call(
|
||||
uintptr(hThumbnail),
|
||||
uintptr(unsafe.Pointer(pSize)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT {
|
||||
ret, _, _ := procDwmRegisterThumbnail.Call(
|
||||
uintptr(hWndDestination),
|
||||
uintptr(hWndSource),
|
||||
uintptr(unsafe.Pointer(phThumbnailId)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) {
|
||||
procDwmRenderGesture.Call(
|
||||
uintptr(gt),
|
||||
uintptr(cContacts),
|
||||
uintptr(unsafe.Pointer(pdwPointerID)),
|
||||
uintptr(unsafe.Pointer(pPoints)))
|
||||
return
|
||||
}
|
||||
|
||||
func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT {
|
||||
ret, _, _ := procDwmSetDxFrameDuration.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(cRefreshes))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT {
|
||||
ret, _, _ := procDwmSetIconicLivePreviewBitmap.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(hbmp),
|
||||
uintptr(unsafe.Pointer(pptClient)),
|
||||
uintptr(dwSITFlags))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT {
|
||||
ret, _, _ := procDwmSetIconicThumbnail.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(hbmp),
|
||||
uintptr(dwSITFlags))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT {
|
||||
ret, _, _ := procDwmSetPresentParameters.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(unsafe.Pointer(pPresentParams)))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT {
|
||||
ret, _, _ := procDwmSetWindowAttribute.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(dwAttribute),
|
||||
uintptr(pvAttribute),
|
||||
uintptr(cbAttribute))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) {
|
||||
procDwmShowContact.Call(
|
||||
uintptr(dwPointerID),
|
||||
uintptr(eShowContact))
|
||||
return
|
||||
}
|
||||
|
||||
func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) {
|
||||
procDwmTetherContact.Call(
|
||||
uintptr(dwPointerID),
|
||||
uintptr(BoolToBOOL(fEnable)),
|
||||
uintptr(unsafe.Pointer(&ptTether)))
|
||||
return
|
||||
}
|
||||
|
||||
func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) {
|
||||
procDwmTransitionOwnedWindow.Call(
|
||||
uintptr(hWnd),
|
||||
uintptr(target))
|
||||
return
|
||||
}
|
||||
|
||||
func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT {
|
||||
ret, _, _ := procDwmUnregisterThumbnail.Call(
|
||||
uintptr(hThumbnailId))
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT {
|
||||
ret, _, _ := procDwmUpdateThumbnailProperties.Call(
|
||||
uintptr(hThumbnailId),
|
||||
uintptr(unsafe.Pointer(ptnProperties)))
|
||||
return HRESULT(ret)
|
||||
}
|
|
@ -1,511 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modgdi32 = syscall.NewLazyDLL("gdi32.dll")
|
||||
|
||||
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
|
||||
procDeleteObject = modgdi32.NewProc("DeleteObject")
|
||||
procCreateFontIndirect = modgdi32.NewProc("CreateFontIndirectW")
|
||||
procAbortDoc = modgdi32.NewProc("AbortDoc")
|
||||
procBitBlt = modgdi32.NewProc("BitBlt")
|
||||
procCloseEnhMetaFile = modgdi32.NewProc("CloseEnhMetaFile")
|
||||
procCopyEnhMetaFile = modgdi32.NewProc("CopyEnhMetaFileW")
|
||||
procCreateBrushIndirect = modgdi32.NewProc("CreateBrushIndirect")
|
||||
procCreateCompatibleDC = modgdi32.NewProc("CreateCompatibleDC")
|
||||
procCreateDC = modgdi32.NewProc("CreateDCW")
|
||||
procCreateDIBSection = modgdi32.NewProc("CreateDIBSection")
|
||||
procCreateEnhMetaFile = modgdi32.NewProc("CreateEnhMetaFileW")
|
||||
procCreateIC = modgdi32.NewProc("CreateICW")
|
||||
procDeleteDC = modgdi32.NewProc("DeleteDC")
|
||||
procDeleteEnhMetaFile = modgdi32.NewProc("DeleteEnhMetaFile")
|
||||
procEllipse = modgdi32.NewProc("Ellipse")
|
||||
procEndDoc = modgdi32.NewProc("EndDoc")
|
||||
procEndPage = modgdi32.NewProc("EndPage")
|
||||
procExtCreatePen = modgdi32.NewProc("ExtCreatePen")
|
||||
procGetEnhMetaFile = modgdi32.NewProc("GetEnhMetaFileW")
|
||||
procGetEnhMetaFileHeader = modgdi32.NewProc("GetEnhMetaFileHeader")
|
||||
procGetObject = modgdi32.NewProc("GetObjectW")
|
||||
procGetStockObject = modgdi32.NewProc("GetStockObject")
|
||||
procGetTextExtentExPoint = modgdi32.NewProc("GetTextExtentExPointW")
|
||||
procGetTextExtentPoint32 = modgdi32.NewProc("GetTextExtentPoint32W")
|
||||
procGetTextMetrics = modgdi32.NewProc("GetTextMetricsW")
|
||||
procLineTo = modgdi32.NewProc("LineTo")
|
||||
procMoveToEx = modgdi32.NewProc("MoveToEx")
|
||||
procPlayEnhMetaFile = modgdi32.NewProc("PlayEnhMetaFile")
|
||||
procRectangle = modgdi32.NewProc("Rectangle")
|
||||
procResetDC = modgdi32.NewProc("ResetDCW")
|
||||
procSelectObject = modgdi32.NewProc("SelectObject")
|
||||
procSetBkMode = modgdi32.NewProc("SetBkMode")
|
||||
procSetBrushOrgEx = modgdi32.NewProc("SetBrushOrgEx")
|
||||
procSetStretchBltMode = modgdi32.NewProc("SetStretchBltMode")
|
||||
procSetTextColor = modgdi32.NewProc("SetTextColor")
|
||||
procSetBkColor = modgdi32.NewProc("SetBkColor")
|
||||
procStartDoc = modgdi32.NewProc("StartDocW")
|
||||
procStartPage = modgdi32.NewProc("StartPage")
|
||||
procStretchBlt = modgdi32.NewProc("StretchBlt")
|
||||
procSetDIBitsToDevice = modgdi32.NewProc("SetDIBitsToDevice")
|
||||
procChoosePixelFormat = modgdi32.NewProc("ChoosePixelFormat")
|
||||
procDescribePixelFormat = modgdi32.NewProc("DescribePixelFormat")
|
||||
procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat")
|
||||
procGetPixelFormat = modgdi32.NewProc("GetPixelFormat")
|
||||
procSetPixelFormat = modgdi32.NewProc("SetPixelFormat")
|
||||
procSwapBuffers = modgdi32.NewProc("SwapBuffers")
|
||||
)
|
||||
|
||||
func GetDeviceCaps(hdc HDC, index int) int {
|
||||
ret, _, _ := procGetDeviceCaps.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(index))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func DeleteObject(hObject HGDIOBJ) bool {
|
||||
ret, _, _ := procDeleteObject.Call(
|
||||
uintptr(hObject))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CreateFontIndirect(logFont *LOGFONT) HFONT {
|
||||
ret, _, _ := procCreateFontIndirect.Call(
|
||||
uintptr(unsafe.Pointer(logFont)))
|
||||
|
||||
return HFONT(ret)
|
||||
}
|
||||
|
||||
func AbortDoc(hdc HDC) int {
|
||||
ret, _, _ := procAbortDoc.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) {
|
||||
ret, _, _ := procBitBlt.Call(
|
||||
uintptr(hdcDest),
|
||||
uintptr(nXDest),
|
||||
uintptr(nYDest),
|
||||
uintptr(nWidth),
|
||||
uintptr(nHeight),
|
||||
uintptr(hdcSrc),
|
||||
uintptr(nXSrc),
|
||||
uintptr(nYSrc),
|
||||
uintptr(dwRop))
|
||||
|
||||
if ret == 0 {
|
||||
panic("BitBlt failed")
|
||||
}
|
||||
}
|
||||
|
||||
func CloseEnhMetaFile(hdc HDC) HENHMETAFILE {
|
||||
ret, _, _ := procCloseEnhMetaFile.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return HENHMETAFILE(ret)
|
||||
}
|
||||
|
||||
func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE {
|
||||
ret, _, _ := procCopyEnhMetaFile.Call(
|
||||
uintptr(hemfSrc),
|
||||
uintptr(unsafe.Pointer(lpszFile)))
|
||||
|
||||
return HENHMETAFILE(ret)
|
||||
}
|
||||
|
||||
func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH {
|
||||
ret, _, _ := procCreateBrushIndirect.Call(
|
||||
uintptr(unsafe.Pointer(lplb)))
|
||||
|
||||
return HBRUSH(ret)
|
||||
}
|
||||
|
||||
func CreateCompatibleDC(hdc HDC) HDC {
|
||||
ret, _, _ := procCreateCompatibleDC.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
if ret == 0 {
|
||||
panic("Create compatible DC failed")
|
||||
}
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC {
|
||||
ret, _, _ := procCreateDC.Call(
|
||||
uintptr(unsafe.Pointer(lpszDriver)),
|
||||
uintptr(unsafe.Pointer(lpszDevice)),
|
||||
uintptr(unsafe.Pointer(lpszOutput)),
|
||||
uintptr(unsafe.Pointer(lpInitData)))
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP {
|
||||
ret, _, _ := procCreateDIBSection.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(pbmi)),
|
||||
uintptr(iUsage),
|
||||
uintptr(unsafe.Pointer(ppvBits)),
|
||||
uintptr(hSection),
|
||||
uintptr(dwOffset))
|
||||
|
||||
return HBITMAP(ret)
|
||||
}
|
||||
|
||||
func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC {
|
||||
ret, _, _ := procCreateEnhMetaFile.Call(
|
||||
uintptr(hdcRef),
|
||||
uintptr(unsafe.Pointer(lpFilename)),
|
||||
uintptr(unsafe.Pointer(lpRect)),
|
||||
uintptr(unsafe.Pointer(lpDescription)))
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC {
|
||||
ret, _, _ := procCreateIC.Call(
|
||||
uintptr(unsafe.Pointer(lpszDriver)),
|
||||
uintptr(unsafe.Pointer(lpszDevice)),
|
||||
uintptr(unsafe.Pointer(lpszOutput)),
|
||||
uintptr(unsafe.Pointer(lpdvmInit)))
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func DeleteDC(hdc HDC) bool {
|
||||
ret, _, _ := procDeleteDC.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func DeleteEnhMetaFile(hemf HENHMETAFILE) bool {
|
||||
ret, _, _ := procDeleteEnhMetaFile.Call(
|
||||
uintptr(hemf))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
|
||||
ret, _, _ := procEllipse.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(nLeftRect),
|
||||
uintptr(nTopRect),
|
||||
uintptr(nRightRect),
|
||||
uintptr(nBottomRect))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EndDoc(hdc HDC) int {
|
||||
ret, _, _ := procEndDoc.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func EndPage(hdc HDC) int {
|
||||
ret, _, _ := procEndPage.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN {
|
||||
ret, _, _ := procExtCreatePen.Call(
|
||||
uintptr(dwPenStyle),
|
||||
uintptr(dwWidth),
|
||||
uintptr(unsafe.Pointer(lplb)),
|
||||
uintptr(dwStyleCount),
|
||||
uintptr(unsafe.Pointer(lpStyle)))
|
||||
|
||||
return HPEN(ret)
|
||||
}
|
||||
|
||||
func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE {
|
||||
ret, _, _ := procGetEnhMetaFile.Call(
|
||||
uintptr(unsafe.Pointer(lpszMetaFile)))
|
||||
|
||||
return HENHMETAFILE(ret)
|
||||
}
|
||||
|
||||
func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint {
|
||||
ret, _, _ := procGetEnhMetaFileHeader.Call(
|
||||
uintptr(hemf),
|
||||
uintptr(cbBuffer),
|
||||
uintptr(unsafe.Pointer(lpemh)))
|
||||
|
||||
return uint(ret)
|
||||
}
|
||||
|
||||
func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int {
|
||||
ret, _, _ := procGetObject.Call(
|
||||
uintptr(hgdiobj),
|
||||
uintptr(cbBuffer),
|
||||
uintptr(lpvObject))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetStockObject(fnObject int) HGDIOBJ {
|
||||
ret, _, _ := procGetDeviceCaps.Call(
|
||||
uintptr(fnObject))
|
||||
|
||||
return HGDIOBJ(ret)
|
||||
}
|
||||
|
||||
func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool {
|
||||
ret, _, _ := procGetTextExtentExPoint.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(lpszStr)),
|
||||
uintptr(cchString),
|
||||
uintptr(nMaxExtent),
|
||||
uintptr(unsafe.Pointer(lpnFit)),
|
||||
uintptr(unsafe.Pointer(alpDx)),
|
||||
uintptr(unsafe.Pointer(lpSize)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool {
|
||||
ret, _, _ := procGetTextExtentPoint32.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(lpString)),
|
||||
uintptr(c),
|
||||
uintptr(unsafe.Pointer(lpSize)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool {
|
||||
ret, _, _ := procGetTextMetrics.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(lptm)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func LineTo(hdc HDC, nXEnd, nYEnd int) bool {
|
||||
ret, _, _ := procLineTo.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(nXEnd),
|
||||
uintptr(nYEnd))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool {
|
||||
ret, _, _ := procMoveToEx.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(unsafe.Pointer(lpPoint)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool {
|
||||
ret, _, _ := procPlayEnhMetaFile.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(hemf),
|
||||
uintptr(unsafe.Pointer(lpRect)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
|
||||
ret, _, _ := procRectangle.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(nLeftRect),
|
||||
uintptr(nTopRect),
|
||||
uintptr(nRightRect),
|
||||
uintptr(nBottomRect))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC {
|
||||
ret, _, _ := procResetDC.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(lpInitData)))
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ {
|
||||
ret, _, _ := procSelectObject.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(hgdiobj))
|
||||
|
||||
if ret == 0 {
|
||||
panic("SelectObject failed")
|
||||
}
|
||||
|
||||
return HGDIOBJ(ret)
|
||||
}
|
||||
|
||||
func SetBkMode(hdc HDC, iBkMode int) int {
|
||||
ret, _, _ := procSetBkMode.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(iBkMode))
|
||||
|
||||
if ret == 0 {
|
||||
panic("SetBkMode failed")
|
||||
}
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool {
|
||||
ret, _, _ := procSetBrushOrgEx.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(nXOrg),
|
||||
uintptr(nYOrg),
|
||||
uintptr(unsafe.Pointer(lppt)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetStretchBltMode(hdc HDC, iStretchMode int) int {
|
||||
ret, _, _ := procSetStretchBltMode.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(iStretchMode))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func SetTextColor(hdc HDC, crColor COLORREF) COLORREF {
|
||||
ret, _, _ := procSetTextColor.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(crColor))
|
||||
|
||||
if ret == CLR_INVALID {
|
||||
panic("SetTextColor failed")
|
||||
}
|
||||
|
||||
return COLORREF(ret)
|
||||
}
|
||||
|
||||
func SetBkColor(hdc HDC, crColor COLORREF) COLORREF {
|
||||
ret, _, _ := procSetBkColor.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(crColor))
|
||||
|
||||
if ret == CLR_INVALID {
|
||||
panic("SetBkColor failed")
|
||||
}
|
||||
|
||||
return COLORREF(ret)
|
||||
}
|
||||
|
||||
func StartDoc(hdc HDC, lpdi *DOCINFO) int {
|
||||
ret, _, _ := procStartDoc.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(lpdi)))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func StartPage(hdc HDC) int {
|
||||
ret, _, _ := procStartPage.Call(
|
||||
uintptr(hdc))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) {
|
||||
ret, _, _ := procStretchBlt.Call(
|
||||
uintptr(hdcDest),
|
||||
uintptr(nXOriginDest),
|
||||
uintptr(nYOriginDest),
|
||||
uintptr(nWidthDest),
|
||||
uintptr(nHeightDest),
|
||||
uintptr(hdcSrc),
|
||||
uintptr(nXOriginSrc),
|
||||
uintptr(nYOriginSrc),
|
||||
uintptr(nWidthSrc),
|
||||
uintptr(nHeightSrc),
|
||||
uintptr(dwRop))
|
||||
|
||||
if ret == 0 {
|
||||
panic("StretchBlt failed")
|
||||
}
|
||||
}
|
||||
|
||||
func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int {
|
||||
ret, _, _ := procSetDIBitsToDevice.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(xDest),
|
||||
uintptr(yDest),
|
||||
uintptr(dwWidth),
|
||||
uintptr(dwHeight),
|
||||
uintptr(xSrc),
|
||||
uintptr(ySrc),
|
||||
uintptr(uStartScan),
|
||||
uintptr(cScanLines),
|
||||
uintptr(unsafe.Pointer(&lpvBits[0])),
|
||||
uintptr(unsafe.Pointer(lpbmi)),
|
||||
uintptr(fuColorUse))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int {
|
||||
ret, _, _ := procChoosePixelFormat.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(pfd)),
|
||||
)
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int {
|
||||
ret, _, _ := procDescribePixelFormat.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(iPixelFormat),
|
||||
uintptr(nBytes),
|
||||
uintptr(unsafe.Pointer(pfd)),
|
||||
)
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint {
|
||||
ret, _, _ := procGetEnhMetaFilePixelFormat.Call(
|
||||
uintptr(hemf),
|
||||
uintptr(cbBuffer),
|
||||
uintptr(unsafe.Pointer(pfd)),
|
||||
)
|
||||
return uint(ret)
|
||||
}
|
||||
|
||||
func GetPixelFormat(hdc HDC) int {
|
||||
ret, _, _ := procGetPixelFormat.Call(
|
||||
uintptr(hdc),
|
||||
)
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool {
|
||||
ret, _, _ := procSetPixelFormat.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(iPixelFormat),
|
||||
uintptr(unsafe.Pointer(pfd)),
|
||||
)
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func SwapBuffers(hdc HDC) bool {
|
||||
ret, _, _ := procSwapBuffers.Call(uintptr(hdc))
|
||||
return ret == TRUE
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
Ok = 0
|
||||
GenericError = 1
|
||||
InvalidParameter = 2
|
||||
OutOfMemory = 3
|
||||
ObjectBusy = 4
|
||||
InsufficientBuffer = 5
|
||||
NotImplemented = 6
|
||||
Win32Error = 7
|
||||
WrongState = 8
|
||||
Aborted = 9
|
||||
FileNotFound = 10
|
||||
ValueOverflow = 11
|
||||
AccessDenied = 12
|
||||
UnknownImageFormat = 13
|
||||
FontFamilyNotFound = 14
|
||||
FontStyleNotFound = 15
|
||||
NotTrueTypeFont = 16
|
||||
UnsupportedGdiplusVersion = 17
|
||||
GdiplusNotInitialized = 18
|
||||
PropertyNotFound = 19
|
||||
PropertyNotSupported = 20
|
||||
ProfileNotFound = 21
|
||||
)
|
||||
|
||||
func GetGpStatus(s int32) string {
|
||||
switch s {
|
||||
case Ok:
|
||||
return "Ok"
|
||||
case GenericError:
|
||||
return "GenericError"
|
||||
case InvalidParameter:
|
||||
return "InvalidParameter"
|
||||
case OutOfMemory:
|
||||
return "OutOfMemory"
|
||||
case ObjectBusy:
|
||||
return "ObjectBusy"
|
||||
case InsufficientBuffer:
|
||||
return "InsufficientBuffer"
|
||||
case NotImplemented:
|
||||
return "NotImplemented"
|
||||
case Win32Error:
|
||||
return "Win32Error"
|
||||
case WrongState:
|
||||
return "WrongState"
|
||||
case Aborted:
|
||||
return "Aborted"
|
||||
case FileNotFound:
|
||||
return "FileNotFound"
|
||||
case ValueOverflow:
|
||||
return "ValueOverflow"
|
||||
case AccessDenied:
|
||||
return "AccessDenied"
|
||||
case UnknownImageFormat:
|
||||
return "UnknownImageFormat"
|
||||
case FontFamilyNotFound:
|
||||
return "FontFamilyNotFound"
|
||||
case FontStyleNotFound:
|
||||
return "FontStyleNotFound"
|
||||
case NotTrueTypeFont:
|
||||
return "NotTrueTypeFont"
|
||||
case UnsupportedGdiplusVersion:
|
||||
return "UnsupportedGdiplusVersion"
|
||||
case GdiplusNotInitialized:
|
||||
return "GdiplusNotInitialized"
|
||||
case PropertyNotFound:
|
||||
return "PropertyNotFound"
|
||||
case PropertyNotSupported:
|
||||
return "PropertyNotSupported"
|
||||
case ProfileNotFound:
|
||||
return "ProfileNotFound"
|
||||
}
|
||||
return "Unknown Status Value"
|
||||
}
|
||||
|
||||
var (
|
||||
token uintptr
|
||||
|
||||
modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
|
||||
|
||||
procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile")
|
||||
procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
|
||||
procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
|
||||
procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
|
||||
procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream")
|
||||
procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage")
|
||||
procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown")
|
||||
procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup")
|
||||
)
|
||||
|
||||
func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
|
||||
var bitmap *uintptr
|
||||
ret, _, _ := procGdipCreateBitmapFromFile.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
|
||||
uintptr(unsafe.Pointer(&bitmap)))
|
||||
|
||||
if ret != Ok {
|
||||
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
|
||||
}
|
||||
|
||||
return bitmap, nil
|
||||
}
|
||||
|
||||
func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
|
||||
var bitmap *uintptr
|
||||
ret, _, _ := procGdipCreateBitmapFromResource.Call(
|
||||
uintptr(instance),
|
||||
uintptr(unsafe.Pointer(resId)),
|
||||
uintptr(unsafe.Pointer(&bitmap)))
|
||||
|
||||
if ret != Ok {
|
||||
return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
|
||||
}
|
||||
|
||||
return bitmap, nil
|
||||
}
|
||||
|
||||
func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
|
||||
var bitmap *uintptr
|
||||
ret, _, _ := procGdipCreateBitmapFromStream.Call(
|
||||
uintptr(unsafe.Pointer(stream)),
|
||||
uintptr(unsafe.Pointer(&bitmap)))
|
||||
|
||||
if ret != Ok {
|
||||
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
|
||||
}
|
||||
|
||||
return bitmap, nil
|
||||
}
|
||||
|
||||
func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
|
||||
var hbitmap HBITMAP
|
||||
ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
|
||||
uintptr(unsafe.Pointer(bitmap)),
|
||||
uintptr(unsafe.Pointer(&hbitmap)),
|
||||
uintptr(background))
|
||||
|
||||
if ret != Ok {
|
||||
return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
|
||||
}
|
||||
|
||||
return hbitmap, nil
|
||||
}
|
||||
|
||||
func GdipDisposeImage(image *uintptr) {
|
||||
procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
|
||||
}
|
||||
|
||||
func GdiplusShutdown() {
|
||||
procGdiplusShutdown.Call(token)
|
||||
}
|
||||
|
||||
func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
|
||||
ret, _, _ := procGdiplusStartup.Call(
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
uintptr(unsafe.Pointer(input)),
|
||||
uintptr(unsafe.Pointer(output)))
|
||||
|
||||
if ret != Ok {
|
||||
panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type pIDispatchVtbl struct {
|
||||
pQueryInterface uintptr
|
||||
pAddRef uintptr
|
||||
pRelease uintptr
|
||||
pGetTypeInfoCount uintptr
|
||||
pGetTypeInfo uintptr
|
||||
pGetIDsOfNames uintptr
|
||||
pInvoke uintptr
|
||||
}
|
||||
|
||||
type IDispatch struct {
|
||||
lpVtbl *pIDispatchVtbl
|
||||
}
|
||||
|
||||
func (this *IDispatch) QueryInterface(id *GUID) *IDispatch {
|
||||
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
|
||||
}
|
||||
|
||||
func (this *IDispatch) AddRef() int32 {
|
||||
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
|
||||
}
|
||||
|
||||
func (this *IDispatch) Release() int32 {
|
||||
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
|
||||
}
|
||||
|
||||
func (this *IDispatch) GetIDsOfName(names []string) []int32 {
|
||||
return ComGetIDsOfName(this, names)
|
||||
}
|
||||
|
||||
func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT {
|
||||
return ComInvoke(this, dispid, dispatch, params...)
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type pIStreamVtbl struct {
|
||||
pQueryInterface uintptr
|
||||
pAddRef uintptr
|
||||
pRelease uintptr
|
||||
}
|
||||
|
||||
type IStream struct {
|
||||
lpVtbl *pIStreamVtbl
|
||||
}
|
||||
|
||||
func (this *IStream) QueryInterface(id *GUID) *IDispatch {
|
||||
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
|
||||
}
|
||||
|
||||
func (this *IStream) AddRef() int32 {
|
||||
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
|
||||
}
|
||||
|
||||
func (this *IStream) Release() int32 {
|
||||
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
type pIUnknownVtbl struct {
|
||||
pQueryInterface uintptr
|
||||
pAddRef uintptr
|
||||
pRelease uintptr
|
||||
}
|
||||
|
||||
type IUnknown struct {
|
||||
lpVtbl *pIUnknownVtbl
|
||||
}
|
||||
|
||||
func (this *IUnknown) QueryInterface(id *GUID) *IDispatch {
|
||||
return ComQueryInterface(this, id)
|
||||
}
|
||||
|
||||
func (this *IUnknown) AddRef() int32 {
|
||||
return ComAddRef(this)
|
||||
}
|
||||
|
||||
func (this *IUnknown) Release() int32 {
|
||||
return ComRelease(this)
|
||||
}
|
|
@ -1,316 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
procGetModuleHandle = modkernel32.NewProc("GetModuleHandleW")
|
||||
procMulDiv = modkernel32.NewProc("MulDiv")
|
||||
procGetConsoleWindow = modkernel32.NewProc("GetConsoleWindow")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives")
|
||||
procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID")
|
||||
procLstrlen = modkernel32.NewProc("lstrlenW")
|
||||
procLstrcpy = modkernel32.NewProc("lstrcpyW")
|
||||
procGlobalAlloc = modkernel32.NewProc("GlobalAlloc")
|
||||
procGlobalFree = modkernel32.NewProc("GlobalFree")
|
||||
procGlobalLock = modkernel32.NewProc("GlobalLock")
|
||||
procGlobalUnlock = modkernel32.NewProc("GlobalUnlock")
|
||||
procMoveMemory = modkernel32.NewProc("RtlMoveMemory")
|
||||
procFindResource = modkernel32.NewProc("FindResourceW")
|
||||
procSizeofResource = modkernel32.NewProc("SizeofResource")
|
||||
procLockResource = modkernel32.NewProc("LockResource")
|
||||
procLoadResource = modkernel32.NewProc("LoadResource")
|
||||
procGetLastError = modkernel32.NewProc("GetLastError")
|
||||
procOpenProcess = modkernel32.NewProc("OpenProcess")
|
||||
procTerminateProcess = modkernel32.NewProc("TerminateProcess")
|
||||
procCloseHandle = modkernel32.NewProc("CloseHandle")
|
||||
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
|
||||
procModule32First = modkernel32.NewProc("Module32FirstW")
|
||||
procModule32Next = modkernel32.NewProc("Module32NextW")
|
||||
procProcess32First = modkernel32.NewProc("Process32FirstW")
|
||||
procProcess32Next = modkernel32.NewProc("Process32NextW")
|
||||
procGetSystemTimes = modkernel32.NewProc("GetSystemTimes")
|
||||
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procSetConsoleTextAttribute = modkernel32.NewProc("SetConsoleTextAttribute")
|
||||
procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW")
|
||||
procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
|
||||
)
|
||||
|
||||
func GetModuleHandle(modulename string) HINSTANCE {
|
||||
var mn uintptr
|
||||
if modulename == "" {
|
||||
mn = 0
|
||||
} else {
|
||||
mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
|
||||
}
|
||||
ret, _, _ := procGetModuleHandle.Call(mn)
|
||||
return HINSTANCE(ret)
|
||||
}
|
||||
|
||||
func MulDiv(number, numerator, denominator int) int {
|
||||
ret, _, _ := procMulDiv.Call(
|
||||
uintptr(number),
|
||||
uintptr(numerator),
|
||||
uintptr(denominator))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetConsoleWindow() HWND {
|
||||
ret, _, _ := procGetConsoleWindow.Call()
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func GetCurrentThread() HANDLE {
|
||||
ret, _, _ := procGetCurrentThread.Call()
|
||||
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func GetLogicalDrives() uint32 {
|
||||
ret, _, _ := procGetLogicalDrives.Call()
|
||||
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func GetUserDefaultLCID() uint32 {
|
||||
ret, _, _ := procGetUserDefaultLCID.Call()
|
||||
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func Lstrlen(lpString *uint16) int {
|
||||
ret, _, _ := procLstrlen.Call(uintptr(unsafe.Pointer(lpString)))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func Lstrcpy(buf []uint16, lpString *uint16) {
|
||||
procLstrcpy.Call(
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(lpString)))
|
||||
}
|
||||
|
||||
func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL {
|
||||
ret, _, _ := procGlobalAlloc.Call(
|
||||
uintptr(uFlags),
|
||||
uintptr(dwBytes))
|
||||
|
||||
if ret == 0 {
|
||||
panic("GlobalAlloc failed")
|
||||
}
|
||||
|
||||
return HGLOBAL(ret)
|
||||
}
|
||||
|
||||
func GlobalFree(hMem HGLOBAL) {
|
||||
ret, _, _ := procGlobalFree.Call(uintptr(hMem))
|
||||
|
||||
if ret != 0 {
|
||||
panic("GlobalFree failed")
|
||||
}
|
||||
}
|
||||
|
||||
func GlobalLock(hMem HGLOBAL) unsafe.Pointer {
|
||||
ret, _, _ := procGlobalLock.Call(uintptr(hMem))
|
||||
|
||||
if ret == 0 {
|
||||
panic("GlobalLock failed")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
||||
|
||||
func GlobalUnlock(hMem HGLOBAL) bool {
|
||||
ret, _, _ := procGlobalUnlock.Call(uintptr(hMem))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func MoveMemory(destination, source unsafe.Pointer, length uint32) {
|
||||
procMoveMemory.Call(
|
||||
uintptr(unsafe.Pointer(destination)),
|
||||
uintptr(source),
|
||||
uintptr(length))
|
||||
}
|
||||
|
||||
func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) {
|
||||
ret, _, _ := procFindResource.Call(
|
||||
uintptr(hModule),
|
||||
uintptr(unsafe.Pointer(lpName)),
|
||||
uintptr(unsafe.Pointer(lpType)))
|
||||
|
||||
if ret == 0 {
|
||||
return 0, syscall.GetLastError()
|
||||
}
|
||||
|
||||
return HRSRC(ret), nil
|
||||
}
|
||||
|
||||
func SizeofResource(hModule HMODULE, hResInfo HRSRC) uint32 {
|
||||
ret, _, _ := procSizeofResource.Call(
|
||||
uintptr(hModule),
|
||||
uintptr(hResInfo))
|
||||
|
||||
if ret == 0 {
|
||||
panic("SizeofResource failed")
|
||||
}
|
||||
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func LockResource(hResData HGLOBAL) unsafe.Pointer {
|
||||
ret, _, _ := procLockResource.Call(uintptr(hResData))
|
||||
|
||||
if ret == 0 {
|
||||
panic("LockResource failed")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
||||
|
||||
func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL {
|
||||
ret, _, _ := procLoadResource.Call(
|
||||
uintptr(hModule),
|
||||
uintptr(hResInfo))
|
||||
|
||||
if ret == 0 {
|
||||
panic("LoadResource failed")
|
||||
}
|
||||
|
||||
return HGLOBAL(ret)
|
||||
}
|
||||
|
||||
func GetLastError() uint32 {
|
||||
ret, _, _ := procGetLastError.Call()
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE {
|
||||
inherit := 0
|
||||
if inheritHandle {
|
||||
inherit = 1
|
||||
}
|
||||
|
||||
ret, _, _ := procOpenProcess.Call(
|
||||
uintptr(desiredAccess),
|
||||
uintptr(inherit),
|
||||
uintptr(processId))
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func TerminateProcess(hProcess HANDLE, uExitCode uint) bool {
|
||||
ret, _, _ := procTerminateProcess.Call(
|
||||
uintptr(hProcess),
|
||||
uintptr(uExitCode))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CloseHandle(object HANDLE) bool {
|
||||
ret, _, _ := procCloseHandle.Call(
|
||||
uintptr(object))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE {
|
||||
ret, _, _ := procCreateToolhelp32Snapshot.Call(
|
||||
uintptr(flags),
|
||||
uintptr(processId))
|
||||
|
||||
if ret <= 0 {
|
||||
return HANDLE(0)
|
||||
}
|
||||
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool {
|
||||
ret, _, _ := procModule32First.Call(
|
||||
uintptr(snapshot),
|
||||
uintptr(unsafe.Pointer(me)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool {
|
||||
ret, _, _ := procModule32Next.Call(
|
||||
uintptr(snapshot),
|
||||
uintptr(unsafe.Pointer(me)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
func Process32First(snapshot HANDLE, pe *PROCESSENTRY32) bool {
|
||||
ret, _, _ := procProcess32First.Call(
|
||||
uintptr(snapshot),
|
||||
uintptr(unsafe.Pointer(pe)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func Process32Next(snapshot HANDLE, pe *PROCESSENTRY32) bool {
|
||||
ret, _, _ := procProcess32Next.Call(
|
||||
uintptr(snapshot),
|
||||
uintptr(unsafe.Pointer(pe)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool {
|
||||
ret, _, _ := procGetSystemTimes.Call(
|
||||
uintptr(unsafe.Pointer(lpIdleTime)),
|
||||
uintptr(unsafe.Pointer(lpKernelTime)),
|
||||
uintptr(unsafe.Pointer(lpUserTime)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetProcessTimes(hProcess HANDLE, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime *FILETIME) bool {
|
||||
ret, _, _ := procGetProcessTimes.Call(
|
||||
uintptr(hProcess),
|
||||
uintptr(unsafe.Pointer(lpCreationTime)),
|
||||
uintptr(unsafe.Pointer(lpExitTime)),
|
||||
uintptr(unsafe.Pointer(lpKernelTime)),
|
||||
uintptr(unsafe.Pointer(lpUserTime)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO {
|
||||
var csbi CONSOLE_SCREEN_BUFFER_INFO
|
||||
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
|
||||
uintptr(hConsoleOutput),
|
||||
uintptr(unsafe.Pointer(&csbi)))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return &csbi
|
||||
}
|
||||
|
||||
func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool {
|
||||
ret, _, _ := procSetConsoleTextAttribute.Call(
|
||||
uintptr(hConsoleOutput),
|
||||
uintptr(wAttributes))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetDiskFreeSpaceEx(dirName string) (r bool,
|
||||
freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) {
|
||||
ret, _, _ := procGetDiskFreeSpaceEx.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(dirName))),
|
||||
uintptr(unsafe.Pointer(&freeBytesAvailable)),
|
||||
uintptr(unsafe.Pointer(&totalNumberOfBytes)),
|
||||
uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)))
|
||||
return ret != 0,
|
||||
freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modole32 = syscall.NewLazyDLL("ole32.dll")
|
||||
|
||||
procCoInitializeEx = modole32.NewProc("CoInitializeEx")
|
||||
procCoInitialize = modole32.NewProc("CoInitialize")
|
||||
procCoUninitialize = modole32.NewProc("CoUninitialize")
|
||||
procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal")
|
||||
)
|
||||
|
||||
func CoInitializeEx(coInit uintptr) HRESULT {
|
||||
ret, _, _ := procCoInitializeEx.Call(
|
||||
0,
|
||||
coInit)
|
||||
|
||||
switch uint32(ret) {
|
||||
case E_INVALIDARG:
|
||||
panic("CoInitializeEx failed with E_INVALIDARG")
|
||||
case E_OUTOFMEMORY:
|
||||
panic("CoInitializeEx failed with E_OUTOFMEMORY")
|
||||
case E_UNEXPECTED:
|
||||
panic("CoInitializeEx failed with E_UNEXPECTED")
|
||||
}
|
||||
|
||||
return HRESULT(ret)
|
||||
}
|
||||
|
||||
func CoInitialize() {
|
||||
procCoInitialize.Call(0)
|
||||
}
|
||||
|
||||
func CoUninitialize() {
|
||||
procCoUninitialize.Call()
|
||||
}
|
||||
|
||||
func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream {
|
||||
stream := new(IStream)
|
||||
ret, _, _ := procCreateStreamOnHGlobal.Call(
|
||||
uintptr(hGlobal),
|
||||
uintptr(BoolToBOOL(fDeleteOnRelease)),
|
||||
uintptr(unsafe.Pointer(&stream)))
|
||||
|
||||
switch uint32(ret) {
|
||||
case E_INVALIDARG:
|
||||
panic("CreateStreamOnHGlobal failed with E_INVALIDARG")
|
||||
case E_OUTOFMEMORY:
|
||||
panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY")
|
||||
case E_UNEXPECTED:
|
||||
panic("CreateStreamOnHGlobal failed with E_UNEXPECTED")
|
||||
}
|
||||
|
||||
return stream
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modoleaut32 = syscall.NewLazyDLL("oleaut32")
|
||||
|
||||
procVariantInit = modoleaut32.NewProc("VariantInit")
|
||||
procSysAllocString = modoleaut32.NewProc("SysAllocString")
|
||||
procSysFreeString = modoleaut32.NewProc("SysFreeString")
|
||||
procSysStringLen = modoleaut32.NewProc("SysStringLen")
|
||||
procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo")
|
||||
procCreateStdDispatch = modoleaut32.NewProc("CreateStdDispatch")
|
||||
)
|
||||
|
||||
func VariantInit(v *VARIANT) {
|
||||
hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
|
||||
if hr != 0 {
|
||||
panic("Invoke VariantInit error.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SysAllocString(v string) (ss *int16) {
|
||||
pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
|
||||
ss = (*int16)(unsafe.Pointer(pss))
|
||||
return
|
||||
}
|
||||
|
||||
func SysFreeString(v *int16) {
|
||||
hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v)))
|
||||
if hr != 0 {
|
||||
panic("Invoke SysFreeString error.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SysStringLen(v *int16) uint {
|
||||
l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v)))
|
||||
return uint(l)
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modopengl32 = syscall.NewLazyDLL("opengl32.dll")
|
||||
|
||||
procwglCreateContext = modopengl32.NewProc("wglCreateContext")
|
||||
procwglCreateLayerContext = modopengl32.NewProc("wglCreateLayerContext")
|
||||
procwglDeleteContext = modopengl32.NewProc("wglDeleteContext")
|
||||
procwglGetProcAddress = modopengl32.NewProc("wglGetProcAddress")
|
||||
procwglMakeCurrent = modopengl32.NewProc("wglMakeCurrent")
|
||||
procwglShareLists = modopengl32.NewProc("wglShareLists")
|
||||
)
|
||||
|
||||
func WglCreateContext(hdc HDC) HGLRC {
|
||||
ret, _, _ := procwglCreateContext.Call(
|
||||
uintptr(hdc),
|
||||
)
|
||||
|
||||
return HGLRC(ret)
|
||||
}
|
||||
|
||||
func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC {
|
||||
ret, _, _ := procwglCreateLayerContext.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(iLayerPlane),
|
||||
)
|
||||
|
||||
return HGLRC(ret)
|
||||
}
|
||||
|
||||
func WglDeleteContext(hglrc HGLRC) bool {
|
||||
ret, _, _ := procwglDeleteContext.Call(
|
||||
uintptr(hglrc),
|
||||
)
|
||||
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func WglGetProcAddress(szProc string) uintptr {
|
||||
ret, _, _ := procwglGetProcAddress.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))),
|
||||
)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool {
|
||||
ret, _, _ := procwglMakeCurrent.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(hglrc),
|
||||
)
|
||||
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func WglShareLists(hglrc1, hglrc2 HGLRC) bool {
|
||||
ret, _, _ := procwglShareLists.Call(
|
||||
uintptr(hglrc1),
|
||||
uintptr(hglrc2),
|
||||
)
|
||||
|
||||
return ret == TRUE
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modpsapi = syscall.NewLazyDLL("psapi.dll")
|
||||
|
||||
procEnumProcesses = modpsapi.NewProc("EnumProcesses")
|
||||
)
|
||||
|
||||
func EnumProcesses(processIds []uint32, cb uint32, bytesReturned *uint32) bool {
|
||||
ret, _, _ := procEnumProcesses.Call(
|
||||
uintptr(unsafe.Pointer(&processIds[0])),
|
||||
uintptr(cb),
|
||||
uintptr(unsafe.Pointer(bytesReturned)))
|
||||
|
||||
return ret != 0
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
modshell32 = syscall.NewLazyDLL("shell32.dll")
|
||||
|
||||
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolderW")
|
||||
procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW")
|
||||
procDragAcceptFiles = modshell32.NewProc("DragAcceptFiles")
|
||||
procDragQueryFile = modshell32.NewProc("DragQueryFileW")
|
||||
procDragQueryPoint = modshell32.NewProc("DragQueryPoint")
|
||||
procDragFinish = modshell32.NewProc("DragFinish")
|
||||
procShellExecute = modshell32.NewProc("ShellExecuteW")
|
||||
procExtractIcon = modshell32.NewProc("ExtractIconW")
|
||||
)
|
||||
|
||||
func SHBrowseForFolder(bi *BROWSEINFO) uintptr {
|
||||
ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi)))
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func SHGetPathFromIDList(idl uintptr) string {
|
||||
buf := make([]uint16, 1024)
|
||||
procSHGetPathFromIDList.Call(
|
||||
idl,
|
||||
uintptr(unsafe.Pointer(&buf[0])))
|
||||
|
||||
return syscall.UTF16ToString(buf)
|
||||
}
|
||||
|
||||
func DragAcceptFiles(hwnd HWND, accept bool) {
|
||||
procDragAcceptFiles.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(BoolToBOOL(accept)))
|
||||
}
|
||||
|
||||
func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) {
|
||||
ret, _, _ := procDragQueryFile.Call(
|
||||
uintptr(hDrop),
|
||||
uintptr(iFile),
|
||||
0,
|
||||
0)
|
||||
|
||||
fileCount = uint(ret)
|
||||
|
||||
if iFile != 0xFFFFFFFF {
|
||||
buf := make([]uint16, fileCount+1)
|
||||
|
||||
ret, _, _ := procDragQueryFile.Call(
|
||||
uintptr(hDrop),
|
||||
uintptr(iFile),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(fileCount+1))
|
||||
|
||||
if ret == 0 {
|
||||
panic("Invoke DragQueryFile error.")
|
||||
}
|
||||
|
||||
fileName = syscall.UTF16ToString(buf)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) {
|
||||
var pt POINT
|
||||
ret, _, _ := procDragQueryPoint.Call(
|
||||
uintptr(hDrop),
|
||||
uintptr(unsafe.Pointer(&pt)))
|
||||
|
||||
return int(pt.X), int(pt.Y), (ret == 1)
|
||||
}
|
||||
|
||||
func DragFinish(hDrop HDROP) {
|
||||
procDragFinish.Call(uintptr(hDrop))
|
||||
}
|
||||
|
||||
func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
|
||||
var op, param, directory uintptr
|
||||
if len(lpOperation) != 0 {
|
||||
op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
|
||||
}
|
||||
if len(lpParameters) != 0 {
|
||||
param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
|
||||
}
|
||||
if len(lpDirectory) != 0 {
|
||||
directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
|
||||
}
|
||||
|
||||
ret, _, _ := procShellExecute.Call(
|
||||
uintptr(hwnd),
|
||||
op,
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
|
||||
param,
|
||||
directory,
|
||||
uintptr(nShowCmd))
|
||||
|
||||
errorMsg := ""
|
||||
if ret != 0 && ret <= 32 {
|
||||
switch int(ret) {
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
errorMsg = "The specified file was not found."
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
errorMsg = "The specified path was not found."
|
||||
case ERROR_BAD_FORMAT:
|
||||
errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."
|
||||
case SE_ERR_ACCESSDENIED:
|
||||
errorMsg = "The operating system denied access to the specified file."
|
||||
case SE_ERR_ASSOCINCOMPLETE:
|
||||
errorMsg = "The file name association is incomplete or invalid."
|
||||
case SE_ERR_DDEBUSY:
|
||||
errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed."
|
||||
case SE_ERR_DDEFAIL:
|
||||
errorMsg = "The DDE transaction failed."
|
||||
case SE_ERR_DDETIMEOUT:
|
||||
errorMsg = "The DDE transaction could not be completed because the request timed out."
|
||||
case SE_ERR_DLLNOTFOUND:
|
||||
errorMsg = "The specified DLL was not found."
|
||||
case SE_ERR_NOASSOC:
|
||||
errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."
|
||||
case SE_ERR_OOM:
|
||||
errorMsg = "There was not enough memory to complete the operation."
|
||||
case SE_ERR_SHARE:
|
||||
errorMsg = "A sharing violation occurred."
|
||||
default:
|
||||
errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret)
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New(errorMsg)
|
||||
}
|
||||
|
||||
func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON {
|
||||
ret, _, _ := procExtractIcon.Call(
|
||||
0,
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))),
|
||||
uintptr(nIconIndex))
|
||||
|
||||
return HICON(ret)
|
||||
}
|
|
@ -1,901 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// From MSDN: Windows Data Types
|
||||
// http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx
|
||||
// ATOM WORD
|
||||
// BOOL int32
|
||||
// BOOLEAN byte
|
||||
// BYTE byte
|
||||
// CCHAR int8
|
||||
// CHAR int8
|
||||
// COLORREF DWORD
|
||||
// DWORD uint32
|
||||
// DWORDLONG ULONGLONG
|
||||
// DWORD_PTR ULONG_PTR
|
||||
// DWORD32 uint32
|
||||
// DWORD64 uint64
|
||||
// FLOAT float32
|
||||
// HACCEL HANDLE
|
||||
// HALF_PTR struct{} // ???
|
||||
// HANDLE PVOID
|
||||
// HBITMAP HANDLE
|
||||
// HBRUSH HANDLE
|
||||
// HCOLORSPACE HANDLE
|
||||
// HCONV HANDLE
|
||||
// HCONVLIST HANDLE
|
||||
// HCURSOR HANDLE
|
||||
// HDC HANDLE
|
||||
// HDDEDATA HANDLE
|
||||
// HDESK HANDLE
|
||||
// HDROP HANDLE
|
||||
// HDWP HANDLE
|
||||
// HENHMETAFILE HANDLE
|
||||
// HFILE HANDLE
|
||||
// HFONT HANDLE
|
||||
// HGDIOBJ HANDLE
|
||||
// HGLOBAL HANDLE
|
||||
// HHOOK HANDLE
|
||||
// HICON HANDLE
|
||||
// HINSTANCE HANDLE
|
||||
// HKEY HANDLE
|
||||
// HKL HANDLE
|
||||
// HLOCAL HANDLE
|
||||
// HMENU HANDLE
|
||||
// HMETAFILE HANDLE
|
||||
// HMODULE HANDLE
|
||||
// HPALETTE HANDLE
|
||||
// HPEN HANDLE
|
||||
// HRESULT int32
|
||||
// HRGN HANDLE
|
||||
// HSZ HANDLE
|
||||
// HWINSTA HANDLE
|
||||
// HWND HANDLE
|
||||
// INT int32
|
||||
// INT_PTR uintptr
|
||||
// INT8 int8
|
||||
// INT16 int16
|
||||
// INT32 int32
|
||||
// INT64 int64
|
||||
// LANGID WORD
|
||||
// LCID DWORD
|
||||
// LCTYPE DWORD
|
||||
// LGRPID DWORD
|
||||
// LONG int32
|
||||
// LONGLONG int64
|
||||
// LONG_PTR uintptr
|
||||
// LONG32 int32
|
||||
// LONG64 int64
|
||||
// LPARAM LONG_PTR
|
||||
// LPBOOL *BOOL
|
||||
// LPBYTE *BYTE
|
||||
// LPCOLORREF *COLORREF
|
||||
// LPCSTR *int8
|
||||
// LPCTSTR LPCWSTR
|
||||
// LPCVOID unsafe.Pointer
|
||||
// LPCWSTR *WCHAR
|
||||
// LPDWORD *DWORD
|
||||
// LPHANDLE *HANDLE
|
||||
// LPINT *INT
|
||||
// LPLONG *LONG
|
||||
// LPSTR *CHAR
|
||||
// LPTSTR LPWSTR
|
||||
// LPVOID unsafe.Pointer
|
||||
// LPWORD *WORD
|
||||
// LPWSTR *WCHAR
|
||||
// LRESULT LONG_PTR
|
||||
// PBOOL *BOOL
|
||||
// PBOOLEAN *BOOLEAN
|
||||
// PBYTE *BYTE
|
||||
// PCHAR *CHAR
|
||||
// PCSTR *CHAR
|
||||
// PCTSTR PCWSTR
|
||||
// PCWSTR *WCHAR
|
||||
// PDWORD *DWORD
|
||||
// PDWORDLONG *DWORDLONG
|
||||
// PDWORD_PTR *DWORD_PTR
|
||||
// PDWORD32 *DWORD32
|
||||
// PDWORD64 *DWORD64
|
||||
// PFLOAT *FLOAT
|
||||
// PHALF_PTR *HALF_PTR
|
||||
// PHANDLE *HANDLE
|
||||
// PHKEY *HKEY
|
||||
// PINT_PTR *INT_PTR
|
||||
// PINT8 *INT8
|
||||
// PINT16 *INT16
|
||||
// PINT32 *INT32
|
||||
// PINT64 *INT64
|
||||
// PLCID *LCID
|
||||
// PLONG *LONG
|
||||
// PLONGLONG *LONGLONG
|
||||
// PLONG_PTR *LONG_PTR
|
||||
// PLONG32 *LONG32
|
||||
// PLONG64 *LONG64
|
||||
// POINTER_32 struct{} // ???
|
||||
// POINTER_64 struct{} // ???
|
||||
// POINTER_SIGNED uintptr
|
||||
// POINTER_UNSIGNED uintptr
|
||||
// PSHORT *SHORT
|
||||
// PSIZE_T *SIZE_T
|
||||
// PSSIZE_T *SSIZE_T
|
||||
// PSTR *CHAR
|
||||
// PTBYTE *TBYTE
|
||||
// PTCHAR *TCHAR
|
||||
// PTSTR PWSTR
|
||||
// PUCHAR *UCHAR
|
||||
// PUHALF_PTR *UHALF_PTR
|
||||
// PUINT *UINT
|
||||
// PUINT_PTR *UINT_PTR
|
||||
// PUINT8 *UINT8
|
||||
// PUINT16 *UINT16
|
||||
// PUINT32 *UINT32
|
||||
// PUINT64 *UINT64
|
||||
// PULONG *ULONG
|
||||
// PULONGLONG *ULONGLONG
|
||||
// PULONG_PTR *ULONG_PTR
|
||||
// PULONG32 *ULONG32
|
||||
// PULONG64 *ULONG64
|
||||
// PUSHORT *USHORT
|
||||
// PVOID unsafe.Pointer
|
||||
// PWCHAR *WCHAR
|
||||
// PWORD *WORD
|
||||
// PWSTR *WCHAR
|
||||
// QWORD uint64
|
||||
// SC_HANDLE HANDLE
|
||||
// SC_LOCK LPVOID
|
||||
// SERVICE_STATUS_HANDLE HANDLE
|
||||
// SHORT int16
|
||||
// SIZE_T ULONG_PTR
|
||||
// SSIZE_T LONG_PTR
|
||||
// TBYTE WCHAR
|
||||
// TCHAR WCHAR
|
||||
// UCHAR uint8
|
||||
// UHALF_PTR struct{} // ???
|
||||
// UINT uint32
|
||||
// UINT_PTR uintptr
|
||||
// UINT8 uint8
|
||||
// UINT16 uint16
|
||||
// UINT32 uint32
|
||||
// UINT64 uint64
|
||||
// ULONG uint32
|
||||
// ULONGLONG uint64
|
||||
// ULONG_PTR uintptr
|
||||
// ULONG32 uint32
|
||||
// ULONG64 uint64
|
||||
// USHORT uint16
|
||||
// USN LONGLONG
|
||||
// WCHAR uint16
|
||||
// WORD uint16
|
||||
// WPARAM UINT_PTR
|
||||
type (
|
||||
ATOM uint16
|
||||
BOOL int32
|
||||
COLORREF uint32
|
||||
DWM_FRAME_COUNT uint64
|
||||
HACCEL HANDLE
|
||||
HANDLE uintptr
|
||||
HBITMAP HANDLE
|
||||
HBRUSH HANDLE
|
||||
HCURSOR HANDLE
|
||||
HDC HANDLE
|
||||
HDROP HANDLE
|
||||
HDWP HANDLE
|
||||
HENHMETAFILE HANDLE
|
||||
HFONT HANDLE
|
||||
HGDIOBJ HANDLE
|
||||
HGLOBAL HANDLE
|
||||
HGLRC HANDLE
|
||||
HICON HANDLE
|
||||
HIMAGELIST HANDLE
|
||||
HINSTANCE HANDLE
|
||||
HKEY HANDLE
|
||||
HKL HANDLE
|
||||
HMENU HANDLE
|
||||
HMODULE HANDLE
|
||||
HMONITOR HANDLE
|
||||
HPEN HANDLE
|
||||
HRESULT int32
|
||||
HRGN HANDLE
|
||||
HRSRC HANDLE
|
||||
HTHUMBNAIL HANDLE
|
||||
HWND HANDLE
|
||||
LPCVOID unsafe.Pointer
|
||||
PVOID unsafe.Pointer
|
||||
QPC_TIME uint64
|
||||
)
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx
|
||||
type POINT struct {
|
||||
X, Y int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx
|
||||
type RECT struct {
|
||||
Left, Top, Right, Bottom int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577.aspx
|
||||
type WNDCLASSEX struct {
|
||||
Size uint32
|
||||
Style uint32
|
||||
WndProc uintptr
|
||||
ClsExtra int32
|
||||
WndExtra int32
|
||||
Instance HINSTANCE
|
||||
Icon HICON
|
||||
Cursor HCURSOR
|
||||
Background HBRUSH
|
||||
MenuName *uint16
|
||||
ClassName *uint16
|
||||
IconSm HICON
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx
|
||||
type MSG struct {
|
||||
Hwnd HWND
|
||||
Message uint32
|
||||
WParam uintptr
|
||||
LParam uintptr
|
||||
Time uint32
|
||||
Pt POINT
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx
|
||||
type LOGFONT struct {
|
||||
Height int32
|
||||
Width int32
|
||||
Escapement int32
|
||||
Orientation int32
|
||||
Weight int32
|
||||
Italic byte
|
||||
Underline byte
|
||||
StrikeOut byte
|
||||
CharSet byte
|
||||
OutPrecision byte
|
||||
ClipPrecision byte
|
||||
Quality byte
|
||||
PitchAndFamily byte
|
||||
FaceName [LF_FACESIZE]uint16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx
|
||||
type OPENFILENAME struct {
|
||||
StructSize uint32
|
||||
Owner HWND
|
||||
Instance HINSTANCE
|
||||
Filter *uint16
|
||||
CustomFilter *uint16
|
||||
MaxCustomFilter uint32
|
||||
FilterIndex uint32
|
||||
File *uint16
|
||||
MaxFile uint32
|
||||
FileTitle *uint16
|
||||
MaxFileTitle uint32
|
||||
InitialDir *uint16
|
||||
Title *uint16
|
||||
Flags uint32
|
||||
FileOffset uint16
|
||||
FileExtension uint16
|
||||
DefExt *uint16
|
||||
CustData uintptr
|
||||
FnHook uintptr
|
||||
TemplateName *uint16
|
||||
PvReserved unsafe.Pointer
|
||||
DwReserved uint32
|
||||
FlagsEx uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205.aspx
|
||||
type BROWSEINFO struct {
|
||||
Owner HWND
|
||||
Root *uint16
|
||||
DisplayName *uint16
|
||||
Title *uint16
|
||||
Flags uint32
|
||||
CallbackFunc uintptr
|
||||
LParam uintptr
|
||||
Image int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx
|
||||
type GUID struct {
|
||||
Data1 uint32
|
||||
Data2 uint16
|
||||
Data3 uint16
|
||||
Data4 [8]byte
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627.aspx
|
||||
type VARIANT struct {
|
||||
VT uint16 // 2
|
||||
WReserved1 uint16 // 4
|
||||
WReserved2 uint16 // 6
|
||||
WReserved3 uint16 // 8
|
||||
Val int64 // 16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221416.aspx
|
||||
type DISPPARAMS struct {
|
||||
Rgvarg uintptr
|
||||
RgdispidNamedArgs uintptr
|
||||
CArgs uint32
|
||||
CNamedArgs uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221133.aspx
|
||||
type EXCEPINFO struct {
|
||||
WCode uint16
|
||||
WReserved uint16
|
||||
BstrSource *uint16
|
||||
BstrDescription *uint16
|
||||
BstrHelpFile *uint16
|
||||
DwHelpContext uint32
|
||||
PvReserved uintptr
|
||||
PfnDeferredFillIn uintptr
|
||||
Scode int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035.aspx
|
||||
type LOGBRUSH struct {
|
||||
LbStyle uint32
|
||||
LbColor COLORREF
|
||||
LbHatch uintptr
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565.aspx
|
||||
type DEVMODE struct {
|
||||
DmDeviceName [CCHDEVICENAME]uint16
|
||||
DmSpecVersion uint16
|
||||
DmDriverVersion uint16
|
||||
DmSize uint16
|
||||
DmDriverExtra uint16
|
||||
DmFields uint32
|
||||
DmOrientation int16
|
||||
DmPaperSize int16
|
||||
DmPaperLength int16
|
||||
DmPaperWidth int16
|
||||
DmScale int16
|
||||
DmCopies int16
|
||||
DmDefaultSource int16
|
||||
DmPrintQuality int16
|
||||
DmColor int16
|
||||
DmDuplex int16
|
||||
DmYResolution int16
|
||||
DmTTOption int16
|
||||
DmCollate int16
|
||||
DmFormName [CCHFORMNAME]uint16
|
||||
DmLogPixels uint16
|
||||
DmBitsPerPel uint32
|
||||
DmPelsWidth uint32
|
||||
DmPelsHeight uint32
|
||||
DmDisplayFlags uint32
|
||||
DmDisplayFrequency uint32
|
||||
DmICMMethod uint32
|
||||
DmICMIntent uint32
|
||||
DmMediaType uint32
|
||||
DmDitherType uint32
|
||||
DmReserved1 uint32
|
||||
DmReserved2 uint32
|
||||
DmPanningWidth uint32
|
||||
DmPanningHeight uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx
|
||||
type BITMAPINFOHEADER struct {
|
||||
BiSize uint32
|
||||
BiWidth int32
|
||||
BiHeight int32
|
||||
BiPlanes uint16
|
||||
BiBitCount uint16
|
||||
BiCompression uint32
|
||||
BiSizeImage uint32
|
||||
BiXPelsPerMeter int32
|
||||
BiYPelsPerMeter int32
|
||||
BiClrUsed uint32
|
||||
BiClrImportant uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx
|
||||
type RGBQUAD struct {
|
||||
RgbBlue byte
|
||||
RgbGreen byte
|
||||
RgbRed byte
|
||||
RgbReserved byte
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375.aspx
|
||||
type BITMAPINFO struct {
|
||||
BmiHeader BITMAPINFOHEADER
|
||||
BmiColors *RGBQUAD
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183371.aspx
|
||||
type BITMAP struct {
|
||||
BmType int32
|
||||
BmWidth int32
|
||||
BmHeight int32
|
||||
BmWidthBytes int32
|
||||
BmPlanes uint16
|
||||
BmBitsPixel uint16
|
||||
BmBits unsafe.Pointer
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx
|
||||
type DIBSECTION struct {
|
||||
DsBm BITMAP
|
||||
DsBmih BITMAPINFOHEADER
|
||||
DsBitfields [3]uint32
|
||||
DshSection HANDLE
|
||||
DsOffset uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162607.aspx
|
||||
type ENHMETAHEADER struct {
|
||||
IType uint32
|
||||
NSize uint32
|
||||
RclBounds RECT
|
||||
RclFrame RECT
|
||||
DSignature uint32
|
||||
NVersion uint32
|
||||
NBytes uint32
|
||||
NRecords uint32
|
||||
NHandles uint16
|
||||
SReserved uint16
|
||||
NDescription uint32
|
||||
OffDescription uint32
|
||||
NPalEntries uint32
|
||||
SzlDevice SIZE
|
||||
SzlMillimeters SIZE
|
||||
CbPixelFormat uint32
|
||||
OffPixelFormat uint32
|
||||
BOpenGL uint32
|
||||
SzlMicrometers SIZE
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145106.aspx
|
||||
type SIZE struct {
|
||||
CX, CY int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145132.aspx
|
||||
type TEXTMETRIC struct {
|
||||
TmHeight int32
|
||||
TmAscent int32
|
||||
TmDescent int32
|
||||
TmInternalLeading int32
|
||||
TmExternalLeading int32
|
||||
TmAveCharWidth int32
|
||||
TmMaxCharWidth int32
|
||||
TmWeight int32
|
||||
TmOverhang int32
|
||||
TmDigitizedAspectX int32
|
||||
TmDigitizedAspectY int32
|
||||
TmFirstChar uint16
|
||||
TmLastChar uint16
|
||||
TmDefaultChar uint16
|
||||
TmBreakChar uint16
|
||||
TmItalic byte
|
||||
TmUnderlined byte
|
||||
TmStruckOut byte
|
||||
TmPitchAndFamily byte
|
||||
TmCharSet byte
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183574.aspx
|
||||
type DOCINFO struct {
|
||||
CbSize int32
|
||||
LpszDocName *uint16
|
||||
LpszOutput *uint16
|
||||
LpszDatatype *uint16
|
||||
FwType uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775514.aspx
|
||||
type NMHDR struct {
|
||||
HwndFrom HWND
|
||||
IdFrom uintptr
|
||||
Code uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx
|
||||
type LVCOLUMN struct {
|
||||
Mask uint32
|
||||
Fmt int32
|
||||
Cx int32
|
||||
PszText *uint16
|
||||
CchTextMax int32
|
||||
ISubItem int32
|
||||
IImage int32
|
||||
IOrder int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx
|
||||
type LVITEM struct {
|
||||
Mask uint32
|
||||
IItem int32
|
||||
ISubItem int32
|
||||
State uint32
|
||||
StateMask uint32
|
||||
PszText *uint16
|
||||
CchTextMax int32
|
||||
IImage int32
|
||||
LParam uintptr
|
||||
IIndent int32
|
||||
IGroupId int32
|
||||
CColumns uint32
|
||||
PuColumns uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx
|
||||
type LVHITTESTINFO struct {
|
||||
Pt POINT
|
||||
Flags uint32
|
||||
IItem int32
|
||||
ISubItem int32
|
||||
IGroup int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774771.aspx
|
||||
type NMITEMACTIVATE struct {
|
||||
Hdr NMHDR
|
||||
IItem int32
|
||||
ISubItem int32
|
||||
UNewState uint32
|
||||
UOldState uint32
|
||||
UChanged uint32
|
||||
PtAction POINT
|
||||
LParam uintptr
|
||||
UKeyFlags uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774773.aspx
|
||||
type NMLISTVIEW struct {
|
||||
Hdr NMHDR
|
||||
IItem int32
|
||||
ISubItem int32
|
||||
UNewState uint32
|
||||
UOldState uint32
|
||||
UChanged uint32
|
||||
PtAction POINT
|
||||
LParam uintptr
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780.aspx
|
||||
type NMLVDISPINFO struct {
|
||||
Hdr NMHDR
|
||||
Item LVITEM
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx
|
||||
type INITCOMMONCONTROLSEX struct {
|
||||
DwSize uint32
|
||||
DwICC uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx
|
||||
type TOOLINFO struct {
|
||||
CbSize uint32
|
||||
UFlags uint32
|
||||
Hwnd HWND
|
||||
UId uintptr
|
||||
Rect RECT
|
||||
Hinst HINSTANCE
|
||||
LpszText *uint16
|
||||
LParam uintptr
|
||||
LpReserved unsafe.Pointer
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604.aspx
|
||||
type TRACKMOUSEEVENT struct {
|
||||
CbSize uint32
|
||||
DwFlags uint32
|
||||
HwndTrack HWND
|
||||
DwHoverTime uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534067.aspx
|
||||
type GdiplusStartupInput struct {
|
||||
GdiplusVersion uint32
|
||||
DebugEventCallback uintptr
|
||||
SuppressBackgroundThread BOOL
|
||||
SuppressExternalCodecs BOOL
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534068.aspx
|
||||
type GdiplusStartupOutput struct {
|
||||
NotificationHook uintptr
|
||||
NotificationUnhook uintptr
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768.aspx
|
||||
type PAINTSTRUCT struct {
|
||||
Hdc HDC
|
||||
FErase BOOL
|
||||
RcPaint RECT
|
||||
FRestore BOOL
|
||||
FIncUpdate BOOL
|
||||
RgbReserved [32]byte
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363646.aspx
|
||||
type EVENTLOGRECORD struct {
|
||||
Length uint32
|
||||
Reserved uint32
|
||||
RecordNumber uint32
|
||||
TimeGenerated uint32
|
||||
TimeWritten uint32
|
||||
EventID uint32
|
||||
EventType uint16
|
||||
NumStrings uint16
|
||||
EventCategory uint16
|
||||
ReservedFlags uint16
|
||||
ClosingRecordNumber uint32
|
||||
StringOffset uint32
|
||||
UserSidLength uint32
|
||||
UserSidOffset uint32
|
||||
DataLength uint32
|
||||
DataOffset uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996.aspx
|
||||
type SERVICE_STATUS struct {
|
||||
DwServiceType uint32
|
||||
DwCurrentState uint32
|
||||
DwControlsAccepted uint32
|
||||
DwWin32ExitCode uint32
|
||||
DwServiceSpecificExitCode uint32
|
||||
DwCheckPoint uint32
|
||||
DwWaitHint uint32
|
||||
}
|
||||
type PROCESSENTRY32 struct {
|
||||
DwSize uint32
|
||||
CntUsage uint32
|
||||
Th32ProcessID uint32
|
||||
Th32DefaultHeapID uintptr
|
||||
Th32ModuleID uint32
|
||||
CntThreads uint32
|
||||
Th32ParentProcessID uint32
|
||||
PcPriClassBase int32
|
||||
DwFlags uint32
|
||||
SzExeFile [MAX_PATH]uint16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225.aspx
|
||||
type MODULEENTRY32 struct {
|
||||
Size uint32
|
||||
ModuleID uint32
|
||||
ProcessID uint32
|
||||
GlblcntUsage uint32
|
||||
ProccntUsage uint32
|
||||
ModBaseAddr *uint8
|
||||
ModBaseSize uint32
|
||||
HModule HMODULE
|
||||
SzModule [MAX_MODULE_NAME32 + 1]uint16
|
||||
SzExePath [MAX_PATH]uint16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
|
||||
type FILETIME struct {
|
||||
DwLowDateTime uint32
|
||||
DwHighDateTime uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx
|
||||
type COORD struct {
|
||||
X, Y int16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311.aspx
|
||||
type SMALL_RECT struct {
|
||||
Left, Top, Right, Bottom int16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093.aspx
|
||||
type CONSOLE_SCREEN_BUFFER_INFO struct {
|
||||
DwSize COORD
|
||||
DwCursorPosition COORD
|
||||
WAttributes uint16
|
||||
SrWindow SMALL_RECT
|
||||
DwMaximumWindowSize COORD
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx
|
||||
type MARGINS struct {
|
||||
CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969500.aspx
|
||||
type DWM_BLURBEHIND struct {
|
||||
DwFlags uint32
|
||||
fEnable BOOL
|
||||
hRgnBlur HRGN
|
||||
fTransitionOnMaximized BOOL
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969501.aspx
|
||||
type DWM_PRESENT_PARAMETERS struct {
|
||||
cbSize uint32
|
||||
fQueue BOOL
|
||||
cRefreshStart DWM_FRAME_COUNT
|
||||
cBuffer uint32
|
||||
fUseSourceRate BOOL
|
||||
rateSource UNSIGNED_RATIO
|
||||
cRefreshesPerFrame uint32
|
||||
eSampling DWM_SOURCE_FRAME_SAMPLING
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969502.aspx
|
||||
type DWM_THUMBNAIL_PROPERTIES struct {
|
||||
dwFlags uint32
|
||||
rcDestination RECT
|
||||
rcSource RECT
|
||||
opacity byte
|
||||
fVisible BOOL
|
||||
fSourceClientAreaOnly BOOL
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969503.aspx
|
||||
type DWM_TIMING_INFO struct {
|
||||
cbSize uint32
|
||||
rateRefresh UNSIGNED_RATIO
|
||||
qpcRefreshPeriod QPC_TIME
|
||||
rateCompose UNSIGNED_RATIO
|
||||
qpcVBlank QPC_TIME
|
||||
cRefresh DWM_FRAME_COUNT
|
||||
cDXRefresh uint32
|
||||
qpcCompose QPC_TIME
|
||||
cFrame DWM_FRAME_COUNT
|
||||
cDXPresent uint32
|
||||
cRefreshFrame DWM_FRAME_COUNT
|
||||
cFrameSubmitted DWM_FRAME_COUNT
|
||||
cDXPresentSubmitted uint32
|
||||
cFrameConfirmed DWM_FRAME_COUNT
|
||||
cDXPresentConfirmed uint32
|
||||
cRefreshConfirmed DWM_FRAME_COUNT
|
||||
cDXRefreshConfirmed uint32
|
||||
cFramesLate DWM_FRAME_COUNT
|
||||
cFramesOutstanding uint32
|
||||
cFrameDisplayed DWM_FRAME_COUNT
|
||||
qpcFrameDisplayed QPC_TIME
|
||||
cRefreshFrameDisplayed DWM_FRAME_COUNT
|
||||
cFrameComplete DWM_FRAME_COUNT
|
||||
qpcFrameComplete QPC_TIME
|
||||
cFramePending DWM_FRAME_COUNT
|
||||
qpcFramePending QPC_TIME
|
||||
cFramesDisplayed DWM_FRAME_COUNT
|
||||
cFramesComplete DWM_FRAME_COUNT
|
||||
cFramesPending DWM_FRAME_COUNT
|
||||
cFramesAvailable DWM_FRAME_COUNT
|
||||
cFramesDropped DWM_FRAME_COUNT
|
||||
cFramesMissed DWM_FRAME_COUNT
|
||||
cRefreshNextDisplayed DWM_FRAME_COUNT
|
||||
cRefreshNextPresented DWM_FRAME_COUNT
|
||||
cRefreshesDisplayed DWM_FRAME_COUNT
|
||||
cRefreshesPresented DWM_FRAME_COUNT
|
||||
cRefreshStarted DWM_FRAME_COUNT
|
||||
cPixelsReceived uint64
|
||||
cPixelsDrawn uint64
|
||||
cBuffersEmpty DWM_FRAME_COUNT
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd389402.aspx
|
||||
type MilMatrix3x2D struct {
|
||||
S_11, S_12, S_21, S_22 float64
|
||||
DX, DY float64
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969505.aspx
|
||||
type UNSIGNED_RATIO struct {
|
||||
uiNumerator uint32
|
||||
uiDenominator uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603.aspx
|
||||
type CREATESTRUCT struct {
|
||||
CreateParams uintptr
|
||||
Instance HINSTANCE
|
||||
Menu HMENU
|
||||
Parent HWND
|
||||
Cy, Cx int32
|
||||
Y, X int32
|
||||
Style int32
|
||||
Name *uint16
|
||||
Class *uint16
|
||||
dwExStyle uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065.aspx
|
||||
type MONITORINFO struct {
|
||||
CbSize uint32
|
||||
RcMonitor RECT
|
||||
RcWork RECT
|
||||
DwFlags uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066.aspx
|
||||
type MONITORINFOEX struct {
|
||||
MONITORINFO
|
||||
SzDevice [CCHDEVICENAME]uint16
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826.aspx
|
||||
type PIXELFORMATDESCRIPTOR struct {
|
||||
Size uint16
|
||||
Version uint16
|
||||
DwFlags uint32
|
||||
IPixelType byte
|
||||
ColorBits byte
|
||||
RedBits, RedShift byte
|
||||
GreenBits, GreenShift byte
|
||||
BlueBits, BlueShift byte
|
||||
AlphaBits, AlphaShift byte
|
||||
AccumBits byte
|
||||
AccumRedBits byte
|
||||
AccumGreenBits byte
|
||||
AccumBlueBits byte
|
||||
AccumAlphaBits byte
|
||||
DepthBits, StencilBits byte
|
||||
AuxBuffers byte
|
||||
ILayerType byte
|
||||
Reserved byte
|
||||
DwLayerMask uint32
|
||||
DwVisibleMask uint32
|
||||
DwDamageMask uint32
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
|
||||
type INPUT struct {
|
||||
Type uint32
|
||||
Mi MOUSEINPUT
|
||||
Ki KEYBDINPUT
|
||||
Hi HARDWAREINPUT
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx
|
||||
type MOUSEINPUT struct {
|
||||
Dx int32
|
||||
Dy int32
|
||||
MouseData uint32
|
||||
DwFlags uint32
|
||||
Time uint32
|
||||
DwExtraInfo uintptr
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271(v=vs.85).aspx
|
||||
type KEYBDINPUT struct {
|
||||
WVk uint16
|
||||
WScan uint16
|
||||
DwFlags uint32
|
||||
Time uint32
|
||||
DwExtraInfo uintptr
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269(v=vs.85).aspx
|
||||
type HARDWAREINPUT struct {
|
||||
UMsg uint32
|
||||
WParamL uint16
|
||||
WParamH uint16
|
||||
}
|
||||
|
||||
type KbdInput struct {
|
||||
typ uint32
|
||||
ki KEYBDINPUT
|
||||
}
|
||||
|
||||
type MouseInput struct {
|
||||
typ uint32
|
||||
mi MOUSEINPUT
|
||||
}
|
||||
|
||||
type HardwareInput struct {
|
||||
typ uint32
|
||||
hi HARDWAREINPUT
|
||||
}
|
|
@ -1,950 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
moduser32 = syscall.NewLazyDLL("user32.dll")
|
||||
|
||||
procRegisterClassEx = moduser32.NewProc("RegisterClassExW")
|
||||
procLoadIcon = moduser32.NewProc("LoadIconW")
|
||||
procLoadCursor = moduser32.NewProc("LoadCursorW")
|
||||
procShowWindow = moduser32.NewProc("ShowWindow")
|
||||
procUpdateWindow = moduser32.NewProc("UpdateWindow")
|
||||
procCreateWindowEx = moduser32.NewProc("CreateWindowExW")
|
||||
procAdjustWindowRect = moduser32.NewProc("AdjustWindowRect")
|
||||
procAdjustWindowRectEx = moduser32.NewProc("AdjustWindowRectEx")
|
||||
procDestroyWindow = moduser32.NewProc("DestroyWindow")
|
||||
procDefWindowProc = moduser32.NewProc("DefWindowProcW")
|
||||
procDefDlgProc = moduser32.NewProc("DefDlgProcW")
|
||||
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
|
||||
procGetMessage = moduser32.NewProc("GetMessageW")
|
||||
procTranslateMessage = moduser32.NewProc("TranslateMessage")
|
||||
procDispatchMessage = moduser32.NewProc("DispatchMessageW")
|
||||
procSendMessage = moduser32.NewProc("SendMessageW")
|
||||
procPostMessage = moduser32.NewProc("PostMessageW")
|
||||
procWaitMessage = moduser32.NewProc("WaitMessage")
|
||||
procSetWindowText = moduser32.NewProc("SetWindowTextW")
|
||||
procGetWindowTextLength = moduser32.NewProc("GetWindowTextLengthW")
|
||||
procGetWindowText = moduser32.NewProc("GetWindowTextW")
|
||||
procGetWindowRect = moduser32.NewProc("GetWindowRect")
|
||||
procMoveWindow = moduser32.NewProc("MoveWindow")
|
||||
procScreenToClient = moduser32.NewProc("ScreenToClient")
|
||||
procCallWindowProc = moduser32.NewProc("CallWindowProcW")
|
||||
procSetWindowLong = moduser32.NewProc("SetWindowLongW")
|
||||
procSetWindowLongPtr = moduser32.NewProc("SetWindowLongW")
|
||||
procGetWindowLong = moduser32.NewProc("GetWindowLongW")
|
||||
procGetWindowLongPtr = moduser32.NewProc("GetWindowLongW")
|
||||
procEnableWindow = moduser32.NewProc("EnableWindow")
|
||||
procIsWindowEnabled = moduser32.NewProc("IsWindowEnabled")
|
||||
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
|
||||
procSetFocus = moduser32.NewProc("SetFocus")
|
||||
procInvalidateRect = moduser32.NewProc("InvalidateRect")
|
||||
procGetClientRect = moduser32.NewProc("GetClientRect")
|
||||
procGetDC = moduser32.NewProc("GetDC")
|
||||
procReleaseDC = moduser32.NewProc("ReleaseDC")
|
||||
procSetCapture = moduser32.NewProc("SetCapture")
|
||||
procReleaseCapture = moduser32.NewProc("ReleaseCapture")
|
||||
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
|
||||
procMessageBox = moduser32.NewProc("MessageBoxW")
|
||||
procGetSystemMetrics = moduser32.NewProc("GetSystemMetrics")
|
||||
procCopyRect = moduser32.NewProc("CopyRect")
|
||||
procEqualRect = moduser32.NewProc("EqualRect")
|
||||
procInflateRect = moduser32.NewProc("InflateRect")
|
||||
procIntersectRect = moduser32.NewProc("IntersectRect")
|
||||
procIsRectEmpty = moduser32.NewProc("IsRectEmpty")
|
||||
procOffsetRect = moduser32.NewProc("OffsetRect")
|
||||
procPtInRect = moduser32.NewProc("PtInRect")
|
||||
procSetRect = moduser32.NewProc("SetRect")
|
||||
procSetRectEmpty = moduser32.NewProc("SetRectEmpty")
|
||||
procSubtractRect = moduser32.NewProc("SubtractRect")
|
||||
procUnionRect = moduser32.NewProc("UnionRect")
|
||||
procCreateDialogParam = moduser32.NewProc("CreateDialogParamW")
|
||||
procDialogBoxParam = moduser32.NewProc("DialogBoxParamW")
|
||||
procGetDlgItem = moduser32.NewProc("GetDlgItem")
|
||||
procDrawIcon = moduser32.NewProc("DrawIcon")
|
||||
procClientToScreen = moduser32.NewProc("ClientToScreen")
|
||||
procIsDialogMessage = moduser32.NewProc("IsDialogMessageW")
|
||||
procIsWindow = moduser32.NewProc("IsWindow")
|
||||
procEndDialog = moduser32.NewProc("EndDialog")
|
||||
procPeekMessage = moduser32.NewProc("PeekMessageW")
|
||||
procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW")
|
||||
procSetWindowPos = moduser32.NewProc("SetWindowPos")
|
||||
procFillRect = moduser32.NewProc("FillRect")
|
||||
procDrawText = moduser32.NewProc("DrawTextW")
|
||||
procAddClipboardFormatListener = moduser32.NewProc("AddClipboardFormatListener")
|
||||
procRemoveClipboardFormatListener = moduser32.NewProc("RemoveClipboardFormatListener")
|
||||
procOpenClipboard = moduser32.NewProc("OpenClipboard")
|
||||
procCloseClipboard = moduser32.NewProc("CloseClipboard")
|
||||
procEnumClipboardFormats = moduser32.NewProc("EnumClipboardFormats")
|
||||
procGetClipboardData = moduser32.NewProc("GetClipboardData")
|
||||
procSetClipboardData = moduser32.NewProc("SetClipboardData")
|
||||
procEmptyClipboard = moduser32.NewProc("EmptyClipboard")
|
||||
procGetClipboardFormatName = moduser32.NewProc("GetClipboardFormatNameW")
|
||||
procIsClipboardFormatAvailable = moduser32.NewProc("IsClipboardFormatAvailable")
|
||||
procBeginPaint = moduser32.NewProc("BeginPaint")
|
||||
procEndPaint = moduser32.NewProc("EndPaint")
|
||||
procGetKeyboardState = moduser32.NewProc("GetKeyboardState")
|
||||
procMapVirtualKey = moduser32.NewProc("MapVirtualKeyExW")
|
||||
procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState")
|
||||
procToAscii = moduser32.NewProc("ToAscii")
|
||||
procSwapMouseButton = moduser32.NewProc("SwapMouseButton")
|
||||
procGetCursorPos = moduser32.NewProc("GetCursorPos")
|
||||
procSetCursorPos = moduser32.NewProc("SetCursorPos")
|
||||
procSetCursor = moduser32.NewProc("SetCursor")
|
||||
procCreateIcon = moduser32.NewProc("CreateIcon")
|
||||
procDestroyIcon = moduser32.NewProc("DestroyIcon")
|
||||
procMonitorFromPoint = moduser32.NewProc("MonitorFromPoint")
|
||||
procMonitorFromRect = moduser32.NewProc("MonitorFromRect")
|
||||
procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow")
|
||||
procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW")
|
||||
procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors")
|
||||
procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW")
|
||||
procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW")
|
||||
procSendInput = moduser32.NewProc("SendInput")
|
||||
)
|
||||
|
||||
func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM {
|
||||
ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx)))
|
||||
return ATOM(ret)
|
||||
}
|
||||
|
||||
func LoadIcon(instance HINSTANCE, iconName *uint16) HICON {
|
||||
ret, _, _ := procLoadIcon.Call(
|
||||
uintptr(instance),
|
||||
uintptr(unsafe.Pointer(iconName)))
|
||||
|
||||
return HICON(ret)
|
||||
|
||||
}
|
||||
|
||||
func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR {
|
||||
ret, _, _ := procLoadCursor.Call(
|
||||
uintptr(instance),
|
||||
uintptr(unsafe.Pointer(cursorName)))
|
||||
|
||||
return HCURSOR(ret)
|
||||
|
||||
}
|
||||
|
||||
func ShowWindow(hwnd HWND, cmdshow int) bool {
|
||||
ret, _, _ := procShowWindow.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(cmdshow))
|
||||
|
||||
return ret != 0
|
||||
|
||||
}
|
||||
|
||||
func UpdateWindow(hwnd HWND) bool {
|
||||
ret, _, _ := procUpdateWindow.Call(
|
||||
uintptr(hwnd))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CreateWindowEx(exStyle uint, className, windowName *uint16,
|
||||
style uint, x, y, width, height int, parent HWND, menu HMENU,
|
||||
instance HINSTANCE, param unsafe.Pointer) HWND {
|
||||
ret, _, _ := procCreateWindowEx.Call(
|
||||
uintptr(exStyle),
|
||||
uintptr(unsafe.Pointer(className)),
|
||||
uintptr(unsafe.Pointer(windowName)),
|
||||
uintptr(style),
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(width),
|
||||
uintptr(height),
|
||||
uintptr(parent),
|
||||
uintptr(menu),
|
||||
uintptr(instance),
|
||||
uintptr(param))
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool {
|
||||
ret, _, _ := procAdjustWindowRectEx.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(style),
|
||||
uintptr(BoolToBOOL(menu)),
|
||||
uintptr(exStyle))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func AdjustWindowRect(rect *RECT, style uint, menu bool) bool {
|
||||
ret, _, _ := procAdjustWindowRect.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(style),
|
||||
uintptr(BoolToBOOL(menu)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func DestroyWindow(hwnd HWND) bool {
|
||||
ret, _, _ := procDestroyWindow.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
|
||||
ret, _, _ := procDefWindowProc.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
|
||||
ret, _, _ := procDefDlgProc.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func PostQuitMessage(exitCode int) {
|
||||
procPostQuitMessage.Call(
|
||||
uintptr(exitCode))
|
||||
}
|
||||
|
||||
func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int {
|
||||
ret, _, _ := procGetMessage.Call(
|
||||
uintptr(unsafe.Pointer(msg)),
|
||||
uintptr(hwnd),
|
||||
uintptr(msgFilterMin),
|
||||
uintptr(msgFilterMax))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func TranslateMessage(msg *MSG) bool {
|
||||
ret, _, _ := procTranslateMessage.Call(
|
||||
uintptr(unsafe.Pointer(msg)))
|
||||
|
||||
return ret != 0
|
||||
|
||||
}
|
||||
|
||||
func DispatchMessage(msg *MSG) uintptr {
|
||||
ret, _, _ := procDispatchMessage.Call(
|
||||
uintptr(unsafe.Pointer(msg)))
|
||||
|
||||
return ret
|
||||
|
||||
}
|
||||
|
||||
func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
|
||||
ret, _, _ := procSendMessage.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool {
|
||||
ret, _, _ := procPostMessage.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam)
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func WaitMessage() bool {
|
||||
ret, _, _ := procWaitMessage.Call()
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetWindowText(hwnd HWND, text string) {
|
||||
procSetWindowText.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))))
|
||||
}
|
||||
|
||||
func GetWindowTextLength(hwnd HWND) int {
|
||||
ret, _, _ := procGetWindowTextLength.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetWindowText(hwnd HWND) string {
|
||||
textLen := GetWindowTextLength(hwnd) + 1
|
||||
|
||||
buf := make([]uint16, textLen)
|
||||
procGetWindowText.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(textLen))
|
||||
|
||||
return syscall.UTF16ToString(buf)
|
||||
}
|
||||
|
||||
func GetWindowRect(hwnd HWND) *RECT {
|
||||
var rect RECT
|
||||
procGetWindowRect.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&rect)))
|
||||
|
||||
return &rect
|
||||
}
|
||||
|
||||
func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool {
|
||||
ret, _, _ := procMoveWindow.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(width),
|
||||
uintptr(height),
|
||||
uintptr(BoolToBOOL(repaint)))
|
||||
|
||||
return ret != 0
|
||||
|
||||
}
|
||||
|
||||
func ScreenToClient(hwnd HWND, x, y int) (X, Y int, ok bool) {
|
||||
pt := POINT{X: int32(x), Y: int32(y)}
|
||||
ret, _, _ := procScreenToClient.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&pt)))
|
||||
|
||||
return int(pt.X), int(pt.Y), ret != 0
|
||||
}
|
||||
|
||||
func CallWindowProc(preWndProc uintptr, hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
|
||||
ret, _, _ := procCallWindowProc.Call(
|
||||
preWndProc,
|
||||
uintptr(hwnd),
|
||||
uintptr(msg),
|
||||
wParam,
|
||||
lParam)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func SetWindowLong(hwnd HWND, index int, value uint32) uint32 {
|
||||
ret, _, _ := procSetWindowLong.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(index),
|
||||
uintptr(value))
|
||||
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
|
||||
ret, _, _ := procSetWindowLongPtr.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(index),
|
||||
value)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetWindowLong(hwnd HWND, index int) int32 {
|
||||
ret, _, _ := procGetWindowLong.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(index))
|
||||
|
||||
return int32(ret)
|
||||
}
|
||||
|
||||
func GetWindowLongPtr(hwnd HWND, index int) uintptr {
|
||||
ret, _, _ := procGetWindowLongPtr.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(index))
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func EnableWindow(hwnd HWND, b bool) bool {
|
||||
ret, _, _ := procEnableWindow.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(BoolToBOOL(b)))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func IsWindowEnabled(hwnd HWND) bool {
|
||||
ret, _, _ := procIsWindowEnabled.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func IsWindowVisible(hwnd HWND) bool {
|
||||
ret, _, _ := procIsWindowVisible.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetFocus(hwnd HWND) HWND {
|
||||
ret, _, _ := procSetFocus.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool {
|
||||
ret, _, _ := procInvalidateRect.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(BoolToBOOL(erase)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetClientRect(hwnd HWND) *RECT {
|
||||
var rect RECT
|
||||
ret, _, _ := procGetClientRect.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&rect)))
|
||||
|
||||
if ret == 0 {
|
||||
panic(fmt.Sprintf("GetClientRect(%d) failed", hwnd))
|
||||
}
|
||||
|
||||
return &rect
|
||||
}
|
||||
|
||||
func GetDC(hwnd HWND) HDC {
|
||||
ret, _, _ := procGetDC.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func ReleaseDC(hwnd HWND, hDC HDC) bool {
|
||||
ret, _, _ := procReleaseDC.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(hDC))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetCapture(hwnd HWND) HWND {
|
||||
ret, _, _ := procSetCapture.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func ReleaseCapture() bool {
|
||||
ret, _, _ := procReleaseCapture.Call()
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetWindowThreadProcessId(hwnd HWND) (HANDLE, int) {
|
||||
var processId int
|
||||
ret, _, _ := procGetWindowThreadProcessId.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&processId)))
|
||||
|
||||
return HANDLE(ret), processId
|
||||
}
|
||||
|
||||
func MessageBox(hwnd HWND, title, caption string, flags uint) int {
|
||||
ret, _, _ := procMessageBox.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
|
||||
uintptr(flags))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetSystemMetrics(index int) int {
|
||||
ret, _, _ := procGetSystemMetrics.Call(
|
||||
uintptr(index))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func CopyRect(dst, src *RECT) bool {
|
||||
ret, _, _ := procCopyRect.Call(
|
||||
uintptr(unsafe.Pointer(dst)),
|
||||
uintptr(unsafe.Pointer(src)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EqualRect(rect1, rect2 *RECT) bool {
|
||||
ret, _, _ := procEqualRect.Call(
|
||||
uintptr(unsafe.Pointer(rect1)),
|
||||
uintptr(unsafe.Pointer(rect2)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func InflateRect(rect *RECT, dx, dy int) bool {
|
||||
ret, _, _ := procInflateRect.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(dx),
|
||||
uintptr(dy))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func IntersectRect(dst, src1, src2 *RECT) bool {
|
||||
ret, _, _ := procIntersectRect.Call(
|
||||
uintptr(unsafe.Pointer(dst)),
|
||||
uintptr(unsafe.Pointer(src1)),
|
||||
uintptr(unsafe.Pointer(src2)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func IsRectEmpty(rect *RECT) bool {
|
||||
ret, _, _ := procIsRectEmpty.Call(
|
||||
uintptr(unsafe.Pointer(rect)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func OffsetRect(rect *RECT, dx, dy int) bool {
|
||||
ret, _, _ := procOffsetRect.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(dx),
|
||||
uintptr(dy))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func PtInRect(rect *RECT, x, y int) bool {
|
||||
pt := POINT{X: int32(x), Y: int32(y)}
|
||||
ret, _, _ := procPtInRect.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(unsafe.Pointer(&pt)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetRect(rect *RECT, left, top, right, bottom int) bool {
|
||||
ret, _, _ := procSetRect.Call(
|
||||
uintptr(unsafe.Pointer(rect)),
|
||||
uintptr(left),
|
||||
uintptr(top),
|
||||
uintptr(right),
|
||||
uintptr(bottom))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetRectEmpty(rect *RECT) bool {
|
||||
ret, _, _ := procSetRectEmpty.Call(
|
||||
uintptr(unsafe.Pointer(rect)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SubtractRect(dst, src1, src2 *RECT) bool {
|
||||
ret, _, _ := procSubtractRect.Call(
|
||||
uintptr(unsafe.Pointer(dst)),
|
||||
uintptr(unsafe.Pointer(src1)),
|
||||
uintptr(unsafe.Pointer(src2)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func UnionRect(dst, src1, src2 *RECT) bool {
|
||||
ret, _, _ := procUnionRect.Call(
|
||||
uintptr(unsafe.Pointer(dst)),
|
||||
uintptr(unsafe.Pointer(src1)),
|
||||
uintptr(unsafe.Pointer(src2)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CreateDialog(hInstance HINSTANCE, lpTemplate *uint16, hWndParent HWND, lpDialogProc uintptr) HWND {
|
||||
ret, _, _ := procCreateDialogParam.Call(
|
||||
uintptr(hInstance),
|
||||
uintptr(unsafe.Pointer(lpTemplate)),
|
||||
uintptr(hWndParent),
|
||||
lpDialogProc,
|
||||
0)
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func DialogBox(hInstance HINSTANCE, lpTemplateName *uint16, hWndParent HWND, lpDialogProc uintptr) int {
|
||||
ret, _, _ := procDialogBoxParam.Call(
|
||||
uintptr(hInstance),
|
||||
uintptr(unsafe.Pointer(lpTemplateName)),
|
||||
uintptr(hWndParent),
|
||||
lpDialogProc,
|
||||
0)
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND {
|
||||
ret, _, _ := procGetDlgItem.Call(
|
||||
uintptr(unsafe.Pointer(hDlg)),
|
||||
uintptr(nIDDlgItem))
|
||||
|
||||
return HWND(ret)
|
||||
}
|
||||
|
||||
func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool {
|
||||
ret, _, _ := procDrawIcon.Call(
|
||||
uintptr(unsafe.Pointer(hDC)),
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(unsafe.Pointer(hIcon)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ClientToScreen(hwnd HWND, x, y int) (int, int) {
|
||||
pt := POINT{X: int32(x), Y: int32(y)}
|
||||
|
||||
procClientToScreen.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(&pt)))
|
||||
|
||||
return int(pt.X), int(pt.Y)
|
||||
}
|
||||
|
||||
func IsDialogMessage(hwnd HWND, msg *MSG) bool {
|
||||
ret, _, _ := procIsDialogMessage.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(msg)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func IsWindow(hwnd HWND) bool {
|
||||
ret, _, _ := procIsWindow.Call(
|
||||
uintptr(hwnd))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EndDialog(hwnd HWND, nResult uintptr) bool {
|
||||
ret, _, _ := procEndDialog.Call(
|
||||
uintptr(hwnd),
|
||||
nResult)
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool {
|
||||
ret, _, _ := procPeekMessage.Call(
|
||||
uintptr(unsafe.Pointer(lpMsg)),
|
||||
uintptr(hwnd),
|
||||
uintptr(wMsgFilterMin),
|
||||
uintptr(wMsgFilterMax),
|
||||
uintptr(wRemoveMsg))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool {
|
||||
ret, _, _ := procTranslateMessage.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(hAccTable),
|
||||
uintptr(unsafe.Pointer(lpMsg)))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetWindowPos(hwnd, hWndInsertAfter HWND, x, y, cx, cy int, uFlags uint) bool {
|
||||
ret, _, _ := procSetWindowPos.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(hWndInsertAfter),
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(cx),
|
||||
uintptr(cy),
|
||||
uintptr(uFlags))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func FillRect(hDC HDC, lprc *RECT, hbr HBRUSH) bool {
|
||||
ret, _, _ := procFillRect.Call(
|
||||
uintptr(hDC),
|
||||
uintptr(unsafe.Pointer(lprc)),
|
||||
uintptr(hbr))
|
||||
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func DrawText(hDC HDC, text string, uCount int, lpRect *RECT, uFormat uint) int {
|
||||
ret, _, _ := procDrawText.Call(
|
||||
uintptr(hDC),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
|
||||
uintptr(uCount),
|
||||
uintptr(unsafe.Pointer(lpRect)),
|
||||
uintptr(uFormat))
|
||||
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func AddClipboardFormatListener(hwnd HWND) bool {
|
||||
ret, _, _ := procAddClipboardFormatListener.Call(
|
||||
uintptr(hwnd))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func RemoveClipboardFormatListener(hwnd HWND) bool {
|
||||
ret, _, _ := procRemoveClipboardFormatListener.Call(
|
||||
uintptr(hwnd))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func OpenClipboard(hWndNewOwner HWND) bool {
|
||||
ret, _, _ := procOpenClipboard.Call(
|
||||
uintptr(hWndNewOwner))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func CloseClipboard() bool {
|
||||
ret, _, _ := procCloseClipboard.Call()
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EnumClipboardFormats(format uint) uint {
|
||||
ret, _, _ := procEnumClipboardFormats.Call(
|
||||
uintptr(format))
|
||||
return uint(ret)
|
||||
}
|
||||
|
||||
func GetClipboardData(uFormat uint) HANDLE {
|
||||
ret, _, _ := procGetClipboardData.Call(
|
||||
uintptr(uFormat))
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE {
|
||||
ret, _, _ := procSetClipboardData.Call(
|
||||
uintptr(uFormat),
|
||||
uintptr(hMem))
|
||||
return HANDLE(ret)
|
||||
}
|
||||
|
||||
func EmptyClipboard() bool {
|
||||
ret, _, _ := procEmptyClipboard.Call()
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetClipboardFormatName(format uint) (string, bool) {
|
||||
cchMaxCount := 255
|
||||
buf := make([]uint16, cchMaxCount)
|
||||
ret, _, _ := procGetClipboardFormatName.Call(
|
||||
uintptr(format),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(cchMaxCount))
|
||||
|
||||
if ret > 0 {
|
||||
return syscall.UTF16ToString(buf), true
|
||||
}
|
||||
|
||||
return "Requested format does not exist or is predefined", false
|
||||
}
|
||||
|
||||
func IsClipboardFormatAvailable(format uint) bool {
|
||||
ret, _, _ := procIsClipboardFormatAvailable.Call(uintptr(format))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC {
|
||||
ret, _, _ := procBeginPaint.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(paint)))
|
||||
return HDC(ret)
|
||||
}
|
||||
|
||||
func EndPaint(hwnd HWND, paint *PAINTSTRUCT) {
|
||||
procBeginPaint.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(unsafe.Pointer(paint)))
|
||||
}
|
||||
|
||||
func GetKeyboardState(lpKeyState *[]byte) bool {
|
||||
ret, _, _ := procGetKeyboardState.Call(
|
||||
uintptr(unsafe.Pointer(&(*lpKeyState)[0])))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint {
|
||||
ret, _, _ := procMapVirtualKey.Call(
|
||||
uintptr(uCode),
|
||||
uintptr(uMapType),
|
||||
uintptr(dwhkl))
|
||||
return uint(ret)
|
||||
}
|
||||
|
||||
func GetAsyncKeyState(vKey int) uint16 {
|
||||
ret, _, _ := procGetAsyncKeyState.Call(uintptr(vKey))
|
||||
return uint16(ret)
|
||||
}
|
||||
|
||||
func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int {
|
||||
ret, _, _ := procToAscii.Call(
|
||||
uintptr(uVirtKey),
|
||||
uintptr(uScanCode),
|
||||
uintptr(unsafe.Pointer(lpKeyState)),
|
||||
uintptr(unsafe.Pointer(lpChar)),
|
||||
uintptr(uFlags))
|
||||
return int(ret)
|
||||
}
|
||||
|
||||
func SwapMouseButton(fSwap bool) bool {
|
||||
ret, _, _ := procSwapMouseButton.Call(
|
||||
uintptr(BoolToBOOL(fSwap)))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func GetCursorPos() (x, y int, ok bool) {
|
||||
pt := POINT{}
|
||||
ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt)))
|
||||
return int(pt.X), int(pt.Y), ret != 0
|
||||
}
|
||||
|
||||
func SetCursorPos(x, y int) bool {
|
||||
ret, _, _ := procSetCursorPos.Call(
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func SetCursor(cursor HCURSOR) HCURSOR {
|
||||
ret, _, _ := procSetCursor.Call(
|
||||
uintptr(cursor),
|
||||
)
|
||||
return HCURSOR(ret)
|
||||
}
|
||||
|
||||
func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON {
|
||||
ret, _, _ := procCreateIcon.Call(
|
||||
uintptr(instance),
|
||||
uintptr(nWidth),
|
||||
uintptr(nHeight),
|
||||
uintptr(cPlanes),
|
||||
uintptr(cBitsPerPixel),
|
||||
uintptr(unsafe.Pointer(ANDbits)),
|
||||
uintptr(unsafe.Pointer(XORbits)),
|
||||
)
|
||||
return HICON(ret)
|
||||
}
|
||||
|
||||
func DestroyIcon(icon HICON) bool {
|
||||
ret, _, _ := procDestroyIcon.Call(
|
||||
uintptr(icon),
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR {
|
||||
ret, _, _ := procMonitorFromPoint.Call(
|
||||
uintptr(x),
|
||||
uintptr(y),
|
||||
uintptr(dwFlags),
|
||||
)
|
||||
return HMONITOR(ret)
|
||||
}
|
||||
|
||||
func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR {
|
||||
ret, _, _ := procMonitorFromRect.Call(
|
||||
uintptr(unsafe.Pointer(rc)),
|
||||
uintptr(dwFlags),
|
||||
)
|
||||
return HMONITOR(ret)
|
||||
}
|
||||
|
||||
func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR {
|
||||
ret, _, _ := procMonitorFromWindow.Call(
|
||||
uintptr(hwnd),
|
||||
uintptr(dwFlags),
|
||||
)
|
||||
return HMONITOR(ret)
|
||||
}
|
||||
|
||||
func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool {
|
||||
ret, _, _ := procGetMonitorInfo.Call(
|
||||
uintptr(hMonitor),
|
||||
uintptr(unsafe.Pointer(lmpi)),
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool {
|
||||
ret, _, _ := procEnumDisplayMonitors.Call(
|
||||
uintptr(hdc),
|
||||
uintptr(unsafe.Pointer(clip)),
|
||||
fnEnum,
|
||||
dwData,
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool {
|
||||
ret, _, _ := procEnumDisplaySettingsEx.Call(
|
||||
uintptr(unsafe.Pointer(szDeviceName)),
|
||||
uintptr(iModeNum),
|
||||
uintptr(unsafe.Pointer(devMode)),
|
||||
uintptr(dwFlags),
|
||||
)
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func ChangeDisplaySettingsEx(szDeviceName *uint16, devMode *DEVMODE, hwnd HWND, dwFlags uint32, lParam uintptr) int32 {
|
||||
ret, _, _ := procChangeDisplaySettingsEx.Call(
|
||||
uintptr(unsafe.Pointer(szDeviceName)),
|
||||
uintptr(unsafe.Pointer(devMode)),
|
||||
uintptr(hwnd),
|
||||
uintptr(dwFlags),
|
||||
lParam,
|
||||
)
|
||||
return int32(ret)
|
||||
}
|
||||
|
||||
/* remove to build without cgo
|
||||
func SendInput(inputs []INPUT) uint32 {
|
||||
var validInputs []C.INPUT
|
||||
|
||||
for _, oneInput := range inputs {
|
||||
input := C.INPUT{_type: C.DWORD(oneInput.Type)}
|
||||
|
||||
switch oneInput.Type {
|
||||
case INPUT_MOUSE:
|
||||
(*MouseInput)(unsafe.Pointer(&input)).mi = oneInput.Mi
|
||||
case INPUT_KEYBOARD:
|
||||
(*KbdInput)(unsafe.Pointer(&input)).ki = oneInput.Ki
|
||||
case INPUT_HARDWARE:
|
||||
(*HardwareInput)(unsafe.Pointer(&input)).hi = oneInput.Hi
|
||||
default:
|
||||
panic("unkown type")
|
||||
}
|
||||
|
||||
validInputs = append(validInputs, input)
|
||||
}
|
||||
|
||||
ret, _, _ := procSendInput.Call(
|
||||
uintptr(len(validInputs)),
|
||||
uintptr(unsafe.Pointer(&validInputs[0])),
|
||||
uintptr(unsafe.Sizeof(C.INPUT{})),
|
||||
)
|
||||
return uint32(ret)
|
||||
}
|
||||
*/
|
|
@ -1,203 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func MakeIntResource(id uint16) *uint16 {
|
||||
return (*uint16)(unsafe.Pointer(uintptr(id)))
|
||||
}
|
||||
|
||||
func LOWORD(dw uint32) uint16 {
|
||||
return uint16(dw)
|
||||
}
|
||||
|
||||
func HIWORD(dw uint32) uint16 {
|
||||
return uint16(dw >> 16 & 0xffff)
|
||||
}
|
||||
|
||||
func BoolToBOOL(value bool) BOOL {
|
||||
if value {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func UTF16PtrToString(cstr *uint16) string {
|
||||
if cstr != nil {
|
||||
us := make([]uint16, 0, 256)
|
||||
for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 {
|
||||
u := *(*uint16)(unsafe.Pointer(p))
|
||||
if u == 0 {
|
||||
return string(utf16.Decode(us))
|
||||
}
|
||||
us = append(us, u)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func ComAddRef(unknown *IUnknown) int32 {
|
||||
ret, _, _ := syscall.Syscall(unknown.lpVtbl.pAddRef, 1,
|
||||
uintptr(unsafe.Pointer(unknown)),
|
||||
0,
|
||||
0)
|
||||
return int32(ret)
|
||||
}
|
||||
|
||||
func ComRelease(unknown *IUnknown) int32 {
|
||||
ret, _, _ := syscall.Syscall(unknown.lpVtbl.pRelease, 1,
|
||||
uintptr(unsafe.Pointer(unknown)),
|
||||
0,
|
||||
0)
|
||||
return int32(ret)
|
||||
}
|
||||
|
||||
func ComQueryInterface(unknown *IUnknown, id *GUID) *IDispatch {
|
||||
var disp *IDispatch
|
||||
hr, _, _ := syscall.Syscall(unknown.lpVtbl.pQueryInterface, 3,
|
||||
uintptr(unsafe.Pointer(unknown)),
|
||||
uintptr(unsafe.Pointer(id)),
|
||||
uintptr(unsafe.Pointer(&disp)))
|
||||
if hr != 0 {
|
||||
panic("Invoke QieryInterface error.")
|
||||
}
|
||||
return disp
|
||||
}
|
||||
|
||||
func ComGetIDsOfName(disp *IDispatch, names []string) []int32 {
|
||||
wnames := make([]*uint16, len(names))
|
||||
dispid := make([]int32, len(names))
|
||||
for i := 0; i < len(names); i++ {
|
||||
wnames[i] = syscall.StringToUTF16Ptr(names[i])
|
||||
}
|
||||
hr, _, _ := syscall.Syscall6(disp.lpVtbl.pGetIDsOfNames, 6,
|
||||
uintptr(unsafe.Pointer(disp)),
|
||||
uintptr(unsafe.Pointer(IID_NULL)),
|
||||
uintptr(unsafe.Pointer(&wnames[0])),
|
||||
uintptr(len(names)),
|
||||
uintptr(GetUserDefaultLCID()),
|
||||
uintptr(unsafe.Pointer(&dispid[0])))
|
||||
if hr != 0 {
|
||||
panic("Invoke GetIDsOfName error.")
|
||||
}
|
||||
return dispid
|
||||
}
|
||||
|
||||
func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) {
|
||||
var dispparams DISPPARAMS
|
||||
|
||||
if dispatch&DISPATCH_PROPERTYPUT != 0 {
|
||||
dispnames := [1]int32{DISPID_PROPERTYPUT}
|
||||
dispparams.RgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0]))
|
||||
dispparams.CNamedArgs = 1
|
||||
}
|
||||
var vargs []VARIANT
|
||||
if len(params) > 0 {
|
||||
vargs = make([]VARIANT, len(params))
|
||||
for i, v := range params {
|
||||
//n := len(params)-i-1
|
||||
n := len(params) - i - 1
|
||||
VariantInit(&vargs[n])
|
||||
switch v.(type) {
|
||||
case bool:
|
||||
if v.(bool) {
|
||||
vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0xffff}
|
||||
} else {
|
||||
vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0}
|
||||
}
|
||||
case *bool:
|
||||
vargs[n] = VARIANT{VT_BOOL | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*bool))))}
|
||||
case byte:
|
||||
vargs[n] = VARIANT{VT_I1, 0, 0, 0, int64(v.(byte))}
|
||||
case *byte:
|
||||
vargs[n] = VARIANT{VT_I1 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*byte))))}
|
||||
case int16:
|
||||
vargs[n] = VARIANT{VT_I2, 0, 0, 0, int64(v.(int16))}
|
||||
case *int16:
|
||||
vargs[n] = VARIANT{VT_I2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int16))))}
|
||||
case uint16:
|
||||
vargs[n] = VARIANT{VT_UI2, 0, 0, 0, int64(v.(int16))}
|
||||
case *uint16:
|
||||
vargs[n] = VARIANT{VT_UI2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint16))))}
|
||||
case int, int32:
|
||||
vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(int))}
|
||||
case *int, *int32:
|
||||
vargs[n] = VARIANT{VT_I4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int))))}
|
||||
case uint, uint32:
|
||||
vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(uint))}
|
||||
case *uint, *uint32:
|
||||
vargs[n] = VARIANT{VT_UI4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint))))}
|
||||
case int64:
|
||||
vargs[n] = VARIANT{VT_I8, 0, 0, 0, v.(int64)}
|
||||
case *int64:
|
||||
vargs[n] = VARIANT{VT_I8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int64))))}
|
||||
case uint64:
|
||||
vargs[n] = VARIANT{VT_UI8, 0, 0, 0, int64(v.(uint64))}
|
||||
case *uint64:
|
||||
vargs[n] = VARIANT{VT_UI8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint64))))}
|
||||
case float32:
|
||||
vargs[n] = VARIANT{VT_R4, 0, 0, 0, int64(v.(float32))}
|
||||
case *float32:
|
||||
vargs[n] = VARIANT{VT_R4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float32))))}
|
||||
case float64:
|
||||
vargs[n] = VARIANT{VT_R8, 0, 0, 0, int64(v.(float64))}
|
||||
case *float64:
|
||||
vargs[n] = VARIANT{VT_R8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float64))))}
|
||||
case string:
|
||||
vargs[n] = VARIANT{VT_BSTR, 0, 0, 0, int64(uintptr(unsafe.Pointer(SysAllocString(v.(string)))))}
|
||||
case *string:
|
||||
vargs[n] = VARIANT{VT_BSTR | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*string))))}
|
||||
case *IDispatch:
|
||||
vargs[n] = VARIANT{VT_DISPATCH, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))}
|
||||
case **IDispatch:
|
||||
vargs[n] = VARIANT{VT_DISPATCH | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))}
|
||||
case nil:
|
||||
vargs[n] = VARIANT{VT_NULL, 0, 0, 0, 0}
|
||||
case *VARIANT:
|
||||
vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))}
|
||||
default:
|
||||
panic("unknown type")
|
||||
}
|
||||
}
|
||||
dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0]))
|
||||
dispparams.CArgs = uint32(len(params))
|
||||
}
|
||||
|
||||
var ret VARIANT
|
||||
var excepInfo EXCEPINFO
|
||||
VariantInit(&ret)
|
||||
hr, _, _ := syscall.Syscall9(disp.lpVtbl.pInvoke, 8,
|
||||
uintptr(unsafe.Pointer(disp)),
|
||||
uintptr(dispid),
|
||||
uintptr(unsafe.Pointer(IID_NULL)),
|
||||
uintptr(GetUserDefaultLCID()),
|
||||
uintptr(dispatch),
|
||||
uintptr(unsafe.Pointer(&dispparams)),
|
||||
uintptr(unsafe.Pointer(&ret)),
|
||||
uintptr(unsafe.Pointer(&excepInfo)),
|
||||
0)
|
||||
if hr != 0 {
|
||||
if excepInfo.BstrDescription != nil {
|
||||
bs := UTF16PtrToString(excepInfo.BstrDescription)
|
||||
panic(bs)
|
||||
}
|
||||
}
|
||||
for _, varg := range vargs {
|
||||
if varg.VT == VT_BSTR && varg.Val != 0 {
|
||||
SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val)))))
|
||||
}
|
||||
}
|
||||
result = &ret
|
||||
return
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package w32
|
||||
|
||||
var (
|
||||
IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
|
||||
IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
|
||||
IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
|
||||
IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
|
||||
IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
|
||||
)
|
|
@ -790,7 +790,7 @@ github.com/samuel/go-zookeeper/zk
|
|||
github.com/sasha-s/go-deadlock
|
||||
# github.com/satori/go.uuid v1.2.0
|
||||
github.com/satori/go.uuid
|
||||
# github.com/shirou/gopsutil v2.19.9+incompatible
|
||||
# github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible
|
||||
github.com/shirou/gopsutil/cpu
|
||||
github.com/shirou/gopsutil/disk
|
||||
github.com/shirou/gopsutil/host
|
||||
|
@ -798,8 +798,6 @@ github.com/shirou/gopsutil/internal/common
|
|||
github.com/shirou/gopsutil/mem
|
||||
github.com/shirou/gopsutil/net
|
||||
github.com/shirou/gopsutil/process
|
||||
# github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4
|
||||
github.com/shirou/w32
|
||||
# github.com/sirupsen/logrus v1.4.2
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/stretchr/testify v1.5.1
|
||||
|
|
Loading…
Reference in New Issue